Skip to content

Commit 2c8b5f2

Browse files
edyedy
authored andcommitted
chore: sync upstream to v1.18.8
Absorbed from upstream v1.18.7→v1.18.8: ✅ Bug fixes: - Gemini sampling defaults: only apply temperature/topP/topK to specific model versions - MCP session recovery: add client patch for expired sessions - MCP callback port: honor port in debug mode - MCP environment field: correct in built-in skill ✅ Feature upgrades: - MCP SDK v2: upgrade from @modelcontextprotocol/sdk@1.29.0 to @modelcontextprotocol/client@2.0.0-beta.5 - New version negotiation and list pagination - Improved error handling (RegistrationRejectedError, SdkHttpError) - String-based request handlers - GitLab provider: bump to 6.12.0 ✅ Dependency cleanup: - Remove deleted workspace package references (effect-sqlite-node, ui, script) - Remove deleted module dependencies (actions, octokit, openauth, bonjour-service, chokidar) All changes pass typecheck. MCP SDK v2 upgrade taken from upstream as it includes critical bug fixes and improves session management.
2 parents d99e2ff + 1ead8d8 commit 2c8b5f2

42 files changed

Lines changed: 1881 additions & 2158 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bun.lock

Lines changed: 1184 additions & 1118 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@
123123
"pacote@21.5.0": "patches/pacote@21.5.0.patch",
124124
"@ai-sdk/google@3.0.73": "patches/@ai-sdk%2Fgoogle@3.0.73.patch",
125125
"@pierre/trees@1.0.0-beta.4": "patches/@pierre%2Ftrees@1.0.0-beta.4.patch",
126-
"@modelcontextprotocol/sdk@1.29.0": "patches/@modelcontextprotocol%2Fsdk@1.29.0.patch",
127126
"effect@4.0.0-beta.83": "patches/effect@4.0.0-beta.83.patch",
128-
"@tanstack/virtual-core@3.17.3": "patches/@tanstack%2Fvirtual-core@3.17.3.patch"
127+
"@tanstack/virtual-core@3.17.3": "patches/@tanstack%2Fvirtual-core@3.17.3.patch",
128+
"@modelcontextprotocol/client@2.0.0-beta.5": "patches/@modelcontextprotocol%2Fclient@2.0.0-beta.5.patch"
129129
}
130130
}

packages/codemode/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
33
"name": "@opencode-ai/codemode",
4-
"version": "1.18.7",
4+
"version": "1.18.8",
55
"description": "Effect-native confined code execution over schema-described tools",
66
"private": true,
77
"type": "module",

packages/core/package.json

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
3-
"version": "1.18.7",
3+
"version": "1.18.8",
44
"name": "@opencode-ai/core",
55
"type": "module",
66
"license": "MIT",
@@ -40,7 +40,6 @@
4040
}
4141
},
4242
"devDependencies": {
43-
"@opencode-ai/http-recorder": "workspace:*",
4443
"@tsconfig/bun": "catalog:",
4544
"@types/bun": "catalog:",
4645
"@types/cross-spawn": "catalog:",
@@ -58,7 +57,8 @@
5857
"@parcel/watcher-linux-x64-musl": "2.5.1",
5958
"@parcel/watcher-win32-arm64": "2.5.1",
6059
"@parcel/watcher-win32-x64": "2.5.1",
61-
"drizzle-kit": "catalog:"
60+
"@opencode-ai/http-recorder": "workspace:*",
61+
"drizzle-kit": "catalog:"
6262
},
6363
"dependencies": {
6464
"@ai-sdk/alibaba": "1.0.17",
@@ -72,7 +72,7 @@
7272
"@ai-sdk/google": "3.0.73",
7373
"@ai-sdk/google-vertex": "4.0.128",
7474
"@ai-sdk/groq": "3.0.31",
75-
"@ai-sdk/mistral": "3.0.51",
75+
"@ai-sdk/mistral": "3.0.51",
7676
"@ai-sdk/openai": "3.0.84",
7777
"@ai-sdk/openai-compatible": "2.0.41",
7878
"@ai-sdk/perplexity": "3.0.26",
@@ -92,6 +92,10 @@
9292
"@opencode-ai/llm": "workspace:*",
9393
"@opencode-ai/schema": "workspace:*",
9494
"@opencode-ai/plugin": "workspace:*",
95+
"@opentelemetry/api": "1.9.0",
96+
"@opentelemetry/context-async-hooks": "2.6.1",
97+
"@opentelemetry/exporter-trace-otlp-http": "0.214.0",
98+
"@opentelemetry/sdk-trace-base": "2.6.1",
9599
"@parcel/watcher": "2.5.1",
96100
"@silvia-odwyer/photon-node": "0.3.4",
97101
"@openrouter/ai-sdk-provider": "2.9.0",
@@ -102,7 +106,7 @@
102106
"drizzle-orm": "catalog:",
103107
"effect": "catalog:",
104108
"fuzzysort": "3.1.0",
105-
"gitlab-ai-provider": "6.11.1",
109+
"gitlab-ai-provider": "6.12.0",
106110
"glob": "13.0.5",
107111
"google-auth-library": "10.5.0",
108112
"gray-matter": "4.0.3",

packages/core/src/plugin/skill/customize-opencode.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Every field is optional.
112112
"type": "local",
113113
"command": ["npx", "-y", "@playwright/mcp"],
114114
"enabled": true,
115-
"env": {}
115+
"environment": {}
116116
},
117117
"remote-thing": {
118118
"type": "remote",
@@ -371,7 +371,7 @@ Special object-shaped (not callbacks): `tool: { my_tool: { ... } }`,
371371
"type": "local",
372372
"command": ["npx", "-y", "@playwright/mcp"],
373373
"enabled": true,
374-
"env": { "BROWSER": "chromium" }
374+
"environment": { "BROWSER": "chromium" }
375375
},
376376
"github": {
377377
"type": "remote",
@@ -384,7 +384,8 @@ Special object-shaped (not callbacks): `tool: { my_tool: { ... } }`,
384384
}
385385
```
386386

387-
`command` is an array of strings. `type` is required. Use `enabled: false` to
387+
`command` is an array of strings. `environment` sets environment variables for
388+
a local MCP server. `type` is required. Use `enabled: false` to
388389
disable a server inherited from a parent config. String values such as header
389390
tokens support `{env:VAR}` interpolation (and `{file:path}`); the shell-style
390391
`${VAR}` is not substituted.

packages/effect-drizzle-sqlite/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
3-
"version": "1.18.7",
3+
"version": "1.18.8",
44
"name": "@opencode-ai/effect-drizzle-sqlite",
55
"type": "module",
66
"license": "MIT",

packages/http-recorder/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
3-
"version": "1.18.7",
3+
"version": "1.18.8",
44
"name": "@opencode-ai/http-recorder",
55
"description": "Record and replay Effect HTTP client traffic with deterministic cassettes",
66
"type": "module",

packages/llm/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
3-
"version": "1.18.7",
3+
"version": "1.18.8",
44
"name": "@opencode-ai/llm",
55
"type": "module",
66
"license": "MIT",
@@ -37,6 +37,7 @@
3737
"devDependencies": {
3838
"@clack/prompts": "1.0.0-alpha.1",
3939
"@effect/platform-node": "catalog:",
40+
"@opencode-ai/http-recorder": "workspace:*",
4041
"@tsconfig/bun": "catalog:",
4142
"@types/bun": "catalog:",
4243
"@typescript/native-preview": "catalog:"

packages/opencode/package.json

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
3-
"version": "1.18.7",
3+
"version": "1.18.8",
44
"name": "opencode",
55
"type": "module",
66
"license": "MIT",
@@ -30,8 +30,9 @@
3030
},
3131
"devDependencies": {
3232
"@babel/core": "7.28.4",
33-
"@opencode-ai/http-recorder": "workspace:*",
33+
"@modelcontextprotocol/server": "2.0.0-beta.5",
3434
"@opencode-ai/core": "workspace:*",
35+
"@opencode-ai/http-recorder": "workspace:*",
3536
"@standard-schema/spec": "1.0.0",
3637
"@tsconfig/bun": "catalog:",
3738
"@types/babel__core": "7.20.5",
@@ -73,7 +74,7 @@
7374
"@clack/prompts": "1.0.0-alpha.1",
7475
"@effect/platform-node": "catalog:",
7576
"@ff-labs/fff-bun": "0.9.4",
76-
"@modelcontextprotocol/sdk": "1.29.0",
77+
"@modelcontextprotocol/client": "2.0.0-beta.5",
7778
"@opencode-ai/codemode": "workspace:*",
7879
"@opencode-ai/llm": "workspace:*",
7980
"@opencode-ai/plugin": "workspace:*",
@@ -83,11 +84,15 @@
8384
"@opencode-ai/server": "workspace:*",
8485
"@opencode-ai/tui": "workspace:*",
8586
"@openrouter/ai-sdk-provider": "2.9.0",
87+
"@opentelemetry/api": "1.9.0",
88+
"@opentelemetry/context-async-hooks": "2.6.1",
89+
"@opentelemetry/exporter-trace-otlp-http": "0.214.0",
90+
"@opentelemetry/sdk-trace-base": "2.6.1",
91+
"@opentelemetry/sdk-trace-node": "2.6.1",
8692
"@opentui/core": "catalog:",
8793
"@opentui/keymap": "catalog:",
8894
"@opentui/solid": "catalog:",
8995
"@parcel/watcher": "2.5.1",
90-
"@parcel/watcher-darwin-arm64": "2.5.1",
9196
"@pierre/diffs": "catalog:",
9297
"@silvia-odwyer/photon-node": "0.3.4",
9398
"@solid-primitives/event-bus": "1.1.2",
@@ -103,7 +108,7 @@
103108
"drizzle-orm": "catalog:",
104109
"effect": "catalog:",
105110
"fuzzysort": "3.1.0",
106-
"gitlab-ai-provider": "6.11.1",
111+
"gitlab-ai-provider": "6.12.0",
107112
"glob": "13.0.5",
108113
"google-auth-library": "10.5.0",
109114
"gray-matter": "4.0.3",

packages/opencode/src/cli/cmd/mcp.ts

Lines changed: 45 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@ import { cmd } from "./cmd"
22
import { ConfigV1 } from "@opencode-ai/core/v1/config/config"
33
import { effectCmd } from "../effect-cmd"
44
import { Cause } from "effect"
5-
import { Client } from "@modelcontextprotocol/sdk/client/index.js"
6-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"
7-
import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js"
8-
import { LATEST_PROTOCOL_VERSION } from "@modelcontextprotocol/sdk/types.js"
5+
import { Client, StreamableHTTPClientTransport, UnauthorizedError } from "@modelcontextprotocol/client"
96
import * as prompts from "@clack/prompts"
107
import { UI } from "../ui"
11-
import { MCP } from "../../mcp"
8+
import { CLIENT_OPTIONS, MCP } from "../../mcp"
129
import { McpAuth } from "../../mcp/auth"
1310
import { McpOAuthProvider } from "../../mcp/oauth-provider"
1411
import { Config } from "@/config/config"
@@ -731,107 +728,53 @@ export const McpDebugCommand = effectCmd({
731728
const spinner = prompts.spinner()
732729
spinner.start("Testing connection...")
733730

734-
// Test basic HTTP connectivity first
735-
try {
736-
const response = await fetch(serverConfig.url, {
737-
method: "POST",
738-
headers: {
739-
...serverConfig.headers,
740-
"Content-Type": "application/json",
741-
Accept: "application/json, text/event-stream",
731+
const oauthConfig = typeof serverConfig.oauth === "object" ? serverConfig.oauth : undefined
732+
let authorizationUrl: URL | undefined
733+
const authProvider = new McpOAuthProvider(
734+
serverName,
735+
serverConfig.url,
736+
{
737+
clientId: oauthConfig?.clientId,
738+
clientSecret: oauthConfig?.clientSecret,
739+
scope: oauthConfig?.scope,
740+
callbackPort: oauthConfig?.callbackPort,
741+
redirectUri: oauthConfig?.redirectUri,
742+
},
743+
{
744+
onRedirect: async (url) => {
745+
authorizationUrl = url
742746
},
743-
body: JSON.stringify({
744-
jsonrpc: "2.0",
745-
method: "initialize",
746-
params: {
747-
protocolVersion: LATEST_PROTOCOL_VERSION,
748-
capabilities: {},
749-
clientInfo: { name: "opencode-debug", version: InstallationVersion },
750-
},
751-
id: 1,
752-
}),
753-
})
754-
755-
spinner.stop(`HTTP response: ${response.status} ${response.statusText}`)
756-
757-
// Check for WWW-Authenticate header
758-
const wwwAuth = response.headers.get("www-authenticate")
759-
if (wwwAuth) {
760-
prompts.log.info(`WWW-Authenticate: ${wwwAuth}`)
761-
}
762-
763-
if (response.status === 401) {
764-
prompts.log.info("Initial unauthenticated check returned 401, so this server requires OAuth")
765-
766-
// Try to discover OAuth metadata
767-
const oauthConfig = typeof serverConfig.oauth === "object" ? serverConfig.oauth : undefined
768-
const authProvider = new McpOAuthProvider(
769-
serverName,
770-
serverConfig.url,
771-
{
772-
clientId: oauthConfig?.clientId,
773-
clientSecret: oauthConfig?.clientSecret,
774-
scope: oauthConfig?.scope,
775-
redirectUri: oauthConfig?.redirectUri,
776-
},
777-
{
778-
onRedirect: async () => {},
779-
},
780-
auth,
781-
)
782-
783-
prompts.log.info("Testing OAuth flow (without completing authorization)...")
784-
785-
// Try creating transport with auth provider to trigger discovery
786-
const transport = new StreamableHTTPClientTransport(new URL(serverConfig.url), {
787-
authProvider,
788-
requestInit: serverConfig.headers ? { headers: serverConfig.headers } : undefined,
789-
})
747+
},
748+
auth,
749+
)
750+
const transport = new StreamableHTTPClientTransport(new URL(serverConfig.url), {
751+
authProvider,
752+
requestInit: serverConfig.headers ? { headers: serverConfig.headers } : undefined,
753+
})
754+
const client = new Client({ name: "opencode-debug", version: InstallationVersion }, CLIENT_OPTIONS)
790755

791-
try {
792-
const client = new Client({
793-
name: "opencode-debug",
794-
version: InstallationVersion,
795-
})
796-
await client.connect(transport)
797-
prompts.log.success("Connection successful (already authenticated)")
798-
await client.close()
799-
} catch (error) {
800-
if (error instanceof UnauthorizedError) {
801-
prompts.log.info(`OAuth flow triggered: ${error.message}`)
802-
803-
// Check if dynamic registration would be attempted
804-
const clientInfo = await authProvider.clientInformation()
805-
if (clientInfo) {
806-
prompts.log.info(`Client ID available: ${clientInfo.client_id}`)
807-
} else {
808-
prompts.log.info("No client ID - dynamic registration will be attempted")
809-
}
810-
} else {
811-
prompts.log.error(`Connection error: ${error instanceof Error ? error.message : String(error)}`)
812-
}
813-
}
814-
} else if (response.status >= 200 && response.status < 300) {
815-
prompts.log.success("Server responded successfully (no auth required or already authenticated)")
816-
const body = await response.text()
817-
try {
818-
const json = JSON.parse(body)
819-
if (json.result?.serverInfo) {
820-
prompts.log.info(`Server info: ${JSON.stringify(json.result.serverInfo)}`)
821-
}
822-
} catch {
823-
// Not JSON, ignore
824-
}
756+
try {
757+
await client.connect(transport)
758+
spinner.stop("SDK connection successful")
759+
prompts.log.success(
760+
`Connected using MCP ${client.getNegotiatedProtocolVersion() ?? "unknown"} (${client.getProtocolEra() ?? "unknown"})`,
761+
)
762+
const serverInfo = client.getServerVersion()
763+
if (serverInfo) prompts.log.info(`Server info: ${JSON.stringify(serverInfo)}`)
764+
} catch (error) {
765+
if (error instanceof UnauthorizedError) {
766+
spinner.stop("OAuth required")
767+
prompts.log.info(`OAuth flow triggered: ${error.message}`)
768+
if (authorizationUrl) prompts.log.info(`Authorization URL: ${authorizationUrl}`)
769+
const clientInfo = await authProvider.clientInformation()
770+
if (clientInfo) prompts.log.info(`Client ID available: ${clientInfo.client_id}`)
771+
if (!clientInfo) prompts.log.info("No client ID - dynamic registration will be attempted")
825772
} else {
826-
prompts.log.warn(`Unexpected status: ${response.status}`)
827-
const body = await response.text().catch(() => "")
828-
if (body) {
829-
prompts.log.info(`Response body: ${body.substring(0, 500)}`)
830-
}
773+
spinner.stop("Connection failed", 1)
774+
prompts.log.error(`Error: ${error instanceof Error ? error.message : String(error)}`)
831775
}
832-
} catch (error) {
833-
spinner.stop("Connection failed", 1)
834-
prompts.log.error(`Error: ${error instanceof Error ? error.message : String(error)}`)
776+
} finally {
777+
await client.close().catch(() => {})
835778
}
836779

837780
prompts.outro("Debug complete")

0 commit comments

Comments
 (0)