@agimon-ai/po-mcp 0.0.0-alpha.0
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/LICENSE +21 -0
- package/README.md +223 -0
- package/dist/apiContracts.cjs +269 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +137 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +258 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/extensions/mcp-ui.mjs +31 -0
- package/dist/extensions/mcp-ui.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +104 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +99 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/server.cjs +2852 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +2839 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +2200 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index.cjs +18 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +9 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mcpCatalog-6Tpt6Gqn.cjs +900 -0
- package/dist/mcpCatalog-6Tpt6Gqn.cjs.map +1 -0
- package/dist/mcpCatalog-SlqWS-sb.mjs +806 -0
- package/dist/mcpCatalog-SlqWS-sb.mjs.map +1 -0
- package/dist/mcpConfig-BYESy-zP.d.mts +57 -0
- package/dist/mcpConfig-BYESy-zP.d.mts.map +1 -0
- package/dist/projection-gyAA2jRB.mjs +43 -0
- package/dist/projection-gyAA2jRB.mjs.map +1 -0
- package/dist/projection-w3XxXmVi.cjs +51 -0
- package/dist/projection-w3XxXmVi.cjs.map +1 -0
- package/dist/projection.cjs +17 -0
- package/dist/projection.d.mts +12 -0
- package/dist/projection.d.mts.map +1 -0
- package/dist/projection.mjs +4 -0
- package/dist/rolldown-runtime-C0BPl7ul.cjs +43 -0
- package/llms.txt +9 -0
- package/package.json +157 -0
- package/src/prompts/po-use-mcp/SKILL.md +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["Type","net","https","path","fs","constants","Value","writeSessionAttachment","path","Type","defineDoomPluginMethod","record","normalizeMcpAppMetadata","normalizeMcpAppMetadata","defineServerMethod","randomUUID","isAppVisibleMcpTool","Type","mcpToolExecutionMetadata","Value","DIRECT_TOOLS_ENV","McpCatalog","readSessionConfig","buildMcpConfigGroups","readCachedCatalog","isModelVisibleMcpTool","normalizeMcpAppMetadata","JSON_HEADERS","json","loadHarnessState","isDoomMcpProjection","mcpSessionConfigFromProjection","path","readSessionConfig","CONTEXT_TOOL_WARNINGS_STATUS_KEY","isModelVisibleMcpTool","DOOM_MCP_PROJECTION_RESOLVER_SERVICE","DOOM_HEADLESS_HOST_SERVICE","DOOM_MCP_STATUS_SERVICE","DOOM_MCP_TOOL_RESOLVER_SERVICE","DOOM_CHILD_SESSION_MCP_TOOL_SERVICE","defineRoot","FileTokenStore","toPiToolName","os","fs","path","mcpSessionConfigFromProjection","buildMcpConfigGroups","readCachedCatalog","McpRuntimeOwner","randomUUID","hubCallbackSink","defineApiRoutes","apiResponse","routes","defineRoute","defineRoute","defineServerCommand","defineRoutedContribution","defineResource","DOOM_HELP_WHEN","readPackageResource","defineServerPlugin","composeServerProviderOverrides","rootSession","apiRoute","composeRootHooks","apiRoute2","commandMcp","methodApps","resourcePoUseMcp"],"sources":["../../src/schemas/fileTransfer.ts","../../src/services/fileTransfer/download.ts","../../src/services/fileTransfer/storage.ts","../../src/services/fileTransfer/index.ts","../../src/schemas/mcpApps.ts","../../src/services/mcpFileParams/index.ts","../../src/services/mcpTools/index.ts","../../src/services/mcpApps/index.ts","../../src/services/mcpHeadlessTools/index.ts","../../src/schemas/mcpHeadlessTool.ts","../../src/services/mcpSessionTools/index.ts","../../src/constants/mcp.ts","../../src/constants/piMcp.ts","../../src/types/webMcp.ts","../../src/services/mcpCommand/index.ts","../../src/services/directTools/index.ts","../../src/services/directToolsEnvironment/index.ts","../../src/services/toolVisibility/index.ts","../../src/services/mcpSession/index.ts","../../src/services/mcpToolCost/index.ts","../../src/services/mcpSessionApi/index.ts","../../src/services/serverRuntime/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/keyringTokenStore/index.ts","../../src/services/mcpSettingsManager/index.ts","../../src/types/apiRoutes.ts","../../src/services/mcpHubApi/index.ts","../../src/extensions/(backend)/api/mcp/route.server.ts","../../src/extensions/workspaces/sessions/(backend)/api/mcp-session/route.server.ts","../../src/extensions/workspaces/sessions/(backend)/command/mcp.server.ts","../../src/extensions/workspaces/sessions/(backend)/method/apps.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/po-use-mcp.server.ts","../../generated/server.ts"],"sourcesContent":["import { Type } from 'typebox';\n\nexport const ShareFileParameters = Type.Object(\n { path: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport const SaveFileParameters = Type.Object(\n {\n file: Type.Union([\n Type.Object(\n {\n download_url: Type.String(),\n file_name: Type.String(),\n file_id: Type.Optional(Type.String()),\n mime_type: Type.Optional(Type.String()),\n },\n { additionalProperties: false },\n ),\n Type.Object({ name: Type.String(), data_base64: Type.String() }, { additionalProperties: false }),\n ]),\n path: Type.Optional(Type.String()),\n },\n { additionalProperties: false },\n);\n","import dns from 'node:dns/promises';\nimport https from 'node:https';\nimport net from 'node:net';\n\nconst MAX_BYTES = 25 * 1024 * 1024;\n/** Conservative public-address allowlist. IPv6 is limited to global unicast, excluding special ranges. */\nexport function isPublicAddress(address: string): boolean {\n if (net.isIP(address) === 4) {\n const [a, b] = address.split('.').map(Number);\n return !(\n a === 0 ||\n a === 10 ||\n a === 127 ||\n a >= 224 ||\n (a === 100 && b >= 64 && b <= 127) ||\n (a === 169 && b === 254) ||\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && (b === 168 || b === 0 || b === 2)) ||\n (a === 198 && (b === 18 || b === 19 || b === 51)) ||\n (a === 203 && b === 0)\n );\n }\n return net.isIP(address) === 6 && /^[23]/u.test(address) && !/^(2001:|2002:|3fff:)/iu.test(address);\n}\n\nexport async function downloadPublicFile(input: string, cancellation?: AbortSignal): Promise<Buffer> {\n const signal = AbortSignal.any([AbortSignal.timeout(30_000), ...(cancellation ? [cancellation] : [])]);\n let url = new URL(input);\n for (let redirects = 0; ; redirects += 1) {\n signal.throwIfAborted();\n if (url.protocol !== 'https:' || url.username || url.password)\n throw new Error('Only public HTTPS URLs without credentials are accepted.');\n const hostname = url.hostname.replace(/^\\[|\\]$/gu, '');\n const addresses = net.isIP(hostname)\n ? [{ address: hostname, family: net.isIP(hostname) }]\n : await new Promise<Awaited<ReturnType<typeof dns.lookup>>[]>((resolve, reject) => {\n const abort = () => reject(signal.reason);\n signal.addEventListener('abort', abort, { once: true });\n dns\n .lookup(hostname, { all: true })\n .then(resolve, reject)\n .finally(() => signal.removeEventListener('abort', abort));\n if (signal.aborted) abort();\n });\n signal.throwIfAborted();\n if (!addresses.length || addresses.some(({ address }) => !isPublicAddress(address)))\n throw new Error('URL must resolve only to public addresses.');\n const pinned = addresses[0];\n const result = await new Promise<Buffer | URL>((resolve, reject) => {\n const request = https.get(\n url,\n {\n signal,\n agent: false,\n lookup: (_host, options, callback) => {\n if (typeof options === 'object' && options.all) callback(null, [pinned]);\n else callback(null, pinned.address, pinned.family);\n },\n },\n (response) => {\n const status = response.statusCode ?? 0;\n if ([301, 302, 303, 307, 308].includes(status)) {\n response.destroy();\n if (redirects >= 3 || !response.headers.location)\n reject(new Error('Too many redirects or missing redirect location.'));\n else {\n try {\n resolve(new URL(response.headers.location, url));\n } catch (error) {\n reject(error);\n }\n }\n return;\n }\n if (status !== 200 || Number(response.headers['content-length']) > MAX_BYTES) {\n response.destroy();\n reject(new Error('Download refused: status or size limit.'));\n return;\n }\n const chunks: Buffer[] = [];\n let size = 0;\n response.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BYTES) response.destroy(new Error('Download exceeds 25 MiB.'));\n else chunks.push(chunk);\n });\n response.on('error', reject);\n response.on('aborted', () => reject(new Error('Download response was interrupted.')));\n response.on('close', () => {\n if (!response.complete) reject(new Error('Download response was interrupted.'));\n });\n response.on('end', () => resolve(Buffer.concat(chunks, size)));\n },\n );\n request.on('error', reject);\n });\n if (Buffer.isBuffer(result)) return result;\n url = result;\n }\n}\n\nexport function decodeFileBase64(data: string): Buffer {\n if (\n data.length > 4 * Math.ceil((5 * 1024 * 1024) / 3) ||\n data.length % 4 !== 0 ||\n !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)\n )\n throw new Error('Invalid or oversized base64 file.');\n const size = (data.length / 4) * 3 - (data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0);\n if (size < 0 || (data.includes('=') && data.length < 4)) throw new Error('Invalid base64 padding.');\n if (size > 5 * 1024 * 1024) throw new Error('Base64 file exceeds 5 MiB.');\n return Buffer.from(data, 'base64');\n}\n","import { constants } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\n// ponytail: Parent identity rechecks are best-effort under concurrent swaps.\n// Atomic containment requires descriptor-relative native traversal.\n/** Existing parents only, pinned by identity before and after exclusive creation. */\nexport async function writeCwdFile(cwd: string, relative: string, bytes: Uint8Array): Promise<string> {\n if (\n !relative ||\n path.isAbsolute(relative) ||\n relative.includes('\\\\') ||\n relative.includes('\\0') ||\n relative.split('/').some((part) => !part || part === '.' || part === '..')\n )\n throw new Error('Path must be relative without traversal.');\n const root = await fs.realpath(cwd);\n const target = path.join(root, relative);\n const parents = [root];\n for (const segment of relative.split('/').slice(0, -1)) parents.push(path.join(parents.at(-1)!, segment));\n const identities = await Promise.all(\n parents.map(async (parent) => {\n const stat = await fs.lstat(parent);\n if (!stat.isDirectory() || stat.isSymbolicLink() || (await fs.realpath(parent)) !== parent)\n throw new Error('Unsafe parent directory.');\n return stat;\n }),\n );\n const check = async () => {\n for (let i = 0; i < parents.length; i += 1) {\n const stat = await fs.lstat(parents[i]);\n if (\n stat.dev !== identities[i].dev ||\n stat.ino !== identities[i].ino ||\n (await fs.realpath(parents[i])) !== parents[i]\n )\n throw new Error('Parent directory changed.');\n }\n };\n await check();\n const handle = await fs.open(\n target,\n constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW,\n 0o600,\n );\n try {\n const identity = await handle.stat();\n const checkFile = async () => {\n const named = await fs.lstat(target);\n if (named.dev !== identity.dev || named.ino !== identity.ino || (await fs.realpath(target)) !== target)\n throw new Error('File identity changed.');\n };\n await check();\n await checkFile();\n await handle.writeFile(bytes);\n await check();\n await checkFile();\n return target;\n } catch (error) {\n // Only our exclusively-created inode is truncated, even if its parents moved.\n await handle.truncate(0);\n // Never unlink through a mutable pathname: Node cannot atomically prove the\n // name still identifies this descriptor. Failed writes may leave an empty file.\n throw error;\n } finally {\n await handle.close();\n }\n}\n","import path from 'node:path';\n\nimport type { DoomHeadlessTool } from '@agimon-ai/po-core/headless';\nimport { writeSessionAttachment, type DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\nimport { Value } from 'typebox/value';\n\nimport { SaveFileParameters, ShareFileParameters } from '../../schemas/fileTransfer';\nimport { decodeFileBase64, downloadPublicFile } from './download';\nimport { writeCwdFile } from './storage';\n\nexport function createFileTransferTools(owner?: DoomServerPluginContext): DoomHeadlessTool[] {\n return [\n {\n // web-plugin-tool-renderers: ignore share_file, remote-only file transfer\n name: 'share_file',\n description: 'Publish a session file as a short-lived public download link. No consent prompt.',\n parameters: ShareFileParameters,\n _meta: { 'doompi/fileTransfer': true },\n async execute(_id, input, signal) {\n const executionSignal = AbortSignal.any([\n ...(signal ? [signal] : []),\n ...(owner?.signal ? [owner.signal] : []),\n ]);\n executionSignal.throwIfAborted();\n if (!Value.Check(ShareFileParameters, input)) throw new Error('Invalid share_file parameters.');\n const host = owner?.host.context;\n if (!host?.shareFile) throw new Error('File sharing is unavailable.');\n const shared = await host.shareFile(input.path, 'share_file');\n if (executionSignal.aborted) {\n shared.revoke();\n executionSignal.throwIfAborted();\n }\n const result = {\n url: shared.url,\n fileName: shared.fileName,\n mimeType: shared.mimeType,\n size: shared.size,\n expiresAt: shared.expiresAt,\n maxDownloads: shared.maxDownloads,\n };\n return { content: [{ type: 'text', text: JSON.stringify(result) }], structuredContent: { ...result } };\n },\n },\n {\n // web-plugin-tool-renderers: ignore save_file, remote-only file transfer\n name: 'save_file',\n description:\n 'Save a public HTTPS file (25 MiB maximum) or base64 file (5 MiB maximum) to session attachments or a new relative cwd path.',\n parameters: SaveFileParameters,\n _meta: { 'doompi/fileTransfer': true, 'openai/fileParams': ['file'] },\n async execute(_id, input, cancellation) {\n if (!Value.Check(SaveFileParameters, input)) throw new Error('Provide exactly one file form.');\n const context = owner?.agent?.context;\n if (!context) throw new Error('Session file storage is unavailable.');\n const signal = AbortSignal.any([\n ...(cancellation ? [cancellation] : []),\n ...(owner?.signal ? [owner.signal] : []),\n ]);\n signal.throwIfAborted();\n const file = input.file;\n const bytes =\n 'download_url' in file\n ? await downloadPublicFile(file.download_url, signal)\n : decodeFileBase64(file.data_base64);\n signal.throwIfAborted();\n const name = 'download_url' in file ? file.file_name : file.name;\n const result =\n input.path === undefined\n ? await writeSessionAttachment(context.sessionId, name, bytes, context.environment)\n : {\n path: await writeCwdFile(context.cwd, input.path, bytes),\n name: path.basename(input.path),\n size: bytes.length,\n mimeType: 'application/octet-stream',\n };\n return { content: [{ type: 'text', text: JSON.stringify(result) }], structuredContent: { ...result } };\n },\n },\n ];\n}\n","import { defineDoomPluginMethod } from '@agimon-ai/po-core/pluginProtocol';\nimport { Type } from 'typebox';\n\nexport type { McpAppOpenResult } from '../types/webMcp';\n\nconst Lease = Type.String({ minLength: 1, maxLength: 128 });\nconst JsonObject = Type.Record(Type.String(), Type.Unknown());\nconst Empty = Type.Object({}, { additionalProperties: false });\nconst Result = Type.Object({\n content: Type.Array(Type.Unknown()),\n structuredContent: Type.Optional(Type.Unknown()),\n _meta: Type.Optional(JsonObject),\n isError: Type.Optional(Type.Boolean()),\n});\nconst Address = { service: 'mcp.apps', scope: 'session', direction: 'client-to-server' } as const;\n\nexport const mcpAppOpenMethod = defineDoomPluginMethod({\n ...Address,\n method: 'open',\n input: Type.Object({ toolCallId: Type.String({ minLength: 1, maxLength: 512 }) }, { additionalProperties: false }),\n output: Type.Object({\n leaseId: Lease,\n html: Type.String(),\n resourceUri: Type.String(),\n protocol: Type.Union([Type.Literal('mcp'), Type.Literal('openai')]),\n resourceMeta: JsonObject,\n tool: Type.Object({\n name: Type.String(),\n description: Type.String(),\n inputSchema: Type.Object({ type: Type.Literal('object') }, { additionalProperties: true }),\n _meta: JsonObject,\n }),\n args: JsonObject,\n result: Result,\n state: Type.Unknown(),\n readOnly: Type.Boolean(),\n }),\n});\n\nexport const mcpAppActivateMethod = defineDoomPluginMethod({\n ...Address,\n method: 'activate',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Type.Object({ readOnly: Type.Literal(false) }),\n});\nexport const mcpAppCallToolMethod = defineDoomPluginMethod({\n ...Address,\n method: 'callTool',\n input: Type.Object(\n { leaseId: Lease, name: Type.String({ minLength: 1, maxLength: 256 }), arguments: JsonObject },\n { additionalProperties: false },\n ),\n output: Result,\n});\nexport const mcpAppSetStateMethod = defineDoomPluginMethod({\n ...Address,\n method: 'setState',\n input: Type.Object({ leaseId: Lease, state: Type.Unknown() }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppFollowUpMethod = defineDoomPluginMethod({\n ...Address,\n method: 'followUp',\n input: Type.Object(\n { leaseId: Lease, prompt: Type.String({ minLength: 1, maxLength: 16000 }) },\n { additionalProperties: false },\n ),\n output: Empty,\n});\nexport const mcpAppCloseMethod = defineDoomPluginMethod({\n ...Address,\n method: 'close',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppMethods = [\n mcpAppOpenMethod,\n mcpAppActivateMethod,\n mcpAppCallToolMethod,\n mcpAppSetStateMethod,\n mcpAppFollowUpMethod,\n mcpAppCloseMethod,\n] as const;\n","import type { DoomSharedFile } from '@agimon-ai/po-core/packageApi';\n\nimport type {\n McpConsentedFilePublisherOptions,\n McpFileParamTool,\n McpFileParamValue,\n McpFilePublisher,\n McpFileShareAudit,\n McpPublishedFileParams,\n} from './type';\n\n/** ChatGPT Apps metadata naming the top-level arguments that carry a file. */\nconst FILE_PARAMS_META_KEY = 'openai/fileParams';\nconst MAX_FILE_PARAMS = 16;\nconst FILE_ID_PREFIX = 'doomfile_';\nconst FILE_SHARE_ENTRY_TYPE = 'mcp.file.share';\nconst CONSENT_TIMEOUT_MS = 120_000;\nconst NO_PUBLISHER = 'This MCP tool takes a file, which needs the Po web host with remote access on.';\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction filePath(value: unknown): string | undefined {\n const path = record(value)?.path;\n return typeof path === 'string' ? path : undefined;\n}\n\n/** Declared file parameters that the input schema really has at its top level. */\nexport function fileParamNames(tool: Pick<McpFileParamTool, 'inputSchema' | '_meta'>): string[] {\n const declared = tool._meta?.[FILE_PARAMS_META_KEY];\n const properties = record(tool.inputSchema.properties);\n if (!Array.isArray(declared) || properties === undefined) return [];\n const names = declared.filter((name): name is string => typeof name === 'string' && Object.hasOwn(properties, name));\n return [...new Set(names)].slice(0, MAX_FILE_PARAMS);\n}\n\n/** What the model is asked for: a `{path}` object in place of each server file shape. */\nexport function modelInputSchema(tool: Pick<McpFileParamTool, 'inputSchema' | '_meta'>): Record<string, unknown> {\n // Pi requires a schema; a downstream tool that declares none takes any object.\n if (Object.keys(tool.inputSchema).length === 0) return { type: 'object', properties: {} };\n const names = fileParamNames(tool);\n if (names.length === 0) return tool.inputSchema;\n const properties = { ...record(tool.inputSchema.properties) };\n for (const name of names) {\n const description = record(properties[name])?.description;\n properties[name] = {\n type: 'object',\n description: `${typeof description === 'string' ? description : 'A file.'} Pass {\"path\": \"<file in the working directory, or the path from an Attached file note>\"}.`,\n properties: { path: { type: 'string' } },\n required: ['path'],\n additionalProperties: false,\n };\n }\n return { ...tool.inputSchema, properties };\n}\n\n/**\n * Swaps each `{path}` file argument for a published link, on a copy.\n *\n * Runs before the server is dialled, so a refused share never reaches it. Values that\n * are not `{path}` objects pass through, including a file a widget already shaped.\n */\nexport async function publishFileParams(\n tool: Pick<McpFileParamTool, 'inputSchema' | '_meta'>,\n params: Record<string, unknown>,\n publish?: (path: string) => Promise<DoomSharedFile>,\n): Promise<McpPublishedFileParams> {\n const names = fileParamNames(tool).filter((name) => filePath(params[name]) !== undefined);\n if (names.length === 0) return { outbound: params, release: () => undefined };\n if (publish === undefined) throw new Error(NO_PUBLISHER);\n const outbound = { ...params };\n const shared: DoomSharedFile[] = [];\n const release = () => {\n for (const file of shared.splice(0)) file.revoke();\n };\n try {\n for (const name of names) {\n const file = await publish(filePath(params[name])!);\n shared.push(file);\n outbound[name] = {\n file_id: `${FILE_ID_PREFIX}${crypto.randomUUID()}`,\n download_url: file.url,\n file_name: file.fileName,\n mime_type: file.mimeType,\n } satisfies McpFileParamValue;\n }\n } catch (error) {\n release();\n throw error;\n }\n return { outbound, release };\n}\n\n/**\n * Publishes a file only after the user approves it for this server and tool.\n *\n * The host mints first so the dialog can name the file and its size; the link leaves\n * this function only on approval. No client, no answer within two minutes, a\n * cancelled call, or a failed audit all revoke it.\n */\nexport function createConsentedFilePublisher(options: McpConsentedFilePublisherOptions): McpFilePublisher {\n return async (path, tool, signal) => {\n const label = `${tool.serverName} / ${tool.toolName}`;\n const shared = await options.shareFile(path, label);\n try {\n const host = options.host();\n if (host === undefined) throw new Error(`There is no Po client to approve sharing \"${shared.fileName}\".`);\n const deadline = new AbortController();\n const timer = setTimeout(() => deadline.abort(new Error('No answer within two minutes.')), CONSENT_TIMEOUT_MS);\n const abort = AbortSignal.any(\n [deadline.signal, signal, options.signal].filter(\n (candidate): candidate is AbortSignal => candidate !== undefined,\n ),\n );\n // Settles on abort even when a client ignores the signal it was given.\n const abandoned = new Promise<never>((_resolve, reject) => {\n if (abort.aborted) reject(abort.reason);\n abort.addEventListener('abort', () => reject(abort.reason), { once: true });\n });\n const answer = await Promise.race([\n host.context.client.request(\n {\n kind: 'confirm',\n title: 'Share a file with an MCP server?',\n message: `Share \"${shared.fileName}\" (${shared.size} bytes) with ${label}? Po publishes it at a link on your remote-access tunnel until this call finishes (10 minutes at most). Cloudflare and ${tool.serverName} can read the file.`,\n },\n abort,\n ),\n abandoned,\n ])\n // A timeout, a cancelled call, or a lost client is an answer: not approved.\n .then(\n (accepted): McpFileShareAudit['outcome'] => (accepted === true ? 'shared' : 'declined'),\n (): McpFileShareAudit['outcome'] => 'unanswered',\n )\n .finally(() => clearTimeout(timer));\n await host.context.session.appendCustomEntry(FILE_SHARE_ENTRY_TYPE, {\n file: shared.fileName,\n server: tool.serverName,\n tool: tool.toolName,\n outcome: answer,\n } satisfies McpFileShareAudit);\n if (answer !== 'shared') throw new Error(`The user declined to share \"${shared.fileName}\".`);\n return shared;\n } catch (error) {\n shared.revoke();\n throw error;\n }\n };\n}\n","import type { McpClientManagerService } from '@agimon-ai/mcp-proxy';\nimport type { DoomHeadlessToolResult } from '@agimon-ai/po-core/headless';\nimport type { CallToolResult } from '@modelcontextprotocol/server';\nimport type { TSchema } from 'typebox';\n\nimport { mcpToolExecutionMetadata, normalizeMcpAppMetadata, type CatalogTool } from '../../services/mcpCatalog';\nimport type { McpAppPresentation, McpResultBlock, McpToolDetails } from '../../types/webMcp';\nimport { modelInputSchema, publishFileParams } from '../mcpFileParams';\nimport type { McpDirectTool } from '../mcpSessionTools';\n\nconst MAX_APP_RESULT_BYTES = 1024 * 1024;\nconst appSnapshots = new WeakMap<CallToolResult, McpAppPresentation>();\n\n/** Clone before output guards can replace structured data or mutate the source. */\nexport function captureMcpAppResult(tool: CatalogTool, result: CallToolResult): McpAppPresentation | undefined {\n const app = normalizeMcpAppMetadata(tool._meta);\n if (!app.appVisible && !app.resourceUri) return undefined;\n try {\n const json = JSON.stringify(result);\n if (Buffer.byteLength(json, 'utf8') > MAX_APP_RESULT_BYTES) return undefined;\n return {\n version: 1,\n ...(app.resourceUri === undefined ? {} : { resourceUri: app.resourceUri, protocol: app.protocol }),\n result: JSON.parse(json) as CallToolResult,\n };\n } catch {\n // Non-JSON or oversized results retain their normal text fallback without an App.\n return undefined;\n }\n}\n\n/** Historical details are untrusted JSON; reject malformed or unbounded snapshots. */\nexport function parseMcpAppSnapshot(value: unknown): McpAppPresentation | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n if (\n record.version !== 1 ||\n typeof record.result !== 'object' ||\n record.result === null ||\n Array.isArray(record.result)\n )\n return undefined;\n if (\n record.resourceUri !== undefined &&\n (typeof record.resourceUri !== 'string' ||\n !record.resourceUri.startsWith('ui://') ||\n record.resourceUri.length > 8192)\n )\n return undefined;\n if (record.protocol !== undefined && record.protocol !== 'mcp' && record.protocol !== 'openai') return undefined;\n if ((record.resourceUri === undefined) !== (record.protocol === undefined)) return undefined;\n const result = record.result as Record<string, unknown>;\n if (!Array.isArray(result.content) || (result.isError !== undefined && typeof result.isError !== 'boolean'))\n return undefined;\n if (\n result.content.some(\n (block: unknown) =>\n typeof block !== 'object' || block === null || !('type' in block) || typeof block.type !== 'string',\n )\n )\n return undefined;\n try {\n const json = JSON.stringify(value);\n if (Buffer.byteLength(json, 'utf8') > MAX_APP_RESULT_BYTES) return undefined;\n return JSON.parse(json) as McpAppPresentation;\n } catch {\n // A non-JSON persisted payload cannot be replayed safely.\n return undefined;\n }\n}\n\n/** Associate the original private payload with the guarded result without widening MCP wire output. */\nexport function retainMcpAppResult(result: CallToolResult, snapshot: McpAppPresentation | undefined): void {\n if (snapshot) appSnapshots.set(result, snapshot);\n}\n\ntype ContentBlock = CallToolResult['content'][number];\n\n/** The text of a downstream result: its text blocks joined, which is what the model reads. */\nfunction resultText(result: Pick<CallToolResult, 'content'>): string {\n return (result.content ?? [])\n .flatMap((block) => (block.type === 'text' ? [block.text] : []))\n .join('\\n')\n .trim();\n}\n\n/** The image blocks, re-emitted as Pi's own image content so the model and the cockpit both see them. */\nfunction resultImages(result: CallToolResult): DoomHeadlessToolResult['content'] {\n return (result.content ?? []).flatMap((block: ContentBlock) =>\n block.type === 'image' ? [{ type: 'image' as const, data: block.data, mimeType: block.mimeType }] : [],\n );\n}\n\n/**\n * Everything else a downstream result carried: audio, resource links, embedded\n * resources, and the structured content. Pi's content cannot hold them, so\n * they ride the result's details for the cockpit's MCP message to render.\n */\nfunction resultBlocks(result: CallToolResult): McpResultBlock[] {\n const blocks: McpResultBlock[] = [];\n for (const block of result.content ?? []) {\n if (block.type === 'audio') blocks.push({ type: 'audio', data: block.data, mimeType: block.mimeType });\n else if (block.type === 'resource_link') {\n blocks.push({\n type: 'resource_link',\n uri: block.uri,\n name: block.name,\n ...(block.title === undefined ? {} : { title: block.title }),\n ...(block.description === undefined ? {} : { description: block.description }),\n ...(block.mimeType === undefined ? {} : { mimeType: block.mimeType }),\n });\n } else if (block.type === 'resource') {\n const resource = block.resource;\n blocks.push({\n type: 'resource',\n uri: resource.uri,\n ...(resource.mimeType === undefined ? {} : { mimeType: resource.mimeType }),\n ...('text' in resource && typeof resource.text === 'string' ? { text: resource.text } : {}),\n ...('blob' in resource && typeof resource.blob === 'string' ? { blob: resource.blob } : {}),\n });\n }\n }\n const structured = structuredRecord(result);\n if (structured !== undefined) blocks.push({ type: 'structured', value: structured });\n return blocks;\n}\n\n/**\n * MCP v2 allows any JSON value as structured content; Po's contract carries an object, which\n * is all v1 permitted. Any other value still reaches the model through the text fallback.\n */\nfunction structuredRecord(result: CallToolResult): Record<string, unknown> | undefined {\n const value = result.structuredContent;\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** Remote MCP preserves error flags and public structured results instead of Pi's thrown-error convention. */\nexport function toHeadlessToolResult(\n tool: CatalogTool,\n result: CallToolResult,\n): DoomHeadlessToolResult & { details: McpToolDetails } {\n const text =\n resultText(result) ||\n (result.structuredContent === undefined ? 'No output.' : JSON.stringify(result.structuredContent));\n const blocks = resultBlocks(result);\n const structured = structuredRecord(result);\n const app =\n appSnapshots.get(result) ??\n (normalizeMcpAppMetadata(tool._meta).resourceUri === undefined ? undefined : captureMcpAppResult(tool, result));\n return {\n content: [{ type: 'text', text }, ...resultImages(result)],\n ...(structured === undefined ? {} : { structuredContent: structured }),\n ...(result.isError === undefined ? {} : { isError: result.isError }),\n ...(result._meta === undefined ? {} : { _meta: result._meta }),\n details: {\n server: tool.serverName,\n tool: tool.toolName,\n ...(blocks.length > 0 ? { blocks } : {}),\n ...(app === undefined ? {} : { app }),\n },\n };\n}\n\n/**\n * Supplies the live client manager, or nothing before the runtime has started.\n *\n * A getter rather than the manager itself: tools are registered from the cached\n * catalog before any container exists, and the same registration has to reach\n * whichever container is live when the tool is finally called.\n */\n\nexport type ClientManagerSource = () => McpClientManagerService | undefined;\nexport type McpToolAvailability = (tool: CatalogTool) => boolean;\n\nconst ALWAYS_AVAILABLE: McpToolAvailability = () => true;\n\n/**\n * Creates one native downstream tool.\n *\n * Availability is checked at execution time. The connection is\n * resolved at execution time rather than captured, so a server that reconnects\n * underneath keeps working.\n */\nexport function createMcpTool(\n clientManagerSource: ClientManagerSource,\n tool: CatalogTool,\n isAvailable: McpToolAvailability = ALWAYS_AVAILABLE,\n executeTool?: (\n tool: CatalogTool,\n parameters: Record<string, unknown>,\n signal?: AbortSignal,\n ) => Promise<CallToolResult>,\n): McpDirectTool {\n return {\n name: tool.piName,\n label: `${tool.serverName}: ${tool.toolName}`,\n description: tool.description ?? `${tool.toolName} on the ${tool.serverName} MCP server.`,\n // The schema arrives as JSON Schema at runtime, so it is wrapped rather than\n // built: TypeBox validates the shape without it having to be declared here.\n // Type.Unsafe only brands this runtime JSON Schema object. A type cast keeps\n // cached stub registration from evaluating the whole TypeBox package.\n // File parameters are declared as `{path}` objects; they are published at call time.\n parameters: modelInputSchema(tool) as TSchema,\n ...(tool._meta === undefined ? {} : { _meta: mcpToolExecutionMetadata(tool) }),\n async execute(_toolCallId, params, signal) {\n if (!isAvailable(tool)) {\n throw new Error(`MCP tool ${tool.piName} is not available in the current session configuration.`);\n }\n if (executeTool) {\n return toHeadlessToolResult(tool, await executeTool(tool, (params ?? {}) as Record<string, unknown>, signal));\n }\n // No publisher on this path, so a file argument is refused before anything is dialled.\n const { outbound } = await publishFileParams(tool, (params ?? {}) as Record<string, unknown>);\n const clientManager = clientManagerSource();\n if (!clientManager) {\n throw new Error(`The MCP runtime is not ready, so ${tool.serverName} cannot be reached yet.`);\n }\n const connection = await clientManager.ensureConnected(tool.serverName);\n const timeout = clientManager.getServerRequestTimeout(tool.serverName);\n const result = await connection.callTool(\n tool.toolName,\n outbound,\n timeout === undefined ? undefined : { timeout },\n );\n return toHeadlessToolResult(tool, result);\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type { DoomHeadlessHostService } from '@agimon-ai/po-core/headless';\nimport type { DoomPluginCaller } from '@agimon-ai/po-core/pluginProtocol';\nimport { defineServerMethod } from '@agimon-ai/po-core/serverFacet';\n\nimport {\n mcpAppActivateMethod,\n mcpAppCallToolMethod,\n mcpAppCloseMethod,\n mcpAppFollowUpMethod,\n mcpAppOpenMethod,\n type McpAppOpenResult,\n mcpAppSetStateMethod,\n} from '../../schemas/mcpApps';\nimport { isAppVisibleMcpTool, normalizeMcpAppMetadata } from '../mcpCatalog';\nimport type { McpSessionToolsService } from '../mcpSessionTools';\nimport { parseMcpAppSnapshot } from '../mcpTools';\n\nconst STATE_ENTRY = 'mcp.app.state';\nconst MAX_HTML_BYTES = 2 * 1024 * 1024;\nconst MAX_RESULT_BYTES = 1024 * 1024;\nconst MAX_STATE_BYTES = 64 * 1024;\nconst MAX_LEASES = 64;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction boundedJson<T>(value: T, limit: number, label: string): T {\n const encoded = JSON.stringify(value);\n if (encoded === undefined || Buffer.byteLength(encoded) > limit) throw new Error(`${label} exceeds its size limit.`);\n return JSON.parse(encoded) as T;\n}\n\ninterface Lease {\n id: string;\n connectionId: string;\n host: DoomHeadlessHostService;\n toolCallId: string;\n server: string;\n tool: string;\n resourceUri: string;\n revision: number;\n runtimeRevision: number;\n controller: AbortController;\n signal: AbortSignal;\n readOnly: boolean;\n busy: boolean;\n actions: number;\n}\n\n/** Browser inputs identify a persisted invocation, never an upstream server or resource. */\nexport function createMcpAppsService(\n tools: McpSessionToolsService,\n getHost: () => DoomHeadlessHostService | undefined,\n lifetime?: AbortSignal,\n) {\n const leases = new Map<string, Lease>();\n let disposed = false;\n let opening = 0;\n\n const revoke = (lease: Lease) => {\n leases.delete(lease.id);\n lease.controller.abort();\n };\n const check = (lease: Lease) => {\n lease.signal.throwIfAborted();\n if (disposed || getHost() !== lease.host) throw new Error('App session is no longer available.');\n lease.host.assertActive();\n const surface = lease.host.toolSurface;\n const current = surface?.readSurface();\n if (!surface || current?.revision !== lease.revision || tools.runtimeRevision() !== lease.runtimeRevision)\n throw new Error('App permissions changed. Reopen the App.');\n const source = tools.snapshot().find((tool) => tool.serverName === lease.server && tool.toolName === lease.tool);\n if (!source || normalizeMcpAppMetadata(source._meta).resourceUri !== lease.resourceUri)\n throw new Error('App resource is no longer available.');\n if (!current.tools.some((tool) => tool.name === source.piName || tool.name === 'mcp'))\n throw new Error('The original App tool is not admitted in this session.');\n return surface;\n };\n const owned = (id: string, caller: DoomPluginCaller) => {\n caller.signal?.throwIfAborted();\n const lease = leases.get(id);\n if (!lease || !caller.connectionId || lease.connectionId !== caller.connectionId)\n throw new Error('App lease is not owned by this connection.');\n try {\n check(lease);\n } catch (error) {\n revoke(lease);\n throw error;\n }\n return lease;\n };\n const operation = async <T>(\n id: string,\n caller: DoomPluginCaller,\n write: boolean,\n run: (lease: Lease) => Promise<T>,\n ) => {\n const lease = owned(id, caller);\n if (write && lease.readOnly) throw new Error('Enable App interactions before performing this action.');\n if (lease.busy) throw new Error('An App action is already in progress.');\n if (++lease.actions > 256) throw new Error('App action limit reached. Reopen the App.');\n lease.busy = true;\n try {\n return await run(lease);\n } finally {\n lease.busy = false;\n }\n };\n const confirm = async (lease: Lease, title: string, message: string) => {\n check(lease);\n const accepted = await lease.host.context.client.request(\n { kind: 'confirm', title, message },\n AbortSignal.any([lease.signal, AbortSignal.timeout(120_000)]),\n );\n check(lease);\n if (accepted !== true) throw new Error('App action was not approved.');\n };\n const invocation = async (host: DoomHeadlessHostService, toolCallId: string) => {\n const entries = await host.context.session.entries({ type: 'message' });\n let call: Record<string, unknown> | undefined;\n let result: Record<string, unknown> | undefined;\n for (const entry of entries) {\n const message = record(entry.message);\n if (message?.role === 'assistant' && Array.isArray(message.content)) {\n for (const block of message.content) {\n const candidate = record(block);\n if (candidate?.type === 'toolCall' && candidate.id === toolCallId) call = candidate;\n }\n }\n if (message?.role === 'toolResult' && message.toolCallId === toolCallId) result = message;\n }\n const details = record(result?.details);\n const app = parseMcpAppSnapshot(details?.app);\n if (\n !call ||\n !app?.resourceUri ||\n !app.protocol ||\n typeof details?.server !== 'string' ||\n typeof details.tool !== 'string'\n )\n throw new Error('This invocation has no retained App result.');\n return { call, details, app };\n };\n\n const stopTools = tools.onChange(() => {\n for (const lease of leases.values()) {\n try {\n check(lease);\n } catch {\n revoke(lease);\n }\n }\n });\n const dispose = () => {\n disposed = true;\n stopTools();\n for (const lease of leases.values()) revoke(lease);\n };\n lifetime?.addEventListener('abort', dispose, { once: true });\n\n return {\n dispose,\n methods: [\n defineServerMethod(mcpAppOpenMethod, async ({ toolCallId }, caller): Promise<McpAppOpenResult> => {\n if (!caller.connectionId || !caller.signal) throw new Error('An authenticated live connection is required.');\n caller.signal.throwIfAborted();\n if (disposed || lifetime?.aborted) throw new Error('App session is no longer available.');\n if (leases.size + opening >= MAX_LEASES)\n throw new Error('Too many open Apps. Close an App before opening another.');\n opening++;\n try {\n const host = getHost();\n if (!host?.toolSurface) throw new Error('App execution is unavailable in this session.');\n host.assertActive();\n const revision = host.toolSurface.readSurface().revision;\n const runtimeRevision = tools.runtimeRevision();\n const { call, details, app } = await invocation(host, toolCallId);\n const source = tools\n .snapshot()\n .find((tool) => tool.serverName === details.server && tool.toolName === details.tool);\n const declared = normalizeMcpAppMetadata(source?._meta);\n if (!source || declared.resourceUri !== app.resourceUri || declared.protocol !== app.protocol)\n throw new Error('The original App resource is no longer declared.');\n const args = record(call.arguments) ?? {};\n const generic = call.name === 'mcp' && args.server === source.serverName && args.tool === source.toolName;\n if (call.name !== source.piName && !generic)\n throw new Error('App invocation identity does not match its tool.');\n const controller = new AbortController();\n const lease: Lease = {\n id: randomUUID(),\n connectionId: caller.connectionId,\n host,\n toolCallId,\n server: source.serverName,\n tool: source.toolName,\n resourceUri: app.resourceUri!,\n revision,\n runtimeRevision,\n controller,\n signal: AbortSignal.any([controller.signal, caller.signal, ...(lifetime ? [lifetime] : [])]),\n readOnly: true,\n busy: false,\n actions: 0,\n };\n check(lease);\n const resource = await tools.readAppResource(lease.server, lease.tool, lease.resourceUri, lease.signal);\n check(lease);\n const content = resource.contents.find((item) => item.uri === lease.resourceUri && 'text' in item);\n if (!content || !('text' in content) || typeof content.text !== 'string')\n throw new Error('App resource must contain HTML text.');\n if (content.mimeType !== 'text/html;profile=mcp-app' && content.mimeType !== 'text/html+skybridge')\n throw new Error('Unsupported App resource MIME type.');\n if (Buffer.byteLength(content.text) > MAX_HTML_BYTES) throw new Error('App HTML exceeds its size limit.');\n const states = await host.context.session.entries({ type: 'custom', customType: STATE_ENTRY });\n let state: unknown = null;\n for (const entry of states) {\n const data = record(entry.data);\n if (\n data?.version === 1 &&\n data.toolCallId === toolCallId &&\n data.server === lease.server &&\n data.tool === lease.tool &&\n data.resourceUri === lease.resourceUri\n )\n state = data.state ?? null;\n }\n check(lease);\n if (leases.size >= MAX_LEASES) throw new Error('Too many open Apps.');\n const opened: McpAppOpenResult = {\n leaseId: lease.id,\n html: content.text,\n resourceUri: lease.resourceUri,\n protocol: app.protocol!,\n resourceMeta: boundedJson(\n record(content._meta) ?? record(resource._meta) ?? {},\n MAX_STATE_BYTES,\n 'Resource metadata',\n ),\n tool: {\n name: source.toolName,\n description: source.description ?? '',\n inputSchema: boundedJson(\n { ...source.inputSchema, type: 'object' as const },\n MAX_STATE_BYTES,\n 'Tool schema',\n ),\n _meta: boundedJson(source._meta ?? {}, MAX_STATE_BYTES, 'Tool metadata'),\n },\n args: boundedJson(generic ? (record(args.arguments) ?? {}) : args, MAX_STATE_BYTES, 'Tool input'),\n result: app.result,\n state: boundedJson(state, MAX_STATE_BYTES, 'App state'),\n readOnly: true,\n };\n leases.set(lease.id, lease);\n lease.signal.addEventListener('abort', () => leases.delete(lease.id), { once: true });\n return opened;\n } finally {\n opening--;\n }\n }),\n defineServerMethod(mcpAppActivateMethod, ({ leaseId }, caller) =>\n operation(leaseId, caller, false, async (lease) => {\n await confirm(\n lease,\n `Enable ${lease.server} App interactions?`,\n 'This App may request tool calls and follow-up messages. Each action still requires approval.',\n );\n lease.readOnly = false;\n return { readOnly: false as const };\n }),\n ),\n defineServerMethod(mcpAppCallToolMethod, ({ leaseId, name, arguments: args }, caller) =>\n operation(leaseId, caller, true, async (lease) => {\n boundedJson(args, MAX_STATE_BYTES, 'Tool arguments');\n const target = tools\n .snapshot()\n .find((tool) => tool.serverName === lease.server && tool.toolName === name && isAppVisibleMcpTool(tool));\n if (!target) throw new Error('This tool is not available to this App.');\n const surface = check(lease);\n const exposed = surface.readSurface().tools;\n const direct = exposed.some((tool) => tool.name === target.piName);\n if (!direct && !exposed.some((tool) => tool.name === 'mcp'))\n throw new Error('This tool is not admitted in this session.');\n await confirm(lease, `Allow ${lease.server} App to call ${name}?`, JSON.stringify(args, null, 2));\n const result = await surface.invokeTool({\n revision: lease.revision,\n name: direct ? target.piName : 'mcp',\n arguments: direct ? args : { server: lease.server, tool: name, arguments: args },\n signal: AbortSignal.any([lease.signal, AbortSignal.timeout(120_000)]),\n authorize: () => {\n check(lease);\n },\n });\n check(lease);\n const retained = parseMcpAppSnapshot(record(result.details)?.app);\n return (\n retained?.result ??\n boundedJson(\n {\n content: result.content,\n ...(result.structuredContent === undefined ? {} : { structuredContent: result.structuredContent }),\n ...(result._meta === undefined ? {} : { _meta: result._meta }),\n ...(result.isError === undefined ? {} : { isError: result.isError }),\n },\n MAX_RESULT_BYTES,\n 'Tool result',\n )\n );\n }),\n ),\n defineServerMethod(mcpAppSetStateMethod, ({ leaseId, state }, caller) =>\n operation(leaseId, caller, false, async (lease) => {\n const saved = boundedJson(state, MAX_STATE_BYTES, 'App state');\n await lease.host.context.session.appendCustomEntry(STATE_ENTRY, {\n version: 1,\n toolCallId: lease.toolCallId,\n server: lease.server,\n tool: lease.tool,\n resourceUri: lease.resourceUri,\n state: saved,\n });\n check(lease);\n return {};\n }),\n ),\n defineServerMethod(mcpAppFollowUpMethod, ({ leaseId, prompt }, caller) =>\n operation(leaseId, caller, true, async (lease) => {\n const session = lease.host.context.session;\n if (!session.admitPrompt) throw new Error('App follow-up messages are unavailable in this session.');\n await confirm(lease, `Send a follow-up from ${lease.server}?`, prompt);\n await session.admitPrompt(\n `[MCP App ${lease.server}/${lease.tool}, invocation ${lease.toolCallId}]\\n${prompt}`,\n 'followUp',\n );\n check(lease);\n return {};\n }),\n ),\n defineServerMethod(mcpAppCloseMethod, ({ leaseId }, caller) => {\n const lease = leases.get(leaseId);\n if (lease && lease.connectionId !== caller.connectionId)\n throw new Error('App lease is not owned by this connection.');\n if (lease) revoke(lease);\n return {};\n }),\n ],\n };\n}\n","import type { DoomHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { DoomMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nexport const MCP_HEADLESS_TOOLS_SERVICE = 'doom/mcp-headless-tools';\n\nexport interface McpHeadlessToolCatalog {\n get(name: string): DoomHeadlessTool | undefined;\n}\n\nexport function mountMcpHeadlessTools(tools: readonly DoomHeadlessTool[]) {\n return (context: Context): void => {\n context.plugin((providerContext) => {\n providerContext.provide(MCP_HEADLESS_TOOLS_SERVICE, {\n get: (name) => tools.find((tool) => tool.name === name),\n } satisfies McpHeadlessToolCatalog);\n });\n };\n}\n\nexport function bindMcpHeadlessTool(context: DoomMcpPluginContext, name: string): DoomHeadlessTool {\n const tool = context.services.get<McpHeadlessToolCatalog>(MCP_HEADLESS_TOOLS_SERVICE)?.get(name);\n if (!tool) throw new Error(`MCP tool is unavailable: ${name}`);\n return {\n ...tool,\n execute(toolCallId, parameters, signal, onUpdate) {\n const executionSignal = AbortSignal.any([context.signal, signal ?? context.signal]);\n return tool.execute(toolCallId, parameters, executionSignal, onUpdate, context.execution);\n },\n };\n}\n","import { Type } from 'typebox';\n\nexport const McpHeadlessToolParameters = Type.Object({\n server: Type.String({ minLength: 1 }),\n tool: Type.String({ minLength: 1 }),\n arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n});\n","import type { DoomChildSessionMcpCatalog, DoomChildSessionMcpTool } from '@agimon-ai/po-core/childSession';\nimport type { DoomHeadlessTool, DoomHeadlessToolResult } from '@agimon-ai/po-core/headless';\nimport type { ReadResourceResult } from '@modelcontextprotocol/server';\nimport type { Static, TSchema } from 'typebox';\nimport { Value } from 'typebox/value';\n\nimport { McpHeadlessToolParameters } from '../../schemas/mcpHeadlessTool';\nimport { mcpToolExecutionMetadata, type CatalogTool } from '../mcpCatalog';\nimport { modelInputSchema } from '../mcpFileParams';\nimport type { McpSession } from '../mcpSession';\n\nexport const MCP_SESSION_TOOLS_SERVICE = 'doom/mcp-session-tools';\n\n/** This projection needs no caller-owned execution context and can be borrowed unchanged. */\nexport interface McpDirectTool extends DoomHeadlessTool {\n execute(toolCallId: string, parameters: unknown, signal?: AbortSignal): Promise<DoomHeadlessToolResult>;\n}\n\n/** Narrow cross-root access to the Pi session's existing upstream MCP runtime. */\nexport interface McpSessionToolsService {\n readonly generation: string;\n runtimeRevision(): number;\n readAppResource(server: string, tool: string, resourceUri: string, signal?: AbortSignal): Promise<ReadResourceResult>;\n snapshot(): readonly CatalogTool[];\n project(): readonly McpDirectTool[];\n refresh(): void;\n dispose(): void;\n resolveSelectors(selectors: readonly string[]): readonly string[];\n onChange(listener: () => void): () => void;\n invoke(name: string, parameters: Record<string, unknown>, signal?: AbortSignal): Promise<DoomHeadlessToolResult>;\n}\n\nexport function createMcpSessionToolsService(\n session: McpSession,\n generation: string,\n assertAvailable: () => void = () => undefined,\n): McpSessionToolsService {\n let disposed = false;\n const listeners = new Set<() => void>();\n const retained = new Map<string, { fingerprint: string; tool: McpDirectTool; retire(): void }>();\n const snapshot = () => {\n try {\n if (disposed) return [];\n assertAvailable();\n return session.activeToolDefinitions();\n } catch {\n // An inactive or stale parent lends no declarations.\n return [];\n }\n };\n const project = (): readonly McpDirectTool[] => {\n const definitions = snapshot();\n const names = new Set(definitions.map((tool) => tool.piName));\n for (const [name, entry] of retained) {\n if (names.has(name)) continue;\n entry.retire();\n retained.delete(name);\n }\n return definitions.map((definition) => {\n const fingerprint = JSON.stringify([session.toolGeneration, definition]);\n const previous = retained.get(definition.piName);\n if (previous?.fingerprint === fingerprint) return previous.tool;\n previous?.retire();\n let retired = false;\n const invoke = session.bindToolInvocation(definition);\n const tool: McpDirectTool = {\n name: definition.piName,\n label: `${definition.serverName}: ${definition.toolName}`,\n description: definition.description ?? `${definition.toolName} on the ${definition.serverName} MCP server.`,\n ...(definition.annotations === undefined ? {} : { annotations: definition.annotations }),\n ...(definition._meta === undefined ? {} : { _meta: mcpToolExecutionMetadata(definition) }),\n ...(definition.outputSchema === undefined ? {} : { outputSchema: definition.outputSchema }),\n // File parameters are validated as the `{path}` objects the model sends.\n parameters: modelInputSchema(definition) as TSchema,\n async execute(_toolCallId, parameters, signal) {\n assertAvailable();\n if (retired) throw new Error(`MCP tool ${definition.piName} is no longer available.`);\n signal?.throwIfAborted();\n const arguments_ = parameters === undefined ? {} : parameters;\n if (!Value.Check(tool.parameters, arguments_))\n throw new Error(`Invalid arguments for MCP tool ${definition.piName}.`);\n const result = await invoke(arguments_ as Record<string, unknown>, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n retained.set(definition.piName, {\n fingerprint,\n tool,\n retire: () => {\n retired = true;\n },\n });\n return tool;\n });\n };\n const refresh = () => {\n project();\n for (const listener of listeners) listener();\n };\n // Retirement must happen even if a borrower temporarily has no change listener.\n const stopSession = session.onChange(refresh);\n return Object.freeze({\n generation,\n runtimeRevision: () => session.toolGeneration,\n readAppResource: async (server: string, tool: string, resourceUri: string, signal?: AbortSignal) => {\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n const result = await session.readAppResource(server, tool, resourceUri, signal);\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n return result;\n },\n snapshot,\n project,\n refresh,\n dispose: () => {\n disposed = true;\n stopSession();\n refresh();\n listeners.clear();\n },\n resolveSelectors: (selectors: readonly string[]) => {\n const active = new Set(snapshot().map((tool) => tool.piName));\n return session\n .resolveToolSelectors(selectors)\n .map((tool) => tool.name)\n .filter((name) => active.has(name));\n },\n onChange: (listener: () => void) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n invoke: async (name: string, parameters: Record<string, unknown>, signal?: AbortSignal) => {\n assertAvailable();\n const tool = project().find((candidate) => candidate.name === name);\n if (!tool) throw new Error(`MCP tool ${name} is not available in this session.`);\n return tool.execute('mcp', parameters, signal);\n },\n });\n}\n\n/** Borrow an existing MCP runtime; a child never starts or disposes its own upstream connections. */\nexport function createMcpChildTool(\n invoke: (\n parameters: Static<typeof McpHeadlessToolParameters>,\n signal?: AbortSignal,\n ) => Promise<DoomHeadlessToolResult>,\n catalog?: DoomChildSessionMcpCatalog,\n): DoomChildSessionMcpTool {\n return {\n name: 'mcp',\n ...(catalog === undefined ? {} : { catalog }),\n description: 'Call a tool exposed by a connected MCP server.',\n parameters: McpHeadlessToolParameters,\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n if (!Value.Check(McpHeadlessToolParameters, parameters)) throw new Error('Invalid MCP tool arguments.');\n const result = await invoke(parameters, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n}\n","export const COMMAND_NAME = 'mcp';\nexport const COMMAND_DESCRIPTION = 'Browse this session MCP servers: authorize, enable, disable, tools and resources';\nexport const SERVER_COMMAND_DESCRIPTION = 'Show MCP configuration or begin an authorization request.';\n","export const PACKAGE_SOURCE = '@agimon-ai/po-mcp';\n/** Leader binding ids are restricted to `[a-z0-9][a-z0-9._:-]*`, so the scope and slash are dropped. */\nexport const LEADER_BINDING_PREFIX = 'doom-mcp';\n/**\n * Sits under the existing `extension` group, beside `tools` and `config`.\n *\n * A top-level key would have to be unique across every extension, and MCP belongs\n * next to the tool browser a user reaches for anyway. `t` in particular is taken:\n * it is Doom Task's top-level group.\n */\nexport const LEADER_GROUP = { key: 'e', label: 'extension', detail: 'tools, skills and config', order: 50 } as const;\nexport const LEADER_KEY = 'm';\nexport const LEADER_LABEL = 'mcp';\nexport const LEADER_DETAIL = 'servers and tools';\n/**\n * Footer status carrying the session's MCP server names, comma separated.\n *\n * MCP tools are registered under `<server>_<tool>`, a name only known at\n * runtime, so the cockpit's web plugin reads this status to recognise which\n * tool calls are MCP calls. The web half duplicates the literal (it may only\n * import src/types and src/constants), and a test keeps the two in step.\n */\nexport const MCP_STATUS_KEY = 'doom-mcp';\n","/**\n * What an MCP tool result carries beyond its text, shared by this package's\n * Pi adapter (which attaches it as the result's details) and its web plugin\n * (which renders it). Wire JSON only: images ride Pi's own content blocks,\n * so they are not repeated here.\n */\nimport type { ContextToolWarning } from '@agimon-ai/po-core/contextApi';\nimport type { CallToolResult } from '@modelcontextprotocol/server';\n\n/** Shared browser/server payload validated by the mcp.apps.open wire schema. */\nexport interface McpAppOpenResult {\n leaseId: string;\n html: string;\n resourceUri: string;\n protocol: 'mcp' | 'openai';\n resourceMeta: Record<string, unknown>;\n tool: {\n name: string;\n description: string;\n inputSchema: { type: 'object'; [key: string]: unknown };\n _meta: Record<string, unknown>;\n };\n args: Record<string, unknown>;\n result: { content: unknown[]; structuredContent?: unknown; _meta?: Record<string, unknown>; isError?: boolean };\n state: unknown;\n readOnly: boolean;\n}\n\n/** Private presentation payload, never appended to model content. */\nexport interface McpAppPresentation {\n version: 1;\n resourceUri?: string;\n protocol?: 'mcp' | 'openai';\n result: CallToolResult;\n}\nexport type McpResultBlock =\n | { type: 'audio'; data: string; mimeType: string }\n | { type: 'resource_link'; uri: string; name: string; title?: string; description?: string; mimeType?: string }\n | { type: 'resource'; uri: string; mimeType?: string; text?: string; blob?: string }\n | { type: 'structured'; value: Record<string, unknown> };\n\nexport interface McpToolDetails {\n server: string;\n tool: string;\n /** Present only when the downstream result carried something beyond text and images. */\n blocks?: McpResultBlock[];\n app?: McpAppPresentation;\n}\n\nexport const MCP_SESSION_AUTH_STATUS_KEY = 'doom-mcp-session-auth';\n\nconst ANSI_ESCAPE_PATTERN = new RegExp(`${String.fromCharCode(27)}\\\\[[0-?]*[ -/]*[@-~]`, 'gu');\nconst MAX_SESSION_AUTH_SERVERS = 128;\nconst MAX_AUTHORIZATION_URL_LENGTH = 8192;\nconst MAX_SERVER_TOOLS = 512;\nconst MAX_TOOL_NAME_LENGTH = 256;\nconst SESSION_AUTH_STATES = [\n 'not-connected',\n 'connecting',\n 'connected',\n 'degraded',\n 'needs-auth',\n 'failed',\n 'closed',\n 'disabled',\n] as const;\nexport type McpSessionAuthState = (typeof SESSION_AUTH_STATES)[number];\n\nfunction isSessionAuthState(value: unknown): value is McpSessionAuthState {\n return SESSION_AUTH_STATES.some((state) => state === value);\n}\n\nexport interface McpSessionAuthStatusItem {\n readonly name: string;\n readonly state: McpSessionAuthState;\n readonly authorizationUrl?: string;\n /** Available tools and their estimated direct-schema cost, not a second context inventory. */\n readonly tools?: readonly McpSessionReachableTool[];\n}\n\nexport interface McpSessionReachableTool {\n /** Original downstream name, used with the configured server for detail lookup. */\n readonly name: string;\n /** Actual registered name. Optional for older live-session status producers. */\n readonly piName?: string;\n readonly tokens?: number;\n}\n\n/** A session's view of one reachable tool: what the dialog shows when a row is opened. */\nexport interface McpSessionToolDetail {\n readonly server: string;\n readonly tool: string;\n readonly piName: string;\n readonly description?: string;\n readonly inputSchema: Record<string, unknown>;\n readonly tokens: number;\n readonly warnings?: readonly ContextToolWarning[];\n readonly _meta?: Record<string, unknown>;\n}\n\n/** Session route for one reachable tool's description and schema. */\nexport const MCP_SESSION_TOOL_API_PATH = '/tool';\nexport const MCP_SESSION_TOOL_SERVER_QUERY = 'server';\nexport const MCP_SESSION_TOOL_NAME_QUERY = 'tool';\n\ninterface McpSessionServerStatusSource {\n readonly name: string;\n readonly state: string;\n readonly authorizationUrl?: unknown;\n readonly tools?: readonly {\n readonly toolName: string;\n readonly piName?: string;\n readonly active: boolean;\n readonly tokens?: number;\n }[];\n}\n\n/** Keeps servers visible before discovery and after failures, without diagnostics or credentials. */\nexport function formatMcpSessionAuthStatus<T extends McpSessionServerStatusSource>(\n servers: readonly T[],\n): string | undefined {\n const items: McpSessionAuthStatusItem[] = servers.flatMap((server) => {\n if (!isSessionAuthState(server.state)) return [];\n const tools = (server.tools ?? [])\n .filter((tool) => tool.active && isToolName(tool.toolName))\n .map((tool): McpSessionReachableTool => ({\n name: tool.toolName,\n ...(isToolName(tool.piName) ? { piName: tool.piName } : {}),\n ...(isTokenCount(tool.tokens) ? { tokens: tool.tokens } : {}),\n }))\n .slice(0, MAX_SERVER_TOOLS);\n const item: McpSessionAuthStatusItem = {\n name: server.name,\n state: server.state,\n ...(isAuthorizationUrl(server.authorizationUrl) ? { authorizationUrl: server.authorizationUrl } : {}),\n ...(tools.length === 0 ? {} : { tools }),\n };\n return [item];\n });\n return items.length === 0 ? undefined : JSON.stringify(items);\n}\n\n/** Reads the live-session status defensively. Empty is the browser's active-session clear value. */\nexport function parseMcpSessionAuthStatus(raw: string | undefined): McpSessionAuthStatusItem[] | undefined {\n if (raw === undefined || raw.trim() === '') return undefined;\n try {\n const value: unknown = JSON.parse(raw.replace(ANSI_ESCAPE_PATTERN, ''));\n if (!Array.isArray(value) || value.length === 0 || value.length > MAX_SESSION_AUTH_SERVERS) return undefined;\n\n const names = new Set<string>();\n for (const item of value) {\n if (!isSessionAuthStatusItem(item) || names.has(item.name)) return undefined;\n names.add(item.name);\n }\n return value;\n } catch {\n return undefined;\n }\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n const codePoint = character.codePointAt(0);\n if (codePoint !== undefined && (codePoint < 32 || (codePoint >= 127 && codePoint <= 159))) return true;\n }\n return false;\n}\n\nfunction isAuthorizationUrl(value: unknown): value is string {\n if (typeof value !== 'string' || value.length > MAX_AUTHORIZATION_URL_LENGTH || hasControlCharacter(value)) {\n return false;\n }\n try {\n const url = new URL(value);\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.username === '' && url.password === '';\n } catch {\n return false;\n }\n}\n\nfunction isToolName(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n value.trim() !== '' &&\n value.length <= MAX_TOOL_NAME_LENGTH &&\n !hasControlCharacter(value)\n );\n}\n\nfunction isTokenCount(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0;\n}\n\nfunction isReachableTool(value: unknown): value is McpSessionReachableTool {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n const record = value as Record<string, unknown>;\n return (\n Object.keys(record).every((key) => key === 'name' || key === 'piName' || key === 'tokens') &&\n isToolName(record.name) &&\n (!('piName' in record) || isToolName(record.piName)) &&\n (!('tokens' in record) || isTokenCount(record.tokens))\n );\n}\n\nfunction isSessionAuthStatusItem(value: unknown): value is McpSessionAuthStatusItem {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n const record = value as Record<string, unknown>;\n return (\n Object.keys(record).every(\n (key) => key === 'name' || key === 'state' || key === 'authorizationUrl' || key === 'tools',\n ) &&\n (!('authorizationUrl' in record) || isAuthorizationUrl(record.authorizationUrl)) &&\n (!('tools' in record) ||\n (Array.isArray(record.tools) &&\n record.tools.length <= MAX_SERVER_TOOLS &&\n record.tools.every(isReachableTool))) &&\n typeof record.name === 'string' &&\n record.name.trim() !== '' &&\n !hasControlCharacter(record.name) &&\n isSessionAuthState(record.state)\n );\n}\n\n/** Hub API paths for repository-scoped MCP management. */\nexport const MCP_REPOSITORY_API_PATH = '/repository';\nexport const MCP_DISCOVERY_API_PATH = '/repository/discover';\nexport const MCP_AUTHORIZATION_API_PATH = '/repository/authorize';\n/** The repository every route is asked about, and the flow segment the two flow routes carry. */\nexport const MCP_REPOSITORY_ID_QUERY = 'repositoryId';\nexport const MCP_FLOW_ID_PARAM = 'flowId';\n\nexport type McpRepositoryServerState =\n | 'not-connected'\n | 'connecting'\n | 'connected'\n | 'degraded'\n | 'needs-auth'\n | 'failed'\n | 'closed';\n\nexport interface McpRepositoryTool {\n name: string;\n piName: string;\n description?: string;\n}\n\nexport interface McpRepositoryServer {\n name: string;\n state: McpRepositoryServerState;\n source: 'cached' | 'live' | 'configured';\n credentialPresent: boolean;\n tools: McpRepositoryTool[];\n error?: string;\n}\n\nexport interface McpRepositoryCatalog {\n repositoryId: string;\n sync: {\n fresh: boolean;\n reasons: string[];\n };\n servers: McpRepositoryServer[];\n droppedServers: string[];\n diagnostics: string[];\n}\n\nexport type McpAuthorizationStatus = 'starting' | 'waiting' | 'completed' | 'failed' | 'cancelled' | 'expired';\n\nexport interface McpAuthorizationFlow {\n id: string;\n repositoryId: string;\n serverName: string;\n status: McpAuthorizationStatus;\n authorizationUrl?: string;\n error?: string;\n expiresAt: number;\n}\n","import type { McpCommandTarget } from '../../types/mcp';\n\n/** One line per server: its state, and how many tools it currently offers. */\nexport function formatStatus(session: McpCommandTarget): string {\n const { servers } = session.getSnapshot();\n if (servers.length === 0) return 'No MCP servers are configured for this session.';\n const lines = servers.map((server) => {\n const detail = server.error ? ` (${server.error})` : '';\n return `${server.name}: ${server.state} · ${server.tools.length} tools${detail}`;\n });\n return [...lines, ...session.getDiagnostics()].join('\\n');\n}\n","const SELECTOR_SEPARATOR = '/';\n\n/**\n * Which downstream tools a child may see.\n *\n * A selector is either a whole server (`pencil`) or one tool of it\n * (`pencil/get_screenshot`).\n */\nexport class DirectToolFilter {\n private readonly servers = new Set<string>();\n private readonly tools = new Map<string, Set<string>>();\n\n constructor(selectors: readonly string[]) {\n for (const raw of selectors) {\n const selector = raw.trim().replace(/\\/+$/, '');\n if (!selector) continue;\n const separator = selector.indexOf(SELECTOR_SEPARATOR);\n if (separator === -1) {\n this.servers.add(selector);\n continue;\n }\n const server = selector.slice(0, separator);\n const tool = selector.slice(separator + 1);\n if (!server) continue;\n if (!tool) {\n this.servers.add(server);\n continue;\n }\n const selected = this.tools.get(server) ?? new Set<string>();\n selected.add(tool);\n this.tools.set(server, selected);\n }\n }\n\n allows(serverName: string, toolName: string): boolean {\n if (this.servers.has(serverName)) return true;\n return this.tools.get(serverName)?.has(toolName) ?? false;\n }\n}\n","import { DIRECT_TOOLS_ENV, NO_DIRECT_TOOLS } from '../../schemas/directTools';\nimport { DirectToolFilter } from '../directTools';\n\n/** Reads a child agent's MCP tool selection from the process environment. */\nexport function readDirectToolFilter(environment: NodeJS.ProcessEnv = process.env): DirectToolFilter | undefined {\n const raw = environment[DIRECT_TOOLS_ENV];\n if (raw === undefined || raw === '') return undefined;\n if (raw === NO_DIRECT_TOOLS) return new DirectToolFilter([]);\n return new DirectToolFilter(raw.split(','));\n}\n","import type { DoomToolRestriction } from '@agimon-ai/po-core/toolSurface';\n\nimport type { McpCatalog } from '../mcpCatalog';\n/**\n * Hides every wrapper this extension owns that the catalog does not currently offer.\n *\n * The surface recomputes from the whole registered inventory, so this only ever\n * removes: a server that reconnected is already in `incoming` and nothing has to\n * put it back. Historical ownership matters after reconfiguration because Pi\n * cannot unregister a wrapper the new domain no longer selects.\n *\n * The visible set is read once, here, so the returned function stays pure and a\n * later re-apply by another owner cannot see half a catalog change.\n */\nexport function mcpToolRestriction(\n catalog: McpCatalog,\n historicallyOwnedNames: ReadonlySet<string> = new Set(catalog.allTools().map((tool) => tool.piName)),\n incompatibleNames: ReadonlySet<string> = new Set(),\n): DoomToolRestriction {\n const visible = new Set(catalog.activeToolNames().filter((name) => !incompatibleNames.has(name)));\n return (incoming) => incoming.filter((name) => !historicallyOwnedNames.has(name) || visible.has(name));\n}\n","import type {\n McpClientManagerService,\n McpOutputSchemaWarning,\n McpServerStateChange,\n TokenStore,\n} from '@agimon-ai/mcp-proxy';\nimport type { ContextToolWarning } from '@agimon-ai/po-core/contextApi';\nimport type { McpStatusSnapshot } from '@agimon-ai/po-core/mcpStatus';\nimport type { DoomMcpResolvedToolSelection } from '@agimon-ai/po-core/mcpToolResolver';\nimport type {\n DoomToolRestriction,\n DoomToolRestrictionHandle,\n DoomToolSurfaceService,\n} from '@agimon-ai/po-core/toolSurface';\nimport type { CallToolResult, ReadResourceResult } from '@modelcontextprotocol/server';\n\nimport { PACKAGE_SOURCE } from '../../constants/piMcp';\nimport type { McpResourceView, McpServerView } from '../../types/mcp';\nimport type { McpConfigGroups, McpConfigSource, McpSessionConfig } from '../../types/mcpConfig';\nimport { buildMcpConfigGroups } from '../configSources';\nimport { readDirectToolFilter } from '../directToolsEnvironment';\nimport { type CatalogTool, isModelVisibleMcpTool, McpCatalog, normalizeMcpAppMetadata } from '../mcpCatalog';\nimport { publishFileParams } from '../mcpFileParams';\nimport type { McpFilePublisher } from '../mcpFileParams/type';\nimport { type McpRuntimeOwner, readCachedCatalog } from '../mcpRuntime';\nimport { captureMcpAppResult, retainMcpAppResult, toHeadlessToolResult } from '../mcpTools';\nimport { readSessionConfig } from '../sessionConfig';\nimport { mcpToolRestriction } from '../toolVisibility';\n\n/** Raised by anything needing a live container before one has been built. */\nconst RUNTIME_NOT_STARTED = 'The MCP runtime has not started yet.';\nconst AUTHORIZATION_URL_NOT_READY = 'No authorization page is waiting for this MCP server.';\n\nfunction canonicalJson(value: unknown): string {\n const normalize = (candidate: unknown): unknown => {\n if (Array.isArray(candidate)) return candidate.map(normalize);\n if (typeof candidate !== 'object' || candidate === null) return candidate;\n return Object.fromEntries(\n Object.entries(candidate as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, child]) => [key, normalize(child)]),\n );\n };\n return JSON.stringify(normalize(value));\n}\n\nexport function mcpConfigurationFingerprint(configuration: McpSessionConfig): string {\n return canonicalJson({\n enabled: configuration.enabled ?? true,\n repoRoot: configuration.repoRoot,\n stagingDirectory: configuration.stagingDirectory,\n generatedConfigPath: configuration.generatedConfigPath,\n pluginConfigPaths: configuration.pluginConfigPaths ?? [],\n sources: configuration.sources ?? [],\n allowlist: {\n servers: [...(configuration.allowlist?.servers ?? [])].sort((left, right) => left.localeCompare(right)),\n proxy: [...(configuration.allowlist?.proxy ?? [])].sort((left, right) => left.localeCompare(right)),\n },\n });\n}\n\nfunction toolRegistrationFingerprint(tool: CatalogTool): string {\n return canonicalJson({\n serverName: tool.serverName,\n toolName: tool.toolName,\n inputSchema: tool.inputSchema,\n _meta: tool._meta,\n });\n}\n\nexport interface McpSessionOptions {\n environment?: NodeJS.ProcessEnv;\n /** Surfaces an OAuth URL, opening it when an explicit authorization requested that. */\n onAuthorizationUrl?: (url: URL, serverName: string, options: { openBrowser: boolean }) => void | Promise<void>;\n /** Overrides the OS keyring store, for tests. */\n tokenStore?: TokenStore;\n /** Publishes a file argument after consent. Without it, a tool with a file argument is refused. */\n publishFile?: McpFilePublisher;\n}\n\n/**\n * The MCP picture for one Pi session.\n *\n * Install is synchronous and cheap: the previous run's catalog is read off disk and\n * its tools registered, so Pi's first turn already has them. Connecting happens on\n * a detached promise afterwards, and each server folds into the active tool set as\n * it lands. Nothing on this path waits for a socket.\n */\nexport class McpSession {\n /** Created after session_start, never while Pi is importing extensions. */\n private runtime: McpRuntimeOwner | undefined;\n private catalog: McpCatalog;\n private groups: McpConfigGroups = {\n shared: { configSources: [], configPaths: [], serverNames: [] },\n sessionLocal: { configSources: [], configPaths: [], serverNames: [] },\n droppedServers: [],\n diagnostics: [],\n };\n private readonly options: McpSessionOptions;\n /** Credential persistence used by the active runtime and explicit reauthorization. */\n private tokenStore: TokenStore | undefined;\n /** Resources per server, listed on demand. Errors are never cached, so a retry re-dials. */\n private readonly resourceCache = new Map<string, readonly McpResourceView[]>();\n private readonly changeListeners = new Set<() => void>();\n /** Authorization URLs waiting to be opened, by server. */\n private readonly authorizationUrls = new Map<string, string>();\n /** Servers whose explicit auth action should launch the browser when its URL arrives. */\n private readonly browserAuthorizationRequests = new Set<string>();\n /** Explicit session disconnects fence late discovery and stale tool invocations. */\n private readonly disconnectedServers = new Set<string>();\n /** Bounded, session-local diagnostics. Never tool-result values or cached credentials. */\n private outputSchemaWarnings: McpOutputSchemaWarning[] = [];\n /** Invalidates deferred startup work when a session reloads or shuts down. */\n private lifecycleGeneration = 0;\n private configurationFingerprint: string | undefined;\n private workspaceRoot: string | undefined;\n private executionCwd: string | undefined;\n /** Pi wrappers survive configuration changes because the host cannot unregister them. */\n private readonly retainedTools = new Map<string, CatalogTool>();\n private readonly registeredToolFingerprints = new Map<string, string>();\n private readonly historicallyOwnedNames = new Set<string>();\n private readonly incompatibleNames = new Set<string>();\n /** The session's slot in the tool surface, held only while a session fiber is up. */\n private toolRestriction: DoomToolRestrictionHandle | undefined;\n\n /** Resolved per tool call, so a registration outlives the container it was made under. */\n readonly getClientManager = (): McpClientManagerService | undefined => this.runtime?.getServices()?.clientManager;\n\n constructor(options: McpSessionOptions) {\n this.options = options;\n this.catalog = this.createCatalog();\n }\n\n /**\n * Puts this session's tool visibility under the Doom tool surface.\n *\n * Registering applies the current restriction immediately, which is the first\n * point the session can express that nothing has connected yet: the surface\n * only exists once a session fiber is up, while the cached tools were\n * registered back at install. Dropping the handle restores every wrapper, so\n * nothing here keeps a snapshot of the tool list.\n */\n bindToolSurface(surface: DoomToolSurfaceService): () => void {\n const handle = surface.register({ source: PACKAGE_SOURCE, restrict: this.currentRestriction() });\n this.toolRestriction = handle;\n return () => {\n if (this.toolRestriction !== handle) return;\n this.toolRestriction = undefined;\n handle.dispose();\n };\n }\n\n private createCatalog(): McpCatalog {\n return new McpCatalog(readDirectToolFilter(this.options.environment));\n }\n\n /**\n * Registers the cached catalog with Pi. Runs at extension install.\n *\n * Returns the servers it seeded, so a caller can report what the session started\n * with before anything connected.\n */\n install(configuration: McpSessionConfig = readSessionConfig(this.options.environment)): McpStatusSnapshot {\n this.executionCwd = configuration.repoRoot;\n this.bindConfiguration(configuration);\n this.emitChange();\n return this.catalog.toSnapshot();\n }\n\n /** Replaces the complete MCP projection and retires the previous live owner. */\n async reconfigure(\n configuration: McpSessionConfig,\n executionCwd = configuration.repoRoot,\n workspaceRoot = configuration.repoRoot,\n ): Promise<void> {\n const fingerprint = mcpConfigurationFingerprint(configuration);\n if (\n fingerprint === this.configurationFingerprint &&\n executionCwd === this.executionCwd &&\n workspaceRoot === this.workspaceRoot\n ) {\n if (!this.runtime?.getServices()) this.startDetached();\n return;\n }\n\n const generation = ++this.lifecycleGeneration;\n const retiredRuntime = this.runtime;\n this.runtime = undefined;\n await retiredRuntime?.dispose();\n if (generation !== this.lifecycleGeneration) return;\n this.resourceCache.clear();\n this.authorizationUrls.clear();\n this.browserAuthorizationRequests.clear();\n this.executionCwd = executionCwd;\n this.bindConfiguration(configuration);\n this.workspaceRoot = workspaceRoot;\n this.emitChange();\n this.updateToolVisibility();\n this.startDetached();\n }\n\n private bindConfiguration(configuration: McpSessionConfig): void {\n this.workspaceRoot = configuration.repoRoot;\n this.configurationFingerprint = mcpConfigurationFingerprint(configuration);\n this.groups = buildMcpConfigGroups(configuration);\n this.disconnectedServers.clear();\n this.catalog = this.createCatalog();\n // Doom embeds the client runtime, so upstreams referenced by a proxy wrapper\n // remain individual servers in the catalog rather than collapsing into it.\n const configuredServers = [\n ...new Set([...this.groups.sessionLocal.serverNames, ...this.groups.shared.serverNames]),\n ];\n this.catalog.seed(readCachedCatalog(this.configSources()), configuredServers);\n for (const diagnostic of this.groups.diagnostics) this.catalog.addDiagnostic(diagnostic);\n this.trackTools(this.catalog.allTools());\n }\n\n private trackTools(tools: readonly CatalogTool[]): void {\n for (const tool of tools) {\n const fingerprint = toolRegistrationFingerprint(tool);\n const registered = this.registeredToolFingerprints.get(tool.piName);\n this.historicallyOwnedNames.add(tool.piName);\n if (registered === undefined) {\n this.registeredToolFingerprints.set(tool.piName, fingerprint);\n this.incompatibleNames.delete(tool.piName);\n this.retainedTools.set(tool.piName, tool);\n continue;\n }\n if (registered === fingerprint) {\n this.incompatibleNames.delete(tool.piName);\n continue;\n }\n this.incompatibleNames.add(tool.piName);\n this.catalog.addDiagnostic(\n `MCP tool \"${tool.piName}\" changed identity, App metadata, or input schema and is hidden until Pi is relaunched.`,\n );\n }\n }\n\n /** Tools the session currently permits on both local and remote surfaces. */\n activeToolDefinitions(): readonly CatalogTool[] {\n const active = new Set(this.catalog.activeToolNames());\n // Retain Pi's declaration identity while publishing current remote metadata.\n return this.toolDefinitions().flatMap((tool) => {\n const current = this.catalog.findTool(tool.piName);\n return active.has(tool.piName) && current !== undefined ? [current] : [];\n });\n }\n\n toolDefinitions(): readonly CatalogTool[] {\n return [...this.retainedTools.values()].filter(\n (tool) =>\n this.catalog.findTool(tool.piName) !== undefined &&\n !this.incompatibleNames.has(tool.piName) &&\n !this.disconnectedServers.has(tool.serverName),\n );\n }\n\n isToolAvailable(registeredTool: CatalogTool): boolean {\n if (!this.catalog.activeToolNames().includes(registeredTool.piName)) return false;\n const current = this.catalog.findTool(registeredTool.piName);\n return (\n current !== undefined && toolRegistrationFingerprint(current) === toolRegistrationFingerprint(registeredTool)\n );\n }\n\n get toolGeneration(): number {\n return this.lifecycleGeneration;\n }\n\n /** Capture a declaration's runtime, so retired wrappers cannot reach a same-name replacement. */\n bindToolInvocation(tool: CatalogTool) {\n const generation = this.lifecycleGeneration;\n return async (parameters: Record<string, unknown>, signal?: AbortSignal) => {\n if (generation !== this.lifecycleGeneration || !this.isToolAvailable(tool))\n throw new Error(`MCP tool ${tool.piName} is no longer available in the current session configuration.`);\n return toHeadlessToolResult(tool, await this.callTool(tool, parameters, signal));\n };\n }\n\n /** Executes through this session's existing manager, never a remote replacement runtime. */\n async invokeTool(\n name: string,\n parameters: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<import('@agimon-ai/po-core/headless').DoomHeadlessToolResult> {\n const tool = this.activeToolDefinitions().find((candidate) => candidate.piName === name);\n if (!tool || !this.isToolAvailable(tool))\n throw new Error(`MCP tool ${name} is not available in the current session configuration.`);\n return this.bindToolInvocation(tool)(parameters, signal);\n }\n\n /** Shared raw execution for Pi and headless, before their distinct result conventions. */\n async callTool(\n tool: CatalogTool,\n parameters: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<CallToolResult> {\n const name = tool.piName;\n if (!this.isToolAvailable(tool))\n throw new Error(`MCP tool ${name} is not available in the current session configuration.`);\n const runtime = this.runtime;\n const services = runtime?.getServices();\n if (!runtime || !services) throw new Error(RUNTIME_NOT_STARTED);\n signal?.throwIfAborted();\n // Shared before dialling, so a refused or declined file never reaches the server.\n const { publishFile } = this.options;\n const files = await publishFileParams(tool, parameters, publishFile && ((path) => publishFile(path, tool, signal)));\n try {\n signal?.throwIfAborted();\n const connection = await services.clientManager.ensureConnected(tool.serverName);\n signal?.throwIfAborted();\n if (!runtime.isCurrent(services) || !this.isToolAvailable(tool))\n throw new Error(`MCP tool ${name} is no longer available in the current session configuration.`);\n const timeout = services.clientManager.getServerRequestTimeout(tool.serverName);\n this.clearToolWarnings(tool.serverName, 'tools/call', tool.toolName);\n let snapshot: ReturnType<typeof captureMcpAppResult>;\n const result = await connection.callTool(tool.toolName, files.outbound, {\n ...(timeout === undefined ? {} : { timeout }),\n ...(signal === undefined ? {} : { signal }),\n onResult: (original) => {\n snapshot = captureMcpAppResult(tool, original);\n },\n });\n signal?.throwIfAborted();\n if (!runtime.isCurrent(services) || !this.isToolAvailable(tool))\n throw new Error(`MCP tool ${name} is no longer available in the current session configuration.`);\n retainMcpAppResult(result, snapshot);\n return result;\n } finally {\n files.release();\n }\n }\n\n /**\n * What this extension hides right now.\n *\n * Rebuilt from scratch every time, so a server that failed drops out and one\n * that reconnected comes back.\n */\n private currentRestriction(): DoomToolRestriction {\n const unavailable = new Set(this.incompatibleNames);\n for (const tool of this.catalog.allTools()) {\n if (this.disconnectedServers.has(tool.serverName)) unavailable.add(tool.piName);\n }\n return mcpToolRestriction(this.catalog, this.historicallyOwnedNames, unavailable);\n }\n\n private updateToolVisibility(): void {\n this.toolRestriction?.update(this.currentRestriction());\n }\n\n private startDetached(): void {\n void this.start().catch((error: unknown) => {\n this.catalog.addDiagnostic(\n `Could not start the MCP runtime: ${error instanceof Error ? error.message : String(error)}`,\n );\n this.emitChange();\n });\n }\n\n /**\n * Starts connecting. Never awaited on Pi's critical path.\n *\n * Resolves once the container exists, not once servers are reachable. A start\n * that a newer generation superseded resolves to nothing and registers nothing.\n */\n async start(): Promise<void> {\n const generation = ++this.lifecycleGeneration;\n this.disconnectedServers.clear();\n this.outputSchemaWarnings = [];\n this.emitChange();\n // Explicit disabled and empty Doom projections must not instantiate any\n // runtime collaborator, including the keyring-backed token store.\n if (this.configuredServerNames().length === 0) return;\n const [{ createTokenStore }, { McpRuntimeOwner }] = await Promise.all([\n import('../keyringTokenStore'),\n import('../mcpRuntime'),\n ]);\n if (generation !== this.lifecycleGeneration) return;\n this.runtime ??= new McpRuntimeOwner();\n const runtime = this.runtime;\n // The container is about to be replaced, so every resource list read from the\n // old one is now hearsay.\n this.resourceCache.clear();\n const configSources = this.configSources();\n const tokenStore = this.options.tokenStore ?? (await createTokenStore());\n this.tokenStore = tokenStore;\n await runtime.start({\n configSources,\n workspaceRoot: this.workspaceRoot,\n executionCwd: this.executionCwd,\n environment: this.options.environment,\n tokenStore,\n onAuthorizationUrl: (url, serverName) => this.onAuthorizationUrl(url, serverName, generation),\n onServerStateChange: (change) => this.onServerStateChange(change, generation),\n onOutputSchemaWarning: (warning) => {\n if (\n generation !== this.lifecycleGeneration ||\n this.disconnectedServers.has(warning.serverName) ||\n !this.configuredServerNames().includes(warning.serverName)\n )\n return;\n if (this.outputSchemaWarnings.length >= 64) return;\n if (this.outputSchemaWarnings.some((current) => canonicalJson(current) === canonicalJson(warning))) return;\n this.outputSchemaWarnings.push(warning);\n this.emitChange();\n },\n });\n // Shutdown can land while the proxy package or token store is loading. Make\n // sure that late container cannot survive and mutate a closed Pi session.\n if (generation !== this.lifecycleGeneration) await runtime.dispose();\n }\n\n /**\n * Records the URL a flow is waiting on, then passes it to the host.\n *\n * Kept here because the status panel a user starts the flow from is where the\n * link is shown; hosts do not repeat it in the transcript. Host work is\n * detached so a failed desktop browser launch never cancels a still-usable OAuth\n * callback; the overlay retains a clickable fallback and a retry action.\n */\n private onAuthorizationUrl(url: URL, serverName: string, generation: number): void {\n if (generation !== this.lifecycleGeneration || this.disconnectedServers.has(serverName)) return;\n this.authorizationUrls.set(serverName, url.toString());\n this.emitChange();\n const openBrowser = this.browserAuthorizationRequests.has(serverName);\n void Promise.resolve()\n .then(() => {\n if (generation !== this.lifecycleGeneration || this.disconnectedServers.has(serverName)) return;\n return this.options.onAuthorizationUrl?.(url, serverName, { openBrowser });\n })\n .catch((error: unknown) => {\n if (generation !== this.lifecycleGeneration) return;\n const detail = error instanceof Error ? error.message : String(error);\n this.catalog.addDiagnostic(`Could not open authorization page for \"${serverName}\": ${detail}`);\n this.emitChange();\n });\n }\n\n /** Ordered layers for the one in-process client container. */\n private configSources(): McpConfigSource[] {\n return [...this.groups.sessionLocal.configSources, ...this.groups.shared.configSources];\n }\n\n private configuredServerNames(): string[] {\n return [...new Set([...this.groups.sessionLocal.serverNames, ...this.groups.shared.serverNames])];\n }\n\n /** Closes only this session's connection. Saved OAuth credentials are untouched. */\n async disconnect(serverName: string): Promise<void> {\n if (!this.configuredServerNames().includes(serverName)) throw new Error(`Unknown MCP server: ${serverName}`);\n const clientManager = this.getClientManager();\n if (!clientManager) throw new Error(RUNTIME_NOT_STARTED);\n const generation = this.lifecycleGeneration;\n this.disconnectedServers.add(serverName);\n try {\n await clientManager.disconnectServer(serverName);\n } catch (error) {\n if (generation === this.lifecycleGeneration) this.disconnectedServers.delete(serverName);\n throw error;\n }\n if (generation !== this.lifecycleGeneration) return;\n this.clearToolWarnings(serverName);\n this.resourceCache.delete(serverName);\n this.authorizationUrls.delete(serverName);\n this.browserAuthorizationRequests.delete(serverName);\n this.catalog.applyStateChange({ serverName, state: 'closed' }, []);\n this.emitChange();\n this.updateToolVisibility();\n }\n\n /**\n * Reconnects one server with a fresh OAuth registration.\n *\n * The connection is dropped before credentials are cleared so a failed disconnect\n * does not silently sign the user out. Clearing both tokens and dynamic client\n * information prevents a server-side registration reset from replaying a stale\n * `client_id` forever.\n */\n async reauthorize(serverName: string): Promise<void> {\n const clientManager = this.getClientManager();\n if (!clientManager) throw new Error(RUNTIME_NOT_STARTED);\n const generation = this.lifecycleGeneration;\n const tokenStore = this.tokenStore;\n this.disconnectedServers.delete(serverName);\n // What this server offers is exactly what the reconnect is about to settle.\n this.resourceCache.delete(serverName);\n if (this.authorizationUrls.delete(serverName)) this.emitChange();\n this.browserAuthorizationRequests.add(serverName);\n try {\n await clientManager.disconnectServer(serverName);\n if (generation !== this.lifecycleGeneration) return;\n await tokenStore?.clear(serverName);\n if (generation !== this.lifecycleGeneration) return;\n await clientManager.ensureConnected(serverName);\n } finally {\n if (generation === this.lifecycleGeneration) this.browserAuthorizationRequests.delete(serverName);\n }\n }\n\n /** Reopens the URL already reserved for a flow without restarting that flow. */\n async openAuthorizationPage(serverName: string): Promise<void> {\n const authorizationUrl = this.authorizationUrls.get(serverName);\n if (!authorizationUrl) throw new Error(AUTHORIZATION_URL_NOT_READY);\n const onAuthorizationUrl = this.options.onAuthorizationUrl;\n if (!onAuthorizationUrl) throw new Error('This host cannot open authorization pages.');\n await onAuthorizationUrl(new URL(authorizationUrl), serverName, { openBrowser: true });\n }\n\n getSnapshot(): McpStatusSnapshot {\n return this.catalog.toSnapshot();\n }\n\n resolveToolSelectors(selectors: readonly string[]): readonly DoomMcpResolvedToolSelection[] {\n return this.catalog.resolveToolSelectors(selectors);\n }\n\n /** The fuller picture the overlay renders, with tool names and descriptions. */\n getServers(): readonly McpServerView[] {\n return this.catalog.toView().map((server) => {\n const authorizationUrl = this.authorizationUrls.get(server.name);\n return authorizationUrl ? { ...server, authorizationUrl } : server;\n });\n }\n\n /** Both the proxy tool and direct tools point to the same live warning origins. */\n getToolWarnings(): Readonly<Record<string, readonly ContextToolWarning[]>> {\n const tools = this.activeToolDefinitions().filter(isModelVisibleMcpTool);\n const entries = tools.flatMap((tool): [string, ContextToolWarning[]][] => {\n const warnings = this.outputSchemaWarnings\n .filter((warning) => warning.serverName === tool.serverName && warning.toolName === tool.toolName)\n .map((warning) => ({\n source: `${warning.serverName}/${warning.toolName} (${warning.method})`,\n path: warning.path,\n message: warning.message,\n }));\n return warnings.length === 0 ? [] : [[tool.piName, warnings]];\n });\n if (entries.length === 0) return {};\n return Object.fromEntries([...entries, ['mcp_use', entries.flatMap(([, warnings]) => warnings)]]);\n }\n\n private clearToolWarnings(serverName: string, method?: McpOutputSchemaWarning['method'], toolName?: string): void {\n const remaining = this.outputSchemaWarnings.filter(\n (warning) =>\n warning.serverName !== serverName ||\n (method !== undefined && warning.method !== method) ||\n (toolName !== undefined && warning.toolName !== toolName),\n );\n if (remaining.length === this.outputSchemaWarnings.length) return;\n this.outputSchemaWarnings = remaining;\n this.emitChange();\n }\n\n /**\n * Hides or restores a server's tools for the rest of this session.\n *\n * Deliberately does not disconnect: this is a session visibility control, so a\n * later enable is instant and does not discard an authenticated live connection.\n * Because each catalog row is now an actual downstream server, the control acts\n * on only that server's tools rather than on an aggregate proxy group.\n *\n * Nothing is re-registered on the way back: Pi 0.84 cannot unregister a tool, so\n * every tool stays registered and only the restriction moves.\n */\n setEnabled(serverName: string, enabled: boolean): void {\n this.catalog.setDisabled(serverName, !enabled);\n this.emitChange();\n this.updateToolVisibility();\n }\n\n /**\n * Lists one server's resources, from cache unless asked for a fresh call.\n *\n * The cache lives here rather than in the overlay so closing and reopening the\n * panel does not re-dial. A rejection is never cached, so a server that has no\n * `resources/list` capability, or one that was briefly unreachable, is retried by\n * the next request rather than remembered as empty.\n */\n async listResources(serverName: string, options: { refresh?: boolean } = {}): Promise<readonly McpResourceView[]> {\n if (this.disconnectedServers.has(serverName)) throw new Error(`MCP server is disconnected: ${serverName}`);\n if (!options.refresh) {\n const cached = this.resourceCache.get(serverName);\n if (cached) return cached;\n }\n const runtime = this.runtime;\n const services = runtime?.getServices();\n if (!runtime || !services) throw new Error(RUNTIME_NOT_STARTED);\n const connection = await services.clientManager.ensureConnected(serverName);\n const resources = await connection.listResources();\n // A reload that landed while this was in flight retired the container it was\n // read from, so the answer is returned to the caller but never written down.\n if (!runtime.isCurrent(services)) return resources;\n this.resourceCache.set(serverName, resources);\n this.catalog.setResourceCount(serverName, resources.length);\n this.emitChange();\n return resources;\n }\n\n /** Reads only the resource advertised by a currently admitted tool, on its existing server. */\n async readAppResource(\n server: string,\n tool: string,\n resourceUri: string,\n signal?: AbortSignal,\n ): Promise<ReadResourceResult> {\n const declaration = this.activeToolDefinitions().find(\n (candidate) => candidate.serverName === server && candidate.toolName === tool,\n );\n if (!declaration || normalizeMcpAppMetadata(declaration._meta).resourceUri !== resourceUri)\n throw new Error('This App resource is not available in the current session.');\n const runtime = this.runtime;\n const services = runtime?.getServices();\n const generation = this.lifecycleGeneration;\n if (!runtime || !services) throw new Error(RUNTIME_NOT_STARTED);\n signal?.throwIfAborted();\n const connection = await services.clientManager.ensureConnected(server);\n const check = () => {\n signal?.throwIfAborted();\n if (generation !== this.lifecycleGeneration || !runtime.isCurrent(services) || !this.isToolAvailable(declaration))\n throw new Error('This App resource belongs to a retired MCP runtime.');\n };\n check();\n const options = { timeout: services.clientManager.getServerRequestTimeout(server), signal };\n const result = await connection.readResource(resourceUri, options);\n check();\n return result;\n }\n\n /** Fires whenever the server picture changes. Returns its own disposer. */\n onChange(listener: () => void): () => void {\n this.changeListeners.add(listener);\n return () => {\n this.changeListeners.delete(listener);\n };\n }\n\n /**\n * Announces a change to whoever is watching.\n *\n * Listener failures are contained rather than propagated: this runs inside the\n * continuation that folds a server into Pi's tool set, and a throw escaping here\n * would abandon that fold, leaving the session silently short of tools because\n * something failed to repaint.\n */\n private emitChange(): void {\n for (const listener of this.changeListeners) {\n try {\n listener();\n } catch (error) {\n // Recorded rather than rethrown: a watcher that cannot render is a defect\n // worth seeing, but not one worth abandoning the tool set over.\n this.catalog.addDiagnostic(\n `An MCP change listener failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n getDiagnostics(): readonly string[] {\n return this.catalog.getDiagnostics();\n }\n\n async dispose(): Promise<void> {\n ++this.lifecycleGeneration;\n this.browserAuthorizationRequests.clear();\n this.authorizationUrls.clear();\n this.resourceCache.clear();\n this.outputSchemaWarnings = [];\n const retiredRuntime = this.runtime;\n this.runtime = undefined;\n await retiredRuntime?.dispose();\n }\n\n /**\n * Folds one server transition into Pi's tool set.\n *\n * The tool list is read from the live connection rather than the state event,\n * which carries no tools; a server that is not readable contributes none and its\n * cached tools simply stay inactive.\n *\n * `ensureConnected` rather than `getClient`: the manager announces `connected`\n * before it registers the client, so a listener that looks the client up\n * synchronously finds nothing and the server lands with an empty tool list.\n * This handler runs detached from the connect, so awaiting it cannot deadlock.\n */\n private onServerStateChange(change: McpServerStateChange, generation: number): void {\n if (generation !== this.lifecycleGeneration || this.disconnectedServers.has(change.serverName)) return;\n if (change.state === 'connecting') this.clearToolWarnings(change.serverName);\n // The flow this URL belonged to is over, one way or the other: a server that\n // reached a terminal state is not still waiting on a redirect.\n if (change.state !== 'connecting' && change.state !== 'needs-auth') {\n this.authorizationUrls.delete(change.serverName);\n }\n const runtime = this.runtime;\n const services = runtime?.getServices();\n const tools =\n change.state === 'connected' && services\n ? services.clientManager.ensureConnected(change.serverName).then((connection) => connection.listTools())\n : Promise.resolve([]);\n void tools\n .then(\n (tools) => ({ tools, error: undefined }),\n () => ({ tools: [], error: `Could not discover tools for MCP server \"${change.serverName}\".` }),\n )\n .then(({ tools, error }) => {\n if (\n generation !== this.lifecycleGeneration ||\n !runtime?.isCurrent(services) ||\n this.disconnectedServers.has(change.serverName)\n )\n return;\n if (error) this.catalog.addDiagnostic(error);\n this.catalog.applyStateChange(error ? { ...change, error } : change, tools);\n this.trackTools(this.catalog.allTools());\n this.emitChange();\n this.updateToolVisibility();\n });\n }\n}\n","import type { CatalogTool } from '../mcpCatalog';\n\nexport type CountTokens = (text: string) => number;\n\n/**\n * What one downstream tool would cost if it were added to the model's tool list directly: its\n * name, description and input schema, priced the way the context panel prices every other tool.\n */\nexport function mcpToolTokens(\n tool: Pick<CatalogTool, 'piName' | 'description' | 'inputSchema'>,\n countTokens: CountTokens,\n): number {\n return countTokens(\n JSON.stringify({\n name: tool.piName,\n ...(tool.description === undefined ? {} : { description: tool.description }),\n parameters: tool.inputSchema,\n }),\n );\n}\n","import type { ContextToolWarning } from '@agimon-ai/po-core/contextApi';\nimport type { DoomApi } from '@agimon-ai/po-core/packageApi';\n\nimport {\n MCP_SESSION_TOOL_API_PATH,\n MCP_SESSION_TOOL_NAME_QUERY,\n MCP_SESSION_TOOL_SERVER_QUERY,\n type McpSessionToolDetail,\n} from '../../types/webMcp';\nimport type { CatalogTool } from '../mcpCatalog';\nimport { type CountTokens, mcpToolTokens } from '../mcpToolCost';\n\nconst JSON_HEADERS = { 'content-type': 'application/json' };\n\nfunction json(body: unknown, status = 200): Response {\n return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS });\n}\n\nexport interface McpSessionApiSource {\n /** The permitted tools available in this session right now. */\n activeToolDefinitions(): readonly CatalogTool[];\n getToolWarnings?(): Readonly<Record<string, readonly ContextToolWarning[]>>;\n}\n\n/**\n * This package's session mount, `mcp-session`: one reachable tool's description and schema.\n *\n * Read-only and bounded to available tools, so a page can inspect what the agent may\n * call without the status line carrying every schema.\n */\nexport function createMcpSessionApi(source: McpSessionApiSource, countTokens: () => Promise<CountTokens>): DoomApi {\n return {\n basePath: 'mcp-session',\n start() {\n return {\n async fetch(request) {\n const url = new URL(request.url);\n if (request.method !== 'GET' || url.pathname !== MCP_SESSION_TOOL_API_PATH)\n return json({ error: 'Not found.' }, 404);\n const server = url.searchParams.get(MCP_SESSION_TOOL_SERVER_QUERY) ?? '';\n const name = url.searchParams.get(MCP_SESSION_TOOL_NAME_QUERY) ?? '';\n if (!server || !name) return json({ error: 'A tool is named by its server and tool name.' }, 400);\n const tool = source\n .activeToolDefinitions()\n .find((candidate) => candidate.serverName === server && candidate.toolName === name);\n if (!tool) return json({ error: `MCP tool ${server}/${name} is not available in this session.` }, 404);\n const warnings = source.getToolWarnings?.()[tool.piName];\n const detail: McpSessionToolDetail = {\n server,\n tool: name,\n piName: tool.piName,\n ...(warnings?.length ? { warnings } : {}),\n ...(tool.description === undefined ? {} : { description: tool.description }),\n inputSchema: tool.inputSchema,\n ...(tool._meta === undefined ? {} : { _meta: tool._meta }),\n tokens: mcpToolTokens(tool, await countTokens()),\n };\n return json(detail);\n },\n // Nothing outlives a request here.\n close: () => undefined,\n };\n },\n };\n}\n","import path from 'node:path';\n\nimport { loadHarnessState } from '@agimon-ai/po-config/harnessStore';\nimport { CONTEXT_TOOL_WARNINGS_STATUS_KEY } from '@agimon-ai/po-core/contextApi';\nimport type {\n DoomHeadlessActivity,\n DoomHeadlessCommand,\n DoomHeadlessExecutionContext,\n DoomHeadlessSelection,\n DoomHeadlessTool,\n} from '@agimon-ai/po-core/headless';\nimport { isDoomMcpProjection, type DoomMcpProjectionResolverService } from '@agimon-ai/po-core/mcpProjection';\nimport type { DoomMcpSessionConfig } from '@agimon-ai/po-core/mcpSession';\n\nimport { COMMAND_NAME, SERVER_COMMAND_DESCRIPTION } from '../../constants/mcp';\nimport { MCP_STATUS_KEY } from '../../constants/piMcp';\nimport { McpHeadlessToolParameters } from '../../schemas/mcpHeadlessTool';\nimport { formatMcpSessionAuthStatus, MCP_SESSION_AUTH_STATUS_KEY } from '../../types/webMcp';\nimport { isModelVisibleMcpTool } from '../mcpCatalog';\nimport { formatStatus } from '../mcpCommand';\nimport type { McpFilePublisher } from '../mcpFileParams/type';\nimport { McpSession } from '../mcpSession';\nimport { createMcpSessionApi } from '../mcpSessionApi';\nimport { createMcpChildTool, createMcpSessionToolsService } from '../mcpSessionTools';\nimport { type CountTokens, mcpToolTokens } from '../mcpToolCost';\nimport { mcpSessionConfigFromProjection } from '../projection';\nimport { readSessionConfig } from '../sessionConfig';\n\nfunction sessionConfiguration(execution: DoomHeadlessExecutionContext, workspaceRoot?: string): DoomMcpSessionConfig {\n if (workspaceRoot !== undefined) {\n const loaded = loadHarnessState({ ...execution.environment });\n const projection = loaded.state.mcpProjection;\n if (\n loaded.filePath &&\n loaded.state.root === workspaceRoot &&\n execution.repoRoot === workspaceRoot &&\n loaded.state.mcp &&\n loaded.state.majorMode === execution.selection.majorMode &&\n JSON.stringify(loaded.state.domains) === JSON.stringify(execution.selection.domains) &&\n JSON.stringify(loaded.state.layers) === JSON.stringify(execution.selection.activeLayers) &&\n isDoomMcpProjection(projection) &&\n projection.repoRoot === workspaceRoot\n )\n return mcpSessionConfigFromProjection(projection, execution.cwd);\n return {\n enabled: false,\n repoRoot: execution.cwd,\n stagingDirectory: path.join(execution.cwd, '.po', 'mcp-disabled'),\n sources: [],\n };\n }\n return readSessionConfig(execution.environment, execution.cwd);\n}\n\nexport function createMcpServerRuntime(\n environment: Readonly<Record<string, string | undefined>> = {},\n workspaceRoot?: string,\n getResolver?: () => DoomMcpProjectionResolverService | undefined,\n publishFile?: McpFilePublisher,\n) {\n let active: DoomHeadlessExecutionContext | undefined;\n let currentSelection: DoomHeadlessSelection | undefined;\n let staleSelection = false;\n let cleanup: (() => Promise<void>) | undefined;\n let transition = Promise.resolve();\n const authorizing = new Map<string, symbol>();\n // Authorization URLs reach clients through the MCP status snapshot, not the transcript.\n const session = new McpSession({\n environment: { ...environment },\n ...(publishFile === undefined ? {} : { publishFile }),\n });\n const assertAvailable = () => {\n if (!active) throw new Error('The MCP runtime has not started yet.');\n if (staleSelection) throw new Error('The MCP projection is stale for the current selection.');\n };\n const sessionTools = createMcpSessionToolsService(session, crypto.randomUUID(), assertAvailable);\n\n const refresh = (execution: DoomHeadlessExecutionContext, selection: DoomHeadlessSelection) => {\n staleSelection = true;\n sessionTools.refresh();\n authorizing.clear();\n transition = transition\n .catch(() => {})\n .then(async () => {\n if (active !== execution) return;\n const previousCleanup = cleanup;\n cleanup = undefined;\n try {\n await session.dispose();\n } finally {\n session.install({ enabled: false, repoRoot: execution.cwd, stagingDirectory: execution.cwd });\n await previousCleanup?.();\n }\n if (active !== execution) return;\n const resolver = getResolver?.();\n const loaded = workspaceRoot ? loadHarnessState({ ...execution.environment }) : undefined;\n const authorized =\n workspaceRoot &&\n loaded?.filePath &&\n loaded.state.root === workspaceRoot &&\n execution.repoRoot === workspaceRoot &&\n loaded.state.mcp &&\n isDoomMcpProjection(loaded.state.mcpProjection) &&\n loaded.state.mcpProjection.repoRoot === workspaceRoot &&\n loaded.state.mcpProjection.enabled;\n if (!resolver || !authorized) {\n // A missing or disabled saved projection never grants implicit repository access.\n if (active === execution && selection === currentSelection) {\n if (\n workspaceRoot === undefined ||\n JSON.stringify(execution.selection.domains) === JSON.stringify(selection.domains)\n ) {\n await session.reconfigure(\n sessionConfiguration(execution, workspaceRoot),\n execution.cwd,\n execution.repoRoot,\n );\n }\n staleSelection =\n workspaceRoot !== undefined &&\n JSON.stringify(execution.selection.domains) !== JSON.stringify(selection.domains);\n }\n return;\n }\n const candidate = await resolver.resolve(selection.domains);\n if (active !== execution || selection !== currentSelection) {\n await candidate.cleanup();\n return;\n }\n try {\n if (\n !isDoomMcpProjection(candidate.projection) ||\n candidate.projection.repoRoot !== workspaceRoot ||\n !candidate.projection.enabled\n ) {\n throw new Error('The selected domains returned an invalid MCP projection.');\n }\n await session.reconfigure(\n mcpSessionConfigFromProjection(candidate.projection, execution.cwd),\n execution.cwd,\n execution.repoRoot,\n );\n cleanup = () => candidate.cleanup();\n if (active === execution && selection === currentSelection) staleSelection = false;\n } catch (error) {\n await candidate.cleanup();\n throw error;\n }\n })\n .then(() => sessionTools.refresh())\n .catch(async (error: unknown) => {\n if (active !== execution || selection !== currentSelection) return;\n await execution.client.notify({\n title: 'Po MCP unavailable',\n body: error instanceof Error ? error.message : String(error),\n level: 'warning',\n });\n });\n return transition;\n };\n\n // The tokenizer loads on first use rather than at startup; the status republishes once it has.\n let countTokens: CountTokens | undefined;\n let tokenizer: Promise<CountTokens> | undefined;\n const loadTokenizer = (): Promise<CountTokens> => {\n tokenizer ??= import('gpt-tokenizer').then((module) => {\n countTokens = module.countTokens;\n return module.countTokens;\n });\n return tokenizer;\n };\n const toolTokens = new Map<string, number>();\n /** Each reachable tool's schema cost, keyed by its registered name, once the tokenizer is loaded. */\n const reachableTokens = (): ReadonlyMap<string, number> => {\n if (countTokens === undefined) return toolTokens;\n for (const tool of session.activeToolDefinitions()) {\n if (!toolTokens.has(tool.piName)) toolTokens.set(tool.piName, mcpToolTokens(tool, countTokens));\n }\n return toolTokens;\n };\n const api = createMcpSessionApi(session, loadTokenizer);\n\n const activity: DoomHeadlessActivity = {\n name: 'po-mcp-runtime',\n async start(execution) {\n active = execution;\n currentSelection = execution.selection;\n staleSelection = false;\n const reported = new Set<string>();\n const publish = () => {\n execution.client.setStatus(\n MCP_STATUS_KEY,\n session\n .getServers()\n .map((server) => server.name)\n .join(','),\n );\n const tokens = reachableTokens();\n execution.client.setStatus(\n MCP_SESSION_AUTH_STATUS_KEY,\n formatMcpSessionAuthStatus(\n session.getServers().map((server) => ({\n ...server,\n tools: server.tools.map((tool) => {\n const cost = tokens.get(tool.piName);\n return cost === undefined ? tool : { ...tool, tokens: cost };\n }),\n })),\n ),\n );\n const warnings = session.getToolWarnings();\n execution.client.setStatus(\n CONTEXT_TOOL_WARNINGS_STATUS_KEY,\n Object.keys(warnings).length === 0 ? undefined : JSON.stringify(warnings),\n );\n for (const diagnostic of session.getDiagnostics()) {\n if (reported.has(diagnostic)) continue;\n reported.add(diagnostic);\n void execution.client.notify({ title: 'Po MCP', body: diagnostic, level: 'warning' });\n }\n };\n const stopPublishing = session.onChange(() => {\n toolTokens.clear();\n publish();\n });\n void loadTokenizer().then(() => {\n if (active === execution) publish();\n });\n try {\n await refresh(execution, execution.selection);\n publish();\n } catch (error) {\n await execution.client.notify({\n title: 'Po MCP unavailable',\n body: error instanceof Error ? error.message : String(error),\n level: 'warning',\n });\n }\n return async () => {\n stopPublishing();\n if (active !== execution) return;\n active = undefined;\n currentSelection = undefined;\n staleSelection = true;\n sessionTools.refresh();\n authorizing.clear();\n await transition;\n const retiredCleanup = cleanup;\n cleanup = undefined;\n try {\n await session.dispose();\n } finally {\n // Withdraw tools and UI state even when a connection fails to close.\n session.install({ enabled: false, repoRoot: execution.cwd, stagingDirectory: execution.cwd });\n await retiredCleanup?.();\n execution.client.setStatus(MCP_STATUS_KEY, undefined);\n execution.client.setStatus(MCP_SESSION_AUTH_STATUS_KEY, undefined);\n execution.client.setStatus(CONTEXT_TOOL_WARNINGS_STATUS_KEY, undefined);\n }\n };\n },\n };\n\n const invoke: Parameters<typeof createMcpChildTool>[0] = async (parameters, signal) => {\n assertAvailable();\n const selected = sessionTools\n .snapshot()\n .filter(isModelVisibleMcpTool)\n .find((candidate) => candidate.serverName === parameters.server && candidate.toolName === parameters.tool);\n if (!selected)\n throw new Error(`MCP tool ${parameters.server}/${parameters.tool} is not available in this session.`);\n return sessionTools.invoke(selected.piName, parameters.arguments ?? {}, signal);\n };\n const childTool = createMcpChildTool(invoke, {\n snapshot: () => sessionTools.project().filter(isModelVisibleMcpTool),\n resolveSelectors: (selectors) => sessionTools.resolveSelectors(selectors),\n subscribe: (listener) => sessionTools.onChange(listener),\n });\n\n // web-plugin-tool-renderers: ignore mcp_use, headless-only generic MCP dispatch\n const tool: DoomHeadlessTool<typeof McpHeadlessToolParameters> = {\n name: 'mcp_use',\n label: 'MCP use',\n description: 'Call a tool exposed by a connected MCP server.',\n parameters: McpHeadlessToolParameters,\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n try {\n return await invoke(parameters, signal);\n } catch (error) {\n return {\n content: [{ type: 'text', text: error instanceof Error ? error.message : String(error) }],\n isError: true,\n };\n }\n },\n };\n\n const command: DoomHeadlessCommand = {\n name: COMMAND_NAME,\n description: SERVER_COMMAND_DESCRIPTION,\n async execute(args, execution) {\n const [subcommand = 'status', ...rest] = args.trim().split(/\\s+/u).filter(Boolean);\n const serverName = rest.join(' ');\n const notify = (body: string, level: 'info' | 'warning' = 'info') =>\n execution.client.notify({ title: 'Po MCP', body, level });\n try {\n if (subcommand === 'status') {\n await notify(formatStatus(session));\n return;\n }\n if (!active) throw new Error('The MCP runtime has not started yet.');\n if (staleSelection) throw new Error('The MCP projection is stale for the current selection.');\n if (subcommand === 'auth' || subcommand === 'disconnect') {\n if (!serverName) throw new Error(`Name the server, for example /mcp ${subcommand} <server>.`);\n const server = session.getServers().find((candidate) => candidate.name === serverName);\n if (!server) throw new Error(`Unknown MCP server: ${serverName}`);\n if (subcommand === 'disconnect') {\n await session.disconnect(serverName);\n authorizing.delete(serverName);\n await notify(`${serverName} is disconnected from this session. Saved credentials were kept.`);\n return;\n }\n if (server.authorizationUrl) {\n await notify(`${serverName} is waiting for sign-in. Open it from the MCP servers panel.`);\n return;\n }\n if (authorizing.has(serverName)) return;\n const request = Symbol(serverName);\n authorizing.set(serverName, request);\n const owner = active;\n // OAuth waits for the browser. Do not hold the session command queue while it does.\n void session.reauthorize(serverName).then(\n async () => {\n if (active !== owner || authorizing.get(serverName) !== request) return;\n authorizing.delete(serverName);\n await notify(`${serverName} is authorized.`);\n },\n async (error: unknown) => {\n if (active !== owner || authorizing.get(serverName) !== request) return;\n authorizing.delete(serverName);\n await notify(\n `Could not authorize ${serverName}: ${error instanceof Error ? error.message : String(error)}`,\n 'warning',\n );\n },\n );\n return;\n }\n if (subcommand === 'reload') {\n if (!currentSelection) throw new Error('The MCP runtime has not started yet.');\n await refresh(active, currentSelection);\n if (!staleSelection) await notify('Reconnecting MCP servers.');\n return;\n }\n throw new Error(`Unknown /${COMMAND_NAME} subcommand \"${subcommand}\". Use status, auth, disconnect, reload.`);\n } catch (error) {\n await notify(error instanceof Error ? error.message : String(error), 'warning');\n }\n },\n };\n return {\n session,\n sessionTools,\n api: [api],\n activities: [activity],\n commands: [command],\n tools: [tool],\n childTool,\n async onSelectionChange(selection: DoomHeadlessSelection) {\n if (!active || workspaceRoot === undefined) return;\n if (JSON.stringify(currentSelection) === JSON.stringify(selection)) return;\n currentSelection = selection;\n await refresh(active, selection);\n },\n };\n}\n","import { DOOM_CHILD_SESSION_MCP_TOOL_SERVICE } from '@agimon-ai/po-core/childSession';\nimport {\n DOOM_HEADLESS_HOST_SERVICE,\n type DoomHeadlessHostService,\n type DoomHeadlessRegistration,\n type DoomHeadlessTool,\n} from '@agimon-ai/po-core/headless';\nimport {\n DOOM_MCP_PROJECTION_RESOLVER_SERVICE,\n type DoomMcpProjectionResolverService,\n} from '@agimon-ai/po-core/mcpProjection';\nimport { DOOM_MCP_STATUS_SERVICE, type DoomMcpStatusService } from '@agimon-ai/po-core/mcpStatus';\nimport { DOOM_MCP_TOOL_RESOLVER_SERVICE, type DoomMcpToolResolverService } from '@agimon-ai/po-core/mcpToolResolver';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { createFileTransferTools } from '../../../../../services/fileTransfer';\nimport { createMcpAppsService } from '../../../../../services/mcpApps';\nimport { createConsentedFilePublisher } from '../../../../../services/mcpFileParams';\nimport { mountMcpHeadlessTools } from '../../../../../services/mcpHeadlessTools';\nimport { MCP_SESSION_TOOLS_SERVICE } from '../../../../../services/mcpSessionTools';\nimport { createMcpServerRuntime } from '../../../../../services/serverRuntime';\n\nexport const createMcpServerRoot = (context?: DoomServerPluginContext) => {\n let resolver: DoomMcpProjectionResolverService | undefined;\n let appHost = context?.agent;\n const hostContext = context?.host.context;\n // Outbound model, widget, and child-session file parameters share one consent flow.\n // Remote share_file instead delegates to the session-bound host restrictions.\n const publishFile =\n hostContext?.shareFile === undefined\n ? undefined\n : createConsentedFilePublisher({\n shareFile: (path, label) => hostContext.shareFile!(path, label),\n host: () => appHost,\n signal: context?.signal,\n });\n const runtime = createMcpServerRuntime(\n context?.agent?.context?.environment,\n context?.host.context.workspaceRoot,\n () => resolver,\n publishFile,\n );\n const generation = `${context?.agent?.context?.sessionId ?? crypto.randomUUID()}:mcp-server`;\n const { session } = runtime;\n const tools = [...runtime.tools, ...createFileTransferTools(context)];\n const apps = createMcpAppsService(runtime.sessionTools, () => appHost, context?.signal);\n const mountSession = (cordis: Context) => {\n cordis.inject([DOOM_MCP_PROJECTION_RESOLVER_SERVICE], (resolverContext) => {\n resolver = resolverContext.get(DOOM_MCP_PROJECTION_RESOLVER_SERVICE) as DoomMcpProjectionResolverService;\n return () => {\n resolver = undefined;\n };\n });\n cordis.inject([DOOM_HEADLESS_HOST_SERVICE], (hostContext) => {\n const host = hostContext.get(DOOM_HEADLESS_HOST_SERVICE) as DoomHeadlessHostService;\n appHost = host;\n const registrations = new Map<string, { tool: DoomHeadlessTool; registration: DoomHeadlessRegistration }>();\n const reconcile = () => {\n const tools = runtime.sessionTools.project();\n const names = new Set(tools.map((tool) => tool.name));\n for (const [name, entry] of registrations) {\n if (names.has(name)) continue;\n entry.registration.dispose();\n registrations.delete(name);\n }\n for (const tool of tools) {\n const previous = registrations.get(tool.name);\n if (previous?.tool === tool) continue;\n previous?.registration.dispose();\n registrations.set(tool.name, { tool, registration: host.registerTool(tool) });\n }\n };\n // Subscribe before reading cached declarations or discovery can race registration.\n const stopTools = runtime.sessionTools.onChange(reconcile);\n const stopSelection = host.subscribeSelection((selection) => runtime.onSelectionChange(selection));\n reconcile();\n return () => {\n if (appHost === host) appHost = undefined;\n stopTools();\n stopSelection();\n for (const entry of registrations.values()) entry.registration.dispose();\n registrations.clear();\n };\n });\n cordis.plugin((provider) => {\n provider.provide(DOOM_MCP_STATUS_SERVICE, {\n generation,\n getSnapshot: () => session.getSnapshot(),\n onChange: (listener) => session.onChange(listener),\n } satisfies DoomMcpStatusService);\n provider.provide(DOOM_MCP_TOOL_RESOLVER_SERVICE, {\n generation,\n resolve: (selectors) => session.resolveToolSelectors(selectors),\n } satisfies DoomMcpToolResolverService);\n provider.provide(MCP_SESSION_TOOLS_SERVICE, runtime.sessionTools);\n provider.provide(DOOM_CHILD_SESSION_MCP_TOOL_SERVICE, runtime.childTool);\n return () => runtime.sessionTools.dispose();\n });\n };\n return {\n value: { ...runtime, appMethods: apps.methods },\n activities: runtime.activities,\n services: [mountMcpHeadlessTools(tools), mountSession],\n onDispose: apps.dispose,\n };\n};\nexport type McpServerScope = Awaited<ReturnType<typeof createMcpServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport { createMcpServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createMcpServerRoot);\n","import { type AuthEntry, FileTokenStore, type TokenStore } from '@agimon-ai/mcp-proxy';\n\n/** Keyring service name. One credential per downstream MCP server. */\nexport const KEYRING_SERVICE = 'ai.agimon.doom-mcp.oauth';\n\n/** The slice of `@napi-rs/keyring`'s `AsyncEntry` this store uses. */\nexport interface KeyringEntry {\n getPassword(): Promise<string | undefined>;\n setPassword(password: string): Promise<void>;\n deletePassword(): Promise<unknown>;\n}\n\nexport type KeyringEntryFactory = (service: string, account: string) => KeyringEntry;\n\n/**\n * OAuth credentials in the OS keyring, with an owner-only file store behind it.\n *\n * The keyring is a native module and the platform service it talks to may be absent\n * (a headless Linux box with no secret service, an unsupported architecture). A\n * missing credential is reported as `undefined` rather than raised, so a rejection\n * means the keyring itself is unusable and the store degrades to the file fallback\n * for the rest of the session instead of failing the run.\n */\nexport class KeyringTokenStore implements TokenStore {\n private degraded = false;\n\n constructor(\n private readonly createEntry: KeyringEntryFactory,\n private readonly fallback: TokenStore = new FileTokenStore(),\n ) {}\n\n /** True once the keyring has failed and the file store has taken over. */\n get isDegraded(): boolean {\n return this.degraded;\n }\n\n async read(serverName: string): Promise<AuthEntry | undefined> {\n if (this.degraded) return this.fallback.read(serverName);\n let raw: string | undefined;\n try {\n raw = await this.createEntry(KEYRING_SERVICE, serverName).getPassword();\n } catch {\n this.degraded = true;\n return this.fallback.read(serverName);\n }\n if (!raw) return undefined;\n try {\n return JSON.parse(raw) as AuthEntry;\n } catch {\n // A credential we cannot parse is treated as absent so the next authorization\n // overwrites it, rather than wedging the server on every start.\n return undefined;\n }\n }\n\n async write(serverName: string, entry: AuthEntry): Promise<void> {\n if (!this.degraded) {\n try {\n await this.createEntry(KEYRING_SERVICE, serverName).setPassword(JSON.stringify(entry));\n return;\n } catch {\n this.degraded = true;\n }\n }\n await this.fallback.write(serverName, entry);\n }\n\n /**\n * Removes the credential from both stores.\n *\n * A session that degraded part way through can have left a copy in either place,\n * and \"signed out\" has to mean no credential survives anywhere. A keyring that\n * refuses the delete is reported rather than absorbed: the caller was told the\n * credential is gone, and it is not. The fallback is still cleared first so the\n * failure leaves one surviving copy instead of two.\n */\n async clear(serverName: string): Promise<void> {\n let keyringFailure: unknown;\n if (!this.degraded) {\n try {\n await this.createEntry(KEYRING_SERVICE, serverName).deletePassword();\n } catch (error) {\n keyringFailure = error;\n }\n }\n await this.fallback.clear(serverName);\n if (keyringFailure !== undefined) {\n const detail = keyringFailure instanceof Error ? keyringFailure.message : JSON.stringify(keyringFailure);\n throw new Error(`Keyring credential for \"${serverName}\" could not be removed: ${detail}`, {\n cause: keyringFailure,\n });\n }\n }\n}\n\n/**\n * Builds the token store for this host, falling back when the native module is absent.\n *\n * doom-mcp loads inside Pi, so a platform without a prebuilt keyring binary must\n * still get a working session rather than a failed extension install.\n */\nexport async function createTokenStore(fallback: TokenStore = new FileTokenStore()): Promise<TokenStore> {\n try {\n const { AsyncEntry } = await import('@napi-rs/keyring');\n return new KeyringTokenStore((service, account) => new AsyncEntry(service, account), fallback);\n } catch {\n return fallback;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { McpServerStateChange, McpToolInfo, TokenStore } from '@agimon-ai/mcp-proxy';\nimport type { DoomOAuthRedirect, DoomRepositorySyncView } from '@agimon-ai/po-core/packageApi';\n\nimport type { McpConfigGroups, McpConfigSource, McpSessionConfig } from '../../types/mcpConfig';\nimport type {\n McpAuthorizationFlow,\n McpRepositoryCatalog,\n McpRepositoryServer,\n McpRepositoryServerState,\n McpRepositoryTool,\n} from '../../types/webMcp';\nimport { buildMcpConfigGroups } from '../configSources';\nimport { createTokenStore } from '../keyringTokenStore';\nimport { toPiToolName } from '../mcpCatalog';\nimport { hubCallbackSink, McpRuntimeOwner, readCachedCatalog } from '../mcpRuntime';\nimport { mcpSessionConfigFromProjection } from '../projection';\n\nconst DISCOVERY_TIMEOUT_MS = 30_000;\nconst AUTHORIZATION_TIMEOUT_MS = 5 * 60_000;\nconst TERMINAL_FLOW_RETENTION_MS = 5 * 60_000;\nconst EMPTY_SYNC = { fresh: false, reasons: ['never-synced'] } as const;\n\ninterface PreparedMcpRepository {\n catalog: McpRepositoryCatalog;\n configSources: McpConfigSource[];\n groups: McpConfigGroups;\n stagingDirectory?: string;\n}\n\ninterface InternalAuthorizationFlow extends McpAuthorizationFlow {\n owner?: McpRuntimeOwner;\n stagingDirectory?: string;\n timeout?: ReturnType<typeof setTimeout>;\n retainedUntil?: number;\n}\n\nexport interface McpSettingsManagerOptions {\n discoveryTimeoutMs?: number;\n authorizationTimeoutMs?: number;\n tokenStore?: TokenStore;\n}\n\nfunction configuredServerNames(groups: McpConfigGroups): string[] {\n return [...new Set([...groups.sessionLocal.serverNames, ...groups.shared.serverNames])].sort((left, right) =>\n left.localeCompare(right),\n );\n}\n\nfunction configSources(groups: McpConfigGroups): McpConfigSource[] {\n return [...groups.sessionLocal.configSources, ...groups.shared.configSources];\n}\n\nfunction toolView(serverName: string, tool: McpToolInfo): McpRepositoryTool {\n return {\n name: tool.name,\n piName: toPiToolName(serverName, tool.name),\n ...(tool.description ? { description: tool.description } : {}),\n };\n}\n\nfunction sanitizeDiagnostic(message: string, repositoryRoot: string, stagingDirectory: string | undefined): string {\n let safe = message;\n for (const value of [stagingDirectory, repositoryRoot, os.homedir()]) {\n if (value) safe = safe.split(value).join(value === os.homedir() ? '~' : '<repository>');\n }\n return safe.replace(/[A-Za-z]:\\\\[^\\s,;)'\"`]+/gu, '<path>').replace(/(^|\\s)\\/(?!\\/)[^\\s,;)'\"`]+/gu, '$1<path>');\n}\n\nfunction publicFlow(flow: InternalAuthorizationFlow): McpAuthorizationFlow {\n return {\n id: flow.id,\n repositoryId: flow.repositoryId,\n serverName: flow.serverName,\n status: flow.status,\n ...(flow.authorizationUrl ? { authorizationUrl: flow.authorizationUrl } : {}),\n ...(flow.error ? { error: flow.error } : {}),\n expiresAt: flow.expiresAt,\n };\n}\n\nfunction isTerminal(status: McpAuthorizationFlow['status']): boolean {\n return status === 'completed' || status === 'failed' || status === 'cancelled' || status === 'expired';\n}\n\nfunction safeAuthorizationUrl(url: URL): string | undefined {\n if ((url.protocol !== 'https:' && url.protocol !== 'http:') || url.toString().length > 4096) return undefined;\n return url.toString();\n}\n\nexport class McpSettingsManager {\n private readonly discoveryTimeoutMs: number;\n private readonly authorizationTimeoutMs: number;\n private readonly injectedTokenStore?: TokenStore;\n private readonly busyRepositories = new Set<string>();\n private readonly flows = new Map<string, InternalAuthorizationFlow>();\n\n constructor(options: McpSettingsManagerOptions = {}) {\n this.discoveryTimeoutMs = options.discoveryTimeoutMs ?? DISCOVERY_TIMEOUT_MS;\n this.authorizationTimeoutMs = options.authorizationTimeoutMs ?? AUTHORIZATION_TIMEOUT_MS;\n this.injectedTokenStore = options.tokenStore;\n }\n\n private async tokenStore(): Promise<TokenStore> {\n return this.injectedTokenStore ?? (await createTokenStore());\n }\n\n private async credentialPresence(serverNames: readonly string[]): Promise<Map<string, boolean>> {\n const presence = new Map<string, boolean>();\n try {\n const tokenStore = await this.tokenStore();\n await Promise.all(\n serverNames.map(async (serverName) => {\n try {\n presence.set(serverName, (await tokenStore.read(serverName)) !== undefined);\n } catch {\n presence.set(serverName, false);\n }\n }),\n );\n } catch {\n for (const serverName of serverNames) presence.set(serverName, false);\n }\n return presence;\n }\n\n private prepare(\n repositoryId: string,\n repositoryRoot: string,\n sync: DoomRepositorySyncView | undefined,\n onlyServer?: string,\n ): PreparedMcpRepository {\n if (!sync?.mcpProjection) {\n const readiness = sync ?? EMPTY_SYNC;\n return {\n catalog: {\n repositoryId,\n sync: { fresh: readiness.fresh, reasons: [...readiness.reasons] },\n servers: [],\n droppedServers: [],\n diagnostics: [],\n },\n configSources: [],\n groups: {\n shared: { configSources: [], configPaths: [], serverNames: [] },\n sessionLocal: { configSources: [], configPaths: [], serverNames: [] },\n droppedServers: [],\n diagnostics: [],\n },\n };\n }\n\n const stagingDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'po-mcp-settings-'));\n fs.chmodSync(stagingDirectory, 0o700);\n try {\n const projected = mcpSessionConfigFromProjection(sync.mcpProjection);\n const configuration: McpSessionConfig = {\n ...projected,\n repoRoot: repositoryRoot,\n stagingDirectory,\n ...(onlyServer ? { allowlist: { servers: [onlyServer], proxy: [] } } : {}),\n };\n const groups = buildMcpConfigGroups(configuration);\n const sources = configSources(groups);\n const names = configuredServerNames(groups);\n const cachedByServer = new Map(readCachedCatalog(sources).servers.map((server) => [server.name, server.tools]));\n const servers: McpRepositoryServer[] = names.map((name) => {\n const tools = cachedByServer.get(name) ?? [];\n return {\n name,\n state: 'not-connected',\n source: tools.length === 0 ? 'configured' : 'cached',\n credentialPresent: false,\n tools: tools.map((tool) => toolView(name, tool)),\n };\n });\n return {\n catalog: {\n repositoryId,\n sync: { fresh: sync.fresh, reasons: [...sync.reasons] },\n servers,\n droppedServers: [...groups.droppedServers],\n diagnostics: groups.diagnostics.map((diagnostic) =>\n sanitizeDiagnostic(diagnostic, repositoryRoot, stagingDirectory),\n ),\n },\n configSources: sources,\n groups,\n stagingDirectory,\n };\n } catch (error) {\n fs.rmSync(stagingDirectory, { recursive: true, force: true });\n throw error;\n }\n }\n\n private cleanupPrepared(prepared: PreparedMcpRepository): void {\n if (prepared.stagingDirectory) fs.rmSync(prepared.stagingDirectory, { recursive: true, force: true });\n }\n\n async readCatalog(\n repositoryId: string,\n repositoryRoot: string,\n sync: DoomRepositorySyncView | undefined,\n ): Promise<McpRepositoryCatalog> {\n const prepared = this.prepare(repositoryId, repositoryRoot, sync);\n try {\n const presence = await this.credentialPresence(prepared.catalog.servers.map((server) => server.name));\n return {\n ...prepared.catalog,\n servers: prepared.catalog.servers.map((server) => ({\n ...server,\n credentialPresent: presence.get(server.name) ?? false,\n })),\n };\n } finally {\n this.cleanupPrepared(prepared);\n }\n }\n\n async discover(\n repositoryId: string,\n repositoryRoot: string,\n sync: DoomRepositorySyncView | undefined,\n ): Promise<McpRepositoryCatalog> {\n if (this.busyRepositories.has(repositoryId))\n throw new Error('MCP management is already active for this repository.');\n const prepared = this.prepare(repositoryId, repositoryRoot, sync);\n if (!prepared.catalog.sync.fresh) {\n this.cleanupPrepared(prepared);\n throw new Error('Sync this repository before discovering MCP capabilities.');\n }\n if (prepared.configSources.length === 0) {\n this.cleanupPrepared(prepared);\n return prepared.catalog;\n }\n\n this.busyRepositories.add(repositoryId);\n const owner = new McpRuntimeOwner();\n const liveStates = new Map<string, McpServerStateChange>();\n try {\n const handle = await owner.start({\n configSources: prepared.configSources,\n workspaceRoot: repositoryRoot,\n executionCwd: repositoryRoot,\n tokenStore: await this.tokenStore(),\n onAuthorizationUrl: (_url, serverName) => {\n liveStates.set(serverName, { serverName, state: 'needs-auth' });\n },\n onServerStateChange: (change) => liveStates.set(change.serverName, change),\n });\n if (handle) {\n await Promise.race([\n handle.connectionsSettled,\n new Promise<void>((resolve) => setTimeout(resolve, this.discoveryTimeoutMs)),\n ]);\n }\n const manager = handle?.services.clientManager;\n const cachedByServer = new Map(\n readCachedCatalog(prepared.configSources).servers.map((server) => [server.name, server.tools]),\n );\n const presence = await this.credentialPresence(prepared.catalog.servers.map((server) => server.name));\n const servers = await Promise.all(\n prepared.catalog.servers.map(async (server): Promise<McpRepositoryServer> => {\n const change = liveStates.get(server.name);\n const state = (change?.state ??\n manager?.getServerState(server.name) ??\n server.state) as McpRepositoryServerState;\n let tools = cachedByServer.get(server.name) ?? [];\n let source: McpRepositoryServer['source'] = tools.length === 0 ? 'configured' : 'cached';\n if (state === 'connected' && manager) {\n try {\n tools = await manager\n .ensureConnected(server.name)\n .then(async (connection) => await connection.listTools());\n source = 'live';\n } catch {\n // Preserve the cache when a server moved between state inspection and listing.\n }\n }\n return {\n name: server.name,\n state,\n source,\n credentialPresent: presence.get(server.name) ?? false,\n tools: tools.map((tool) => toolView(server.name, tool)),\n ...(change?.error ? { error: 'The server reported a connection error.' } : {}),\n };\n }),\n );\n return { ...prepared.catalog, servers };\n } finally {\n await owner.dispose();\n this.cleanupPrepared(prepared);\n this.busyRepositories.delete(repositoryId);\n }\n }\n\n async authorize(\n repositoryId: string,\n repositoryRoot: string,\n sync: DoomRepositorySyncView | undefined,\n serverName: string,\n /**\n * The hub's redirect surface. Present, the authorization server sends the\n * browser back to the hub, which is reachable whether the operator is at\n * this machine or on a tunnel. Absent, the proxy keeps its loopback\n * listener and behaviour is unchanged.\n */\n redirect?: DoomOAuthRedirect,\n ): Promise<McpAuthorizationFlow> {\n this.sweepFlows();\n if (this.busyRepositories.has(repositoryId))\n throw new Error('MCP management is already active for this repository.');\n\n const full = this.prepare(repositoryId, repositoryRoot, sync);\n const configured = full.catalog.servers.some((server) => server.name === serverName);\n const fresh = full.catalog.sync.fresh;\n this.cleanupPrepared(full);\n if (!fresh) throw new Error('Sync this repository before authorizing an MCP server.');\n if (!configured) throw new Error('That MCP server is not enabled for this repository.');\n\n const prepared = this.prepare(repositoryId, repositoryRoot, sync, serverName);\n const flow: InternalAuthorizationFlow = {\n id: randomUUID(),\n repositoryId,\n serverName,\n status: 'starting',\n expiresAt: Date.now() + this.authorizationTimeoutMs,\n stagingDirectory: prepared.stagingDirectory,\n };\n this.flows.set(flow.id, flow);\n this.busyRepositories.add(repositoryId);\n void this.runAuthorization(flow, prepared.configSources, repositoryRoot, redirect);\n return publicFlow(flow);\n }\n\n getAuthorization(flowId: string, repositoryId: string): McpAuthorizationFlow | undefined {\n this.sweepFlows();\n const flow = this.flows.get(flowId);\n return flow?.repositoryId === repositoryId ? publicFlow(flow) : undefined;\n }\n\n async cancelAuthorization(flowId: string, repositoryId: string): Promise<McpAuthorizationFlow | undefined> {\n const flow = this.flows.get(flowId);\n if (!flow || flow.repositoryId !== repositoryId) return undefined;\n if (!isTerminal(flow.status)) {\n flow.status = 'cancelled';\n await this.finishFlow(flow);\n }\n return publicFlow(flow);\n }\n\n private async runAuthorization(\n flow: InternalAuthorizationFlow,\n sources: McpConfigSource[],\n repositoryRoot: string,\n redirect?: DoomOAuthRedirect,\n ): Promise<void> {\n const owner = new McpRuntimeOwner();\n flow.owner = owner;\n flow.timeout = setTimeout(() => {\n if (isTerminal(flow.status)) return;\n flow.status = 'expired';\n flow.error = 'Authorization timed out.';\n void this.finishFlow(flow);\n }, this.authorizationTimeoutMs);\n\n try {\n const handle = await owner.start({\n configSources: sources,\n workspaceRoot: repositoryRoot,\n executionCwd: repositoryRoot,\n tokenStore: await this.tokenStore(),\n ...(redirect ? { callbackServer: hubCallbackSink(redirect) } : {}),\n onAuthorizationUrl: (url, serverName) => {\n if (serverName !== flow.serverName || isTerminal(flow.status)) return;\n const safeUrl = safeAuthorizationUrl(url);\n if (!safeUrl) {\n flow.status = 'failed';\n flow.error = 'The server returned an invalid authorization URL.';\n void this.finishFlow(flow);\n return;\n }\n flow.authorizationUrl = safeUrl;\n flow.status = 'waiting';\n },\n onServerStateChange: (change) => this.applyAuthorizationState(flow, change),\n });\n if (!handle || isTerminal(flow.status)) return;\n const manager = handle.services.clientManager;\n await manager.disconnectServer(flow.serverName);\n await manager.ensureConnected(flow.serverName);\n if (!isTerminal(flow.status)) flow.status = 'completed';\n } catch {\n if (!isTerminal(flow.status)) {\n flow.status = 'failed';\n flow.error = 'The MCP server could not complete authorization.';\n }\n } finally {\n if (!isTerminal(flow.status)) flow.status = 'completed';\n await this.finishFlow(flow);\n }\n }\n\n private applyAuthorizationState(flow: InternalAuthorizationFlow, change: McpServerStateChange): void {\n if (change.serverName !== flow.serverName || isTerminal(flow.status)) return;\n if (change.state === 'connected') flow.status = 'completed';\n else if (change.state === 'needs-auth' && flow.status === 'starting') flow.status = 'waiting';\n else if (change.state === 'failed') {\n flow.status = 'failed';\n flow.error = 'The MCP server rejected the authorization attempt.';\n }\n }\n\n private async finishFlow(flow: InternalAuthorizationFlow): Promise<void> {\n if (flow.timeout) clearTimeout(flow.timeout);\n flow.timeout = undefined;\n const owner = flow.owner;\n flow.owner = undefined;\n await owner?.dispose();\n if (flow.stagingDirectory) fs.rmSync(flow.stagingDirectory, { recursive: true, force: true });\n flow.stagingDirectory = undefined;\n this.busyRepositories.delete(flow.repositoryId);\n flow.retainedUntil = Date.now() + TERMINAL_FLOW_RETENTION_MS;\n }\n\n private sweepFlows(): void {\n const now = Date.now();\n for (const [id, flow] of this.flows) {\n if (flow.retainedUntil !== undefined && flow.retainedUntil <= now) this.flows.delete(id);\n }\n }\n\n async dispose(): Promise<void> {\n await Promise.all(\n [...this.flows.values()].map(async (flow) => {\n if (!isTerminal(flow.status)) flow.status = 'cancelled';\n await this.finishFlow(flow);\n }),\n );\n this.flows.clear();\n this.busyRepositories.clear();\n }\n}\n","import { apiResponse, defineApiRoutes } from '@agimon-ai/po-core/web';\n\nimport {\n MCP_AUTHORIZATION_API_PATH,\n MCP_DISCOVERY_API_PATH,\n MCP_FLOW_ID_PARAM,\n MCP_REPOSITORY_API_PATH,\n MCP_REPOSITORY_ID_QUERY,\n MCP_SESSION_TOOL_API_PATH,\n MCP_SESSION_TOOL_NAME_QUERY,\n MCP_SESSION_TOOL_SERVER_QUERY,\n type McpAuthorizationFlow,\n type McpRepositoryCatalog,\n type McpSessionToolDetail,\n} from './webMcp';\n\n/** One authorization flow, addressed by id below the flow collection. */\nconst AUTHORIZATION_FLOW_PATH = `${MCP_AUTHORIZATION_API_PATH}/:${MCP_FLOW_ID_PARAM}`;\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/(backend)/api/mcp/`, so the mount is stated once, by the\n * folder that creates it. The sub-paths come from `webMcp`, which already owned\n * them, so this table names where a route sits and nothing else.\n *\n * This is the one file the hub handler and the settings panel both read, so a\n * path cannot move on one side alone. The handler matches on these strings\n * rather than parsing its own copies of them.\n *\n * `:flowId` is the client's parameter syntax; the handler reads the segment off\n * the same path, so the two cannot disagree about where the id sits.\n */\nexport default defineApiRoutes({\n catalog: {\n method: 'GET',\n path: MCP_REPOSITORY_API_PATH,\n query: [MCP_REPOSITORY_ID_QUERY],\n response: apiResponse<McpRepositoryCatalog>(),\n },\n discover: {\n method: 'POST',\n path: MCP_DISCOVERY_API_PATH,\n response: apiResponse<McpRepositoryCatalog>(),\n },\n authorize: {\n method: 'POST',\n path: MCP_AUTHORIZATION_API_PATH,\n response: apiResponse<McpAuthorizationFlow>(),\n },\n readAuthorization: {\n method: 'GET',\n path: AUTHORIZATION_FLOW_PATH,\n query: [MCP_REPOSITORY_ID_QUERY],\n response: apiResponse<McpAuthorizationFlow>(),\n },\n /** The same path as `readAuthorization`; the method is the whole of the difference. */\n cancelAuthorization: {\n method: 'DELETE',\n path: AUTHORIZATION_FLOW_PATH,\n query: [MCP_REPOSITORY_ID_QUERY],\n response: apiResponse<McpAuthorizationFlow>(),\n },\n /** Session scope: one available tool's registered name, description and schema. */\n sessionTool: {\n method: 'GET',\n path: MCP_SESSION_TOOL_API_PATH,\n query: [MCP_SESSION_TOOL_SERVER_QUERY, MCP_SESSION_TOOL_NAME_QUERY],\n response: apiResponse<McpSessionToolDetail>(),\n },\n});\n","import type { DoomApi, DoomApiContext } from '@agimon-ai/po-core/packageApi';\n\nimport { McpSettingsManager } from '../../services/mcpSettingsManager';\nimport routes from '../../types/apiRoutes';\nimport { MCP_FLOW_ID_PARAM, MCP_REPOSITORY_ID_QUERY } from '../../types/webMcp';\n\n/**\n * What sits above a flow id, read off the flow route itself.\n *\n * This handler matches paths by hand rather than through a router, so the one\n * route carrying a parameter is split here: everything before `:flowId` is the\n * prefix a request must start with, and what follows it is the id.\n */\nconst AUTHORIZATION_FLOW_PREFIX = routes.readAuthorization.path.replace(`:${MCP_FLOW_ID_PARAM}`, '');\n\nconst JSON_HEADERS = { 'content-type': 'application/json' };\n// Legacy 32-hex ids, `repo-` ids, and the UUIDs the workspace registry mints today.\nconst REPOSITORY_ID =\n /^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$/u;\nconst FLOW_ID = /^[a-f0-9-]{36}$/u;\nconst MAX_BODY_BYTES = 8 * 1024;\nconst MAX_SERVER_NAME = 160;\nconst manager = new McpSettingsManager();\n\ntype JsonRecord = Record<string, unknown>;\n\nfunction json(body: unknown, status = 200): Response {\n return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS });\n}\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nasync function bodyOf(request: Request): Promise<JsonRecord | undefined> {\n const text = await request.text();\n if (text.length > MAX_BODY_BYTES) return undefined;\n try {\n const parsed = JSON.parse(text) as unknown;\n return isRecord(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction repositoryIdOf(value: unknown): string | undefined {\n return typeof value === 'string' && REPOSITORY_ID.test(value) ? value : undefined;\n}\n\nfunction serverNameOf(value: unknown): string | undefined {\n return typeof value === 'string' &&\n value.length > 0 &&\n value.length <= MAX_SERVER_NAME &&\n !Array.from(value).some((character) => character.charCodeAt(0) <= 0x1f)\n ? value\n : undefined;\n}\n\nfunction resolveRepository(context: DoomApiContext, repositoryId: string): string | undefined {\n return context.resolveRepository?.(repositoryId);\n}\n\nfunction errorStatus(error: unknown): { status: number; message: string } {\n const message = error instanceof Error ? error.message : '';\n if (message.includes('already active')) return { status: 409, message };\n if (message.startsWith('Sync this repository')) return { status: 409, message };\n if (message.includes('not enabled')) return { status: 404, message };\n return { status: 500, message: 'MCP management could not complete that request.' };\n}\n\nasync function handleCatalog(request: Request, context: DoomApiContext): Promise<Response> {\n const repositoryId = repositoryIdOf(new URL(request.url).searchParams.get(MCP_REPOSITORY_ID_QUERY));\n if (!repositoryId) return json({ error: 'A valid repositoryId is required.' }, 400);\n const repositoryRoot = resolveRepository(context, repositoryId);\n if (!repositoryRoot) return json({ error: 'That repository is not available to this hub.' }, 404);\n try {\n return json(\n await manager.readCatalog(repositoryId, repositoryRoot, await context.readRepositorySync?.(repositoryId)),\n );\n } catch {\n return json({ error: 'The synced MCP catalog could not be read.' }, 500);\n }\n}\n\nasync function handleDiscovery(request: Request, context: DoomApiContext): Promise<Response> {\n const body = await bodyOf(request);\n const repositoryId = repositoryIdOf(body?.repositoryId);\n if (!repositoryId) return json({ error: 'A valid repositoryId is required.' }, 400);\n const repositoryRoot = resolveRepository(context, repositoryId);\n if (!repositoryRoot) return json({ error: 'That repository is not available to this hub.' }, 404);\n try {\n return json(await manager.discover(repositoryId, repositoryRoot, await context.readRepositorySync?.(repositoryId)));\n } catch (error) {\n const failure = errorStatus(error);\n return json({ error: failure.message }, failure.status);\n }\n}\n\nasync function handleAuthorize(request: Request, context: DoomApiContext): Promise<Response> {\n const body = await bodyOf(request);\n const repositoryId = repositoryIdOf(body?.repositoryId);\n const serverName = serverNameOf(body?.serverName);\n if (!repositoryId || !serverName) return json({ error: 'A valid repositoryId and serverName are required.' }, 400);\n const repositoryRoot = resolveRepository(context, repositoryId);\n if (!repositoryRoot) return json({ error: 'That repository is not available to this hub.' }, 404);\n try {\n return json(\n await manager.authorize(\n repositoryId,\n repositoryRoot,\n await context.readRepositorySync?.(repositoryId),\n serverName,\n context.oauthRedirect?.(),\n ),\n 202,\n );\n } catch (error) {\n const failure = errorStatus(error);\n return json({ error: failure.message }, failure.status);\n }\n}\n\nasync function handleAuthorizationFlow(request: Request, context: DoomApiContext, path: string): Promise<Response> {\n const flowId = path.slice(AUTHORIZATION_FLOW_PREFIX.length);\n const repositoryId = repositoryIdOf(new URL(request.url).searchParams.get(MCP_REPOSITORY_ID_QUERY));\n if (!repositoryId || !FLOW_ID.test(flowId))\n return json({ error: 'A valid repositoryId and flow id are required.' }, 400);\n if (!resolveRepository(context, repositoryId)) {\n return json({ error: 'That repository is not available to this hub.' }, 404);\n }\n if (request.method === routes.cancelAuthorization.method) {\n const flow = await manager.cancelAuthorization(flowId, repositoryId);\n return flow ? json(flow) : json({ error: 'That authorization flow was not found.' }, 404);\n }\n const flow = manager.getAuthorization(flowId, repositoryId);\n return flow ? json(flow) : json({ error: 'That authorization flow was not found.' }, 404);\n}\n\nexport const mcpHubApi: DoomApi = {\n basePath: 'mcp',\n start(context) {\n return {\n async fetch(request) {\n const path = new URL(request.url).pathname;\n if (request.method === routes.catalog.method && path === routes.catalog.path) {\n return await handleCatalog(request, context);\n }\n if (request.method === routes.discover.method && path === routes.discover.path) {\n return await handleDiscovery(request, context);\n }\n if (request.method === routes.authorize.method && path === routes.authorize.path) {\n return await handleAuthorize(request, context);\n }\n if (\n (request.method === routes.readAuthorization.method ||\n request.method === routes.cancelAuthorization.method) &&\n path.startsWith(AUTHORIZATION_FLOW_PREFIX)\n ) {\n return await handleAuthorizationFlow(request, context, path);\n }\n return json({ error: 'Not found.' }, 404);\n },\n close() {\n void manager.dispose();\n },\n };\n },\n};\n","import { defineRoute } from '@agimon-ai/po-core/extensionFile';\n\nimport { mcpHubApi } from '../../../../services/mcpHubApi';\n\n/**\n * Mounts this package's HTTP API at `mcp`, which the folder names.\n *\n * The folder is the declaration: the build reads the base path off it and hands\n * the browser a client bound to the same segment, so the settings panel can no\n * longer spell a workspace mount by hand.\n */\nexport default defineRoute(mcpHubApi);\n","import { defineRoute, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport type { McpServerScope } from '../../_lib/serverRoot';\n\n/** Mounts the session's `mcp-session` API: the reachable tool detail the context panel opens. */\nexport default defineRoute((context: WithRoot<unknown, McpServerScope>) => context.root.api[0]!);\n","import { defineServerCommand, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerCommand(\n (context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.commands[0]!,\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\n\nexport default defineRoutedContribution((context: WithRoot<unknown, McpServerScope>) => context.root.appMethods, {\n cardinality: 'many',\n});\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { DOOM_HELP_WHEN } from '@agimon-ai/po-core/help';\nimport { readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineResource({\n name: 'po-use-mcp',\n description:\n 'Inspect domain-scoped MCP servers, authenticate, reload configuration, and troubleshoot tool availability.',\n when: DOOM_HELP_WHEN,\n kind: 'skill' as const,\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-mcp/SKILL.md'),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/po-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/mcp/route.server';\nimport apiRoute2 from '../src/extensions/workspaces/sessions/(backend)/api/mcp-session/route.server';\nimport commandMcp from '../src/extensions/workspaces/sessions/(backend)/command/mcp.server';\nimport methodApps from '../src/extensions/workspaces/sessions/(backend)/method/apps.server';\nimport resourcePoUseMcp from '../src/extensions/workspaces/sessions/(backend)/resource/po-use-mcp.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/po-mcp',\n providerOverrides: composeServerProviderOverrides(rootSession),\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n }),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context), at(apiRoute2, contextSession)]; },\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'mcp' }, at(commandMcp, contextSession))]; },\n get methods(): DoomServerSessionPlugin['methods'] { return [...many(methodApps, contextSession)]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourcePoUseMcp, contextSession)]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";qBAuBa,gDAAK"}
|