@agimon-ai/doompi-mcp 0.0.1-alpha.92 → 0.0.1-alpha.93
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.
|
@@ -86,7 +86,7 @@ function createMcpServerRuntime(environment = {}, workspaceRoot, getResolver) {
|
|
|
86
86
|
if (active !== execution) return;
|
|
87
87
|
const resolver = getResolver?.();
|
|
88
88
|
const loaded = workspaceRoot ? (0, _agimon_ai_doompi_config_harnessStore.loadHarnessState)({ ...execution.environment }) : void 0;
|
|
89
|
-
const authorized = workspaceRoot && loaded?.filePath && loaded.state.root === workspaceRoot && execution.repoRoot === workspaceRoot && loaded.state.mcp &&
|
|
89
|
+
const authorized = workspaceRoot && loaded?.filePath && loaded.state.root === workspaceRoot && execution.repoRoot === workspaceRoot && loaded.state.mcp && (0, _agimon_ai_doompi_core_mcpProjection.isDoomMcpProjection)(loaded.state.mcpProjection) && loaded.state.mcpProjection.repoRoot === workspaceRoot && loaded.state.mcpProjection.enabled;
|
|
90
90
|
if (!resolver || !authorized) {
|
|
91
91
|
if (active === execution && selection === currentSelection) {
|
|
92
92
|
if (workspaceRoot === void 0 || JSON.stringify(execution.selection.domains) === JSON.stringify(selection.domains)) await session.reconfigure(sessionConfiguration(execution, workspaceRoot), execution.cwd, execution.repoRoot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.cjs","names":["loadHarnessState","isDoomMcpProjection","mcpSessionConfigFromProjection","path","readSessionConfig","McpSession","MCP_STATUS_KEY","MCP_SESSION_AUTH_STATUS_KEY","formatMcpSessionAuthStatus","createMcpChildTool","SERVER_COMMAND_DESCRIPTION","formatStatus","McpHeadlessToolParameters","DOOM_MCP_PROJECTION_RESOLVER_SERVICE","DOOM_HEADLESS_HOST_SERVICE","DOOM_MCP_STATUS_SERVICE","DOOM_MCP_TOOL_RESOLVER_SERVICE","MCP_SESSION_TOOLS_SERVICE","createMcpSessionToolsService","DOOM_CHILD_SESSION_MCP_TOOL_SERVICE","defineRoot","toPiToolName","os","createTokenStore","fs","path","mcpSessionConfigFromProjection","buildMcpConfigGroups","readCachedCatalog","McpRuntimeOwner","randomUUID","hubCallbackSink","MCP_AUTHORIZATION_API_PATH","MCP_FLOW_ID_PARAM","defineApiRoutes","MCP_REPOSITORY_API_PATH","MCP_REPOSITORY_ID_QUERY","apiResponse","MCP_DISCOVERY_API_PATH","routes","MCP_FLOW_ID_PARAM","MCP_REPOSITORY_ID_QUERY","defineRoute","defineServerCommand","defineServerTool","defineServerPlugin","apiRoute","rootSession","composeRootHooks","commandMcp","toolMcpUse"],"sources":["../../src/services/mcpHeadlessTools/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/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)/command/mcp.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.server.ts","../../generated/server.ts"],"sourcesContent":["import type { DoomHeadlessTool } from '@agimon-ai/doompi-core/headless';\nimport type { DoomMcpPluginContext } from '@agimon-ai/doompi-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 path from 'node:path';\n\nimport { loadHarnessState } from '@agimon-ai/doompi-config/harnessStore';\nimport type {\n DoomHeadlessActivity,\n DoomHeadlessCommand,\n DoomHeadlessExecutionContext,\n DoomHeadlessSelection,\n DoomHeadlessTool,\n} from '@agimon-ai/doompi-core/headless';\nimport { isDoomMcpProjection, type DoomMcpProjectionResolverService } from '@agimon-ai/doompi-core/mcpProjection';\nimport type { DoomMcpSessionConfig } from '@agimon-ai/doompi-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 { formatStatus } from '../mcpCommand';\nimport { McpSession } from '../mcpSession';\nimport { createMcpChildTool } from '../mcpSessionTools';\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, '.doom', '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) {\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 const session = new McpSession({\n environment: { ...environment },\n onAuthorizationUrl: async (url, serverName) => {\n if (staleSelection || !session.getServers().some((server) => server.name === serverName)) return;\n await active?.client.notify({\n title: `Authorize MCP server ${serverName}`,\n body: url.toString(),\n level: 'warning',\n });\n },\n });\n\n const refresh = (execution: DoomHeadlessExecutionContext, selection: DoomHeadlessSelection) => {\n staleSelection = true;\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 loaded.state.majorMode === selection.majorMode &&\n JSON.stringify(loaded.state.domains) === JSON.stringify(execution.selection.domains) &&\n JSON.stringify(loaded.state.layers) === JSON.stringify(selection.activeLayers) &&\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 .catch(async (error: unknown) => {\n if (active !== execution || selection !== currentSelection) return;\n await execution.client.notify({\n title: 'DoomPi MCP unavailable',\n body: error instanceof Error ? error.message : String(error),\n level: 'warning',\n });\n });\n return transition;\n };\n\n const activity: DoomHeadlessActivity = {\n name: 'doompi-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 execution.client.setStatus(MCP_SESSION_AUTH_STATUS_KEY, formatMcpSessionAuthStatus(session.getServers()));\n for (const diagnostic of session.getDiagnostics()) {\n if (reported.has(diagnostic)) continue;\n reported.add(diagnostic);\n void execution.client.notify({ title: 'DoomPi MCP', body: diagnostic, level: 'warning' });\n }\n };\n const stopPublishing = session.onChange(publish);\n try {\n await refresh(execution, execution.selection);\n publish();\n } catch (error) {\n await execution.client.notify({\n title: 'DoomPi 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 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 }\n };\n },\n };\n\n const invoke: Parameters<typeof createMcpChildTool>[0] = async (parameters, signal) => {\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 const selected = session\n .activeToolDefinitions()\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 session.invokeTool(selected.piName, parameters.arguments ?? {}, signal);\n };\n const childTool = createMcpChildTool(invoke);\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: 'DoomPi 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 session.openAuthorizationPage(serverName);\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 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/doompi-core/childSession';\nimport { DOOM_HEADLESS_HOST_SERVICE, type DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport {\n DOOM_MCP_PROJECTION_RESOLVER_SERVICE,\n type DoomMcpProjectionResolverService,\n} from '@agimon-ai/doompi-core/mcpProjection';\nimport { DOOM_MCP_STATUS_SERVICE, type DoomMcpStatusService } from '@agimon-ai/doompi-core/mcpStatus';\nimport {\n DOOM_MCP_TOOL_RESOLVER_SERVICE,\n type DoomMcpToolResolverService,\n} from '@agimon-ai/doompi-core/mcpToolResolver';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { mountMcpHeadlessTools } from '../../../../../services/mcpHeadlessTools';\nimport { createMcpSessionToolsService, MCP_SESSION_TOOLS_SERVICE } from '../../../../../services/mcpSessionTools';\nimport { createMcpServerRuntime } from '../../../../../services/serverRuntime';\n\nexport const createMcpServerRoot = (context?: DoomServerPluginContext) => {\n let resolver: DoomMcpProjectionResolverService | undefined;\n const runtime = createMcpServerRuntime(\n context?.agent?.context?.environment,\n context?.host.context.workspaceRoot,\n () => resolver,\n );\n const generation = `${context?.agent?.context?.sessionId ?? crypto.randomUUID()}:mcp-server`;\n const { session } = runtime;\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 return host.subscribeSelection((selection) => runtime.onSelectionChange(selection));\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, createMcpSessionToolsService(session, generation));\n provider.provide(DOOM_CHILD_SESSION_MCP_TOOL_SERVICE, runtime.childTool);\n });\n };\n return {\n value: runtime,\n activities: runtime.activities,\n services: [mountMcpHeadlessTools(runtime.tools), mountSession],\n };\n};\nexport type McpServerScope = Awaited<ReturnType<typeof createMcpServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createMcpServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createMcpServerRoot);\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { DoomOAuthRedirect, DoomRepositorySyncView } from '@agimon-ai/doompi-core/packageApi';\nimport type { McpServerStateChange, McpToolInfo, TokenStore } from '@agimon-ai/mcp-proxy';\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(), 'doompi-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/doompi-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 type McpAuthorizationFlow,\n type McpRepositoryCatalog,\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});\n","import type { DoomApi, DoomApiContext } from '@agimon-ai/doompi-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' };\nconst REPOSITORY_ID = /^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24})$/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(await manager.readCatalog(repositoryId, repositoryRoot, context.readRepositorySync?.(repositoryId)));\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, 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 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/doompi-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 { defineServerCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerCommand(\n (context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.commands[0]!,\n);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.tools[0]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/mcp/route.server';\nimport commandMcp from '../src/extensions/workspaces/sessions/(backend)/command/mcp.server';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.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;\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/doompi-mcp',\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)]; },\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'mcp' }, at(commandMcp, contextSession))]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'mcp_use' }, at(toolMcpUse, 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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"}
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["loadHarnessState","isDoomMcpProjection","mcpSessionConfigFromProjection","path","readSessionConfig","McpSession","MCP_STATUS_KEY","MCP_SESSION_AUTH_STATUS_KEY","formatMcpSessionAuthStatus","createMcpChildTool","SERVER_COMMAND_DESCRIPTION","formatStatus","McpHeadlessToolParameters","DOOM_MCP_PROJECTION_RESOLVER_SERVICE","DOOM_HEADLESS_HOST_SERVICE","DOOM_MCP_STATUS_SERVICE","DOOM_MCP_TOOL_RESOLVER_SERVICE","MCP_SESSION_TOOLS_SERVICE","createMcpSessionToolsService","DOOM_CHILD_SESSION_MCP_TOOL_SERVICE","defineRoot","toPiToolName","os","createTokenStore","fs","path","mcpSessionConfigFromProjection","buildMcpConfigGroups","readCachedCatalog","McpRuntimeOwner","randomUUID","hubCallbackSink","MCP_AUTHORIZATION_API_PATH","MCP_FLOW_ID_PARAM","defineApiRoutes","MCP_REPOSITORY_API_PATH","MCP_REPOSITORY_ID_QUERY","apiResponse","MCP_DISCOVERY_API_PATH","routes","MCP_FLOW_ID_PARAM","MCP_REPOSITORY_ID_QUERY","defineRoute","defineServerCommand","defineServerTool","defineServerPlugin","apiRoute","rootSession","composeRootHooks","commandMcp","toolMcpUse"],"sources":["../../src/services/mcpHeadlessTools/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/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)/command/mcp.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.server.ts","../../generated/server.ts"],"sourcesContent":["import type { DoomHeadlessTool } from '@agimon-ai/doompi-core/headless';\nimport type { DoomMcpPluginContext } from '@agimon-ai/doompi-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 path from 'node:path';\n\nimport { loadHarnessState } from '@agimon-ai/doompi-config/harnessStore';\nimport type {\n DoomHeadlessActivity,\n DoomHeadlessCommand,\n DoomHeadlessExecutionContext,\n DoomHeadlessSelection,\n DoomHeadlessTool,\n} from '@agimon-ai/doompi-core/headless';\nimport { isDoomMcpProjection, type DoomMcpProjectionResolverService } from '@agimon-ai/doompi-core/mcpProjection';\nimport type { DoomMcpSessionConfig } from '@agimon-ai/doompi-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 { formatStatus } from '../mcpCommand';\nimport { McpSession } from '../mcpSession';\nimport { createMcpChildTool } from '../mcpSessionTools';\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, '.doom', '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) {\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 const session = new McpSession({\n environment: { ...environment },\n onAuthorizationUrl: async (url, serverName) => {\n if (staleSelection || !session.getServers().some((server) => server.name === serverName)) return;\n await active?.client.notify({\n title: `Authorize MCP server ${serverName}`,\n body: url.toString(),\n level: 'warning',\n });\n },\n });\n\n const refresh = (execution: DoomHeadlessExecutionContext, selection: DoomHeadlessSelection) => {\n staleSelection = true;\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 .catch(async (error: unknown) => {\n if (active !== execution || selection !== currentSelection) return;\n await execution.client.notify({\n title: 'DoomPi MCP unavailable',\n body: error instanceof Error ? error.message : String(error),\n level: 'warning',\n });\n });\n return transition;\n };\n\n const activity: DoomHeadlessActivity = {\n name: 'doompi-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 execution.client.setStatus(MCP_SESSION_AUTH_STATUS_KEY, formatMcpSessionAuthStatus(session.getServers()));\n for (const diagnostic of session.getDiagnostics()) {\n if (reported.has(diagnostic)) continue;\n reported.add(diagnostic);\n void execution.client.notify({ title: 'DoomPi MCP', body: diagnostic, level: 'warning' });\n }\n };\n const stopPublishing = session.onChange(publish);\n try {\n await refresh(execution, execution.selection);\n publish();\n } catch (error) {\n await execution.client.notify({\n title: 'DoomPi 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 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 }\n };\n },\n };\n\n const invoke: Parameters<typeof createMcpChildTool>[0] = async (parameters, signal) => {\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 const selected = session\n .activeToolDefinitions()\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 session.invokeTool(selected.piName, parameters.arguments ?? {}, signal);\n };\n const childTool = createMcpChildTool(invoke);\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: 'DoomPi 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 session.openAuthorizationPage(serverName);\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 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/doompi-core/childSession';\nimport { DOOM_HEADLESS_HOST_SERVICE, type DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport {\n DOOM_MCP_PROJECTION_RESOLVER_SERVICE,\n type DoomMcpProjectionResolverService,\n} from '@agimon-ai/doompi-core/mcpProjection';\nimport { DOOM_MCP_STATUS_SERVICE, type DoomMcpStatusService } from '@agimon-ai/doompi-core/mcpStatus';\nimport {\n DOOM_MCP_TOOL_RESOLVER_SERVICE,\n type DoomMcpToolResolverService,\n} from '@agimon-ai/doompi-core/mcpToolResolver';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { mountMcpHeadlessTools } from '../../../../../services/mcpHeadlessTools';\nimport { createMcpSessionToolsService, MCP_SESSION_TOOLS_SERVICE } from '../../../../../services/mcpSessionTools';\nimport { createMcpServerRuntime } from '../../../../../services/serverRuntime';\n\nexport const createMcpServerRoot = (context?: DoomServerPluginContext) => {\n let resolver: DoomMcpProjectionResolverService | undefined;\n const runtime = createMcpServerRuntime(\n context?.agent?.context?.environment,\n context?.host.context.workspaceRoot,\n () => resolver,\n );\n const generation = `${context?.agent?.context?.sessionId ?? crypto.randomUUID()}:mcp-server`;\n const { session } = runtime;\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 return host.subscribeSelection((selection) => runtime.onSelectionChange(selection));\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, createMcpSessionToolsService(session, generation));\n provider.provide(DOOM_CHILD_SESSION_MCP_TOOL_SERVICE, runtime.childTool);\n });\n };\n return {\n value: runtime,\n activities: runtime.activities,\n services: [mountMcpHeadlessTools(runtime.tools), mountSession],\n };\n};\nexport type McpServerScope = Awaited<ReturnType<typeof createMcpServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createMcpServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createMcpServerRoot);\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { DoomOAuthRedirect, DoomRepositorySyncView } from '@agimon-ai/doompi-core/packageApi';\nimport type { McpServerStateChange, McpToolInfo, TokenStore } from '@agimon-ai/mcp-proxy';\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(), 'doompi-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/doompi-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 type McpAuthorizationFlow,\n type McpRepositoryCatalog,\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});\n","import type { DoomApi, DoomApiContext } from '@agimon-ai/doompi-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' };\nconst REPOSITORY_ID = /^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24})$/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(await manager.readCatalog(repositoryId, repositoryRoot, context.readRepositorySync?.(repositoryId)));\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, 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 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/doompi-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 { defineServerCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerCommand(\n (context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.commands[0]!,\n);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.tools[0]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/mcp/route.server';\nimport commandMcp from '../src/extensions/workspaces/sessions/(backend)/command/mcp.server';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.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;\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/doompi-mcp',\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)]; },\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'mcp' }, at(commandMcp, contextSession))]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'mcp_use' }, at(toolMcpUse, 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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"}
|
|
@@ -78,7 +78,7 @@ function createMcpServerRuntime(environment = {}, workspaceRoot, getResolver) {
|
|
|
78
78
|
if (active !== execution) return;
|
|
79
79
|
const resolver = getResolver?.();
|
|
80
80
|
const loaded = workspaceRoot ? loadHarnessState({ ...execution.environment }) : void 0;
|
|
81
|
-
const authorized = workspaceRoot && loaded?.filePath && loaded.state.root === workspaceRoot && execution.repoRoot === workspaceRoot && loaded.state.mcp &&
|
|
81
|
+
const authorized = workspaceRoot && loaded?.filePath && loaded.state.root === workspaceRoot && execution.repoRoot === workspaceRoot && loaded.state.mcp && isDoomMcpProjection(loaded.state.mcpProjection) && loaded.state.mcpProjection.repoRoot === workspaceRoot && loaded.state.mcpProjection.enabled;
|
|
82
82
|
if (!resolver || !authorized) {
|
|
83
83
|
if (active === execution && selection === currentSelection) {
|
|
84
84
|
if (workspaceRoot === void 0 || JSON.stringify(execution.selection.domains) === JSON.stringify(selection.domains)) await session.reconfigure(sessionConfiguration(execution, workspaceRoot), execution.cwd, execution.repoRoot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":["routes","apiRoute","rootSession","commandMcp","toolMcpUse"],"sources":["../../src/services/mcpHeadlessTools/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/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)/command/mcp.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.server.ts","../../generated/server.ts"],"sourcesContent":["import type { DoomHeadlessTool } from '@agimon-ai/doompi-core/headless';\nimport type { DoomMcpPluginContext } from '@agimon-ai/doompi-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 path from 'node:path';\n\nimport { loadHarnessState } from '@agimon-ai/doompi-config/harnessStore';\nimport type {\n DoomHeadlessActivity,\n DoomHeadlessCommand,\n DoomHeadlessExecutionContext,\n DoomHeadlessSelection,\n DoomHeadlessTool,\n} from '@agimon-ai/doompi-core/headless';\nimport { isDoomMcpProjection, type DoomMcpProjectionResolverService } from '@agimon-ai/doompi-core/mcpProjection';\nimport type { DoomMcpSessionConfig } from '@agimon-ai/doompi-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 { formatStatus } from '../mcpCommand';\nimport { McpSession } from '../mcpSession';\nimport { createMcpChildTool } from '../mcpSessionTools';\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, '.doom', '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) {\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 const session = new McpSession({\n environment: { ...environment },\n onAuthorizationUrl: async (url, serverName) => {\n if (staleSelection || !session.getServers().some((server) => server.name === serverName)) return;\n await active?.client.notify({\n title: `Authorize MCP server ${serverName}`,\n body: url.toString(),\n level: 'warning',\n });\n },\n });\n\n const refresh = (execution: DoomHeadlessExecutionContext, selection: DoomHeadlessSelection) => {\n staleSelection = true;\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 loaded.state.majorMode === selection.majorMode &&\n JSON.stringify(loaded.state.domains) === JSON.stringify(execution.selection.domains) &&\n JSON.stringify(loaded.state.layers) === JSON.stringify(selection.activeLayers) &&\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 .catch(async (error: unknown) => {\n if (active !== execution || selection !== currentSelection) return;\n await execution.client.notify({\n title: 'DoomPi MCP unavailable',\n body: error instanceof Error ? error.message : String(error),\n level: 'warning',\n });\n });\n return transition;\n };\n\n const activity: DoomHeadlessActivity = {\n name: 'doompi-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 execution.client.setStatus(MCP_SESSION_AUTH_STATUS_KEY, formatMcpSessionAuthStatus(session.getServers()));\n for (const diagnostic of session.getDiagnostics()) {\n if (reported.has(diagnostic)) continue;\n reported.add(diagnostic);\n void execution.client.notify({ title: 'DoomPi MCP', body: diagnostic, level: 'warning' });\n }\n };\n const stopPublishing = session.onChange(publish);\n try {\n await refresh(execution, execution.selection);\n publish();\n } catch (error) {\n await execution.client.notify({\n title: 'DoomPi 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 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 }\n };\n },\n };\n\n const invoke: Parameters<typeof createMcpChildTool>[0] = async (parameters, signal) => {\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 const selected = session\n .activeToolDefinitions()\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 session.invokeTool(selected.piName, parameters.arguments ?? {}, signal);\n };\n const childTool = createMcpChildTool(invoke);\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: 'DoomPi 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 session.openAuthorizationPage(serverName);\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 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/doompi-core/childSession';\nimport { DOOM_HEADLESS_HOST_SERVICE, type DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport {\n DOOM_MCP_PROJECTION_RESOLVER_SERVICE,\n type DoomMcpProjectionResolverService,\n} from '@agimon-ai/doompi-core/mcpProjection';\nimport { DOOM_MCP_STATUS_SERVICE, type DoomMcpStatusService } from '@agimon-ai/doompi-core/mcpStatus';\nimport {\n DOOM_MCP_TOOL_RESOLVER_SERVICE,\n type DoomMcpToolResolverService,\n} from '@agimon-ai/doompi-core/mcpToolResolver';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { mountMcpHeadlessTools } from '../../../../../services/mcpHeadlessTools';\nimport { createMcpSessionToolsService, MCP_SESSION_TOOLS_SERVICE } from '../../../../../services/mcpSessionTools';\nimport { createMcpServerRuntime } from '../../../../../services/serverRuntime';\n\nexport const createMcpServerRoot = (context?: DoomServerPluginContext) => {\n let resolver: DoomMcpProjectionResolverService | undefined;\n const runtime = createMcpServerRuntime(\n context?.agent?.context?.environment,\n context?.host.context.workspaceRoot,\n () => resolver,\n );\n const generation = `${context?.agent?.context?.sessionId ?? crypto.randomUUID()}:mcp-server`;\n const { session } = runtime;\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 return host.subscribeSelection((selection) => runtime.onSelectionChange(selection));\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, createMcpSessionToolsService(session, generation));\n provider.provide(DOOM_CHILD_SESSION_MCP_TOOL_SERVICE, runtime.childTool);\n });\n };\n return {\n value: runtime,\n activities: runtime.activities,\n services: [mountMcpHeadlessTools(runtime.tools), mountSession],\n };\n};\nexport type McpServerScope = Awaited<ReturnType<typeof createMcpServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createMcpServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createMcpServerRoot);\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { DoomOAuthRedirect, DoomRepositorySyncView } from '@agimon-ai/doompi-core/packageApi';\nimport type { McpServerStateChange, McpToolInfo, TokenStore } from '@agimon-ai/mcp-proxy';\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(), 'doompi-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/doompi-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 type McpAuthorizationFlow,\n type McpRepositoryCatalog,\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});\n","import type { DoomApi, DoomApiContext } from '@agimon-ai/doompi-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' };\nconst REPOSITORY_ID = /^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24})$/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(await manager.readCatalog(repositoryId, repositoryRoot, context.readRepositorySync?.(repositoryId)));\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, 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 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/doompi-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 { defineServerCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerCommand(\n (context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.commands[0]!,\n);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.tools[0]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/mcp/route.server';\nimport commandMcp from '../src/extensions/workspaces/sessions/(backend)/command/mcp.server';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.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;\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/doompi-mcp',\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)]; },\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'mcp' }, at(commandMcp, contextSession))]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'mcp_use' }, at(toolMcpUse, 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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"}
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["routes","apiRoute","rootSession","commandMcp","toolMcpUse"],"sources":["../../src/services/mcpHeadlessTools/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/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)/command/mcp.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.server.ts","../../generated/server.ts"],"sourcesContent":["import type { DoomHeadlessTool } from '@agimon-ai/doompi-core/headless';\nimport type { DoomMcpPluginContext } from '@agimon-ai/doompi-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 path from 'node:path';\n\nimport { loadHarnessState } from '@agimon-ai/doompi-config/harnessStore';\nimport type {\n DoomHeadlessActivity,\n DoomHeadlessCommand,\n DoomHeadlessExecutionContext,\n DoomHeadlessSelection,\n DoomHeadlessTool,\n} from '@agimon-ai/doompi-core/headless';\nimport { isDoomMcpProjection, type DoomMcpProjectionResolverService } from '@agimon-ai/doompi-core/mcpProjection';\nimport type { DoomMcpSessionConfig } from '@agimon-ai/doompi-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 { formatStatus } from '../mcpCommand';\nimport { McpSession } from '../mcpSession';\nimport { createMcpChildTool } from '../mcpSessionTools';\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, '.doom', '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) {\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 const session = new McpSession({\n environment: { ...environment },\n onAuthorizationUrl: async (url, serverName) => {\n if (staleSelection || !session.getServers().some((server) => server.name === serverName)) return;\n await active?.client.notify({\n title: `Authorize MCP server ${serverName}`,\n body: url.toString(),\n level: 'warning',\n });\n },\n });\n\n const refresh = (execution: DoomHeadlessExecutionContext, selection: DoomHeadlessSelection) => {\n staleSelection = true;\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 .catch(async (error: unknown) => {\n if (active !== execution || selection !== currentSelection) return;\n await execution.client.notify({\n title: 'DoomPi MCP unavailable',\n body: error instanceof Error ? error.message : String(error),\n level: 'warning',\n });\n });\n return transition;\n };\n\n const activity: DoomHeadlessActivity = {\n name: 'doompi-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 execution.client.setStatus(MCP_SESSION_AUTH_STATUS_KEY, formatMcpSessionAuthStatus(session.getServers()));\n for (const diagnostic of session.getDiagnostics()) {\n if (reported.has(diagnostic)) continue;\n reported.add(diagnostic);\n void execution.client.notify({ title: 'DoomPi MCP', body: diagnostic, level: 'warning' });\n }\n };\n const stopPublishing = session.onChange(publish);\n try {\n await refresh(execution, execution.selection);\n publish();\n } catch (error) {\n await execution.client.notify({\n title: 'DoomPi 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 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 }\n };\n },\n };\n\n const invoke: Parameters<typeof createMcpChildTool>[0] = async (parameters, signal) => {\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 const selected = session\n .activeToolDefinitions()\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 session.invokeTool(selected.piName, parameters.arguments ?? {}, signal);\n };\n const childTool = createMcpChildTool(invoke);\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: 'DoomPi 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 session.openAuthorizationPage(serverName);\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 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/doompi-core/childSession';\nimport { DOOM_HEADLESS_HOST_SERVICE, type DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport {\n DOOM_MCP_PROJECTION_RESOLVER_SERVICE,\n type DoomMcpProjectionResolverService,\n} from '@agimon-ai/doompi-core/mcpProjection';\nimport { DOOM_MCP_STATUS_SERVICE, type DoomMcpStatusService } from '@agimon-ai/doompi-core/mcpStatus';\nimport {\n DOOM_MCP_TOOL_RESOLVER_SERVICE,\n type DoomMcpToolResolverService,\n} from '@agimon-ai/doompi-core/mcpToolResolver';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { mountMcpHeadlessTools } from '../../../../../services/mcpHeadlessTools';\nimport { createMcpSessionToolsService, MCP_SESSION_TOOLS_SERVICE } from '../../../../../services/mcpSessionTools';\nimport { createMcpServerRuntime } from '../../../../../services/serverRuntime';\n\nexport const createMcpServerRoot = (context?: DoomServerPluginContext) => {\n let resolver: DoomMcpProjectionResolverService | undefined;\n const runtime = createMcpServerRuntime(\n context?.agent?.context?.environment,\n context?.host.context.workspaceRoot,\n () => resolver,\n );\n const generation = `${context?.agent?.context?.sessionId ?? crypto.randomUUID()}:mcp-server`;\n const { session } = runtime;\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 return host.subscribeSelection((selection) => runtime.onSelectionChange(selection));\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, createMcpSessionToolsService(session, generation));\n provider.provide(DOOM_CHILD_SESSION_MCP_TOOL_SERVICE, runtime.childTool);\n });\n };\n return {\n value: runtime,\n activities: runtime.activities,\n services: [mountMcpHeadlessTools(runtime.tools), mountSession],\n };\n};\nexport type McpServerScope = Awaited<ReturnType<typeof createMcpServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createMcpServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createMcpServerRoot);\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { DoomOAuthRedirect, DoomRepositorySyncView } from '@agimon-ai/doompi-core/packageApi';\nimport type { McpServerStateChange, McpToolInfo, TokenStore } from '@agimon-ai/mcp-proxy';\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(), 'doompi-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/doompi-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 type McpAuthorizationFlow,\n type McpRepositoryCatalog,\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});\n","import type { DoomApi, DoomApiContext } from '@agimon-ai/doompi-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' };\nconst REPOSITORY_ID = /^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24})$/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(await manager.readCatalog(repositoryId, repositoryRoot, context.readRepositorySync?.(repositoryId)));\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, 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 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/doompi-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 { defineServerCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerCommand(\n (context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.commands[0]!,\n);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { McpServerScope } from '../_lib/serverRoot';\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, McpServerScope>) => context.root.tools[0]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/mcp/route.server';\nimport commandMcp from '../src/extensions/workspaces/sessions/(backend)/command/mcp.server';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.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;\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/doompi-mcp',\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)]; },\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'mcp' }, at(commandMcp, contextSession))]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'mcp_use' }, at(toolMcpUse, 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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-mcp",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.93",
|
|
4
4
|
"description": "Domain-aware MCP server selection and access boundaries for Pi sessions composed with DoomPi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -73,10 +73,10 @@
|
|
|
73
73
|
"access": "public"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@agimon-ai/doompi-config": "0.0.1-alpha.
|
|
77
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
78
|
-
"@agimon-ai/doompi-ui": "0.0.1-alpha.
|
|
79
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.
|
|
76
|
+
"@agimon-ai/doompi-config": "0.0.1-alpha.91",
|
|
77
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.92",
|
|
78
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.92",
|
|
79
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.50",
|
|
80
80
|
"@agimon-ai/doompi-web-security": "0.0.1-alpha.46",
|
|
81
81
|
"@agimon-ai/mcp-proxy": "0.31.30",
|
|
82
82
|
"@deepseek-ai/cordis": "4.0.2",
|