@routecraft/ai 0.4.0 → 0.5.0-canary.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +234 -14
- package/dist/index.d.ts +234 -14
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/brand.ts","../src/llm/providers/index.ts","../src/llm/structured-output.ts","../src/llm/types.ts","../src/llm/destination.ts","../src/llm/llm.ts","../src/llm/validate-options.ts","../src/llm/plugin.ts","../src/mcp/types.ts","../src/mcp/adapters/mcp/shared.ts","../src/mcp/adapters/mcp/source.ts","../src/mcp/extract-content.ts","../src/mcp/build-auth-headers.ts","../src/mcp/adapters/mcp/destination.ts","../src/mcp/adapters/mcp/index.ts","../src/mcp/jwt.ts","../src/mcp/server.ts","../src/mcp/validate-options.ts","../src/mcp/stdio-client-manager.ts","../src/mcp/tool-registry.ts","../src/mcp/plugin.ts","../src/agent/runner.ts","../src/agent/destination.ts","../src/agent/agent.ts","../src/embedding/providers/index.ts","../src/embedding/types.ts","../src/embedding/destination.ts","../src/embedding/embedding.ts","../src/embedding/plugin.ts"],"names":["BRAND","isBranded","obj","key","isMcpAdapter","throwProviderInstallError","pkg","provider","isModuleNotFoundFor","error","msg","PROVIDER_DEFAULTS","toLlmUsage","u","getStructuredOutput","result","assertLanguageModelShape","model","providerName","modelId","m","callLlm","params","config","options","systemPrompt","userPrompt","output","callOpenAI","callAnthropic","callGemini","callOpenRouter","callOllama","_","createOpenAI","generateText","openaiSettings","genParams","out","parsed","createAnthropic","createGoogleGenerativeAI","createOpenRouter","openrouter","resolvedId","rawModel","createOllama","ollama","name","toAiOutputSpec","schema","standard","jsonSchemaObj","validate","value","err","formatSchemaIssues","aiSchema","jsonSchema","Output","ADAPTER_LLM_PROVIDERS","ADAPTER_LLM_OPTIONS","parseStructuredTextFallback","text","DEFAULT_TEMPERATURE","DEFAULT_MAX_TOKENS","resolvePrompt","source","exchange","resolveUserPromptDefault","body","parseProviderModel","id","colon","resolveProviderAndModel","context","store","providerId","modelName","LlmDestinationAdapter","getExchangeContext","merged","opts","fallback","llmResult","metadata","llm","PROVIDERS","isProvider","s","validateLlmPluginOptions","PROVIDER_IDS","toModelConfig","llmPlugin","ctx","map","MCP_PLUGIN_REGISTERED","ADAPTER_MCP_CLIENT_SERVERS","MCP_TOOL_REGISTRY","MCP_STDIO_MANAGERS","McpHeadersKeys","BRAND_MCP_ADAPTER","McpSourceAdapter","endpoint","rcError","handler","abortController","onReady","direct","extractContent","response","content","item","rrIndexes","resolveToken","token","idx","buildAuthHeaders","auth","headers","customHeaders","authorizationOverride","resolved","assertHttpUrl","url","trimmed","resolveServerConfig","resolveConnection","defaultArgs","McpDestinationAdapter","toolName","args","manager","serverConfig","serverUrl","clientModule","transportModule","Client","StreamableHTTPClientTransport","transportOptions","transport","clientInfo","client","clientCleanup","closeOrDisconnect","transportCleanup","closeOrDestroy","mcp","endpointOrOptions","clientOpts","entry","isClientColonOptions","colonIndex","serverId","tool","clientOptions","HMAC_ALGORITHMS","RSA_ALGORITHMS","decodeToken","parts","headerB64","payloadB64","signatureB64","header","payload","checkTemporalClaims","clockToleranceSec","now","buildPrincipal","sub","principal","aud","a","scope","r","isHmac","createHmacValidator","secret","algorithm","digest","decoded","hmac","createHmac","expectedSig","expectedBuf","actualBuf","timingSafeEqual","createRsaValidator","publicKey","verifyAlgorithm","verifier","createVerify","jwt","principalStore","AsyncLocalStorage","MCP_SDK_INSTALL","McpServer","isRoutecraftError","Server","StdioServerTransport","ServerCtor","TransportClass","port","host","createSession","server","sessionId","tr","prevOnClose","sid","handleRequest","createServer","req","res","runWithPrincipal","fn","session","hr","resolve","reject","boundPort","listenDetail","addr","authOptions","rawHeader","detail","schemeMatch","successDetail","typesModule","t","ListToolsRequestSchema","CallToolRequestSchema","srv","tools","request","names","exposedDetail","registry","ADAPTER_DIRECT_REGISTRY","toolsFilter","allowed","meta","channelStore","ADAPTER_DIRECT_STORE","channel","DefaultExchange","resultExchange","resultText","logMsg","userMsg","cause","validateMcpPluginOptions","validateWithSchema","StdioClientManager","logger","onEvent","onToolsUpdated","clientMod","stdioMod","command","env","cwd","data","_error","transportWithClose","maxRestarts","restartDelayMs","restartBackoffMultiplier","delay","stableMs","McpToolRegistry","sourceMap","isStdioConfig","mcpPlugin","stdioManagers","httpClients","httpRefreshTimers","toolRegistry","clientEntries","k","v","startStdioClient","httpConfig","listHttpClientTools","setupHttpToolRefresh","timer","managerOpts","event","details","_serverId","getOrCreateHttpClient","existing","rawClient","typed","interval","AgentRunner","_options","validateModelId","AgentDestinationAdapter","agent","pipelineCache","disposeEmbeddingPipelineCache","entries","cached","resolveHuggingFaceModel","HUGGINGFACE_INSTALL","getHuggingFacePipeline","pipelineFn","pipe","run","previewForError","toNumberArray","d","callEmbedding","vec","i","ADAPTER_EMBEDDING_PROVIDERS","ADAPTER_EMBEDDING_OPTIONS","buildText","using","EmbeddingDestinationAdapter","embedding","embeddingPlugin"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Cross-instance identity for @routecraft/ai: Symbol.for() keys and type guards.\n * Shared across all copies of @routecraft/ai (and multiple routecraft versions) in a process.\n */\n\nexport const BRAND = {\n McpAdapter: Symbol.for(\"routecraft.ai.McpAdapter\"),\n} as const;\n\nfunction isBranded(obj: unknown, key: symbol): boolean {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as Record<symbol, unknown>)[key] === true\n );\n}\n\nexport function isMcpAdapter(obj: unknown): boolean {\n return isBranded(obj, BRAND.McpAdapter);\n}\n","import type {\n LlmModelConfig,\n LlmOptionsMerged,\n LlmResult,\n LlmUsage,\n} from \"../types.ts\";\n\nfunction throwProviderInstallError(pkg: string, provider: string): never {\n throw new Error(\n `The ${provider} LLM provider requires the \"${pkg}\" package. Install it with: pnpm add ${pkg}`,\n );\n}\n\nfunction isModuleNotFoundFor(error: unknown, pkg: string): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message ?? \"\";\n return (\n (msg.includes(\"ERR_MODULE_NOT_FOUND\") ||\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\")) &&\n msg.includes(pkg)\n );\n}\n\n/** Provider-level defaults so users can register models with minimal config (e.g. { provider: \"ollama\" }). */\nconst PROVIDER_DEFAULTS = {\n ollama: {\n baseURL: \"http://localhost:11434/api\",\n },\n} as const;\n\n/** Pass through AI SDK usage so LlmUsage matches LanguageModelUsage (inputTokens/outputTokens). */\nfunction toLlmUsage(u: {\n inputTokens?: number | undefined;\n outputTokens?: number | undefined;\n totalTokens?: number | undefined;\n}): LlmUsage {\n return {\n ...(u.inputTokens !== undefined && { inputTokens: u.inputTokens }),\n ...(u.outputTokens !== undefined && { outputTokens: u.outputTokens }),\n ...(u.totalTokens !== undefined && { totalTokens: u.totalTokens }),\n };\n}\n\n/**\n * Safely read structured output from generateText result. The AI SDK's result.output\n * is a getter that throws AI_NoOutputGeneratedError when the model didn't produce\n * valid structured output (e.g. empty, blocked, or unparseable). Catching here\n * allows returning without output so the adapter can try parsing result.text.\n */\nfunction getStructuredOutput(result: { output?: unknown }): unknown {\n try {\n if (\"output\" in result && result.output !== undefined) return result.output;\n } catch {\n // SDK getter threw (e.g. AI_NoOutputGeneratedError); leave output undefined.\n }\n return undefined;\n}\n\n/**\n * Runtime check that a provider-returned value has the minimal LanguageModel shape\n * required by the AI SDK generateText (doGenerate, doStream). Throws a descriptive\n * error if validation fails so we avoid silent type assertions.\n */\nfunction assertLanguageModelShape(\n model: unknown,\n providerName: string,\n modelId: string,\n): void {\n if (model === null || typeof model !== \"object\") {\n throw new Error(\n `[${providerName}] Invalid model: expected an object, got ${typeof model}. Model id: ${modelId}`,\n );\n }\n const m = model as Record<string, unknown>;\n if (typeof m[\"doGenerate\"] !== \"function\") {\n throw new Error(\n `[${providerName}] Invalid model: missing or invalid doGenerate method. Model id: ${modelId}. ` +\n \"Ensure the provider returns an AI SDK-compatible language model.\",\n );\n }\n if (typeof m[\"doStream\"] !== \"function\") {\n throw new Error(\n `[${providerName}] Invalid model: missing or invalid doStream method. Model id: ${modelId}. ` +\n \"Ensure the provider returns an AI SDK-compatible language model.\",\n );\n }\n}\n\nexport interface CallLlmParams {\n config: LlmModelConfig;\n /** Model id to use for the request (for OpenRouter may be config.modelId ?? registeredId). */\n modelId: string;\n options: Pick<\n LlmOptionsMerged,\n | \"temperature\"\n | \"maxTokens\"\n | \"topP\"\n | \"frequencyPenalty\"\n | \"presencePenalty\"\n >;\n systemPrompt: string;\n userPrompt: string;\n /** Optional structured output spec (from toAiOutputSpec). Enables provider-level JSON schema. */\n output?: unknown;\n}\n\n/**\n * Dispatches to the appropriate provider and returns a normalized LlmResult.\n */\nexport async function callLlm(params: CallLlmParams): Promise<LlmResult> {\n const { config, modelId, options, systemPrompt, userPrompt, output } = params;\n switch (config.provider) {\n case \"openai\":\n return callOpenAI(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"anthropic\":\n return callAnthropic(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"gemini\":\n return callGemini(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"openrouter\":\n return callOpenRouter(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"ollama\":\n return callOllama(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n default: {\n const _: never = config;\n throw new Error(\n `LLM provider not implemented: ${(_ as LlmModelConfig).provider}`,\n );\n }\n }\n}\n\nasync function callOpenAI(\n config: import(\"../types.ts\").LlmModelConfigOpenAI,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createOpenAI: (s: {\n apiKey: string;\n baseURL?: string;\n }) => (m: string) => unknown;\n try {\n const mod = await import(\"@ai-sdk/openai\");\n createOpenAI = mod.createOpenAI as typeof createOpenAI;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@ai-sdk/openai\")) {\n throwProviderInstallError(\"@ai-sdk/openai\", \"OpenAI\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const openaiSettings: { apiKey: string; baseURL?: string } = {\n apiKey: config.apiKey,\n };\n if (config.baseURL !== undefined) openaiSettings.baseURL = config.baseURL;\n const openai = createOpenAI(openaiSettings);\n const model = openai(modelId);\n const genParams: Parameters<typeof generateText>[0] = {\n model: model as Parameters<typeof generateText>[0][\"model\"],\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callAnthropic(\n config: import(\"../types.ts\").LlmModelConfigAnthropic,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createAnthropic: (s: { apiKey: string }) => (m: string) => unknown;\n try {\n const mod = await import(\"@ai-sdk/anthropic\");\n createAnthropic = mod.createAnthropic as typeof createAnthropic;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@ai-sdk/anthropic\")) {\n throwProviderInstallError(\"@ai-sdk/anthropic\", \"Anthropic\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const anthropic = createAnthropic({ apiKey: config.apiKey });\n const model = anthropic(modelId);\n const genParams: Parameters<typeof generateText>[0] = {\n model: model as Parameters<typeof generateText>[0][\"model\"],\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI; SDK passes through. Anthropic supports topP;\n // frequencyPenalty/presencePenalty may be unsupported (SDK may warn).\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callGemini(\n config: import(\"../types.ts\").LlmModelConfigGemini,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createGoogleGenerativeAI: (s: {\n apiKey: string;\n }) => (m: string) => unknown;\n try {\n const mod = await import(\"@ai-sdk/google\");\n createGoogleGenerativeAI =\n mod.createGoogleGenerativeAI as typeof createGoogleGenerativeAI;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@ai-sdk/google\")) {\n throwProviderInstallError(\"@ai-sdk/google\", \"Gemini\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const google = createGoogleGenerativeAI({ apiKey: config.apiKey });\n const model = google(modelId);\n const genParams: Parameters<typeof generateText>[0] = {\n model: model as Parameters<typeof generateText>[0][\"model\"],\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI; SDK passes through. Gemini may not support\n // all (e.g. frequencyPenalty/presencePenalty); check result.warnings if needed.\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callOpenRouter(\n config: import(\"../types.ts\").LlmModelConfigOpenRouter,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createOpenRouter: (s: { apiKey: string }) => {\n chat: (id: string) => unknown;\n };\n try {\n const mod = await import(\"@openrouter/ai-sdk-provider\");\n createOpenRouter = mod.createOpenRouter as typeof createOpenRouter;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@openrouter/ai-sdk-provider\")) {\n throwProviderInstallError(\"@openrouter/ai-sdk-provider\", \"OpenRouter\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const openrouter = createOpenRouter({ apiKey: config.apiKey });\n const resolvedId = config.modelId ?? modelId;\n const rawModel = openrouter.chat(resolvedId);\n assertLanguageModelShape(rawModel, \"OpenRouter\", resolvedId);\n const model = rawModel as Parameters<typeof generateText>[0][\"model\"];\n const genParams: Parameters<typeof generateText>[0] = {\n model,\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI. OpenRouter is OpenAI-compatible; typically supports all.\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callOllama(\n config: import(\"../types.ts\").LlmModelConfigOllama,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createOllama: (s: { baseURL?: string }) => (name: string) => unknown;\n try {\n const mod = await import(\"ollama-ai-provider-v2\");\n createOllama = mod.createOllama as typeof createOllama;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"ollama-ai-provider-v2\")) {\n throwProviderInstallError(\"ollama-ai-provider-v2\", \"Ollama\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const ollama = createOllama({\n baseURL: config.baseURL ?? PROVIDER_DEFAULTS.ollama.baseURL,\n });\n const name = config.modelId ?? modelId;\n const rawModel = ollama(name);\n assertLanguageModelShape(rawModel, \"Ollama\", name);\n const model = rawModel as Parameters<typeof generateText>[0][\"model\"];\n const genParams: Parameters<typeof generateText>[0] = {\n model,\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI. Ollama supports top_p; frequencyPenalty/presencePenalty\n // may be unsupported (SDK may warn).\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { formatSchemaIssues } from \"@routecraft/routecraft\";\nimport { Output, jsonSchema } from \"ai\";\n\n/**\n * Build an AI SDK output spec from a Standard Schema for provider-level\n * structured output (OpenAI response_format, Ollama format, etc.) and validation.\n *\n * The AI SDK accepts Zod directly in Output.object({ schema: z.object(...) }).\n * This package uses Standard Schema (per .standards/type-safety-and-schemas.md), so\n * it cannot depend on Zod. This helper bridges any Standard Schema (Zod, Valibot,\n * ArkType, etc.) by using the SDK’s lower-level jsonSchema(jsonSchemaObj, {\n * validate }): we get the JSON schema from ~standard.jsonSchema.output/.input\n * and use ~standard.validate as the validate callback. Callers can pass a Zod\n * schema (as Standard Schema), Valibot, or ArkType and get the same behavior.\n */\nexport function toAiOutputSpec(schema: StandardSchemaV1): unknown {\n const standard = (schema as unknown as Record<string, unknown>)[\n \"~standard\"\n ] as\n | {\n validate: (\n value: unknown,\n ) =>\n | { value?: unknown; issues?: unknown }\n | Promise<{ value?: unknown; issues?: unknown }>;\n jsonSchema?: {\n output?: (opts: { target: string }) => Record<string, unknown>;\n input?: (opts: { target: string }) => Record<string, unknown>;\n };\n }\n | undefined;\n\n if (!standard?.validate) {\n throw new Error(\n \"LLM outputSchema must be a StandardSchemaV1 with ~standard.validate\",\n );\n }\n\n const jsonSchemaObj =\n standard.jsonSchema?.output?.({ target: \"draft-2020-12\" }) ??\n standard.jsonSchema?.input?.({ target: \"draft-2020-12\" });\n\n if (!jsonSchemaObj || typeof jsonSchemaObj !== \"object\") {\n throw new Error(\n \"LLM outputSchema must expose ~standard.jsonSchema.output or .input for provider structured output\",\n );\n }\n\n function validate(\n value: unknown,\n ): { success: true; value: unknown } | { success: false; error: Error } {\n let result:\n | { value?: unknown; issues?: unknown }\n | Promise<{\n value?: unknown;\n issues?: unknown;\n }>;\n try {\n result = standard!.validate(value);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err : new Error(String(err)),\n };\n }\n if (result instanceof Promise) {\n return {\n success: false,\n error: new Error(\n \"Async output schema is not supported for LLM structured output\",\n ),\n };\n }\n const hasIssues =\n result.issues != null &&\n (Array.isArray(result.issues)\n ? result.issues.length > 0\n : typeof result.issues === \"object\" && result.issues !== null\n ? Object.keys(result.issues).length > 0\n : Boolean(result.issues));\n if (hasIssues) {\n return {\n success: false,\n error: new Error(formatSchemaIssues(result.issues)),\n };\n }\n return { success: true, value: result.value };\n }\n\n const aiSchema = jsonSchema(\n jsonSchemaObj as Parameters<typeof jsonSchema>[0],\n { validate },\n );\n return Output.object({ schema: aiSchema });\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { Exchange } from \"@routecraft/routecraft\";\n\n/**\n * Store key for plugin-registered providers (provider id -> LlmModelConfig).\n * @experimental\n */\nexport const ADAPTER_LLM_PROVIDERS = Symbol.for(\n \"routecraft.adapter.llm.providers\",\n);\n\n/**\n * Store key for context-level default LLM options.\n * @experimental\n */\nexport const ADAPTER_LLM_OPTIONS = Symbol.for(\"routecraft.adapter.llm.options\");\n\ndeclare module \"@routecraft/routecraft\" {\n interface StoreRegistry {\n [ADAPTER_LLM_PROVIDERS]: Map<string, LlmModelConfig>;\n [ADAPTER_LLM_OPTIONS]: Partial<LlmOptionsMerged>;\n }\n}\n\nexport type LlmProviderType =\n | \"openai\"\n | \"anthropic\"\n | \"openrouter\"\n | \"ollama\"\n | \"gemini\";\n\nexport interface LlmModelConfigOpenAI {\n provider: \"openai\";\n apiKey: string;\n baseURL?: string;\n}\n\nexport interface LlmModelConfigAnthropic {\n provider: \"anthropic\";\n apiKey: string;\n}\n\nexport interface LlmModelConfigOpenRouter {\n provider: \"openrouter\";\n apiKey: string;\n /** OpenRouter model id (e.g. anthropic/claude-3.5-sonnet). Defaults to the registered key. */\n modelId?: string;\n}\n\nexport interface LlmModelConfigOllama {\n provider: \"ollama\";\n /**\n * Ollama server URL. Optional: defaults to http://localhost:11434/api.\n * Only set when using a remote Ollama or custom port.\n */\n baseURL?: string;\n /**\n * Override model name sent to Ollama. Optional: defaults to the model\n * from the llm(\"provider:model\") call (the part after the colon).\n */\n modelId?: string;\n}\n\nexport interface LlmModelConfigGemini {\n provider: \"gemini\";\n apiKey: string;\n}\n\nexport type LlmModelConfig =\n | LlmModelConfigOpenAI\n | LlmModelConfigAnthropic\n | LlmModelConfigOpenRouter\n | LlmModelConfigOllama\n | LlmModelConfigGemini;\n\n/** Provider options for llmPlugin({ providers }). Key is the provider; no need to repeat provider in the value. */\nexport interface LlmOllamaProviderOptions {\n baseURL?: string;\n modelId?: string;\n}\nexport interface LlmOpenAIProviderOptions {\n apiKey: string;\n baseURL?: string;\n}\nexport interface LlmAnthropicProviderOptions {\n apiKey: string;\n}\nexport interface LlmOpenRouterProviderOptions {\n apiKey: string;\n modelId?: string;\n}\nexport interface LlmGeminiProviderOptions {\n apiKey: string;\n}\n\nexport interface LlmPluginProviders {\n ollama?: LlmOllamaProviderOptions;\n openai?: LlmOpenAIProviderOptions;\n anthropic?: LlmAnthropicProviderOptions;\n openrouter?: LlmOpenRouterProviderOptions;\n gemini?: LlmGeminiProviderOptions;\n}\n\n/** Map provider id → provider-specific options (for type-safe toModelConfig). */\nexport type LlmProviderOptionsMap = Required<LlmPluginProviders>;\n\n/** Resolve system or user prompt from exchange (string or function). */\nexport type LlmPromptSource =\n | string\n | ((exchange: Exchange<unknown>) => string);\n\nexport interface LlmOptions {\n systemPrompt?: LlmPromptSource;\n userPrompt?: LlmPromptSource;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n frequencyPenalty?: number;\n presencePenalty?: number;\n /**\n * Optional output schema (Standard Schema). When set, the adapter requests\n * provider-level structured output and validates the result. Supported by\n * OpenAI (gpt-4o/mini) and Ollama; others may return JSON that is validated\n * after the call. On success, the parsed value is set on LlmResult.output.\n */\n outputSchema?: StandardSchemaV1;\n}\n\n/** Internal merged type for adapter and store. */\nexport type LlmOptionsMerged = Required<\n Pick<LlmOptions, \"temperature\" | \"maxTokens\">\n> &\n Omit<LlmOptions, \"temperature\" | \"maxTokens\">;\n\n/**\n * Token usage. Matches Vercel AI SDK LanguageModelUsage shape (inputTokens/outputTokens)\n * so result.usage can be used interchangeably with generateText() return value.\n */\nexport interface LlmUsage {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n}\n\n/**\n * LLM result shape aligned with Vercel AI SDK generateText() return value.\n * Same property names (text, output, usage) so code and docs transfer directly.\n */\nexport interface LlmResult {\n /** Generated text (raw string from the model). */\n text: string;\n /** Parsed structured output when outputSchema was set and validation succeeded. */\n output?: unknown;\n /** Token usage for the last step. Same shape as AI SDK usage. */\n usage?: LlmUsage;\n /** Full generateText() result for advanced use (debugging, response metadata). */\n raw?: unknown;\n}\n\n/**\n * When outputSchema S is provided to llm(), the result type narrows output to InferOutput<S>.\n * Used for type inference from llm(modelId, { outputSchema }) so body.output is typed downstream.\n */\nexport type LlmResultWithOutput<S extends StandardSchemaV1 | undefined> =\n S extends StandardSchemaV1\n ? Omit<LlmResult, \"output\"> & {\n output?: StandardSchemaV1.InferOutput<S>;\n }\n : LlmResult;\n\n/**\n * Recommended LLM model ids for autocomplete (chat/completion use cases).\n * Format: \"providerId:modelName\". Custom models are allowed via string.\n * Updated for 2026.\n */\nexport type LlmModelId =\n // OpenAI (2026: GPT-5.2, Codex, o1)\n | \"openai:gpt-5.2\"\n | \"openai:gpt-5.2-codex\"\n | \"openai:gpt-5\"\n | \"openai:gpt-5.1-chat-latest\"\n | \"openai:gpt-5-mini\"\n | \"openai:gpt-5-codex-mini\"\n | \"openai:gpt-4o\"\n | \"openai:gpt-4o-mini\"\n | \"openai:o1\"\n | \"openai:o1-mini\"\n // Anthropic (2026: Claude 4.6 / 4.5)\n | \"anthropic:claude-opus-4-6\"\n | \"anthropic:claude-sonnet-4-6\"\n | \"anthropic:claude-haiku-4-5\"\n // Ollama (common local models)\n | \"ollama:qwen3\"\n | \"ollama:llama3.2\"\n | \"ollama:llama3.3\"\n | \"ollama:mistral\"\n | \"ollama:gemma2\"\n | \"ollama:deepseek-r1\"\n | \"ollama:lfm2.5-thinking\"\n // OpenRouter (top open-weight / frontier: GLM, Kimi, Qwen, DeepSeek)\n | \"openrouter:z-ai/glm-5\"\n | \"openrouter:z-ai/glm-4.7\"\n | \"openrouter:moonshotai/kimi-k2-thinking\"\n | \"openrouter:qwen/qwen3.5-plus-02-15\"\n | \"openrouter:qwen/qwen3-next\"\n | \"openrouter:deepseek/deepseek-v3.2\"\n | \"openrouter:deepseek/deepseek-r1\"\n | \"openrouter:meta-llama/llama-3.3-70b-instruct\"\n // Gemini (2026: 2.5 + 3.x preview)\n | \"gemini:gemini-2.5-pro\"\n | \"gemini:gemini-2.5-flash\"\n | \"gemini:gemini-2.5-flash-lite\"\n | \"gemini:gemini-3.1-pro-preview\"\n | \"gemini:gemini-3-pro-preview\"\n | \"gemini:gemini-3-flash-preview\"\n // Other (custom models)\n | string;\n\nexport interface LlmPluginOptions {\n /**\n * Supported providers keyed by id. Only set options you need (defaults for url etc. apply).\n * Routes use llm(\"providerId:modelName\"), e.g. llm(\"ollama:lfm2.5-thinking\").\n */\n providers: LlmPluginProviders;\n /** Optional context-level default options (systemPrompt, temperature, etc.). */\n defaultOptions?: Partial<LlmOptionsMerged>;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n getExchangeContext,\n type CraftContext,\n type Destination,\n type Exchange,\n type MergedOptions,\n} from \"@routecraft/routecraft\";\nimport { callLlm } from \"./providers/index.ts\";\nimport { toAiOutputSpec } from \"./structured-output.ts\";\nimport type {\n LlmModelConfig,\n LlmOptions,\n LlmOptionsMerged,\n LlmPromptSource,\n LlmResultWithOutput,\n} from \"./types.ts\";\nimport { ADAPTER_LLM_OPTIONS, ADAPTER_LLM_PROVIDERS } from \"./types.ts\";\n\n/**\n * When the AI SDK doesn't set result.output (e.g. it threw on the getter), try to\n * parse result.text as JSON and validate with the output schema. Returns the\n * parsed value or undefined. Handles both sync and async Standard Schema validate().\n */\nasync function parseStructuredTextFallback(\n text: string,\n schema: StandardSchemaV1,\n): Promise<unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n const standard = (schema as unknown as Record<string, unknown>)[\n \"~standard\"\n ] as\n | {\n validate: (\n value: unknown,\n ) =>\n | { value?: unknown; issues?: unknown }\n | Promise<{ value?: unknown; issues?: unknown }>;\n }\n | undefined;\n if (!standard?.validate) return undefined;\n let result = standard.validate(parsed);\n if (result instanceof Promise) result = await result;\n if (\n result &&\n typeof result === \"object\" &&\n \"issues\" in result &&\n result.issues\n )\n return undefined;\n return result && typeof result === \"object\" && \"value\" in result\n ? result.value\n : undefined;\n}\n\nconst DEFAULT_TEMPERATURE = 0;\nconst DEFAULT_MAX_TOKENS = 1024;\n\nfunction resolvePrompt(\n source: LlmPromptSource | undefined,\n exchange: Exchange<unknown>,\n): string {\n if (source === undefined || source === \"\") return \"\";\n if (typeof source === \"function\") return source(exchange);\n return source;\n}\n\nfunction resolveUserPromptDefault(exchange: Exchange<unknown>): string {\n const body = exchange.body;\n if (typeof body === \"string\") return body;\n if (body === null || body === undefined) return \"\";\n if (typeof body === \"object\") return JSON.stringify(body);\n return String(body);\n}\n\n/** Format: \"providerId:modelName\", e.g. \"ollama:lfm2.5-thinking\". */\nfunction parseProviderModel(id: string): {\n providerId: string;\n modelName: string;\n} {\n const colon = id.indexOf(\":\");\n if (colon < 1 || colon === id.length - 1) {\n throw new Error(\n `LLM adapter: model id must be \"providerId:modelName\" (e.g. ollama:lfm2.5-thinking). Got: \"${id}\"`,\n );\n }\n return {\n providerId: id.slice(0, colon),\n modelName: id.slice(colon + 1),\n };\n}\n\nfunction resolveProviderAndModel(\n modelId: string,\n context: CraftContext | undefined,\n): { config: LlmModelConfig; modelName: string } {\n if (!context) {\n throw new Error(\n `LLM adapter: model id \"${modelId}\" requires a context to resolve. Ensure the exchange has context (e.g. from a route) so store \"${ADAPTER_LLM_PROVIDERS.description}\" can be read.`,\n );\n }\n const store = context.getStore(\n ADAPTER_LLM_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, LlmModelConfig> | undefined;\n if (!store) {\n throw new Error(\n `LLM provider not found: no providers registered. Add llmPlugin({ providers: { ollama: { provider: \"ollama\" }, ... } }) to your config.`,\n );\n }\n const { providerId, modelName } = parseProviderModel(modelId);\n const config = store.get(providerId);\n if (!config) {\n throw new Error(\n `LLM provider \"${providerId}\" not found. Register it with llmPlugin({ providers: { \"${providerId}\": { provider, apiKey?, baseURL? } } }).`,\n );\n }\n return { config, modelName };\n}\n\n/**\n * LLM destination adapter. Expects model id as \"providerId:modelName\" (e.g. ollama:lfm2.5-thinking),\n * resolves the provider from the plugin store, merges options, and calls the provider with the model name.\n * Use with .enrich(llm(\"providerId:modelName\", options)) or .to(llm(...)).\n *\n * @experimental\n * @template S - Output schema type when outputSchema is provided; narrows result.output for downstream typing.\n */\nexport class LlmDestinationAdapter<\n S extends StandardSchemaV1 | undefined = undefined,\n>\n implements\n Destination<unknown, LlmResultWithOutput<S>>,\n MergedOptions<LlmOptionsMerged>\n{\n readonly adapterId = \"routecraft.adapter.llm\";\n\n constructor(\n private readonly modelId: string,\n options: Partial<LlmOptions> = {},\n ) {\n this.options = options as Partial<LlmOptionsMerged>;\n }\n\n public options: Partial<LlmOptionsMerged>;\n\n mergedOptions(context: CraftContext): LlmOptionsMerged {\n const store = context.getStore(\n ADAPTER_LLM_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Partial<LlmOptionsMerged> | undefined;\n return {\n temperature: DEFAULT_TEMPERATURE,\n maxTokens: DEFAULT_MAX_TOKENS,\n ...store,\n ...this.options,\n } as LlmOptionsMerged;\n }\n\n async send(exchange: Exchange<unknown>): Promise<LlmResultWithOutput<S>> {\n const context = getExchangeContext(exchange);\n const { config, modelName } = resolveProviderAndModel(\n this.modelId,\n context,\n );\n const merged = this.mergedOptions(context!);\n\n const systemPrompt = resolvePrompt(merged.systemPrompt, exchange);\n const userPrompt =\n resolvePrompt(merged.userPrompt, exchange) ||\n resolveUserPromptDefault(exchange);\n\n const opts: Parameters<typeof callLlm>[0][\"options\"] = {\n temperature: merged.temperature,\n maxTokens: merged.maxTokens,\n };\n if (merged.topP !== undefined) opts.topP = merged.topP;\n if (merged.frequencyPenalty !== undefined)\n opts.frequencyPenalty = merged.frequencyPenalty;\n if (merged.presencePenalty !== undefined)\n opts.presencePenalty = merged.presencePenalty;\n\n const output =\n merged.outputSchema !== undefined\n ? toAiOutputSpec(merged.outputSchema)\n : undefined;\n\n const result = await callLlm({\n config,\n modelId: modelName,\n options: opts,\n systemPrompt,\n userPrompt,\n output,\n });\n\n if (\n result.output === undefined &&\n result.text &&\n merged.outputSchema !== undefined\n ) {\n const fallback = await parseStructuredTextFallback(\n result.text,\n merged.outputSchema,\n );\n if (fallback !== undefined) result.output = fallback;\n }\n\n return result as LlmResultWithOutput<S>;\n }\n\n /**\n * Extract metadata from LLM result for observability.\n * Includes model, provider, and token usage.\n */\n getMetadata(result: unknown): Record<string, unknown> {\n const llmResult = result as LlmResultWithOutput<S>;\n const { providerId } = parseProviderModel(this.modelId);\n\n const metadata: Record<string, unknown> = {\n model: this.modelId,\n provider: providerId,\n };\n\n if (llmResult.usage) {\n if (llmResult.usage[\"inputTokens\"] !== undefined) {\n metadata[\"inputTokens\"] = llmResult.usage[\"inputTokens\"];\n }\n if (llmResult.usage[\"outputTokens\"] !== undefined) {\n metadata[\"outputTokens\"] = llmResult.usage[\"outputTokens\"];\n }\n }\n\n return metadata;\n }\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { Destination } from \"@routecraft/routecraft\";\nimport { LlmDestinationAdapter } from \"./destination.ts\";\nimport type { LlmOptions, LlmResultWithOutput } from \"./types.ts\";\nimport type { RegisteredLlmModelId } from \"../registry.ts\";\n\n/**\n * Creates an LLM destination that calls a provider with a model. Use with .enrich() or .to().\n * Pass model id as \"providerId:modelName\" (e.g. ollama:lfm2.5-thinking). The provider must be\n * registered via llmPlugin({ providers: { ollama: { provider: \"ollama\" }, ... } }).\n * When options.outputSchema is provided, the result type narrows so body.output is typed downstream.\n *\n * @experimental\n * @param modelId - \"providerId:modelName\"; the provider is resolved from the plugin, the model name is sent to the provider.\n * @param options - Optional overrides (systemPrompt, userPrompt, temperature, maxTokens, outputSchema, etc.). User prompt defaults to exchange.body.\n */\nexport function llm<S extends StandardSchemaV1 | undefined = undefined>(\n modelId: RegisteredLlmModelId,\n options?: Partial<LlmOptions> & { outputSchema?: S },\n): Destination<unknown, LlmResultWithOutput<S>> {\n return new LlmDestinationAdapter<S>(modelId, options);\n}\n","import type { LlmPluginOptions, LlmProviderType } from \"./types.ts\";\n\nconst PROVIDERS: LlmProviderType[] = [\n \"openai\",\n \"anthropic\",\n \"openrouter\",\n \"ollama\",\n \"gemini\",\n];\n\nfunction isProvider(s: string): s is LlmProviderType {\n return (PROVIDERS as string[]).includes(s);\n}\n\n/**\n * Validates LLM plugin options at apply time.\n * Key is the provider; value is options for that provider (no provider field).\n */\nexport function validateLlmPluginOptions(options: LlmPluginOptions): void {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"llmPlugin: options must be an object\");\n }\n if (!options.providers || typeof options.providers !== \"object\") {\n throw new TypeError(\n \"llmPlugin: options.providers must be an object (record of provider id → options)\",\n );\n }\n for (const [providerId, opts] of Object.entries(options.providers)) {\n if (opts === undefined) continue;\n if (!opts || typeof opts !== \"object\") {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"] must be an object`,\n );\n }\n if (!isProvider(providerId)) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"] is not a supported provider. Supported: ${PROVIDERS.join(\", \")}`,\n );\n }\n switch (providerId) {\n case \"openai\":\n case \"anthropic\":\n case \"openrouter\":\n case \"gemini\":\n if (\n typeof (opts as { apiKey?: string }).apiKey !== \"string\" ||\n !(opts as { apiKey: string }).apiKey.trim()\n ) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"].apiKey is required`,\n );\n }\n break;\n case \"ollama\":\n if (\n (opts as { baseURL?: string }).baseURL !== undefined &&\n typeof (opts as { baseURL?: string }).baseURL !== \"string\"\n ) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"].baseURL must be a string when provided`,\n );\n }\n if (\n (opts as { modelId?: string }).modelId !== undefined &&\n (typeof (opts as { modelId?: string }).modelId !== \"string\" ||\n !(opts as { modelId: string }).modelId.trim())\n ) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"].modelId must be a non-empty string when provided`,\n );\n }\n break;\n }\n }\n if (\n options.defaultOptions !== undefined &&\n (typeof options.defaultOptions !== \"object\" ||\n options.defaultOptions === null)\n ) {\n throw new TypeError(\n \"llmPlugin: defaultOptions must be an object when provided\",\n );\n }\n}\n","import type { CraftContext, CraftPlugin } from \"@routecraft/routecraft\";\nimport { ADAPTER_LLM_OPTIONS, ADAPTER_LLM_PROVIDERS } from \"./types.ts\";\nimport type {\n LlmModelConfig,\n LlmPluginOptions,\n LlmProviderOptionsMap,\n} from \"./types.ts\";\nimport { validateLlmPluginOptions } from \"./validate-options.ts\";\n\nconst PROVIDER_IDS = [\n \"openai\",\n \"anthropic\",\n \"openrouter\",\n \"ollama\",\n \"gemini\",\n] as const satisfies readonly LlmModelConfig[\"provider\"][];\n\n/** Normalize provider options to full LlmModelConfig (add provider field from key). */\nfunction toModelConfig<P extends LlmModelConfig[\"provider\"]>(\n providerId: P,\n opts: LlmProviderOptionsMap[P],\n): Extract<LlmModelConfig, { provider: P }> {\n return { provider: providerId, ...opts } as Extract<\n LlmModelConfig,\n { provider: P }\n >;\n}\n\n/**\n * LLM plugin: config-only helper (no lifecycle hooks). Registers providers and optional\n * default options in the context store so routes can use llm(\"providerId:modelName\", options),\n * e.g. llm(\"ollama:lfm2.5-thinking\"). Key is the provider; only set options you need.\n *\n * Advanced users can set the store directly: context.setStore(ADAPTER_LLM_PROVIDERS, map)\n * and context.setStore(ADAPTER_LLM_OPTIONS, partialOptions) without using this plugin.\n *\n * @experimental\n */\nexport function llmPlugin(\n options: LlmPluginOptions = { providers: {} },\n): CraftPlugin {\n validateLlmPluginOptions(options);\n\n return {\n apply(ctx: CraftContext) {\n const map = new Map<string, LlmModelConfig>();\n for (const providerId of PROVIDER_IDS) {\n const opts = options.providers[providerId];\n if (opts !== undefined)\n map.set(providerId, toModelConfig(providerId, opts));\n }\n ctx.setStore(\n ADAPTER_LLM_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n map,\n );\n if (\n options.defaultOptions &&\n Object.keys(options.defaultOptions).length > 0\n ) {\n ctx.setStore(\n ADAPTER_LLM_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n options.defaultOptions,\n );\n }\n },\n };\n}\n","import type {\n DirectRouteMetadata,\n DirectServerOptions,\n Exchange,\n} from \"@routecraft/routecraft\";\nimport type { McpToolRegistry } from \"./tool-registry.ts\";\n\n/**\n * Store key set by mcpPlugin() when applied; routes using .from(mcp(...)) require it.\n * @internal\n */\nexport const MCP_PLUGIN_REGISTERED = Symbol.for(\n \"routecraft.mcp.plugin.registered\",\n);\n\n/**\n * Store key for named remote MCP servers (mcpPlugin({ clients })). Used by McpClient to resolve serverId.\n * @internal\n */\nexport const ADAPTER_MCP_CLIENT_SERVERS = Symbol.for(\n \"routecraft.mcp.client.servers\",\n);\n\n/**\n * Store key for the unified MCP tool registry. Used by agent adapter for tool discovery.\n * @internal\n */\nexport const MCP_TOOL_REGISTRY = Symbol.for(\"routecraft.mcp.tool.registry\");\n\n/**\n * Store key for stdio client managers. Used by destination adapter to call tools on stdio clients.\n * @internal\n */\nexport const MCP_STDIO_MANAGERS = Symbol.for(\"routecraft.mcp.stdio.managers\");\n\ndeclare module \"@routecraft/routecraft\" {\n interface StoreRegistry {\n [MCP_PLUGIN_REGISTERED]: boolean;\n [ADAPTER_MCP_CLIENT_SERVERS]: Map<\n string,\n McpClientHttpConfig | McpClientStdioConfig | string\n >;\n [MCP_TOOL_REGISTRY]: McpToolRegistry;\n [MCP_STDIO_MANAGERS]: Map<\n string,\n {\n callTool(name: string, args: Record<string, unknown>): Promise<unknown>;\n }\n >;\n }\n\n interface RoutecraftHeaders {\n /** The MCP tool name that triggered this exchange. */\n \"routecraft.mcp.tool\"?: string;\n /** The MCP session identifier. */\n \"routecraft.mcp.session\"?: string;\n /** Authenticated subject (from AuthPrincipal). */\n \"routecraft.auth.subject\"?: string;\n /** Authentication scheme used. */\n \"routecraft.auth.scheme\"?: string;\n /** Roles assigned to the authenticated principal. */\n \"routecraft.auth.roles\"?: string[];\n /** Scopes granted to the authenticated principal. */\n \"routecraft.auth.scopes\"?: string[];\n /** Email of the authenticated principal. */\n \"routecraft.auth.email\"?: string;\n /** Display name of the authenticated principal. */\n \"routecraft.auth.name\"?: string;\n /** Token issuer (JWT `iss`). */\n \"routecraft.auth.issuer\"?: string;\n /** Intended audience (JWT `aud`). */\n \"routecraft.auth.audience\"?: string[];\n }\n}\n\n/**\n * HTTP client config for a remote MCP server (Streamable HTTP).\n * Used in mcpPlugin({ clients: { name: config } }).\n */\nexport interface McpClientHttpConfig {\n transport?: \"streamable-http\";\n url: string;\n /** Auth credentials sent on every request to this server. */\n auth?: McpClientAuthOptions;\n}\n\n/**\n * Stdio client config for a local MCP server subprocess.\n * Used in mcpPlugin({ clients: { name: config } }).\n * The plugin spawns the process, manages its lifecycle, and auto-restarts on crash.\n */\nexport interface McpClientStdioConfig {\n transport: \"stdio\";\n /** The executable to run (e.g. \"npx\", \"node\", \"python\"). */\n command: string;\n /** Command line arguments to pass to the executable. */\n args?: string[];\n /** Environment variables for the child process. Defaults to a safe subset of the parent env. */\n env?: Record<string, string>;\n /** Working directory for the child process. Defaults to the current working directory. */\n cwd?: string;\n}\n\n/** Union of client configs accepted by mcpPlugin({ clients }). */\nexport type McpClientServerConfig = McpClientHttpConfig | McpClientStdioConfig;\n\n/**\n * Header keys set on exchanges created by the MCP server.\n * Use these with `exchange.headers[McpHeadersKeys.AUTH_SUBJECT]` for type-safe access.\n *\n * @example\n * ```ts\n * import { McpHeadersKeys } from '@routecraft/ai'\n *\n * .process((ex) => {\n * const user = ex.headers[McpHeadersKeys.AUTH_SUBJECT]\n * const tool = ex.headers[McpHeadersKeys.TOOL]\n * })\n * ```\n */\nexport enum McpHeadersKeys {\n /** The MCP tool name that triggered this exchange. */\n TOOL = \"routecraft.mcp.tool\",\n /** The MCP session identifier. */\n SESSION = \"routecraft.mcp.session\",\n /** Authenticated subject (from AuthPrincipal). */\n AUTH_SUBJECT = \"routecraft.auth.subject\",\n /** Authentication scheme used. */\n AUTH_SCHEME = \"routecraft.auth.scheme\",\n /** Roles assigned to the authenticated principal. */\n AUTH_ROLES = \"routecraft.auth.roles\",\n /** Scopes granted to the authenticated principal. */\n AUTH_SCOPES = \"routecraft.auth.scopes\",\n /** Email of the authenticated principal. */\n AUTH_EMAIL = \"routecraft.auth.email\",\n /** Display name of the authenticated principal. */\n AUTH_NAME = \"routecraft.auth.name\",\n /** Token issuer (JWT `iss`). */\n AUTH_ISSUER = \"routecraft.auth.issuer\",\n /** Intended audience (JWT `aud`). */\n AUTH_AUDIENCE = \"routecraft.auth.audience\",\n}\n\n/**\n * Authenticated user principal resolved from an incoming request.\n * Returned by the auth validator to populate exchange headers for logging,\n * filtering, and access control inside routes.\n *\n * `subject` and `scheme` are always required; everything else is\n * scheme-dependent and may be absent.\n *\n * @experimental\n */\nexport interface AuthPrincipal {\n /** Unique user/client identifier (JWT `sub`, username, API key ID, etc.). */\n subject: string;\n /** Authentication scheme that produced this principal. */\n scheme: \"bearer\" | \"basic\" | \"api-key\" | (string & {});\n /** Role names granted to this principal. */\n roles?: string[];\n /** OAuth 2.0 / JWT scopes. */\n scopes?: string[];\n /** Email address, if known. */\n email?: string;\n /** Display name, if known. */\n name?: string;\n /** Token issuer (JWT `iss`). */\n issuer?: string;\n /** Intended audiences (JWT `aud`). */\n audience?: string[];\n /** Expiry as Unix epoch seconds (JWT `exp`, session expiry). */\n expiresAt?: number;\n /** Arbitrary extra claims. For JWTs this holds the full decoded payload. */\n claims?: Record<string, unknown>;\n}\n\n/**\n * Authentication options for the MCP HTTP server.\n * Only applies when `transport` is `\"http\"`. Ignored for stdio.\n *\n * The validator receives the raw bearer token from the `Authorization` header\n * on every request and must return an {@link AuthPrincipal} on success or\n * `null` / `false` to reject with 401. Use the built-in `jwt()` helper for\n * HMAC-signed JWTs or supply a custom function for other schemes.\n *\n * @example\n * ```ts\n * // Built-in JWT helper (HMAC / HS256)\n * import { jwt } from \"@routecraft/ai\";\n * auth: jwt({ secret: process.env.JWT_SECRET! })\n *\n * // Custom validator\n * auth: {\n * validator: async (token) => {\n * const user = await lookupApiKey(token);\n * if (!user) return null;\n * return { subject: user.id, scheme: \"api-key\", roles: user.roles };\n * }\n * }\n * ```\n *\n * @experimental\n */\nexport interface McpHttpAuthOptions {\n /**\n * Validator function called with the raw bearer token on every request.\n *\n * Return an {@link AuthPrincipal} to allow access; return `null` or `false`\n * to reject with 401. May be async.\n *\n * If the function throws, the server responds with 500.\n * Validators should catch expected failures (e.g. JWT expiry) and return `null`.\n */\n validator: McpAuthValidator;\n}\n\n/**\n * A function that validates a bearer token and resolves the authenticated principal.\n * Called on every incoming HTTP request.\n * May be synchronous or asynchronous.\n *\n * Return an {@link AuthPrincipal} to allow access, or `null` / `false` to reject with 401.\n * If the function throws, the server responds with 500.\n *\n * @experimental\n */\nexport type McpAuthValidator = (\n token: string,\n) => AuthPrincipal | null | false | Promise<AuthPrincipal | null | false>;\n\n/**\n * A function that provides a bearer token for outbound requests.\n * Called on every request; may be synchronous or asynchronous.\n * Useful for dynamic tokens (JWT refresh, rotating API keys, etc.).\n *\n * @experimental\n */\nexport type McpClientTokenProvider = () => string | Promise<string>;\n\n/**\n * Auth config for an outbound MCP HTTP client connection.\n * Passed as request headers on every connection to the remote server.\n *\n * @experimental\n */\nexport interface McpClientAuthOptions {\n /**\n * Bearer token(s) or provider for the `Authorization` header.\n * Builds `Authorization: Bearer <token>`.\n *\n * - `string` -- single static token.\n * - `string[]` -- array of tokens; one is selected per request (round-robin).\n * - `() => string | Promise<string>` -- called per request for dynamic tokens.\n */\n token?: string | string[] | McpClientTokenProvider;\n /**\n * Additional headers to include on every request to the remote server.\n * If `Authorization` is set here, it overrides `token`.\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Options for the MCP plugin (mcpPlugin).\n * One plugin per adapter: this is the single options type for the MCP plugin.\n */\nexport interface McpPluginOptions {\n /** Server name in MCP protocol handshake. Default: \"routecraft\" */\n name?: string;\n\n /** Server version. Default: \"1.0.0\" */\n version?: string;\n\n /** Transport mode for MCP server. Default: \"stdio\" */\n transport?: \"stdio\" | \"http\";\n\n /** Port for the streamable-http MCP server. Default: 3001 (only used with transport: \"http\") */\n port?: number;\n\n /** Host to bind to. Default: \"localhost\" (only used with transport: \"http\") */\n host?: string;\n\n /**\n * Authentication for the HTTP transport. When set, every request to `/mcp` must\n * include a valid `Authorization: Bearer <token>` header. Ignored for stdio.\n *\n * @example\n * ```ts\n * import { jwt } from \"@routecraft/ai\";\n * auth: jwt({ secret: process.env.JWT_SECRET! })\n * ```\n */\n auth?: McpHttpAuthOptions;\n\n /**\n * Filter which tools to expose. Default: all mcp() routes.\n * Can be an array of endpoint names or a filter function.\n */\n tools?: string[] | ((meta: DirectRouteMetadata) => boolean);\n\n /**\n * Named remote MCP servers for .to(mcp(\"name:tool\")).\n * Keys are server names; values are HTTP or stdio config.\n * Stdio clients are managed as subprocesses with auto-restart.\n * HTTP clients are used for ephemeral tool calls.\n */\n clients?: Record<string, McpClientHttpConfig | McpClientStdioConfig>;\n\n /**\n * Max auto-restart attempts for stdio clients before giving up.\n * Applies to all stdio clients. Default: 5.\n */\n maxRestarts?: number;\n\n /**\n * Base delay in ms before the first restart attempt.\n * Subsequent attempts use exponential backoff. Default: 1000.\n */\n restartDelayMs?: number;\n\n /**\n * Multiplier for exponential backoff between restart attempts.\n * Delay = restartDelayMs * (restartBackoffMultiplier ^ restartCount). Default: 2.\n */\n restartBackoffMultiplier?: number;\n\n /**\n * Interval in ms to re-list tools from HTTP clients.\n * Set to 0 to disable periodic refresh. Default: 60000 (60s).\n */\n toolRefreshIntervalMs?: number;\n}\n\n/**\n * Options for mcp() when used as a server in .from().\n * Description is required for AI/MCP discoverability.\n */\nexport interface McpServerOptions extends DirectServerOptions {\n /** Human-readable description (required for MCP tools). */\n description: string;\n}\n\nexport type McpOptions = McpServerOptions;\n\n/**\n * Extracts MCP tool arguments from an exchange. Default implementation uses exchange.body.\n */\nexport type McpArgsExtractor = (\n exchange: Exchange<unknown>,\n) => Record<string, unknown>;\n\n/**\n * Options for mcp() when used as a Client in .to() to call a remote MCP server.\n * Provide either url (inline HTTP) or serverId (from plugin/store); tool is required.\n *\n * Supported transports:\n * - **HTTP:** use `url` for an inline endpoint or `serverId` for a named backend.\n * - **Stdio:** use `serverId` referencing a stdio client from mcpPlugin({ clients }).\n * The destination adapter resolves the manager from the context store and calls\n * tools directly on the subprocess -- no HTTP involved.\n */\nexport interface McpClientOptions {\n /** URL of the remote MCP server (HTTP/HTTPS only). Omit when using serverId. */\n url?: string;\n /** Tool name to invoke. If omitted, exchange body may specify it or a default applies. */\n tool?: string;\n /** Server id from context store; resolved to URL at runtime. Use when URL is registered via mcpPlugin({ clients }). */\n serverId?: string;\n /**\n * Extract tool arguments from the exchange. Receives the full exchange.\n * Default: body as object -> use as args; otherwise { input: body }.\n */\n args?: McpArgsExtractor;\n /**\n * Auth credentials for the outbound HTTP connection.\n * When using `serverId`, auth flows automatically from `mcpPlugin({ clients })`\n * so this field is rarely needed. Use it to override registered auth or to\n * supply credentials when using inline `url`.\n */\n auth?: McpClientAuthOptions;\n}\n\n/**\n * Represents a tool exposed via MCP\n */\nexport interface McpTool {\n name: string;\n description?: string;\n inputSchema: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n [key: string]: unknown;\n };\n}\n\n/**\n * A tool entry in the unified MCP tool registry.\n * Combines local mcp() route tools and remote client tools (stdio and HTTP).\n */\nexport interface McpToolRegistryEntry {\n /** Tool name (unique within a source, may collide across sources). */\n name: string;\n /** Human-readable description of the tool. */\n description?: string;\n /** JSON Schema for tool input. */\n inputSchema: Record<string, unknown>;\n /** Source server ID. Local mcp() routes use \"local\". */\n source: string;\n /** Transport type of the source. */\n transport: \"stdio\" | \"http\" | \"local\";\n}\n\n/**\n * MCP tool call result\n */\nexport interface McpToolResult {\n content: Array<{\n type: \"text\" | \"image\" | \"resource\";\n text?: string;\n data?: string;\n mimeType?: string;\n }>;\n isError?: boolean;\n}\n","/**\n * Brand symbol for MCP adapter type checking.\n * Used internally to identify MCP adapters.\n * @experimental\n */\nexport const BRAND_MCP_ADAPTER = Symbol.for(\"routecraft.mcp.adapter\");\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n direct,\n rcError,\n type CraftContext,\n type Exchange,\n type ExchangeHeaders,\n type Source,\n} from \"@routecraft/routecraft\";\nimport { MCP_PLUGIN_REGISTERED, type McpServerOptions } from \"../../types.ts\";\nimport type { McpMessage } from \"./types.ts\";\nimport { BRAND_MCP_ADAPTER } from \"./shared.ts\";\n\n/**\n * McpSourceAdapter implements the Source interface for the MCP adapter.\n *\n * This adapter is used when mcp() is called with two arguments:\n * - `mcp(endpoint, options)` where options contains a description (required for MCP)\n *\n * It delegates to the direct() adapter internally after validating the MCP plugin is registered.\n * The MCP plugin will expose these routes as tools via the MCP protocol.\n */\nexport class McpSourceAdapter<\n S extends StandardSchemaV1 | undefined = undefined,\n> implements Source<McpMessage<S>> {\n readonly adapterId: string = \"routecraft.adapter.mcp\";\n\n private endpoint: string;\n private options: McpServerOptions & { schema?: S };\n\n constructor(endpoint: string, options: McpServerOptions & { schema?: S }) {\n (this as unknown as Record<symbol, boolean>)[BRAND_MCP_ADAPTER] = true;\n\n // Validate endpoint and options\n if (typeof endpoint !== \"string\") {\n throw rcError(\"RC5003\", undefined, {\n message: \"Dynamic endpoints cannot be used as source\",\n suggestion:\n \"Use a static string endpoint for source: .from(mcp('endpoint', options)).\",\n });\n }\n\n if (\"url\" in options || \"serverId\" in options) {\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp() with url or serverId must be used as destination: .to(mcp({ url, tool }))\",\n suggestion:\n \"Use .to(mcp({ url: '...', tool: '...' })) to call a remote MCP server.\",\n });\n }\n\n if (\n \"args\" in options &&\n (options as { args?: unknown }).args !== undefined &&\n !(\"description\" in options)\n ) {\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp(endpoint, { args }) is for client usage with a 'server:tool' target, not for defining a source\",\n suggestion:\n \"Use .to(mcp('server:tool', { args })) to call a remote tool, or .from(mcp('endpoint', { description: '...' })) to define a source.\",\n });\n }\n\n if (\n !(\"description\" in options) ||\n typeof options.description !== \"string\"\n ) {\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp(endpoint, options) as source requires options.description\",\n suggestion:\n \"Use .from(mcp('endpoint', { description: '...' })) to define a source.\",\n });\n }\n\n this.endpoint = endpoint;\n this.options = options;\n }\n\n async subscribe(\n context: CraftContext,\n handler: (\n message: McpMessage<S>,\n headers?: ExchangeHeaders,\n ) => Promise<Exchange>,\n abortController: AbortController,\n onReady?: () => void,\n ): Promise<void> {\n // Verify MCP plugin is registered\n const registered = context.getStore(\n MCP_PLUGIN_REGISTERED as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as boolean | undefined;\n if (registered !== true) {\n throw new Error(\n \"MCP plugin required: routes using .from(mcp(...)) require the MCP plugin. Add mcpPlugin() to your config: plugins: [mcpPlugin()].\",\n );\n }\n\n // Delegate to direct adapter\n const directAdapter = direct(this.endpoint, this.options);\n return directAdapter.subscribe(context, handler, abortController, onReady);\n }\n}\n","/**\n * Extract content from an MCP tool response.\n *\n * - Single text item: returns the string directly for convenience.\n * - Multiple items or non-text items: returns the full content array so\n * callers can inspect type/text/data on each entry.\n * - No content: returns the raw response object.\n */\nexport function extractContent(\n response: {\n content?: Array<{ type: string; text?: string; data?: string }>;\n } | null,\n): unknown {\n const content = response?.content;\n if (!Array.isArray(content) || content.length === 0) return response;\n\n // Single text entry: return the string for backward compatibility\n if (content.length === 1) {\n const item = content[0];\n if (item.type === \"text\" && typeof item.text === \"string\") return item.text;\n if (typeof item.data === \"string\") return item.data;\n }\n\n // Multiple items or non-text: return the full array\n return content;\n}\n","import type { McpClientAuthOptions } from \"./types.ts\";\n\n/** Round-robin index for array tokens, keyed by the array reference. */\nconst rrIndexes = new WeakMap<string[], number>();\n\n/**\n * Resolve the raw token value from the various accepted forms.\n * @internal\n */\nasync function resolveToken(\n token: NonNullable<McpClientAuthOptions[\"token\"]>,\n): Promise<string> {\n if (typeof token === \"function\") {\n return token();\n }\n if (Array.isArray(token)) {\n if (token.length === 0) {\n throw new Error(\"McpClientAuthOptions.token array must not be empty\");\n }\n const idx = (rrIndexes.get(token) ?? 0) % token.length;\n rrIndexes.set(token, idx + 1);\n return token[idx];\n }\n return token;\n}\n\n/**\n * Build HTTP headers from MCP client auth options.\n * Returns undefined when no headers are needed.\n * @internal\n */\nexport async function buildAuthHeaders(\n auth?: McpClientAuthOptions,\n): Promise<Record<string, string> | undefined> {\n if (!auth) return undefined;\n\n const headers: Record<string, string> = {};\n const customHeaders = auth.headers ?? {};\n\n // Check if custom headers provide an Authorization override (case-insensitive)\n const authorizationOverride = Object.entries(customHeaders).find(\n ([name]) => name.toLowerCase() === \"authorization\",\n )?.[1];\n\n if (authorizationOverride) {\n headers[\"Authorization\"] = authorizationOverride;\n } else if (auth.token !== undefined) {\n const resolved = await resolveToken(auth.token);\n if (resolved.length === 0) {\n throw new Error(\n \"McpClientAuthOptions.token must be a non-empty string when provided\",\n );\n }\n headers[\"Authorization\"] = `Bearer ${resolved}`;\n }\n\n // Merge remaining custom headers, skipping any authorization variant\n for (const [name, value] of Object.entries(customHeaders)) {\n if (name.toLowerCase() !== \"authorization\") {\n headers[name] = value;\n }\n }\n\n return Object.keys(headers).length > 0 ? headers : undefined;\n}\n","import type { Exchange, Destination } from \"@routecraft/routecraft\";\nimport { getExchangeContext } from \"@routecraft/routecraft\";\nimport type {\n McpClientOptions,\n McpArgsExtractor,\n McpClientAuthOptions,\n McpClientHttpConfig,\n} from \"../../types.ts\";\nimport { ADAPTER_MCP_CLIENT_SERVERS, MCP_STDIO_MANAGERS } from \"../../types.ts\";\nimport { BRAND_MCP_ADAPTER } from \"./shared.ts\";\nimport { extractContent } from \"../../extract-content.ts\";\nimport { buildAuthHeaders } from \"../../build-auth-headers.ts\";\n\n/** Ensure inline url is HTTP(S) only. Stdio clients are resolved via MCP_STDIO_MANAGERS store. */\nfunction assertHttpUrl(url: string): void {\n const trimmed = url.trim().toLowerCase();\n if (!trimmed.startsWith(\"http://\") && !trimmed.startsWith(\"https://\")) {\n throw new Error(\n `MCP client: url must be HTTP or HTTPS. Stdio is not supported in routes; register stdio clients via mcpPlugin({ clients: { name: { command, args } } }). Got: \"${url.slice(0, 50)}${url.length > 50 ? \"...\" : \"\"}\"`,\n );\n }\n}\n\n/**\n * Look up the registered server config from the context store.\n * Returns undefined when no context or no matching serverId.\n * Backward-compat: store value may be a plain string (url only).\n */\nfunction resolveServerConfig(\n options: McpClientOptions,\n context: ReturnType<typeof getExchangeContext>,\n): McpClientHttpConfig | string | undefined {\n if (!options.serverId || !context) return undefined;\n const servers = context.getStore(\n ADAPTER_MCP_CLIENT_SERVERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, McpClientHttpConfig | string> | undefined;\n return servers?.get(options.serverId);\n}\n\n/**\n * Resolves the URL and auth for the MCP server from options or context (serverId).\n * Returns both in a single lookup to avoid duplicate store reads.\n */\nfunction resolveConnection(\n options: McpClientOptions,\n context: ReturnType<typeof getExchangeContext>,\n): { url: string; auth?: McpClientAuthOptions | undefined } {\n if (options.url) {\n assertHttpUrl(options.url);\n return { url: options.url, auth: options.auth };\n }\n if (options.serverId && !context) {\n throw new Error(\n `MCP client: serverId \"${options.serverId}\" requires a context to resolve. Ensure the exchange has context (e.g. from a route) so store \"${String(ADAPTER_MCP_CLIENT_SERVERS)}\" can be read.`,\n );\n }\n if (options.serverId && context) {\n const config = resolveServerConfig(options, context);\n if (!config) {\n throw new Error(\n `MCP client: serverId \"${options.serverId}\" not found in context store. Register it with context store key \"${String(ADAPTER_MCP_CLIENT_SERVERS)}\".`,\n );\n }\n const url = typeof config === \"string\" ? config : config.url;\n const auth =\n options.auth ??\n (typeof config === \"object\" && \"auth\" in config\n ? config.auth\n : undefined);\n return { url, auth };\n }\n throw new Error(\n \"MCP client: either url or serverId must be provided in McpClientOptions.\",\n );\n}\n\n/**\n * Default args extractor: use exchange body as tool arguments.\n * If body is a non-null object, use it as the args; otherwise use { input: body }.\n */\nexport const defaultArgs: McpArgsExtractor = (exchange) =>\n typeof exchange.body === \"object\" && exchange.body !== null\n ? (exchange.body as Record<string, unknown>)\n : { input: exchange.body };\n\n/**\n * McpDestinationAdapter implements the Destination interface for the MCP adapter.\n *\n * This adapter is used when mcp() is called with client options:\n * - `mcp({ url, tool })` - Direct HTTP URL\n * - `mcp({ serverId, tool })` - Server registered via mcpPlugin\n * - `mcp('server:tool')` - Shorthand for serverId:tool\n *\n * It makes HTTP calls to remote MCP servers using the MCP SDK.\n */\nexport class McpDestinationAdapter implements Destination<unknown, unknown> {\n readonly adapterId: string = \"routecraft.adapter.mcp\";\n\n constructor(private readonly options: McpClientOptions) {\n (this as unknown as Record<symbol, boolean>)[BRAND_MCP_ADAPTER] = true;\n\n // Validate client options\n if (!options.url && !options.serverId) {\n throw new Error(\n \"MCP client: either url or serverId must be provided in McpClientOptions.\",\n );\n }\n\n if (options.url && options.serverId) {\n throw new Error(\n \"MCP client: cannot provide both url and serverId. Use either url for direct HTTP or serverId for registered servers.\",\n );\n }\n }\n\n async send(exchange: Exchange<unknown>): Promise<unknown> {\n const context = getExchangeContext(exchange);\n const toolName =\n this.options.tool ??\n (typeof exchange.body === \"object\" &&\n exchange.body !== null &&\n \"tool\" in exchange.body &&\n typeof (exchange.body as { tool: string }).tool === \"string\"\n ? (exchange.body as { tool: string }).tool\n : undefined);\n if (!toolName) {\n throw new Error(\n \"MCP client: tool name required. Set options.tool or exchange.body.tool.\",\n );\n }\n const argsExtractor = this.options.args ?? defaultArgs;\n const args = argsExtractor(exchange);\n\n // Check for stdio manager first (registered via mcpPlugin)\n if (this.options.serverId && context) {\n const stdioManagers = context.getStore(\n MCP_STDIO_MANAGERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as\n | Map<\n string,\n {\n callTool(\n name: string,\n args: Record<string, unknown>,\n ): Promise<unknown>;\n }\n >\n | undefined;\n const manager = stdioManagers?.get(this.options.serverId);\n if (manager) {\n const result = await manager.callTool(toolName, args);\n if (result && typeof result === \"object\") {\n (result as Record<string, unknown>)[\"metadata\"] = {\n toolName,\n transport: \"stdio\",\n serverId: this.options.serverId,\n };\n }\n return result;\n }\n\n // Guard: if the registered config is stdio-type but the manager is missing,\n // throw a clear error instead of falling through to HTTP (which would fail\n // confusingly since stdio configs have no url property).\n const servers = context.getStore(\n ADAPTER_MCP_CLIENT_SERVERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, unknown> | undefined;\n const serverConfig = servers?.get(this.options.serverId);\n if (\n serverConfig &&\n typeof serverConfig === \"object\" &&\n \"transport\" in serverConfig &&\n (serverConfig as { transport: string }).transport === \"stdio\"\n ) {\n throw new Error(\n `MCP client: stdio server \"${this.options.serverId}\" is not running. Ensure mcpPlugin is applied and the stdio client started successfully.`,\n );\n }\n }\n\n // Fall through to HTTP\n const { url, auth } = resolveConnection(this.options, context);\n const result = await this.callRemoteTool(url, toolName, args, auth);\n\n // Attach metadata to result for getMetadata() to read (eliminates race condition)\n if (result && typeof result === \"object\") {\n (result as Record<string, unknown>)[\"metadata\"] = {\n toolName,\n url,\n transport: \"http\",\n ...(this.options.serverId ? { serverId: this.options.serverId } : {}),\n };\n }\n\n return result;\n }\n\n /**\n * Extract metadata from MCP adapter execution.\n * Reads metadata from the result object to avoid race conditions with concurrent exchanges.\n */\n getMetadata(result: unknown): Record<string, unknown> {\n if (result && typeof result === \"object\" && \"metadata\" in result) {\n return (result as { metadata: Record<string, unknown> }).metadata;\n }\n return {\n toolName: \"unknown\",\n transport: \"unknown\",\n };\n }\n\n private async callRemoteTool(\n serverUrl: string,\n toolName: string,\n args: Record<string, unknown>,\n auth?: McpClientAuthOptions,\n ): Promise<unknown> {\n let clientModule: {\n Client: new (\n info: { name: string; version: string },\n options?: { capabilities?: Record<string, unknown> },\n ) => unknown;\n };\n let transportModule: {\n StreamableHTTPClientTransport: new (\n url: URL,\n options?: {\n sessionId?: string;\n requestInit?: { headers?: Record<string, string> };\n },\n ) => unknown;\n };\n try {\n clientModule = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n transportModule =\n await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n } catch {\n throw new Error(\n 'MCP client requires \"@modelcontextprotocol/sdk\". Install it with: pnpm add @modelcontextprotocol/sdk',\n );\n }\n const Client = clientModule.Client;\n const StreamableHTTPClientTransport =\n transportModule.StreamableHTTPClientTransport;\n\n const url = new URL(serverUrl);\n const headers = await buildAuthHeaders(auth);\n const transportOptions = headers ? { requestInit: { headers } } : undefined;\n const transport = new StreamableHTTPClientTransport(url, transportOptions);\n const clientInfo = { name: \"routecraft-mcp-client\", version: \"1.0.0\" };\n const client = new (Client as new (\n info: { name: string; version: string },\n options?: { capabilities?: Record<string, unknown> },\n ) => InstanceType<typeof clientModule.Client>)(clientInfo, {\n capabilities: {},\n });\n try {\n const connect = (\n client as unknown as { connect(transport: unknown): Promise<void> }\n ).connect;\n await connect.call(client, transport);\n\n const callTool = (\n client as unknown as {\n callTool(params: {\n name: string;\n arguments?: Record<string, unknown>;\n }): Promise<{ content?: Array<{ type: string; text?: string }> }>;\n }\n ).callTool;\n const response = await callTool.call(client, {\n name: toolName,\n arguments: args,\n });\n\n return extractContent(response);\n } finally {\n const clientCleanup = client as unknown as {\n close?: () => void | Promise<void>;\n disconnect?: () => void | Promise<void>;\n };\n const closeOrDisconnect = clientCleanup.close ?? clientCleanup.disconnect;\n if (typeof closeOrDisconnect === \"function\") {\n try {\n await Promise.resolve(closeOrDisconnect.call(client));\n } catch {\n // Ignore cleanup errors so original error propagates\n }\n }\n const transportCleanup = transport as unknown as {\n close?: () => void | Promise<void>;\n destroy?: () => void;\n };\n const closeOrDestroy = transportCleanup.close ?? transportCleanup.destroy;\n if (typeof closeOrDestroy === \"function\") {\n try {\n await Promise.resolve(closeOrDestroy.call(transport));\n } catch {\n // Ignore cleanup errors so original error propagates\n }\n }\n }\n }\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n rcError,\n type Exchange,\n type Source,\n type Destination,\n} from \"@routecraft/routecraft\";\nimport type {\n McpArgsExtractor,\n McpClientOptions,\n McpServerOptions,\n} from \"../../types.ts\";\nimport type { RegisteredMcpShorthand } from \"../../../registry.ts\";\nimport { McpSourceAdapter } from \"./source.ts\";\nimport { McpDestinationAdapter } from \"./destination.ts\";\nimport type { McpMessage } from \"./types.ts\";\n\n/**\n * Creates an MCP adapter for communicating with MCP servers.\n *\n * - **Source (for `.from()`):** Call with two arguments: `mcp(endpoint, options)`.\n * Options must include a `description` field (required for MCP tool exposure).\n * Requires the MCP plugin: `plugins: [mcpPlugin()]`.\n * Body type is inferred from `options.schema` when provided.\n *\n * - **Destination (for `.to()` / `.tap()`):** Call with one argument containing client options:\n * - `mcp({ url, tool })` - Direct HTTP URL to remote MCP server\n * - `mcp({ serverId, tool })` - Server ID registered via mcpPlugin({ clients })\n * - `mcp('server:tool', { args? })` - Shorthand for serverId:tool with optional args extractor\n *\n * The MCP adapter delegates to the direct() adapter for source routes and makes HTTP calls\n * to remote MCP servers for destination routes.\n *\n * @param endpointOrOptions - Endpoint string (source) or client options object (destination) or 'server:tool' string (destination)\n * @param options - Server options (source) or args extractor (destination)\n * @returns Source when called with two arguments; Destination when called with one argument\n *\n * @experimental\n *\n * @example\n * ```typescript\n * // Source route (MCP tool)\n * .from(mcp('/search', { description: 'Search documents', schema: mySchema }))\n *\n * // Destination (call remote MCP server)\n * .to(mcp({ url: 'http://localhost:3001/mcp', tool: 'search' }))\n * .to(mcp({ serverId: 'my-server', tool: 'search' }))\n * .to(mcp('my-server:search'))\n * .to(mcp('my-server:search', { args: (ex) => ex.body.params }))\n * ```\n */\nexport function mcp<S extends StandardSchemaV1 | undefined = undefined>(\n endpoint: string,\n options: McpServerOptions & { schema?: S },\n): Source<McpMessage<S>>;\nexport function mcp(\n clientOptions: McpClientOptions,\n): Destination<unknown, unknown>;\nexport function mcp(\n shorthand: RegisteredMcpShorthand,\n options?: { args?: McpArgsExtractor },\n): Destination<unknown, unknown>;\nexport function mcp<S extends StandardSchemaV1 | undefined = undefined>(\n endpointOrOptions:\n | string\n | ((exchange: Exchange<McpMessage<S>>) => string)\n | McpClientOptions,\n options?: (McpServerOptions & { schema?: S }) | { args?: McpArgsExtractor },\n): Source<McpMessage<S>> | Destination<unknown, unknown> {\n // Client: object with url or serverId\n if (\n typeof endpointOrOptions === \"object\" &&\n endpointOrOptions !== null &&\n (\"url\" in endpointOrOptions || \"serverId\" in endpointOrOptions)\n ) {\n const clientOpts = endpointOrOptions as McpClientOptions;\n if (typeof clientOpts.auth?.token === \"string\") {\n if (clientOpts.auth.token.trim().length === 0) {\n throw new TypeError(\n \"mcp(): auth.token must be a non-empty string when provided\",\n );\n }\n }\n if (Array.isArray(clientOpts.auth?.token)) {\n if (clientOpts.auth.token.length === 0) {\n throw new TypeError(\"mcp(): auth.token array must not be empty\");\n }\n for (let i = 0; i < clientOpts.auth.token.length; i++) {\n const entry = clientOpts.auth.token[i];\n if (typeof entry !== \"string\" || entry.trim().length === 0) {\n throw new TypeError(\n `mcp(): auth.token[${i}] must be a non-empty string`,\n );\n }\n }\n }\n return new McpDestinationAdapter(clientOpts);\n }\n\n // Client: \"server:tool\" string with optional args\n const isClientColonOptions =\n options === undefined ||\n (typeof options === \"object\" &&\n options !== null &&\n !(\"description\" in options));\n if (\n typeof endpointOrOptions === \"string\" &&\n endpointOrOptions.includes(\":\") &&\n isClientColonOptions\n ) {\n const colonIndex = endpointOrOptions.indexOf(\":\");\n const serverId = endpointOrOptions.slice(0, colonIndex);\n const tool = endpointOrOptions.slice(colonIndex + 1);\n const clientOptions: McpClientOptions = { serverId, tool };\n if (\n options !== undefined &&\n typeof options === \"object\" &&\n \"args\" in options &&\n options.args !== undefined\n ) {\n clientOptions.args = options.args as McpArgsExtractor;\n }\n return new McpDestinationAdapter(clientOptions);\n }\n\n // Server: endpoint + options with description\n const endpoint = endpointOrOptions as\n | string\n | ((exchange: Exchange<McpMessage<S>>) => string);\n if (options !== undefined) {\n return new McpSourceAdapter<S>(\n endpoint as string,\n options as McpServerOptions & { schema?: S },\n );\n }\n\n // Invalid: endpoint only (no options) — direct not supported\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp() with only an endpoint is not supported. Use direct('endpoint') for in-process. For MCP server use .from(mcp('endpoint', { description: '...' })); for client use .to(mcp({ url, tool })) or .to(mcp('server:tool', { args })).\",\n suggestion:\n \"Use .from(mcp('endpoint', { description: '...' })) or .to(mcp({ url, tool })) or direct('endpoint').\",\n });\n}\n\n// Re-export types for public API\nexport type {\n McpMessage,\n McpArgsExtractor,\n McpClientHttpConfig,\n} from \"./types\";\nexport { BRAND_MCP_ADAPTER } from \"./shared\";\nexport { defaultArgs } from \"./destination\";\n","import { createHmac, createVerify, timingSafeEqual } from \"node:crypto\";\nimport type { AuthPrincipal, McpHttpAuthOptions } from \"./types.ts\";\n\n/**\n * Supported HMAC algorithms for JWT signature verification.\n * Maps JWT `alg` header values to Node.js `crypto.createHmac` digest names.\n */\nconst HMAC_ALGORITHMS = {\n HS256: \"sha256\",\n HS384: \"sha384\",\n HS512: \"sha512\",\n} as const;\n\n/**\n * Supported RSA algorithms for JWT signature verification.\n * Maps JWT `alg` header values to Node.js `crypto.createVerify` algorithm names.\n */\nconst RSA_ALGORITHMS = {\n RS256: \"RSA-SHA256\",\n RS384: \"RSA-SHA384\",\n RS512: \"RSA-SHA512\",\n} as const;\n\ntype HmacAlgorithm = keyof typeof HMAC_ALGORITHMS;\ntype RsaAlgorithm = keyof typeof RSA_ALGORITHMS;\n\n/**\n * HMAC (symmetric) JWT options.\n * Uses a shared secret to sign and verify tokens.\n *\n * @experimental\n */\nexport interface JwtHmacOptions {\n /** Shared secret used to verify HMAC signatures. */\n secret: string;\n /**\n * HMAC algorithm to accept. Default: `\"HS256\"`.\n * The helper rejects tokens whose `alg` header does not match.\n */\n algorithm?: HmacAlgorithm;\n /**\n * Clock skew tolerance in seconds for `exp` and `nbf` checks.\n * Default: `0` (no tolerance).\n */\n clockToleranceSec?: number;\n}\n\n/**\n * RSA (asymmetric) JWT options.\n * Uses a public key to verify signatures. Only the public key is needed\n * since the server only verifies, never signs.\n *\n * @experimental\n */\nexport interface JwtRsaOptions {\n /** PEM-encoded public key or certificate used to verify RSA signatures. */\n publicKey: string;\n /**\n * RSA algorithm to accept. Default: `\"RS256\"`.\n * The helper rejects tokens whose `alg` header does not match.\n */\n algorithm?: RsaAlgorithm;\n /**\n * Clock skew tolerance in seconds for `exp` and `nbf` checks.\n * Default: `0` (no tolerance).\n */\n clockToleranceSec?: number;\n}\n\n/**\n * Options for the built-in JWT auth helper.\n * Supports HMAC (symmetric) and RSA (asymmetric) signing.\n *\n * Discriminated by key: pass `secret` for HMAC, `publicKey` for RSA.\n *\n * @experimental\n */\nexport type JwtAuthOptions = JwtHmacOptions | JwtRsaOptions;\n\n/**\n * Decode and parse the JWT header and payload segments.\n * Returns `null` if the token is malformed or not valid JSON.\n */\nfunction decodeToken(token: string): {\n headerB64: string;\n payloadB64: string;\n signatureB64: string;\n header: Record<string, unknown>;\n payload: Record<string, unknown>;\n} | null {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const [headerB64, payloadB64, signatureB64] = parts;\n\n try {\n const header = JSON.parse(\n Buffer.from(headerB64, \"base64url\").toString(),\n ) as Record<string, unknown>;\n const payload = JSON.parse(\n Buffer.from(payloadB64, \"base64url\").toString(),\n ) as Record<string, unknown>;\n return { headerB64, payloadB64, signatureB64, header, payload };\n } catch {\n return null;\n }\n}\n\n/**\n * Check `exp` and `nbf` temporal claims.\n * Returns `true` if the token is within valid time bounds.\n */\nfunction checkTemporalClaims(\n payload: Record<string, unknown>,\n clockToleranceSec: number,\n): boolean {\n const now = Math.floor(Date.now() / 1000);\n\n if (typeof payload[\"exp\"] === \"number\") {\n if (now > payload[\"exp\"] + clockToleranceSec) return false;\n }\n if (typeof payload[\"nbf\"] === \"number\") {\n if (now < payload[\"nbf\"] - clockToleranceSec) return false;\n }\n return true;\n}\n\n/**\n * Build an {@link AuthPrincipal} from standard JWT claims.\n * Returns `null` if the `sub` claim is missing or empty.\n */\nfunction buildPrincipal(\n payload: Record<string, unknown>,\n): AuthPrincipal | null {\n const sub = payload[\"sub\"];\n if (typeof sub !== \"string\" || sub.length === 0) return null;\n\n const principal: AuthPrincipal = {\n subject: sub,\n scheme: \"bearer\",\n claims: payload,\n };\n\n if (typeof payload[\"iss\"] === \"string\") principal.issuer = payload[\"iss\"];\n if (typeof payload[\"exp\"] === \"number\") principal.expiresAt = payload[\"exp\"];\n if (typeof payload[\"email\"] === \"string\") principal.email = payload[\"email\"];\n if (typeof payload[\"name\"] === \"string\") principal.name = payload[\"name\"];\n\n const aud = payload[\"aud\"];\n if (Array.isArray(aud))\n principal.audience = aud.filter((a): a is string => typeof a === \"string\");\n else if (typeof aud === \"string\") principal.audience = [aud];\n\n const scope = payload[\"scope\"];\n if (typeof scope === \"string\")\n principal.scopes = scope.split(\" \").filter(Boolean);\n\n if (Array.isArray(payload[\"roles\"]))\n principal.roles = (payload[\"roles\"] as unknown[]).filter(\n (r): r is string => typeof r === \"string\",\n );\n\n return principal;\n}\n\n/** Type guard: options contain `secret` (HMAC). */\nfunction isHmac(options: JwtAuthOptions): options is JwtHmacOptions {\n return \"secret\" in options;\n}\n\n/**\n * Create an HMAC signature verifier.\n */\nfunction createHmacValidator(\n options: JwtHmacOptions,\n): (token: string) => AuthPrincipal | null {\n const { secret, algorithm = \"HS256\", clockToleranceSec = 0 } = options;\n\n if (!secret || typeof secret !== \"string\") {\n throw new TypeError(\"jwt: secret must be a non-empty string\");\n }\n if (!(algorithm in HMAC_ALGORITHMS)) {\n throw new TypeError(\n `jwt: unsupported algorithm \"${algorithm}\". Supported: ${Object.keys(HMAC_ALGORITHMS).join(\", \")}`,\n );\n }\n\n const digest = HMAC_ALGORITHMS[algorithm];\n\n return (token: string): AuthPrincipal | null => {\n const decoded = decodeToken(token);\n if (!decoded) return null;\n\n const { headerB64, payloadB64, signatureB64, header, payload } = decoded;\n\n if (header[\"alg\"] !== algorithm) return null;\n\n const hmac = createHmac(digest, secret);\n hmac.update(`${headerB64}.${payloadB64}`);\n const expectedSig = hmac.digest(\"base64url\");\n\n const expectedBuf = Buffer.from(expectedSig);\n const actualBuf = Buffer.from(signatureB64);\n if (\n expectedBuf.length !== actualBuf.length ||\n !timingSafeEqual(expectedBuf, actualBuf)\n ) {\n return null;\n }\n\n if (!checkTemporalClaims(payload, clockToleranceSec)) return null;\n return buildPrincipal(payload);\n };\n}\n\n/**\n * Create an RSA signature verifier.\n */\nfunction createRsaValidator(\n options: JwtRsaOptions,\n): (token: string) => AuthPrincipal | null {\n const { publicKey, algorithm = \"RS256\", clockToleranceSec = 0 } = options;\n\n if (!publicKey || typeof publicKey !== \"string\") {\n throw new TypeError(\"jwt: publicKey must be a non-empty PEM string\");\n }\n if (!(algorithm in RSA_ALGORITHMS)) {\n throw new TypeError(\n `jwt: unsupported algorithm \"${algorithm}\". Supported: ${Object.keys(RSA_ALGORITHMS).join(\", \")}`,\n );\n }\n\n const verifyAlgorithm = RSA_ALGORITHMS[algorithm];\n\n return (token: string): AuthPrincipal | null => {\n const decoded = decodeToken(token);\n if (!decoded) return null;\n\n const { headerB64, payloadB64, signatureB64, header, payload } = decoded;\n\n if (header[\"alg\"] !== algorithm) return null;\n\n const verifier = createVerify(verifyAlgorithm);\n verifier.update(`${headerB64}.${payloadB64}`);\n\n if (!verifier.verify(publicKey, signatureB64, \"base64url\")) {\n return null;\n }\n\n if (!checkTemporalClaims(payload, clockToleranceSec)) return null;\n return buildPrincipal(payload);\n };\n}\n\n/**\n * Built-in JWT authentication helper for MCP HTTP servers.\n * Verifies HMAC or RSA signed JWTs using only `node:crypto` (no external\n * dependencies).\n *\n * Returns an {@link McpHttpAuthOptions} that can be passed directly to\n * `mcpPlugin({ auth: jwt({ ... }) })`.\n *\n * On success the validator returns an {@link AuthPrincipal} populated from\n * standard JWT claims (`sub`, `iss`, `aud`, `exp`, `scope`, etc.) with the\n * full decoded payload available in `claims`.\n *\n * @example\n * ```ts\n * import { mcpPlugin, jwt } from \"@routecraft/ai\";\n *\n * // HMAC (symmetric) - shared secret\n * mcpPlugin({\n * transport: \"http\",\n * auth: jwt({ secret: process.env.JWT_SECRET! }),\n * });\n *\n * // RSA (asymmetric) - public key only\n * mcpPlugin({\n * transport: \"http\",\n * auth: jwt({ algorithm: \"RS256\", publicKey: process.env.JWT_PUBLIC_KEY! }),\n * });\n * ```\n *\n * @experimental\n */\nexport function jwt(options: JwtAuthOptions): McpHttpAuthOptions {\n const validator = isHmac(options)\n ? createHmacValidator(options)\n : createRsaValidator(options);\n\n return { validator };\n}\n","import type { CraftContext, DirectRouteMetadata } from \"@routecraft/routecraft\";\nimport {\n ADAPTER_DIRECT_REGISTRY,\n ADAPTER_DIRECT_STORE,\n DefaultExchange,\n isRoutecraftError,\n} from \"@routecraft/routecraft\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createServer } from \"node:http\";\nimport type { IncomingMessage } from \"node:http\";\nimport { McpHeadersKeys } from \"./types.ts\";\nimport type {\n AuthPrincipal,\n McpHttpAuthOptions,\n McpPluginOptions,\n} from \"./types.ts\";\n\n/**\n * Request-scoped storage for the authenticated principal.\n * Set in the HTTP request handler after auth validation;\n * read in handleToolCall to populate exchange headers.\n */\nconst principalStore = new AsyncLocalStorage<AuthPrincipal | undefined>();\n\nconst MCP_SDK_INSTALL =\n 'MCP server requires \"@modelcontextprotocol/sdk\". Install it with: pnpm add @modelcontextprotocol/sdk';\n\n/** Resolved options with defaults applied (internal use). */\ntype McpServerResolvedOptions = Required<\n Pick<McpPluginOptions, \"name\" | \"version\" | \"transport\" | \"port\" | \"host\">\n> &\n Pick<McpPluginOptions, \"tools\" | \"auth\">;\n\n/**\n * McpServer wraps the MCP SDK and bridges it to Routecraft's DirectChannel infrastructure.\n * It reads the MCP route registry lazily (on first tools/list request) to ensure routes have subscribed.\n *\n * Note: Uses dynamic imports to avoid TypeScript compatibility issues with the MCP SDK.\n * Supports both stdio and streamable-http transports.\n *\n * @experimental\n */\nexport class McpServer {\n private context: CraftContext;\n private options: McpServerResolvedOptions;\n private server: unknown = null;\n private transport: unknown = null;\n /** Node HTTP server when transport is http; used to listen on port and close on stop. */\n private httpServer: ReturnType<typeof createServer> | null = null;\n /** Active HTTP sessions keyed by session ID (each session has its own server+transport pair). */\n private httpSessions = new Map<\n string,\n { server: unknown; transport: unknown }\n >();\n private running = false;\n private toolsListLogged = false;\n\n constructor(context: CraftContext, options: McpPluginOptions = {}) {\n this.context = context;\n this.options = {\n name: \"routecraft\",\n version: \"1.0.0\",\n transport: \"stdio\",\n port: 3001,\n host: \"localhost\",\n ...options,\n };\n }\n\n /**\n * Start the MCP server and listen for connections\n */\n async start(): Promise<void> {\n if (this.running) {\n this.context.logger.warn({}, \"MCP server already running\");\n return;\n }\n\n try {\n const transport = this.options.transport;\n\n if (transport === \"http\") {\n await this.startHttp();\n } else {\n await this.startStdio();\n }\n\n this.running = true;\n this.context.logger.info(\n {\n name: this.options.name,\n version: this.options.version,\n transport,\n },\n \"MCP server started\",\n );\n this.logExposedToolsOnce();\n } catch (error) {\n const msg = isRoutecraftError(error)\n ? (error as unknown as { meta: { message: string } }).meta.message\n : error instanceof Error\n ? error.message\n : \"Failed to start MCP server\";\n this.context.logger.error({ err: error }, msg);\n throw error;\n }\n }\n\n /**\n * Start stdio transport\n */\n private async startStdio(): Promise<void> {\n let Server: new (\n info: { name: string; version: string },\n options: { capabilities: { tools: Record<string, unknown> } },\n ) => unknown;\n let StdioServerTransport: new () => unknown;\n try {\n const serverMod =\n await import(\"@modelcontextprotocol/sdk/server/index.js\");\n Server = serverMod.Server;\n const stdioMod =\n await import(\"@modelcontextprotocol/sdk/server/stdio.js\");\n StdioServerTransport = stdioMod.StdioServerTransport;\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n\n this.server = new Server(\n {\n name: this.options.name,\n version: this.options.version,\n },\n { capabilities: { tools: {} } },\n );\n\n await this.setupRequestHandlers();\n\n this.transport = new StdioServerTransport();\n const srvWithConnect = this.server as Record<\n string,\n (transport: unknown) => Promise<void>\n >;\n await srvWithConnect[\"connect\"](this.transport);\n }\n\n /**\n * Start HTTP transport (streamable-http).\n * Creates a Node HTTP server that manages per-session MCP server+transport pairs.\n * Each client session (identified by the `mcp-session-id` header) gets its own\n * Server and StreamableHTTPServerTransport so that reconnecting clients can\n * establish fresh sessions without restarting the process.\n */\n private async startHttp(): Promise<void> {\n let ServerCtor: new (\n info: { name: string; version: string },\n options: { capabilities: { tools: Record<string, unknown> } },\n ) => unknown;\n try {\n const serverModule =\n await import(\"@modelcontextprotocol/sdk/server/index.js\");\n ServerCtor = serverModule.Server;\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n\n const streamableModule =\n await import(\"@modelcontextprotocol/sdk/server/streamableHttp.js\").catch(\n () => null,\n );\n const TransportClass = (\n streamableModule as Record<string, unknown> | null\n )?.[\"StreamableHTTPServerTransport\"] as\n | (new (options?: {\n sessionIdGenerator?: () => string;\n onsessioninitialized?: (sessionId: string) => void;\n enableJsonResponse?: boolean;\n }) => unknown)\n | undefined;\n\n if (!TransportClass) {\n throw new Error(\n \"StreamableHTTPServerTransport not found in MCP SDK - ensure @modelcontextprotocol/sdk v1.26.0+ is installed\",\n );\n }\n\n const port = this.options.port;\n const host = this.options.host;\n\n /**\n * Creates a new MCP Server + Transport pair for a single session.\n * Called on every initialization request (no session ID header).\n */\n const createSession = async (): Promise<{\n transport: unknown;\n handleRequest: (\n req: unknown,\n res: unknown,\n parsedBody?: unknown,\n ) => Promise<void>;\n }> => {\n const server = new ServerCtor(\n { name: this.options.name, version: this.options.version },\n { capabilities: { tools: {} } },\n );\n\n // Wire up request handlers on this server instance.\n await this.setupRequestHandlersOn(server);\n\n const transport = new TransportClass({\n sessionIdGenerator: () => crypto.randomUUID(),\n onsessioninitialized: (sessionId: string) => {\n this.httpSessions.set(sessionId, { server, transport });\n this.context.logger.debug({ sessionId }, \"MCP session created\");\n this.context.emit(\"plugin:mcp:session:created\", { sessionId });\n },\n enableJsonResponse: true,\n });\n\n const srvWithConnect = server as Record<\n string,\n (t: unknown) => Promise<void>\n >;\n await srvWithConnect[\"connect\"](transport);\n\n // Clean up on transport close so the session map does not leak.\n const tr = transport as Record<string, unknown>;\n const prevOnClose = tr[\"onclose\"] as (() => void) | undefined;\n tr[\"onclose\"] = () => {\n const sid = (transport as { sessionId?: string }).sessionId;\n if (sid) {\n this.httpSessions.delete(sid);\n this.context.logger.debug({ sessionId: sid }, \"MCP session closed\");\n this.context.emit(\"plugin:mcp:session:closed\", {\n sessionId: sid,\n });\n }\n prevOnClose?.();\n };\n\n const handleRequest = (\n transport as Record<\n string,\n (req: unknown, res: unknown, parsedBody?: unknown) => Promise<void>\n >\n )[\"handleRequest\"];\n if (typeof handleRequest !== \"function\") {\n throw new Error(\n \"StreamableHTTPServerTransport.handleRequest not found - SDK may have changed\",\n );\n }\n\n return {\n transport,\n handleRequest: handleRequest.bind(transport) as (\n req: unknown,\n res: unknown,\n parsedBody?: unknown,\n ) => Promise<void>,\n };\n };\n\n this.httpServer = createServer(async (req, res) => {\n const url = req.url?.split(\"?\")[0] ?? \"\";\n if (url !== \"/mcp\" && url !== \"/mcp/\") {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not Found\", path: url }));\n return;\n }\n // Resolve principal when auth is configured; skip for unauthenticated servers.\n let principal: AuthPrincipal | undefined;\n if (this.options.auth) {\n const result = await this.validateAuth(req);\n if (!result) {\n res.writeHead(401, {\n \"Content-Type\": \"application/json\",\n \"WWW-Authenticate\": 'Bearer realm=\"mcp\"',\n });\n res.end(JSON.stringify({ error: \"Unauthorized\" }));\n return;\n }\n principal = result;\n }\n\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n // Run the SDK handler inside AsyncLocalStorage so handleToolCall\n // can read the principal without threading it through the SDK.\n const runWithPrincipal = <T>(fn: () => Promise<T>): Promise<T> =>\n principalStore.run(principal, fn);\n\n try {\n if (sessionId && this.httpSessions.has(sessionId)) {\n // Existing session: route to the corresponding transport.\n const session = this.httpSessions.get(sessionId)!;\n const hr = (\n session.transport as Record<\n string,\n (\n req: unknown,\n res: unknown,\n parsedBody?: unknown,\n ) => Promise<void>\n >\n )[\"handleRequest\"];\n await runWithPrincipal(() => hr.call(session.transport, req, res));\n } else if (!sessionId || req.method === \"POST\") {\n // No session ID or unknown session on POST: create a new session.\n // The SDK will respond with 400 for non-initialize requests without a\n // session ID, so it is safe to always create a session here and let\n // the SDK enforce protocol rules.\n const { handleRequest } = await createSession();\n await runWithPrincipal(() => handleRequest(req, res));\n } else {\n // GET/DELETE with unknown session ID: reject.\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Session not found\" }));\n }\n } catch (err) {\n const msg = isRoutecraftError(err)\n ? (err as unknown as { meta: { message: string } }).meta.message\n : err instanceof Error\n ? err.message\n : \"MCP HTTP request error\";\n this.context.logger.error({ err }, msg);\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Internal Server Error\" }));\n }\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n this.httpServer!.listen(port, host, () => resolve());\n this.httpServer!.on(\"error\", (err) => {\n const msg = isRoutecraftError(err)\n ? (err as unknown as { meta: { message: string } }).meta.message\n : err instanceof Error\n ? err.message\n : \"MCP HTTP server listen failed\";\n this.context.logger.error({ err }, msg);\n reject(err);\n });\n });\n\n const boundPort = this.getHttpPort() ?? port;\n const listenDetail = { host, port: boundPort, path: \"/mcp\" };\n this.context.logger.info(listenDetail, \"MCP HTTP server listening\");\n this.context.emit(\"plugin:mcp:server:listening\", listenDetail);\n }\n\n /**\n * When transport is http, returns the bound port (useful when port 0 was used). Otherwise undefined.\n */\n getHttpPort(): number | undefined {\n const addr = this.httpServer?.address();\n if (addr && typeof addr === \"object\" && \"port\" in addr) {\n return (addr as { port: number }).port;\n }\n return undefined;\n }\n\n /**\n * Validate the Authorization header using the configured validator.\n * Returns the authenticated principal on success, or `null` to reject with 401.\n */\n private async validateAuth(\n req: IncomingMessage,\n ): Promise<AuthPrincipal | null> {\n const authOptions = this.options.auth as McpHttpAuthOptions | undefined;\n if (!authOptions) return null;\n\n const rawHeader = req.headers[\"authorization\"];\n if (!rawHeader || Array.isArray(rawHeader)) {\n const detail = {\n reason: \"missing_header\",\n scheme: \"bearer\",\n source: \"mcp\",\n };\n this.context.logger.warn(\n detail,\n \"Auth rejected: missing or malformed Authorization header\",\n );\n this.context.emit(\"auth:rejected\", detail);\n return null;\n }\n\n const schemeMatch = /^bearer\\s+(.+)$/i.exec(rawHeader);\n if (!schemeMatch) {\n const detail = {\n reason: \"unsupported_scheme\",\n scheme: \"bearer\",\n source: \"mcp\",\n };\n this.context.logger.warn(\n detail,\n \"Auth rejected: unsupported authorization scheme\",\n );\n this.context.emit(\"auth:rejected\", detail);\n return null;\n }\n const token = schemeMatch[1];\n\n // Delegate to the validator. It must return an AuthPrincipal on success\n // or null/false to reject. Throws propagate as 500.\n const result = await authOptions.validator(token);\n if (!result) {\n const detail = {\n reason: \"invalid_token\",\n scheme: \"bearer\",\n source: \"mcp\",\n };\n this.context.logger.warn(\n detail,\n \"Auth rejected: token validation failed\",\n );\n this.context.emit(\"auth:rejected\", detail);\n return null;\n }\n\n const successDetail = {\n subject: result.subject,\n scheme: result.scheme,\n source: \"mcp\",\n };\n this.context.logger.info(successDetail, \"Auth succeeded\");\n this.context.emit(\"auth:success\", successDetail);\n return result;\n }\n\n /**\n * Set up request handlers on this.server (used by stdio transport).\n */\n private async setupRequestHandlers(): Promise<void> {\n await this.setupRequestHandlersOn(this.server);\n }\n\n /**\n * Set up request handlers on the given server instance.\n * Uses SDK request schemas so setRequestHandler receives a proper schema (method literal).\n */\n private async setupRequestHandlersOn(server: unknown): Promise<void> {\n let typesModule: Record<string, unknown>;\n try {\n typesModule =\n (await import(\"@modelcontextprotocol/sdk/types.js\")) as Record<\n string,\n unknown\n >;\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n const t = typesModule;\n const ListToolsRequestSchema = t[\"ListToolsRequestSchema\"];\n const CallToolRequestSchema = t[\"CallToolRequestSchema\"];\n\n if (!ListToolsRequestSchema || !CallToolRequestSchema) {\n throw new Error(\n \"MCP SDK types missing ListToolsRequestSchema or CallToolRequestSchema - ensure @modelcontextprotocol/sdk is installed\",\n );\n }\n\n const srv = server as Record<\n string,\n (schema: unknown, handler: (request: unknown) => Promise<unknown>) => void\n >;\n\n srv[\"setRequestHandler\"](ListToolsRequestSchema, async () => {\n const tools = this.getAvailableTools();\n this.logExposedToolsOnce();\n return { tools };\n });\n\n srv[\"setRequestHandler\"](\n CallToolRequestSchema,\n async (request: unknown) => {\n const req = request as Record<string, unknown>;\n const params = req[\"params\"] as Record<string, unknown>;\n return await this.handleToolCall(\n (params[\"name\"] as string) || \"\",\n (params[\"arguments\"] as Record<string, unknown>) || {},\n );\n },\n );\n }\n\n /**\n * Stop the MCP server\n */\n async stop(): Promise<void> {\n if (!this.running) {\n return;\n }\n\n try {\n if (this.httpServer) {\n // Close all active HTTP sessions.\n for (const [, session] of this.httpSessions) {\n const tr = session.transport as Record<string, () => Promise<void>>;\n if (typeof tr[\"close\"] === \"function\") {\n await tr[\"close\"]();\n }\n }\n this.httpSessions.clear();\n\n await new Promise<void>((resolve) => {\n this.httpServer!.close(() => resolve());\n });\n this.httpServer = null;\n }\n if (this.transport) {\n const tr = this.transport as Record<string, () => Promise<void>>;\n if (typeof tr[\"close\"] === \"function\") {\n await tr[\"close\"]();\n }\n }\n this.running = false;\n this.context.logger.info({}, \"MCP server stopped\");\n } catch (error) {\n const msg = isRoutecraftError(error)\n ? (error as unknown as { meta: { message: string } }).meta.message\n : error instanceof Error\n ? error.message\n : \"Error stopping MCP server\";\n this.context.logger.error({ err: error }, msg);\n }\n }\n\n /**\n * Log exposed MCP tool names once (at start or on first tools/list).\n */\n private logExposedToolsOnce(): void {\n if (this.toolsListLogged) return;\n const tools = this.getAvailableTools();\n if (tools.length === 0) return;\n const names = tools.map((t) => (t[\"name\"] as string) ?? \"?\");\n const exposedDetail = { tools: names, count: names.length };\n this.context.logger.info(exposedDetail, \"Exposing MCP tools\");\n this.context.emit(\"plugin:mcp:server:tools:exposed\", exposedDetail);\n this.toolsListLogged = true;\n }\n\n /**\n * Get list of tools that should be exposed via MCP.\n * Reads the registry lazily - called on every tools/list request and for tests.\n */\n getAvailableTools(): Array<Record<string, unknown>> {\n const registry = this.context.getStore(ADAPTER_DIRECT_REGISTRY) as\n | Map<string, DirectRouteMetadata>\n | undefined;\n\n if (!registry) {\n return [];\n }\n\n // Get all mcp() routes (those with description)\n let tools = Array.from(registry.values()).filter(\n (t) => t.description !== undefined,\n );\n\n // Apply user filter if provided\n const toolsFilter = this.options.tools;\n if (toolsFilter) {\n if (Array.isArray(toolsFilter)) {\n const allowed = new Set(toolsFilter);\n tools = tools.filter((t) => allowed.has(t.endpoint));\n } else if (typeof toolsFilter === \"function\") {\n tools = tools.filter(toolsFilter);\n }\n }\n\n // Convert to MCP tool format\n return tools.map((meta) => this.metadataToMcpTool(meta));\n }\n\n /**\n * Convert Routecraft mcp() route metadata to MCP tool format\n */\n private metadataToMcpTool(\n metadata: DirectRouteMetadata,\n ): Record<string, unknown> {\n return {\n name: metadata.endpoint,\n description: metadata.description || \"\",\n inputSchema: this.schemaToJsonSchema(metadata.schema),\n };\n }\n\n /**\n * Convert to JSON Schema using Standard JSON Schema (schema['~standard'].jsonSchema.input)\n * when available; otherwise return a generic object schema.\n * Works with any spec-compliant library (Zod 4.2+, ArkType, Valibot via toStandardJsonSchema).\n */\n private schemaToJsonSchema(schema: unknown): Record<string, unknown> {\n if (!schema || typeof schema !== \"object\") {\n return { type: \"object\" };\n }\n\n const standard = (schema as Record<string, unknown>)[\"~standard\"] as\n | {\n jsonSchema?: {\n input?: (opts: { target: string }) => Record<string, unknown>;\n };\n }\n | undefined;\n if (standard?.jsonSchema?.input) {\n try {\n const out = standard.jsonSchema.input({\n target: \"draft-2020-12\",\n });\n return typeof out === \"object\" && out !== null\n ? out\n : { type: \"object\" };\n } catch (error) {\n this.context.logger.debug(\n error,\n \"Standard JSON Schema conversion failed\",\n );\n return { type: \"object\" };\n }\n }\n\n if (\"~standard\" in schema) {\n return { type: \"object\", additionalProperties: true };\n }\n return { type: \"object\" };\n }\n\n /**\n * Handle a tool call from MCP client\n */\n private async handleToolCall(\n toolName: string,\n args: Record<string, unknown>,\n ): Promise<{\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n }> {\n try {\n // Get the direct channel store\n const channelStore = this.context.getStore(ADAPTER_DIRECT_STORE) as\n | Map<string, Record<string, unknown>>\n | undefined;\n\n if (!channelStore) {\n const err = new Error(\"No direct channels available\");\n this.context.emit(`plugin:mcp:tool:failed`, {\n tool: toolName,\n error: err.message,\n });\n return {\n isError: true,\n content: [\n { type: \"text\", text: `Error: No direct channels available` },\n ],\n };\n }\n\n // Get the channel for this tool endpoint\n const channel = channelStore.get(toolName);\n if (!channel) {\n const err = new Error(`Tool not found: ${toolName}`);\n this.context.emit(`plugin:mcp:tool:failed`, {\n tool: toolName,\n error: err.message,\n });\n return {\n isError: true,\n content: [\n { type: \"text\", text: `Error: Tool not found: ${toolName}` },\n ],\n };\n }\n\n // Ensure body is an object when client sends JSON (SDK may pass parsed object or raw string)\n const body =\n typeof args === \"string\"\n ? (() => {\n try {\n return (JSON.parse(args) as Record<string, unknown>) || {};\n } catch {\n return { input: args };\n }\n })()\n : args && typeof args === \"object\"\n ? args\n : {};\n\n this.context.logger.debug(\n { bodyType: typeof body, body },\n \"MCP tool call exchange body\",\n );\n\n // Build exchange headers, including auth principal if present.\n const principal = principalStore.getStore();\n const headers: Record<string, string | string[] | undefined> = {\n [McpHeadersKeys.TOOL]: toolName,\n [McpHeadersKeys.SESSION]: `mcp-${Date.now()}`,\n };\n if (principal) {\n headers[McpHeadersKeys.AUTH_SUBJECT] = principal.subject;\n headers[McpHeadersKeys.AUTH_SCHEME] = principal.scheme;\n if (principal.roles)\n headers[McpHeadersKeys.AUTH_ROLES] = principal.roles;\n if (principal.scopes)\n headers[McpHeadersKeys.AUTH_SCOPES] = principal.scopes;\n if (principal.email)\n headers[McpHeadersKeys.AUTH_EMAIL] = principal.email;\n if (principal.name) headers[McpHeadersKeys.AUTH_NAME] = principal.name;\n if (principal.issuer)\n headers[McpHeadersKeys.AUTH_ISSUER] = principal.issuer;\n if (principal.audience)\n headers[McpHeadersKeys.AUTH_AUDIENCE] = principal.audience;\n }\n\n const exchange = new DefaultExchange(this.context, {\n body,\n headers,\n });\n\n this.context.emit(`plugin:mcp:tool:called`, {\n tool: toolName,\n args,\n });\n\n // Send the exchange through the direct channel\n const channelTyped = channel as Record<\n string,\n (name: string, ex: unknown) => Promise<unknown>\n >;\n const resultExchange = (await channelTyped[\"send\"](\n toolName,\n exchange,\n )) as Record<string, unknown>;\n\n // Convert result to MCP format\n const resultText =\n typeof resultExchange[\"body\"] === \"string\"\n ? (resultExchange[\"body\"] as string)\n : JSON.stringify(resultExchange[\"body\"]);\n\n this.context.emit(`plugin:mcp:tool:completed`, {\n tool: toolName,\n });\n\n return {\n content: [{ type: \"text\", text: resultText }],\n };\n } catch (error) {\n const logMsg = isRoutecraftError(error)\n ? (error as unknown as { meta: { message: string } }).meta.message\n : error instanceof Error\n ? error.message\n : String(error);\n this.context.logger.error({ tool: toolName, err: error }, logMsg);\n this.context.emit(`plugin:mcp:tool:failed`, {\n tool: toolName,\n error: logMsg,\n });\n\n // Build a clean user-facing message: include the cause (e.g. schema\n // field errors) but never expose stack traces or internal details.\n let userMsg = logMsg;\n if (isRoutecraftError(error)) {\n const cause = (error as { cause?: Error }).cause;\n if (cause?.message) {\n userMsg = `${logMsg}: ${cause.message}`;\n }\n }\n\n return {\n content: [{ type: \"text\", text: `Error: ${userMsg}` }],\n isError: true,\n };\n }\n }\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { formatSchemaIssues } from \"@routecraft/routecraft\";\nimport type { McpPluginOptions } from \"./types.ts\";\n\n/** Standard Schema validate result: success has value, failure has issues. */\ntype ValidateResult<T = unknown> =\n | { value: T; issues?: never }\n | { value?: never; issues: readonly unknown[] };\n\n/**\n * Validates MCP plugin options at apply time.\n * For full schema validation (required props, shape), use validateWithSchema() with a\n * StandardSchemaV1 from Zod, Valibot, or ArkType before calling mcpPlugin().\n */\nexport function validateMcpPluginOptions(options: McpPluginOptions): void {\n if (options.transport === \"http\") {\n if (options.port !== undefined) {\n if (typeof options.port !== \"number\") {\n throw new TypeError(\n \"mcpPlugin: when transport is 'http', port must be a number\",\n );\n }\n if (options.port < 0 || options.port > 65535) {\n throw new RangeError(\n \"mcpPlugin: port must be between 0 and 65535 when transport is 'http'\",\n );\n }\n }\n if (options.host !== undefined && typeof options.host !== \"string\") {\n throw new TypeError(\"mcpPlugin: when provided, host must be a string\");\n }\n }\n\n // Validate auth options\n if (options.auth !== undefined) {\n if (typeof options.auth.validator !== \"function\") {\n throw new TypeError(\n \"mcpPlugin: auth.validator must be a function that returns an AuthPrincipal or null\",\n );\n }\n }\n\n // Validate stdio client configs\n if (options.clients) {\n for (const [name, config] of Object.entries(options.clients)) {\n if (\n typeof config === \"object\" &&\n config !== null &&\n \"transport\" in config &&\n config.transport === \"stdio\"\n ) {\n if (!config.command || typeof config.command !== \"string\") {\n throw new TypeError(\n `mcpPlugin: stdio client \"${name}\" must have a non-empty command string`,\n );\n }\n }\n }\n }\n\n // Validate restart options\n if (options.maxRestarts !== undefined) {\n if (\n typeof options.maxRestarts !== \"number\" ||\n !Number.isInteger(options.maxRestarts) ||\n options.maxRestarts < 0\n ) {\n throw new TypeError(\n \"mcpPlugin: maxRestarts must be a non-negative integer\",\n );\n }\n }\n if (options.restartDelayMs !== undefined) {\n if (\n typeof options.restartDelayMs !== \"number\" ||\n options.restartDelayMs <= 0\n ) {\n throw new TypeError(\n \"mcpPlugin: restartDelayMs must be a positive number\",\n );\n }\n }\n if (options.restartBackoffMultiplier !== undefined) {\n if (\n typeof options.restartBackoffMultiplier !== \"number\" ||\n options.restartBackoffMultiplier < 1\n ) {\n throw new TypeError(\"mcpPlugin: restartBackoffMultiplier must be >= 1\");\n }\n }\n\n // Validate HTTP tool refresh interval\n if (options.toolRefreshIntervalMs !== undefined) {\n if (\n typeof options.toolRefreshIntervalMs !== \"number\" ||\n !Number.isInteger(options.toolRefreshIntervalMs) ||\n options.toolRefreshIntervalMs < 0\n ) {\n throw new TypeError(\n \"mcpPlugin: toolRefreshIntervalMs must be a non-negative integer\",\n );\n }\n }\n}\n\n/**\n * Validate plugin options with a StandardSchemaV1 (e.g. from Zod, Valibot, ArkType).\n * Use this when you need required props or full shape validation before mcpPlugin().\n *\n * @example\n * import { z } from \"zod\";\n * const schema = z.object({ transport: z.enum([\"stdio\", \"http\"]), port: z.number().optional() });\n * const validated = await validateWithSchema(options, schema);\n * mcpPlugin(validated);\n */\nexport async function validateWithSchema(\n options: McpPluginOptions,\n schema: StandardSchemaV1,\n): Promise<McpPluginOptions> {\n const standard = (\n schema as {\n \"~standard\"?: {\n validate: (\n v: unknown,\n ) => ValidateResult<unknown> | Promise<ValidateResult<unknown>>;\n };\n }\n )[\"~standard\"];\n if (!standard?.validate) {\n throw new Error(\n \"mcpPlugin: schema must be a StandardSchemaV1 with ~standard.validate\",\n );\n }\n let result = standard.validate(options);\n if (result instanceof Promise) {\n result = await result;\n }\n if (result.issues) {\n throw new Error(\n `mcpPlugin options validation failed: ${formatSchemaIssues(result.issues)}`,\n );\n }\n // Guard against schemas that pass (no issues) but omit value\n if (result.value === undefined) {\n throw new Error(\"mcpPlugin options validation failed: no value returned\");\n }\n return result.value as McpPluginOptions;\n}\n","import type { McpTool } from \"./types.ts\";\nimport { extractContent } from \"./extract-content.ts\";\n\nconst MCP_SDK_INSTALL =\n 'MCP stdio client requires \"@modelcontextprotocol/sdk\". Install it with: pnpm add @modelcontextprotocol/sdk';\n\nexport interface StdioClientManagerOptions {\n serverId: string;\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n maxRestarts: number;\n restartDelayMs: number;\n restartBackoffMultiplier: number;\n}\n\n/** Logger interface matching pino child logger shape used in Routecraft. */\ninterface Logger {\n info(obj: Record<string, unknown>, msg: string): void;\n warn(obj: Record<string, unknown>, msg: string): void;\n error(obj: Record<string, unknown>, msg: string): void;\n debug(obj: Record<string, unknown>, msg: string): void;\n}\n\n/** Typed subset of the MCP SDK Client used by StdioClientManager. */\ninterface McpSdkClient {\n connect(transport: unknown): Promise<void>;\n close(): Promise<void>;\n listTools(): Promise<{ tools: McpTool[] }>;\n callTool(params: {\n name: string;\n arguments?: Record<string, unknown>;\n }): Promise<{\n content?: Array<{ type: string; text?: string; data?: string }>;\n }>;\n}\n\n/**\n * Manages a single stdio MCP client subprocess.\n *\n * Delegates to the MCP SDK's Client + StdioClientTransport for process spawning,\n * protocol handling, and tool listing. Adds auto-restart with exponential backoff\n * and event bridging into Routecraft's event system.\n */\nexport class StdioClientManager {\n private client: McpSdkClient | null = null;\n private transport: unknown = null;\n private running = false;\n private stopping = false;\n private restartCount = 0;\n private restartTimer: ReturnType<typeof setTimeout> | null = null;\n private stabilityTimer: ReturnType<typeof setTimeout> | null = null;\n private tools: McpTool[] = [];\n\n /**\n * @param options - Subprocess command, restart policy, and server identity\n * @param logger - Logger matching the pino child logger shape\n * @param onEvent - Callback invoked for every lifecycle event\n * @param onToolsUpdated - Callback invoked whenever the tool list changes\n */\n constructor(\n private readonly options: StdioClientManagerOptions,\n private readonly logger: Logger,\n private readonly onEvent: (\n event: string,\n details: Record<string, unknown>,\n ) => void,\n private readonly onToolsUpdated: (\n serverId: string,\n tools: McpTool[],\n ) => void,\n ) {}\n\n /** Spawn the child process, perform the MCP handshake, and list initial tools. */\n async start(): Promise<void> {\n if (this.running) return;\n this.stopping = false;\n\n // Cancel any pending restart to avoid race with externally-initiated start\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n\n type SdkClientModule =\n typeof import(\"@modelcontextprotocol/sdk/client/index.js\");\n type SdkStdioModule =\n typeof import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n\n let clientMod: SdkClientModule;\n let stdioMod: SdkStdioModule;\n\n try {\n clientMod = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n stdioMod = await import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n\n const { serverId, command, args, env, cwd } = this.options;\n\n // Create transport (spawns child process)\n this.transport = new stdioMod.StdioClientTransport({\n command,\n args: args ?? [],\n ...(env ? { env } : {}),\n ...(cwd ? { cwd } : {}),\n stderr: \"pipe\",\n });\n\n // Wire up transport error/close handlers\n const transport = this.transport as {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n stderr: {\n on?: (event: string, cb: (data: unknown) => void) => void;\n } | null;\n };\n\n transport.onerror = (error: Error) => {\n this.logger.error(\n { err: error, serverId },\n \"Stdio client transport error\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:error`, {\n serverId,\n error,\n });\n };\n\n transport.onclose = () => {\n if (!this.stopping) {\n this.running = false;\n this.handleDisconnect();\n }\n };\n\n // Log stderr from child process\n if (transport.stderr?.on) {\n transport.stderr.on(\"data\", (data: unknown) => {\n this.logger.debug(\n { serverId, stderr: String(data).trimEnd() },\n \"Stdio client stderr output\",\n );\n });\n }\n\n // Create client with listChanged support for auto tool refresh\n this.client = new clientMod.Client(\n { name: \"routecraft-mcp-client\", version: \"1.0.0\" },\n {\n capabilities: {},\n listChanged: {\n tools: {\n onChanged: (_error: unknown, tools: unknown) => {\n if (\n tools &&\n Array.isArray((tools as { tools: unknown[] }).tools)\n ) {\n this.tools = (tools as { tools: McpTool[] }).tools;\n this.onToolsUpdated(serverId, this.tools);\n this.onEvent(`plugin:mcp:client:${serverId}:tools:listed`, {\n serverId,\n toolCount: this.tools.length,\n });\n } else {\n // Server notified of change but SDK couldn't fetch; re-list manually\n void this.refreshTools();\n }\n },\n },\n },\n },\n ) as unknown as McpSdkClient;\n\n // Connect (performs MCP initialize handshake)\n await this.client.connect(this.transport);\n\n this.running = true;\n\n // List initial tools\n await this.refreshTools();\n\n this.logger.info(\n { serverId, toolCount: this.tools.length },\n \"Stdio client started\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:started`, {\n serverId,\n toolCount: this.tools.length,\n });\n }\n\n /** Gracefully close the client and transport, cancelling any pending restart. */\n async stop(): Promise<void> {\n this.stopping = true;\n\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n if (this.stabilityTimer) {\n clearTimeout(this.stabilityTimer);\n this.stabilityTimer = null;\n }\n\n const { serverId } = this.options;\n\n if (this.client) {\n try {\n await this.client.close();\n } catch {\n // Ignore cleanup errors\n }\n this.client = null;\n }\n\n if (this.transport) {\n const transportWithClose = this.transport as {\n close?: () => void | Promise<void>;\n };\n if (typeof transportWithClose.close === \"function\") {\n try {\n await Promise.resolve(transportWithClose.close());\n } catch {\n // Ignore cleanup errors\n }\n }\n this.transport = null;\n }\n\n this.running = false;\n this.logger.info({ serverId }, \"Stdio client stopped\");\n this.onEvent(`plugin:mcp:client:${serverId}:stopped`, {\n serverId,\n reason: \"graceful\",\n });\n }\n\n /**\n * Call a tool on the remote MCP server.\n * Delegates to SDK Client.callTool().\n *\n * @param name - Tool name to invoke\n * @param args - Arguments passed to the tool\n * @returns The tool result (text content extracted when available)\n */\n async callTool(\n name: string,\n args: Record<string, unknown>,\n ): Promise<unknown> {\n if (!this.running || !this.client) {\n throw new Error(\n `Stdio client \"${this.options.serverId}\" is not running. Cannot call tool \"${name}\".`,\n );\n }\n\n const response = await this.client.callTool({\n name,\n arguments: args,\n });\n\n return extractContent(response);\n }\n\n /** @returns The current list of tools advertised by this server. */\n getTools(): McpTool[] {\n return [...this.tools];\n }\n\n /** @returns Whether the subprocess is connected and running. */\n isRunning(): boolean {\n return this.running;\n }\n\n private async refreshTools(): Promise<void> {\n if (!this.client) return;\n\n const { serverId } = this.options;\n\n try {\n const result = await this.client.listTools();\n this.tools = result.tools ?? [];\n this.onToolsUpdated(serverId, this.tools);\n this.onEvent(`plugin:mcp:client:${serverId}:tools:listed`, {\n serverId,\n toolCount: this.tools.length,\n });\n } catch (err) {\n this.logger.warn(\n { err, serverId },\n \"Failed to list tools for stdio client\",\n );\n }\n }\n\n private handleDisconnect(): void {\n const { serverId, maxRestarts, restartDelayMs, restartBackoffMultiplier } =\n this.options;\n\n // Clear stale tools so consumers don't see tools from a dead process\n if (this.tools.length > 0) {\n this.tools = [];\n this.onToolsUpdated(serverId, []);\n }\n\n this.logger.warn({ serverId }, \"Stdio client disconnected unexpectedly\");\n this.onEvent(`plugin:mcp:client:${serverId}:stopped`, {\n serverId,\n reason: \"unexpected\",\n });\n\n if (this.restartCount >= maxRestarts) {\n this.logger.error(\n { serverId, restartCount: this.restartCount, maxRestarts },\n \"Stdio client exceeded max restarts, giving up\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:error`, {\n serverId,\n error: new Error(\n `Max restarts (${maxRestarts}) exceeded for stdio client \"${serverId}\"`,\n ),\n });\n return;\n }\n\n const delay =\n restartDelayMs * Math.pow(restartBackoffMultiplier, this.restartCount);\n this.logger.info(\n { serverId, restartCount: this.restartCount, delayMs: delay },\n \"Scheduling stdio client restart\",\n );\n\n this.restartTimer = setTimeout(() => {\n this.restartTimer = null;\n void this.restart();\n }, delay);\n }\n\n private async restart(): Promise<void> {\n const { serverId } = this.options;\n this.restartCount++;\n\n // Clean up stale references\n this.client = null;\n this.transport = null;\n\n try {\n await this.start();\n this.logger.info(\n { serverId, restartCount: this.restartCount },\n \"Stdio client restarted successfully\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:restarted`, {\n serverId,\n restartCount: this.restartCount,\n });\n // Reset restart count only after process stays alive for a stability period.\n // This prevents a flapping process from resetting the counter on every\n // momentary connection and bypassing maxRestarts.\n const stableMs = this.options.restartDelayMs * 2;\n this.stabilityTimer = setTimeout(() => {\n this.stabilityTimer = null;\n if (this.running) this.restartCount = 0;\n }, stableMs);\n } catch (err) {\n this.logger.error(\n { err, serverId, restartCount: this.restartCount },\n \"Stdio client restart failed\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:error`, {\n serverId,\n error: err,\n });\n // Schedule another restart attempt\n this.handleDisconnect();\n }\n }\n}\n","import type { McpToolRegistryEntry } from \"./types.ts\";\n\n/**\n * Central registry of all MCP tools from all sources.\n * Stored in context store under MCP_TOOL_REGISTRY for agent adapter discovery.\n *\n * Sources:\n * - \"local\": mcp() routes from ADAPTER_DIRECT_REGISTRY (tools exposed by this context)\n * - stdio clients: long-lived subprocess MCP servers\n * - HTTP clients: remote HTTP MCP servers (tools refreshed periodically)\n *\n * @experimental\n */\nexport class McpToolRegistry {\n /** Nested Map: source -> toolName -> McpToolRegistryEntry */\n private tools = new Map<string, Map<string, McpToolRegistryEntry>>();\n\n /**\n * Set all tools for a given source (replaces previous tools from that source).\n * Called on initial tool listing and on re-listing after restart/refresh.\n *\n * @param source - Identifier for the tool source (e.g. server ID or \"local\")\n * @param transport - How the tools are reached (\"stdio\", \"http\", or \"local\")\n * @param tools - Tool definitions to register for this source\n */\n setToolsForSource(\n source: string,\n transport: \"stdio\" | \"http\" | \"local\",\n tools: Array<{\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n }>,\n ): void {\n const sourceMap = new Map<string, McpToolRegistryEntry>();\n\n for (const tool of tools) {\n const entry: McpToolRegistryEntry = {\n name: tool.name,\n inputSchema: tool.inputSchema,\n source,\n transport,\n };\n if (tool.description !== undefined) {\n entry.description = tool.description;\n }\n sourceMap.set(tool.name, entry);\n }\n\n this.tools.set(source, sourceMap);\n }\n\n /**\n * Remove all tools for a source (when a client is permanently stopped).\n *\n * @param source - Source identifier whose tools should be removed\n */\n removeSource(source: string): void {\n this.tools.delete(source);\n }\n\n /**\n * Get all tools across all sources.\n *\n * @returns Array of every registered tool entry\n */\n getTools(): McpToolRegistryEntry[] {\n const result: McpToolRegistryEntry[] = [];\n for (const sourceMap of this.tools.values()) {\n for (const entry of sourceMap.values()) {\n result.push(entry);\n }\n }\n return result;\n }\n\n /**\n * Get tools from a specific source/server.\n *\n * @param serverId - Source identifier to filter by\n * @returns Array of tool entries belonging to that source\n */\n getToolsByServer(serverId: string): McpToolRegistryEntry[] {\n const sourceMap = this.tools.get(serverId);\n if (!sourceMap) return [];\n return Array.from(sourceMap.values());\n }\n\n /**\n * Get a specific tool by name. Returns first match if name exists in multiple sources.\n *\n * @param name - Tool name to search for\n * @returns The first matching entry, or undefined\n */\n getTool(name: string): McpToolRegistryEntry | undefined {\n for (const sourceMap of this.tools.values()) {\n const entry = sourceMap.get(name);\n if (entry) return entry;\n }\n return undefined;\n }\n\n /**\n * Get a specific tool by source and name.\n *\n * @param source - Source identifier\n * @param name - Tool name\n * @returns The matching entry, or undefined\n */\n getToolBySource(\n source: string,\n name: string,\n ): McpToolRegistryEntry | undefined {\n return this.tools.get(source)?.get(name);\n }\n}\n","import {\n type CraftContext,\n type CraftPlugin,\n type EventName,\n} from \"@routecraft/routecraft\";\nimport { McpServer } from \"./server.ts\";\nimport {\n ADAPTER_MCP_CLIENT_SERVERS,\n MCP_PLUGIN_REGISTERED,\n MCP_STDIO_MANAGERS,\n MCP_TOOL_REGISTRY,\n} from \"./types.ts\";\nimport type {\n McpClientHttpConfig,\n McpClientStdioConfig,\n McpPluginOptions,\n McpTool,\n} from \"./types.ts\";\nimport { validateMcpPluginOptions } from \"./validate-options.ts\";\nimport { StdioClientManager } from \"./stdio-client-manager.ts\";\nimport { McpToolRegistry } from \"./tool-registry.ts\";\nimport { buildAuthHeaders } from \"./build-auth-headers.ts\";\n\ntype ClientConfig = McpClientHttpConfig | McpClientStdioConfig;\n\nfunction isStdioConfig(config: ClientConfig): config is McpClientStdioConfig {\n return \"transport\" in config && config.transport === \"stdio\";\n}\n\n/**\n * MCP plugin: one plugin per adapter. Starts the MCP server during plugin apply (before routes start) so startup failures fail context build. Exposes mcp() routes to external MCP clients.\n * Optional clients: register named remote MCP servers so routes can use .to(mcp(\"name:tool\")) without passing url.\n * Stdio clients are spawned as subprocesses with auto-restart; HTTP clients are used for ephemeral tool calls.\n * All discovered external tools (stdio, HTTP) are stored in a unified McpToolRegistry for agent adapter discovery.\n * Required when any route uses .from(mcp(...)); the route will fail at start if this plugin is not applied.\n *\n * @experimental\n */\nexport function mcpPlugin(options: McpPluginOptions = {}): CraftPlugin {\n validateMcpPluginOptions(options);\n\n let server: McpServer | null = null;\n const stdioManagers = new Map<string, StdioClientManager>();\n const httpClients = new Map<\n string,\n { close(): Promise<void>; listTools(): Promise<{ tools: McpTool[] }> }\n >();\n const httpRefreshTimers: ReturnType<typeof setInterval>[] = [];\n let toolRegistry: McpToolRegistry | null = null;\n\n return {\n async apply(ctx: CraftContext) {\n ctx.setStore(\n MCP_PLUGIN_REGISTERED as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n true,\n );\n\n // Create and store tool registry\n toolRegistry = new McpToolRegistry();\n ctx.setStore(\n MCP_TOOL_REGISTRY as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n toolRegistry,\n );\n\n // Store stdio managers map so destination adapter can call tools on stdio clients\n ctx.setStore(\n MCP_STDIO_MANAGERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n stdioManagers as unknown as Map<\n string,\n {\n callTool(\n name: string,\n args: Record<string, unknown>,\n ): Promise<unknown>;\n }\n >,\n );\n\n if (options.clients && Object.keys(options.clients).length > 0) {\n const clientEntries = Object.entries(options.clients);\n const map = new Map<\n string,\n McpClientHttpConfig | McpClientStdioConfig | string\n >();\n for (const [k, v] of clientEntries) {\n map.set(k, v);\n }\n ctx.setStore(\n ADAPTER_MCP_CLIENT_SERVERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n map,\n );\n\n // Start stdio clients and list HTTP client tools\n for (const [serverId, config] of clientEntries) {\n if (isStdioConfig(config)) {\n await startStdioClient(ctx, serverId, config, toolRegistry);\n } else {\n // HTTP client: list tools immediately and optionally refresh periodically\n const httpConfig = config as McpClientHttpConfig;\n await listHttpClientTools(\n ctx,\n serverId,\n httpConfig.url,\n toolRegistry,\n httpConfig.auth,\n );\n setupHttpToolRefresh(\n ctx,\n serverId,\n httpConfig.url,\n toolRegistry,\n httpConfig.auth,\n );\n }\n\n const transport = isStdioConfig(config) ? \"stdio\" : \"http\";\n ctx.emit(\n `plugin:mcp:client:${serverId}:registered` as EventName,\n { serverId, transport } as Record<string, unknown>,\n );\n }\n }\n\n server = new McpServer(ctx, options);\n await server.start();\n },\n async teardown(ctx: CraftContext) {\n // Clear HTTP refresh timers\n for (const timer of httpRefreshTimers) {\n clearInterval(timer);\n }\n httpRefreshTimers.length = 0;\n\n // Close persistent HTTP clients\n for (const [serverId, client] of httpClients) {\n try {\n await client.close();\n } catch (error) {\n ctx.logger.error(\n { err: error, serverId, operation: \"close\" },\n \"Failed to close HTTP client\",\n );\n }\n }\n httpClients.clear();\n\n // Stop all stdio client managers\n for (const [serverId, manager] of stdioManagers) {\n try {\n await manager.stop();\n } catch (error) {\n ctx.logger.error(\n { err: error, serverId, operation: \"stop\" },\n \"Failed to stop stdio client\",\n );\n }\n }\n stdioManagers.clear();\n\n if (server) {\n try {\n await server.stop();\n } catch (error) {\n ctx.logger.error(\n { err: error, operation: \"stop\" },\n \"Failed to stop MCP server plugin\",\n );\n }\n server = null;\n }\n\n toolRegistry = null;\n },\n };\n\n async function startStdioClient(\n ctx: CraftContext,\n serverId: string,\n config: McpClientStdioConfig,\n registry: McpToolRegistry,\n ): Promise<void> {\n const managerOpts: import(\"./stdio-client-manager.ts\").StdioClientManagerOptions =\n {\n serverId,\n command: config.command,\n args: config.args ?? [],\n maxRestarts: options.maxRestarts ?? 5,\n restartDelayMs: options.restartDelayMs ?? 1000,\n restartBackoffMultiplier: options.restartBackoffMultiplier ?? 2,\n };\n if (config.env !== undefined) managerOpts.env = config.env;\n if (config.cwd !== undefined) managerOpts.cwd = config.cwd;\n\n const manager = new StdioClientManager(\n managerOpts,\n ctx.logger,\n (event, details) => {\n ctx.emit(event as EventName, details as Record<string, unknown>);\n },\n (_serverId, tools) => {\n registry.setToolsForSource(\n _serverId,\n \"stdio\",\n tools.map((t) => {\n const entry: {\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n } = {\n name: t.name,\n inputSchema: t.inputSchema as Record<string, unknown>,\n };\n if (t.description !== undefined) {\n entry.description = t.description;\n }\n return entry;\n }),\n );\n },\n );\n\n stdioManagers.set(serverId, manager);\n\n try {\n await manager.start();\n } catch (error) {\n ctx.logger.error(\n { err: error, serverId, operation: \"start\" },\n \"Failed to start stdio client\",\n );\n ctx.emit(\n `plugin:mcp:client:${serverId}:error` as EventName,\n {\n serverId,\n error,\n } as Record<string, unknown>,\n );\n }\n }\n\n async function getOrCreateHttpClient(\n serverId: string,\n url: string,\n auth?: McpClientHttpConfig[\"auth\"],\n ): Promise<{\n close(): Promise<void>;\n listTools(): Promise<{ tools: McpTool[] }>;\n }> {\n const existing = httpClients.get(serverId);\n if (existing) return existing;\n\n const { Client } =\n await import(\"@modelcontextprotocol/sdk/client/index.js\");\n const { StreamableHTTPClientTransport } =\n await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n\n const headers = await buildAuthHeaders(auth);\n const transportOptions = headers ? { requestInit: { headers } } : undefined;\n const transport = new (StreamableHTTPClientTransport as new (\n url: URL,\n options?: { requestInit?: { headers?: Record<string, string> } },\n ) => unknown)(new URL(url), transportOptions);\n const rawClient = new Client(\n { name: \"routecraft-mcp-client\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n await (\n rawClient as unknown as { connect(t: unknown): Promise<void> }\n ).connect(transport);\n\n const typed = rawClient as unknown as {\n close(): Promise<void>;\n listTools(): Promise<{ tools: McpTool[] }>;\n };\n httpClients.set(serverId, typed);\n return typed;\n }\n\n async function listHttpClientTools(\n ctx: CraftContext,\n serverId: string,\n url: string,\n registry: McpToolRegistry,\n auth?: McpClientHttpConfig[\"auth\"],\n ): Promise<void> {\n try {\n const client = await getOrCreateHttpClient(serverId, url, auth);\n\n const result = await client.listTools();\n const tools = result.tools ?? [];\n registry.setToolsForSource(\n serverId,\n \"http\",\n tools.map((t) => {\n const entry: {\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n } = {\n name: t.name,\n inputSchema: t.inputSchema as Record<string, unknown>,\n };\n if (t.description !== undefined) {\n entry.description = t.description;\n }\n return entry;\n }),\n );\n\n ctx.emit(\n `plugin:mcp:client:${serverId}:tools:listed` as EventName,\n {\n serverId,\n toolCount: tools.length,\n } as Record<string, unknown>,\n );\n } catch (error) {\n // Connection may have gone stale; discard so next attempt reconnects\n httpClients.delete(serverId);\n ctx.logger.warn(\n { err: error, serverId, url, operation: \"listTools\" },\n \"Failed to list tools from HTTP client\",\n );\n }\n }\n\n function setupHttpToolRefresh(\n ctx: CraftContext,\n serverId: string,\n url: string,\n registry: McpToolRegistry,\n auth?: McpClientHttpConfig[\"auth\"],\n ): void {\n const interval = options.toolRefreshIntervalMs ?? 60_000;\n if (interval <= 0) return;\n\n const timer = setInterval(() => {\n void listHttpClientTools(ctx, serverId, url, registry, auth);\n }, interval);\n httpRefreshTimers.push(timer);\n }\n}\n","import type { Exchange } from \"@routecraft/routecraft\";\nimport type { AgentOptions, AgentResult } from \"./types.ts\";\n\n/**\n * Internal runner for the agent loop. Phase 1: stub that passes through and returns\n * exchange body. Full implementation (LLM + tool dispatch) in Phase 2.\n */\nexport class AgentRunner {\n constructor(private readonly _options: AgentOptions) {}\n\n async run(exchange: Exchange<unknown>): Promise<AgentResult> {\n void this._options; // Phase 2 will use modelId, allowedRoutes, etc.\n // Phase 1: pass-through only\n if (exchange.logger) {\n exchange.logger.debug(\n { adapter: \"agent\" },\n \"Agent pass-through — implementation pending\",\n );\n }\n return {\n output: exchange.body,\n steps: 0,\n };\n }\n}\n","import type { Destination, Exchange } from \"@routecraft/routecraft\";\nimport { AgentRunner } from \"./runner.ts\";\nimport type { AgentOptions, AgentResult } from \"./types.ts\";\n\n/** Validate modelId format \"providerId:modelName\". */\nfunction validateModelId(modelId: string): void {\n const colon = modelId.indexOf(\":\");\n if (colon < 1 || colon === modelId.length - 1) {\n throw new Error(\n `Agent adapter: modelId must be \"providerId:modelName\" (e.g. ollama:llama3). Got: \"${modelId}\"`,\n );\n }\n}\n\n/**\n * Agent destination adapter.\n * Use via agent(); do not instantiate AgentRunner directly.\n *\n * @experimental\n */\nexport class AgentDestinationAdapter implements Destination<\n unknown,\n AgentResult\n> {\n readonly adapterId = \"routecraft.adapter.agent\";\n\n private readonly runner: AgentRunner;\n\n constructor(options: AgentOptions) {\n validateModelId(options.modelId);\n this.runner = new AgentRunner(options);\n }\n\n async send(exchange: Exchange<unknown>): Promise<AgentResult> {\n return this.runner.run(exchange);\n }\n}\n","import type { Destination } from \"@routecraft/routecraft\";\nimport { AgentDestinationAdapter } from \"./destination.ts\";\nimport type { AgentOptions, AgentResult } from \"./types.ts\";\n\n/**\n * Create an agent destination.\n *\n * @experimental\n * @param options Agent options (modelId, systemPrompt, allowedRoutes, etc.)\n * @returns Destination that produces AgentResult\n */\nexport function agent(\n options: AgentOptions,\n): Destination<unknown, AgentResult> {\n return new AgentDestinationAdapter(options);\n}\n","import type { EmbeddingModelConfig } from \"../types.ts\";\n\nexport interface CallEmbeddingParams {\n config: EmbeddingModelConfig;\n modelName: string;\n text: string;\n}\n\ntype PipelineFn = (\n text: string,\n options?: { pooling?: string; normalize?: boolean },\n) => Promise<unknown>;\n\ninterface CachedPipeline {\n run: PipelineFn;\n dispose?: (() => Promise<void>) | undefined;\n}\n\nconst pipelineCache = new Map<string, CachedPipeline>();\n\n/**\n * Dispose all cached HuggingFace pipelines and clear the cache. Call on context\n * shutdown so pipeline.dispose() releases native/ONNX resources.\n *\n * Callers must avoid process.exit() after this -- let the event loop drain\n * naturally so ONNX Runtime's C++ statics aren't torn down prematurely\n * (onnxruntime#25038: \"mutex lock failed: Invalid argument\").\n *\n * @experimental\n */\nexport async function disposeEmbeddingPipelineCache(): Promise<void> {\n const entries = [...pipelineCache.entries()];\n pipelineCache.clear();\n if (entries.length === 0) return;\n\n await Promise.all(\n entries.map(async ([, cached]) => {\n try {\n if (typeof cached.dispose === \"function\") {\n await cached.dispose();\n }\n } catch {\n // Ignore dispose errors during shutdown\n }\n }),\n );\n}\n\n/** Resolve to full Hugging Face repo id. Short names like \"all-MiniLM-L6-v2\" use Xenova/ (ONNX-converted). */\nfunction resolveHuggingFaceModel(modelName: string): string {\n if (modelName.includes(\"/\")) return modelName;\n return `Xenova/${modelName}`;\n}\n\nconst HUGGINGFACE_INSTALL =\n 'The Hugging Face embedding provider requires \"@huggingface/transformers\". Install it with: pnpm add @huggingface/transformers';\n\nfunction isModuleNotFoundFor(error: unknown, pkg: string): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message ?? \"\";\n return (\n (msg.includes(\"ERR_MODULE_NOT_FOUND\") ||\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\")) &&\n msg.includes(pkg)\n );\n}\n\nasync function getHuggingFacePipeline(modelName: string): Promise<PipelineFn> {\n const resolved = resolveHuggingFaceModel(modelName);\n const cached = pipelineCache.get(resolved);\n if (cached) return cached.run;\n\n let pipelineFn: (\n task: string,\n model: string,\n opts?: { dtype?: string },\n ) => Promise<unknown>;\n try {\n const mod = await import(\"@huggingface/transformers\");\n pipelineFn = mod.pipeline as typeof pipelineFn;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@huggingface/transformers\")) {\n throw new Error(HUGGINGFACE_INSTALL);\n }\n throw error;\n }\n const pipe = (await pipelineFn(\"feature-extraction\", resolved, {\n dtype: \"fp32\",\n })) as {\n (\n text: string,\n options?: { pooling?: string; normalize?: boolean },\n ): Promise<unknown>;\n dispose?: () => void;\n };\n const run: PipelineFn = (text, options) =>\n pipe(text, {\n pooling: (options?.pooling ?? \"mean\") as \"mean\",\n normalize: options?.normalize ?? true,\n });\n const entry: CachedPipeline = {\n run,\n dispose:\n typeof pipe.dispose === \"function\"\n ? () => Promise.resolve(pipe.dispose!())\n : undefined,\n };\n pipelineCache.set(resolved, entry);\n return run;\n}\n\nfunction previewForError(value: unknown): string {\n if (value === null) return \"null\";\n if (typeof value !== \"object\") return String(value);\n if (Array.isArray(value)) return `array(${value.length})`;\n try {\n const s = JSON.stringify(value);\n return s.length > 100 ? s.slice(0, 100) + \"...\" : s;\n } catch {\n return \"object\";\n }\n}\n\nfunction toNumberArray(data: Float32Array | number[] | unknown): number[] {\n if (Array.isArray(data)) return data as number[];\n if (data instanceof Float32Array) return Array.from(data);\n if (data && typeof data === \"object\" && \"data\" in data) {\n const d = (data as { data: unknown }).data;\n if (Array.isArray(d)) return d as number[];\n if (d instanceof Float32Array) return Array.from(d);\n throw new Error(\n `Embedding output .data must be an Array or Float32Array; got ${typeof d}: ${previewForError(d)}`,\n );\n }\n throw new Error(\n `Embedding output must be an Array, Float32Array, or object with .data; got ${typeof data}: ${previewForError(data)}`,\n );\n}\n\nexport async function callEmbedding(\n params: CallEmbeddingParams,\n): Promise<number[]> {\n const { config, modelName, text } = params;\n if (config.provider === \"mock\") {\n const dim = 8;\n const vec: number[] = [];\n for (let i = 0; i < dim; i++) {\n vec.push(((text.length + i) % 100) / 100);\n }\n return vec;\n }\n if (config.provider === \"huggingface\") {\n const pipe = await getHuggingFacePipeline(modelName);\n const output = await pipe(text, {\n pooling: \"mean\" as const,\n normalize: true,\n });\n const data =\n output && typeof output === \"object\" && \"data\" in output\n ? (output as { data: Float32Array | number[] }).data\n : output;\n return toNumberArray(data);\n }\n if (config.provider === \"ollama\" || config.provider === \"openai\") {\n throw new Error(\n `Embedding provider \"${config.provider}\" is not yet implemented. Use huggingface for now.`,\n );\n }\n throw new Error(\n `Unknown embedding provider: ${(config as EmbeddingModelConfig).provider}`,\n );\n}\n","import type { Exchange } from \"@routecraft/routecraft\";\n\n/** Store key for plugin-registered embedding providers (provider id → EmbeddingModelConfig). */\nexport const ADAPTER_EMBEDDING_PROVIDERS = Symbol.for(\n \"routecraft.adapter.embedding.providers\",\n);\n\n/** Store key for context-level default embedding options. */\nexport const ADAPTER_EMBEDDING_OPTIONS = Symbol.for(\n \"routecraft.adapter.embedding.options\",\n);\n\ndeclare module \"@routecraft/routecraft\" {\n interface StoreRegistry {\n [ADAPTER_EMBEDDING_PROVIDERS]: Map<string, EmbeddingModelConfig>;\n [ADAPTER_EMBEDDING_OPTIONS]: Partial<EmbeddingOptions>;\n }\n}\n\nexport interface EmbeddingModelConfigHuggingFace {\n provider: \"huggingface\";\n}\n\nexport interface EmbeddingModelConfigOllama {\n provider: \"ollama\";\n baseURL?: string;\n}\n\nexport interface EmbeddingModelConfigOpenAI {\n provider: \"openai\";\n apiKey: string;\n baseURL?: string;\n}\n\n/** Used by tests only: returns a deterministic vector, no model download. */\nexport interface EmbeddingModelConfigMock {\n provider: \"mock\";\n}\n\nexport type EmbeddingModelConfig =\n | EmbeddingModelConfigHuggingFace\n | EmbeddingModelConfigOllama\n | EmbeddingModelConfigOpenAI\n | EmbeddingModelConfigMock;\n\nexport type EmbeddingProviderType =\n | \"huggingface\"\n | \"ollama\"\n | \"openai\"\n | \"mock\";\n\nexport interface EmbeddingOptions<T = unknown> {\n /** Build the string to embed from the exchange (e.g. jobTitle + location). */\n using: (exchange: Exchange<T>) => string | string[];\n}\n\nexport interface EmbeddingResult {\n embedding: number[];\n}\n\n/** Provider options for embeddingPlugin({ providers }). Key is the provider id. */\nexport interface EmbeddingPluginProviders {\n huggingface?: Record<string, never>;\n ollama?: { baseURL?: string };\n openai?: { apiKey: string; baseURL?: string };\n /** Test-only: deterministic vector, no network. */\n mock?: Record<string, never>;\n}\n\nexport interface EmbeddingPluginOptions {\n providers: EmbeddingPluginProviders;\n /** Optional context-level default options. */\n defaultOptions?: Partial<EmbeddingOptions>;\n}\n\n/**\n * Recommended embedding model ids for autocomplete.\n * Format: \"providerId:modelName\". Custom models are allowed via string.\n * Updated for 2026.\n */\nexport type EmbeddingModelId =\n // HuggingFace\n | \"huggingface:all-MiniLM-L6-v2\"\n | \"huggingface:sentence-transformers/all-MiniLM-L6-v2\"\n | \"huggingface:sentence-transformers/all-mpnet-base-v2\"\n | \"huggingface:BAAI/bge-small-en-v1.5\"\n | \"huggingface:BAAI/bge-base-en-v1.5\"\n | \"huggingface:BAAI/bge-m3\"\n | \"huggingface:intfloat/e5-small-v2\"\n | \"huggingface:intfloat/e5-base-v2\"\n | \"huggingface:intfloat/multilingual-e5-large\"\n // OpenAI\n | \"openai:text-embedding-3-small\"\n | \"openai:text-embedding-3-large\"\n | \"openai:text-embedding-ada-002\"\n // Ollama\n | \"ollama:nomic-embed-text\"\n | \"ollama:nomic-embed-text-v1.5\"\n | \"ollama:mxbai-embed-large\"\n | \"ollama:all-minilm\"\n // Other (custom models)\n | string;\n","import {\n getExchangeContext,\n type CraftContext,\n type Destination,\n type Exchange,\n type MergedOptions,\n} from \"@routecraft/routecraft\";\nimport { callEmbedding } from \"./providers/index.ts\";\nimport type {\n EmbeddingModelConfig,\n EmbeddingOptions,\n EmbeddingResult,\n} from \"./types.ts\";\nimport {\n ADAPTER_EMBEDDING_OPTIONS,\n ADAPTER_EMBEDDING_PROVIDERS,\n} from \"./types.ts\";\n\nfunction parseProviderModel(id: string): {\n providerId: string;\n modelName: string;\n} {\n const colon = id.indexOf(\":\");\n if (colon < 1 || colon === id.length - 1) {\n throw new Error(\n `Embedding adapter: model id must be \"providerId:modelName\" (e.g. huggingface:all-MiniLM-L6-v2). Got: \"${id}\"`,\n );\n }\n return {\n providerId: id.slice(0, colon),\n modelName: id.slice(colon + 1),\n };\n}\n\nfunction resolveProviderAndModel(\n modelId: string,\n context: CraftContext | undefined,\n): { config: EmbeddingModelConfig; modelName: string } {\n if (!context) {\n throw new Error(\n `Embedding adapter: model id \"${modelId}\" requires a context to resolve. Ensure the exchange has context (e.g. from a route) so embedding providers can be read.`,\n );\n }\n const store = context.getStore(\n ADAPTER_EMBEDDING_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, EmbeddingModelConfig> | undefined;\n if (!store) {\n throw new Error(\n \"Embedding provider not found: no providers registered. Add embeddingPlugin({ providers: { huggingface: {} } }) to your config.\",\n );\n }\n const { providerId, modelName } = parseProviderModel(modelId);\n const config = store.get(providerId);\n if (!config) {\n throw new Error(\n `Embedding provider \"${providerId}\" not found. Register it with embeddingPlugin({ providers: { \"${providerId}\": {} } }).`,\n );\n }\n return { config, modelName };\n}\n\nfunction buildText<T>(\n using: (exchange: Exchange<T>) => string | string[],\n): (exchange: Exchange<T>) => string {\n return (exchange: Exchange<T>) => {\n const value = using(exchange);\n return Array.isArray(value) ? value.filter(Boolean).join(\" | \") : value;\n };\n}\n\n/**\n * Embedding destination adapter. Expects model id as \"providerId:modelName\"\n * (e.g. huggingface:all-MiniLM-L6-v2), resolves the provider from the plugin store,\n * and returns { embedding: number[] }. Use with .enrich(embedding(\"provider:model\", { using: ... })).\n *\n * @experimental\n */\nexport class EmbeddingDestinationAdapter<T = unknown>\n implements Destination<T, EmbeddingResult>, MergedOptions<EmbeddingOptions>\n{\n readonly adapterId = \"routecraft.adapter.embedding\";\n\n constructor(\n private readonly modelId: string,\n options: Partial<EmbeddingOptions<T>> = {},\n ) {\n this.options = options as Partial<EmbeddingOptions>;\n }\n\n public options: Partial<EmbeddingOptions>;\n\n mergedOptions(context: CraftContext): EmbeddingOptions {\n const store = context.getStore(\n ADAPTER_EMBEDDING_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Partial<EmbeddingOptions> | undefined;\n return { ...store, ...this.options } as EmbeddingOptions;\n }\n\n async send(exchange: Exchange<T>): Promise<EmbeddingResult> {\n const context = getExchangeContext(exchange);\n const { config, modelName } = resolveProviderAndModel(\n this.modelId,\n context,\n );\n const merged = this.mergedOptions(context!);\n\n if (!merged.using) {\n throw new Error(\n \"Embedding adapter: options.using(exchange) is required to build the string to embed.\",\n );\n }\n\n const getText = buildText(\n merged.using as (e: Exchange<unknown>) => string | string[],\n );\n const text = getText(exchange as Exchange<unknown>);\n\n const embedding = await callEmbedding({ config, modelName, text });\n return { embedding };\n }\n}\n","import type { Destination } from \"@routecraft/routecraft\";\nimport { EmbeddingDestinationAdapter } from \"./destination.ts\";\nimport type {\n EmbeddingModelId,\n EmbeddingOptions,\n EmbeddingResult,\n} from \"./types.ts\";\n\n/**\n * Creates an embedding destination that computes a vector for the given text.\n * Use with .enrich(). Pass model id as \"providerId:modelName\" (e.g. huggingface:all-MiniLM-L6-v2).\n * The provider must be registered via embeddingPlugin({ providers: { huggingface: {} } }).\n *\n * @experimental\n * @param modelId - \"providerId:modelName\"; the provider is resolved from the plugin.\n * @param options - using(exchange) returns the string (or string[]) to embed.\n */\nexport function embedding<T = unknown>(\n modelId: EmbeddingModelId,\n options?: Partial<EmbeddingOptions<T>>,\n): Destination<T, EmbeddingResult> {\n return new EmbeddingDestinationAdapter<T>(modelId, options);\n}\n","import type { CraftContext, CraftPlugin } from \"@routecraft/routecraft\";\nimport { disposeEmbeddingPipelineCache } from \"./providers/index.ts\";\nimport {\n ADAPTER_EMBEDDING_OPTIONS,\n ADAPTER_EMBEDDING_PROVIDERS,\n} from \"./types.ts\";\nimport type { EmbeddingModelConfig, EmbeddingPluginOptions } from \"./types.ts\";\n\n/** Normalize provider options to full EmbeddingModelConfig (providerId wins over opts.provider). */\nfunction toModelConfig(\n providerId: string,\n opts: Record<string, unknown>,\n): EmbeddingModelConfig {\n return {\n ...opts,\n provider: providerId as EmbeddingModelConfig[\"provider\"],\n } as EmbeddingModelConfig;\n}\n\n/**\n * Embedding plugin: registers providers and teardown to clear the pipeline\n * cache when the context stops (releases native/ONNX resources).\n * Use embedding(\"providerId:modelName\", { using: ... }),\n * e.g. embedding(\"huggingface:all-MiniLM-L6-v2\", { using: (e) => e.body.title }).\n *\n * @experimental\n */\nexport function embeddingPlugin(\n options: EmbeddingPluginOptions = { providers: {} },\n): CraftPlugin {\n return {\n apply(ctx: CraftContext) {\n const map = new Map<string, EmbeddingModelConfig>();\n for (const [providerId, opts] of Object.entries(options.providers)) {\n if (opts !== undefined) {\n map.set(\n providerId,\n toModelConfig(providerId, opts as Record<string, unknown>),\n );\n }\n }\n ctx.setStore(\n ADAPTER_EMBEDDING_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n map,\n );\n if (\n options.defaultOptions &&\n Object.keys(options.defaultOptions).length > 0\n ) {\n ctx.setStore(\n ADAPTER_EMBEDDING_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n options.defaultOptions,\n );\n }\n },\n async teardown() {\n await disposeEmbeddingPipelineCache();\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/brand.ts","../src/llm/providers/index.ts","../src/llm/structured-output.ts","../src/llm/types.ts","../src/llm/destination.ts","../src/llm/llm.ts","../src/llm/validate-options.ts","../src/llm/plugin.ts","../src/mcp/types.ts","../src/mcp/adapters/mcp/shared.ts","../src/mcp/adapters/mcp/source.ts","../src/mcp/extract-content.ts","../src/mcp/build-auth-headers.ts","../src/mcp/adapters/mcp/destination.ts","../src/mcp/adapters/mcp/index.ts","../src/mcp/jwt.ts","../src/mcp/oauth.ts","../src/mcp/server.ts","../src/mcp/validate-options.ts","../src/mcp/stdio-client-manager.ts","../src/mcp/tool-registry.ts","../src/mcp/plugin.ts","../src/agent/runner.ts","../src/agent/destination.ts","../src/agent/agent.ts","../src/embedding/providers/index.ts","../src/embedding/types.ts","../src/embedding/destination.ts","../src/embedding/embedding.ts","../src/embedding/plugin.ts"],"names":["BRAND","isBranded","obj","key","isMcpAdapter","throwProviderInstallError","pkg","provider","isModuleNotFoundFor","error","msg","PROVIDER_DEFAULTS","toLlmUsage","u","getStructuredOutput","result","assertLanguageModelShape","model","providerName","modelId","m","callLlm","params","config","options","systemPrompt","userPrompt","output","callOpenAI","callAnthropic","callGemini","callOpenRouter","callOllama","_","createOpenAI","generateText","openaiSettings","genParams","out","parsed","createAnthropic","createGoogleGenerativeAI","createOpenRouter","openrouter","resolvedId","rawModel","createOllama","ollama","name","toAiOutputSpec","schema","standard","jsonSchemaObj","validate","value","err","formatSchemaIssues","aiSchema","jsonSchema","Output","ADAPTER_LLM_PROVIDERS","ADAPTER_LLM_OPTIONS","parseStructuredTextFallback","text","DEFAULT_TEMPERATURE","DEFAULT_MAX_TOKENS","resolvePrompt","source","exchange","resolveUserPromptDefault","body","parseProviderModel","id","colon","resolveProviderAndModel","context","store","providerId","modelName","LlmDestinationAdapter","getExchangeContext","merged","opts","fallback","llmResult","metadata","llm","PROVIDERS","isProvider","s","validateLlmPluginOptions","PROVIDER_IDS","toModelConfig","llmPlugin","ctx","map","MCP_PLUGIN_REGISTERED","ADAPTER_MCP_CLIENT_SERVERS","MCP_TOOL_REGISTRY","MCP_STDIO_MANAGERS","McpHeadersKeys","isOAuthAuth","auth","BRAND_MCP_ADAPTER","McpSourceAdapter","endpoint","rcError","handler","abortController","onReady","direct","extractContent","response","content","item","rrIndexes","resolveToken","token","idx","buildAuthHeaders","headers","customHeaders","authorizationOverride","resolved","assertHttpUrl","url","trimmed","resolveServerConfig","resolveConnection","defaultArgs","McpDestinationAdapter","toolName","args","manager","serverConfig","serverUrl","clientModule","transportModule","Client","StreamableHTTPClientTransport","transportOptions","transport","clientInfo","client","clientCleanup","closeOrDisconnect","transportCleanup","closeOrDestroy","mcp","endpointOrOptions","clientOpts","entry","isClientColonOptions","colonIndex","serverId","tool","clientOptions","HMAC_ALGORITHMS","RSA_ALGORITHMS","decodeToken","parts","headerB64","payloadB64","signatureB64","header","payload","checkTemporalClaims","clockToleranceSec","now","buildPrincipal","sub","principal","aud","a","scope","r","isHmac","createHmacValidator","secret","algorithm","digest","decoded","hmac","createHmac","expectedSig","expectedBuf","actualBuf","timingSafeEqual","createRsaValidator","publicKey","verifyAlgorithm","verifier","createVerify","jwt","oauth","principalStore","AsyncLocalStorage","MCP_SDK_INSTALL","McpServer","isRoutecraftError","Server","StdioServerTransport","ServerCtor","TransportClass","server","sessionId","tr","prevOnClose","sid","handleRequest","req","res","createSessionFn","runWithPrincipal","fn","session","hr","port","host","createServer","oauthOptions","expressFn","mcpAuthRouter","requireBearerAuth","ProxyOAuthServerProvider","expressMod","app","authRouterOptions","bearerOptions","nodeReq","nodeRes","authInfo","successDetail","resolve","reject","boundPort","listenDetail","addr","authOptions","rawHeader","detail","schemeMatch","typesModule","t","ListToolsRequestSchema","CallToolRequestSchema","srv","tools","request","names","exposedDetail","registry","ADAPTER_DIRECT_REGISTRY","toolsFilter","allowed","meta","channelStore","ADAPTER_DIRECT_STORE","channel","DefaultExchange","resultExchange","resultText","logMsg","userMsg","cause","validateMcpPluginOptions","validateWithSchema","StdioClientManager","logger","onEvent","onToolsUpdated","clientMod","stdioMod","command","env","cwd","data","_error","transportWithClose","maxRestarts","restartDelayMs","restartBackoffMultiplier","delay","stableMs","McpToolRegistry","sourceMap","isStdioConfig","mcpPlugin","stdioManagers","httpClients","httpRefreshTimers","toolRegistry","clientEntries","k","v","startStdioClient","httpConfig","listHttpClientTools","setupHttpToolRefresh","timer","managerOpts","event","details","_serverId","getOrCreateHttpClient","existing","rawClient","typed","interval","AgentRunner","_options","validateModelId","AgentDestinationAdapter","agent","pipelineCache","disposeEmbeddingPipelineCache","entries","cached","resolveHuggingFaceModel","HUGGINGFACE_INSTALL","getHuggingFacePipeline","pipelineFn","pipe","run","previewForError","toNumberArray","d","callEmbedding","vec","i","ADAPTER_EMBEDDING_PROVIDERS","ADAPTER_EMBEDDING_OPTIONS","buildText","using","EmbeddingDestinationAdapter","embedding","embeddingPlugin"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Cross-instance identity for @routecraft/ai: Symbol.for() keys and type guards.\n * Shared across all copies of @routecraft/ai (and multiple routecraft versions) in a process.\n */\n\nexport const BRAND = {\n McpAdapter: Symbol.for(\"routecraft.ai.McpAdapter\"),\n} as const;\n\nfunction isBranded(obj: unknown, key: symbol): boolean {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as Record<symbol, unknown>)[key] === true\n );\n}\n\nexport function isMcpAdapter(obj: unknown): boolean {\n return isBranded(obj, BRAND.McpAdapter);\n}\n","import type {\n LlmModelConfig,\n LlmOptionsMerged,\n LlmResult,\n LlmUsage,\n} from \"../types.ts\";\n\nfunction throwProviderInstallError(pkg: string, provider: string): never {\n throw new Error(\n `The ${provider} LLM provider requires the \"${pkg}\" package. Install it with: pnpm add ${pkg}`,\n );\n}\n\nfunction isModuleNotFoundFor(error: unknown, pkg: string): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message ?? \"\";\n return (\n (msg.includes(\"ERR_MODULE_NOT_FOUND\") ||\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\")) &&\n msg.includes(pkg)\n );\n}\n\n/** Provider-level defaults so users can register models with minimal config (e.g. { provider: \"ollama\" }). */\nconst PROVIDER_DEFAULTS = {\n ollama: {\n baseURL: \"http://localhost:11434/api\",\n },\n} as const;\n\n/** Pass through AI SDK usage so LlmUsage matches LanguageModelUsage (inputTokens/outputTokens). */\nfunction toLlmUsage(u: {\n inputTokens?: number | undefined;\n outputTokens?: number | undefined;\n totalTokens?: number | undefined;\n}): LlmUsage {\n return {\n ...(u.inputTokens !== undefined && { inputTokens: u.inputTokens }),\n ...(u.outputTokens !== undefined && { outputTokens: u.outputTokens }),\n ...(u.totalTokens !== undefined && { totalTokens: u.totalTokens }),\n };\n}\n\n/**\n * Safely read structured output from generateText result. The AI SDK's result.output\n * is a getter that throws AI_NoOutputGeneratedError when the model didn't produce\n * valid structured output (e.g. empty, blocked, or unparseable). Catching here\n * allows returning without output so the adapter can try parsing result.text.\n */\nfunction getStructuredOutput(result: { output?: unknown }): unknown {\n try {\n if (\"output\" in result && result.output !== undefined) return result.output;\n } catch {\n // SDK getter threw (e.g. AI_NoOutputGeneratedError); leave output undefined.\n }\n return undefined;\n}\n\n/**\n * Runtime check that a provider-returned value has the minimal LanguageModel shape\n * required by the AI SDK generateText (doGenerate, doStream). Throws a descriptive\n * error if validation fails so we avoid silent type assertions.\n */\nfunction assertLanguageModelShape(\n model: unknown,\n providerName: string,\n modelId: string,\n): void {\n if (model === null || typeof model !== \"object\") {\n throw new Error(\n `[${providerName}] Invalid model: expected an object, got ${typeof model}. Model id: ${modelId}`,\n );\n }\n const m = model as Record<string, unknown>;\n if (typeof m[\"doGenerate\"] !== \"function\") {\n throw new Error(\n `[${providerName}] Invalid model: missing or invalid doGenerate method. Model id: ${modelId}. ` +\n \"Ensure the provider returns an AI SDK-compatible language model.\",\n );\n }\n if (typeof m[\"doStream\"] !== \"function\") {\n throw new Error(\n `[${providerName}] Invalid model: missing or invalid doStream method. Model id: ${modelId}. ` +\n \"Ensure the provider returns an AI SDK-compatible language model.\",\n );\n }\n}\n\nexport interface CallLlmParams {\n config: LlmModelConfig;\n /** Model id to use for the request (for OpenRouter may be config.modelId ?? registeredId). */\n modelId: string;\n options: Pick<\n LlmOptionsMerged,\n | \"temperature\"\n | \"maxTokens\"\n | \"topP\"\n | \"frequencyPenalty\"\n | \"presencePenalty\"\n >;\n systemPrompt: string;\n userPrompt: string;\n /** Optional structured output spec (from toAiOutputSpec). Enables provider-level JSON schema. */\n output?: unknown;\n}\n\n/**\n * Dispatches to the appropriate provider and returns a normalized LlmResult.\n */\nexport async function callLlm(params: CallLlmParams): Promise<LlmResult> {\n const { config, modelId, options, systemPrompt, userPrompt, output } = params;\n switch (config.provider) {\n case \"openai\":\n return callOpenAI(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"anthropic\":\n return callAnthropic(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"gemini\":\n return callGemini(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"openrouter\":\n return callOpenRouter(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n case \"ollama\":\n return callOllama(\n config,\n modelId,\n options,\n systemPrompt,\n userPrompt,\n output,\n );\n default: {\n const _: never = config;\n throw new Error(\n `LLM provider not implemented: ${(_ as LlmModelConfig).provider}`,\n );\n }\n }\n}\n\nasync function callOpenAI(\n config: import(\"../types.ts\").LlmModelConfigOpenAI,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createOpenAI: (s: {\n apiKey: string;\n baseURL?: string;\n }) => (m: string) => unknown;\n try {\n const mod = await import(\"@ai-sdk/openai\");\n createOpenAI = mod.createOpenAI as typeof createOpenAI;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@ai-sdk/openai\")) {\n throwProviderInstallError(\"@ai-sdk/openai\", \"OpenAI\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const openaiSettings: { apiKey: string; baseURL?: string } = {\n apiKey: config.apiKey,\n };\n if (config.baseURL !== undefined) openaiSettings.baseURL = config.baseURL;\n const openai = createOpenAI(openaiSettings);\n const model = openai(modelId);\n const genParams: Parameters<typeof generateText>[0] = {\n model: model as Parameters<typeof generateText>[0][\"model\"],\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callAnthropic(\n config: import(\"../types.ts\").LlmModelConfigAnthropic,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createAnthropic: (s: { apiKey: string }) => (m: string) => unknown;\n try {\n const mod = await import(\"@ai-sdk/anthropic\");\n createAnthropic = mod.createAnthropic as typeof createAnthropic;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@ai-sdk/anthropic\")) {\n throwProviderInstallError(\"@ai-sdk/anthropic\", \"Anthropic\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const anthropic = createAnthropic({ apiKey: config.apiKey });\n const model = anthropic(modelId);\n const genParams: Parameters<typeof generateText>[0] = {\n model: model as Parameters<typeof generateText>[0][\"model\"],\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI; SDK passes through. Anthropic supports topP;\n // frequencyPenalty/presencePenalty may be unsupported (SDK may warn).\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callGemini(\n config: import(\"../types.ts\").LlmModelConfigGemini,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createGoogleGenerativeAI: (s: {\n apiKey: string;\n }) => (m: string) => unknown;\n try {\n const mod = await import(\"@ai-sdk/google\");\n createGoogleGenerativeAI =\n mod.createGoogleGenerativeAI as typeof createGoogleGenerativeAI;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@ai-sdk/google\")) {\n throwProviderInstallError(\"@ai-sdk/google\", \"Gemini\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const google = createGoogleGenerativeAI({ apiKey: config.apiKey });\n const model = google(modelId);\n const genParams: Parameters<typeof generateText>[0] = {\n model: model as Parameters<typeof generateText>[0][\"model\"],\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI; SDK passes through. Gemini may not support\n // all (e.g. frequencyPenalty/presencePenalty); check result.warnings if needed.\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callOpenRouter(\n config: import(\"../types.ts\").LlmModelConfigOpenRouter,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createOpenRouter: (s: { apiKey: string }) => {\n chat: (id: string) => unknown;\n };\n try {\n const mod = await import(\"@openrouter/ai-sdk-provider\");\n createOpenRouter = mod.createOpenRouter as typeof createOpenRouter;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@openrouter/ai-sdk-provider\")) {\n throwProviderInstallError(\"@openrouter/ai-sdk-provider\", \"OpenRouter\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const openrouter = createOpenRouter({ apiKey: config.apiKey });\n const resolvedId = config.modelId ?? modelId;\n const rawModel = openrouter.chat(resolvedId);\n assertLanguageModelShape(rawModel, \"OpenRouter\", resolvedId);\n const model = rawModel as Parameters<typeof generateText>[0][\"model\"];\n const genParams: Parameters<typeof generateText>[0] = {\n model,\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI. OpenRouter is OpenAI-compatible; typically supports all.\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n\nasync function callOllama(\n config: import(\"../types.ts\").LlmModelConfigOllama,\n modelId: string,\n options: CallLlmParams[\"options\"],\n systemPrompt: string,\n userPrompt: string,\n output: CallLlmParams[\"output\"],\n): Promise<LlmResult> {\n let createOllama: (s: { baseURL?: string }) => (name: string) => unknown;\n try {\n const mod = await import(\"ollama-ai-provider-v2\");\n createOllama = mod.createOllama as typeof createOllama;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"ollama-ai-provider-v2\")) {\n throwProviderInstallError(\"ollama-ai-provider-v2\", \"Ollama\");\n }\n throw error;\n }\n const { generateText } = await import(\"ai\");\n const ollama = createOllama({\n baseURL: config.baseURL ?? PROVIDER_DEFAULTS.ollama.baseURL,\n });\n const name = config.modelId ?? modelId;\n const rawModel = ollama(name);\n assertLanguageModelShape(rawModel, \"Ollama\", name);\n const model = rawModel as Parameters<typeof generateText>[0][\"model\"];\n const genParams: Parameters<typeof generateText>[0] = {\n model,\n prompt: userPrompt,\n ...(options.maxTokens !== undefined && {\n maxOutputTokens: options.maxTokens,\n }),\n temperature: options.temperature,\n };\n if (systemPrompt) genParams.system = systemPrompt;\n // Same option keys as callOpenAI. Ollama supports top_p; frequencyPenalty/presencePenalty\n // may be unsupported (SDK may warn).\n if (options.topP !== undefined) genParams.topP = options.topP;\n if (options.frequencyPenalty !== undefined)\n genParams.frequencyPenalty = options.frequencyPenalty;\n if (options.presencePenalty !== undefined)\n genParams.presencePenalty = options.presencePenalty;\n const params = output !== undefined ? { ...genParams, output } : genParams;\n const result = await generateText(\n params as Parameters<typeof generateText>[0],\n );\n const out: LlmResult = { text: result.text ?? \"\", raw: result };\n if (result.usage) out.usage = toLlmUsage(result.usage);\n const parsed = getStructuredOutput(result as { output?: unknown });\n if (parsed !== undefined) out.output = parsed;\n return out;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { formatSchemaIssues } from \"@routecraft/routecraft\";\nimport { Output, jsonSchema } from \"ai\";\n\n/**\n * Build an AI SDK output spec from a Standard Schema for provider-level\n * structured output (OpenAI response_format, Ollama format, etc.) and validation.\n *\n * The AI SDK accepts Zod directly in Output.object({ schema: z.object(...) }).\n * This package uses Standard Schema (per .standards/type-safety-and-schemas.md), so\n * it cannot depend on Zod. This helper bridges any Standard Schema (Zod, Valibot,\n * ArkType, etc.) by using the SDK’s lower-level jsonSchema(jsonSchemaObj, {\n * validate }): we get the JSON schema from ~standard.jsonSchema.output/.input\n * and use ~standard.validate as the validate callback. Callers can pass a Zod\n * schema (as Standard Schema), Valibot, or ArkType and get the same behavior.\n */\nexport function toAiOutputSpec(schema: StandardSchemaV1): unknown {\n const standard = (schema as unknown as Record<string, unknown>)[\n \"~standard\"\n ] as\n | {\n validate: (\n value: unknown,\n ) =>\n | { value?: unknown; issues?: unknown }\n | Promise<{ value?: unknown; issues?: unknown }>;\n jsonSchema?: {\n output?: (opts: { target: string }) => Record<string, unknown>;\n input?: (opts: { target: string }) => Record<string, unknown>;\n };\n }\n | undefined;\n\n if (!standard?.validate) {\n throw new Error(\n \"LLM outputSchema must be a StandardSchemaV1 with ~standard.validate\",\n );\n }\n\n const jsonSchemaObj =\n standard.jsonSchema?.output?.({ target: \"draft-2020-12\" }) ??\n standard.jsonSchema?.input?.({ target: \"draft-2020-12\" });\n\n if (!jsonSchemaObj || typeof jsonSchemaObj !== \"object\") {\n throw new Error(\n \"LLM outputSchema must expose ~standard.jsonSchema.output or .input for provider structured output\",\n );\n }\n\n function validate(\n value: unknown,\n ): { success: true; value: unknown } | { success: false; error: Error } {\n let result:\n | { value?: unknown; issues?: unknown }\n | Promise<{\n value?: unknown;\n issues?: unknown;\n }>;\n try {\n result = standard!.validate(value);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err : new Error(String(err)),\n };\n }\n if (result instanceof Promise) {\n return {\n success: false,\n error: new Error(\n \"Async output schema is not supported for LLM structured output\",\n ),\n };\n }\n const hasIssues =\n result.issues != null &&\n (Array.isArray(result.issues)\n ? result.issues.length > 0\n : typeof result.issues === \"object\" && result.issues !== null\n ? Object.keys(result.issues).length > 0\n : Boolean(result.issues));\n if (hasIssues) {\n return {\n success: false,\n error: new Error(formatSchemaIssues(result.issues)),\n };\n }\n return { success: true, value: result.value };\n }\n\n const aiSchema = jsonSchema(\n jsonSchemaObj as Parameters<typeof jsonSchema>[0],\n { validate },\n );\n return Output.object({ schema: aiSchema });\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { Exchange } from \"@routecraft/routecraft\";\n\n/**\n * Store key for plugin-registered providers (provider id -> LlmModelConfig).\n * @experimental\n */\nexport const ADAPTER_LLM_PROVIDERS = Symbol.for(\n \"routecraft.adapter.llm.providers\",\n);\n\n/**\n * Store key for context-level default LLM options.\n * @experimental\n */\nexport const ADAPTER_LLM_OPTIONS = Symbol.for(\"routecraft.adapter.llm.options\");\n\ndeclare module \"@routecraft/routecraft\" {\n interface StoreRegistry {\n [ADAPTER_LLM_PROVIDERS]: Map<string, LlmModelConfig>;\n [ADAPTER_LLM_OPTIONS]: Partial<LlmOptionsMerged>;\n }\n}\n\nexport type LlmProviderType =\n | \"openai\"\n | \"anthropic\"\n | \"openrouter\"\n | \"ollama\"\n | \"gemini\";\n\nexport interface LlmModelConfigOpenAI {\n provider: \"openai\";\n apiKey: string;\n baseURL?: string;\n}\n\nexport interface LlmModelConfigAnthropic {\n provider: \"anthropic\";\n apiKey: string;\n}\n\nexport interface LlmModelConfigOpenRouter {\n provider: \"openrouter\";\n apiKey: string;\n /** OpenRouter model id (e.g. anthropic/claude-3.5-sonnet). Defaults to the registered key. */\n modelId?: string;\n}\n\nexport interface LlmModelConfigOllama {\n provider: \"ollama\";\n /**\n * Ollama server URL. Optional: defaults to http://localhost:11434/api.\n * Only set when using a remote Ollama or custom port.\n */\n baseURL?: string;\n /**\n * Override model name sent to Ollama. Optional: defaults to the model\n * from the llm(\"provider:model\") call (the part after the colon).\n */\n modelId?: string;\n}\n\nexport interface LlmModelConfigGemini {\n provider: \"gemini\";\n apiKey: string;\n}\n\nexport type LlmModelConfig =\n | LlmModelConfigOpenAI\n | LlmModelConfigAnthropic\n | LlmModelConfigOpenRouter\n | LlmModelConfigOllama\n | LlmModelConfigGemini;\n\n/** Provider options for llmPlugin({ providers }). Key is the provider; no need to repeat provider in the value. */\nexport interface LlmOllamaProviderOptions {\n baseURL?: string;\n modelId?: string;\n}\nexport interface LlmOpenAIProviderOptions {\n apiKey: string;\n baseURL?: string;\n}\nexport interface LlmAnthropicProviderOptions {\n apiKey: string;\n}\nexport interface LlmOpenRouterProviderOptions {\n apiKey: string;\n modelId?: string;\n}\nexport interface LlmGeminiProviderOptions {\n apiKey: string;\n}\n\nexport interface LlmPluginProviders {\n ollama?: LlmOllamaProviderOptions;\n openai?: LlmOpenAIProviderOptions;\n anthropic?: LlmAnthropicProviderOptions;\n openrouter?: LlmOpenRouterProviderOptions;\n gemini?: LlmGeminiProviderOptions;\n}\n\n/** Map provider id → provider-specific options (for type-safe toModelConfig). */\nexport type LlmProviderOptionsMap = Required<LlmPluginProviders>;\n\n/** Resolve system or user prompt from exchange (string or function). */\nexport type LlmPromptSource =\n | string\n | ((exchange: Exchange<unknown>) => string);\n\nexport interface LlmOptions {\n systemPrompt?: LlmPromptSource;\n userPrompt?: LlmPromptSource;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n frequencyPenalty?: number;\n presencePenalty?: number;\n /**\n * Optional output schema (Standard Schema). When set, the adapter requests\n * provider-level structured output and validates the result. Supported by\n * OpenAI (gpt-4o/mini) and Ollama; others may return JSON that is validated\n * after the call. On success, the parsed value is set on LlmResult.output.\n */\n outputSchema?: StandardSchemaV1;\n}\n\n/** Internal merged type for adapter and store. */\nexport type LlmOptionsMerged = Required<\n Pick<LlmOptions, \"temperature\" | \"maxTokens\">\n> &\n Omit<LlmOptions, \"temperature\" | \"maxTokens\">;\n\n/**\n * Token usage. Matches Vercel AI SDK LanguageModelUsage shape (inputTokens/outputTokens)\n * so result.usage can be used interchangeably with generateText() return value.\n */\nexport interface LlmUsage {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n}\n\n/**\n * LLM result shape aligned with Vercel AI SDK generateText() return value.\n * Same property names (text, output, usage) so code and docs transfer directly.\n */\nexport interface LlmResult {\n /** Generated text (raw string from the model). */\n text: string;\n /** Parsed structured output when outputSchema was set and validation succeeded. */\n output?: unknown;\n /** Token usage for the last step. Same shape as AI SDK usage. */\n usage?: LlmUsage;\n /** Full generateText() result for advanced use (debugging, response metadata). */\n raw?: unknown;\n}\n\n/**\n * When outputSchema S is provided to llm(), the result type narrows output to InferOutput<S>.\n * Used for type inference from llm(modelId, { outputSchema }) so body.output is typed downstream.\n */\nexport type LlmResultWithOutput<S extends StandardSchemaV1 | undefined> =\n S extends StandardSchemaV1\n ? Omit<LlmResult, \"output\"> & {\n output?: StandardSchemaV1.InferOutput<S>;\n }\n : LlmResult;\n\n/**\n * Recommended LLM model ids for autocomplete (chat/completion use cases).\n * Format: \"providerId:modelName\". Custom models are allowed via string.\n * Updated for 2026.\n */\nexport type LlmModelId =\n // OpenAI (2026: GPT-5.2, Codex, o1)\n | \"openai:gpt-5.2\"\n | \"openai:gpt-5.2-codex\"\n | \"openai:gpt-5\"\n | \"openai:gpt-5.1-chat-latest\"\n | \"openai:gpt-5-mini\"\n | \"openai:gpt-5-codex-mini\"\n | \"openai:gpt-4o\"\n | \"openai:gpt-4o-mini\"\n | \"openai:o1\"\n | \"openai:o1-mini\"\n // Anthropic (2026: Claude 4.6 / 4.5)\n | \"anthropic:claude-opus-4-6\"\n | \"anthropic:claude-sonnet-4-6\"\n | \"anthropic:claude-haiku-4-5\"\n // Ollama (common local models)\n | \"ollama:qwen3\"\n | \"ollama:llama3.2\"\n | \"ollama:llama3.3\"\n | \"ollama:mistral\"\n | \"ollama:gemma2\"\n | \"ollama:deepseek-r1\"\n | \"ollama:lfm2.5-thinking\"\n // OpenRouter (top open-weight / frontier: GLM, Kimi, Qwen, DeepSeek)\n | \"openrouter:z-ai/glm-5\"\n | \"openrouter:z-ai/glm-4.7\"\n | \"openrouter:moonshotai/kimi-k2-thinking\"\n | \"openrouter:qwen/qwen3.5-plus-02-15\"\n | \"openrouter:qwen/qwen3-next\"\n | \"openrouter:deepseek/deepseek-v3.2\"\n | \"openrouter:deepseek/deepseek-r1\"\n | \"openrouter:meta-llama/llama-3.3-70b-instruct\"\n // Gemini (2026: 2.5 + 3.x preview)\n | \"gemini:gemini-2.5-pro\"\n | \"gemini:gemini-2.5-flash\"\n | \"gemini:gemini-2.5-flash-lite\"\n | \"gemini:gemini-3.1-pro-preview\"\n | \"gemini:gemini-3-pro-preview\"\n | \"gemini:gemini-3-flash-preview\"\n // Other (custom models)\n | string;\n\nexport interface LlmPluginOptions {\n /**\n * Supported providers keyed by id. Only set options you need (defaults for url etc. apply).\n * Routes use llm(\"providerId:modelName\"), e.g. llm(\"ollama:lfm2.5-thinking\").\n */\n providers: LlmPluginProviders;\n /** Optional context-level default options (systemPrompt, temperature, etc.). */\n defaultOptions?: Partial<LlmOptionsMerged>;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n getExchangeContext,\n type CraftContext,\n type Destination,\n type Exchange,\n type MergedOptions,\n} from \"@routecraft/routecraft\";\nimport { callLlm } from \"./providers/index.ts\";\nimport { toAiOutputSpec } from \"./structured-output.ts\";\nimport type {\n LlmModelConfig,\n LlmOptions,\n LlmOptionsMerged,\n LlmPromptSource,\n LlmResultWithOutput,\n} from \"./types.ts\";\nimport { ADAPTER_LLM_OPTIONS, ADAPTER_LLM_PROVIDERS } from \"./types.ts\";\n\n/**\n * When the AI SDK doesn't set result.output (e.g. it threw on the getter), try to\n * parse result.text as JSON and validate with the output schema. Returns the\n * parsed value or undefined. Handles both sync and async Standard Schema validate().\n */\nasync function parseStructuredTextFallback(\n text: string,\n schema: StandardSchemaV1,\n): Promise<unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n const standard = (schema as unknown as Record<string, unknown>)[\n \"~standard\"\n ] as\n | {\n validate: (\n value: unknown,\n ) =>\n | { value?: unknown; issues?: unknown }\n | Promise<{ value?: unknown; issues?: unknown }>;\n }\n | undefined;\n if (!standard?.validate) return undefined;\n let result = standard.validate(parsed);\n if (result instanceof Promise) result = await result;\n if (\n result &&\n typeof result === \"object\" &&\n \"issues\" in result &&\n result.issues\n )\n return undefined;\n return result && typeof result === \"object\" && \"value\" in result\n ? result.value\n : undefined;\n}\n\nconst DEFAULT_TEMPERATURE = 0;\nconst DEFAULT_MAX_TOKENS = 1024;\n\nfunction resolvePrompt(\n source: LlmPromptSource | undefined,\n exchange: Exchange<unknown>,\n): string {\n if (source === undefined || source === \"\") return \"\";\n if (typeof source === \"function\") return source(exchange);\n return source;\n}\n\nfunction resolveUserPromptDefault(exchange: Exchange<unknown>): string {\n const body = exchange.body;\n if (typeof body === \"string\") return body;\n if (body === null || body === undefined) return \"\";\n if (typeof body === \"object\") return JSON.stringify(body);\n return String(body);\n}\n\n/** Format: \"providerId:modelName\", e.g. \"ollama:lfm2.5-thinking\". */\nfunction parseProviderModel(id: string): {\n providerId: string;\n modelName: string;\n} {\n const colon = id.indexOf(\":\");\n if (colon < 1 || colon === id.length - 1) {\n throw new Error(\n `LLM adapter: model id must be \"providerId:modelName\" (e.g. ollama:lfm2.5-thinking). Got: \"${id}\"`,\n );\n }\n return {\n providerId: id.slice(0, colon),\n modelName: id.slice(colon + 1),\n };\n}\n\nfunction resolveProviderAndModel(\n modelId: string,\n context: CraftContext | undefined,\n): { config: LlmModelConfig; modelName: string } {\n if (!context) {\n throw new Error(\n `LLM adapter: model id \"${modelId}\" requires a context to resolve. Ensure the exchange has context (e.g. from a route) so store \"${ADAPTER_LLM_PROVIDERS.description}\" can be read.`,\n );\n }\n const store = context.getStore(\n ADAPTER_LLM_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, LlmModelConfig> | undefined;\n if (!store) {\n throw new Error(\n `LLM provider not found: no providers registered. Add llmPlugin({ providers: { ollama: { provider: \"ollama\" }, ... } }) to your config.`,\n );\n }\n const { providerId, modelName } = parseProviderModel(modelId);\n const config = store.get(providerId);\n if (!config) {\n throw new Error(\n `LLM provider \"${providerId}\" not found. Register it with llmPlugin({ providers: { \"${providerId}\": { provider, apiKey?, baseURL? } } }).`,\n );\n }\n return { config, modelName };\n}\n\n/**\n * LLM destination adapter. Expects model id as \"providerId:modelName\" (e.g. ollama:lfm2.5-thinking),\n * resolves the provider from the plugin store, merges options, and calls the provider with the model name.\n * Use with .enrich(llm(\"providerId:modelName\", options)) or .to(llm(...)).\n *\n * @experimental\n * @template S - Output schema type when outputSchema is provided; narrows result.output for downstream typing.\n */\nexport class LlmDestinationAdapter<\n S extends StandardSchemaV1 | undefined = undefined,\n>\n implements\n Destination<unknown, LlmResultWithOutput<S>>,\n MergedOptions<LlmOptionsMerged>\n{\n readonly adapterId = \"routecraft.adapter.llm\";\n\n constructor(\n private readonly modelId: string,\n options: Partial<LlmOptions> = {},\n ) {\n this.options = options as Partial<LlmOptionsMerged>;\n }\n\n public options: Partial<LlmOptionsMerged>;\n\n mergedOptions(context: CraftContext): LlmOptionsMerged {\n const store = context.getStore(\n ADAPTER_LLM_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Partial<LlmOptionsMerged> | undefined;\n return {\n temperature: DEFAULT_TEMPERATURE,\n maxTokens: DEFAULT_MAX_TOKENS,\n ...store,\n ...this.options,\n } as LlmOptionsMerged;\n }\n\n async send(exchange: Exchange<unknown>): Promise<LlmResultWithOutput<S>> {\n const context = getExchangeContext(exchange);\n const { config, modelName } = resolveProviderAndModel(\n this.modelId,\n context,\n );\n const merged = this.mergedOptions(context!);\n\n const systemPrompt = resolvePrompt(merged.systemPrompt, exchange);\n const userPrompt =\n resolvePrompt(merged.userPrompt, exchange) ||\n resolveUserPromptDefault(exchange);\n\n const opts: Parameters<typeof callLlm>[0][\"options\"] = {\n temperature: merged.temperature,\n maxTokens: merged.maxTokens,\n };\n if (merged.topP !== undefined) opts.topP = merged.topP;\n if (merged.frequencyPenalty !== undefined)\n opts.frequencyPenalty = merged.frequencyPenalty;\n if (merged.presencePenalty !== undefined)\n opts.presencePenalty = merged.presencePenalty;\n\n const output =\n merged.outputSchema !== undefined\n ? toAiOutputSpec(merged.outputSchema)\n : undefined;\n\n const result = await callLlm({\n config,\n modelId: modelName,\n options: opts,\n systemPrompt,\n userPrompt,\n output,\n });\n\n if (\n result.output === undefined &&\n result.text &&\n merged.outputSchema !== undefined\n ) {\n const fallback = await parseStructuredTextFallback(\n result.text,\n merged.outputSchema,\n );\n if (fallback !== undefined) result.output = fallback;\n }\n\n return result as LlmResultWithOutput<S>;\n }\n\n /**\n * Extract metadata from LLM result for observability.\n * Includes model, provider, and token usage.\n */\n getMetadata(result: unknown): Record<string, unknown> {\n const llmResult = result as LlmResultWithOutput<S>;\n const { providerId } = parseProviderModel(this.modelId);\n\n const metadata: Record<string, unknown> = {\n model: this.modelId,\n provider: providerId,\n };\n\n if (llmResult.usage) {\n if (llmResult.usage[\"inputTokens\"] !== undefined) {\n metadata[\"inputTokens\"] = llmResult.usage[\"inputTokens\"];\n }\n if (llmResult.usage[\"outputTokens\"] !== undefined) {\n metadata[\"outputTokens\"] = llmResult.usage[\"outputTokens\"];\n }\n }\n\n return metadata;\n }\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { Destination } from \"@routecraft/routecraft\";\nimport { LlmDestinationAdapter } from \"./destination.ts\";\nimport type { LlmOptions, LlmResultWithOutput } from \"./types.ts\";\nimport type { RegisteredLlmModelId } from \"../registry.ts\";\n\n/**\n * Creates an LLM destination that calls a provider with a model. Use with .enrich() or .to().\n * Pass model id as \"providerId:modelName\" (e.g. ollama:lfm2.5-thinking). The provider must be\n * registered via llmPlugin({ providers: { ollama: { provider: \"ollama\" }, ... } }).\n * When options.outputSchema is provided, the result type narrows so body.output is typed downstream.\n *\n * @experimental\n * @param modelId - \"providerId:modelName\"; the provider is resolved from the plugin, the model name is sent to the provider.\n * @param options - Optional overrides (systemPrompt, userPrompt, temperature, maxTokens, outputSchema, etc.). User prompt defaults to exchange.body.\n */\nexport function llm<S extends StandardSchemaV1 | undefined = undefined>(\n modelId: RegisteredLlmModelId,\n options?: Partial<LlmOptions> & { outputSchema?: S },\n): Destination<unknown, LlmResultWithOutput<S>> {\n return new LlmDestinationAdapter<S>(modelId, options);\n}\n","import type { LlmPluginOptions, LlmProviderType } from \"./types.ts\";\n\nconst PROVIDERS: LlmProviderType[] = [\n \"openai\",\n \"anthropic\",\n \"openrouter\",\n \"ollama\",\n \"gemini\",\n];\n\nfunction isProvider(s: string): s is LlmProviderType {\n return (PROVIDERS as string[]).includes(s);\n}\n\n/**\n * Validates LLM plugin options at apply time.\n * Key is the provider; value is options for that provider (no provider field).\n */\nexport function validateLlmPluginOptions(options: LlmPluginOptions): void {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"llmPlugin: options must be an object\");\n }\n if (!options.providers || typeof options.providers !== \"object\") {\n throw new TypeError(\n \"llmPlugin: options.providers must be an object (record of provider id → options)\",\n );\n }\n for (const [providerId, opts] of Object.entries(options.providers)) {\n if (opts === undefined) continue;\n if (!opts || typeof opts !== \"object\") {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"] must be an object`,\n );\n }\n if (!isProvider(providerId)) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"] is not a supported provider. Supported: ${PROVIDERS.join(\", \")}`,\n );\n }\n switch (providerId) {\n case \"openai\":\n case \"anthropic\":\n case \"openrouter\":\n case \"gemini\":\n if (\n typeof (opts as { apiKey?: string }).apiKey !== \"string\" ||\n !(opts as { apiKey: string }).apiKey.trim()\n ) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"].apiKey is required`,\n );\n }\n break;\n case \"ollama\":\n if (\n (opts as { baseURL?: string }).baseURL !== undefined &&\n typeof (opts as { baseURL?: string }).baseURL !== \"string\"\n ) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"].baseURL must be a string when provided`,\n );\n }\n if (\n (opts as { modelId?: string }).modelId !== undefined &&\n (typeof (opts as { modelId?: string }).modelId !== \"string\" ||\n !(opts as { modelId: string }).modelId.trim())\n ) {\n throw new TypeError(\n `llmPlugin: providers[\"${providerId}\"].modelId must be a non-empty string when provided`,\n );\n }\n break;\n }\n }\n if (\n options.defaultOptions !== undefined &&\n (typeof options.defaultOptions !== \"object\" ||\n options.defaultOptions === null)\n ) {\n throw new TypeError(\n \"llmPlugin: defaultOptions must be an object when provided\",\n );\n }\n}\n","import type { CraftContext, CraftPlugin } from \"@routecraft/routecraft\";\nimport { ADAPTER_LLM_OPTIONS, ADAPTER_LLM_PROVIDERS } from \"./types.ts\";\nimport type {\n LlmModelConfig,\n LlmPluginOptions,\n LlmProviderOptionsMap,\n} from \"./types.ts\";\nimport { validateLlmPluginOptions } from \"./validate-options.ts\";\n\nconst PROVIDER_IDS = [\n \"openai\",\n \"anthropic\",\n \"openrouter\",\n \"ollama\",\n \"gemini\",\n] as const satisfies readonly LlmModelConfig[\"provider\"][];\n\n/** Normalize provider options to full LlmModelConfig (add provider field from key). */\nfunction toModelConfig<P extends LlmModelConfig[\"provider\"]>(\n providerId: P,\n opts: LlmProviderOptionsMap[P],\n): Extract<LlmModelConfig, { provider: P }> {\n return { provider: providerId, ...opts } as Extract<\n LlmModelConfig,\n { provider: P }\n >;\n}\n\n/**\n * LLM plugin: config-only helper (no lifecycle hooks). Registers providers and optional\n * default options in the context store so routes can use llm(\"providerId:modelName\", options),\n * e.g. llm(\"ollama:lfm2.5-thinking\"). Key is the provider; only set options you need.\n *\n * Advanced users can set the store directly: context.setStore(ADAPTER_LLM_PROVIDERS, map)\n * and context.setStore(ADAPTER_LLM_OPTIONS, partialOptions) without using this plugin.\n *\n * @experimental\n */\nexport function llmPlugin(\n options: LlmPluginOptions = { providers: {} },\n): CraftPlugin {\n validateLlmPluginOptions(options);\n\n return {\n apply(ctx: CraftContext) {\n const map = new Map<string, LlmModelConfig>();\n for (const providerId of PROVIDER_IDS) {\n const opts = options.providers[providerId];\n if (opts !== undefined)\n map.set(providerId, toModelConfig(providerId, opts));\n }\n ctx.setStore(\n ADAPTER_LLM_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n map,\n );\n if (\n options.defaultOptions &&\n Object.keys(options.defaultOptions).length > 0\n ) {\n ctx.setStore(\n ADAPTER_LLM_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n options.defaultOptions,\n );\n }\n },\n };\n}\n","import type {\n DirectRouteMetadata,\n DirectServerOptions,\n Exchange,\n} from \"@routecraft/routecraft\";\nimport type { McpToolRegistry } from \"./tool-registry.ts\";\n\n/**\n * Store key set by mcpPlugin() when applied; routes using .from(mcp(...)) require it.\n * @internal\n */\nexport const MCP_PLUGIN_REGISTERED = Symbol.for(\n \"routecraft.mcp.plugin.registered\",\n);\n\n/**\n * Store key for named remote MCP servers (mcpPlugin({ clients })). Used by McpClient to resolve serverId.\n * @internal\n */\nexport const ADAPTER_MCP_CLIENT_SERVERS = Symbol.for(\n \"routecraft.mcp.client.servers\",\n);\n\n/**\n * Store key for the unified MCP tool registry. Used by agent adapter for tool discovery.\n * @internal\n */\nexport const MCP_TOOL_REGISTRY = Symbol.for(\"routecraft.mcp.tool.registry\");\n\n/**\n * Store key for stdio client managers. Used by destination adapter to call tools on stdio clients.\n * @internal\n */\nexport const MCP_STDIO_MANAGERS = Symbol.for(\"routecraft.mcp.stdio.managers\");\n\ndeclare module \"@routecraft/routecraft\" {\n interface StoreRegistry {\n [MCP_PLUGIN_REGISTERED]: boolean;\n [ADAPTER_MCP_CLIENT_SERVERS]: Map<\n string,\n McpClientHttpConfig | McpClientStdioConfig | string\n >;\n [MCP_TOOL_REGISTRY]: McpToolRegistry;\n [MCP_STDIO_MANAGERS]: Map<\n string,\n {\n callTool(name: string, args: Record<string, unknown>): Promise<unknown>;\n }\n >;\n }\n\n interface RoutecraftHeaders {\n /** The MCP tool name that triggered this exchange. */\n \"routecraft.mcp.tool\"?: string;\n /** The MCP session identifier. */\n \"routecraft.mcp.session\"?: string;\n /** Authenticated subject (from AuthPrincipal). */\n \"routecraft.auth.subject\"?: string;\n /** Authentication scheme used. */\n \"routecraft.auth.scheme\"?: string;\n /** Roles assigned to the authenticated principal. */\n \"routecraft.auth.roles\"?: string[];\n /** Scopes granted to the authenticated principal. */\n \"routecraft.auth.scopes\"?: string[];\n /** Email of the authenticated principal. */\n \"routecraft.auth.email\"?: string;\n /** Display name of the authenticated principal. */\n \"routecraft.auth.name\"?: string;\n /** Token issuer (JWT `iss`). */\n \"routecraft.auth.issuer\"?: string;\n /** Intended audience (JWT `aud`). */\n \"routecraft.auth.audience\"?: string[];\n }\n}\n\n/**\n * HTTP client config for a remote MCP server (Streamable HTTP).\n * Used in mcpPlugin({ clients: { name: config } }).\n */\nexport interface McpClientHttpConfig {\n transport?: \"streamable-http\";\n url: string;\n /** Auth credentials sent on every request to this server. */\n auth?: McpClientAuthOptions;\n}\n\n/**\n * Stdio client config for a local MCP server subprocess.\n * Used in mcpPlugin({ clients: { name: config } }).\n * The plugin spawns the process, manages its lifecycle, and auto-restarts on crash.\n */\nexport interface McpClientStdioConfig {\n transport: \"stdio\";\n /** The executable to run (e.g. \"npx\", \"node\", \"python\"). */\n command: string;\n /** Command line arguments to pass to the executable. */\n args?: string[];\n /** Environment variables for the child process. Defaults to a safe subset of the parent env. */\n env?: Record<string, string>;\n /** Working directory for the child process. Defaults to the current working directory. */\n cwd?: string;\n}\n\n/** Union of client configs accepted by mcpPlugin({ clients }). */\nexport type McpClientServerConfig = McpClientHttpConfig | McpClientStdioConfig;\n\n/**\n * Header keys set on exchanges created by the MCP server.\n * Use these with `exchange.headers[McpHeadersKeys.AUTH_SUBJECT]` for type-safe access.\n *\n * @example\n * ```ts\n * import { McpHeadersKeys } from '@routecraft/ai'\n *\n * .process((ex) => {\n * const user = ex.headers[McpHeadersKeys.AUTH_SUBJECT]\n * const tool = ex.headers[McpHeadersKeys.TOOL]\n * })\n * ```\n */\nexport enum McpHeadersKeys {\n /** The MCP tool name that triggered this exchange. */\n TOOL = \"routecraft.mcp.tool\",\n /** The MCP session identifier. */\n SESSION = \"routecraft.mcp.session\",\n /** Authenticated subject (from AuthPrincipal). */\n AUTH_SUBJECT = \"routecraft.auth.subject\",\n /** Authentication scheme used. */\n AUTH_SCHEME = \"routecraft.auth.scheme\",\n /** Roles assigned to the authenticated principal. */\n AUTH_ROLES = \"routecraft.auth.roles\",\n /** Scopes granted to the authenticated principal. */\n AUTH_SCOPES = \"routecraft.auth.scopes\",\n /** Email of the authenticated principal. */\n AUTH_EMAIL = \"routecraft.auth.email\",\n /** Display name of the authenticated principal. */\n AUTH_NAME = \"routecraft.auth.name\",\n /** Token issuer (JWT `iss`). */\n AUTH_ISSUER = \"routecraft.auth.issuer\",\n /** Intended audience (JWT `aud`). */\n AUTH_AUDIENCE = \"routecraft.auth.audience\",\n}\n\n/**\n * Authenticated user principal resolved from an incoming request.\n * Returned by the auth validator to populate exchange headers for logging,\n * filtering, and access control inside routes.\n *\n * `subject` and `scheme` are always required; everything else is\n * scheme-dependent and may be absent.\n *\n * @experimental\n */\nexport interface AuthPrincipal {\n /** Unique user/client identifier (JWT `sub`, username, API key ID, etc.). */\n subject: string;\n /** Authentication scheme that produced this principal. */\n scheme: \"bearer\" | \"basic\" | \"api-key\" | (string & {});\n /** Role names granted to this principal. */\n roles?: string[];\n /** OAuth 2.0 / JWT scopes. */\n scopes?: string[];\n /** Email address, if known. */\n email?: string;\n /** Display name, if known. */\n name?: string;\n /** Token issuer (JWT `iss`). */\n issuer?: string;\n /** Intended audiences (JWT `aud`). */\n audience?: string[];\n /** Expiry as Unix epoch seconds (JWT `exp`, session expiry). */\n expiresAt?: number;\n /** Arbitrary extra claims. For JWTs this holds the full decoded payload. */\n claims?: Record<string, unknown>;\n}\n\n/**\n * Token info returned by the OAuth `verifyAccessToken` callback.\n * Mirrors the MCP SDK's `AuthInfo` with only the fields routecraft needs.\n *\n * @experimental\n */\nexport interface OAuthTokenInfo {\n /** The raw access token string. */\n token: string;\n /** OAuth client ID that obtained this token. */\n clientId: string;\n /** Scopes granted to the token. */\n scopes: string[];\n /** Expiry as Unix epoch seconds. */\n expiresAt?: number;\n}\n\n/**\n * OAuth client info returned by the `getClient` callback.\n * Mirrors the MCP SDK's `OAuthClientInformationFull` with only the fields routecraft needs.\n *\n * Field names use snake_case to match the OAuth 2.0 Dynamic Client Registration\n * specification (RFC 7591) and the MCP SDK's `OAuthClientInformationFull`.\n *\n * @experimental\n */\nexport interface OAuthClientInfo {\n /** The client identifier. */\n client_id: string;\n /** Allowed redirect URIs for authorization code flow. */\n redirect_uris: string[];\n /** Human-readable client name. */\n client_name?: string;\n /** Client secret (for confidential clients). */\n client_secret?: string;\n}\n\n/**\n * Endpoint URLs for the upstream OAuth provider (used by the proxy).\n *\n * @experimental\n */\nexport interface OAuthProxyEndpoints {\n /** Authorization endpoint URL. */\n authorizationUrl: string;\n /** Token endpoint URL. */\n tokenUrl: string;\n /** Token revocation endpoint URL. */\n revocationUrl?: string;\n /** Dynamic client registration endpoint URL. */\n registrationUrl?: string;\n}\n\n/**\n * Validator-based auth: bearer token checked on every request.\n * Used with `jwt()` helper or custom validator functions.\n *\n * @example\n * ```ts\n * import { jwt } from \"@routecraft/ai\";\n * auth: jwt({ secret: process.env.JWT_SECRET! })\n *\n * // Custom validator\n * auth: {\n * validator: async (token) => {\n * const user = await lookupApiKey(token);\n * if (!user) return null;\n * return { subject: user.id, scheme: \"api-key\", roles: user.roles };\n * }\n * }\n * ```\n *\n * @experimental\n */\nexport interface McpValidatorAuthOptions {\n /**\n * Validator function called with the raw bearer token on every request.\n *\n * Return an {@link AuthPrincipal} to allow access; return `null` or `false`\n * to reject with 401. May be async.\n *\n * If the function throws, the server responds with 500.\n * Validators should catch expected failures (e.g. JWT expiry) and return `null`.\n */\n validator: McpAuthValidator;\n}\n\n/**\n * OAuth provider auth: full OAuth 2.1 server flow with proxy to upstream IdP.\n * Mounts discovery, authorization, token, and revocation endpoints alongside `/mcp`.\n * Uses the MCP SDK's `ProxyOAuthServerProvider` and `mcpAuthRouter` internally.\n *\n * @example\n * ```ts\n * import { oauth } from \"@routecraft/ai\";\n * auth: oauth({\n * issuerUrl: \"https://mcp.example.com\",\n * endpoints: {\n * authorizationUrl: \"https://idp.example.com/authorize\",\n * tokenUrl: \"https://idp.example.com/token\",\n * },\n * verifyAccessToken: async (token) => ({\n * token, clientId: \"my-client\", scopes: [\"read\"],\n * }),\n * getClient: async (clientId) => ({\n * client_id: clientId, redirect_uris: [\"http://localhost:3000/callback\"],\n * }),\n * })\n * ```\n *\n * @experimental\n */\nexport interface McpOAuthAuthOptions {\n /** Discriminant for the union. Always `\"oauth\"`. */\n provider: \"oauth\";\n /** Issuer URL for OAuth metadata discovery. Must be HTTPS in production. */\n issuerUrl: string | URL;\n /** Base URL for OAuth endpoints (defaults to issuerUrl). */\n baseUrl?: string | URL;\n /** Upstream OAuth provider endpoints to proxy. */\n endpoints: OAuthProxyEndpoints;\n /**\n * Verify an access token and return token info.\n * Called on every authenticated request to `/mcp`.\n */\n verifyAccessToken: (token: string) => Promise<OAuthTokenInfo>;\n /**\n * Look up a registered OAuth client by ID.\n * Return `undefined` to reject the client.\n */\n getClient: (clientId: string) => Promise<OAuthClientInfo | undefined>;\n /** OAuth scopes the server advertises as supported. */\n scopesSupported?: string[];\n /** Scopes required on every request to `/mcp`. */\n requiredScopes?: string[];\n /** URL to service documentation (included in OAuth metadata). */\n serviceDocumentationUrl?: string | URL;\n /** Human-readable resource name (included in OAuth metadata). */\n resourceName?: string;\n}\n\n/**\n * Authentication options for the MCP HTTP server.\n * Only applies when `transport` is `\"http\"`. Ignored for stdio.\n *\n * Two strategies are supported:\n * - `Validator`: simple bearer token check via `jwt()` or custom function.\n * - `OAuth`: full OAuth 2.1 server flow via `oauth()`, proxying to an upstream IdP.\n *\n * @experimental\n */\nexport type McpHttpAuthOptions = McpValidatorAuthOptions | McpOAuthAuthOptions;\n\n/**\n * Type guard: returns `true` when auth is configured for OAuth provider mode.\n */\nexport function isOAuthAuth(\n auth: McpHttpAuthOptions,\n): auth is McpOAuthAuthOptions {\n return \"provider\" in auth && auth.provider === \"oauth\";\n}\n\n/**\n * A function that validates a bearer token and resolves the authenticated principal.\n * Called on every incoming HTTP request.\n * May be synchronous or asynchronous.\n *\n * Return an {@link AuthPrincipal} to allow access, or `null` / `false` to reject with 401.\n * If the function throws, the server responds with 500.\n *\n * @experimental\n */\nexport type McpAuthValidator = (\n token: string,\n) => AuthPrincipal | null | false | Promise<AuthPrincipal | null | false>;\n\n/**\n * A function that provides a bearer token for outbound requests.\n * Called on every request; may be synchronous or asynchronous.\n * Useful for dynamic tokens (JWT refresh, rotating API keys, etc.).\n *\n * @experimental\n */\nexport type McpClientTokenProvider = () => string | Promise<string>;\n\n/**\n * Auth config for an outbound MCP HTTP client connection.\n * Passed as request headers on every connection to the remote server.\n *\n * @experimental\n */\nexport interface McpClientAuthOptions {\n /**\n * Bearer token(s) or provider for the `Authorization` header.\n * Builds `Authorization: Bearer <token>`.\n *\n * - `string` -- single static token.\n * - `string[]` -- array of tokens; one is selected per request (round-robin).\n * - `() => string | Promise<string>` -- called per request for dynamic tokens.\n */\n token?: string | string[] | McpClientTokenProvider;\n /**\n * Additional headers to include on every request to the remote server.\n * If `Authorization` is set here, it overrides `token`.\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Options for the MCP plugin (mcpPlugin).\n * One plugin per adapter: this is the single options type for the MCP plugin.\n */\nexport interface McpPluginOptions {\n /** Server name in MCP protocol handshake. Default: \"routecraft\" */\n name?: string;\n\n /** Server version. Default: \"1.0.0\" */\n version?: string;\n\n /** Transport mode for MCP server. Default: \"stdio\" */\n transport?: \"stdio\" | \"http\";\n\n /** Port for the streamable-http MCP server. Default: 3001 (only used with transport: \"http\") */\n port?: number;\n\n /** Host to bind to. Default: \"localhost\" (only used with transport: \"http\") */\n host?: string;\n\n /**\n * Authentication for the HTTP transport. When set, every request to `/mcp` must\n * include a valid `Authorization: Bearer <token>` header. Ignored for stdio.\n *\n * @example\n * ```ts\n * import { jwt } from \"@routecraft/ai\";\n * auth: jwt({ secret: process.env.JWT_SECRET! })\n * ```\n */\n auth?: McpHttpAuthOptions;\n\n /**\n * Filter which tools to expose. Default: all mcp() routes.\n * Can be an array of endpoint names or a filter function.\n */\n tools?: string[] | ((meta: DirectRouteMetadata) => boolean);\n\n /**\n * Named remote MCP servers for .to(mcp(\"name:tool\")).\n * Keys are server names; values are HTTP or stdio config.\n * Stdio clients are managed as subprocesses with auto-restart.\n * HTTP clients are used for ephemeral tool calls.\n */\n clients?: Record<string, McpClientHttpConfig | McpClientStdioConfig>;\n\n /**\n * Max auto-restart attempts for stdio clients before giving up.\n * Applies to all stdio clients. Default: 5.\n */\n maxRestarts?: number;\n\n /**\n * Base delay in ms before the first restart attempt.\n * Subsequent attempts use exponential backoff. Default: 1000.\n */\n restartDelayMs?: number;\n\n /**\n * Multiplier for exponential backoff between restart attempts.\n * Delay = restartDelayMs * (restartBackoffMultiplier ^ restartCount). Default: 2.\n */\n restartBackoffMultiplier?: number;\n\n /**\n * Interval in ms to re-list tools from HTTP clients.\n * Set to 0 to disable periodic refresh. Default: 60000 (60s).\n */\n toolRefreshIntervalMs?: number;\n}\n\n/**\n * Options for mcp() when used as a server in .from().\n * Description is required for AI/MCP discoverability.\n */\nexport interface McpServerOptions extends DirectServerOptions {\n /** Human-readable description (required for MCP tools). */\n description: string;\n}\n\nexport type McpOptions = McpServerOptions;\n\n/**\n * Extracts MCP tool arguments from an exchange. Default implementation uses exchange.body.\n */\nexport type McpArgsExtractor = (\n exchange: Exchange<unknown>,\n) => Record<string, unknown>;\n\n/**\n * Options for mcp() when used as a Client in .to() to call a remote MCP server.\n * Provide either url (inline HTTP) or serverId (from plugin/store); tool is required.\n *\n * Supported transports:\n * - **HTTP:** use `url` for an inline endpoint or `serverId` for a named backend.\n * - **Stdio:** use `serverId` referencing a stdio client from mcpPlugin({ clients }).\n * The destination adapter resolves the manager from the context store and calls\n * tools directly on the subprocess -- no HTTP involved.\n */\nexport interface McpClientOptions {\n /** URL of the remote MCP server (HTTP/HTTPS only). Omit when using serverId. */\n url?: string;\n /** Tool name to invoke. If omitted, exchange body may specify it or a default applies. */\n tool?: string;\n /** Server id from context store; resolved to URL at runtime. Use when URL is registered via mcpPlugin({ clients }). */\n serverId?: string;\n /**\n * Extract tool arguments from the exchange. Receives the full exchange.\n * Default: body as object -> use as args; otherwise { input: body }.\n */\n args?: McpArgsExtractor;\n /**\n * Auth credentials for the outbound HTTP connection.\n * When using `serverId`, auth flows automatically from `mcpPlugin({ clients })`\n * so this field is rarely needed. Use it to override registered auth or to\n * supply credentials when using inline `url`.\n */\n auth?: McpClientAuthOptions;\n}\n\n/**\n * Represents a tool exposed via MCP\n */\nexport interface McpTool {\n name: string;\n description?: string;\n inputSchema: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n [key: string]: unknown;\n };\n}\n\n/**\n * A tool entry in the unified MCP tool registry.\n * Combines local mcp() route tools and remote client tools (stdio and HTTP).\n */\nexport interface McpToolRegistryEntry {\n /** Tool name (unique within a source, may collide across sources). */\n name: string;\n /** Human-readable description of the tool. */\n description?: string;\n /** JSON Schema for tool input. */\n inputSchema: Record<string, unknown>;\n /** Source server ID. Local mcp() routes use \"local\". */\n source: string;\n /** Transport type of the source. */\n transport: \"stdio\" | \"http\" | \"local\";\n}\n\n/**\n * MCP tool call result\n */\nexport interface McpToolResult {\n content: Array<{\n type: \"text\" | \"image\" | \"resource\";\n text?: string;\n data?: string;\n mimeType?: string;\n }>;\n isError?: boolean;\n}\n","/**\n * Brand symbol for MCP adapter type checking.\n * Used internally to identify MCP adapters.\n * @experimental\n */\nexport const BRAND_MCP_ADAPTER = Symbol.for(\"routecraft.mcp.adapter\");\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n direct,\n rcError,\n type CraftContext,\n type Exchange,\n type ExchangeHeaders,\n type Source,\n} from \"@routecraft/routecraft\";\nimport { MCP_PLUGIN_REGISTERED, type McpServerOptions } from \"../../types.ts\";\nimport type { McpMessage } from \"./types.ts\";\nimport { BRAND_MCP_ADAPTER } from \"./shared.ts\";\n\n/**\n * McpSourceAdapter implements the Source interface for the MCP adapter.\n *\n * This adapter is used when mcp() is called with two arguments:\n * - `mcp(endpoint, options)` where options contains a description (required for MCP)\n *\n * It delegates to the direct() adapter internally after validating the MCP plugin is registered.\n * The MCP plugin will expose these routes as tools via the MCP protocol.\n */\nexport class McpSourceAdapter<\n S extends StandardSchemaV1 | undefined = undefined,\n> implements Source<McpMessage<S>> {\n readonly adapterId: string = \"routecraft.adapter.mcp\";\n\n private endpoint: string;\n private options: McpServerOptions & { schema?: S };\n\n constructor(endpoint: string, options: McpServerOptions & { schema?: S }) {\n (this as unknown as Record<symbol, boolean>)[BRAND_MCP_ADAPTER] = true;\n\n // Validate endpoint and options\n if (typeof endpoint !== \"string\") {\n throw rcError(\"RC5003\", undefined, {\n message: \"Dynamic endpoints cannot be used as source\",\n suggestion:\n \"Use a static string endpoint for source: .from(mcp('endpoint', options)).\",\n });\n }\n\n if (\"url\" in options || \"serverId\" in options) {\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp() with url or serverId must be used as destination: .to(mcp({ url, tool }))\",\n suggestion:\n \"Use .to(mcp({ url: '...', tool: '...' })) to call a remote MCP server.\",\n });\n }\n\n if (\n \"args\" in options &&\n (options as { args?: unknown }).args !== undefined &&\n !(\"description\" in options)\n ) {\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp(endpoint, { args }) is for client usage with a 'server:tool' target, not for defining a source\",\n suggestion:\n \"Use .to(mcp('server:tool', { args })) to call a remote tool, or .from(mcp('endpoint', { description: '...' })) to define a source.\",\n });\n }\n\n if (\n !(\"description\" in options) ||\n typeof options.description !== \"string\"\n ) {\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp(endpoint, options) as source requires options.description\",\n suggestion:\n \"Use .from(mcp('endpoint', { description: '...' })) to define a source.\",\n });\n }\n\n this.endpoint = endpoint;\n this.options = options;\n }\n\n async subscribe(\n context: CraftContext,\n handler: (\n message: McpMessage<S>,\n headers?: ExchangeHeaders,\n ) => Promise<Exchange>,\n abortController: AbortController,\n onReady?: () => void,\n ): Promise<void> {\n // Verify MCP plugin is registered\n const registered = context.getStore(\n MCP_PLUGIN_REGISTERED as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as boolean | undefined;\n if (registered !== true) {\n throw new Error(\n \"MCP plugin required: routes using .from(mcp(...)) require the MCP plugin. Add mcpPlugin() to your config: plugins: [mcpPlugin()].\",\n );\n }\n\n // Delegate to direct adapter\n const directAdapter = direct(this.endpoint, this.options);\n return directAdapter.subscribe(context, handler, abortController, onReady);\n }\n}\n","/**\n * Extract content from an MCP tool response.\n *\n * - Single text item: returns the string directly for convenience.\n * - Multiple items or non-text items: returns the full content array so\n * callers can inspect type/text/data on each entry.\n * - No content: returns the raw response object.\n */\nexport function extractContent(\n response: {\n content?: Array<{ type: string; text?: string; data?: string }>;\n } | null,\n): unknown {\n const content = response?.content;\n if (!Array.isArray(content) || content.length === 0) return response;\n\n // Single text entry: return the string for backward compatibility\n if (content.length === 1) {\n const item = content[0];\n if (item.type === \"text\" && typeof item.text === \"string\") return item.text;\n if (typeof item.data === \"string\") return item.data;\n }\n\n // Multiple items or non-text: return the full array\n return content;\n}\n","import type { McpClientAuthOptions } from \"./types.ts\";\n\n/** Round-robin index for array tokens, keyed by the array reference. */\nconst rrIndexes = new WeakMap<string[], number>();\n\n/**\n * Resolve the raw token value from the various accepted forms.\n * @internal\n */\nasync function resolveToken(\n token: NonNullable<McpClientAuthOptions[\"token\"]>,\n): Promise<string> {\n if (typeof token === \"function\") {\n return token();\n }\n if (Array.isArray(token)) {\n if (token.length === 0) {\n throw new Error(\"McpClientAuthOptions.token array must not be empty\");\n }\n const idx = (rrIndexes.get(token) ?? 0) % token.length;\n rrIndexes.set(token, idx + 1);\n return token[idx];\n }\n return token;\n}\n\n/**\n * Build HTTP headers from MCP client auth options.\n * Returns undefined when no headers are needed.\n * @internal\n */\nexport async function buildAuthHeaders(\n auth?: McpClientAuthOptions,\n): Promise<Record<string, string> | undefined> {\n if (!auth) return undefined;\n\n const headers: Record<string, string> = {};\n const customHeaders = auth.headers ?? {};\n\n // Check if custom headers provide an Authorization override (case-insensitive)\n const authorizationOverride = Object.entries(customHeaders).find(\n ([name]) => name.toLowerCase() === \"authorization\",\n )?.[1];\n\n if (authorizationOverride) {\n headers[\"Authorization\"] = authorizationOverride;\n } else if (auth.token !== undefined) {\n const resolved = await resolveToken(auth.token);\n if (resolved.length === 0) {\n throw new Error(\n \"McpClientAuthOptions.token must be a non-empty string when provided\",\n );\n }\n headers[\"Authorization\"] = `Bearer ${resolved}`;\n }\n\n // Merge remaining custom headers, skipping any authorization variant\n for (const [name, value] of Object.entries(customHeaders)) {\n if (name.toLowerCase() !== \"authorization\") {\n headers[name] = value;\n }\n }\n\n return Object.keys(headers).length > 0 ? headers : undefined;\n}\n","import type { Exchange, Destination } from \"@routecraft/routecraft\";\nimport { getExchangeContext } from \"@routecraft/routecraft\";\nimport type {\n McpClientOptions,\n McpArgsExtractor,\n McpClientAuthOptions,\n McpClientHttpConfig,\n} from \"../../types.ts\";\nimport { ADAPTER_MCP_CLIENT_SERVERS, MCP_STDIO_MANAGERS } from \"../../types.ts\";\nimport { BRAND_MCP_ADAPTER } from \"./shared.ts\";\nimport { extractContent } from \"../../extract-content.ts\";\nimport { buildAuthHeaders } from \"../../build-auth-headers.ts\";\n\n/** Ensure inline url is HTTP(S) only. Stdio clients are resolved via MCP_STDIO_MANAGERS store. */\nfunction assertHttpUrl(url: string): void {\n const trimmed = url.trim().toLowerCase();\n if (!trimmed.startsWith(\"http://\") && !trimmed.startsWith(\"https://\")) {\n throw new Error(\n `MCP client: url must be HTTP or HTTPS. Stdio is not supported in routes; register stdio clients via mcpPlugin({ clients: { name: { command, args } } }). Got: \"${url.slice(0, 50)}${url.length > 50 ? \"...\" : \"\"}\"`,\n );\n }\n}\n\n/**\n * Look up the registered server config from the context store.\n * Returns undefined when no context or no matching serverId.\n * Backward-compat: store value may be a plain string (url only).\n */\nfunction resolveServerConfig(\n options: McpClientOptions,\n context: ReturnType<typeof getExchangeContext>,\n): McpClientHttpConfig | string | undefined {\n if (!options.serverId || !context) return undefined;\n const servers = context.getStore(\n ADAPTER_MCP_CLIENT_SERVERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, McpClientHttpConfig | string> | undefined;\n return servers?.get(options.serverId);\n}\n\n/**\n * Resolves the URL and auth for the MCP server from options or context (serverId).\n * Returns both in a single lookup to avoid duplicate store reads.\n */\nfunction resolveConnection(\n options: McpClientOptions,\n context: ReturnType<typeof getExchangeContext>,\n): { url: string; auth?: McpClientAuthOptions | undefined } {\n if (options.url) {\n assertHttpUrl(options.url);\n return { url: options.url, auth: options.auth };\n }\n if (options.serverId && !context) {\n throw new Error(\n `MCP client: serverId \"${options.serverId}\" requires a context to resolve. Ensure the exchange has context (e.g. from a route) so store \"${String(ADAPTER_MCP_CLIENT_SERVERS)}\" can be read.`,\n );\n }\n if (options.serverId && context) {\n const config = resolveServerConfig(options, context);\n if (!config) {\n throw new Error(\n `MCP client: serverId \"${options.serverId}\" not found in context store. Register it with context store key \"${String(ADAPTER_MCP_CLIENT_SERVERS)}\".`,\n );\n }\n const url = typeof config === \"string\" ? config : config.url;\n const auth =\n options.auth ??\n (typeof config === \"object\" && \"auth\" in config\n ? config.auth\n : undefined);\n return { url, auth };\n }\n throw new Error(\n \"MCP client: either url or serverId must be provided in McpClientOptions.\",\n );\n}\n\n/**\n * Default args extractor: use exchange body as tool arguments.\n * If body is a non-null object, use it as the args; otherwise use { input: body }.\n */\nexport const defaultArgs: McpArgsExtractor = (exchange) =>\n typeof exchange.body === \"object\" && exchange.body !== null\n ? (exchange.body as Record<string, unknown>)\n : { input: exchange.body };\n\n/**\n * McpDestinationAdapter implements the Destination interface for the MCP adapter.\n *\n * This adapter is used when mcp() is called with client options:\n * - `mcp({ url, tool })` - Direct HTTP URL\n * - `mcp({ serverId, tool })` - Server registered via mcpPlugin\n * - `mcp('server:tool')` - Shorthand for serverId:tool\n *\n * It makes HTTP calls to remote MCP servers using the MCP SDK.\n */\nexport class McpDestinationAdapter implements Destination<unknown, unknown> {\n readonly adapterId: string = \"routecraft.adapter.mcp\";\n\n constructor(private readonly options: McpClientOptions) {\n (this as unknown as Record<symbol, boolean>)[BRAND_MCP_ADAPTER] = true;\n\n // Validate client options\n if (!options.url && !options.serverId) {\n throw new Error(\n \"MCP client: either url or serverId must be provided in McpClientOptions.\",\n );\n }\n\n if (options.url && options.serverId) {\n throw new Error(\n \"MCP client: cannot provide both url and serverId. Use either url for direct HTTP or serverId for registered servers.\",\n );\n }\n }\n\n async send(exchange: Exchange<unknown>): Promise<unknown> {\n const context = getExchangeContext(exchange);\n const toolName =\n this.options.tool ??\n (typeof exchange.body === \"object\" &&\n exchange.body !== null &&\n \"tool\" in exchange.body &&\n typeof (exchange.body as { tool: string }).tool === \"string\"\n ? (exchange.body as { tool: string }).tool\n : undefined);\n if (!toolName) {\n throw new Error(\n \"MCP client: tool name required. Set options.tool or exchange.body.tool.\",\n );\n }\n const argsExtractor = this.options.args ?? defaultArgs;\n const args = argsExtractor(exchange);\n\n // Check for stdio manager first (registered via mcpPlugin)\n if (this.options.serverId && context) {\n const stdioManagers = context.getStore(\n MCP_STDIO_MANAGERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as\n | Map<\n string,\n {\n callTool(\n name: string,\n args: Record<string, unknown>,\n ): Promise<unknown>;\n }\n >\n | undefined;\n const manager = stdioManagers?.get(this.options.serverId);\n if (manager) {\n const result = await manager.callTool(toolName, args);\n if (result && typeof result === \"object\") {\n (result as Record<string, unknown>)[\"metadata\"] = {\n toolName,\n transport: \"stdio\",\n serverId: this.options.serverId,\n };\n }\n return result;\n }\n\n // Guard: if the registered config is stdio-type but the manager is missing,\n // throw a clear error instead of falling through to HTTP (which would fail\n // confusingly since stdio configs have no url property).\n const servers = context.getStore(\n ADAPTER_MCP_CLIENT_SERVERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, unknown> | undefined;\n const serverConfig = servers?.get(this.options.serverId);\n if (\n serverConfig &&\n typeof serverConfig === \"object\" &&\n \"transport\" in serverConfig &&\n (serverConfig as { transport: string }).transport === \"stdio\"\n ) {\n throw new Error(\n `MCP client: stdio server \"${this.options.serverId}\" is not running. Ensure mcpPlugin is applied and the stdio client started successfully.`,\n );\n }\n }\n\n // Fall through to HTTP\n const { url, auth } = resolveConnection(this.options, context);\n const result = await this.callRemoteTool(url, toolName, args, auth);\n\n // Attach metadata to result for getMetadata() to read (eliminates race condition)\n if (result && typeof result === \"object\") {\n (result as Record<string, unknown>)[\"metadata\"] = {\n toolName,\n url,\n transport: \"http\",\n ...(this.options.serverId ? { serverId: this.options.serverId } : {}),\n };\n }\n\n return result;\n }\n\n /**\n * Extract metadata from MCP adapter execution.\n * Reads metadata from the result object to avoid race conditions with concurrent exchanges.\n */\n getMetadata(result: unknown): Record<string, unknown> {\n if (result && typeof result === \"object\" && \"metadata\" in result) {\n return (result as { metadata: Record<string, unknown> }).metadata;\n }\n return {\n toolName: \"unknown\",\n transport: \"unknown\",\n };\n }\n\n private async callRemoteTool(\n serverUrl: string,\n toolName: string,\n args: Record<string, unknown>,\n auth?: McpClientAuthOptions,\n ): Promise<unknown> {\n let clientModule: {\n Client: new (\n info: { name: string; version: string },\n options?: { capabilities?: Record<string, unknown> },\n ) => unknown;\n };\n let transportModule: {\n StreamableHTTPClientTransport: new (\n url: URL,\n options?: {\n sessionId?: string;\n requestInit?: { headers?: Record<string, string> };\n },\n ) => unknown;\n };\n try {\n clientModule = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n transportModule =\n await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n } catch {\n throw new Error(\n 'MCP client requires \"@modelcontextprotocol/sdk\". Install it with: pnpm add @modelcontextprotocol/sdk',\n );\n }\n const Client = clientModule.Client;\n const StreamableHTTPClientTransport =\n transportModule.StreamableHTTPClientTransport;\n\n const url = new URL(serverUrl);\n const headers = await buildAuthHeaders(auth);\n const transportOptions = headers ? { requestInit: { headers } } : undefined;\n const transport = new StreamableHTTPClientTransport(url, transportOptions);\n const clientInfo = { name: \"routecraft-mcp-client\", version: \"1.0.0\" };\n const client = new (Client as new (\n info: { name: string; version: string },\n options?: { capabilities?: Record<string, unknown> },\n ) => InstanceType<typeof clientModule.Client>)(clientInfo, {\n capabilities: {},\n });\n try {\n const connect = (\n client as unknown as { connect(transport: unknown): Promise<void> }\n ).connect;\n await connect.call(client, transport);\n\n const callTool = (\n client as unknown as {\n callTool(params: {\n name: string;\n arguments?: Record<string, unknown>;\n }): Promise<{ content?: Array<{ type: string; text?: string }> }>;\n }\n ).callTool;\n const response = await callTool.call(client, {\n name: toolName,\n arguments: args,\n });\n\n return extractContent(response);\n } finally {\n const clientCleanup = client as unknown as {\n close?: () => void | Promise<void>;\n disconnect?: () => void | Promise<void>;\n };\n const closeOrDisconnect = clientCleanup.close ?? clientCleanup.disconnect;\n if (typeof closeOrDisconnect === \"function\") {\n try {\n await Promise.resolve(closeOrDisconnect.call(client));\n } catch {\n // Ignore cleanup errors so original error propagates\n }\n }\n const transportCleanup = transport as unknown as {\n close?: () => void | Promise<void>;\n destroy?: () => void;\n };\n const closeOrDestroy = transportCleanup.close ?? transportCleanup.destroy;\n if (typeof closeOrDestroy === \"function\") {\n try {\n await Promise.resolve(closeOrDestroy.call(transport));\n } catch {\n // Ignore cleanup errors so original error propagates\n }\n }\n }\n }\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n rcError,\n type Exchange,\n type Source,\n type Destination,\n} from \"@routecraft/routecraft\";\nimport type {\n McpArgsExtractor,\n McpClientOptions,\n McpServerOptions,\n} from \"../../types.ts\";\nimport type { RegisteredMcpShorthand } from \"../../../registry.ts\";\nimport { McpSourceAdapter } from \"./source.ts\";\nimport { McpDestinationAdapter } from \"./destination.ts\";\nimport type { McpMessage } from \"./types.ts\";\n\n/**\n * Creates an MCP adapter for communicating with MCP servers.\n *\n * - **Source (for `.from()`):** Call with two arguments: `mcp(endpoint, options)`.\n * Options must include a `description` field (required for MCP tool exposure).\n * Requires the MCP plugin: `plugins: [mcpPlugin()]`.\n * Body type is inferred from `options.schema` when provided.\n *\n * - **Destination (for `.to()` / `.tap()`):** Call with one argument containing client options:\n * - `mcp({ url, tool })` - Direct HTTP URL to remote MCP server\n * - `mcp({ serverId, tool })` - Server ID registered via mcpPlugin({ clients })\n * - `mcp('server:tool', { args? })` - Shorthand for serverId:tool with optional args extractor\n *\n * The MCP adapter delegates to the direct() adapter for source routes and makes HTTP calls\n * to remote MCP servers for destination routes.\n *\n * @param endpointOrOptions - Endpoint string (source) or client options object (destination) or 'server:tool' string (destination)\n * @param options - Server options (source) or args extractor (destination)\n * @returns Source when called with two arguments; Destination when called with one argument\n *\n * @experimental\n *\n * @example\n * ```typescript\n * // Source route (MCP tool)\n * .from(mcp('/search', { description: 'Search documents', schema: mySchema }))\n *\n * // Destination (call remote MCP server)\n * .to(mcp({ url: 'http://localhost:3001/mcp', tool: 'search' }))\n * .to(mcp({ serverId: 'my-server', tool: 'search' }))\n * .to(mcp('my-server:search'))\n * .to(mcp('my-server:search', { args: (ex) => ex.body.params }))\n * ```\n */\nexport function mcp<S extends StandardSchemaV1 | undefined = undefined>(\n endpoint: string,\n options: McpServerOptions & { schema?: S },\n): Source<McpMessage<S>>;\nexport function mcp(\n clientOptions: McpClientOptions,\n): Destination<unknown, unknown>;\nexport function mcp(\n shorthand: RegisteredMcpShorthand,\n options?: { args?: McpArgsExtractor },\n): Destination<unknown, unknown>;\nexport function mcp<S extends StandardSchemaV1 | undefined = undefined>(\n endpointOrOptions:\n | string\n | ((exchange: Exchange<McpMessage<S>>) => string)\n | McpClientOptions,\n options?: (McpServerOptions & { schema?: S }) | { args?: McpArgsExtractor },\n): Source<McpMessage<S>> | Destination<unknown, unknown> {\n // Client: object with url or serverId\n if (\n typeof endpointOrOptions === \"object\" &&\n endpointOrOptions !== null &&\n (\"url\" in endpointOrOptions || \"serverId\" in endpointOrOptions)\n ) {\n const clientOpts = endpointOrOptions as McpClientOptions;\n if (typeof clientOpts.auth?.token === \"string\") {\n if (clientOpts.auth.token.trim().length === 0) {\n throw new TypeError(\n \"mcp(): auth.token must be a non-empty string when provided\",\n );\n }\n }\n if (Array.isArray(clientOpts.auth?.token)) {\n if (clientOpts.auth.token.length === 0) {\n throw new TypeError(\"mcp(): auth.token array must not be empty\");\n }\n for (let i = 0; i < clientOpts.auth.token.length; i++) {\n const entry = clientOpts.auth.token[i];\n if (typeof entry !== \"string\" || entry.trim().length === 0) {\n throw new TypeError(\n `mcp(): auth.token[${i}] must be a non-empty string`,\n );\n }\n }\n }\n return new McpDestinationAdapter(clientOpts);\n }\n\n // Client: \"server:tool\" string with optional args\n const isClientColonOptions =\n options === undefined ||\n (typeof options === \"object\" &&\n options !== null &&\n !(\"description\" in options));\n if (\n typeof endpointOrOptions === \"string\" &&\n endpointOrOptions.includes(\":\") &&\n isClientColonOptions\n ) {\n const colonIndex = endpointOrOptions.indexOf(\":\");\n const serverId = endpointOrOptions.slice(0, colonIndex);\n const tool = endpointOrOptions.slice(colonIndex + 1);\n const clientOptions: McpClientOptions = { serverId, tool };\n if (\n options !== undefined &&\n typeof options === \"object\" &&\n \"args\" in options &&\n options.args !== undefined\n ) {\n clientOptions.args = options.args as McpArgsExtractor;\n }\n return new McpDestinationAdapter(clientOptions);\n }\n\n // Server: endpoint + options with description\n const endpoint = endpointOrOptions as\n | string\n | ((exchange: Exchange<McpMessage<S>>) => string);\n if (options !== undefined) {\n return new McpSourceAdapter<S>(\n endpoint as string,\n options as McpServerOptions & { schema?: S },\n );\n }\n\n // Invalid: endpoint only (no options) — direct not supported\n throw rcError(\"RC5003\", undefined, {\n message:\n \"mcp() with only an endpoint is not supported. Use direct('endpoint') for in-process. For MCP server use .from(mcp('endpoint', { description: '...' })); for client use .to(mcp({ url, tool })) or .to(mcp('server:tool', { args })).\",\n suggestion:\n \"Use .from(mcp('endpoint', { description: '...' })) or .to(mcp({ url, tool })) or direct('endpoint').\",\n });\n}\n\n// Re-export types for public API\nexport type {\n McpMessage,\n McpArgsExtractor,\n McpClientHttpConfig,\n} from \"./types\";\nexport { BRAND_MCP_ADAPTER } from \"./shared\";\nexport { defaultArgs } from \"./destination\";\n","import { createHmac, createVerify, timingSafeEqual } from \"node:crypto\";\nimport type { AuthPrincipal, McpHttpAuthOptions } from \"./types.ts\";\n\n/**\n * Supported HMAC algorithms for JWT signature verification.\n * Maps JWT `alg` header values to Node.js `crypto.createHmac` digest names.\n */\nconst HMAC_ALGORITHMS = {\n HS256: \"sha256\",\n HS384: \"sha384\",\n HS512: \"sha512\",\n} as const;\n\n/**\n * Supported RSA algorithms for JWT signature verification.\n * Maps JWT `alg` header values to Node.js `crypto.createVerify` algorithm names.\n */\nconst RSA_ALGORITHMS = {\n RS256: \"RSA-SHA256\",\n RS384: \"RSA-SHA384\",\n RS512: \"RSA-SHA512\",\n} as const;\n\ntype HmacAlgorithm = keyof typeof HMAC_ALGORITHMS;\ntype RsaAlgorithm = keyof typeof RSA_ALGORITHMS;\n\n/**\n * HMAC (symmetric) JWT options.\n * Uses a shared secret to sign and verify tokens.\n *\n * @experimental\n */\nexport interface JwtHmacOptions {\n /** Shared secret used to verify HMAC signatures. */\n secret: string;\n /**\n * HMAC algorithm to accept. Default: `\"HS256\"`.\n * The helper rejects tokens whose `alg` header does not match.\n */\n algorithm?: HmacAlgorithm;\n /**\n * Clock skew tolerance in seconds for `exp` and `nbf` checks.\n * Default: `0` (no tolerance).\n */\n clockToleranceSec?: number;\n}\n\n/**\n * RSA (asymmetric) JWT options.\n * Uses a public key to verify signatures. Only the public key is needed\n * since the server only verifies, never signs.\n *\n * @experimental\n */\nexport interface JwtRsaOptions {\n /** PEM-encoded public key or certificate used to verify RSA signatures. */\n publicKey: string;\n /**\n * RSA algorithm to accept. Default: `\"RS256\"`.\n * The helper rejects tokens whose `alg` header does not match.\n */\n algorithm?: RsaAlgorithm;\n /**\n * Clock skew tolerance in seconds for `exp` and `nbf` checks.\n * Default: `0` (no tolerance).\n */\n clockToleranceSec?: number;\n}\n\n/**\n * Options for the built-in JWT auth helper.\n * Supports HMAC (symmetric) and RSA (asymmetric) signing.\n *\n * Discriminated by key: pass `secret` for HMAC, `publicKey` for RSA.\n *\n * @experimental\n */\nexport type JwtAuthOptions = JwtHmacOptions | JwtRsaOptions;\n\n/**\n * Decode and parse the JWT header and payload segments.\n * Returns `null` if the token is malformed or not valid JSON.\n */\nfunction decodeToken(token: string): {\n headerB64: string;\n payloadB64: string;\n signatureB64: string;\n header: Record<string, unknown>;\n payload: Record<string, unknown>;\n} | null {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const [headerB64, payloadB64, signatureB64] = parts;\n\n try {\n const header = JSON.parse(\n Buffer.from(headerB64, \"base64url\").toString(),\n ) as Record<string, unknown>;\n const payload = JSON.parse(\n Buffer.from(payloadB64, \"base64url\").toString(),\n ) as Record<string, unknown>;\n return { headerB64, payloadB64, signatureB64, header, payload };\n } catch {\n return null;\n }\n}\n\n/**\n * Check `exp` and `nbf` temporal claims.\n * Returns `true` if the token is within valid time bounds.\n */\nfunction checkTemporalClaims(\n payload: Record<string, unknown>,\n clockToleranceSec: number,\n): boolean {\n const now = Math.floor(Date.now() / 1000);\n\n if (typeof payload[\"exp\"] === \"number\") {\n if (now > payload[\"exp\"] + clockToleranceSec) return false;\n }\n if (typeof payload[\"nbf\"] === \"number\") {\n if (now < payload[\"nbf\"] - clockToleranceSec) return false;\n }\n return true;\n}\n\n/**\n * Build an {@link AuthPrincipal} from standard JWT claims.\n * Returns `null` if the `sub` claim is missing or empty.\n */\nfunction buildPrincipal(\n payload: Record<string, unknown>,\n): AuthPrincipal | null {\n const sub = payload[\"sub\"];\n if (typeof sub !== \"string\" || sub.length === 0) return null;\n\n const principal: AuthPrincipal = {\n subject: sub,\n scheme: \"bearer\",\n claims: payload,\n };\n\n if (typeof payload[\"iss\"] === \"string\") principal.issuer = payload[\"iss\"];\n if (typeof payload[\"exp\"] === \"number\") principal.expiresAt = payload[\"exp\"];\n if (typeof payload[\"email\"] === \"string\") principal.email = payload[\"email\"];\n if (typeof payload[\"name\"] === \"string\") principal.name = payload[\"name\"];\n\n const aud = payload[\"aud\"];\n if (Array.isArray(aud))\n principal.audience = aud.filter((a): a is string => typeof a === \"string\");\n else if (typeof aud === \"string\") principal.audience = [aud];\n\n const scope = payload[\"scope\"];\n if (typeof scope === \"string\")\n principal.scopes = scope.split(\" \").filter(Boolean);\n\n if (Array.isArray(payload[\"roles\"]))\n principal.roles = (payload[\"roles\"] as unknown[]).filter(\n (r): r is string => typeof r === \"string\",\n );\n\n return principal;\n}\n\n/** Type guard: options contain `secret` (HMAC). */\nfunction isHmac(options: JwtAuthOptions): options is JwtHmacOptions {\n return \"secret\" in options;\n}\n\n/**\n * Create an HMAC signature verifier.\n */\nfunction createHmacValidator(\n options: JwtHmacOptions,\n): (token: string) => AuthPrincipal | null {\n const { secret, algorithm = \"HS256\", clockToleranceSec = 0 } = options;\n\n if (!secret || typeof secret !== \"string\") {\n throw new TypeError(\"jwt: secret must be a non-empty string\");\n }\n if (!(algorithm in HMAC_ALGORITHMS)) {\n throw new TypeError(\n `jwt: unsupported algorithm \"${algorithm}\". Supported: ${Object.keys(HMAC_ALGORITHMS).join(\", \")}`,\n );\n }\n\n const digest = HMAC_ALGORITHMS[algorithm];\n\n return (token: string): AuthPrincipal | null => {\n const decoded = decodeToken(token);\n if (!decoded) return null;\n\n const { headerB64, payloadB64, signatureB64, header, payload } = decoded;\n\n if (header[\"alg\"] !== algorithm) return null;\n\n const hmac = createHmac(digest, secret);\n hmac.update(`${headerB64}.${payloadB64}`);\n const expectedSig = hmac.digest(\"base64url\");\n\n const expectedBuf = Buffer.from(expectedSig);\n const actualBuf = Buffer.from(signatureB64);\n if (\n expectedBuf.length !== actualBuf.length ||\n !timingSafeEqual(expectedBuf, actualBuf)\n ) {\n return null;\n }\n\n if (!checkTemporalClaims(payload, clockToleranceSec)) return null;\n return buildPrincipal(payload);\n };\n}\n\n/**\n * Create an RSA signature verifier.\n */\nfunction createRsaValidator(\n options: JwtRsaOptions,\n): (token: string) => AuthPrincipal | null {\n const { publicKey, algorithm = \"RS256\", clockToleranceSec = 0 } = options;\n\n if (!publicKey || typeof publicKey !== \"string\") {\n throw new TypeError(\"jwt: publicKey must be a non-empty PEM string\");\n }\n if (!(algorithm in RSA_ALGORITHMS)) {\n throw new TypeError(\n `jwt: unsupported algorithm \"${algorithm}\". Supported: ${Object.keys(RSA_ALGORITHMS).join(\", \")}`,\n );\n }\n\n const verifyAlgorithm = RSA_ALGORITHMS[algorithm];\n\n return (token: string): AuthPrincipal | null => {\n const decoded = decodeToken(token);\n if (!decoded) return null;\n\n const { headerB64, payloadB64, signatureB64, header, payload } = decoded;\n\n if (header[\"alg\"] !== algorithm) return null;\n\n const verifier = createVerify(verifyAlgorithm);\n verifier.update(`${headerB64}.${payloadB64}`);\n\n if (!verifier.verify(publicKey, signatureB64, \"base64url\")) {\n return null;\n }\n\n if (!checkTemporalClaims(payload, clockToleranceSec)) return null;\n return buildPrincipal(payload);\n };\n}\n\n/**\n * Built-in JWT authentication helper for MCP HTTP servers.\n * Verifies HMAC or RSA signed JWTs using only `node:crypto` (no external\n * dependencies).\n *\n * Returns an {@link McpHttpAuthOptions} that can be passed directly to\n * `mcpPlugin({ auth: jwt({ ... }) })`.\n *\n * On success the validator returns an {@link AuthPrincipal} populated from\n * standard JWT claims (`sub`, `iss`, `aud`, `exp`, `scope`, etc.) with the\n * full decoded payload available in `claims`.\n *\n * @example\n * ```ts\n * import { mcpPlugin, jwt } from \"@routecraft/ai\";\n *\n * // HMAC (symmetric) - shared secret\n * mcpPlugin({\n * transport: \"http\",\n * auth: jwt({ secret: process.env.JWT_SECRET! }),\n * });\n *\n * // RSA (asymmetric) - public key only\n * mcpPlugin({\n * transport: \"http\",\n * auth: jwt({ algorithm: \"RS256\", publicKey: process.env.JWT_PUBLIC_KEY! }),\n * });\n * ```\n *\n * @experimental\n */\nexport function jwt(options: JwtAuthOptions): McpHttpAuthOptions {\n const validator = isHmac(options)\n ? createHmacValidator(options)\n : createRsaValidator(options);\n\n return { validator };\n}\n","import type {\n McpOAuthAuthOptions,\n OAuthClientInfo,\n OAuthProxyEndpoints,\n OAuthTokenInfo,\n} from \"./types.ts\";\n\n/**\n * Options for the `oauth()` factory.\n *\n * @experimental\n */\nexport interface OAuthFactoryOptions {\n /** Issuer URL for OAuth metadata discovery. Must be HTTPS in production. */\n issuerUrl: string | URL;\n /** Base URL for OAuth endpoints (defaults to issuerUrl). */\n baseUrl?: string | URL;\n /** Upstream OAuth provider endpoints to proxy. */\n endpoints: OAuthProxyEndpoints;\n /**\n * Verify an access token and return token info.\n * Called on every authenticated request to `/mcp`.\n */\n verifyAccessToken: (token: string) => Promise<OAuthTokenInfo>;\n /**\n * Look up a registered OAuth client by ID.\n * Return `undefined` to reject the client.\n */\n getClient: (clientId: string) => Promise<OAuthClientInfo | undefined>;\n /** OAuth scopes the server advertises as supported. */\n scopesSupported?: string[];\n /** Scopes required on every request to `/mcp`. */\n requiredScopes?: string[];\n /** URL to service documentation (included in OAuth metadata). */\n serviceDocumentationUrl?: string | URL;\n /** Human-readable resource name (included in OAuth metadata). */\n resourceName?: string;\n}\n\n/**\n * Built-in OAuth authentication helper for MCP HTTP servers.\n * Configures a full OAuth 2.1 server flow that proxies to an upstream identity\n * provider using the MCP SDK's `ProxyOAuthServerProvider` and `mcpAuthRouter`.\n *\n * Returns an {@link McpHttpAuthOptions} that can be passed directly to\n * `mcpPlugin({ auth: oauth({ ... }) })`.\n *\n * The server will mount OAuth endpoints (`/.well-known/oauth-authorization-server`,\n * `/authorize`, `/token`, `/revoke`) alongside the `/mcp` transport endpoint.\n *\n * @example\n * ```ts\n * import { mcpPlugin, oauth } from \"@routecraft/ai\";\n *\n * mcpPlugin({\n * transport: \"http\",\n * auth: oauth({\n * issuerUrl: \"https://mcp.example.com\",\n * endpoints: {\n * authorizationUrl: \"https://idp.example.com/authorize\",\n * tokenUrl: \"https://idp.example.com/token\",\n * },\n * verifyAccessToken: async (token) => ({\n * token,\n * clientId: \"my-client\",\n * scopes: [\"read\"],\n * }),\n * getClient: async (clientId) => ({\n * client_id: clientId,\n * redirect_uris: [\"http://localhost:3000/callback\"],\n * }),\n * }),\n * });\n * ```\n *\n * @experimental\n */\nexport function oauth(options: OAuthFactoryOptions): McpOAuthAuthOptions {\n // Warn when issuerUrl is not HTTPS (OAuth 2.1 requires TLS).\n const issuer = new URL(options.issuerUrl.toString());\n if (issuer.protocol !== \"https:\") {\n if (process.env[\"NODE_ENV\"] === \"production\") {\n throw new TypeError(\"oauth: issuerUrl must use HTTPS in production\");\n }\n }\n\n const result: McpOAuthAuthOptions = {\n provider: \"oauth\",\n issuerUrl: options.issuerUrl,\n endpoints: options.endpoints,\n verifyAccessToken: options.verifyAccessToken,\n getClient: options.getClient,\n ...(options.baseUrl !== undefined && { baseUrl: options.baseUrl }),\n ...(options.scopesSupported !== undefined && {\n scopesSupported: options.scopesSupported,\n }),\n ...(options.requiredScopes !== undefined && {\n requiredScopes: options.requiredScopes,\n }),\n ...(options.serviceDocumentationUrl !== undefined && {\n serviceDocumentationUrl: options.serviceDocumentationUrl,\n }),\n ...(options.resourceName !== undefined && {\n resourceName: options.resourceName,\n }),\n };\n\n return result;\n}\n","import type { CraftContext, DirectRouteMetadata } from \"@routecraft/routecraft\";\nimport {\n ADAPTER_DIRECT_REGISTRY,\n ADAPTER_DIRECT_STORE,\n DefaultExchange,\n isRoutecraftError,\n} from \"@routecraft/routecraft\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createServer } from \"node:http\";\nimport type { IncomingMessage } from \"node:http\";\nimport { McpHeadersKeys, isOAuthAuth } from \"./types.ts\";\nimport type {\n AuthPrincipal,\n McpOAuthAuthOptions,\n McpPluginOptions,\n McpValidatorAuthOptions,\n} from \"./types.ts\";\n\n/**\n * Request-scoped storage for the authenticated principal.\n * Set in the HTTP request handler after auth validation;\n * read in handleToolCall to populate exchange headers.\n */\nconst principalStore = new AsyncLocalStorage<AuthPrincipal | undefined>();\n\nconst MCP_SDK_INSTALL =\n 'MCP server requires \"@modelcontextprotocol/sdk\". Install it with: pnpm add @modelcontextprotocol/sdk';\n\n/** Resolved options with defaults applied (internal use). */\ntype McpServerResolvedOptions = Required<\n Pick<McpPluginOptions, \"name\" | \"version\" | \"transport\" | \"port\" | \"host\">\n> &\n Pick<McpPluginOptions, \"tools\" | \"auth\">;\n\n/**\n * McpServer wraps the MCP SDK and bridges it to Routecraft's DirectChannel infrastructure.\n * It reads the MCP route registry lazily (on first tools/list request) to ensure routes have subscribed.\n *\n * Note: Uses dynamic imports to avoid TypeScript compatibility issues with the MCP SDK.\n * Supports both stdio and streamable-http transports.\n *\n * @experimental\n */\nexport class McpServer {\n private context: CraftContext;\n private options: McpServerResolvedOptions;\n private server: unknown = null;\n private transport: unknown = null;\n /**\n * Node HTTP server when transport is http; used to listen on port and close on stop.\n * When OAuth is enabled this holds the Express app's underlying server.\n */\n private httpServer: ReturnType<typeof createServer> | null = null;\n /** Active HTTP sessions keyed by session ID (each session has its own server+transport pair). */\n private httpSessions = new Map<\n string,\n { server: unknown; transport: unknown }\n >();\n private running = false;\n private toolsListLogged = false;\n\n constructor(context: CraftContext, options: McpPluginOptions = {}) {\n this.context = context;\n this.options = {\n name: \"routecraft\",\n version: \"1.0.0\",\n transport: \"stdio\",\n port: 3001,\n host: \"localhost\",\n ...options,\n };\n }\n\n /**\n * Start the MCP server and listen for connections\n */\n async start(): Promise<void> {\n if (this.running) {\n this.context.logger.warn({}, \"MCP server already running\");\n return;\n }\n\n try {\n const transport = this.options.transport;\n\n if (transport === \"http\") {\n await this.startHttp();\n } else {\n await this.startStdio();\n }\n\n this.running = true;\n this.context.logger.info(\n {\n name: this.options.name,\n version: this.options.version,\n transport,\n },\n \"MCP server started\",\n );\n this.logExposedToolsOnce();\n } catch (error) {\n const msg = isRoutecraftError(error)\n ? (error as unknown as { meta: { message: string } }).meta.message\n : error instanceof Error\n ? error.message\n : \"Failed to start MCP server\";\n this.context.logger.error({ err: error }, msg);\n throw error;\n }\n }\n\n /**\n * Start stdio transport\n */\n private async startStdio(): Promise<void> {\n let Server: new (\n info: { name: string; version: string },\n options: { capabilities: { tools: Record<string, unknown> } },\n ) => unknown;\n let StdioServerTransport: new () => unknown;\n try {\n const serverMod =\n await import(\"@modelcontextprotocol/sdk/server/index.js\");\n Server = serverMod.Server;\n const stdioMod =\n await import(\"@modelcontextprotocol/sdk/server/stdio.js\");\n StdioServerTransport = stdioMod.StdioServerTransport;\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n\n this.server = new Server(\n {\n name: this.options.name,\n version: this.options.version,\n },\n { capabilities: { tools: {} } },\n );\n\n await this.setupRequestHandlers();\n\n this.transport = new StdioServerTransport();\n const srvWithConnect = this.server as Record<\n string,\n (transport: unknown) => Promise<void>\n >;\n await srvWithConnect[\"connect\"](this.transport);\n }\n\n /**\n * Start HTTP transport (streamable-http).\n * Dispatches to the OAuth or raw-HTTP path depending on the auth config.\n */\n private async startHttp(): Promise<void> {\n if (this.options.auth && isOAuthAuth(this.options.auth)) {\n await this.startHttpWithOAuth(this.options.auth);\n } else {\n await this.startHttpWithValidator();\n }\n }\n\n /**\n * Import the MCP SDK Server constructor and StreamableHTTPServerTransport.\n * Shared by both HTTP startup paths.\n */\n private async importSdkHttp(): Promise<{\n ServerCtor: new (\n info: { name: string; version: string },\n options: { capabilities: { tools: Record<string, unknown> } },\n ) => unknown;\n TransportClass: new (options?: {\n sessionIdGenerator?: () => string;\n onsessioninitialized?: (sessionId: string) => void;\n enableJsonResponse?: boolean;\n }) => unknown;\n }> {\n let ServerCtor: new (\n info: { name: string; version: string },\n options: { capabilities: { tools: Record<string, unknown> } },\n ) => unknown;\n try {\n const serverModule =\n await import(\"@modelcontextprotocol/sdk/server/index.js\");\n ServerCtor = serverModule.Server;\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n\n const streamableModule =\n await import(\"@modelcontextprotocol/sdk/server/streamableHttp.js\").catch(\n () => null,\n );\n const TransportClass = (\n streamableModule as Record<string, unknown> | null\n )?.[\"StreamableHTTPServerTransport\"] as\n | (new (options?: {\n sessionIdGenerator?: () => string;\n onsessioninitialized?: (sessionId: string) => void;\n enableJsonResponse?: boolean;\n }) => unknown)\n | undefined;\n\n if (!TransportClass) {\n throw new Error(\n \"StreamableHTTPServerTransport not found in MCP SDK - ensure @modelcontextprotocol/sdk v1.26.0+ is installed\",\n );\n }\n\n return { ServerCtor, TransportClass };\n }\n\n /**\n * Creates a new MCP Server + Transport pair for a single HTTP session.\n * Called on every initialization request (no session ID header).\n */\n private async createSession(\n ServerCtor: new (\n info: { name: string; version: string },\n options: { capabilities: { tools: Record<string, unknown> } },\n ) => unknown,\n TransportClass: new (options?: {\n sessionIdGenerator?: () => string;\n onsessioninitialized?: (sessionId: string) => void;\n enableJsonResponse?: boolean;\n }) => unknown,\n ): Promise<{\n transport: unknown;\n handleRequest: (\n req: unknown,\n res: unknown,\n parsedBody?: unknown,\n ) => Promise<void>;\n }> {\n const server = new ServerCtor(\n { name: this.options.name, version: this.options.version },\n { capabilities: { tools: {} } },\n );\n\n await this.setupRequestHandlersOn(server);\n\n const transport = new TransportClass({\n sessionIdGenerator: () => crypto.randomUUID(),\n onsessioninitialized: (sessionId: string) => {\n this.httpSessions.set(sessionId, { server, transport });\n this.context.logger.debug({ sessionId }, \"MCP session created\");\n this.context.emit(\"plugin:mcp:session:created\", { sessionId });\n },\n enableJsonResponse: true,\n });\n\n const srvWithConnect = server as Record<\n string,\n (t: unknown) => Promise<void>\n >;\n await srvWithConnect[\"connect\"](transport);\n\n // Clean up on transport close so the session map does not leak.\n const tr = transport as Record<string, unknown>;\n const prevOnClose = tr[\"onclose\"] as (() => void) | undefined;\n tr[\"onclose\"] = () => {\n const sid = (transport as { sessionId?: string }).sessionId;\n if (sid) {\n this.httpSessions.delete(sid);\n this.context.logger.debug({ sessionId: sid }, \"MCP session closed\");\n this.context.emit(\"plugin:mcp:session:closed\", {\n sessionId: sid,\n });\n }\n prevOnClose?.();\n };\n\n const handleRequest = (\n transport as Record<\n string,\n (req: unknown, res: unknown, parsedBody?: unknown) => Promise<void>\n >\n )[\"handleRequest\"];\n if (typeof handleRequest !== \"function\") {\n throw new Error(\n \"StreamableHTTPServerTransport.handleRequest not found - SDK may have changed\",\n );\n }\n\n return {\n transport,\n handleRequest: handleRequest.bind(transport) as (\n req: unknown,\n res: unknown,\n parsedBody?: unknown,\n ) => Promise<void>,\n };\n }\n\n /**\n * Route an MCP request through session management with principal context.\n * Shared by both HTTP startup paths.\n */\n private async handleMcpRequest(\n req: IncomingMessage,\n res: import(\"node:http\").ServerResponse,\n principal: AuthPrincipal | undefined,\n createSessionFn: () => Promise<{\n handleRequest: (\n req: unknown,\n res: unknown,\n parsedBody?: unknown,\n ) => Promise<void>;\n }>,\n ): Promise<void> {\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n const runWithPrincipal = <T>(fn: () => Promise<T>): Promise<T> =>\n principalStore.run(principal, fn);\n\n try {\n if (sessionId && this.httpSessions.has(sessionId)) {\n const session = this.httpSessions.get(sessionId)!;\n const hr = (\n session.transport as Record<\n string,\n (req: unknown, res: unknown, parsedBody?: unknown) => Promise<void>\n >\n )[\"handleRequest\"];\n await runWithPrincipal(() => hr.call(session.transport, req, res));\n } else if (!sessionId || req.method === \"POST\") {\n const { handleRequest } = await createSessionFn();\n await runWithPrincipal(() => handleRequest(req, res));\n } else {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Session not found\" }));\n }\n } catch (err) {\n const msg = isRoutecraftError(err)\n ? (err as unknown as { meta: { message: string } }).meta.message\n : err instanceof Error\n ? err.message\n : \"MCP HTTP request error\";\n this.context.logger.error({ err }, msg);\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Internal Server Error\" }));\n }\n }\n }\n\n /**\n * Start HTTP transport with validator-based auth (existing behavior).\n * Uses raw Node.js `http.createServer`.\n */\n private async startHttpWithValidator(): Promise<void> {\n const { ServerCtor, TransportClass } = await this.importSdkHttp();\n const port = this.options.port;\n const host = this.options.host;\n\n const createSessionFn = () =>\n this.createSession(ServerCtor, TransportClass);\n\n this.httpServer = createServer(async (req, res) => {\n const url = req.url?.split(\"?\")[0] ?? \"\";\n if (url !== \"/mcp\" && url !== \"/mcp/\") {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not Found\", path: url }));\n return;\n }\n\n let principal: AuthPrincipal | undefined;\n if (this.options.auth) {\n const result = await this.validateAuth(req);\n if (!result) {\n res.writeHead(401, {\n \"Content-Type\": \"application/json\",\n \"WWW-Authenticate\": 'Bearer realm=\"mcp\"',\n });\n res.end(JSON.stringify({ error: \"Unauthorized\" }));\n return;\n }\n principal = result;\n }\n\n await this.handleMcpRequest(req, res, principal, createSessionFn);\n });\n\n await this.listenHttp(port, host);\n }\n\n /**\n * Start HTTP transport with OAuth provider auth.\n * Uses Express to mount `mcpAuthRouter` (OAuth endpoints) alongside `/mcp`.\n * Express is available as a transitive dependency of `@modelcontextprotocol/sdk`.\n *\n * Note: if the server runs behind a reverse proxy, `req.ip` and `req.protocol`\n * may be incorrect. Users should set `trust proxy` on the Express app via a\n * future configuration option or by using a custom HTTP server.\n */\n private async startHttpWithOAuth(\n oauthOptions: McpOAuthAuthOptions,\n ): Promise<void> {\n const { ServerCtor, TransportClass } = await this.importSdkHttp();\n\n // Dynamic imports for Express and SDK OAuth infrastructure.\n // Express types are not available at compile time (transitive dep of SDK),\n // so all Express values are typed as unknown and accessed dynamically.\n let expressFn: (...args: unknown[]) => {\n use: (...args: unknown[]) => void;\n all: (...args: unknown[]) => void;\n listen: (\n port: number,\n host: string,\n cb: () => void,\n ) => ReturnType<typeof createServer>;\n };\n let mcpAuthRouter: (options: Record<string, unknown>) => unknown;\n let requireBearerAuth: (options: Record<string, unknown>) => unknown;\n let ProxyOAuthServerProvider: new (\n options: Record<string, unknown>,\n ) => unknown;\n\n try {\n // @ts-expect-error -- Express is a transitive dep of @modelcontextprotocol/sdk; no type declarations in this project\n const expressMod = (await import(\"express\")) as Record<string, unknown>;\n expressFn = (expressMod[\"default\"] ?? expressMod) as typeof expressFn;\n } catch {\n throw new Error(\n 'OAuth auth requires \"express\". It should be installed as a dependency of @modelcontextprotocol/sdk.',\n );\n }\n\n try {\n const routerMod =\n await import(\"@modelcontextprotocol/sdk/server/auth/router.js\");\n mcpAuthRouter = (routerMod as Record<string, unknown>)[\n \"mcpAuthRouter\"\n ] as typeof mcpAuthRouter;\n\n const bearerMod =\n await import(\"@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js\");\n requireBearerAuth = (bearerMod as Record<string, unknown>)[\n \"requireBearerAuth\"\n ] as typeof requireBearerAuth;\n\n const proxyMod =\n await import(\"@modelcontextprotocol/sdk/server/auth/providers/proxyProvider.js\");\n ProxyOAuthServerProvider = (proxyMod as Record<string, unknown>)[\n \"ProxyOAuthServerProvider\"\n ] as typeof ProxyOAuthServerProvider;\n } catch {\n throw new Error(\n \"OAuth auth requires @modelcontextprotocol/sdk v1.27.0+ with OAuth support. \" +\n \"Install it with: pnpm add @modelcontextprotocol/sdk\",\n );\n }\n\n // Build the ProxyOAuthServerProvider from the user's config.\n const provider = new ProxyOAuthServerProvider({\n endpoints: {\n authorizationUrl: oauthOptions.endpoints.authorizationUrl,\n tokenUrl: oauthOptions.endpoints.tokenUrl,\n revocationUrl: oauthOptions.endpoints.revocationUrl,\n registrationUrl: oauthOptions.endpoints.registrationUrl,\n },\n verifyAccessToken: oauthOptions.verifyAccessToken,\n getClient: oauthOptions.getClient,\n });\n\n const port = this.options.port;\n const host = this.options.host;\n\n const app = expressFn();\n\n // Mount OAuth endpoints at root (discovery, authorize, token, revoke).\n const authRouterOptions: Record<string, unknown> = {\n provider,\n issuerUrl: new URL(oauthOptions.issuerUrl.toString()),\n };\n if (oauthOptions.baseUrl) {\n authRouterOptions[\"baseUrl\"] = new URL(oauthOptions.baseUrl.toString());\n }\n if (oauthOptions.scopesSupported) {\n authRouterOptions[\"scopesSupported\"] = oauthOptions.scopesSupported;\n }\n if (oauthOptions.serviceDocumentationUrl) {\n authRouterOptions[\"serviceDocumentationUrl\"] = new URL(\n oauthOptions.serviceDocumentationUrl.toString(),\n );\n }\n if (oauthOptions.resourceName) {\n authRouterOptions[\"resourceName\"] = oauthOptions.resourceName;\n }\n app.use(mcpAuthRouter(authRouterOptions));\n\n // Bearer auth middleware for /mcp.\n const bearerOptions: Record<string, unknown> = { verifier: provider };\n if (oauthOptions.requiredScopes) {\n bearerOptions[\"requiredScopes\"] = oauthOptions.requiredScopes;\n }\n app.use(\"/mcp\", requireBearerAuth(bearerOptions));\n\n const createSessionFn = () =>\n this.createSession(ServerCtor, TransportClass);\n\n // MCP transport handler at /mcp.\n app.all(\"/mcp\", async (req: unknown, res: unknown) => {\n const nodeReq = req as IncomingMessage;\n const nodeRes = res as import(\"node:http\").ServerResponse;\n\n // The SDK's requireBearerAuth sets req.auth with the verified AuthInfo.\n const authInfo = (req as Record<string, unknown>)[\"auth\"] as\n | {\n clientId: string;\n scopes: string[];\n token: string;\n expiresAt?: number;\n }\n | undefined;\n const principal = this.authInfoToPrincipal(authInfo);\n\n if (principal) {\n const successDetail = {\n subject: principal.subject,\n scheme: principal.scheme,\n source: \"mcp\",\n };\n this.context.logger.info(successDetail, \"Auth succeeded\");\n this.context.emit(\"auth:success\", successDetail);\n }\n\n await this.handleMcpRequest(nodeReq, nodeRes, principal, createSessionFn);\n });\n\n // Wrap the Express app in a raw HTTP server so listenHttp can bind it.\n // Express apps are callable as (req, res) request handlers.\n this.httpServer = createServer(\n app as unknown as (\n req: import(\"node:http\").IncomingMessage,\n res: import(\"node:http\").ServerResponse,\n ) => void,\n );\n await this.listenHttp(port, host);\n }\n\n /**\n * Bind the HTTP server to the configured port and host.\n * Used by the validator path.\n */\n private async listenHttp(port: number, host: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.httpServer!.listen(port, host, () => resolve());\n this.httpServer!.on(\"error\", (err) => {\n const msg = isRoutecraftError(err)\n ? (err as unknown as { meta: { message: string } }).meta.message\n : err instanceof Error\n ? err.message\n : \"MCP HTTP server listen failed\";\n this.context.logger.error({ err }, msg);\n reject(err);\n });\n });\n\n const boundPort = this.getHttpPort() ?? port;\n const listenDetail = { host, port: boundPort, path: \"/mcp\" };\n this.context.logger.info(listenDetail, \"MCP HTTP server listening\");\n this.context.emit(\"plugin:mcp:server:listening\", listenDetail);\n }\n\n /**\n * Convert the MCP SDK's AuthInfo (set by requireBearerAuth) to an AuthPrincipal\n * for routecraft's exchange headers.\n */\n private authInfoToPrincipal(\n authInfo:\n | {\n clientId: string;\n scopes: string[];\n token: string;\n expiresAt?: number;\n }\n | undefined,\n ): AuthPrincipal | undefined {\n if (!authInfo) return undefined;\n const principal: AuthPrincipal = {\n subject: authInfo.clientId,\n scheme: \"bearer\",\n scopes: authInfo.scopes,\n claims: {\n clientId: authInfo.clientId,\n },\n };\n if (authInfo.expiresAt !== undefined) {\n principal.expiresAt = authInfo.expiresAt;\n }\n return principal;\n }\n\n /**\n * When transport is http, returns the bound port (useful when port 0 was used). Otherwise undefined.\n */\n getHttpPort(): number | undefined {\n const addr = this.httpServer?.address();\n if (addr && typeof addr === \"object\" && \"port\" in addr) {\n return (addr as { port: number }).port;\n }\n return undefined;\n }\n\n /**\n * Validate the Authorization header using the configured validator.\n * Only used on the validator auth path (not OAuth -- that uses Express middleware).\n * Returns the authenticated principal on success, or `null` to reject with 401.\n */\n private async validateAuth(\n req: IncomingMessage,\n ): Promise<AuthPrincipal | null> {\n const authOptions = this.options.auth as\n | McpValidatorAuthOptions\n | undefined;\n if (!authOptions || !(\"validator\" in authOptions)) return null;\n\n const rawHeader = req.headers[\"authorization\"];\n if (!rawHeader || Array.isArray(rawHeader)) {\n const detail = {\n reason: \"missing_header\",\n scheme: \"bearer\",\n source: \"mcp\",\n };\n this.context.logger.warn(\n detail,\n \"Auth rejected: missing or malformed Authorization header\",\n );\n this.context.emit(\"auth:rejected\", detail);\n return null;\n }\n\n const schemeMatch = /^bearer\\s+(.+)$/i.exec(rawHeader);\n if (!schemeMatch) {\n const detail = {\n reason: \"unsupported_scheme\",\n scheme: \"bearer\",\n source: \"mcp\",\n };\n this.context.logger.warn(\n detail,\n \"Auth rejected: unsupported authorization scheme\",\n );\n this.context.emit(\"auth:rejected\", detail);\n return null;\n }\n const token = schemeMatch[1];\n\n // Delegate to the validator. It must return an AuthPrincipal on success\n // or null/false to reject. Throws propagate as 500.\n const result = await authOptions.validator(token);\n if (!result) {\n const detail = {\n reason: \"invalid_token\",\n scheme: \"bearer\",\n source: \"mcp\",\n };\n this.context.logger.warn(\n detail,\n \"Auth rejected: token validation failed\",\n );\n this.context.emit(\"auth:rejected\", detail);\n return null;\n }\n\n const successDetail = {\n subject: result.subject,\n scheme: result.scheme,\n source: \"mcp\",\n };\n this.context.logger.info(successDetail, \"Auth succeeded\");\n this.context.emit(\"auth:success\", successDetail);\n return result;\n }\n\n /**\n * Set up request handlers on this.server (used by stdio transport).\n */\n private async setupRequestHandlers(): Promise<void> {\n await this.setupRequestHandlersOn(this.server);\n }\n\n /**\n * Set up request handlers on the given server instance.\n * Uses SDK request schemas so setRequestHandler receives a proper schema (method literal).\n */\n private async setupRequestHandlersOn(server: unknown): Promise<void> {\n let typesModule: Record<string, unknown>;\n try {\n typesModule =\n (await import(\"@modelcontextprotocol/sdk/types.js\")) as Record<\n string,\n unknown\n >;\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n const t = typesModule;\n const ListToolsRequestSchema = t[\"ListToolsRequestSchema\"];\n const CallToolRequestSchema = t[\"CallToolRequestSchema\"];\n\n if (!ListToolsRequestSchema || !CallToolRequestSchema) {\n throw new Error(\n \"MCP SDK types missing ListToolsRequestSchema or CallToolRequestSchema - ensure @modelcontextprotocol/sdk is installed\",\n );\n }\n\n const srv = server as Record<\n string,\n (schema: unknown, handler: (request: unknown) => Promise<unknown>) => void\n >;\n\n srv[\"setRequestHandler\"](ListToolsRequestSchema, async () => {\n const tools = this.getAvailableTools();\n this.logExposedToolsOnce();\n return { tools };\n });\n\n srv[\"setRequestHandler\"](\n CallToolRequestSchema,\n async (request: unknown) => {\n const req = request as Record<string, unknown>;\n const params = req[\"params\"] as Record<string, unknown>;\n return await this.handleToolCall(\n (params[\"name\"] as string) || \"\",\n (params[\"arguments\"] as Record<string, unknown>) || {},\n );\n },\n );\n }\n\n /**\n * Stop the MCP server\n */\n async stop(): Promise<void> {\n if (!this.running) {\n return;\n }\n\n try {\n if (this.httpServer) {\n // Close all active HTTP sessions.\n for (const [, session] of this.httpSessions) {\n const tr = session.transport as Record<string, () => Promise<void>>;\n if (typeof tr[\"close\"] === \"function\") {\n await tr[\"close\"]();\n }\n }\n this.httpSessions.clear();\n\n await new Promise<void>((resolve) => {\n this.httpServer!.close(() => resolve());\n });\n this.httpServer = null;\n }\n if (this.transport) {\n const tr = this.transport as Record<string, () => Promise<void>>;\n if (typeof tr[\"close\"] === \"function\") {\n await tr[\"close\"]();\n }\n }\n this.running = false;\n this.context.logger.info({}, \"MCP server stopped\");\n } catch (error) {\n const msg = isRoutecraftError(error)\n ? (error as unknown as { meta: { message: string } }).meta.message\n : error instanceof Error\n ? error.message\n : \"Error stopping MCP server\";\n this.context.logger.error({ err: error }, msg);\n }\n }\n\n /**\n * Log exposed MCP tool names once (at start or on first tools/list).\n */\n private logExposedToolsOnce(): void {\n if (this.toolsListLogged) return;\n const tools = this.getAvailableTools();\n if (tools.length === 0) return;\n const names = tools.map((t) => (t[\"name\"] as string) ?? \"?\");\n const exposedDetail = { tools: names, count: names.length };\n this.context.logger.info(exposedDetail, \"Exposing MCP tools\");\n this.context.emit(\"plugin:mcp:server:tools:exposed\", exposedDetail);\n this.toolsListLogged = true;\n }\n\n /**\n * Get list of tools that should be exposed via MCP.\n * Reads the registry lazily - called on every tools/list request and for tests.\n */\n getAvailableTools(): Array<Record<string, unknown>> {\n const registry = this.context.getStore(ADAPTER_DIRECT_REGISTRY) as\n | Map<string, DirectRouteMetadata>\n | undefined;\n\n if (!registry) {\n return [];\n }\n\n // Get all mcp() routes (those with description)\n let tools = Array.from(registry.values()).filter(\n (t) => t.description !== undefined,\n );\n\n // Apply user filter if provided\n const toolsFilter = this.options.tools;\n if (toolsFilter) {\n if (Array.isArray(toolsFilter)) {\n const allowed = new Set(toolsFilter);\n tools = tools.filter((t) => allowed.has(t.endpoint));\n } else if (typeof toolsFilter === \"function\") {\n tools = tools.filter(toolsFilter);\n }\n }\n\n // Convert to MCP tool format\n return tools.map((meta) => this.metadataToMcpTool(meta));\n }\n\n /**\n * Convert Routecraft mcp() route metadata to MCP tool format\n */\n private metadataToMcpTool(\n metadata: DirectRouteMetadata,\n ): Record<string, unknown> {\n return {\n name: metadata.endpoint,\n description: metadata.description || \"\",\n inputSchema: this.schemaToJsonSchema(metadata.schema),\n };\n }\n\n /**\n * Convert to JSON Schema using Standard JSON Schema (schema['~standard'].jsonSchema.input)\n * when available; otherwise return a generic object schema.\n * Works with any spec-compliant library (Zod 4.2+, ArkType, Valibot via toStandardJsonSchema).\n */\n private schemaToJsonSchema(schema: unknown): Record<string, unknown> {\n if (!schema || typeof schema !== \"object\") {\n return { type: \"object\" };\n }\n\n const standard = (schema as Record<string, unknown>)[\"~standard\"] as\n | {\n jsonSchema?: {\n input?: (opts: { target: string }) => Record<string, unknown>;\n };\n }\n | undefined;\n if (standard?.jsonSchema?.input) {\n try {\n const out = standard.jsonSchema.input({\n target: \"draft-2020-12\",\n });\n return typeof out === \"object\" && out !== null\n ? out\n : { type: \"object\" };\n } catch (error) {\n this.context.logger.debug(\n error,\n \"Standard JSON Schema conversion failed\",\n );\n return { type: \"object\" };\n }\n }\n\n if (\"~standard\" in schema) {\n return { type: \"object\", additionalProperties: true };\n }\n return { type: \"object\" };\n }\n\n /**\n * Handle a tool call from MCP client\n */\n private async handleToolCall(\n toolName: string,\n args: Record<string, unknown>,\n ): Promise<{\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n }> {\n try {\n // Get the direct channel store\n const channelStore = this.context.getStore(ADAPTER_DIRECT_STORE) as\n | Map<string, Record<string, unknown>>\n | undefined;\n\n if (!channelStore) {\n const err = new Error(\"No direct channels available\");\n this.context.emit(`plugin:mcp:tool:failed`, {\n tool: toolName,\n error: err.message,\n });\n return {\n isError: true,\n content: [\n { type: \"text\", text: `Error: No direct channels available` },\n ],\n };\n }\n\n // Get the channel for this tool endpoint\n const channel = channelStore.get(toolName);\n if (!channel) {\n const err = new Error(`Tool not found: ${toolName}`);\n this.context.emit(`plugin:mcp:tool:failed`, {\n tool: toolName,\n error: err.message,\n });\n return {\n isError: true,\n content: [\n { type: \"text\", text: `Error: Tool not found: ${toolName}` },\n ],\n };\n }\n\n // Ensure body is an object when client sends JSON (SDK may pass parsed object or raw string)\n const body =\n typeof args === \"string\"\n ? (() => {\n try {\n return (JSON.parse(args) as Record<string, unknown>) || {};\n } catch {\n return { input: args };\n }\n })()\n : args && typeof args === \"object\"\n ? args\n : {};\n\n this.context.logger.debug(\n { bodyType: typeof body, body },\n \"MCP tool call exchange body\",\n );\n\n // Build exchange headers, including auth principal if present.\n const principal = principalStore.getStore();\n const headers: Record<string, string | string[] | undefined> = {\n [McpHeadersKeys.TOOL]: toolName,\n [McpHeadersKeys.SESSION]: `mcp-${Date.now()}`,\n };\n if (principal) {\n headers[McpHeadersKeys.AUTH_SUBJECT] = principal.subject;\n headers[McpHeadersKeys.AUTH_SCHEME] = principal.scheme;\n if (principal.roles)\n headers[McpHeadersKeys.AUTH_ROLES] = principal.roles;\n if (principal.scopes)\n headers[McpHeadersKeys.AUTH_SCOPES] = principal.scopes;\n if (principal.email)\n headers[McpHeadersKeys.AUTH_EMAIL] = principal.email;\n if (principal.name) headers[McpHeadersKeys.AUTH_NAME] = principal.name;\n if (principal.issuer)\n headers[McpHeadersKeys.AUTH_ISSUER] = principal.issuer;\n if (principal.audience)\n headers[McpHeadersKeys.AUTH_AUDIENCE] = principal.audience;\n }\n\n const exchange = new DefaultExchange(this.context, {\n body,\n headers,\n });\n\n this.context.emit(`plugin:mcp:tool:called`, {\n tool: toolName,\n args,\n });\n\n // Send the exchange through the direct channel\n const channelTyped = channel as Record<\n string,\n (name: string, ex: unknown) => Promise<unknown>\n >;\n const resultExchange = (await channelTyped[\"send\"](\n toolName,\n exchange,\n )) as Record<string, unknown>;\n\n // Convert result to MCP format\n const resultText =\n typeof resultExchange[\"body\"] === \"string\"\n ? (resultExchange[\"body\"] as string)\n : JSON.stringify(resultExchange[\"body\"]);\n\n this.context.emit(`plugin:mcp:tool:completed`, {\n tool: toolName,\n });\n\n return {\n content: [{ type: \"text\", text: resultText }],\n };\n } catch (error) {\n const logMsg = isRoutecraftError(error)\n ? (error as unknown as { meta: { message: string } }).meta.message\n : error instanceof Error\n ? error.message\n : String(error);\n this.context.logger.error({ tool: toolName, err: error }, logMsg);\n this.context.emit(`plugin:mcp:tool:failed`, {\n tool: toolName,\n error: logMsg,\n });\n\n // Build a clean user-facing message: include the cause (e.g. schema\n // field errors) but never expose stack traces or internal details.\n let userMsg = logMsg;\n if (isRoutecraftError(error)) {\n const cause = (error as { cause?: Error }).cause;\n if (cause?.message) {\n userMsg = `${logMsg}: ${cause.message}`;\n }\n }\n\n return {\n content: [{ type: \"text\", text: `Error: ${userMsg}` }],\n isError: true,\n };\n }\n }\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { formatSchemaIssues } from \"@routecraft/routecraft\";\nimport type { McpPluginOptions } from \"./types.ts\";\n\n/** Standard Schema validate result: success has value, failure has issues. */\ntype ValidateResult<T = unknown> =\n | { value: T; issues?: never }\n | { value?: never; issues: readonly unknown[] };\n\n/**\n * Validates MCP plugin options at apply time.\n * For full schema validation (required props, shape), use validateWithSchema() with a\n * StandardSchemaV1 from Zod, Valibot, or ArkType before calling mcpPlugin().\n */\nexport function validateMcpPluginOptions(options: McpPluginOptions): void {\n if (options.transport === \"http\") {\n if (options.port !== undefined) {\n if (typeof options.port !== \"number\") {\n throw new TypeError(\n \"mcpPlugin: when transport is 'http', port must be a number\",\n );\n }\n if (options.port < 0 || options.port > 65535) {\n throw new RangeError(\n \"mcpPlugin: port must be between 0 and 65535 when transport is 'http'\",\n );\n }\n }\n if (options.host !== undefined && typeof options.host !== \"string\") {\n throw new TypeError(\"mcpPlugin: when provided, host must be a string\");\n }\n }\n\n // Validate auth options\n if (options.auth !== undefined) {\n if (\"provider\" in options.auth) {\n // OAuth provider auth -- validated by the oauth() factory.\n if (options.auth.provider !== \"oauth\") {\n throw new TypeError(\n 'mcpPlugin: auth.provider must be \"oauth\". Use the oauth() helper.',\n );\n }\n } else if (\"validator\" in options.auth) {\n if (typeof options.auth.validator !== \"function\") {\n throw new TypeError(\n \"mcpPlugin: auth.validator must be a function that returns an AuthPrincipal or null\",\n );\n }\n } else {\n throw new TypeError(\n \"mcpPlugin: auth must have either a 'validator' function or 'provider' set to 'oauth'. \" +\n \"Use jwt(), oauth(), or a custom { validator } object.\",\n );\n }\n }\n\n // Validate stdio client configs\n if (options.clients) {\n for (const [name, config] of Object.entries(options.clients)) {\n if (\n typeof config === \"object\" &&\n config !== null &&\n \"transport\" in config &&\n config.transport === \"stdio\"\n ) {\n if (!config.command || typeof config.command !== \"string\") {\n throw new TypeError(\n `mcpPlugin: stdio client \"${name}\" must have a non-empty command string`,\n );\n }\n }\n }\n }\n\n // Validate restart options\n if (options.maxRestarts !== undefined) {\n if (\n typeof options.maxRestarts !== \"number\" ||\n !Number.isInteger(options.maxRestarts) ||\n options.maxRestarts < 0\n ) {\n throw new TypeError(\n \"mcpPlugin: maxRestarts must be a non-negative integer\",\n );\n }\n }\n if (options.restartDelayMs !== undefined) {\n if (\n typeof options.restartDelayMs !== \"number\" ||\n options.restartDelayMs <= 0\n ) {\n throw new TypeError(\n \"mcpPlugin: restartDelayMs must be a positive number\",\n );\n }\n }\n if (options.restartBackoffMultiplier !== undefined) {\n if (\n typeof options.restartBackoffMultiplier !== \"number\" ||\n options.restartBackoffMultiplier < 1\n ) {\n throw new TypeError(\"mcpPlugin: restartBackoffMultiplier must be >= 1\");\n }\n }\n\n // Validate HTTP tool refresh interval\n if (options.toolRefreshIntervalMs !== undefined) {\n if (\n typeof options.toolRefreshIntervalMs !== \"number\" ||\n !Number.isInteger(options.toolRefreshIntervalMs) ||\n options.toolRefreshIntervalMs < 0\n ) {\n throw new TypeError(\n \"mcpPlugin: toolRefreshIntervalMs must be a non-negative integer\",\n );\n }\n }\n}\n\n/**\n * Validate plugin options with a StandardSchemaV1 (e.g. from Zod, Valibot, ArkType).\n * Use this when you need required props or full shape validation before mcpPlugin().\n *\n * @example\n * import { z } from \"zod\";\n * const schema = z.object({ transport: z.enum([\"stdio\", \"http\"]), port: z.number().optional() });\n * const validated = await validateWithSchema(options, schema);\n * mcpPlugin(validated);\n */\nexport async function validateWithSchema(\n options: McpPluginOptions,\n schema: StandardSchemaV1,\n): Promise<McpPluginOptions> {\n const standard = (\n schema as {\n \"~standard\"?: {\n validate: (\n v: unknown,\n ) => ValidateResult<unknown> | Promise<ValidateResult<unknown>>;\n };\n }\n )[\"~standard\"];\n if (!standard?.validate) {\n throw new Error(\n \"mcpPlugin: schema must be a StandardSchemaV1 with ~standard.validate\",\n );\n }\n let result = standard.validate(options);\n if (result instanceof Promise) {\n result = await result;\n }\n if (result.issues) {\n throw new Error(\n `mcpPlugin options validation failed: ${formatSchemaIssues(result.issues)}`,\n );\n }\n // Guard against schemas that pass (no issues) but omit value\n if (result.value === undefined) {\n throw new Error(\"mcpPlugin options validation failed: no value returned\");\n }\n return result.value as McpPluginOptions;\n}\n","import type { McpTool } from \"./types.ts\";\nimport { extractContent } from \"./extract-content.ts\";\n\nconst MCP_SDK_INSTALL =\n 'MCP stdio client requires \"@modelcontextprotocol/sdk\". Install it with: pnpm add @modelcontextprotocol/sdk';\n\nexport interface StdioClientManagerOptions {\n serverId: string;\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n maxRestarts: number;\n restartDelayMs: number;\n restartBackoffMultiplier: number;\n}\n\n/** Logger interface matching pino child logger shape used in Routecraft. */\ninterface Logger {\n info(obj: Record<string, unknown>, msg: string): void;\n warn(obj: Record<string, unknown>, msg: string): void;\n error(obj: Record<string, unknown>, msg: string): void;\n debug(obj: Record<string, unknown>, msg: string): void;\n}\n\n/** Typed subset of the MCP SDK Client used by StdioClientManager. */\ninterface McpSdkClient {\n connect(transport: unknown): Promise<void>;\n close(): Promise<void>;\n listTools(): Promise<{ tools: McpTool[] }>;\n callTool(params: {\n name: string;\n arguments?: Record<string, unknown>;\n }): Promise<{\n content?: Array<{ type: string; text?: string; data?: string }>;\n }>;\n}\n\n/**\n * Manages a single stdio MCP client subprocess.\n *\n * Delegates to the MCP SDK's Client + StdioClientTransport for process spawning,\n * protocol handling, and tool listing. Adds auto-restart with exponential backoff\n * and event bridging into Routecraft's event system.\n */\nexport class StdioClientManager {\n private client: McpSdkClient | null = null;\n private transport: unknown = null;\n private running = false;\n private stopping = false;\n private restartCount = 0;\n private restartTimer: ReturnType<typeof setTimeout> | null = null;\n private stabilityTimer: ReturnType<typeof setTimeout> | null = null;\n private tools: McpTool[] = [];\n\n /**\n * @param options - Subprocess command, restart policy, and server identity\n * @param logger - Logger matching the pino child logger shape\n * @param onEvent - Callback invoked for every lifecycle event\n * @param onToolsUpdated - Callback invoked whenever the tool list changes\n */\n constructor(\n private readonly options: StdioClientManagerOptions,\n private readonly logger: Logger,\n private readonly onEvent: (\n event: string,\n details: Record<string, unknown>,\n ) => void,\n private readonly onToolsUpdated: (\n serverId: string,\n tools: McpTool[],\n ) => void,\n ) {}\n\n /** Spawn the child process, perform the MCP handshake, and list initial tools. */\n async start(): Promise<void> {\n if (this.running) return;\n this.stopping = false;\n\n // Cancel any pending restart to avoid race with externally-initiated start\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n\n type SdkClientModule =\n typeof import(\"@modelcontextprotocol/sdk/client/index.js\");\n type SdkStdioModule =\n typeof import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n\n let clientMod: SdkClientModule;\n let stdioMod: SdkStdioModule;\n\n try {\n clientMod = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n stdioMod = await import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n } catch {\n throw new Error(MCP_SDK_INSTALL);\n }\n\n const { serverId, command, args, env, cwd } = this.options;\n\n // Create transport (spawns child process)\n this.transport = new stdioMod.StdioClientTransport({\n command,\n args: args ?? [],\n ...(env ? { env } : {}),\n ...(cwd ? { cwd } : {}),\n stderr: \"pipe\",\n });\n\n // Wire up transport error/close handlers\n const transport = this.transport as {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n stderr: {\n on?: (event: string, cb: (data: unknown) => void) => void;\n } | null;\n };\n\n transport.onerror = (error: Error) => {\n this.logger.error(\n { err: error, serverId },\n \"Stdio client transport error\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:error`, {\n serverId,\n error,\n });\n };\n\n transport.onclose = () => {\n if (!this.stopping) {\n this.running = false;\n this.handleDisconnect();\n }\n };\n\n // Log stderr from child process\n if (transport.stderr?.on) {\n transport.stderr.on(\"data\", (data: unknown) => {\n this.logger.debug(\n { serverId, stderr: String(data).trimEnd() },\n \"Stdio client stderr output\",\n );\n });\n }\n\n // Create client with listChanged support for auto tool refresh\n this.client = new clientMod.Client(\n { name: \"routecraft-mcp-client\", version: \"1.0.0\" },\n {\n capabilities: {},\n listChanged: {\n tools: {\n onChanged: (_error: unknown, tools: unknown) => {\n if (\n tools &&\n Array.isArray((tools as { tools: unknown[] }).tools)\n ) {\n this.tools = (tools as { tools: McpTool[] }).tools;\n this.onToolsUpdated(serverId, this.tools);\n this.onEvent(`plugin:mcp:client:${serverId}:tools:listed`, {\n serverId,\n toolCount: this.tools.length,\n });\n } else {\n // Server notified of change but SDK couldn't fetch; re-list manually\n void this.refreshTools();\n }\n },\n },\n },\n },\n ) as unknown as McpSdkClient;\n\n // Connect (performs MCP initialize handshake)\n await this.client.connect(this.transport);\n\n this.running = true;\n\n // List initial tools\n await this.refreshTools();\n\n this.logger.info(\n { serverId, toolCount: this.tools.length },\n \"Stdio client started\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:started`, {\n serverId,\n toolCount: this.tools.length,\n });\n }\n\n /** Gracefully close the client and transport, cancelling any pending restart. */\n async stop(): Promise<void> {\n this.stopping = true;\n\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n if (this.stabilityTimer) {\n clearTimeout(this.stabilityTimer);\n this.stabilityTimer = null;\n }\n\n const { serverId } = this.options;\n\n if (this.client) {\n try {\n await this.client.close();\n } catch {\n // Ignore cleanup errors\n }\n this.client = null;\n }\n\n if (this.transport) {\n const transportWithClose = this.transport as {\n close?: () => void | Promise<void>;\n };\n if (typeof transportWithClose.close === \"function\") {\n try {\n await Promise.resolve(transportWithClose.close());\n } catch {\n // Ignore cleanup errors\n }\n }\n this.transport = null;\n }\n\n this.running = false;\n this.logger.info({ serverId }, \"Stdio client stopped\");\n this.onEvent(`plugin:mcp:client:${serverId}:stopped`, {\n serverId,\n reason: \"graceful\",\n });\n }\n\n /**\n * Call a tool on the remote MCP server.\n * Delegates to SDK Client.callTool().\n *\n * @param name - Tool name to invoke\n * @param args - Arguments passed to the tool\n * @returns The tool result (text content extracted when available)\n */\n async callTool(\n name: string,\n args: Record<string, unknown>,\n ): Promise<unknown> {\n if (!this.running || !this.client) {\n throw new Error(\n `Stdio client \"${this.options.serverId}\" is not running. Cannot call tool \"${name}\".`,\n );\n }\n\n const response = await this.client.callTool({\n name,\n arguments: args,\n });\n\n return extractContent(response);\n }\n\n /** @returns The current list of tools advertised by this server. */\n getTools(): McpTool[] {\n return [...this.tools];\n }\n\n /** @returns Whether the subprocess is connected and running. */\n isRunning(): boolean {\n return this.running;\n }\n\n private async refreshTools(): Promise<void> {\n if (!this.client) return;\n\n const { serverId } = this.options;\n\n try {\n const result = await this.client.listTools();\n this.tools = result.tools ?? [];\n this.onToolsUpdated(serverId, this.tools);\n this.onEvent(`plugin:mcp:client:${serverId}:tools:listed`, {\n serverId,\n toolCount: this.tools.length,\n });\n } catch (err) {\n this.logger.warn(\n { err, serverId },\n \"Failed to list tools for stdio client\",\n );\n }\n }\n\n private handleDisconnect(): void {\n const { serverId, maxRestarts, restartDelayMs, restartBackoffMultiplier } =\n this.options;\n\n // Clear stale tools so consumers don't see tools from a dead process\n if (this.tools.length > 0) {\n this.tools = [];\n this.onToolsUpdated(serverId, []);\n }\n\n this.logger.warn({ serverId }, \"Stdio client disconnected unexpectedly\");\n this.onEvent(`plugin:mcp:client:${serverId}:stopped`, {\n serverId,\n reason: \"unexpected\",\n });\n\n if (this.restartCount >= maxRestarts) {\n this.logger.error(\n { serverId, restartCount: this.restartCount, maxRestarts },\n \"Stdio client exceeded max restarts, giving up\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:error`, {\n serverId,\n error: new Error(\n `Max restarts (${maxRestarts}) exceeded for stdio client \"${serverId}\"`,\n ),\n });\n return;\n }\n\n const delay =\n restartDelayMs * Math.pow(restartBackoffMultiplier, this.restartCount);\n this.logger.info(\n { serverId, restartCount: this.restartCount, delayMs: delay },\n \"Scheduling stdio client restart\",\n );\n\n this.restartTimer = setTimeout(() => {\n this.restartTimer = null;\n void this.restart();\n }, delay);\n }\n\n private async restart(): Promise<void> {\n const { serverId } = this.options;\n this.restartCount++;\n\n // Clean up stale references\n this.client = null;\n this.transport = null;\n\n try {\n await this.start();\n this.logger.info(\n { serverId, restartCount: this.restartCount },\n \"Stdio client restarted successfully\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:restarted`, {\n serverId,\n restartCount: this.restartCount,\n });\n // Reset restart count only after process stays alive for a stability period.\n // This prevents a flapping process from resetting the counter on every\n // momentary connection and bypassing maxRestarts.\n const stableMs = this.options.restartDelayMs * 2;\n this.stabilityTimer = setTimeout(() => {\n this.stabilityTimer = null;\n if (this.running) this.restartCount = 0;\n }, stableMs);\n } catch (err) {\n this.logger.error(\n { err, serverId, restartCount: this.restartCount },\n \"Stdio client restart failed\",\n );\n this.onEvent(`plugin:mcp:client:${serverId}:error`, {\n serverId,\n error: err,\n });\n // Schedule another restart attempt\n this.handleDisconnect();\n }\n }\n}\n","import type { McpToolRegistryEntry } from \"./types.ts\";\n\n/**\n * Central registry of all MCP tools from all sources.\n * Stored in context store under MCP_TOOL_REGISTRY for agent adapter discovery.\n *\n * Sources:\n * - \"local\": mcp() routes from ADAPTER_DIRECT_REGISTRY (tools exposed by this context)\n * - stdio clients: long-lived subprocess MCP servers\n * - HTTP clients: remote HTTP MCP servers (tools refreshed periodically)\n *\n * @experimental\n */\nexport class McpToolRegistry {\n /** Nested Map: source -> toolName -> McpToolRegistryEntry */\n private tools = new Map<string, Map<string, McpToolRegistryEntry>>();\n\n /**\n * Set all tools for a given source (replaces previous tools from that source).\n * Called on initial tool listing and on re-listing after restart/refresh.\n *\n * @param source - Identifier for the tool source (e.g. server ID or \"local\")\n * @param transport - How the tools are reached (\"stdio\", \"http\", or \"local\")\n * @param tools - Tool definitions to register for this source\n */\n setToolsForSource(\n source: string,\n transport: \"stdio\" | \"http\" | \"local\",\n tools: Array<{\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n }>,\n ): void {\n const sourceMap = new Map<string, McpToolRegistryEntry>();\n\n for (const tool of tools) {\n const entry: McpToolRegistryEntry = {\n name: tool.name,\n inputSchema: tool.inputSchema,\n source,\n transport,\n };\n if (tool.description !== undefined) {\n entry.description = tool.description;\n }\n sourceMap.set(tool.name, entry);\n }\n\n this.tools.set(source, sourceMap);\n }\n\n /**\n * Remove all tools for a source (when a client is permanently stopped).\n *\n * @param source - Source identifier whose tools should be removed\n */\n removeSource(source: string): void {\n this.tools.delete(source);\n }\n\n /**\n * Get all tools across all sources.\n *\n * @returns Array of every registered tool entry\n */\n getTools(): McpToolRegistryEntry[] {\n const result: McpToolRegistryEntry[] = [];\n for (const sourceMap of this.tools.values()) {\n for (const entry of sourceMap.values()) {\n result.push(entry);\n }\n }\n return result;\n }\n\n /**\n * Get tools from a specific source/server.\n *\n * @param serverId - Source identifier to filter by\n * @returns Array of tool entries belonging to that source\n */\n getToolsByServer(serverId: string): McpToolRegistryEntry[] {\n const sourceMap = this.tools.get(serverId);\n if (!sourceMap) return [];\n return Array.from(sourceMap.values());\n }\n\n /**\n * Get a specific tool by name. Returns first match if name exists in multiple sources.\n *\n * @param name - Tool name to search for\n * @returns The first matching entry, or undefined\n */\n getTool(name: string): McpToolRegistryEntry | undefined {\n for (const sourceMap of this.tools.values()) {\n const entry = sourceMap.get(name);\n if (entry) return entry;\n }\n return undefined;\n }\n\n /**\n * Get a specific tool by source and name.\n *\n * @param source - Source identifier\n * @param name - Tool name\n * @returns The matching entry, or undefined\n */\n getToolBySource(\n source: string,\n name: string,\n ): McpToolRegistryEntry | undefined {\n return this.tools.get(source)?.get(name);\n }\n}\n","import {\n type CraftContext,\n type CraftPlugin,\n type EventName,\n} from \"@routecraft/routecraft\";\nimport { McpServer } from \"./server.ts\";\nimport {\n ADAPTER_MCP_CLIENT_SERVERS,\n MCP_PLUGIN_REGISTERED,\n MCP_STDIO_MANAGERS,\n MCP_TOOL_REGISTRY,\n} from \"./types.ts\";\nimport type {\n McpClientHttpConfig,\n McpClientStdioConfig,\n McpPluginOptions,\n McpTool,\n} from \"./types.ts\";\nimport { validateMcpPluginOptions } from \"./validate-options.ts\";\nimport { StdioClientManager } from \"./stdio-client-manager.ts\";\nimport { McpToolRegistry } from \"./tool-registry.ts\";\nimport { buildAuthHeaders } from \"./build-auth-headers.ts\";\n\ntype ClientConfig = McpClientHttpConfig | McpClientStdioConfig;\n\nfunction isStdioConfig(config: ClientConfig): config is McpClientStdioConfig {\n return \"transport\" in config && config.transport === \"stdio\";\n}\n\n/**\n * MCP plugin: one plugin per adapter. Starts the MCP server during plugin apply (before routes start) so startup failures fail context build. Exposes mcp() routes to external MCP clients.\n * Optional clients: register named remote MCP servers so routes can use .to(mcp(\"name:tool\")) without passing url.\n * Stdio clients are spawned as subprocesses with auto-restart; HTTP clients are used for ephemeral tool calls.\n * All discovered external tools (stdio, HTTP) are stored in a unified McpToolRegistry for agent adapter discovery.\n * Required when any route uses .from(mcp(...)); the route will fail at start if this plugin is not applied.\n *\n * @experimental\n */\nexport function mcpPlugin(options: McpPluginOptions = {}): CraftPlugin {\n validateMcpPluginOptions(options);\n\n let server: McpServer | null = null;\n const stdioManagers = new Map<string, StdioClientManager>();\n const httpClients = new Map<\n string,\n { close(): Promise<void>; listTools(): Promise<{ tools: McpTool[] }> }\n >();\n const httpRefreshTimers: ReturnType<typeof setInterval>[] = [];\n let toolRegistry: McpToolRegistry | null = null;\n\n return {\n async apply(ctx: CraftContext) {\n ctx.setStore(\n MCP_PLUGIN_REGISTERED as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n true,\n );\n\n // Create and store tool registry\n toolRegistry = new McpToolRegistry();\n ctx.setStore(\n MCP_TOOL_REGISTRY as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n toolRegistry,\n );\n\n // Store stdio managers map so destination adapter can call tools on stdio clients\n ctx.setStore(\n MCP_STDIO_MANAGERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n stdioManagers as unknown as Map<\n string,\n {\n callTool(\n name: string,\n args: Record<string, unknown>,\n ): Promise<unknown>;\n }\n >,\n );\n\n if (options.clients && Object.keys(options.clients).length > 0) {\n const clientEntries = Object.entries(options.clients);\n const map = new Map<\n string,\n McpClientHttpConfig | McpClientStdioConfig | string\n >();\n for (const [k, v] of clientEntries) {\n map.set(k, v);\n }\n ctx.setStore(\n ADAPTER_MCP_CLIENT_SERVERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n map,\n );\n\n // Start stdio clients and list HTTP client tools\n for (const [serverId, config] of clientEntries) {\n if (isStdioConfig(config)) {\n await startStdioClient(ctx, serverId, config, toolRegistry);\n } else {\n // HTTP client: list tools immediately and optionally refresh periodically\n const httpConfig = config as McpClientHttpConfig;\n await listHttpClientTools(\n ctx,\n serverId,\n httpConfig.url,\n toolRegistry,\n httpConfig.auth,\n );\n setupHttpToolRefresh(\n ctx,\n serverId,\n httpConfig.url,\n toolRegistry,\n httpConfig.auth,\n );\n }\n\n const transport = isStdioConfig(config) ? \"stdio\" : \"http\";\n ctx.emit(\n `plugin:mcp:client:${serverId}:registered` as EventName,\n { serverId, transport } as Record<string, unknown>,\n );\n }\n }\n\n server = new McpServer(ctx, options);\n await server.start();\n },\n async teardown(ctx: CraftContext) {\n // Clear HTTP refresh timers\n for (const timer of httpRefreshTimers) {\n clearInterval(timer);\n }\n httpRefreshTimers.length = 0;\n\n // Close persistent HTTP clients\n for (const [serverId, client] of httpClients) {\n try {\n await client.close();\n } catch (error) {\n ctx.logger.error(\n { err: error, serverId, operation: \"close\" },\n \"Failed to close HTTP client\",\n );\n }\n }\n httpClients.clear();\n\n // Stop all stdio client managers\n for (const [serverId, manager] of stdioManagers) {\n try {\n await manager.stop();\n } catch (error) {\n ctx.logger.error(\n { err: error, serverId, operation: \"stop\" },\n \"Failed to stop stdio client\",\n );\n }\n }\n stdioManagers.clear();\n\n if (server) {\n try {\n await server.stop();\n } catch (error) {\n ctx.logger.error(\n { err: error, operation: \"stop\" },\n \"Failed to stop MCP server plugin\",\n );\n }\n server = null;\n }\n\n toolRegistry = null;\n },\n };\n\n async function startStdioClient(\n ctx: CraftContext,\n serverId: string,\n config: McpClientStdioConfig,\n registry: McpToolRegistry,\n ): Promise<void> {\n const managerOpts: import(\"./stdio-client-manager.ts\").StdioClientManagerOptions =\n {\n serverId,\n command: config.command,\n args: config.args ?? [],\n maxRestarts: options.maxRestarts ?? 5,\n restartDelayMs: options.restartDelayMs ?? 1000,\n restartBackoffMultiplier: options.restartBackoffMultiplier ?? 2,\n };\n if (config.env !== undefined) managerOpts.env = config.env;\n if (config.cwd !== undefined) managerOpts.cwd = config.cwd;\n\n const manager = new StdioClientManager(\n managerOpts,\n ctx.logger,\n (event, details) => {\n ctx.emit(event as EventName, details as Record<string, unknown>);\n },\n (_serverId, tools) => {\n registry.setToolsForSource(\n _serverId,\n \"stdio\",\n tools.map((t) => {\n const entry: {\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n } = {\n name: t.name,\n inputSchema: t.inputSchema as Record<string, unknown>,\n };\n if (t.description !== undefined) {\n entry.description = t.description;\n }\n return entry;\n }),\n );\n },\n );\n\n stdioManagers.set(serverId, manager);\n\n try {\n await manager.start();\n } catch (error) {\n ctx.logger.error(\n { err: error, serverId, operation: \"start\" },\n \"Failed to start stdio client\",\n );\n ctx.emit(\n `plugin:mcp:client:${serverId}:error` as EventName,\n {\n serverId,\n error,\n } as Record<string, unknown>,\n );\n }\n }\n\n async function getOrCreateHttpClient(\n serverId: string,\n url: string,\n auth?: McpClientHttpConfig[\"auth\"],\n ): Promise<{\n close(): Promise<void>;\n listTools(): Promise<{ tools: McpTool[] }>;\n }> {\n const existing = httpClients.get(serverId);\n if (existing) return existing;\n\n const { Client } =\n await import(\"@modelcontextprotocol/sdk/client/index.js\");\n const { StreamableHTTPClientTransport } =\n await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n\n const headers = await buildAuthHeaders(auth);\n const transportOptions = headers ? { requestInit: { headers } } : undefined;\n const transport = new (StreamableHTTPClientTransport as new (\n url: URL,\n options?: { requestInit?: { headers?: Record<string, string> } },\n ) => unknown)(new URL(url), transportOptions);\n const rawClient = new Client(\n { name: \"routecraft-mcp-client\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n await (\n rawClient as unknown as { connect(t: unknown): Promise<void> }\n ).connect(transport);\n\n const typed = rawClient as unknown as {\n close(): Promise<void>;\n listTools(): Promise<{ tools: McpTool[] }>;\n };\n httpClients.set(serverId, typed);\n return typed;\n }\n\n async function listHttpClientTools(\n ctx: CraftContext,\n serverId: string,\n url: string,\n registry: McpToolRegistry,\n auth?: McpClientHttpConfig[\"auth\"],\n ): Promise<void> {\n try {\n const client = await getOrCreateHttpClient(serverId, url, auth);\n\n const result = await client.listTools();\n const tools = result.tools ?? [];\n registry.setToolsForSource(\n serverId,\n \"http\",\n tools.map((t) => {\n const entry: {\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n } = {\n name: t.name,\n inputSchema: t.inputSchema as Record<string, unknown>,\n };\n if (t.description !== undefined) {\n entry.description = t.description;\n }\n return entry;\n }),\n );\n\n ctx.emit(\n `plugin:mcp:client:${serverId}:tools:listed` as EventName,\n {\n serverId,\n toolCount: tools.length,\n } as Record<string, unknown>,\n );\n } catch (error) {\n // Connection may have gone stale; discard so next attempt reconnects\n httpClients.delete(serverId);\n ctx.logger.warn(\n { err: error, serverId, url, operation: \"listTools\" },\n \"Failed to list tools from HTTP client\",\n );\n }\n }\n\n function setupHttpToolRefresh(\n ctx: CraftContext,\n serverId: string,\n url: string,\n registry: McpToolRegistry,\n auth?: McpClientHttpConfig[\"auth\"],\n ): void {\n const interval = options.toolRefreshIntervalMs ?? 60_000;\n if (interval <= 0) return;\n\n const timer = setInterval(() => {\n void listHttpClientTools(ctx, serverId, url, registry, auth);\n }, interval);\n httpRefreshTimers.push(timer);\n }\n}\n","import type { Exchange } from \"@routecraft/routecraft\";\nimport type { AgentOptions, AgentResult } from \"./types.ts\";\n\n/**\n * Internal runner for the agent loop. Phase 1: stub that passes through and returns\n * exchange body. Full implementation (LLM + tool dispatch) in Phase 2.\n */\nexport class AgentRunner {\n constructor(private readonly _options: AgentOptions) {}\n\n async run(exchange: Exchange<unknown>): Promise<AgentResult> {\n void this._options; // Phase 2 will use modelId, allowedRoutes, etc.\n // Phase 1: pass-through only\n if (exchange.logger) {\n exchange.logger.debug(\n { adapter: \"agent\" },\n \"Agent pass-through — implementation pending\",\n );\n }\n return {\n output: exchange.body,\n steps: 0,\n };\n }\n}\n","import type { Destination, Exchange } from \"@routecraft/routecraft\";\nimport { AgentRunner } from \"./runner.ts\";\nimport type { AgentOptions, AgentResult } from \"./types.ts\";\n\n/** Validate modelId format \"providerId:modelName\". */\nfunction validateModelId(modelId: string): void {\n const colon = modelId.indexOf(\":\");\n if (colon < 1 || colon === modelId.length - 1) {\n throw new Error(\n `Agent adapter: modelId must be \"providerId:modelName\" (e.g. ollama:llama3). Got: \"${modelId}\"`,\n );\n }\n}\n\n/**\n * Agent destination adapter.\n * Use via agent(); do not instantiate AgentRunner directly.\n *\n * @experimental\n */\nexport class AgentDestinationAdapter implements Destination<\n unknown,\n AgentResult\n> {\n readonly adapterId = \"routecraft.adapter.agent\";\n\n private readonly runner: AgentRunner;\n\n constructor(options: AgentOptions) {\n validateModelId(options.modelId);\n this.runner = new AgentRunner(options);\n }\n\n async send(exchange: Exchange<unknown>): Promise<AgentResult> {\n return this.runner.run(exchange);\n }\n}\n","import type { Destination } from \"@routecraft/routecraft\";\nimport { AgentDestinationAdapter } from \"./destination.ts\";\nimport type { AgentOptions, AgentResult } from \"./types.ts\";\n\n/**\n * Create an agent destination.\n *\n * @experimental\n * @param options Agent options (modelId, systemPrompt, allowedRoutes, etc.)\n * @returns Destination that produces AgentResult\n */\nexport function agent(\n options: AgentOptions,\n): Destination<unknown, AgentResult> {\n return new AgentDestinationAdapter(options);\n}\n","import type { EmbeddingModelConfig } from \"../types.ts\";\n\nexport interface CallEmbeddingParams {\n config: EmbeddingModelConfig;\n modelName: string;\n text: string;\n}\n\ntype PipelineFn = (\n text: string,\n options?: { pooling?: string; normalize?: boolean },\n) => Promise<unknown>;\n\ninterface CachedPipeline {\n run: PipelineFn;\n dispose?: (() => Promise<void>) | undefined;\n}\n\nconst pipelineCache = new Map<string, CachedPipeline>();\n\n/**\n * Dispose all cached HuggingFace pipelines and clear the cache. Call on context\n * shutdown so pipeline.dispose() releases native/ONNX resources.\n *\n * Callers must avoid process.exit() after this -- let the event loop drain\n * naturally so ONNX Runtime's C++ statics aren't torn down prematurely\n * (onnxruntime#25038: \"mutex lock failed: Invalid argument\").\n *\n * @experimental\n */\nexport async function disposeEmbeddingPipelineCache(): Promise<void> {\n const entries = [...pipelineCache.entries()];\n pipelineCache.clear();\n if (entries.length === 0) return;\n\n await Promise.all(\n entries.map(async ([, cached]) => {\n try {\n if (typeof cached.dispose === \"function\") {\n await cached.dispose();\n }\n } catch {\n // Ignore dispose errors during shutdown\n }\n }),\n );\n}\n\n/** Resolve to full Hugging Face repo id. Short names like \"all-MiniLM-L6-v2\" use Xenova/ (ONNX-converted). */\nfunction resolveHuggingFaceModel(modelName: string): string {\n if (modelName.includes(\"/\")) return modelName;\n return `Xenova/${modelName}`;\n}\n\nconst HUGGINGFACE_INSTALL =\n 'The Hugging Face embedding provider requires \"@huggingface/transformers\". Install it with: pnpm add @huggingface/transformers';\n\nfunction isModuleNotFoundFor(error: unknown, pkg: string): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message ?? \"\";\n return (\n (msg.includes(\"ERR_MODULE_NOT_FOUND\") ||\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\")) &&\n msg.includes(pkg)\n );\n}\n\nasync function getHuggingFacePipeline(modelName: string): Promise<PipelineFn> {\n const resolved = resolveHuggingFaceModel(modelName);\n const cached = pipelineCache.get(resolved);\n if (cached) return cached.run;\n\n let pipelineFn: (\n task: string,\n model: string,\n opts?: { dtype?: string },\n ) => Promise<unknown>;\n try {\n const mod = await import(\"@huggingface/transformers\");\n pipelineFn = mod.pipeline as typeof pipelineFn;\n } catch (error) {\n if (isModuleNotFoundFor(error, \"@huggingface/transformers\")) {\n throw new Error(HUGGINGFACE_INSTALL);\n }\n throw error;\n }\n const pipe = (await pipelineFn(\"feature-extraction\", resolved, {\n dtype: \"fp32\",\n })) as {\n (\n text: string,\n options?: { pooling?: string; normalize?: boolean },\n ): Promise<unknown>;\n dispose?: () => void;\n };\n const run: PipelineFn = (text, options) =>\n pipe(text, {\n pooling: (options?.pooling ?? \"mean\") as \"mean\",\n normalize: options?.normalize ?? true,\n });\n const entry: CachedPipeline = {\n run,\n dispose:\n typeof pipe.dispose === \"function\"\n ? () => Promise.resolve(pipe.dispose!())\n : undefined,\n };\n pipelineCache.set(resolved, entry);\n return run;\n}\n\nfunction previewForError(value: unknown): string {\n if (value === null) return \"null\";\n if (typeof value !== \"object\") return String(value);\n if (Array.isArray(value)) return `array(${value.length})`;\n try {\n const s = JSON.stringify(value);\n return s.length > 100 ? s.slice(0, 100) + \"...\" : s;\n } catch {\n return \"object\";\n }\n}\n\nfunction toNumberArray(data: Float32Array | number[] | unknown): number[] {\n if (Array.isArray(data)) return data as number[];\n if (data instanceof Float32Array) return Array.from(data);\n if (data && typeof data === \"object\" && \"data\" in data) {\n const d = (data as { data: unknown }).data;\n if (Array.isArray(d)) return d as number[];\n if (d instanceof Float32Array) return Array.from(d);\n throw new Error(\n `Embedding output .data must be an Array or Float32Array; got ${typeof d}: ${previewForError(d)}`,\n );\n }\n throw new Error(\n `Embedding output must be an Array, Float32Array, or object with .data; got ${typeof data}: ${previewForError(data)}`,\n );\n}\n\nexport async function callEmbedding(\n params: CallEmbeddingParams,\n): Promise<number[]> {\n const { config, modelName, text } = params;\n if (config.provider === \"mock\") {\n const dim = 8;\n const vec: number[] = [];\n for (let i = 0; i < dim; i++) {\n vec.push(((text.length + i) % 100) / 100);\n }\n return vec;\n }\n if (config.provider === \"huggingface\") {\n const pipe = await getHuggingFacePipeline(modelName);\n const output = await pipe(text, {\n pooling: \"mean\" as const,\n normalize: true,\n });\n const data =\n output && typeof output === \"object\" && \"data\" in output\n ? (output as { data: Float32Array | number[] }).data\n : output;\n return toNumberArray(data);\n }\n if (config.provider === \"ollama\" || config.provider === \"openai\") {\n throw new Error(\n `Embedding provider \"${config.provider}\" is not yet implemented. Use huggingface for now.`,\n );\n }\n throw new Error(\n `Unknown embedding provider: ${(config as EmbeddingModelConfig).provider}`,\n );\n}\n","import type { Exchange } from \"@routecraft/routecraft\";\n\n/** Store key for plugin-registered embedding providers (provider id → EmbeddingModelConfig). */\nexport const ADAPTER_EMBEDDING_PROVIDERS = Symbol.for(\n \"routecraft.adapter.embedding.providers\",\n);\n\n/** Store key for context-level default embedding options. */\nexport const ADAPTER_EMBEDDING_OPTIONS = Symbol.for(\n \"routecraft.adapter.embedding.options\",\n);\n\ndeclare module \"@routecraft/routecraft\" {\n interface StoreRegistry {\n [ADAPTER_EMBEDDING_PROVIDERS]: Map<string, EmbeddingModelConfig>;\n [ADAPTER_EMBEDDING_OPTIONS]: Partial<EmbeddingOptions>;\n }\n}\n\nexport interface EmbeddingModelConfigHuggingFace {\n provider: \"huggingface\";\n}\n\nexport interface EmbeddingModelConfigOllama {\n provider: \"ollama\";\n baseURL?: string;\n}\n\nexport interface EmbeddingModelConfigOpenAI {\n provider: \"openai\";\n apiKey: string;\n baseURL?: string;\n}\n\n/** Used by tests only: returns a deterministic vector, no model download. */\nexport interface EmbeddingModelConfigMock {\n provider: \"mock\";\n}\n\nexport type EmbeddingModelConfig =\n | EmbeddingModelConfigHuggingFace\n | EmbeddingModelConfigOllama\n | EmbeddingModelConfigOpenAI\n | EmbeddingModelConfigMock;\n\nexport type EmbeddingProviderType =\n | \"huggingface\"\n | \"ollama\"\n | \"openai\"\n | \"mock\";\n\nexport interface EmbeddingOptions<T = unknown> {\n /** Build the string to embed from the exchange (e.g. jobTitle + location). */\n using: (exchange: Exchange<T>) => string | string[];\n}\n\nexport interface EmbeddingResult {\n embedding: number[];\n}\n\n/** Provider options for embeddingPlugin({ providers }). Key is the provider id. */\nexport interface EmbeddingPluginProviders {\n huggingface?: Record<string, never>;\n ollama?: { baseURL?: string };\n openai?: { apiKey: string; baseURL?: string };\n /** Test-only: deterministic vector, no network. */\n mock?: Record<string, never>;\n}\n\nexport interface EmbeddingPluginOptions {\n providers: EmbeddingPluginProviders;\n /** Optional context-level default options. */\n defaultOptions?: Partial<EmbeddingOptions>;\n}\n\n/**\n * Recommended embedding model ids for autocomplete.\n * Format: \"providerId:modelName\". Custom models are allowed via string.\n * Updated for 2026.\n */\nexport type EmbeddingModelId =\n // HuggingFace\n | \"huggingface:all-MiniLM-L6-v2\"\n | \"huggingface:sentence-transformers/all-MiniLM-L6-v2\"\n | \"huggingface:sentence-transformers/all-mpnet-base-v2\"\n | \"huggingface:BAAI/bge-small-en-v1.5\"\n | \"huggingface:BAAI/bge-base-en-v1.5\"\n | \"huggingface:BAAI/bge-m3\"\n | \"huggingface:intfloat/e5-small-v2\"\n | \"huggingface:intfloat/e5-base-v2\"\n | \"huggingface:intfloat/multilingual-e5-large\"\n // OpenAI\n | \"openai:text-embedding-3-small\"\n | \"openai:text-embedding-3-large\"\n | \"openai:text-embedding-ada-002\"\n // Ollama\n | \"ollama:nomic-embed-text\"\n | \"ollama:nomic-embed-text-v1.5\"\n | \"ollama:mxbai-embed-large\"\n | \"ollama:all-minilm\"\n // Other (custom models)\n | string;\n","import {\n getExchangeContext,\n type CraftContext,\n type Destination,\n type Exchange,\n type MergedOptions,\n} from \"@routecraft/routecraft\";\nimport { callEmbedding } from \"./providers/index.ts\";\nimport type {\n EmbeddingModelConfig,\n EmbeddingOptions,\n EmbeddingResult,\n} from \"./types.ts\";\nimport {\n ADAPTER_EMBEDDING_OPTIONS,\n ADAPTER_EMBEDDING_PROVIDERS,\n} from \"./types.ts\";\n\nfunction parseProviderModel(id: string): {\n providerId: string;\n modelName: string;\n} {\n const colon = id.indexOf(\":\");\n if (colon < 1 || colon === id.length - 1) {\n throw new Error(\n `Embedding adapter: model id must be \"providerId:modelName\" (e.g. huggingface:all-MiniLM-L6-v2). Got: \"${id}\"`,\n );\n }\n return {\n providerId: id.slice(0, colon),\n modelName: id.slice(colon + 1),\n };\n}\n\nfunction resolveProviderAndModel(\n modelId: string,\n context: CraftContext | undefined,\n): { config: EmbeddingModelConfig; modelName: string } {\n if (!context) {\n throw new Error(\n `Embedding adapter: model id \"${modelId}\" requires a context to resolve. Ensure the exchange has context (e.g. from a route) so embedding providers can be read.`,\n );\n }\n const store = context.getStore(\n ADAPTER_EMBEDDING_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Map<string, EmbeddingModelConfig> | undefined;\n if (!store) {\n throw new Error(\n \"Embedding provider not found: no providers registered. Add embeddingPlugin({ providers: { huggingface: {} } }) to your config.\",\n );\n }\n const { providerId, modelName } = parseProviderModel(modelId);\n const config = store.get(providerId);\n if (!config) {\n throw new Error(\n `Embedding provider \"${providerId}\" not found. Register it with embeddingPlugin({ providers: { \"${providerId}\": {} } }).`,\n );\n }\n return { config, modelName };\n}\n\nfunction buildText<T>(\n using: (exchange: Exchange<T>) => string | string[],\n): (exchange: Exchange<T>) => string {\n return (exchange: Exchange<T>) => {\n const value = using(exchange);\n return Array.isArray(value) ? value.filter(Boolean).join(\" | \") : value;\n };\n}\n\n/**\n * Embedding destination adapter. Expects model id as \"providerId:modelName\"\n * (e.g. huggingface:all-MiniLM-L6-v2), resolves the provider from the plugin store,\n * and returns { embedding: number[] }. Use with .enrich(embedding(\"provider:model\", { using: ... })).\n *\n * @experimental\n */\nexport class EmbeddingDestinationAdapter<T = unknown>\n implements Destination<T, EmbeddingResult>, MergedOptions<EmbeddingOptions>\n{\n readonly adapterId = \"routecraft.adapter.embedding\";\n\n constructor(\n private readonly modelId: string,\n options: Partial<EmbeddingOptions<T>> = {},\n ) {\n this.options = options as Partial<EmbeddingOptions>;\n }\n\n public options: Partial<EmbeddingOptions>;\n\n mergedOptions(context: CraftContext): EmbeddingOptions {\n const store = context.getStore(\n ADAPTER_EMBEDDING_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n ) as Partial<EmbeddingOptions> | undefined;\n return { ...store, ...this.options } as EmbeddingOptions;\n }\n\n async send(exchange: Exchange<T>): Promise<EmbeddingResult> {\n const context = getExchangeContext(exchange);\n const { config, modelName } = resolveProviderAndModel(\n this.modelId,\n context,\n );\n const merged = this.mergedOptions(context!);\n\n if (!merged.using) {\n throw new Error(\n \"Embedding adapter: options.using(exchange) is required to build the string to embed.\",\n );\n }\n\n const getText = buildText(\n merged.using as (e: Exchange<unknown>) => string | string[],\n );\n const text = getText(exchange as Exchange<unknown>);\n\n const embedding = await callEmbedding({ config, modelName, text });\n return { embedding };\n }\n}\n","import type { Destination } from \"@routecraft/routecraft\";\nimport { EmbeddingDestinationAdapter } from \"./destination.ts\";\nimport type {\n EmbeddingModelId,\n EmbeddingOptions,\n EmbeddingResult,\n} from \"./types.ts\";\n\n/**\n * Creates an embedding destination that computes a vector for the given text.\n * Use with .enrich(). Pass model id as \"providerId:modelName\" (e.g. huggingface:all-MiniLM-L6-v2).\n * The provider must be registered via embeddingPlugin({ providers: { huggingface: {} } }).\n *\n * @experimental\n * @param modelId - \"providerId:modelName\"; the provider is resolved from the plugin.\n * @param options - using(exchange) returns the string (or string[]) to embed.\n */\nexport function embedding<T = unknown>(\n modelId: EmbeddingModelId,\n options?: Partial<EmbeddingOptions<T>>,\n): Destination<T, EmbeddingResult> {\n return new EmbeddingDestinationAdapter<T>(modelId, options);\n}\n","import type { CraftContext, CraftPlugin } from \"@routecraft/routecraft\";\nimport { disposeEmbeddingPipelineCache } from \"./providers/index.ts\";\nimport {\n ADAPTER_EMBEDDING_OPTIONS,\n ADAPTER_EMBEDDING_PROVIDERS,\n} from \"./types.ts\";\nimport type { EmbeddingModelConfig, EmbeddingPluginOptions } from \"./types.ts\";\n\n/** Normalize provider options to full EmbeddingModelConfig (providerId wins over opts.provider). */\nfunction toModelConfig(\n providerId: string,\n opts: Record<string, unknown>,\n): EmbeddingModelConfig {\n return {\n ...opts,\n provider: providerId as EmbeddingModelConfig[\"provider\"],\n } as EmbeddingModelConfig;\n}\n\n/**\n * Embedding plugin: registers providers and teardown to clear the pipeline\n * cache when the context stops (releases native/ONNX resources).\n * Use embedding(\"providerId:modelName\", { using: ... }),\n * e.g. embedding(\"huggingface:all-MiniLM-L6-v2\", { using: (e) => e.body.title }).\n *\n * @experimental\n */\nexport function embeddingPlugin(\n options: EmbeddingPluginOptions = { providers: {} },\n): CraftPlugin {\n return {\n apply(ctx: CraftContext) {\n const map = new Map<string, EmbeddingModelConfig>();\n for (const [providerId, opts] of Object.entries(options.providers)) {\n if (opts !== undefined) {\n map.set(\n providerId,\n toModelConfig(providerId, opts as Record<string, unknown>),\n );\n }\n }\n ctx.setStore(\n ADAPTER_EMBEDDING_PROVIDERS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n map,\n );\n if (\n options.defaultOptions &&\n Object.keys(options.defaultOptions).length > 0\n ) {\n ctx.setStore(\n ADAPTER_EMBEDDING_OPTIONS as keyof import(\"@routecraft/routecraft\").StoreRegistry,\n options.defaultOptions,\n );\n }\n },\n async teardown() {\n await disposeEmbeddingPipelineCache();\n },\n };\n}\n"]}
|