Upgrade Harper to v5#4
Conversation
- Replace harperdb imports with harper across all source files - Install harper@5.0.28 as devDependency; remove postinstall harperdb link - Update dev/server scripts from harperdb to harper CLI - Add @harperfast/integration-testing@0.4.0 devDependency - Add test:integration script using harper-integration-test-run - Write integrationTests/mcp.test.ts covering startup, resources/list, resources/read (missing uri error), unknown method error, and valid read - Apply harperBinPath fix in test setup (harper exports map only exposes ".") - Add .github/workflows/integration-tests.yml for Node 22/24/26 matrix - Regenerate package-lock.json with --os=linux --cpu=x64 --include=optional so bufferutil/utf-8-validate/node-gyp-build are recorded for Linux CI - Branding: HarperDB -> Harper in prose throughout README.md - Fix ResourceInfo types to include databaseName and primaryKey fields Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
| name: string; | ||
| tableName?: string; | ||
| databaseName?: string; | ||
| primaryKey?: string; |
There was a problem hiding this comment.
Bug: primaryKey typed as optional but used unsafely, producing corrupted resource URIs
This newly added primaryKey?: string (optional) is passed directly to formatTableData as a string parameter in resourceRead.ts:41, then used in encodeURIComponent(item[primaryKeyField]). When primaryKey is undefined (unset on the Harper resource), item[undefined] evaluates to undefined and encodeURIComponent(undefined) produces the literal string "undefined", so every record gets a URI like http://host/table/undefined.
Fix: Guard before calling formatTableData:
if (!resourceMatch.Resource.primaryKey) {
return { contents: [] };
}Or make primaryKey required if Harper always provides it for table resources.
| }); | ||
| } | ||
|
|
||
| void suite('MCP Server', (ctx: ContextWithHarper) => { |
There was a problem hiding this comment.
Bug: parseInt NaN bypasses the ?? 250 default limit, sending NaN to Resource.get()
In resourceRead.ts, limit and start are parsed with parseInt(value, 10). When value is not a valid integer (e.g., ?limit=abc or ?limit=), parseInt returns NaN. The nullish-coalescing operator ?? 250 only guards against null/undefined — NaN passes through unchanged:
parseInt("abc", 10) // NaN
NaN ?? 250 // NaN (not 250!)
Resource.get({ limit: NaN, offset: NaN }) receives an invalid numeric argument. Depending on Harpers internal handling, this could result in a full-table scan (unbounded query), a runtime error, or silent query failure.
Fix: Use Number.isFinite to validate before passing:
limit = Number.isFinite(parsed) ? parsed : undefined;or inline at the call site: limit: Number.isFinite(limit) ? limit : 250.
| id: set-node-versions | ||
| env: | ||
| NODE_VER: ${{ github.event.inputs.node-version }} | ||
| run: | |
There was a problem hiding this comment.
Misleading action version comments (security/audit concern)
All three pinned actions have version comments that do not match any released version:
| Action | Comment claims | Actual latest |
|---|---|---|
actions/checkout |
# v6.0.3 |
v4.x |
actions/setup-node |
# v6.4.0 |
v4.x |
actions/upload-artifact |
# v7.0.1 |
v4.x |
Pinning to a commit hash is the right security practice — the hash is what GitHub actually runs. But when the human-readable version comment is wrong by 2–3 major versions, auditors relying on the comment to verify the pin will draw false conclusions about what is deployed. Please verify each hash against the correct tag and update the comments to match:
# Example: verify checkout hash
gh api repos/actions/checkout/git/ref/tags/v4.2.2 --jq .object.sha| @@ -0,0 +1,114 @@ | |||
| import { suite, test, before, after } from 'node:test'; | |||
| import { strictEqual, ok, deepStrictEqual } from 'node:assert/strict'; | |||
There was a problem hiding this comment.
Cleanup: deepStrictEqual is imported but never used
deepStrictEqual is destructured from node:assert/strict on line 2 but is not called anywhere in the file. Remove it to keep imports clean and avoid lint noise.
// Before
import { strictEqual, ok, deepStrictEqual } from "node:assert/strict";
// After
import { strictEqual, ok } from "node:assert/strict";| Resource: { | ||
| name: string; | ||
| tableName?: string; | ||
| databaseName?: string; |
There was a problem hiding this comment.
Plausible crash: non-null assertion attributes! on an optional field
In resourceList.ts, formatTableForContext calls attributesToString(resource.attributes!). The attributes field is typed as attributes?: TableAttr[] (optional), so it can be undefined at runtime for table resources that have not yet had their schema introspected or for edge cases in Harper v5. The ! assertion suppresses the TypeScript error but does not guard against the actual undefined — if attributes is undefined, attributesToString receives undefined, its .map() call throws TypeError: Cannot read properties of undefined (reading "map"), and the entire resources/list response fails.
Fix: Add a guard or default:
const attrs = attributesToString(resource.attributes ?? []);…ributes non-null assertion - Guard against undefined primaryKey before calling formatTableData to avoid corrupted URIs - Validate parseInt result with Number.isFinite to prevent NaN bypassing the ?? 250 default limit - Replace resource.attributes! non-null assertion with safe ?? [] default in resourceList Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Summary
harperdb(v4, runtime global) withharper@^5.0.28as a devDependency; removedpostinstall: npm link harperdbscript.from 'harperdb'imports tofrom 'harper'acrosssrc/resources/index.ts,src/resources/mcpResources/resourceList.ts,src/resources/mcpResources/resourceRead.ts, andsrc/harper.d.ts.devandserverscripts fromharperdb dev/runtoharper dev/run.integrationTests/mcp.test.tscovering Harper startup,resources/list,resources/read(missing URI error), unknown method error, and valid read with empty response. AppliesharperBinPathfix forERR_PACKAGE_PATH_NOT_EXPORTED(harper's exports map only exposes".")..github/workflows/integration-tests.ymlwith Node 22/24/26 matrix, actions pinned to commit hashes.package-lock.jsonwith--os=linux --cpu=x64 --include=optionalto recordbufferutil,utf-8-validate, andnode-gyp-buildnative deps for Linux CI.HarperDB→Harperin README prose; updated version requirement to v5; updatedauthorfield toHarper, Inc..databaseNameandprimaryKeytoResourceInfointerface (used but missing from types).Migration items N/A
Table.get()return value / frozen records /wasLoadedFromSource()— no Table.get() calls in this codebase; it is a REST adapter, not a DB consumer.harperdb-config.yaml→config.yaml— already usesconfig.yaml.Known issues / notes
npm run test:integrationfails locally withEADDRNOTAVAIL/LoopbackAddressValidationErrorbecause macOS loopback aliases are not configured on this machine (127.0.0.2+ not available). This is an environment issue, not a code bug. CI (ubuntu-latest) supports the full 127.0.0.0/8 range and is the test gate.harperpackage'sexportsmap only exposes"."— the integration harness cannot auto-resolveharper/dist/bin/harper.js. TheharperBinPathexplicit-path workaround is applied in the test file. Upstream should export the bin path or the harness should resolve via the package root.@harperdb/mcp-server— migrating to the current Harper npm scope (@harperfast/or similar) is a manual release task per org policy. Flagged for the team.Test plan
resources/listreturns a valid JSON-RPC result with aresourcesarrayresources/readwith missingurireturns error code-32602-32601resources/readwith a valid URI path returnscontentsarray🤖 Generated with Claude Code