Skip to content

Commit 100d621

Browse files
committed
more graceful mcp failures
1 parent f0e19a6 commit 100d621

4 files changed

Lines changed: 64 additions & 6 deletions

File tree

opencode.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
{
2-
"$schema": "https://opencode.ai/config.json"
2+
"$schema": "https://opencode.ai/config.json",
3+
"mcp": {
4+
"sentry": {
5+
"type": "remote",
6+
"url": "https://mcp.sentry.dev/sse"
7+
}
8+
}
39
}

packages/opencode/src/cli/error.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Config } from "../config/config"
2+
import { MCP } from "../mcp"
23

34
export function FormatError(input: unknown) {
5+
if (MCP.Failed.isInstance(input))
6+
return `MCP server "${input.data.name}" failed. Note, opencode does not support MCP authentication yet.`
47
if (Config.JsonError.isInstance(input))
58
return `Config file at ${input.data.path} is not valid JSON`
69
if (Config.InvalidError.isInstance(input))

packages/opencode/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import { Bus } from "./bus"
2020
import { Config } from "./config/config"
2121
import { NamedError } from "./util/error"
2222
import { FormatError } from "./cli/error"
23+
import { MCP } from "./mcp"
24+
25+
const cancel = new AbortController()
2326

2427
const cli = yargs(hideBin(process.argv))
2528
.scriptName("opencode")
@@ -72,6 +75,7 @@ const cli = yargs(hideBin(process.argv))
7275
}
7376
const proc = Bun.spawn({
7477
cmd: [...cmd, ...process.argv.slice(2)],
78+
signal: cancel.signal,
7579
cwd,
7680
stdout: "inherit",
7781
stderr: "inherit",
@@ -157,3 +161,5 @@ try {
157161
"Unexpected error, check log file at " + Log.file() + " for more details",
158162
)
159163
}
164+
165+
cancel.abort()

packages/opencode/src/mcp/index.ts

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,22 @@ import { experimental_createMCPClient, type Tool } from "ai"
22
import { Experimental_StdioMCPTransport } from "ai/mcp-stdio"
33
import { App } from "../app/app"
44
import { Config } from "../config/config"
5+
import { Log } from "../util/log"
6+
import { NamedError } from "../util/error"
7+
import { z } from "zod"
8+
import { Session } from "../session"
9+
import { Bus } from "../bus"
510

611
export namespace MCP {
12+
const log = Log.create({ service: "mcp" })
13+
14+
export const Failed = NamedError.create(
15+
"MCPFailed",
16+
z.object({
17+
name: z.string(),
18+
}),
19+
)
20+
721
const state = App.state(
822
"mcp",
923
async () => {
@@ -12,27 +26,56 @@ export namespace MCP {
1226
[name: string]: Awaited<ReturnType<typeof experimental_createMCPClient>>
1327
} = {}
1428
for (const [key, mcp] of Object.entries(cfg.mcp ?? {})) {
29+
log.info("found", { key, type: mcp.type })
1530
if (mcp.type === "remote") {
16-
clients[key] = await experimental_createMCPClient({
31+
const client = await experimental_createMCPClient({
1732
name: key,
1833
transport: {
1934
type: "sse",
2035
url: mcp.url,
2136
},
22-
})
37+
}).catch(() => {})
38+
if (!client) {
39+
Bus.publish(Session.Event.Error, {
40+
error: {
41+
name: "UnknownError",
42+
data: {
43+
message: `MCP server ${key} failed to start`,
44+
},
45+
},
46+
})
47+
continue
48+
}
49+
clients[key] = client
2350
}
2451

2552
if (mcp.type === "local") {
2653
const [cmd, ...args] = mcp.command
27-
clients[key] = await experimental_createMCPClient({
54+
const client = await experimental_createMCPClient({
2855
name: key,
2956
transport: new Experimental_StdioMCPTransport({
3057
stderr: "ignore",
3158
command: cmd,
3259
args,
33-
env: mcp.environment,
60+
env: {
61+
...process.env,
62+
...(cmd === "opencode" ? { BUN_BE_BUN: "1" } : {}),
63+
...mcp.environment,
64+
},
3465
}),
35-
})
66+
}).catch(() => {})
67+
if (!client) {
68+
Bus.publish(Session.Event.Error, {
69+
error: {
70+
name: "UnknownError",
71+
data: {
72+
message: `MCP server ${key} failed to start`,
73+
},
74+
},
75+
})
76+
continue
77+
}
78+
clients[key] = client
3679
}
3780
}
3881

0 commit comments

Comments
 (0)