feat(opencode): support non-interactive MCP add (#31054)

This commit is contained in:
Aiden Cline
2026-06-05 21:21:20 -05:00
committed by GitHub
parent 3f0ef9b71c
commit ba57718b05
3 changed files with 151 additions and 5 deletions
+68 -2
View File
@@ -437,13 +437,79 @@ async function addMcpToConfig(name: string, mcpConfig: ConfigMCPV1.Info, configP
}
export const McpAddCommand = effectCmd({
command: "add",
command: "add [name]",
describe: "add an MCP server",
handler: Effect.fn("Cli.mcp.add")(function* () {
builder: (yargs) =>
yargs
.positional("name", {
describe: "name of the MCP server",
type: "string",
})
.option("url", {
describe: "URL for a remote MCP server",
type: "string",
})
.option("env", {
describe: "environment variable for a local MCP server (KEY=VALUE)",
type: "string",
array: true,
})
.option("header", {
describe: "HTTP header for a remote MCP server (KEY=VALUE)",
type: "string",
array: true,
}),
handler: Effect.fn("Cli.mcp.add")(function* (args) {
const maybeCtx = yield* InstanceRef
if (!maybeCtx) return yield* Effect.die("InstanceRef not provided")
const ctx = maybeCtx
yield* Effect.promise(async () => {
const command = args["--"] ?? []
if (!args.name && (args.url || args.env?.length || args.header?.length || command.length)) {
throw new Error("A server name is required for non-interactive MCP configuration")
}
if (args.name) {
if (!!args.url === !!command.length) {
throw new Error("Provide either --url <url> or a command after --")
}
if (args.url && !URL.canParse(args.url)) {
throw new Error(`Invalid URL: ${args.url}`)
}
if (args.url && args.env?.length) {
throw new Error("--env is only valid for local MCP servers")
}
if (command.length && args.header?.length) {
throw new Error("--header is only valid for remote MCP servers")
}
const entries = (values: string[], kind: string) =>
Object.fromEntries(
values.map((entry) => {
const index = entry.indexOf("=")
if (index < 1) throw new Error(`Invalid ${kind}: ${entry}. Expected KEY=VALUE`)
return [entry.slice(0, index), entry.slice(index + 1)]
}),
)
const environment = entries(args.env ?? [], "environment variable")
const headers = entries(args.header ?? [], "HTTP header")
const mcpConfig: ConfigMCPV1.Info = args.url
? {
type: "remote",
url: args.url,
...(Object.keys(headers).length ? { headers } : {}),
}
: {
type: "local",
command,
...(Object.keys(environment).length ? { environment } : {}),
}
const configPath = await resolveConfigPath(Global.Path.config, true)
await addMcpToConfig(args.name, mcpConfig, configPath)
prompts.log.success(`MCP server "${args.name}" added to ${configPath}`)
return
}
UI.empty()
prompts.intro("Add MCP server")