Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package opencode for openSUSE:Factory checked in at 2026-10-12 22:08:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/opencode (Old) and /work/SRC/openSUSE:Factory/.opencode.new.3698736 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "opencode" Mon Oct 12 22:08:12 2026 rev:22 rq:1384314 version:2.0.26 Changes: -------- --- /work/SRC/openSUSE:Factory/opencode/opencode.changes 2026-10-09 21:46:08.301224109 +0200 +++ /work/SRC/openSUSE:Factory/.opencode.new.3698736/opencode.changes 2026-10-12 22:08:23.445232776 +0200 @@ -1,0 +2,5 @@ +Sun Oct 11 20:37:31 UTC 2026 - Robert Munteanu <[email protected]> + +- Add opencode-mcp-elicitation-capability.patch + +------------------------------------------------------------------- New: ---- opencode-mcp-elicitation-capability.patch ----------(New B)---------- New: - Add opencode-mcp-elicitation-capability.patch ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ opencode.spec ++++++ --- /var/tmp/diff_new_pack.dsTy8n/_old 2026-10-12 22:08:24.635282419 +0200 +++ /var/tmp/diff_new_pack.dsTy8n/_new 2026-10-12 22:08:24.637282502 +0200 @@ -116,6 +116,9 @@ # through bun:ffi; the wasm route needs a runtime module only emscripten can # build. Placeholders are filled in below. Patch4: %{name}-native-tree-sitter.patch +# Advertise spec-shaped MCP elicitation capabilities so strict servers accept +# initialization. https://github.com/anomalyco/opencode/pull/53196 +Patch5: %{name}-mcp-elicitation-capability.patch # No floor. Which bun upstream wants changes with every release and Patch0 # turns a mismatch into a warning; a floor here would be a guess at which # older bun still works, and the package is a git snapshot anyway, so ++++++ opencode-mcp-elicitation-capability.patch ++++++ >From 2537244971fab1df71082636549f648fbcd11626 Mon Sep 17 00:00:00 2001 From: Don Bowman <[email protected]> Date: Sun, 4 Oct 2026 14:34:06 -0400 Subject: [PATCH] fix(core): advertise the spec-shaped MCP elicitation capability The specification defines the elicitation capability as `{ form: {}, url: {} }`. The SDK's `applyDefaults` member is not part of it, and strict servers reject the unknown field during initialize. Fixes #52319 --- packages/core/src/mcp/client.ts | 6 +++- packages/core/test/mcp.test.ts | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/core/src/mcp/client.ts b/packages/core/src/mcp/client.ts index 39a7085ec6b1..e06c55a256bb 100644 --- a/packages/core/src/mcp/client.ts +++ b/packages/core/src/mcp/client.ts @@ -185,7 +185,11 @@ export const connect = Effect.fnUntraced(function* ( const runFork = Effect.runForkWith(yield* Effect.context()) const client = new Client(clientInfo, { capabilities: { - ...(elicitation ? { elicitation: { form: { applyDefaults: true }, url: {} } } : {}), + // Advertise the capability exactly as the specification defines it: `form` and `url` are + // empty object schemas. Strict servers reject vendor fields such as the SDK's + // `applyDefaults`, and the form service applies each schema `default` when it renders, so + // we do not need it. See https://github.com/anomalyco/opencode/issues/52319. + ...(elicitation ? { elicitation: { form: {}, url: {} } } : {}), // Legacy era only: roots are deprecated as of 2026-07-28 and modern servers cannot request them. // Some legacy servers refuse to run without one (https://github.com/anomalyco/opencode/issues/2308). roots: {}, diff --git a/packages/core/test/mcp.test.ts b/packages/core/test/mcp.test.ts index 314b81fcb8aa..a9eb7e8eced5 100644 --- a/packages/core/test/mcp.test.ts +++ b/packages/core/test/mcp.test.ts @@ -119,6 +119,10 @@ function resourceServer( progressToken: unknown }>, initializations: 0, + // Legacy capabilities arrive in the initialize handshake; modern ones ride every request's + // `_meta.io.modelcontextprotocol/clientCapabilities`, so both are recorded to assert the wire shape. + capabilities: [] as unknown[], + metaCapabilities: [] as unknown[], urls: [] as string[], sessions: [] as string[], } @@ -239,6 +243,18 @@ function resourceServer( if (typeof body === "object" && body !== null && "method" in body && body.method === "initialize") { state.initializations += 1 } + if (typeof body === "object" && body !== null && "params" in body) { + const params = body.params + if (typeof params === "object" && params !== null) { + if ("capabilities" in params) state.capabilities.push(params.capabilities) + const meta = + "_meta" in params && typeof params._meta === "object" && params._meta !== null + ? (params._meta as Record<string, unknown>) + : undefined + const capabilities = meta?.["io.modelcontextprotocol/clientCapabilities"] + if (capabilities !== undefined) state.metaCapabilities.push(capabilities) + } + } return (await input.respond?.(request)) ?? modern?.fetch(request) ?? current.transport.handleRequest(request) }, }) @@ -1359,6 +1375,45 @@ test("settles modern MCP URL elicitations when the user confirms", async () => { ) }) +test("advertises the specification's MCP elicitation capability in both protocol eras", async () => { + await Effect.runPromise( + Effect.scoped( + Effect.gen(function* () { + const legacy = yield* resourceServer({ resources: false }) + yield* Effect.gen(function* () { + yield* settled(yield* Mcp.Service) + }).pipe(Effect.provide(resourceMcpLayer(legacy.url))) + + // `toEqual` catches extra members, so a vendor field such as the SDK's `applyDefaults` + // fails this. The capability is specified as `{ form: {}, url: {} }`. + const legacyCapabilities = legacy.state.capabilities.at(-1) as { elicitation?: unknown } | undefined + expect(legacyCapabilities?.elicitation).toEqual({ form: {}, url: {} }) + + const modern = yield* resourceServer({ modern: true, resources: false }) + yield* Effect.gen(function* () { + yield* settled(yield* Mcp.Service) + }).pipe( + Effect.provide( + resourceMcpLayer( + new ConfigMCP.Remote({ + type: "remote", + url: modern.url, + oauth: false, + protocol: "2026-07-28", + }), + ), + ), + ) + + // 2026-07-28 carries the same capability object in every request's `_meta` instead of the + // initialize handshake, so the wire shape is asserted there too. + const modernCapabilities = modern.state.metaCapabilities.at(-1) as { elicitation?: unknown } | undefined + expect(modernCapabilities?.elicitation).toEqual({ form: {}, url: {} }) + }), + ), + ) +}) + test("loads and reads MCP resources", async () => { await Effect.runPromise( Effect.scoped(
