{"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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"}