Skip to content

Commit a19be3d

Browse files
revert(local-mcp): relay the MCP initialize handshake instead of faking it
Answering initialize locally regressed the relay: desktop main.log showed servers connecting and executing with the relayed handshake, but stopped connecting once the synthetic-initialize build shipped (the streamable-HTTP session the client sets up on initialize wasn't honored by a locally-fabricated response, so tools/list never followed). Revert to relaying initialize through to the real server, keeping the liveness and startup-buffering fixes that made the round trip work end to end. Generated-By: PostHog Code Task-Id: 7c87c3a4-0be6-475e-a8ec-269140ded301
1 parent 2b5663a commit a19be3d

2 files changed

Lines changed: 2 additions & 61 deletions

File tree

packages/agent/src/server/mcp-relay-server.test.ts

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -179,40 +179,11 @@ describe("McpRelayServer", () => {
179179
expect(events).toHaveLength(0);
180180
});
181181

182-
it("answers the initialize handshake locally without relaying", async () => {
183-
// Even with no reachable client, the connection must establish so the
184-
// real (slow-to-spawn) server isn't dropped during startup.
185-
const { events, post } = await startRelay({
186-
hasReachableClient: () => false,
187-
});
188-
const response = await post("slack", {
189-
jsonrpc: "2.0",
190-
id: 1,
191-
method: "initialize",
192-
params: { protocolVersion: "2025-06-18" },
193-
});
194-
expect(response.status).toBe(200);
195-
const body = (await response.json()) as {
196-
result: { protocolVersion: string; capabilities: { tools: unknown } };
197-
};
198-
expect(body.result.protocolVersion).toBe("2025-06-18");
199-
expect(body.result.capabilities.tools).toBeDefined();
200-
expect(events).toHaveLength(0);
201-
202-
// The paired initialized notification is also answered locally.
203-
const notified = await post("slack", {
204-
jsonrpc: "2.0",
205-
method: "notifications/initialized",
206-
});
207-
expect(notified.status).toBe(202);
208-
expect(events).toHaveLength(0);
209-
});
210-
211-
it("relays non-initialize notifications fire-and-forget with a 202", async () => {
182+
it("relays notifications fire-and-forget with a 202", async () => {
212183
const { events, post } = await startRelay();
213184
const response = await post("slack", {
214185
jsonrpc: "2.0",
215-
method: "notifications/cancelled",
186+
method: "notifications/initialized",
216187
});
217188
expect(response.status).toBe(202);
218189
await expect.poll(() => events.length).toBe(1);

packages/agent/src/server/mcp-relay-server.ts

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -222,36 +222,6 @@ export class McpRelayServer {
222222
});
223223
}
224224

225-
// Answer the MCP `initialize` handshake locally. The real server may be
226-
// a slow-to-spawn stdio process on the user's machine; making connection
227-
// establishment wait on a cross-machine round trip + process spawn blows
228-
// the client's init timeout, and the server is dropped for the run. As a
229-
// pass-through proxy we advertise tools capability and echo the client's
230-
// protocol version; `tools/list` and tool calls relay for real (with
231-
// generous per-request timeouts). The matching `initialized` notification
232-
// is likewise answered locally.
233-
if (payload.method === "initialize") {
234-
const params = payload.params as
235-
| { protocolVersion?: unknown }
236-
| undefined;
237-
const protocolVersion =
238-
typeof params?.protocolVersion === "string"
239-
? params.protocolVersion
240-
: "2025-06-18";
241-
return c.json({
242-
jsonrpc: "2.0",
243-
id: payload.id,
244-
result: {
245-
protocolVersion,
246-
capabilities: { tools: { listChanged: false } },
247-
serverInfo: { name: `relay:${server}`, version: "1.0.0" },
248-
},
249-
});
250-
}
251-
if (payload.method === "notifications/initialized") {
252-
return c.body(null, 202);
253-
}
254-
255225
const requestId = crypto.randomUUID();
256226
const timeoutMs =
257227
this.config.requestTimeoutMs ?? DEFAULT_RELAY_TIMEOUT_MS;

0 commit comments

Comments
 (0)