Skip to content

Commit e261f25

Browse files
committed
chore: sync upstream to v1.18.9
Upstream changes: - MCP SDK migration: @modelcontextprotocol/client (beta) -> @modelcontextprotocol/sdk 1.29.0 - OAuth flow simplified (iss parameter removed from callback/finishAuth) - McpCatalog: paginate utility, tolerant outputSchema validation, convertTool signature changed - McpOAuthProvider: simplified clientInformation/saveClientInformation - Version bumps across all packages (1.18.8 -> 1.18.9) Fork handling: - Removed re-added deleted deps (@octokit/*, @openauthjs/*, @gitlab/*, etc.) - Deleted re-added removed packages (app, desktop, publish.yml, sdks/vscode, nix, openapi.json) - Added @modelcontextprotocol/sdk to replace @modelcontextprotocol/client - Updated PLAN.md baseline to v1.18.9 - PLAN/MERGE reviewed: no deviation list changes needed (MCP changes auto-merged)
2 parents d78d989 + 03c9ec6 commit e261f25

42 files changed

Lines changed: 2397 additions & 1690 deletions

Some content is hidden

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

PLAN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ opencode-x 是 [anomalyco/opencode](https://github.com/anomalyco/opencode) 的
3434

3535
## 当前状态
3636

37-
- **上游基线**`v1.18.8`(sync 轨迹:v1.18.2 → v1.18.4 → v1.18.6 → v1.18.7 → v1.18.8)
37+
- **上游基线**`v1.18.9`(sync 轨迹:v1.18.2 → v1.18.4 → v1.18.6 → v1.18.7 → v1.18.8 → v1.18.9
3838
- **包规模**:12 个包(11 个功能包 + sdk),原生模块(natives/)已全部删除,grep 跟随上游使用 ripgrep
3939
- **裁剪工程(Batch 0–3)**:✅ 全部完成
4040
- **TUI 审计打磨(四批 23 轮)**:✅ 全部完成

bun.lock

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

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
"@types/node": "catalog:"
112112
},
113113
"patchedDependencies": {
114+
"@dnd-kit/dom@0.5.0": "patches/@dnd-kit%2Fdom@0.5.0.patch",
114115
"@ff-labs/fff-bun@0.9.3": "patches/@ff-labs%2Ffff-bun@0.9.3.patch",
115116
"@npmcli/agent@4.0.2": "patches/@npmcli%2Fagent@4.0.2.patch",
116117
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch",
@@ -122,8 +123,8 @@
122123
"pacote@21.5.0": "patches/pacote@21.5.0.patch",
123124
"@ai-sdk/google@3.0.73": "patches/@ai-sdk%2Fgoogle@3.0.73.patch",
124125
"@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",
125127
"effect@4.0.0-beta.83": "patches/effect@4.0.0-beta.83.patch",
126-
"@tanstack/virtual-core@3.17.3": "patches/@tanstack%2Fvirtual-core@3.17.3.patch",
127-
"@modelcontextprotocol/client@2.0.0-beta.5": "patches/@modelcontextprotocol%2Fclient@2.0.0-beta.5.patch"
128+
"@tanstack/virtual-core@3.17.3": "patches/@tanstack%2Fvirtual-core@3.17.3.patch"
128129
}
129130
}

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.8",
4+
"version": "1.18.9",
55
"description": "Effect-native confined code execution over schema-described tools",
66
"private": true,
77
"type": "module",

packages/core/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.8",
3+
"version": "1.18.9",
44
"name": "@opencode-ai/core",
55
"type": "module",
66
"license": "MIT",

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.8",
3+
"version": "1.18.9",
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.8",
3+
"version": "1.18.9",
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: 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.8",
3+
"version": "1.18.9",
44
"name": "@opencode-ai/llm",
55
"type": "module",
66
"license": "MIT",

packages/opencode/package.json

Lines changed: 2 additions & 3 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.8",
3+
"version": "1.18.9",
44
"name": "opencode",
55
"type": "module",
66
"license": "MIT",
@@ -30,7 +30,6 @@
3030
},
3131
"devDependencies": {
3232
"@babel/core": "7.28.4",
33-
"@modelcontextprotocol/server": "2.0.0-beta.5",
3433
"@opencode-ai/core": "workspace:*",
3534
"@opencode-ai/http-recorder": "workspace:*",
3635
"@standard-schema/spec": "1.0.0",
@@ -74,7 +73,7 @@
7473
"@clack/prompts": "1.0.0-alpha.1",
7574
"@effect/platform-node": "catalog:",
7675
"@ff-labs/fff-bun": "0.9.4",
77-
"@modelcontextprotocol/client": "2.0.0-beta.5",
76+
"@modelcontextprotocol/sdk": "1.29.0",
7877
"@opencode-ai/codemode": "workspace:*",
7978
"@opencode-ai/llm": "workspace:*",
8079
"@opencode-ai/plugin": "workspace:*",

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

Lines changed: 102 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ 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, StreamableHTTPClientTransport, UnauthorizedError } from "@modelcontextprotocol/client"
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"
69
import * as prompts from "@clack/prompts"
710
import { UI } from "../ui"
8-
import { CLIENT_OPTIONS, MCP } from "../../mcp"
11+
import { MCP } from "../../mcp"
912
import { McpAuth } from "../../mcp/auth"
1013
import { McpOAuthProvider } from "../../mcp/oauth-provider"
1114
import { Config } from "@/config/config"
@@ -728,53 +731,107 @@ export const McpDebugCommand = effectCmd({
728731
const spinner = prompts.spinner()
729732
spinner.start("Testing connection...")
730733

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
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",
746742
},
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)
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+
})
755754

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")
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+
})
790+
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+
}
772825
} else {
773-
spinner.stop("Connection failed", 1)
774-
prompts.log.error(`Error: ${error instanceof Error ? error.message : String(error)}`)
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+
}
775831
}
776-
} finally {
777-
await client.close().catch(() => {})
832+
} catch (error) {
833+
spinner.stop("Connection failed", 1)
834+
prompts.log.error(`Error: ${error instanceof Error ? error.message : String(error)}`)
778835
}
779836

780837
prompts.outro("Debug complete")

0 commit comments

Comments
 (0)