import type { IncomingMessage, ServerResponse } from 'node:http'; import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { type ExecutionRegistry } from '@zhixuan92/multi-model-agent-core'; import type { ExecutionRuntime } from '../application/execution-runtime.js'; import type { ExecutionStore } from '../application/execution-store.js'; import type { ProjectRegistry } from '../application/project-registry.js'; import type { InitiativeRecordRuntime } from '../application/initiative-record-runtime.js'; import { type McpCapabilities } from './tool-surface.js'; export interface McpAdapterDeps { runtime: ExecutionRuntime; executionRegistry: ExecutionRegistry; store: ExecutionStore; /** The SAME `InitiativeRecordRuntime` `POST /initiatives` (Task I-6) calls * into — the `mma_` Initiative tools below are a second thin * transport over it, never a second store/runtime. */ initiativeRuntime: InitiativeRecordRuntime; serverVersion: string; /** Resolved ONCE at daemon start (see `http/server.ts`); read here for both the * `Server` constructor and the `server/discover` handler so they cannot disagree. */ capabilities: McpCapabilities; /** Shared with the REST control handlers (`application/context-block-ops.ts`) — the * `mma_context_block_*` tools call the SAME `createContextBlock` / `deleteContextBlock` * operations those handlers wrap, against this same registry. */ projectRegistry: ProjectRegistry; maxContextBlockBytes: number; maxContextBlocksPerProject: number; } interface ToolResult { [key: string]: unknown; content: Array<{ type: 'text'; text: string; }>; isError?: boolean; } /** * Attribute the execution to the CLIENT, not to the transport. * * MCP is a transport that any client can speak — Claude Code, Codex CLI, an * IDE, a script — so recording a flat `mcp` would erase which one it was and * make telemetry useless for the one question it exists to answer. The * 2026-07-28 protocol carries `io.modelcontextprotocol/clientInfo` in every * request's `_meta`, so use it when present. Older clients (Claude Code * currently negotiates 2025-06-18, which sends clientInfo only at initialize, * and this adapter is stateless per request) fall back to what the install * declared in `X-MMA-Client`, and only then to `mcp`. * * The value rides into the wire record's `client` column, which accepts any * STRICT_ID_REGEX string — no allowlist to extend. */ export declare function callerClientFromMeta(meta: Record | undefined, declaredClient?: string): string; /** * MCP shape of a typed Initiative error. * * The classification lives in `application/initiative-error-report.ts`, shared with the HTTP * handler; only the envelope differs. The two used to be parallel `instanceof` chains over the * same eighteen classes and had already drifted on two of them. */ declare function initiativeErrorToMcp(err: unknown): ToolResult; /** Build a fresh SDK server wired to the shared runtime. One per request — * the protocol core is stateless; all durable state lives in the runtime. */ export declare function buildMcpServer(deps: McpAdapterDeps, declaredClient?: string): Server; /** * POST /mcp — one stateless exchange per request: fresh Server + transport * (no session id), closed when the response ends. Registered on the existing * router, so bearer auth applies before this runs. */ export declare function handleMcpRequest(deps: McpAdapterDeps, req: IncomingMessage, res: ServerResponse, body: unknown): Promise; /** Test seam: see `__initiativeErrorToHttpForTests`. The two mappers cover the same typed-error * union and must report the same code and details; the parity test needs both. */ export declare const __initiativeErrorToMcpForTests: typeof initiativeErrorToMcp; export {}; //# sourceMappingURL=mcp-adapter.d.ts.map