@bastani/atomic 0.9.26-alpha.2 → 0.9.26-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/builtin/intercom/broker/spawn.ts +2 -0
- package/dist/builtin/intercom/index.bundle.mjs +1 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/native-client-licenses/NOTICE +2 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts.map +1 -1
- package/dist/extensions/mcp/cli.js +4 -1
- package/dist/extensions/mcp/cli.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/callback.d.ts +4 -2
- package/dist/extensions/mcp/client/oauth/callback.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/callback.js +12 -7
- package/dist/extensions/mcp/client/oauth/callback.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.d.ts +7 -1
- package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.js +20 -21
- package/dist/extensions/mcp/client/oauth/flow.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/index.d.ts +1 -1
- package/dist/extensions/mcp/client/oauth/index.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/index.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/provider.d.ts +5 -2
- package/dist/extensions/mcp/client/oauth/provider.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/provider.js +2 -0
- package/dist/extensions/mcp/client/oauth/provider.js.map +1 -1
- package/dist/extensions/mcp/config.d.ts +16 -4
- package/dist/extensions/mcp/config.d.ts.map +1 -1
- package/dist/extensions/mcp/config.js +50 -11
- package/dist/extensions/mcp/config.js.map +1 -1
- package/dist/extensions/mcp/index.d.ts +4 -1
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +80 -46
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/oauth.d.ts.map +1 -1
- package/dist/extensions/mcp/oauth.js +9 -5
- package/dist/extensions/mcp/oauth.js.map +1 -1
- package/dist/extensions/mcp/ui.d.ts.map +1 -1
- package/dist/extensions/mcp/ui.js +8 -4
- package/dist/extensions/mcp/ui.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/chat-input-actions.js.map +1 -1
- package/dist/modes/interactive/components/auth-url.d.ts +10 -0
- package/dist/modes/interactive/components/auth-url.d.ts.map +1 -0
- package/dist/modes/interactive/components/auth-url.js +37 -0
- package/dist/modes/interactive/components/auth-url.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +10 -5
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.js +0 -1
- package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -11
- package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -2
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +0 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +0 -5
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +0 -2
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-tui.js.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.js +38 -2
- package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +10 -0
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +10 -0
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/interactive-engine/remote-component.d.ts +2 -1
- package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-component.js +23 -1
- package/dist/modes/interactive-engine/remote-component.js.map +1 -1
- package/docs/keybindings.md +3 -0
- package/docs/mcp-servers.md +13 -1
- package/docs/providers.md +2 -0
- package/npm-shrinkwrap.json +55 -33
- package/package.json +4 -3
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
- package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
- package/dist/modes/interactive/components/daxnuts.js +0 -140
- package/dist/modes/interactive/components/daxnuts.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/extensions/mcp/cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `pi mcp`: add, remove, and check MCP servers and sign in to them outside a session. Agents run it\n * through bash to configure servers, verify an `mcp.json` they wrote, and start an OAuth sign-in;\n * the user only approves access in the browser. Running sessions pick up new credentials on their\n * next turn.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME } from \"../../config.js\";\nimport { validateMcpServerConfig } from \"../../core/mcp-servers.ts\";\nimport { ProjectTrustStore } from \"../../core/trust-manager.ts\";\nimport { openBrowser } from \"../../utils/open-browser.ts\";\nimport {\n\taddMcpServerConfig,\n\tgetMcpToolExposure,\n\ttype LoadedMcpConfig,\n\tloadMcpConfig,\n\ttype McpServerEntry,\n\tremoveMcpServerConfig,\n} from \"./config.ts\";\nimport {\n\tcreateDefaultTransport,\n\tMcpOAuthCredentialStore,\n\tMcpServerConnection,\n\tMcpServerLog,\n\tMcpSignInCancelledError,\n\tsignInMcpServer,\n} from \"./runtime.ts\";\n\nconst HELP = `${chalk.bold(\"Usage:\")}\n ${APP_NAME} mcp add <server> [options] -- <command> [args...]\n ${APP_NAME} mcp add <server> [options] --url <url>\n ${APP_NAME} mcp remove <server> [-l]\n ${APP_NAME} mcp list [--json]\n ${APP_NAME} mcp login <server> [--timeout <seconds>]\n ${APP_NAME} mcp logout <server>\n\nConfigure and check MCP servers and sign in to OAuth servers without starting a session.\nReads ~/${CONFIG_DIR_NAME}/agent/mcp.json and, in trusted projects, ${CONFIG_DIR_NAME}/mcp.json.\n\nCommands:\n add <server> Add or replace a server in mcp.json\n remove <server> Remove a server from mcp.json\n list Show state, tools, and errors (exits 1 on failure)\n login <server> Sign in through the browser\n logout <server> Delete the stored OAuth credentials\n\nOptions for add and remove:\n -l, --local Use ${CONFIG_DIR_NAME}/mcp.json in the current project instead of the global file\n\nOptions for add:\n --url <url> Streamable HTTP server URL (instead of a command)\n --env <KEY=VALUE> Environment variable for a stdio server (repeatable)\n --cwd <dir> Working directory for a stdio server\n --header <KEY=VALUE> HTTP header (repeatable)\n --bearer-token-env-var <NAME>\n Send \"Authorization: Bearer \\${NAME}\"\n --oauth-client-id <id> Pre-registered OAuth client id\n --oauth-client-secret <secret>\n OAuth client secret (may be \\${NAME} or !command)\n --oauth-callback-port <port>\n Fixed OAuth callback port\n --oauth-client-name <name>\n Client name sent when registering with the OAuth server\n --exposure <mode> codemode (default), deferred, direct, or hidden\n --description <text> What the server offers, shown in the system prompt\n\nOther options:\n --json Print the list as JSON\n --timeout <seconds> How long login waits for the browser (default: 300)`;\n\nconst HELP_HINT = chalk.dim(`Use \"${APP_NAME} mcp --help\" for usage.`);\n\nconst DEFAULT_LOGIN_TIMEOUT_SECONDS = 300;\n\nexport interface McpCommandOptions {\n\tcwd: string;\n\tagentDir: string;\n\t/** Defaults to `mcp-auth.json` in the agent directory. */\n\tcredentials?: McpOAuthCredentialStore;\n\t/** Defaults to the platform browser. */\n\topenUrl?: (url: string) => void;\n\t/** Defaults to console output. */\n\tlog?: (line: string) => void;\n\terror?: (line: string) => void;\n}\n\ninterface ServerReport {\n\tname: string;\n\tscope: string;\n\tsource: string;\n\tenabled: boolean;\n\texposure: string;\n\ttransport: string;\n\tstate: string;\n\ttools: string[];\n\t/** Tools whose exposure differs from the server's, from `toolExposure`. */\n\ttoolExposure?: Record<string, string>;\n\tresources?: number;\n\tresourceTemplates?: number;\n\terror?: string;\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction describeTransport(entry: McpServerEntry): string {\n\tconst { config } = entry;\n\treturn \"url\" in config ? config.url : [config.command, ...(config.args ?? [])].join(\" \");\n}\n\nfunction createConnection(entry: McpServerEntry, options: McpCommandOptions, credentials: McpOAuthCredentialStore) {\n\treturn new McpServerConnection({\n\t\tentry,\n\t\tcwd: options.cwd,\n\t\tcreateTransport: createDefaultTransport,\n\t\tcredentials,\n\t\tlog: new McpServerLog(join(options.agentDir, \"mcp.log\")),\n\t\tonTools: () => {},\n\t});\n}\n\n/** Short spellings of options. `-l`/`--local` match `pi install`. */\nconst OPTION_ALIASES = new Map([[\"-l\", \"--local\"]]);\n\ninterface ParsedOptions {\n\tpositional: string[];\n\tvalues: Map<string, string | true>;\n\t/** Values of `list` options, in order. */\n\tlists: Map<string, string[]>;\n}\n\n/**\n * Parse `--name value` options; returns undefined and reports unknown ones. `--` ends the options,\n * as does reaching `maxPositionals` positional arguments: the remaining arguments are positional,\n * so a command's own options (`add <server> <command> --flag`) are passed through.\n */\nfunction parseOptions(\n\targs: string[],\n\tknown: Record<string, \"flag\" | \"value\" | \"list\">,\n\terror: (line: string) => void,\n\tmaxPositionals = Number.POSITIVE_INFINITY,\n): ParsedOptions | undefined {\n\tconst positional: string[] = [];\n\tconst values = new Map<string, string | true>();\n\tconst lists = new Map<string, string[]>();\n\tfor (let index = 0; index < args.length; index++) {\n\t\tconst arg = OPTION_ALIASES.get(args[index]) ?? args[index];\n\t\tif (arg === \"--\" || positional.length >= maxPositionals) {\n\t\t\tpositional.push(...args.slice(arg === \"--\" ? index + 1 : index));\n\t\t\tbreak;\n\t\t}\n\t\tif (!arg.startsWith(\"--\")) {\n\t\t\tpositional.push(arg);\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = arg.slice(2);\n\t\tconst kind = known[name];\n\t\tif (!kind) {\n\t\t\terror(`Unknown option ${arg}.\\n${HELP_HINT}`);\n\t\t\treturn undefined;\n\t\t}\n\t\tif (kind === \"flag\") {\n\t\t\tvalues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tconst value = args[++index];\n\t\tif (value === undefined) {\n\t\t\terror(`${arg} needs a value.`);\n\t\t\treturn undefined;\n\t\t}\n\t\tif (kind === \"list\") lists.set(name, [...(lists.get(name) ?? []), value]);\n\t\telse values.set(name, value);\n\t}\n\treturn { positional, values, lists };\n}\n\n/** Run `pi mcp <args>` and return the exit code. */\nexport async function runMcpCommand(args: string[], options: McpCommandOptions): Promise<number> {\n\tconst log = options.log ?? ((line: string) => console.log(line));\n\tconst error = options.error ?? ((line: string) => console.error(line));\n\tconst [command, ...rest] = args;\n\tif (command === undefined || command === \"help\" || args.includes(\"--help\") || args.includes(\"-h\")) {\n\t\tlog(HELP);\n\t\treturn 0;\n\t}\n\n\tconst projectConfig = join(options.cwd, CONFIG_DIR_NAME, \"mcp.json\");\n\tif (command === \"add\" || command === \"remove\") {\n\t\treturn command === \"add\"\n\t\t\t? add(rest, projectConfig, options, log, error)\n\t\t\t: remove(rest, projectConfig, options, log, error);\n\t}\n\tconst projectTrusted = new ProjectTrustStore(options.agentDir).get(options.cwd) === true;\n\tconst loaded = loadMcpConfig({ agentDir: options.agentDir, cwd: options.cwd, projectTrusted });\n\tconst untrustedNote =\n\t\t!projectTrusted && existsSync(projectConfig)\n\t\t\t? `${projectConfig} is ignored because the project is not trusted. Start ${APP_NAME} in the project to trust it.`\n\t\t\t: undefined;\n\tconst credentials = options.credentials ?? new McpOAuthCredentialStore();\n\n\tswitch (command) {\n\t\tcase \"list\": {\n\t\t\tconst parsed = parseOptions(rest, { json: \"flag\" }, error);\n\t\t\tif (!parsed) return 1;\n\t\t\tif (parsed.positional.length > 0) {\n\t\t\t\terror(`Usage: ${APP_NAME} mcp list [--json]\\n${HELP_HINT}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn list(loaded, parsed.values.has(\"json\"), untrustedNote, options, credentials, log);\n\t\t}\n\t\tcase \"login\":\n\t\tcase \"logout\": {\n\t\t\tconst parsed = parseOptions(rest, command === \"login\" ? { timeout: \"value\" } : {}, error);\n\t\t\tif (!parsed) return 1;\n\t\t\tconst [name, ...extra] = parsed.positional;\n\t\t\tif (!name || extra.length > 0) {\n\t\t\t\terror(`Usage: ${APP_NAME} mcp ${command} <server>\\n${HELP_HINT}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tconst entry = loaded.servers.find((server) => server.name === name);\n\t\t\tif (!entry) {\n\t\t\t\terror(\n\t\t\t\t\t`No MCP server named \"${name}\".${untrustedNote ? ` ${untrustedNote}` : \"\"} Configured: ${loaded.servers.map((server) => server.name).join(\", \") || \"none\"}.`,\n\t\t\t\t);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tconst connection = createConnection(entry, options, credentials);\n\t\t\tconst url = connection.oauthUrl;\n\t\t\tif (!url) {\n\t\t\t\terror(`MCP server \"${name}\" does not use OAuth. Only HTTP servers without an Authorization header do.`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (command === \"logout\") {\n\t\t\t\tconst removed = await credentials.removeAsync(name, url);\n\t\t\t\tlog(removed ? `Signed out of MCP server \"${name}\".` : `No stored credentials for MCP server \"${name}\".`);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tconst timeout = Number(parsed.values.get(\"timeout\") ?? DEFAULT_LOGIN_TIMEOUT_SECONDS);\n\t\t\tif (!Number.isFinite(timeout) || timeout <= 0) {\n\t\t\t\terror(\"--timeout must be a positive number of seconds.\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn await login(entry, connection, url, timeout * 1000, options, credentials, log, error);\n\t\t\t} finally {\n\t\t\t\tawait connection.close();\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\terror(`Unknown mcp command \"${command}\".\\n${HELP_HINT}`);\n\t\t\treturn 1;\n\t}\n}\n\n/** Parse `KEY=VALUE` pairs of a repeatable option into a record. */\nfunction parsePairs(option: string, pairs: string[] | undefined, error: (line: string) => void) {\n\tif (!pairs) return {};\n\tconst record: Record<string, string> = {};\n\tfor (const pair of pairs) {\n\t\tconst separator = pair.indexOf(\"=\");\n\t\tif (separator <= 0) {\n\t\t\terror(`--${option} expects KEY=VALUE, got \"${pair}\".`);\n\t\t\treturn undefined;\n\t\t}\n\t\trecord[pair.slice(0, separator)] = pair.slice(separator + 1);\n\t}\n\treturn record;\n}\n\nfunction add(\n\targs: string[],\n\tprojectConfig: string,\n\toptions: McpCommandOptions,\n\tlog: (line: string) => void,\n\terror: (line: string) => void,\n): number {\n\tconst usage = `Usage: ${APP_NAME} mcp add <server> [options] (--url <url> | -- <command> [args...])\\n${HELP_HINT}`;\n\tconst parsed = parseOptions(\n\t\targs,\n\t\t{\n\t\t\tlocal: \"flag\",\n\t\t\turl: \"value\",\n\t\t\tenv: \"list\",\n\t\t\tcwd: \"value\",\n\t\t\theader: \"list\",\n\t\t\t\"bearer-token-env-var\": \"value\",\n\t\t\t\"oauth-client-id\": \"value\",\n\t\t\t\"oauth-client-secret\": \"value\",\n\t\t\t\"oauth-callback-port\": \"value\",\n\t\t\t\"oauth-client-name\": \"value\",\n\t\t\texposure: \"value\",\n\t\t\tdescription: \"value\",\n\t\t},\n\t\terror,\n\t\t2,\n\t);\n\tif (!parsed) return 1;\n\tconst { positional, values, lists } = parsed;\n\tconst [name, ...command] = positional;\n\tconst url = values.get(\"url\");\n\tif (!name || (url === undefined) === (command.length === 0)) {\n\t\terror(usage);\n\t\treturn 1;\n\t}\n\tconst value = (option: string) => {\n\t\tconst found = values.get(option);\n\t\treturn typeof found === \"string\" ? found : undefined;\n\t};\n\tconst exposure = value(\"exposure\");\n\tconst httpOnly = [\n\t\t\"header\",\n\t\t\"bearer-token-env-var\",\n\t\t\"oauth-client-id\",\n\t\t\"oauth-client-secret\",\n\t\t\"oauth-callback-port\",\n\t\t\"oauth-client-name\",\n\t];\n\tconst stdioOnly = [\"env\", \"cwd\"];\n\tconst misplaced = (url === undefined ? httpOnly : stdioOnly).find(\n\t\t(option) => values.has(option) || lists.has(option),\n\t);\n\tif (misplaced) {\n\t\terror(`--${misplaced} only applies to ${url === undefined ? \"HTTP servers (--url)\" : \"stdio servers\"}.`);\n\t\treturn 1;\n\t}\n\n\tlet config: Record<string, unknown>;\n\tif (typeof url === \"string\") {\n\t\tconst headers = parsePairs(\"header\", lists.get(\"header\"), error);\n\t\tif (!headers) return 1;\n\t\tconst bearer = value(\"bearer-token-env-var\");\n\t\tif (bearer !== undefined) headers.Authorization = `Bearer \\${${bearer}}`;\n\t\tconst port = value(\"oauth-callback-port\");\n\t\tconst oauth = {\n\t\t\t...(value(\"oauth-client-id\") === undefined ? {} : { clientId: value(\"oauth-client-id\") }),\n\t\t\t...(value(\"oauth-client-secret\") === undefined ? {} : { clientSecret: value(\"oauth-client-secret\") }),\n\t\t\t...(port === undefined ? {} : { callbackPort: Number(port) }),\n\t\t\t...(value(\"oauth-client-name\") === undefined ? {} : { clientName: value(\"oauth-client-name\") }),\n\t\t};\n\t\tconfig = {\n\t\t\turl,\n\t\t\t...(Object.keys(headers).length > 0 ? { headers } : {}),\n\t\t\t...(Object.keys(oauth).length > 0 ? { oauth } : {}),\n\t\t};\n\t} else {\n\t\tconst env = parsePairs(\"env\", lists.get(\"env\"), error);\n\t\tif (!env) return 1;\n\t\tconst [executable, ...commandArgs] = command;\n\t\tconfig = {\n\t\t\tcommand: executable,\n\t\t\t...(commandArgs.length > 0 ? { args: commandArgs } : {}),\n\t\t\t...(Object.keys(env).length > 0 ? { env } : {}),\n\t\t\t...(value(\"cwd\") === undefined ? {} : { cwd: value(\"cwd\") }),\n\t\t};\n\t}\n\tif (exposure !== undefined) config.exposure = exposure;\n\tconst description = value(\"description\");\n\tif (description !== undefined) config.description = description;\n\tconst validated = validateMcpServerConfig(name, config);\n\tif (typeof validated === \"string\") {\n\t\terror(validated);\n\t\treturn 1;\n\t}\n\n\tconst project = values.has(\"local\");\n\tconst path = project ? projectConfig : join(options.agentDir, \"mcp.json\");\n\tconst scope = project ? \"project\" : \"global\";\n\tlet replaced: boolean;\n\ttry {\n\t\treplaced = addMcpServerConfig(path, name, validated);\n\t} catch (addError) {\n\t\terror(`Could not update ${path}: ${errorMessage(addError)}`);\n\t\treturn 1;\n\t}\n\tlog(`${replaced ? \"Replaced\" : \"Added\"} ${scope} MCP server \"${name}\" in ${path}.`);\n\tif (project && new ProjectTrustStore(options.agentDir).get(options.cwd) !== true) {\n\t\tlog(`The project is not trusted, so ${path} is ignored until you start ${APP_NAME} in the project and trust it.`);\n\t}\n\t// HTTP servers without an Authorization header may use OAuth.\n\tconst mayNeedSignIn =\n\t\t\"url\" in validated &&\n\t\t!Object.keys(validated.headers ?? {}).some((header) => header.toLowerCase() === \"authorization\");\n\tlog(\n\t\t`Check it with: ${APP_NAME} mcp list${mayNeedSignIn ? `. If it requires sign-in: ${APP_NAME} mcp login ${name}` : \"\"}`,\n\t);\n\treturn 0;\n}\n\nfunction remove(\n\targs: string[],\n\tprojectConfig: string,\n\toptions: McpCommandOptions,\n\tlog: (line: string) => void,\n\terror: (line: string) => void,\n): number {\n\tconst parsed = parseOptions(args, { local: \"flag\" }, error);\n\tif (!parsed) return 1;\n\tconst [name, ...extra] = parsed.positional;\n\tif (!name || extra.length > 0) {\n\t\terror(`Usage: ${APP_NAME} mcp remove <server> [-l]\\n${HELP_HINT}`);\n\t\treturn 1;\n\t}\n\tconst project = parsed.values.has(\"local\");\n\tconst globalConfig = join(options.agentDir, \"mcp.json\");\n\tconst path = project ? projectConfig : globalConfig;\n\tconst scope = project ? \"project\" : \"global\";\n\tlet removed: boolean;\n\ttry {\n\t\tremoved = removeMcpServerConfig(path, name);\n\t} catch (removeError) {\n\t\terror(`Could not update ${path}: ${errorMessage(removeError)}`);\n\t\treturn 1;\n\t}\n\tif (removed) {\n\t\tlog(`Removed ${scope} MCP server \"${name}\" from ${path}.`);\n\t\treturn 0;\n\t}\n\tconst other = loadMcpConfig({ agentDir: options.agentDir, cwd: options.cwd, projectTrusted: true }).servers.find(\n\t\t(server) => server.name === name && server.scope !== scope,\n\t);\n\terror(\n\t\t`No ${scope} MCP server named \"${name}\" in ${path}.${other ? ` It is defined in ${other.source}${other.scope === \"project\" ? \"; use --local\" : \"; omit --local\"}.` : \"\"}`,\n\t);\n\treturn 1;\n}\n\nasync function list(\n\tloaded: LoadedMcpConfig,\n\tjson: boolean,\n\tuntrustedNote: string | undefined,\n\toptions: McpCommandOptions,\n\tcredentials: McpOAuthCredentialStore,\n\tlog: (line: string) => void,\n): Promise<number> {\n\tconst reports = await Promise.all(\n\t\tloaded.servers.map(async (entry): Promise<ServerReport> => {\n\t\t\tconst report: ServerReport = {\n\t\t\t\tname: entry.name,\n\t\t\t\tscope: entry.scope ?? \"global\",\n\t\t\t\tsource: entry.source,\n\t\t\t\tenabled: entry.config.enabled !== false,\n\t\t\t\texposure: entry.config.exposure ?? \"codemode\",\n\t\t\t\ttransport: describeTransport(entry),\n\t\t\t\tstate: \"disabled\",\n\t\t\t\ttools: [],\n\t\t\t};\n\t\t\tif (!report.enabled) return report;\n\t\t\tconst connection = createConnection(entry, options, credentials);\n\t\t\ttry {\n\t\t\t\tawait connection.getClient();\n\t\t\t} catch {\n\t\t\t\t// The connection records the state and error.\n\t\t\t}\n\t\t\treport.state = connection.state;\n\t\t\treport.tools = connection.tools.map((tool) => tool.name);\n\t\t\tconst overrides = connection.tools.flatMap((tool) => {\n\t\t\t\tconst exposure = getMcpToolExposure(entry.config, tool.name);\n\t\t\t\treturn exposure === report.exposure ? [] : [[tool.name, exposure] as const];\n\t\t\t});\n\t\t\tif (overrides.length > 0) report.toolExposure = Object.fromEntries(overrides);\n\t\t\tif (connection.hasResources) {\n\t\t\t\treport.resources = connection.resources.length;\n\t\t\t\treport.resourceTemplates = connection.resourceTemplates.length;\n\t\t\t}\n\t\t\tif (connection.state !== \"connected\" && connection.error) report.error = connection.error;\n\t\t\tawait connection.close();\n\t\t\treturn report;\n\t\t}),\n\t);\n\tconst failed = loaded.errors.length > 0 || reports.some((report) => report.enabled && report.state !== \"connected\");\n\n\tif (json) {\n\t\tlog(\n\t\t\tJSON.stringify(\n\t\t\t\t{ servers: reports, errors: loaded.errors, ...(untrustedNote ? { note: untrustedNote } : {}) },\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t),\n\t\t);\n\t\treturn failed ? 1 : 0;\n\t}\n\tif (reports.length === 0 && loaded.errors.length === 0) {\n\t\tlog(`No MCP servers configured. Add them to ${join(options.agentDir, \"mcp.json\")} or .pi/mcp.json.`);\n\t}\n\tfor (const report of reports) {\n\t\tconst state =\n\t\t\treport.state === \"connected\"\n\t\t\t\t? `connected, ${report.tools.length} tool${report.tools.length === 1 ? \"\" : \"s\"}`\n\t\t\t\t: report.state === \"needs-auth\"\n\t\t\t\t\t? \"needs sign-in\"\n\t\t\t\t\t: report.state;\n\t\tlog(`${report.name}: ${state} (${report.exposure}, ${report.scope})`);\n\t\tlog(` ${report.transport}`);\n\t\tif (report.state === \"needs-auth\") log(` sign in with: ${APP_NAME} mcp login ${report.name}`);\n\t\tif (report.tools.length > 0) {\n\t\t\tconst tools = report.tools.map((tool) => {\n\t\t\t\tconst exposure = report.toolExposure?.[tool];\n\t\t\t\treturn exposure ? `${tool} [${exposure}]` : tool;\n\t\t\t});\n\t\t\tlog(` tools: ${tools.join(\", \")}`);\n\t\t}\n\t\tif (report.resources !== undefined) {\n\t\t\tlog(` resources: ${report.resources}, URI templates: ${report.resourceTemplates ?? 0}`);\n\t\t}\n\t\tif (report.error) log(` ${report.error.split(\"\\n\").join(\"\\n \")}`);\n\t}\n\tfor (const configError of loaded.errors) log(`config error: ${configError}`);\n\tif (untrustedNote) log(untrustedNote);\n\treturn failed ? 1 : 0;\n}\n\nasync function login(\n\tentry: McpServerEntry,\n\tconnection: McpServerConnection,\n\turl: string,\n\ttimeoutMs: number,\n\toptions: McpCommandOptions,\n\tcredentials: McpOAuthCredentialStore,\n\tlog: (line: string) => void,\n\terror: (line: string) => void,\n): Promise<number> {\n\tconst { name } = entry;\n\t// Connecting first answers whether a sign-in is needed and records the server's challenge.\n\ttry {\n\t\tawait connection.getClient();\n\t\tlog(`Already signed in to MCP server \"${name}\" (${connection.tools.length} tools).`);\n\t\treturn 0;\n\t} catch {\n\t\tif (connection.state !== \"needs-auth\") {\n\t\t\terror(`MCP server \"${name}\" failed to connect: ${connection.error ?? \"unknown error\"}`);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tconst openUrl = options.openUrl ?? openBrowser;\n\tconst interactive = process.stdin.isTTY === true && options.openUrl === undefined;\n\ttry {\n\t\tawait signInMcpServer({\n\t\t\tserverUrl: url,\n\t\t\tstore: credentials.forServer(name, url),\n\t\t\tsettings: connection.oauthSettings(),\n\t\t\tchallenge: connection.challenge,\n\t\t\tprompt: {\n\t\t\t\tshowAuthorizationUrl: (authorizationUrl) => {\n\t\t\t\t\tlog(`Sign in to MCP server \"${name}\" in your browser:\\n${authorizationUrl.href}`);\n\t\t\t\t\topenUrl(authorizationUrl.href);\n\t\t\t\t},\n\t\t\t\tpromptForRedirectUrl: (signal) => waitForRedirectUrl(signal, timeoutMs, interactive),\n\t\t\t},\n\t\t});\n\t} catch (signInError) {\n\t\terror(\n\t\t\tsignInError instanceof McpSignInCancelledError\n\t\t\t\t? `Sign-in to MCP server \"${name}\" was cancelled or not completed within ${Math.round(timeoutMs / 1000)} seconds.`\n\t\t\t\t: `Sign-in to MCP server \"${name}\" failed: ${errorMessage(signInError)}`,\n\t\t);\n\t\treturn 1;\n\t}\n\tconnection.challenge = undefined;\n\ttry {\n\t\tawait connection.reconnect();\n\t} catch (connectError) {\n\t\terror(`Signed in, but ${errorMessage(connectError)}`);\n\t\treturn 1;\n\t}\n\tlog(`Signed in to MCP server \"${name}\" (${connection.tools.length} tools).`);\n\treturn 0;\n}\n\n/**\n * The pasted redirect URL in a terminal; otherwise only the browser callback can finish the sign-in.\n * Resolves to undefined (cancelling the sign-in) after `timeoutMs`, or when the callback arrived.\n */\nasync function waitForRedirectUrl(\n\tsignal: AbortSignal,\n\ttimeoutMs: number,\n\tinteractive: boolean,\n): Promise<string | undefined> {\n\tconst controller = new AbortController();\n\tconst abort = () => controller.abort();\n\tsignal.addEventListener(\"abort\", abort, { once: true });\n\tconst timer = setTimeout(abort, timeoutMs);\n\ttry {\n\t\tif (!interactive) {\n\t\t\tawait new Promise<void>((resolve) =>\n\t\t\t\tcontroller.signal.addEventListener(\"abort\", () => resolve(), { once: true }),\n\t\t\t);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst readline = createInterface({ input: process.stdin, output: process.stderr });\n\t\ttry {\n\t\t\treturn await readline.question(\n\t\t\t\t\"If the browser cannot reach this machine, paste the URL it was redirected to: \",\n\t\t\t\t{ signal: controller.signal },\n\t\t\t);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t} finally {\n\t\t\treadline.close();\n\t\t}\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tsignal.removeEventListener(\"abort\", abort);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/extensions/mcp/cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACN,kBAAkB,EAClB,kBAAkB,EAElB,aAAa,EAEb,qBAAqB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,eAAe,GACf,MAAM,cAAc,CAAC;AAEtB,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;IAChC,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;;;UAGF,eAAe,6CAA6C,eAAe;;;;;;;;;;gCAUrD,eAAe;;;;;;;;;;;;;;;;;;;;;8EAqB+B,CAAC;AAE/E,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,QAAQ,yBAAyB,CAAC,CAAC;AAEvE,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAgC1C,SAAS,YAAY,CAAC,KAAc;IACnC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAqB;IAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,OAAO,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAqB,EAAE,OAA0B,EAAE,WAAoC;IAChH,OAAO,IAAI,mBAAmB,CAAC;QAC9B,KAAK;QACL,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,eAAe,EAAE,sBAAsB;QACvC,WAAW;QACX,GAAG,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACxD,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;KACjB,CAAC,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AASpD;;;;GAIG;AACH,SAAS,YAAY,CACpB,IAAc,EACd,KAAgD,EAChD,KAA6B,EAC7B,cAAc,GAAG,MAAM,CAAC,iBAAiB;IAEzC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3D,IAAI,GAAG,KAAK,IAAI,IAAI,UAAU,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;YACzD,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACjE,MAAM;QACP,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,SAAS;QACV,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,KAAK,CAAC,kBAAkB,GAAG,MAAM,SAAS,EAAE,CAAC,CAAC;YAC9C,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACvB,SAAS;QACV,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,KAAK,CAAC,GAAG,GAAG,iBAAiB,CAAC,CAAC;YAC/B,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,KAAK,MAAM;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;;YACrE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACtC,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc,EAAE,OAA0B;IAC7E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnG,GAAG,CAAC,IAAI,CAAC,CAAC;QACV,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;IACrE,IAAI,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC/C,OAAO,OAAO,KAAK,KAAK;YACvB,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC;YAC/C,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,cAAc,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IACzF,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;IAC/F,MAAM,aAAa,GAClB,CAAC,cAAc,IAAI,UAAU,CAAC,aAAa,CAAC;QAC3C,CAAC,CAAC,GAAG,aAAa,yDAAyD,QAAQ,8BAA8B;QACjH,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,uBAAuB,EAAE,CAAC;IAEzE,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;YAC3D,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YACtB,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,KAAK,CAAC,UAAU,QAAQ,uBAAuB,SAAS,EAAE,CAAC,CAAC;gBAC5D,OAAO,CAAC,CAAC;YACV,CAAC;YACD,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QAC1F,CAAC;QACD,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAC1F,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YACtB,MAAM,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;YAC3C,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,KAAK,CAAC,UAAU,QAAQ,QAAQ,OAAO,cAAc,SAAS,EAAE,CAAC,CAAC;gBAClE,OAAO,CAAC,CAAC;YACV,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YACpE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,KAAK,CACJ,wBAAwB,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CAC5J,CAAC;gBACF,OAAO,CAAC,CAAC;YACV,CAAC;YACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;YACjE,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC;YAChC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACV,KAAK,CAAC,eAAe,IAAI,6EAA6E,CAAC,CAAC;gBACxG,OAAO,CAAC,CAAC;YACV,CAAC;YACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBACzD,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,IAAI,IAAI,CAAC,CAAC,CAAC,yCAAyC,IAAI,IAAI,CAAC,CAAC;gBACzG,OAAO,CAAC,CAAC;YACV,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,6BAA6B,CAAC,CAAC;YACtF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;gBAC/C,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACzD,OAAO,CAAC,CAAC;YACV,CAAC;YACD,IAAI,CAAC;gBACJ,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9F,CAAC;oBAAS,CAAC;gBACV,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;YAC1B,CAAC;QACF,CAAC;QACD;YACC,KAAK,CAAC,wBAAwB,OAAO,OAAO,SAAS,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,CAAC;IACX,CAAC;AACF,CAAC;AAED,oEAAoE;AACpE,SAAS,UAAU,CAAC,MAAc,EAAE,KAA2B,EAAE,KAA6B;IAC7F,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACpB,KAAK,CAAC,KAAK,MAAM,4BAA4B,IAAI,IAAI,CAAC,CAAC;YACvD,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,GAAG,CACX,IAAc,EACd,aAAqB,EACrB,OAA0B,EAC1B,GAA2B,EAC3B,KAA6B;IAE7B,MAAM,KAAK,GAAG,UAAU,QAAQ,uEAAuE,SAAS,EAAE,CAAC;IACnH,MAAM,MAAM,GAAG,YAAY,CAC1B,IAAI,EACJ;QACC,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,OAAO;QACZ,MAAM,EAAE,MAAM;QACd,sBAAsB,EAAE,OAAO;QAC/B,iBAAiB,EAAE,OAAO;QAC1B,qBAAqB,EAAE,OAAO;QAC9B,qBAAqB,EAAE,OAAO;QAC9B,mBAAmB,EAAE,OAAO;QAC5B,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,OAAO;KACpB,EACD,KAAK,EACL,CAAC,CACD,CAAC;IACF,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,UAAU,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC7D,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,OAAO,CAAC,CAAC;IACV,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,EAAE;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG;QAChB,QAAQ;QACR,sBAAsB;QACtB,iBAAiB;QACjB,qBAAqB;QACrB,qBAAqB;QACrB,mBAAmB;KACnB,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAChE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CACnD,CAAC;IACF,IAAI,SAAS,EAAE,CAAC;QACf,KAAK,CAAC,KAAK,SAAS,oBAAoB,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC;QACzG,OAAO,CAAC,CAAC;IACV,CAAC;IAED,IAAI,MAA+B,CAAC;IACpC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC;QACvB,MAAM,MAAM,GAAG,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,aAAa,GAAG,aAAa,MAAM,GAAG,CAAC;QACzE,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG;YACb,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACzF,GAAG,CAAC,KAAK,CAAC,qBAAqB,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC;YACrG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC;SAC/F,CAAC;QACF,MAAM,GAAG;YACR,GAAG;YACH,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD,CAAC;IACH,CAAC;SAAM,CAAC;QACP,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,GAAG;YAAE,OAAO,CAAC,CAAC;QACnB,MAAM,CAAC,UAAU,EAAE,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC;QAC7C,MAAM,GAAG;YACR,OAAO,EAAE,UAAU;YACnB,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;SAC5D,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACvD,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;IACzC,IAAI,WAAW,KAAK,SAAS;QAAE,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IAChE,MAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QACnC,KAAK,CAAC,SAAS,CAAC,CAAC;QACjB,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC7C,IAAI,QAAiB,CAAC;IACtB,IAAI,CAAC;QACJ,QAAQ,GAAG,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,QAAQ,EAAE,CAAC;QACnB,KAAK,CAAC,oBAAoB,IAAI,KAAK,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,CAAC;IACV,CAAC;IACD,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,gBAAgB,IAAI,QAAQ,IAAI,GAAG,CAAC,CAAC;IACpF,IAAI,OAAO,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAClF,GAAG,CAAC,kCAAkC,IAAI,+BAA+B,QAAQ,+BAA+B,CAAC,CAAC;IACnH,CAAC;IACD,8DAA8D;IAC9D,MAAM,aAAa,GAClB,KAAK,IAAI,SAAS;QAClB,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,eAAe,CAAC,CAAC;IAClG,GAAG,CACF,kBAAkB,QAAQ,YAAY,aAAa,CAAC,CAAC,CAAC,6BAA6B,QAAQ,cAAc,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACtH,CAAC;IACF,OAAO,CAAC,CAAC;AACV,CAAC;AAED,SAAS,MAAM,CACd,IAAc,EACd,aAAqB,EACrB,OAA0B,EAC1B,GAA2B,EAC3B,KAA6B;IAE7B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,MAAM,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;IAC3C,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,UAAU,QAAQ,8BAA8B,SAAS,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC;IACV,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC7C,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACJ,OAAO,GAAG,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,WAAW,EAAE,CAAC;QACtB,KAAK,CAAC,oBAAoB,IAAI,KAAK,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,CAAC;IACV,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACb,GAAG,CAAC,WAAW,KAAK,gBAAgB,IAAI,UAAU,IAAI,GAAG,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC;IACV,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAC/G,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,CAC1D,CAAC;IACF,KAAK,CACJ,MAAM,KAAK,sBAAsB,IAAI,QAAQ,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,qBAAqB,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACzK,CAAC;IACF,OAAO,CAAC,CAAC;AACV,CAAC;AAED,KAAK,UAAU,IAAI,CAClB,MAAuB,EACvB,IAAa,EACb,aAAiC,EACjC,OAA0B,EAC1B,WAAoC,EACpC,GAA2B;IAE3B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAyB,EAAE;QACzD,MAAM,MAAM,GAAiB;YAC5B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,QAAQ;YAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK;YACvC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,UAAU;YAC7C,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC;YACnC,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,EAAE;SACT,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,MAAM,CAAC;QACnC,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QACjE,IAAI,CAAC;YACJ,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACR,8CAA8C;QAC/C,CAAC;QACD,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAChC,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACnD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,OAAO,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAU,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QACH,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC9E,IAAI,UAAU,CAAC,YAAY,EAAE,CAAC;YAC7B,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC;YAC/C,MAAM,CAAC,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAChE,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,KAAK,WAAW,IAAI,UAAU,CAAC,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC1F,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC,CAAC,CACF,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;IAEpH,IAAI,IAAI,EAAE,CAAC;QACV,GAAG,CACF,IAAI,CAAC,SAAS,CACb,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAC9F,IAAI,EACJ,CAAC,CACD,CACD,CAAC;QACF,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxD,GAAG,CACF,0CAA0C,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,eAAe,YAAY,CAC9G,CAAC;IACH,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,KAAK,GACV,MAAM,CAAC,KAAK,KAAK,WAAW;YAC3B,CAAC,CAAC,cAAc,MAAM,CAAC,KAAK,CAAC,MAAM,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;YACjF,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,YAAY;gBAC9B,CAAC,CAAC,eAAe;gBACjB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAClB,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,KAAK,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;QACtE,GAAG,CAAC,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,QAAQ;YAAE,GAAG,CAAC,uBAAuB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,KAAK,KAAK,YAAY;YAAE,GAAG,CAAC,mBAAmB,QAAQ,cAAc,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/F,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;gBAC7C,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAClD,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,GAAG,CAAC,gBAAgB,MAAM,CAAC,SAAS,oBAAoB,MAAM,CAAC,iBAAiB,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,IAAI,MAAM,CAAC,KAAK;YAAE,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM;QAAE,GAAG,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC;IAC7E,IAAI,aAAa;QAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,KAAK,CACnB,KAAqB,EACrB,UAA+B,EAC/B,GAAW,EACX,SAAiB,EACjB,OAA0B,EAC1B,WAAoC,EACpC,GAA2B,EAC3B,KAA6B;IAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACvB,2FAA2F;IAC3F,IAAI,CAAC;QACJ,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC;QAC7B,GAAG,CAAC,oCAAoC,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,CAAC;QACrF,OAAO,CAAC,CAAC;IACV,CAAC;IAAC,MAAM,CAAC;QACR,IAAI,UAAU,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;YACvC,KAAK,CAAC,eAAe,IAAI,wBAAwB,UAAU,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;YACxF,OAAO,CAAC,CAAC;QACV,CAAC;IACF,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC;IAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC;IAClF,IAAI,CAAC;QACJ,MAAM,eAAe,CAAC;YACrB,SAAS,EAAE,GAAG;YACd,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC;YACvC,QAAQ,EAAE,UAAU,CAAC,aAAa,EAAE;YACpC,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,MAAM,EAAE;gBACP,oBAAoB,EAAE,CAAC,gBAAgB,EAAE,EAAE;oBAC1C,GAAG,CAAC,0BAA0B,IAAI,uBAAuB,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;oBAClF,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBAChC,CAAC;gBACD,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC;aACpF;SACD,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,WAAW,EAAE,CAAC;QACtB,KAAK,CACJ,WAAW,YAAY,uBAAuB;YAC7C,CAAC,CAAC,0BAA0B,IAAI,2CAA2C,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW;YAClH,CAAC,CAAC,0BAA0B,IAAI,aAAa,YAAY,CAAC,WAAW,CAAC,EAAE,CACzE,CAAC;QACF,OAAO,CAAC,CAAC;IACV,CAAC;IACD,UAAU,CAAC,SAAS,GAAG,SAAS,CAAC;IACjC,IAAI,CAAC;QACJ,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,YAAY,EAAE,CAAC;QACvB,KAAK,CAAC,kBAAkB,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,CAAC;IACV,CAAC;IACD,GAAG,CAAC,4BAA4B,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,CAAC;IAC7E,OAAO,CAAC,CAAC;AACV,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,kBAAkB,CAChC,MAAmB,EACnB,SAAiB,EACjB,WAAoB;IAEpB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IACvC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3C,IAAI,CAAC;QACJ,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CACnC,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAC5E,CAAC;YACF,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC;YACJ,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAC7B,gFAAgF,EAChF,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAC7B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;gBAAS,CAAC;YACV,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;IACF,CAAC;YAAS,CAAC;QACV,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;AACF,CAAC","sourcesContent":["/**\n * `pi mcp`: add, remove, and check MCP servers and sign in to them outside a session. Agents run it\n * through bash to configure servers, verify an `mcp.json` they wrote, and start an OAuth sign-in;\n * the user only approves access in the browser. Running sessions pick up new credentials on their\n * next turn.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME } from \"../../config.js\";\nimport { validateMcpServerConfig } from \"../../core/mcp-servers.ts\";\nimport { ProjectTrustStore } from \"../../core/trust-manager.ts\";\nimport { openBrowser } from \"../../utils/open-browser.ts\";\nimport {\n\taddMcpServerConfig,\n\tgetMcpToolExposure,\n\ttype LoadedMcpConfig,\n\tloadMcpConfig,\n\ttype McpServerEntry,\n\tremoveMcpServerConfig,\n} from \"./config.ts\";\nimport {\n\tcreateDefaultTransport,\n\tMcpOAuthCredentialStore,\n\tMcpServerConnection,\n\tMcpServerLog,\n\tMcpSignInCancelledError,\n\tsignInMcpServer,\n} from \"./runtime.ts\";\n\nconst HELP = `${chalk.bold(\"Usage:\")}\n ${APP_NAME} mcp add <server> [options] -- <command> [args...]\n ${APP_NAME} mcp add <server> [options] --url <url>\n ${APP_NAME} mcp remove <server> [-l]\n ${APP_NAME} mcp list [--json]\n ${APP_NAME} mcp login <server> [--timeout <seconds>]\n ${APP_NAME} mcp logout <server>\n\nConfigure and check MCP servers and sign in to OAuth servers without starting a session.\nReads ~/${CONFIG_DIR_NAME}/agent/mcp.json and, in trusted projects, ${CONFIG_DIR_NAME}/mcp.json.\n\nCommands:\n add <server> Add or replace a server in mcp.json\n remove <server> Remove a server from mcp.json\n list Show state, tools, and errors (exits 1 on failure)\n login <server> Sign in through the browser\n logout <server> Delete the stored OAuth credentials\n\nOptions for add and remove:\n -l, --local Use ${CONFIG_DIR_NAME}/mcp.json in the current project instead of the global file\n\nOptions for add:\n --url <url> Streamable HTTP server URL (instead of a command)\n --env <KEY=VALUE> Environment variable for a stdio server (repeatable)\n --cwd <dir> Working directory for a stdio server\n --header <KEY=VALUE> HTTP header (repeatable)\n --bearer-token-env-var <NAME>\n Send \"Authorization: Bearer \\${NAME}\"\n --oauth-client-id <id> Pre-registered OAuth client id\n --oauth-client-secret <secret>\n OAuth client secret (may be \\${NAME} or !command)\n --oauth-callback-port <port>\n Fixed OAuth callback port\n --oauth-client-name <name>\n Client name sent when registering with the OAuth server\n --exposure <mode> codemode (default), deferred, direct, or hidden\n --description <text> What the server offers, shown in the system prompt\n\nOther options:\n --json Print the list as JSON\n --timeout <seconds> How long login waits for the browser (default: 300)`;\n\nconst HELP_HINT = chalk.dim(`Use \"${APP_NAME} mcp --help\" for usage.`);\n\nconst DEFAULT_LOGIN_TIMEOUT_SECONDS = 300;\n\nexport interface McpCommandOptions {\n\tcwd: string;\n\tagentDir: string;\n\t/** Defaults to `mcp-auth.json` in the agent directory. */\n\tcredentials?: McpOAuthCredentialStore;\n\t/** Defaults to the platform browser. */\n\topenUrl?: (url: string) => void;\n\t/** Defaults to console output. */\n\tlog?: (line: string) => void;\n\terror?: (line: string) => void;\n}\n\ninterface ServerReport {\n\tname: string;\n\tscope: string;\n\tsource: string;\n\t/** Project `mcp.json` that overrides `enabled`, `exposure`, or `toolExposure` of this global server. */\n\toverride?: string;\n\tenabled: boolean;\n\texposure: string;\n\ttransport: string;\n\tstate: string;\n\ttools: string[];\n\t/** Tools whose exposure differs from the server's, from `toolExposure`. */\n\ttoolExposure?: Record<string, string>;\n\tresources?: number;\n\tresourceTemplates?: number;\n\terror?: string;\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction describeTransport(entry: McpServerEntry): string {\n\tconst { config } = entry;\n\treturn \"url\" in config ? config.url : [config.command, ...(config.args ?? [])].join(\" \");\n}\n\nfunction createConnection(entry: McpServerEntry, options: McpCommandOptions, credentials: McpOAuthCredentialStore) {\n\treturn new McpServerConnection({\n\t\tentry,\n\t\tcwd: options.cwd,\n\t\tcreateTransport: createDefaultTransport,\n\t\tcredentials,\n\t\tlog: new McpServerLog(join(options.agentDir, \"mcp.log\")),\n\t\tonTools: () => {},\n\t});\n}\n\n/** Short spellings of options. `-l`/`--local` match `pi install`. */\nconst OPTION_ALIASES = new Map([[\"-l\", \"--local\"]]);\n\ninterface ParsedOptions {\n\tpositional: string[];\n\tvalues: Map<string, string | true>;\n\t/** Values of `list` options, in order. */\n\tlists: Map<string, string[]>;\n}\n\n/**\n * Parse `--name value` options; returns undefined and reports unknown ones. `--` ends the options,\n * as does reaching `maxPositionals` positional arguments: the remaining arguments are positional,\n * so a command's own options (`add <server> <command> --flag`) are passed through.\n */\nfunction parseOptions(\n\targs: string[],\n\tknown: Record<string, \"flag\" | \"value\" | \"list\">,\n\terror: (line: string) => void,\n\tmaxPositionals = Number.POSITIVE_INFINITY,\n): ParsedOptions | undefined {\n\tconst positional: string[] = [];\n\tconst values = new Map<string, string | true>();\n\tconst lists = new Map<string, string[]>();\n\tfor (let index = 0; index < args.length; index++) {\n\t\tconst arg = OPTION_ALIASES.get(args[index]) ?? args[index];\n\t\tif (arg === \"--\" || positional.length >= maxPositionals) {\n\t\t\tpositional.push(...args.slice(arg === \"--\" ? index + 1 : index));\n\t\t\tbreak;\n\t\t}\n\t\tif (!arg.startsWith(\"--\")) {\n\t\t\tpositional.push(arg);\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = arg.slice(2);\n\t\tconst kind = known[name];\n\t\tif (!kind) {\n\t\t\terror(`Unknown option ${arg}.\\n${HELP_HINT}`);\n\t\t\treturn undefined;\n\t\t}\n\t\tif (kind === \"flag\") {\n\t\t\tvalues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tconst value = args[++index];\n\t\tif (value === undefined) {\n\t\t\terror(`${arg} needs a value.`);\n\t\t\treturn undefined;\n\t\t}\n\t\tif (kind === \"list\") lists.set(name, [...(lists.get(name) ?? []), value]);\n\t\telse values.set(name, value);\n\t}\n\treturn { positional, values, lists };\n}\n\n/** Run `pi mcp <args>` and return the exit code. */\nexport async function runMcpCommand(args: string[], options: McpCommandOptions): Promise<number> {\n\tconst log = options.log ?? ((line: string) => console.log(line));\n\tconst error = options.error ?? ((line: string) => console.error(line));\n\tconst [command, ...rest] = args;\n\tif (command === undefined || command === \"help\" || args.includes(\"--help\") || args.includes(\"-h\")) {\n\t\tlog(HELP);\n\t\treturn 0;\n\t}\n\n\tconst projectConfig = join(options.cwd, CONFIG_DIR_NAME, \"mcp.json\");\n\tif (command === \"add\" || command === \"remove\") {\n\t\treturn command === \"add\"\n\t\t\t? add(rest, projectConfig, options, log, error)\n\t\t\t: remove(rest, projectConfig, options, log, error);\n\t}\n\tconst projectTrusted = new ProjectTrustStore(options.agentDir).get(options.cwd) === true;\n\tconst loaded = loadMcpConfig({ agentDir: options.agentDir, cwd: options.cwd, projectTrusted });\n\tconst untrustedNote =\n\t\t!projectTrusted && existsSync(projectConfig)\n\t\t\t? `${projectConfig} is ignored because the project is not trusted. Start ${APP_NAME} in the project to trust it.`\n\t\t\t: undefined;\n\tconst credentials = options.credentials ?? new McpOAuthCredentialStore();\n\n\tswitch (command) {\n\t\tcase \"list\": {\n\t\t\tconst parsed = parseOptions(rest, { json: \"flag\" }, error);\n\t\t\tif (!parsed) return 1;\n\t\t\tif (parsed.positional.length > 0) {\n\t\t\t\terror(`Usage: ${APP_NAME} mcp list [--json]\\n${HELP_HINT}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn list(loaded, parsed.values.has(\"json\"), untrustedNote, options, credentials, log);\n\t\t}\n\t\tcase \"login\":\n\t\tcase \"logout\": {\n\t\t\tconst parsed = parseOptions(rest, command === \"login\" ? { timeout: \"value\" } : {}, error);\n\t\t\tif (!parsed) return 1;\n\t\t\tconst [name, ...extra] = parsed.positional;\n\t\t\tif (!name || extra.length > 0) {\n\t\t\t\terror(`Usage: ${APP_NAME} mcp ${command} <server>\\n${HELP_HINT}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tconst entry = loaded.servers.find((server) => server.name === name);\n\t\t\tif (!entry) {\n\t\t\t\terror(\n\t\t\t\t\t`No MCP server named \"${name}\".${untrustedNote ? ` ${untrustedNote}` : \"\"} Configured: ${loaded.servers.map((server) => server.name).join(\", \") || \"none\"}.`,\n\t\t\t\t);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tconst connection = createConnection(entry, options, credentials);\n\t\t\tconst url = connection.oauthUrl;\n\t\t\tif (!url) {\n\t\t\t\terror(`MCP server \"${name}\" does not use OAuth. Only HTTP servers without an Authorization header do.`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (command === \"logout\") {\n\t\t\t\tconst removed = await credentials.removeAsync(name, url);\n\t\t\t\tlog(removed ? `Signed out of MCP server \"${name}\".` : `No stored credentials for MCP server \"${name}\".`);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tconst timeout = Number(parsed.values.get(\"timeout\") ?? DEFAULT_LOGIN_TIMEOUT_SECONDS);\n\t\t\tif (!Number.isFinite(timeout) || timeout <= 0) {\n\t\t\t\terror(\"--timeout must be a positive number of seconds.\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn await login(entry, connection, url, timeout * 1000, options, credentials, log, error);\n\t\t\t} finally {\n\t\t\t\tawait connection.close();\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\terror(`Unknown mcp command \"${command}\".\\n${HELP_HINT}`);\n\t\t\treturn 1;\n\t}\n}\n\n/** Parse `KEY=VALUE` pairs of a repeatable option into a record. */\nfunction parsePairs(option: string, pairs: string[] | undefined, error: (line: string) => void) {\n\tif (!pairs) return {};\n\tconst record: Record<string, string> = {};\n\tfor (const pair of pairs) {\n\t\tconst separator = pair.indexOf(\"=\");\n\t\tif (separator <= 0) {\n\t\t\terror(`--${option} expects KEY=VALUE, got \"${pair}\".`);\n\t\t\treturn undefined;\n\t\t}\n\t\trecord[pair.slice(0, separator)] = pair.slice(separator + 1);\n\t}\n\treturn record;\n}\n\nfunction add(\n\targs: string[],\n\tprojectConfig: string,\n\toptions: McpCommandOptions,\n\tlog: (line: string) => void,\n\terror: (line: string) => void,\n): number {\n\tconst usage = `Usage: ${APP_NAME} mcp add <server> [options] (--url <url> | -- <command> [args...])\\n${HELP_HINT}`;\n\tconst parsed = parseOptions(\n\t\targs,\n\t\t{\n\t\t\tlocal: \"flag\",\n\t\t\turl: \"value\",\n\t\t\tenv: \"list\",\n\t\t\tcwd: \"value\",\n\t\t\theader: \"list\",\n\t\t\t\"bearer-token-env-var\": \"value\",\n\t\t\t\"oauth-client-id\": \"value\",\n\t\t\t\"oauth-client-secret\": \"value\",\n\t\t\t\"oauth-callback-port\": \"value\",\n\t\t\t\"oauth-client-name\": \"value\",\n\t\t\texposure: \"value\",\n\t\t\tdescription: \"value\",\n\t\t},\n\t\terror,\n\t\t2,\n\t);\n\tif (!parsed) return 1;\n\tconst { positional, values, lists } = parsed;\n\tconst [name, ...command] = positional;\n\tconst url = values.get(\"url\");\n\tif (!name || (url === undefined) === (command.length === 0)) {\n\t\terror(usage);\n\t\treturn 1;\n\t}\n\tconst value = (option: string) => {\n\t\tconst found = values.get(option);\n\t\treturn typeof found === \"string\" ? found : undefined;\n\t};\n\tconst exposure = value(\"exposure\");\n\tconst httpOnly = [\n\t\t\"header\",\n\t\t\"bearer-token-env-var\",\n\t\t\"oauth-client-id\",\n\t\t\"oauth-client-secret\",\n\t\t\"oauth-callback-port\",\n\t\t\"oauth-client-name\",\n\t];\n\tconst stdioOnly = [\"env\", \"cwd\"];\n\tconst misplaced = (url === undefined ? httpOnly : stdioOnly).find(\n\t\t(option) => values.has(option) || lists.has(option),\n\t);\n\tif (misplaced) {\n\t\terror(`--${misplaced} only applies to ${url === undefined ? \"HTTP servers (--url)\" : \"stdio servers\"}.`);\n\t\treturn 1;\n\t}\n\n\tlet config: Record<string, unknown>;\n\tif (typeof url === \"string\") {\n\t\tconst headers = parsePairs(\"header\", lists.get(\"header\"), error);\n\t\tif (!headers) return 1;\n\t\tconst bearer = value(\"bearer-token-env-var\");\n\t\tif (bearer !== undefined) headers.Authorization = `Bearer \\${${bearer}}`;\n\t\tconst port = value(\"oauth-callback-port\");\n\t\tconst oauth = {\n\t\t\t...(value(\"oauth-client-id\") === undefined ? {} : { clientId: value(\"oauth-client-id\") }),\n\t\t\t...(value(\"oauth-client-secret\") === undefined ? {} : { clientSecret: value(\"oauth-client-secret\") }),\n\t\t\t...(port === undefined ? {} : { callbackPort: Number(port) }),\n\t\t\t...(value(\"oauth-client-name\") === undefined ? {} : { clientName: value(\"oauth-client-name\") }),\n\t\t};\n\t\tconfig = {\n\t\t\turl,\n\t\t\t...(Object.keys(headers).length > 0 ? { headers } : {}),\n\t\t\t...(Object.keys(oauth).length > 0 ? { oauth } : {}),\n\t\t};\n\t} else {\n\t\tconst env = parsePairs(\"env\", lists.get(\"env\"), error);\n\t\tif (!env) return 1;\n\t\tconst [executable, ...commandArgs] = command;\n\t\tconfig = {\n\t\t\tcommand: executable,\n\t\t\t...(commandArgs.length > 0 ? { args: commandArgs } : {}),\n\t\t\t...(Object.keys(env).length > 0 ? { env } : {}),\n\t\t\t...(value(\"cwd\") === undefined ? {} : { cwd: value(\"cwd\") }),\n\t\t};\n\t}\n\tif (exposure !== undefined) config.exposure = exposure;\n\tconst description = value(\"description\");\n\tif (description !== undefined) config.description = description;\n\tconst validated = validateMcpServerConfig(name, config);\n\tif (typeof validated === \"string\") {\n\t\terror(validated);\n\t\treturn 1;\n\t}\n\n\tconst project = values.has(\"local\");\n\tconst path = project ? projectConfig : join(options.agentDir, \"mcp.json\");\n\tconst scope = project ? \"project\" : \"global\";\n\tlet replaced: boolean;\n\ttry {\n\t\treplaced = addMcpServerConfig(path, name, validated);\n\t} catch (addError) {\n\t\terror(`Could not update ${path}: ${errorMessage(addError)}`);\n\t\treturn 1;\n\t}\n\tlog(`${replaced ? \"Replaced\" : \"Added\"} ${scope} MCP server \"${name}\" in ${path}.`);\n\tif (project && new ProjectTrustStore(options.agentDir).get(options.cwd) !== true) {\n\t\tlog(`The project is not trusted, so ${path} is ignored until you start ${APP_NAME} in the project and trust it.`);\n\t}\n\t// HTTP servers without an Authorization header may use OAuth.\n\tconst mayNeedSignIn =\n\t\t\"url\" in validated &&\n\t\t!Object.keys(validated.headers ?? {}).some((header) => header.toLowerCase() === \"authorization\");\n\tlog(\n\t\t`Check it with: ${APP_NAME} mcp list${mayNeedSignIn ? `. If it requires sign-in: ${APP_NAME} mcp login ${name}` : \"\"}`,\n\t);\n\treturn 0;\n}\n\nfunction remove(\n\targs: string[],\n\tprojectConfig: string,\n\toptions: McpCommandOptions,\n\tlog: (line: string) => void,\n\terror: (line: string) => void,\n): number {\n\tconst parsed = parseOptions(args, { local: \"flag\" }, error);\n\tif (!parsed) return 1;\n\tconst [name, ...extra] = parsed.positional;\n\tif (!name || extra.length > 0) {\n\t\terror(`Usage: ${APP_NAME} mcp remove <server> [-l]\\n${HELP_HINT}`);\n\t\treturn 1;\n\t}\n\tconst project = parsed.values.has(\"local\");\n\tconst globalConfig = join(options.agentDir, \"mcp.json\");\n\tconst path = project ? projectConfig : globalConfig;\n\tconst scope = project ? \"project\" : \"global\";\n\tlet removed: boolean;\n\ttry {\n\t\tremoved = removeMcpServerConfig(path, name);\n\t} catch (removeError) {\n\t\terror(`Could not update ${path}: ${errorMessage(removeError)}`);\n\t\treturn 1;\n\t}\n\tif (removed) {\n\t\tlog(`Removed ${scope} MCP server \"${name}\" from ${path}.`);\n\t\treturn 0;\n\t}\n\tconst other = loadMcpConfig({ agentDir: options.agentDir, cwd: options.cwd, projectTrusted: true }).servers.find(\n\t\t(server) => server.name === name && server.scope !== scope,\n\t);\n\terror(\n\t\t`No ${scope} MCP server named \"${name}\" in ${path}.${other ? ` It is defined in ${other.source}${other.scope === \"project\" ? \"; use --local\" : \"; omit --local\"}.` : \"\"}`,\n\t);\n\treturn 1;\n}\n\nasync function list(\n\tloaded: LoadedMcpConfig,\n\tjson: boolean,\n\tuntrustedNote: string | undefined,\n\toptions: McpCommandOptions,\n\tcredentials: McpOAuthCredentialStore,\n\tlog: (line: string) => void,\n): Promise<number> {\n\tconst reports = await Promise.all(\n\t\tloaded.servers.map(async (entry): Promise<ServerReport> => {\n\t\t\tconst report: ServerReport = {\n\t\t\t\tname: entry.name,\n\t\t\t\tscope: entry.scope ?? \"global\",\n\t\t\t\tsource: entry.source,\n\t\t\t\t...(entry.override ? { override: entry.override } : {}),\n\t\t\t\tenabled: entry.config.enabled !== false,\n\t\t\t\texposure: entry.config.exposure ?? \"codemode\",\n\t\t\t\ttransport: describeTransport(entry),\n\t\t\t\tstate: \"disabled\",\n\t\t\t\ttools: [],\n\t\t\t};\n\t\t\tif (!report.enabled) return report;\n\t\t\tconst connection = createConnection(entry, options, credentials);\n\t\t\ttry {\n\t\t\t\tawait connection.getClient();\n\t\t\t} catch {\n\t\t\t\t// The connection records the state and error.\n\t\t\t}\n\t\t\treport.state = connection.state;\n\t\t\treport.tools = connection.tools.map((tool) => tool.name);\n\t\t\tconst overrides = connection.tools.flatMap((tool) => {\n\t\t\t\tconst exposure = getMcpToolExposure(entry.config, tool.name);\n\t\t\t\treturn exposure === report.exposure ? [] : [[tool.name, exposure] as const];\n\t\t\t});\n\t\t\tif (overrides.length > 0) report.toolExposure = Object.fromEntries(overrides);\n\t\t\tif (connection.hasResources) {\n\t\t\t\treport.resources = connection.resources.length;\n\t\t\t\treport.resourceTemplates = connection.resourceTemplates.length;\n\t\t\t}\n\t\t\tif (connection.state !== \"connected\" && connection.error) report.error = connection.error;\n\t\t\tawait connection.close();\n\t\t\treturn report;\n\t\t}),\n\t);\n\tconst failed = loaded.errors.length > 0 || reports.some((report) => report.enabled && report.state !== \"connected\");\n\n\tif (json) {\n\t\tlog(\n\t\t\tJSON.stringify(\n\t\t\t\t{ servers: reports, errors: loaded.errors, ...(untrustedNote ? { note: untrustedNote } : {}) },\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t),\n\t\t);\n\t\treturn failed ? 1 : 0;\n\t}\n\tif (reports.length === 0 && loaded.errors.length === 0) {\n\t\tlog(\n\t\t\t`No MCP servers configured. Add them to ${join(options.agentDir, \"mcp.json\")} or ${CONFIG_DIR_NAME}/mcp.json.`,\n\t\t);\n\t}\n\tfor (const report of reports) {\n\t\tconst state =\n\t\t\treport.state === \"connected\"\n\t\t\t\t? `connected, ${report.tools.length} tool${report.tools.length === 1 ? \"\" : \"s\"}`\n\t\t\t\t: report.state === \"needs-auth\"\n\t\t\t\t\t? \"needs sign-in\"\n\t\t\t\t\t: report.state;\n\t\tlog(`${report.name}: ${state} (${report.exposure}, ${report.scope})`);\n\t\tlog(` ${report.transport}`);\n\t\tif (report.override) log(` project override: ${report.override}`);\n\t\tif (report.state === \"needs-auth\") log(` sign in with: ${APP_NAME} mcp login ${report.name}`);\n\t\tif (report.tools.length > 0) {\n\t\t\tconst tools = report.tools.map((tool) => {\n\t\t\t\tconst exposure = report.toolExposure?.[tool];\n\t\t\t\treturn exposure ? `${tool} [${exposure}]` : tool;\n\t\t\t});\n\t\t\tlog(` tools: ${tools.join(\", \")}`);\n\t\t}\n\t\tif (report.resources !== undefined) {\n\t\t\tlog(` resources: ${report.resources}, URI templates: ${report.resourceTemplates ?? 0}`);\n\t\t}\n\t\tif (report.error) log(` ${report.error.split(\"\\n\").join(\"\\n \")}`);\n\t}\n\tfor (const configError of loaded.errors) log(`config error: ${configError}`);\n\tif (untrustedNote) log(untrustedNote);\n\treturn failed ? 1 : 0;\n}\n\nasync function login(\n\tentry: McpServerEntry,\n\tconnection: McpServerConnection,\n\turl: string,\n\ttimeoutMs: number,\n\toptions: McpCommandOptions,\n\tcredentials: McpOAuthCredentialStore,\n\tlog: (line: string) => void,\n\terror: (line: string) => void,\n): Promise<number> {\n\tconst { name } = entry;\n\t// Connecting first answers whether a sign-in is needed and records the server's challenge.\n\ttry {\n\t\tawait connection.getClient();\n\t\tlog(`Already signed in to MCP server \"${name}\" (${connection.tools.length} tools).`);\n\t\treturn 0;\n\t} catch {\n\t\tif (connection.state !== \"needs-auth\") {\n\t\t\terror(`MCP server \"${name}\" failed to connect: ${connection.error ?? \"unknown error\"}`);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tconst openUrl = options.openUrl ?? openBrowser;\n\tconst interactive = process.stdin.isTTY === true && options.openUrl === undefined;\n\ttry {\n\t\tawait signInMcpServer({\n\t\t\tserverUrl: url,\n\t\t\tstore: credentials.forServer(name, url),\n\t\t\tsettings: connection.oauthSettings(),\n\t\t\tchallenge: connection.challenge,\n\t\t\tprompt: {\n\t\t\t\tshowAuthorizationUrl: (authorizationUrl) => {\n\t\t\t\t\tlog(`Sign in to MCP server \"${name}\" in your browser:\\n${authorizationUrl.href}`);\n\t\t\t\t\topenUrl(authorizationUrl.href);\n\t\t\t\t},\n\t\t\t\tpromptForRedirectUrl: (signal) => waitForRedirectUrl(signal, timeoutMs, interactive),\n\t\t\t},\n\t\t});\n\t} catch (signInError) {\n\t\terror(\n\t\t\tsignInError instanceof McpSignInCancelledError\n\t\t\t\t? `Sign-in to MCP server \"${name}\" was cancelled or not completed within ${Math.round(timeoutMs / 1000)} seconds.`\n\t\t\t\t: `Sign-in to MCP server \"${name}\" failed: ${errorMessage(signInError)}`,\n\t\t);\n\t\treturn 1;\n\t}\n\tconnection.challenge = undefined;\n\ttry {\n\t\tawait connection.reconnect();\n\t} catch (connectError) {\n\t\terror(`Signed in, but ${errorMessage(connectError)}`);\n\t\treturn 1;\n\t}\n\tlog(`Signed in to MCP server \"${name}\" (${connection.tools.length} tools).`);\n\treturn 0;\n}\n\n/**\n * The pasted redirect URL in a terminal; otherwise only the browser callback can finish the sign-in.\n * Resolves to undefined (cancelling the sign-in) after `timeoutMs`, or when the callback arrived.\n */\nasync function waitForRedirectUrl(\n\tsignal: AbortSignal,\n\ttimeoutMs: number,\n\tinteractive: boolean,\n): Promise<string | undefined> {\n\tconst controller = new AbortController();\n\tconst abort = () => controller.abort();\n\tsignal.addEventListener(\"abort\", abort, { once: true });\n\tconst timer = setTimeout(abort, timeoutMs);\n\ttry {\n\t\tif (!interactive) {\n\t\t\tawait new Promise<void>((resolve) =>\n\t\t\t\tcontroller.signal.addEventListener(\"abort\", () => resolve(), { once: true }),\n\t\t\t);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst readline = createInterface({ input: process.stdin, output: process.stderr });\n\t\ttry {\n\t\t\treturn await readline.question(\n\t\t\t\t\"If the browser cannot reach this machine, paste the URL it was redirected to: \",\n\t\t\t\t{ signal: controller.signal },\n\t\t\t);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t} finally {\n\t\t\treadline.close();\n\t\t}\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tsignal.removeEventListener(\"abort\", abort);\n\t}\n}\n"]}
|
|
@@ -21,6 +21,8 @@ export interface OAuthCallbackServerOptions {
|
|
|
21
21
|
redirectHost?: string;
|
|
22
22
|
port?: number;
|
|
23
23
|
path?: string;
|
|
24
|
+
/** Additional callback paths, for server-specific redirect URIs. */
|
|
25
|
+
extraPaths?: string[];
|
|
24
26
|
timeoutMs?: number;
|
|
25
27
|
/** Render the browser page as HTML. Default: a plain-text message. */
|
|
26
28
|
renderPage?: (page: OAuthCallbackPage) => string;
|
|
@@ -28,13 +30,13 @@ export interface OAuthCallbackServerOptions {
|
|
|
28
30
|
export declare class OAuthCallbackServer {
|
|
29
31
|
readonly redirectUrl: string;
|
|
30
32
|
private server;
|
|
31
|
-
private
|
|
33
|
+
private paths;
|
|
32
34
|
private timeoutMs;
|
|
33
35
|
private renderPage;
|
|
34
36
|
private pending;
|
|
35
37
|
private constructor();
|
|
36
38
|
static listen(options?: OAuthCallbackServerOptions): Promise<OAuthCallbackServer>;
|
|
37
|
-
waitForCallback(state: string): Promise<OAuthCallback>;
|
|
39
|
+
waitForCallback(state: string, path?: string): Promise<OAuthCallback>;
|
|
38
40
|
close(): Promise<void>;
|
|
39
41
|
private reply;
|
|
40
42
|
private handle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/callback.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,4DAA4D;AAC5D,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG,MAAM,WAAW,0BAA0B;IAC1C,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,MAAM,CAAC;CACjD;AAOD,qBAAa,mBAAmB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/callback.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,4DAA4D;AAC5D,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG,MAAM,WAAW,0BAA0B;IAC1C,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,MAAM,CAAC;CACjD;AAOD,qBAAa,mBAAmB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAoD;IACtE,OAAO,CAAC,OAAO,CAQX;IAEJ,OAAO,eAYN;IAED,OAAa,MAAM,CAAC,OAAO,GAAE,0BAA+B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuB1F;IAED,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CASpE;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAS3B;IAED,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,MAAM;CAwCd"}
|
|
@@ -7,14 +7,14 @@ function plainText(page) {
|
|
|
7
7
|
export class OAuthCallbackServer {
|
|
8
8
|
redirectUrl;
|
|
9
9
|
server;
|
|
10
|
-
|
|
10
|
+
paths;
|
|
11
11
|
timeoutMs;
|
|
12
12
|
renderPage;
|
|
13
13
|
pending = new Map();
|
|
14
|
-
constructor(server, redirectUrl,
|
|
14
|
+
constructor(server, redirectUrl, paths, timeoutMs, renderPage) {
|
|
15
15
|
this.server = server;
|
|
16
16
|
this.redirectUrl = redirectUrl;
|
|
17
|
-
this.
|
|
17
|
+
this.paths = paths;
|
|
18
18
|
this.timeoutMs = timeoutMs;
|
|
19
19
|
this.renderPage = renderPage;
|
|
20
20
|
}
|
|
@@ -34,10 +34,10 @@ export class OAuthCallbackServer {
|
|
|
34
34
|
const address = server.address();
|
|
35
35
|
if (!address || typeof address === "string")
|
|
36
36
|
throw new Error("OAuth callback server did not bind to TCP");
|
|
37
|
-
instance = new OAuthCallbackServer(server, `http://${redirectHost.includes(":") ? `[${redirectHost}]` : redirectHost}:${address.port}${path}`, path, options.timeoutMs ?? 5 * 60_000, options.renderPage);
|
|
37
|
+
instance = new OAuthCallbackServer(server, `http://${redirectHost.includes(":") ? `[${redirectHost}]` : redirectHost}:${address.port}${path}`, [path, ...(options.extraPaths ?? [])], options.timeoutMs ?? 5 * 60_000, options.renderPage);
|
|
38
38
|
return instance;
|
|
39
39
|
}
|
|
40
|
-
waitForCallback(state) {
|
|
40
|
+
waitForCallback(state, path) {
|
|
41
41
|
if (this.pending.has(state))
|
|
42
42
|
throw new Error("OAuth state is already pending");
|
|
43
43
|
return new Promise((resolve, reject) => {
|
|
@@ -45,7 +45,7 @@ export class OAuthCallbackServer {
|
|
|
45
45
|
this.pending.delete(state);
|
|
46
46
|
reject(new Error("OAuth callback timed out"));
|
|
47
47
|
}, this.timeoutMs);
|
|
48
|
-
this.pending.set(state, { resolve, reject, timer });
|
|
48
|
+
this.pending.set(state, { resolve, reject, timer, path });
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
async close() {
|
|
@@ -69,7 +69,7 @@ export class OAuthCallbackServer {
|
|
|
69
69
|
}
|
|
70
70
|
handle(rawUrl, response) {
|
|
71
71
|
const url = new URL(rawUrl, this.redirectUrl);
|
|
72
|
-
if (url.pathname
|
|
72
|
+
if (!this.paths.includes(url.pathname)) {
|
|
73
73
|
this.reply(response, 404, { ok: false, message: "Not found" });
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
@@ -81,6 +81,11 @@ export class OAuthCallbackServer {
|
|
|
81
81
|
}
|
|
82
82
|
clearTimeout(pending.timer);
|
|
83
83
|
this.pending.delete(state);
|
|
84
|
+
if (pending.path !== undefined && url.pathname !== pending.path) {
|
|
85
|
+
pending.reject(new Error("The authorization response arrived on another redirect URI"));
|
|
86
|
+
this.reply(response, 400, { ok: false, message: "Unexpected redirect URI" });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
84
89
|
const error = url.searchParams.get("error");
|
|
85
90
|
if (error) {
|
|
86
91
|
const description = url.searchParams.get("error_description") ?? error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/callback.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type Server, type ServerResponse } from \"node:http\";\n\nexport interface OAuthCallback {\n\tcode: string;\n\tstate: string;\n\tiss?: string;\n}\n\n/** Outcome shown on the browser page after the redirect. */\nexport type OAuthCallbackPage = { ok: true } | { ok: false; message: string; details?: string };\n\nexport interface OAuthCallbackServerOptions {\n\t/** Address to listen on. Default: `127.0.0.1`. */\n\thost?: string;\n\t/**\n\t * Host name in `redirectUrl`, for example `localhost` for a client registered with it while\n\t * listening on `127.0.0.1`. Default: `host`.\n\t */\n\tredirectHost?: string;\n\tport?: number;\n\tpath?: string;\n\ttimeoutMs?: number;\n\t/** Render the browser page as HTML. Default: a plain-text message. */\n\trenderPage?: (page: OAuthCallbackPage) => string;\n}\n\nfunction plainText(page: OAuthCallbackPage): string {\n\tif (page.ok) return \"Authorization complete. You may close this window.\";\n\treturn page.details ? `${page.message}\\n\\n${page.details}` : page.message;\n}\n\nexport class OAuthCallbackServer {\n\treadonly redirectUrl: string;\n\tprivate server: Server;\n\tprivate path: string;\n\tprivate timeoutMs: number;\n\tprivate renderPage: ((page: OAuthCallbackPage) => string) | undefined;\n\tprivate pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (callback: OAuthCallback) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimer: ReturnType<typeof setTimeout>;\n\t\t}\n\t>();\n\n\tprivate constructor(\n\t\tserver: Server,\n\t\tredirectUrl: string,\n\t\tpath: string,\n\t\ttimeoutMs: number,\n\t\trenderPage: ((page: OAuthCallbackPage) => string) | undefined,\n\t) {\n\t\tthis.server = server;\n\t\tthis.redirectUrl = redirectUrl;\n\t\tthis.path = path;\n\t\tthis.timeoutMs = timeoutMs;\n\t\tthis.renderPage = renderPage;\n\t}\n\n\tstatic async listen(options: OAuthCallbackServerOptions = {}): Promise<OAuthCallbackServer> {\n\t\tconst host = options.host ?? \"127.0.0.1\";\n\t\tconst redirectHost = options.redirectHost ?? host;\n\t\tconst path = options.path ?? \"/callback\";\n\t\tlet instance: OAuthCallbackServer | undefined;\n\t\tconst server = createServer((request, response) => instance?.handle(request.url ?? \"/\", response));\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tserver.once(\"error\", reject);\n\t\t\tserver.listen(options.port ?? 0, host, () => {\n\t\t\t\tserver.off(\"error\", reject);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tconst address = server.address();\n\t\tif (!address || typeof address === \"string\") throw new Error(\"OAuth callback server did not bind to TCP\");\n\t\tinstance = new OAuthCallbackServer(\n\t\t\tserver,\n\t\t\t`http://${redirectHost.includes(\":\") ? `[${redirectHost}]` : redirectHost}:${address.port}${path}`,\n\t\t\tpath,\n\t\t\toptions.timeoutMs ?? 5 * 60_000,\n\t\t\toptions.renderPage,\n\t\t);\n\t\treturn instance;\n\t}\n\n\twaitForCallback(state: string): Promise<OAuthCallback> {\n\t\tif (this.pending.has(state)) throw new Error(\"OAuth state is already pending\");\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.pending.delete(state);\n\t\t\t\treject(new Error(\"OAuth callback timed out\"));\n\t\t\t}, this.timeoutMs);\n\t\t\tthis.pending.set(state, { resolve, reject, timer });\n\t\t});\n\t}\n\n\tasync close(): Promise<void> {\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tclearTimeout(pending.timer);\n\t\t\tpending.reject(new Error(\"OAuth callback server closed\"));\n\t\t}\n\t\tthis.pending.clear();\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tthis.server.close((error) => (error ? reject(error) : resolve()));\n\t\t});\n\t}\n\n\tprivate reply(response: ServerResponse, status: number, page: OAuthCallbackPage): void {\n\t\tif (this.renderPage) {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" });\n\t\t\tresponse.end(this.renderPage(page));\n\t\t} else {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" }).end(plainText(page));\n\t\t}\n\t}\n\n\tprivate handle(rawUrl: string, response: ServerResponse): void {\n\t\tconst url = new URL(rawUrl, this.redirectUrl);\n\t\tif (url.pathname !== this.path) {\n\t\t\tthis.reply(response, 404, { ok: false, message: \"Not found\" });\n\t\t\treturn;\n\t\t}\n\t\tconst state = url.searchParams.get(\"state\");\n\t\tconst pending = state ? this.pending.get(state) : undefined;\n\t\tif (!state || !pending) {\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Invalid or expired OAuth state\" });\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(pending.timer);\n\t\tthis.pending.delete(state);\n\t\tconst error = url.searchParams.get(\"error\");\n\t\tif (error) {\n\t\t\tconst description = url.searchParams.get(\"error_description\") ?? error;\n\t\t\tpending.reject(new Error(description));\n\t\t\tthis.reply(response, 200, {\n\t\t\t\tok: false,\n\t\t\t\tmessage: \"Authorization failed. You may close this window.\",\n\t\t\t\tdetails: description,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst code = url.searchParams.get(\"code\");\n\t\tif (!code) {\n\t\t\tpending.reject(new Error(\"OAuth callback did not include an authorization code\"));\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Missing authorization code\" });\n\t\t\treturn;\n\t\t}\n\t\tconst iss = url.searchParams.get(\"iss\");\n\t\tpending.resolve({ code, state, ...(iss ? { iss } : {}) });\n\t\tthis.reply(response, 200, { ok: true });\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/callback.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type Server, type ServerResponse } from \"node:http\";\n\nexport interface OAuthCallback {\n\tcode: string;\n\tstate: string;\n\tiss?: string;\n}\n\n/** Outcome shown on the browser page after the redirect. */\nexport type OAuthCallbackPage = { ok: true } | { ok: false; message: string; details?: string };\n\nexport interface OAuthCallbackServerOptions {\n\t/** Address to listen on. Default: `127.0.0.1`. */\n\thost?: string;\n\t/**\n\t * Host name in `redirectUrl`, for example `localhost` for a client registered with it while\n\t * listening on `127.0.0.1`. Default: `host`.\n\t */\n\tredirectHost?: string;\n\tport?: number;\n\tpath?: string;\n\t/** Additional callback paths, for server-specific redirect URIs. */\n\textraPaths?: string[];\n\ttimeoutMs?: number;\n\t/** Render the browser page as HTML. Default: a plain-text message. */\n\trenderPage?: (page: OAuthCallbackPage) => string;\n}\n\nfunction plainText(page: OAuthCallbackPage): string {\n\tif (page.ok) return \"Authorization complete. You may close this window.\";\n\treturn page.details ? `${page.message}\\n\\n${page.details}` : page.message;\n}\n\nexport class OAuthCallbackServer {\n\treadonly redirectUrl: string;\n\tprivate server: Server;\n\tprivate paths: string[];\n\tprivate timeoutMs: number;\n\tprivate renderPage: ((page: OAuthCallbackPage) => string) | undefined;\n\tprivate pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (callback: OAuthCallback) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimer: ReturnType<typeof setTimeout>;\n\t\t\tpath: string | undefined;\n\t\t}\n\t>();\n\n\tprivate constructor(\n\t\tserver: Server,\n\t\tredirectUrl: string,\n\t\tpaths: string[],\n\t\ttimeoutMs: number,\n\t\trenderPage: ((page: OAuthCallbackPage) => string) | undefined,\n\t) {\n\t\tthis.server = server;\n\t\tthis.redirectUrl = redirectUrl;\n\t\tthis.paths = paths;\n\t\tthis.timeoutMs = timeoutMs;\n\t\tthis.renderPage = renderPage;\n\t}\n\n\tstatic async listen(options: OAuthCallbackServerOptions = {}): Promise<OAuthCallbackServer> {\n\t\tconst host = options.host ?? \"127.0.0.1\";\n\t\tconst redirectHost = options.redirectHost ?? host;\n\t\tconst path = options.path ?? \"/callback\";\n\t\tlet instance: OAuthCallbackServer | undefined;\n\t\tconst server = createServer((request, response) => instance?.handle(request.url ?? \"/\", response));\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tserver.once(\"error\", reject);\n\t\t\tserver.listen(options.port ?? 0, host, () => {\n\t\t\t\tserver.off(\"error\", reject);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tconst address = server.address();\n\t\tif (!address || typeof address === \"string\") throw new Error(\"OAuth callback server did not bind to TCP\");\n\t\tinstance = new OAuthCallbackServer(\n\t\t\tserver,\n\t\t\t`http://${redirectHost.includes(\":\") ? `[${redirectHost}]` : redirectHost}:${address.port}${path}`,\n\t\t\t[path, ...(options.extraPaths ?? [])],\n\t\t\toptions.timeoutMs ?? 5 * 60_000,\n\t\t\toptions.renderPage,\n\t\t);\n\t\treturn instance;\n\t}\n\n\twaitForCallback(state: string, path?: string): Promise<OAuthCallback> {\n\t\tif (this.pending.has(state)) throw new Error(\"OAuth state is already pending\");\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.pending.delete(state);\n\t\t\t\treject(new Error(\"OAuth callback timed out\"));\n\t\t\t}, this.timeoutMs);\n\t\t\tthis.pending.set(state, { resolve, reject, timer, path });\n\t\t});\n\t}\n\n\tasync close(): Promise<void> {\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tclearTimeout(pending.timer);\n\t\t\tpending.reject(new Error(\"OAuth callback server closed\"));\n\t\t}\n\t\tthis.pending.clear();\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tthis.server.close((error) => (error ? reject(error) : resolve()));\n\t\t});\n\t}\n\n\tprivate reply(response: ServerResponse, status: number, page: OAuthCallbackPage): void {\n\t\tif (this.renderPage) {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" });\n\t\t\tresponse.end(this.renderPage(page));\n\t\t} else {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" }).end(plainText(page));\n\t\t}\n\t}\n\n\tprivate handle(rawUrl: string, response: ServerResponse): void {\n\t\tconst url = new URL(rawUrl, this.redirectUrl);\n\t\tif (!this.paths.includes(url.pathname)) {\n\t\t\tthis.reply(response, 404, { ok: false, message: \"Not found\" });\n\t\t\treturn;\n\t\t}\n\t\tconst state = url.searchParams.get(\"state\");\n\t\tconst pending = state ? this.pending.get(state) : undefined;\n\t\tif (!state || !pending) {\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Invalid or expired OAuth state\" });\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(pending.timer);\n\t\tthis.pending.delete(state);\n\t\tif (pending.path !== undefined && url.pathname !== pending.path) {\n\t\t\tpending.reject(new Error(\"The authorization response arrived on another redirect URI\"));\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Unexpected redirect URI\" });\n\t\t\treturn;\n\t\t}\n\t\tconst error = url.searchParams.get(\"error\");\n\t\tif (error) {\n\t\t\tconst description = url.searchParams.get(\"error_description\") ?? error;\n\t\t\tpending.reject(new Error(description));\n\t\t\tthis.reply(response, 200, {\n\t\t\t\tok: false,\n\t\t\t\tmessage: \"Authorization failed. You may close this window.\",\n\t\t\t\tdetails: description,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst code = url.searchParams.get(\"code\");\n\t\tif (!code) {\n\t\t\tpending.reject(new Error(\"OAuth callback did not include an authorization code\"));\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Missing authorization code\" });\n\t\t\treturn;\n\t\t}\n\t\tconst iss = url.searchParams.get(\"iss\");\n\t\tpending.resolve({ code, state, ...(iss ? { iss } : {}) });\n\t\tthis.reply(response, 200, { ok: true });\n\t}\n}\n"]}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { AuthProvider, McpFetch } from "../auth-provider.js";
|
|
2
2
|
import { type AuthorizationServerMetadata, type OAuthClientInformationFull, type OAuthClientInformationMixed, type OAuthClientMetadata, type OAuthDiscoveryState, type OAuthTokens } from "./types.js";
|
|
3
3
|
export type AddClientAuthentication = (headers: Headers, params: URLSearchParams, url: string | URL, metadata?: AuthorizationServerMetadata) => void | Promise<void>;
|
|
4
|
+
/** A Client ID Metadata Document URL and a redirect URI it lists. */
|
|
5
|
+
export interface OAuthClientMetadataDocument {
|
|
6
|
+
url: string;
|
|
7
|
+
redirectUrl: string;
|
|
8
|
+
}
|
|
4
9
|
export interface OAuthClientProvider {
|
|
5
10
|
readonly redirectUrl: string | URL;
|
|
6
11
|
readonly clientMetadata: OAuthClientMetadata;
|
|
7
|
-
|
|
12
|
+
/** Called without stored client information. The caller checks server support; the document is not stored. */
|
|
13
|
+
clientMetadataDocument?(metadata: AuthorizationServerMetadata | undefined): OAuthClientMetadataDocument | undefined;
|
|
8
14
|
state?(): string | Promise<string>;
|
|
9
15
|
clientInformation(): OAuthClientInformationMixed | undefined | Promise<OAuthClientInformationMixed | undefined>;
|
|
10
16
|
saveClientInformation?(information: OAuthClientInformationMixed): void | Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/flow.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAuB,MAAM,qBAAqB,CAAC;AAevF,OAAO,EACN,KAAK,2BAA2B,EAEhC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAGhB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,uBAAuB,GAAG,CACrC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,QAAQ,CAAC,EAAE,2BAA2B,KAClC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC;IACnC,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC7C,
|
|
1
|
+
{"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -175,29 +175,28 @@ async function runFlow(provider, options) {
|
|
|
175
175
|
const resource = selectResource(options.serverUrl, discovered.resourceMetadata);
|
|
176
176
|
// `||`, not `??`: an empty scope (for example from `scopes_supported: []`) falls through to the next source.
|
|
177
177
|
const scope = options.scope || discovered.resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
|
|
178
|
-
|
|
178
|
+
const stored = await provider.clientInformation();
|
|
179
|
+
const clientDocument = stored ? undefined : provider.clientMetadataDocument?.(metadata);
|
|
180
|
+
if (clientDocument) {
|
|
181
|
+
const url = new URL(clientDocument.url);
|
|
182
|
+
if (url.protocol !== "https:" || url.pathname === "/")
|
|
183
|
+
throw new Error("Invalid OAuth client metadata URL");
|
|
184
|
+
}
|
|
185
|
+
let client = stored ?? (clientDocument && { client_id: clientDocument.url });
|
|
179
186
|
if (!client) {
|
|
180
187
|
if (options.authorizationCode)
|
|
181
188
|
throw new Error("OAuth client information is missing during code exchange");
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
throw new Error("OAuth client information cannot be persisted");
|
|
192
|
-
client = await registerClient(discovered.authorizationServerUrl, {
|
|
193
|
-
metadata,
|
|
194
|
-
clientMetadata: provider.clientMetadata,
|
|
195
|
-
scope,
|
|
196
|
-
fetch: options.fetch,
|
|
197
|
-
});
|
|
198
|
-
await provider.saveClientInformation(client);
|
|
199
|
-
}
|
|
189
|
+
if (!provider.saveClientInformation)
|
|
190
|
+
throw new Error("OAuth client information cannot be persisted");
|
|
191
|
+
client = await registerClient(discovered.authorizationServerUrl, {
|
|
192
|
+
metadata,
|
|
193
|
+
clientMetadata: provider.clientMetadata,
|
|
194
|
+
scope,
|
|
195
|
+
fetch: options.fetch,
|
|
196
|
+
});
|
|
197
|
+
await provider.saveClientInformation(client);
|
|
200
198
|
}
|
|
199
|
+
const redirectUrl = clientDocument?.redirectUrl ?? provider.redirectUrl;
|
|
201
200
|
const tokenOptions = {
|
|
202
201
|
metadata,
|
|
203
202
|
clientInformation: client,
|
|
@@ -216,7 +215,7 @@ async function runFlow(provider, options) {
|
|
|
216
215
|
...tokenOptions,
|
|
217
216
|
code: options.authorizationCode,
|
|
218
217
|
codeVerifier: await provider.codeVerifier(),
|
|
219
|
-
redirectUrl
|
|
218
|
+
redirectUrl,
|
|
220
219
|
});
|
|
221
220
|
// A response without `scope` grants the requested scope (RFC 6749 §5.1). Recorded so a step-up can
|
|
222
221
|
// keep it. Callers pass the options of the authorization request, so `scope` is what was requested.
|
|
@@ -245,7 +244,7 @@ async function runFlow(provider, options) {
|
|
|
245
244
|
const authorization = await startAuthorization(discovered.authorizationServerUrl, {
|
|
246
245
|
metadata,
|
|
247
246
|
clientInformation: client,
|
|
248
|
-
redirectUrl
|
|
247
|
+
redirectUrl,
|
|
249
248
|
scope,
|
|
250
249
|
state,
|
|
251
250
|
resource,
|