fix(server): make the pinned lookup honor Node's all:true callback shape

Addresses the round-1 Copilot review.

- createPinnedAgent: Node's net.connect runs with autoSelectFamily on
  (Node >= 20), so it calls the lookup hook with `{ all: true }` and
  requires an ARRAY of `{ address, family }`. The scalar-only callback
  failed every hostname request with ERR_INVALID_IP_ADDRESS, so /fetch
  could only reach literal-IP targets. Both callback shapes are now
  supported. Reproduced against Node 22/26 before and after.
- Tests: cover the `{ all: true }` shape for IPv4 and IPv6, and add an
  end-to-end request through the agent over the production path
  (node-fetch -> http.Agent -> net.connect) using an unresolvable
  hostname, so the request can only succeed via the pinned IP. Verified
  these three fail without the fix. Replaced the `Function`-typed casts
  with a typed pinnedLookup() helper.
- CI: run the new server suite (.github/workflows/main.yml) and add a
  root `test-server` script, so this regression coverage is enforced.
- package-lock.json: sync the server workspace manifest mirror with the
  added @types/node and vitest devDependencies.
- index.ts: drop the `agent as any` cast and its eslint-disable — the
  node-fetch RequestInit already types `agent`, and tsc is clean without
  the suppression.
- Formatting: prettier-check now passes (it failed on the two new files).

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-19 16:59:06 -04:00
commit 0e1bc1d402

View file

@ -42,6 +42,7 @@
"start-client": "cd client && npm run preview",
"test": "npm run prettier-check && cd client && npm test",
"test-cli": "cd cli && npm run test",
"test-server": "cd server && npm run test",
"test:e2e": "MCP_AUTO_OPEN_ENABLED=false npm run test:e2e --workspace=client",
"prettier-fix": "prettier --write .",
"prettier-check": "prettier --check .",