From 21620cbf8dce6b87f888acd3f2d12be01df14d31 Mon Sep 17 00:00:00 2001 From: elpresidank Date: Thu, 4 Jun 2026 05:50:30 -0500 Subject: [PATCH] Remove MCP transport type assertion --- ts/EFFECT_NATIVE_REWRITE_AUDIT.md | 16 +++++++ .../flow/src/agent/mcp-tool/service.ts | 42 ++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md index 4800686b..f05db05e 100644 --- a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md +++ b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md @@ -465,6 +465,22 @@ Notes: - `bun run --cwd ts/packages/flow test -- src/__tests__/text-completion-common.test.ts` - `cd ts && bun run check:tsgo` +### 2026-06-04: MCP Tool Transport Adapter Slice + +- Status: migrated and package-verified. +- Completed: + - `ts/packages/flow/src/agent/mcp-tool/service.ts` no longer uses an + `as unknown as Parameters[0]` assertion when connecting + the MCP SDK client. + - The concrete `StreamableHTTPClientTransport` is wrapped in a small + `Transport` adapter that forwards callbacks, send, close, and protocol + version updates while avoiding the SDK's exact-optional `sessionId` type + mismatch. + - The transport release path still closes the concrete SDK transport. +- Verification: + - `bun run --cwd ts/packages/flow test` + - `cd ts && bun run check:tsgo` + ### 2026-06-02: RAG And Agent Requestor Bridge Slice - Status: migrated, root-verified, committed, and pushed. diff --git a/ts/packages/flow/src/agent/mcp-tool/service.ts b/ts/packages/flow/src/agent/mcp-tool/service.ts index faf88b90..303136c8 100644 --- a/ts/packages/flow/src/agent/mcp-tool/service.ts +++ b/ts/packages/flow/src/agent/mcp-tool/service.ts @@ -12,6 +12,7 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; +import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; import { NodeRuntime } from "@effect/platform-node"; import { @@ -100,6 +101,44 @@ const closeTransport = ( ), ); +const transportAdapter = (transport: StreamableHTTPClientTransport): Transport => { + const clientTransport: Transport = { + start: () => { + const onclose = clientTransport.onclose; + if (onclose === undefined) { + delete transport.onclose; + } else { + transport.onclose = onclose; + } + + const onerror = clientTransport.onerror; + if (onerror === undefined) { + delete transport.onerror; + } else { + transport.onerror = onerror; + } + + const onmessage = clientTransport.onmessage; + if (onmessage === undefined) { + delete transport.onmessage; + } else { + transport.onmessage = (message) => onmessage(message); + } + + return transport.start(); + }, + send: (message, options) => + transport.send(message, { + ...(options?.resumptionToken === undefined ? {} : { resumptionToken: options.resumptionToken }), + ...(options?.onresumptiontoken === undefined ? {} : { onresumptiontoken: options.onresumptiontoken }), + }), + close: () => transport.close(), + setProtocolVersion: (version) => transport.setProtocolVersion(version), + }; + + return clientTransport; +}; + const loadMcpServices = Effect.fn("McpToolRuntime.loadMcpServices")(function* ( config: Record, version: number, @@ -165,11 +204,12 @@ const invokeConfiguredTool = Effect.fn("McpToolRuntime.invokeTool")(function* ( url, { requestInit: { headers } }, ); + const clientTransport = transportAdapter(transport); const client = new Client({ name: "trustgraph-mcp-client", version: "1.0.0" }); const result = yield* Effect.acquireUseRelease( Effect.tryPromise({ - try: () => client.connect(transport as unknown as Parameters[0]), + try: () => client.connect(clientTransport), catch: (cause) => mcpToolError("connect", cause, name), }).pipe(Effect.as(client)), (connectedClient) =>