---
id: 10183
title: MCP Server Integration Testing Harness for CallToolRequestSchema
state: CLOSED
labels:
  - enhancement
  - ai
  - testing
  - needs-re-triage
assignees: []
createdAt: '2026-04-22T16:06:29Z'
updatedAt: '2026-06-06T07:34:24Z'
githubUrl: 'https://github.com/neomjs/neo/issues/10183'
author: neo-gemini-pro
commentsCount: 2
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking:
  - '[x] 10190 Implement chosen shared caching substrate for Memory Core'
closedAt: '2026-06-06T07:34:24Z'
---
# MCP Server Integration Testing Harness for CallToolRequestSchema

**Context**
During the resolution of the identity binding race condition in #10181 (merged via PR #10182), we successfully implemented a self-heal hook inside `ai/mcp/server/memory-core/Server.mjs` directly on the `CallToolRequestSchema` dispatch path. However, we could not add a unit test for this specific logic because simulating the "node added to SQLite *after* first binding attempt" scenario requires the full MCP Server harness (MCP protocol transport + dispatch path), which no current test exercises.

**The Problem**
Our current test coverage (e.g., `MailboxService.spec.mjs`) primarily tests the underlying service logic in isolation, mocking or bypassing the actual MCP transport layer. We currently lack a dedicated test scaffolding that exercises the `CallToolRequestSchema` dispatch path end-to-end within the unit testing harness. This prevents us from testing transport-layer middleware, dispatch hooks, and context-scoping mechanics reliably.

**The Architectural Reality**
The `ai/mcp/server/*/Server.mjs` classes handle the raw MCP protocol. We need a Playwright testing fixture/utility that can stand up an instance of the MCP Server in-memory, mock the Stdio/WebSocket transport streams, and allow test files to dispatch `CallToolRequestSchema` requests exactly as the IDE/Claude Desktop would.

**The Fix**
- Create a reusable MCP test harness utility (likely in `test/playwright/unit/ai/mcp/utils/` or similar).
- The harness should instantiate a target `Server` class, attach a mock transport, and provide an API for sending JSON-RPC messages and asserting on the responses.
- Implement the first consuming test: migrate or add the scenario from #10181 to verify the `CallToolRequestSchema` self-heal logic end-to-end.

**Acceptance Criteria**
- [ ] An `McpTestHarness` utility is created that can instantiate and interact with an MCP server via mocked transport.
- [ ] The utility is capable of emitting raw JSON-RPC `CallToolRequestSchema` payloads and capturing the results/errors.
- [ ] A new test file (e.g., `Server.spec.mjs` or similar) is created for `memory-core` that successfully uses the harness.
- [ ] The specific "late node seeding" self-heal scenario from #10181 is explicitly tested and passes.

**Out of Scope**
- We are not replacing existing service-level unit tests.
- We are not building a full E2E system testing against live Claude Desktop instances. This is purely for the Playwright unit testing layer.

**Related**
- Resolves the missing test AC from #10181
- PR #10182 (shipped the fix that needs this test)

Origin Session ID: 984150f3-3aab-4a25-b623-d6e7472b4dd3

## Timeline

- 2026-04-22T16:06:30Z @neo-gemini-pro added the `enhancement` label
- 2026-04-22T16:06:30Z @neo-gemini-pro added the `ai` label
- 2026-04-22T16:06:31Z @neo-gemini-pro added the `testing` label
- 2026-04-22T18:33:25Z @neo-gemini-pro cross-referenced by #10190
- 2026-04-22T18:33:39Z @neo-gemini-pro marked this issue as blocking #10190
- 2026-04-22T20:11:30Z @neo-opus-ada cross-referenced by PR #10202
### @neo-gpt - 2026-06-06T05:08:31Z

**Input from GPT-5 (Codex Desktop):**

> ● ## Ticket Intake Refresh — already covered by current MCP server tests
> 
> [ARCH_ALIGNMENT] Verdict: `already-resolved / stale-as-written`; I am not claiming a branch for this ticket.
> 
> To assert whether #10183 is still a missing implementation lane, I checked the live issue, searched for open PRs targeting `10183`, inspected the current MCP server/test substrate, and ran the focused unit evidence.
> 
> Current-source evidence:
> 
> - `test/playwright/unit/ai/mcp/server/BaseServer.spec.mjs` now contains a schema-keyed mock MCP server that captures handlers registered with `ListToolsRequestSchema` and `CallToolRequestSchema`.
> - That spec directly invokes the `CallToolRequestSchema` handler and verifies dispatch through `wrapDispatch`, health-gate behavior, `beforeToolDispatch`, `onHealthGateFailure`, result formatting, and canonical boot/request-handler setup.
> - `test/playwright/unit/ai/mcp/server/memory-core/Server.spec.mjs` now pins the identity binding regression family, including recovery from a stuck `vicinityLoadedNodes` cache miss and the Promise-returning `GraphService.getNode` path.
> - `ai/mcp/server/BaseServer.mjs` now centralizes `CallToolRequestSchema` dispatch for all MCP servers, so the original per-server harness gap has been substantially replaced by the shared `BaseServer` test substrate.
> - No open PR exists for `10183`.
> 
> Verification run:
> 
> ```bash
> npm run test-unit -- test/playwright/unit/ai/mcp/server/BaseServer.spec.mjs test/playwright/unit/ai/mcp/server/memory-core/Server.spec.mjs
> ```
> 
> Result: `35 passed`.
> 
> Residual caveat: the original ticket asked for a reusable `McpTestHarness` utility. Current substrate chose a leaner in-spec mock server for `BaseServer` plus targeted memory-core server tests. Given the operator's current no-micro-PR guidance and the passing focused coverage, extracting that helper now would be cleanup churn unless a second consuming spec needs the same abstraction.
> 
> Recommendation: close #10183 as resolved/stale, or keep it only if a maintainer wants to rewrite it narrowly as a helper-extraction ticket after a second real consumer appears.

- 2026-06-06T05:08:46Z @neo-gpt added the `needs-re-triage` label
### @neo-gpt - 2026-06-06T07:34:24Z

Closing as resolved/stale-as-written after fresh V-B-A.

Current substrate already covers the load-bearing #10183 contract:
- `BaseServer.setupRequestHandlers()` wires the real `CallToolRequestSchema` dispatch path.
- `BaseServer.spec.mjs` captures schema-keyed handlers and directly invokes the `CallToolRequestSchema` handler, covering dispatch, `wrapDispatch`, health gate, pre-dispatch hook, health-failure hook, and result formatting.
- `memory-core/Server.spec.mjs` pins the identity-binding regression family including Promise-returning `GraphService.getNode` and stuck `vicinityLoadedNodes` recovery.
- Focused unit run: `npm run test-unit -- test/playwright/unit/ai/mcp/server/BaseServer.spec.mjs test/playwright/unit/ai/mcp/server/memory-core/Server.spec.mjs` => `35 passed`.

Residual explicitly not carried here: extracting a reusable MCP test harness helper. Current coverage uses a lean in-spec harness; without a second consumer, helper extraction would be cleanup churn and conflicts with current operator guidance to avoid micro PRs.

- 2026-06-06T07:34:24Z @neo-gpt closed this issue

