fix(opencode): respect MCP server capabilities (#31271)

This commit is contained in:
Aiden Cline
2026-06-07 21:24:41 -05:00
committed by GitHub
parent 4d09a71ef4
commit b5cb9aae7f
4 changed files with 151 additions and 5 deletions
+19 -5
View File
@@ -204,7 +204,7 @@ function fetchFromClient<T extends { name: string }>(
return Effect.tryPromise({
try: () => listFn(client),
catch: (e: any) => {
log.error(`failed to get ${label}`, { clientName, error: e.message })
log.warn(`failed to get ${label}`, { clientName, error: e.message })
return e
},
}).pipe(
@@ -472,7 +472,7 @@ export const layer = Layer.effect(
return { status } satisfies CreateResult
}
const listed = yield* defs(key, mcpClient, mcp.timeout)
const listed = mcpClient.getServerCapabilities()?.tools ? yield* defs(key, mcpClient, mcp.timeout) : []
if (!listed) {
yield* Effect.tryPromise(() => mcpClient.close()).pipe(Effect.ignore)
return { status: { status: "failed", error: "Failed to get tools" } } satisfies CreateResult
@@ -508,6 +508,7 @@ export const layer = Layer.effect(
)
function watch(s: State, name: string, client: MCPClient, bridge: EffectBridge.Shape, timeout?: number) {
if (!client.getServerCapabilities()?.tools) return
client.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
log.info("tools list changed notification received", { server: name })
if (s.clients[name] !== client || s.status[name]?.status !== "connected") return
@@ -718,12 +719,21 @@ export const layer = Layer.effect(
const prompts = Effect.fn("MCP.prompts")(function* () {
const s = yield* InstanceState.get(state)
return yield* collectFromConnected(s, (c) => c.listPrompts().then((r) => r.prompts), "prompts")
return yield* collectFromConnected(
s,
(c) => (c.getServerCapabilities()?.prompts ? c.listPrompts().then((r) => r.prompts) : Promise.resolve([])),
"prompts",
)
})
const resources = Effect.fn("MCP.resources")(function* () {
const s = yield* InstanceState.get(state)
return yield* collectFromConnected(s, (c) => c.listResources().then((r) => r.resources), "resources")
return yield* collectFromConnected(
s,
(c) =>
c.getServerCapabilities()?.resources ? c.listResources().then((r) => r.resources) : Promise.resolve([]),
"resources",
)
})
const withClient = Effect.fnUntraced(function* <A>(
@@ -848,7 +858,11 @@ export const layer = Layer.effect(
Effect.tapError(() => Effect.tryPromise(() => client?.close() ?? Promise.resolve()).pipe(Effect.ignore)),
)
const listed = client ? yield* defs(mcpName, client, mcpConfig.timeout) : undefined
const listed = client
? client.getServerCapabilities()?.tools
? yield* defs(mcpName, client, mcpConfig.timeout)
: []
: undefined
if (!client || !listed) {
yield* Effect.tryPromise(() => client?.close() ?? Promise.resolve()).pipe(Effect.ignore)
return { status: "failed", error: "Failed to get tools" } as Status