From 4f204537d6da4a99d3b0d6f0b854237d6609036c Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Fri, 3 Jul 2026 02:55:30 -0500 Subject: [PATCH 1/2] refactor(opencode): expose MCP tools in native shape from the service --- packages/opencode/src/mcp/index.ts | 17 +++++++++++------ packages/opencode/src/session/tools.ts | 4 +++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index e574e20fbaac..59053f13f3e7 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -1,7 +1,6 @@ import path from "node:path" import { pathToFileURL } from "node:url" import { LayerNode } from "@opencode-ai/core/effect/layer-node" -import { type Tool } from "ai" import { ConfigV1 } from "@opencode-ai/core/v1/config/config" import { serviceUse } from "@opencode-ai/core/effect/service-use" import { Client, type ClientOptions } from "@modelcontextprotocol/sdk/client/index.js" @@ -154,11 +153,18 @@ export interface ServerInstructions { tools: string[] } +/** An MCP tool in its native shape; consumers adapt it to their own tool format. */ +export interface McpTool { + def: MCPToolDef + client: MCPClient + timeout?: number +} + export interface Interface { readonly status: () => Effect.Effect> readonly clients: () => Effect.Effect> readonly instructions: () => Effect.Effect - readonly tools: () => Effect.Effect> + readonly tools: () => Effect.Effect> readonly prompts: () => Effect.Effect> readonly resources: (clientName?: string) => Effect.Effect> readonly resourceTemplates: ( @@ -656,7 +662,7 @@ const layer = Layer.effect( } const tools = Effect.fn("MCP.tools")(function* () { - const result: Record = {} + const result: Record = {} const s = yield* InstanceState.get(state) const cfg = yield* cfgSvc.get() @@ -672,9 +678,8 @@ const layer = Layer.effect( continue } const timeout = requestTimeout(s, clientName, mcpConfig, defaultTimeout) - for (const mcpTool of listed) { - const key = McpCatalog.toolName(clientName, mcpTool.name) - result[key] = McpCatalog.convertTool(mcpTool, client, timeout) + for (const def of listed) { + result[McpCatalog.toolName(clientName, def.name)] = { def, client, timeout } } } return result diff --git a/packages/opencode/src/session/tools.ts b/packages/opencode/src/session/tools.ts index 376ba8f2b861..449e83f32b69 100644 --- a/packages/opencode/src/session/tools.ts +++ b/packages/opencode/src/session/tools.ts @@ -3,6 +3,7 @@ import { SessionV1 } from "@opencode-ai/core/v1/session" import { Provider } from "@/provider/provider" import { ProviderTransform } from "@/provider/transform" import { MCP } from "@/mcp" +import { McpCatalog } from "@/mcp/catalog" import { Permission } from "@/permission" import { Tool } from "@/tool/tool" import { ToolJsonSchema } from "@/tool/json-schema" @@ -381,7 +382,8 @@ export const resolve = Effect.fn("SessionTools.resolve")(function* (input: { }) } - for (const [key, item] of Object.entries(yield* mcp.tools())) { + for (const [key, entry] of Object.entries(yield* mcp.tools())) { + const item = McpCatalog.convertTool(entry.def, entry.client, entry.timeout) const execute = item.execute if (!execute) continue From 135a0f87a57b68cd1e068f54749931261edfc3ae Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Fri, 3 Jul 2026 03:02:30 -0500 Subject: [PATCH 2/2] refactor(opencode): mark McpTool fields readonly --- packages/opencode/src/mcp/index.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index 59053f13f3e7..0d6c8c65dcdc 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -155,9 +155,10 @@ export interface ServerInstructions { /** An MCP tool in its native shape; consumers adapt it to their own tool format. */ export interface McpTool { - def: MCPToolDef - client: MCPClient - timeout?: number + /** Shared cached definition; consumers must copy rather than mutate it. */ + readonly def: MCPToolDef + readonly client: MCPClient + readonly timeout?: number } export interface Interface {