P0.9.1 — ν MCP Bridge — Verification

Step 5 of the 5-step chain. Test evidence and build evidence for the ν MCP Bridge.

Build evidence

Command: npm run build (from worktree, using main checkout’s node_modules)

Result: PASS — zero new TypeScript errors.

Pre-existing error (unchanged from main, not introduced by this task):

src/domains/proof/merkle.ts(47,28): error TS2307: Cannot find module
  'merkletreejs' or its corresponding type declarations.

This is a pre-existing @types gap for merkletreejs (no @types/merkletreejs package). skipLibCheck: true in tsconfig.json prevents it from failing the compile — but the diagnostic still shows. Not introduced by this PR. Confirmed identical on main before this branch.

One deliberate type cast added in mcp-bridge.ts:

return new StreamableHTTPClientTransport(new URL(url)) as unknown as Transport;

Required because StreamableHTTPClientTransport.sessionId is typed as string | undefined while the Transport interface (under exactOptionalPropertyTypes: true) expects exactly string. The cast is safe — the runtime behaviour is identical.

Test evidence

Command: node --experimental-vm-modules node_modules/jest/bin/jest.js --no-coverage

Run from: .worktrees/claude/p0-9-1-nu-mcp-bridge/ with node_modules resolved from E:/AMS/ (worktrees share the main checkout’s node_modules).

mcp-bridge test suite results

Test Suites: 1 passed, 1 total (mcp-bridge.test.ts)
Tests:       24 passed, 24 total
Time:        5.597 s
Test group Tests Status
connectToServer 5 PASS
callTool roundtrip 3 PASS
timeout via COLIBRI_MCP_TIMEOUT 2 PASS
retry on transient errors 2 PASS
non-retryable errors 2 PASS
max retries exhausted 2 PASS
close() 2 PASS
exported constants 4 PASS
McpBridgeError 2 PASS

Full suite results

Test Suites: 21 passed, 21 total
Tests:       934 passed, 934 total
Snapshots:   0 total
Time:        20.511 s

Pre-task baseline (main at 21e199cb): 835+ tests across 20 suites. Post-task: 934 tests across 21 suites. New tests added: 24 (mcp-bridge.test.ts). Regressions: 0.

Acceptance criteria verification

Criterion Test Status
McpBridge wraps outbound MCP client calls connectToServer › returns a bridge with a Client instance PASS
connectToServer(url) creates client, returns connected bridge connectToServer › returns a bridge with the correct url property + Client instance test PASS
callTool(bridge, name, args) calls remote tool, returns result callTool roundtrip › calls the echo tool and returns the correct content (InMemory server) PASS
Timeout: 30s default via COLIBRI_MCP_TIMEOUT timeout via COLIBRI_MCP_TIMEOUT › DEFAULT_TIMEOUT_MS is 30000 + env override test PASS
Retry: 3 attempts with exponential backoff retry on transient errors › retries on McpError InternalError and succeeds on 3rd attempt + backoff delays test PASS
Test: mock MCP server → verify roundtrip tool call callTool roundtrip group (uses InMemoryTransport.createLinkedPair() + McpServer) PASS

Key implementation notes

SDK transport type cast

StreamableHTTPClientTransport from @modelcontextprotocol/sdk declares sessionId?: string | undefined which is incompatible with Transport’s sessionId: string under exactOptionalPropertyTypes: true. The cast as unknown as Transport is the correct escape hatch. This is a known SDK type gap, not a Colibri issue.

McpServer tool error wrapping

The MCP SDK’s McpServer wraps tool handler throws into { isError: true, content: [...] } responses — NOT into McpError exceptions on the client side. Only UrlElicitationRequired propagates as an actual protocol error. This means:

  • Application-level tool errors (tool handler throws) → { isError: true } result, no retry
  • Transport/network-level errors (McpError from protocol layer, AbortError, TypeError) → retry

The retry tests use a makeFakeBridge() helper that bypasses the SDK’s error wrapping to inject McpError exceptions directly, correctly simulating transport-level failures.

__setSleep injection

The production _sleep function is module-level and injectable via __setSleep(). This allows retry tests to run instantly (no real 1-3s delays) while still asserting the correct delay values are computed.

Library-only

No new MCP tool surface was registered in src/server.ts. The bridge exports:

  • McpBridge (interface)
  • connectToServer (function)
  • callTool (function)
  • McpBridgeError (class)
  • Constants: MCP_TIMEOUT_ENV_KEY, DEFAULT_TIMEOUT_MS, DEFAULT_MAX_ATTEMPTS, BACKOFF_BASE_MS

These are available for future consumers (δ Model Router, etc.) via the ν barrel.

Pre-existing flakes

The startup › subprocess smoke test is intermittently flaky (pre-existing, noted by all Wave F sub-agents). It did not affect this test run.

Files created / modified

Path Change
src/domains/integrations/mcp-bridge.ts New: bridge implementation (291 lines)
src/__tests__/domains/integrations/mcp-bridge.test.ts New: 24 tests
src/config.ts Modified: added COLIBRI_MCP_TIMEOUT to Zod schema
src/domains/integrations/index.ts Modified: added export * from './mcp-bridge.js'
docs/audits/p0-9-1-nu-mcp-bridge-audit.md New: Step 1
docs/contracts/p0-9-1-nu-mcp-bridge-contract.md New: Step 2
docs/packets/p0-9-1-nu-mcp-bridge-packet.md New: Step 3
docs/verification/p0-9-1-nu-mcp-bridge-verification.md New: Step 5 (this file)

Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.