@agent-native/core 0.105.0 → 0.106.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +33 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/AssistantChat.tsx +4 -0
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +5 -1
- package/corpus/core/src/client/composer/PromptComposer.tsx +8 -0
- package/corpus/core/src/client/composer/TiptapComposer.tsx +38 -1
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +107 -32
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +33 -0
- package/corpus/core/src/client/resources/use-mcp-servers.ts +1 -0
- package/corpus/core/src/client/use-chat-models.ts +10 -2
- package/corpus/core/src/connections/catalog.ts +107 -6
- package/corpus/core/src/localization/default-messages.ts +2 -0
- package/corpus/core/src/mcp/actions/call-mcp-tool.ts +18 -0
- package/corpus/core/src/mcp/actions/list-mcp-tools.ts +18 -0
- package/corpus/core/src/mcp-client/app-api.ts +136 -0
- package/corpus/core/src/mcp-client/index.ts +21 -0
- package/corpus/core/src/mcp-client/oauth-client.ts +462 -0
- package/corpus/core/src/mcp-client/oauth-routes.ts +307 -0
- package/corpus/core/src/mcp-client/remote-store.ts +93 -118
- package/corpus/core/src/mcp-client/remote-url.ts +97 -0
- package/corpus/core/src/mcp-client/routes.ts +11 -0
- package/corpus/core/src/oauth-tokens/store.ts +10 -4
- package/corpus/core/src/provider-api/index.ts +690 -55
- package/corpus/core/src/secrets/register-framework-secrets.ts +30 -0
- package/corpus/core/src/server/action-discovery.ts +2 -0
- package/corpus/core/src/server/core-routes-plugin.ts +9 -1
- package/corpus/core/src/server/workspace-provider-oauth.ts +448 -61
- package/corpus/core/src/templates/default/AGENTS.md +9 -7
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +46 -0
- package/corpus/templates/analytics/app/lib/data-source-status.ts +2 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +61 -0
- package/corpus/templates/analytics/server/handlers/jira.ts +7 -0
- package/corpus/templates/analytics/server/lib/jira.ts +14 -42
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +11 -0
- package/corpus/templates/dispatch/app/routes/integrations.tsx +57 -4
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +2 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +5 -2
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts +2 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +5 -2
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +4 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +13 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +58 -14
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +9 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +13 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +1 -0
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
- package/dist/client/resources/use-mcp-servers.js.map +1 -1
- package/dist/client/use-chat-models.d.ts +1 -0
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +8 -2
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/connections/catalog.d.ts +78 -7
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +97 -6
- package/dist/connections/catalog.js.map +1 -1
- package/dist/localization/default-messages.d.ts +2 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +2 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/actions/call-mcp-tool.d.ts +7 -0
- package/dist/mcp/actions/call-mcp-tool.d.ts.map +1 -0
- package/dist/mcp/actions/call-mcp-tool.js +15 -0
- package/dist/mcp/actions/call-mcp-tool.js.map +1 -0
- package/dist/mcp/actions/list-mcp-tools.d.ts +5 -0
- package/dist/mcp/actions/list-mcp-tools.d.ts.map +1 -0
- package/dist/mcp/actions/list-mcp-tools.js +16 -0
- package/dist/mcp/actions/list-mcp-tools.js.map +1 -0
- package/dist/mcp-client/app-api.d.ts +34 -0
- package/dist/mcp-client/app-api.d.ts.map +1 -0
- package/dist/mcp-client/app-api.js +94 -0
- package/dist/mcp-client/app-api.js.map +1 -0
- package/dist/mcp-client/index.d.ts +3 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +3 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/oauth-client.d.ts +113 -0
- package/dist/mcp-client/oauth-client.d.ts.map +1 -0
- package/dist/mcp-client/oauth-client.js +316 -0
- package/dist/mcp-client/oauth-client.js.map +1 -0
- package/dist/mcp-client/oauth-routes.d.ts +25 -0
- package/dist/mcp-client/oauth-routes.d.ts.map +1 -0
- package/dist/mcp-client/oauth-routes.js +218 -0
- package/dist/mcp-client/oauth-routes.js.map +1 -0
- package/dist/mcp-client/remote-store.d.ts +21 -6
- package/dist/mcp-client/remote-store.d.ts.map +1 -1
- package/dist/mcp-client/remote-store.js +72 -124
- package/dist/mcp-client/remote-store.js.map +1 -1
- package/dist/mcp-client/remote-url.d.ts +8 -0
- package/dist/mcp-client/remote-url.d.ts.map +1 -0
- package/dist/mcp-client/remote-url.js +103 -0
- package/dist/mcp-client/remote-url.js.map +1 -0
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +9 -0
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +2 -2
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +10 -6
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/provider-api/index.d.ts +14 -0
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +499 -61
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +28 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +2 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +9 -1
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +10 -3
- package/dist/server/workspace-provider-oauth.d.ts.map +1 -1
- package/dist/server/workspace-provider-oauth.js +325 -43
- package/dist/server/workspace-provider-oauth.js.map +1 -1
- package/dist/templates/default/AGENTS.md +9 -7
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +46 -0
- package/package.json +2 -2
- package/src/templates/default/AGENTS.md +9 -7
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +46 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp-client/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP client module — symmetric counterpart to `@agent-native/core/mcp`\n * (the MCP server). Connects to local MCP servers configured in\n * `mcp.config.json` or the `MCP_SERVERS` env var and exposes their tools\n * to the agent-chat tool-use loop.\n */\n\nexport {\n loadMcpConfig,\n autoDetectMcpConfig,\n type McpConfig,\n type McpServerConfig,\n} from \"./config.js\";\n\nexport {\n McpClientManager,\n buildMcpToolName,\n parseMcpToolName,\n MCP_TOOL_PREFIX,\n type McpTool,\n type McpClientManagerOptions,\n} from \"./manager.js\";\n\nexport {\n listRemoteServers,\n addRemoteServer,\n addFirstPartyRemoteServer,\n isFirstPartyRemoteEndpointTrusted,\n removeRemoteServer,\n validateRemoteUrl,\n normalizeServerName,\n mergedConfigKey,\n parseMergedKey,\n hashEmail,\n toHttpServerConfig,\n toHttpServerConfigAsync,\n materializeHeaders,\n type RemoteMcpScope,\n type StoredRemoteMcpServer,\n} from \"./remote-store.js\";\n\nexport {\n areBuiltinMcpCapabilitiesSupported,\n BUILTIN_MCP_CAPABILITIES,\n getBuiltinMcpCapability,\n isBuiltinMcpCapabilityAvailable,\n listSupportedBuiltinMcpCapabilities,\n normalizeBuiltinMcpCapabilityIds,\n toBuiltinMcpServerConfig,\n type BuiltinMcpCapability,\n type BuiltinMcpCapabilityId,\n} from \"./builtin-capabilities.js\";\n\nexport {\n builtinMcpCapabilitiesSettingsKey,\n listEnabledBuiltinMcpCapabilities,\n setEnabledBuiltinMcpCapabilities,\n setBuiltinMcpCapabilityEnabled,\n type StoredBuiltinMcpCapabilities,\n} from \"./builtin-store.js\";\n\nexport {\n mountMcpServersRoutes,\n buildMergedConfig,\n builtinMergedConfigKey,\n startMcpConfigRefresh,\n type ClientBuiltinCapability,\n} from \"./routes.js\";\n\nexport {\n mountMcpHubRoutes,\n listHubServers,\n getHubStatus,\n isHubServeEnabled,\n isHubConsumeEnabled,\n type HubServerRecord,\n type HubServersResponse,\n} from \"./hub-routes.js\";\n\nexport { fetchHubServers } from \"./hub-client.js\";\n\nexport { isMcpToolAllowedForRequest } from \"./visibility.js\";\nimport { isMcpToolAllowedForRequest } from \"./visibility.js\";\nexport {\n classifyMcpToolCall,\n evaluateMcpToolCallPolicy,\n type McpToolCallClassification,\n type McpToolEffect,\n type McpToolFamily,\n type McpToolInvocationPolicy,\n type McpToolPolicyDecision,\n} from \"./tool-policy.js\";\nexport {\n configureScreenMemory,\n queryScreenMemoryContext,\n readScreenMemoryStatus,\n type ScreenMemoryConfig,\n type ScreenMemoryContextItem,\n type ScreenMemoryQueryResult,\n type ScreenMemoryStatus,\n} from \"./screen-memory-local.js\";\nexport {\n MCP_ACTION_RESULT_MARKER,\n isMcpActionResult,\n type AgentMcpAppPayload,\n type AgentMcpAppResourceContent,\n type McpActionResult,\n} from \"./app-result.js\";\nimport {\n getToolUiResourceUri,\n isToolVisibilityAppOnly,\n isToolVisibilityModelOnly,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\n\nimport { MCP_APP_MIME_TYPE } from \"../action.js\";\nimport type { EngineToolResultImagePart } from \"../agent/engine/types.js\";\n/**\n * Convert MCP tools into `ActionEntry` values suitable for registration in\n * the agent's action registry. Each tool is marked `http: false` so it's\n * never auto-mounted as an HTTP endpoint — MCP tools are agent-only.\n */\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport { normalizeToolResultImages } from \"../agent/tool-result-images.js\";\nimport {\n MCP_ACTION_RESULT_MARKER,\n toolForMcpAppPayload,\n type AgentMcpAppPayload,\n type AgentMcpAppResourceContent,\n type McpActionResult,\n} from \"./app-result.js\";\nimport type { McpClientManager, McpTool } from \"./manager.js\";\nimport {\n evaluateMcpToolCallPolicy,\n type McpToolInvocationPolicy,\n} from \"./tool-policy.js\";\n\nexport interface McpActionEntryOptions {\n invocationPolicy?: McpToolInvocationPolicy;\n}\n\nexport function mcpToolsToActionEntries(\n manager: McpClientManager,\n options: McpActionEntryOptions = {},\n): Record<string, ActionEntry> {\n const entries: Record<string, ActionEntry> = {};\n for (const tool of manager.getTools().filter(isVisibleToModel)) {\n entries[tool.name] = mcpToolToActionEntry(manager, tool, options);\n }\n return entries;\n}\n\n/**\n * Mutate a target action dict in place so it matches the current MCP tool set:\n * - adds new `mcp__*` keys that aren't in target,\n * - removes `mcp__*` keys that no longer exist in the manager,\n * - leaves non-MCP keys untouched.\n *\n * Used by the agent-chat plugin to keep its `prodActions` / `devActions`\n * registries in sync after `McpClientManager.reconfigure()` runs.\n */\nexport function syncMcpActionEntries(\n manager: McpClientManager,\n target: Record<string, ActionEntry>,\n): void {\n const current = new Set<string>();\n for (const tool of manager.getTools().filter(isVisibleToModel)) {\n current.add(tool.name);\n target[tool.name] = mcpToolToActionEntry(manager, tool);\n }\n for (const key of Object.keys(target)) {\n if (key.startsWith(\"mcp__\") && !current.has(key)) {\n delete target[key];\n }\n }\n}\n\nfunction mcpToolToActionEntry(\n manager: McpClientManager,\n tool: McpTool,\n options: McpActionEntryOptions = {},\n): ActionEntry {\n return {\n tool: {\n description: tool.description,\n parameters: tool.inputSchema as any,\n },\n http: false,\n ...(tool.annotations?.readOnlyHint === true ? { readOnly: true } : {}),\n run: async (args: Record<string, unknown>) => {\n // Defense-in-depth: even if a cross-scope MCP tool somehow makes it\n // into the LLM's visible tool list, reject invocation here so we never\n // execute a user's credentials on behalf of another user.\n if (!isMcpToolAllowedForRequest(tool.name)) {\n return buildMcpErrorActionResult(\n tool,\n args,\n `Error: MCP tool ${tool.name} is not available in the current request scope.`,\n );\n }\n if (options.invocationPolicy) {\n const decision = evaluateMcpToolCallPolicy(\n options.invocationPolicy,\n tool,\n args,\n );\n if (!decision.allowed) {\n return buildMcpErrorActionResult(\n tool,\n args,\n `Error: MCP tool ${tool.name} is unavailable in read-only mode: ${decision.reason}.`,\n );\n }\n }\n try {\n const result = await manager.callTool(tool.name, args);\n return await buildMcpActionResult(manager, tool, args, result);\n } catch (err: any) {\n return buildMcpErrorActionResult(\n tool,\n args,\n `Error calling MCP tool ${tool.name}: ${err?.message ?? err}`,\n );\n }\n },\n };\n}\n\nfunction isVisibleToModel(tool: McpTool): boolean {\n try {\n return !isToolVisibilityAppOnly(tool.raw as any);\n } catch {\n return true;\n }\n}\n\nexport function isVisibleToMcpApp(tool: McpTool): boolean {\n try {\n return !isToolVisibilityModelOnly(tool.raw as any);\n } catch {\n return true;\n }\n}\n\nexport function flattenMcpToolResult(result: unknown): string {\n if (\n result &&\n typeof result === \"object\" &&\n Array.isArray((result as any).content)\n ) {\n const parts = (result as any).content as Array<Record<string, any>>;\n const text = parts.map(formatMcpContentPart).join(\"\\n\");\n const fallback =\n text ||\n (hasStructuredContent(result)\n ? JSON.stringify((result as any).structuredContent, null, 2)\n : \"(no output)\");\n if ((result as any).isError) return `Error: ${fallback}`;\n return fallback;\n }\n return typeof result === \"string\" ? result : JSON.stringify(result);\n}\n\nfunction formatMcpContentPart(part: Record<string, any>): string {\n if (part?.type === \"text\" && typeof part.text === \"string\") {\n return part.text;\n }\n if (part?.type === \"image\") {\n return `[image: ${part?.mimeType ?? \"unknown\"}]`;\n }\n if (part?.type === \"resource\") {\n const resource = part.resource ?? {};\n const uri = typeof resource.uri === \"string\" ? ` ${resource.uri}` : \"\";\n return `[resource: ${resource.mimeType ?? \"unknown\"}${uri}]`;\n }\n if (part?.type === \"resource_link\") {\n const uri = typeof part.uri === \"string\" ? ` ${part.uri}` : \"\";\n return `[resource: ${part.mimeType ?? \"unknown\"}${uri}]`;\n }\n return JSON.stringify(part);\n}\n\nfunction hasStructuredContent(result: unknown): boolean {\n return (\n !!result &&\n typeof result === \"object\" &&\n Object.prototype.hasOwnProperty.call(result, \"structuredContent\")\n );\n}\n\n/**\n * Extract vision images from a raw MCP tool result so the model can SEE\n * screenshots/previews returned by external MCP tools instead of only the\n * `[image: <mime>]` placeholder that `flattenMcpToolResult` leaves in the\n * text. Shares the per-result caps with `_agentImages` (max count, max base64\n * size); over-cap or unsupported images stay placeholder-only. Never throws.\n */\nexport function extractMcpToolResultImages(\n result: unknown,\n): EngineToolResultImagePart[] {\n if (\n !result ||\n typeof result !== \"object\" ||\n !Array.isArray((result as any).content) ||\n (result as any).isError\n ) {\n return [];\n }\n const candidates = ((result as any).content as Array<Record<string, any>>)\n .filter((part) => part?.type === \"image\" && typeof part.data === \"string\")\n .map((part) => ({\n data: part.data as string,\n mediaType: typeof part.mimeType === \"string\" ? part.mimeType : undefined,\n }));\n return normalizeToolResultImages(candidates).images;\n}\n\nasync function buildMcpActionResult(\n manager: McpClientManager,\n tool: McpTool,\n input: Record<string, unknown>,\n raw: unknown,\n): Promise<McpActionResult> {\n const text = flattenMcpToolResult(raw);\n const mcpApp = await extractMcpAppPayload(manager, tool, input, raw);\n return {\n [MCP_ACTION_RESULT_MARKER]: true,\n text,\n raw,\n serverId: tool.source,\n toolName: tool.name,\n originalToolName: tool.originalName,\n input,\n ...(mcpApp ? { mcpApp } : {}),\n };\n}\n\nfunction buildMcpErrorActionResult(\n tool: McpTool,\n input: Record<string, unknown>,\n text: string,\n): McpActionResult {\n return {\n [MCP_ACTION_RESULT_MARKER]: true,\n text,\n raw: {\n isError: true,\n content: [{ type: \"text\", text }],\n },\n serverId: tool.source,\n toolName: tool.name,\n originalToolName: tool.originalName,\n input,\n };\n}\n\nasync function extractMcpAppPayload(\n manager: McpClientManager,\n tool: McpTool,\n input: Record<string, unknown>,\n raw: unknown,\n): Promise<AgentMcpAppPayload | undefined> {\n const inlineResource = findInlineMcpAppResource(raw);\n const resourceUri =\n inlineResource?.uri ??\n resourceUriFromTool(tool) ??\n resourceUriFromResult(raw);\n if (!resourceUri) return undefined;\n\n const resource =\n inlineResource ?? (await readMcpAppResource(manager, tool, resourceUri));\n\n return {\n serverId: tool.source,\n toolName: tool.name,\n originalToolName: tool.originalName,\n resourceUri,\n toolInput: input,\n toolResult:\n raw && typeof raw === \"object\"\n ? ({ ...(raw as Record<string, unknown>) } as Record<string, unknown>)\n : { content: [{ type: \"text\", text: String(raw ?? \"\") }] },\n tool: toolForMcpAppPayload(tool),\n ...(resource ? { resource } : {}),\n };\n}\n\nfunction resourceUriFromTool(tool: McpTool): string | undefined {\n try {\n return getToolUiResourceUri(tool.raw as any);\n } catch {\n return undefined;\n }\n}\n\nfunction resourceUriFromResult(raw: unknown): string | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const meta = (raw as any)._meta;\n const nested = meta?.ui?.resourceUri;\n if (typeof nested === \"string\" && nested.startsWith(\"ui://\")) return nested;\n const flat = meta?.[\"ui/resourceUri\"] ?? meta?.[\"ui.resourceUri\"];\n if (typeof flat === \"string\" && flat.startsWith(\"ui://\")) return flat;\n return findInlineMcpAppResource(raw)?.uri;\n}\n\nfunction findInlineMcpAppResource(\n raw: unknown,\n): AgentMcpAppResourceContent | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const content = Array.isArray((raw as any).content)\n ? ((raw as any).content as unknown[])\n : [];\n for (const part of content) {\n const resource = normalizeMcpAppResourceContent(part);\n if (resource) return resource;\n }\n return undefined;\n}\n\nfunction normalizeMcpAppResourceContent(\n part: unknown,\n): AgentMcpAppResourceContent | undefined {\n if (!part || typeof part !== \"object\") return undefined;\n const candidate =\n (part as any).type === \"resource\"\n ? (part as any).resource\n : ((part as any).resource ?? part);\n if (!candidate || typeof candidate !== \"object\") return undefined;\n const uri = (candidate as any).uri;\n if (typeof uri !== \"string\" || !uri.startsWith(\"ui://\")) return undefined;\n const mimeType =\n typeof (candidate as any).mimeType === \"string\"\n ? (candidate as any).mimeType\n : undefined;\n if (mimeType && !mimeType.includes(MCP_APP_MIME_TYPE)) return undefined;\n const text =\n typeof (candidate as any).text === \"string\"\n ? (candidate as any).text\n : undefined;\n const blob =\n typeof (candidate as any).blob === \"string\"\n ? (candidate as any).blob\n : undefined;\n const meta =\n (candidate as any)._meta && typeof (candidate as any)._meta === \"object\"\n ? ((candidate as any)._meta as Record<string, unknown>)\n : (part as any)._meta && typeof (part as any)._meta === \"object\"\n ? ((part as any)._meta as Record<string, unknown>)\n : undefined;\n return {\n uri,\n ...(mimeType ? { mimeType } : {}),\n ...(text ? { text } : {}),\n ...(blob ? { blob } : {}),\n ...(meta ? { _meta: meta } : {}),\n };\n}\n\nasync function readMcpAppResource(\n manager: McpClientManager,\n tool: McpTool,\n resourceUri: string,\n): Promise<AgentMcpAppResourceContent | undefined> {\n try {\n const result = await manager.readResourceForTool(tool.name, resourceUri);\n const contents = Array.isArray((result as any)?.contents)\n ? ((result as any).contents as unknown[])\n : [];\n for (const content of contents) {\n const resource = normalizeMcpAppResourceContent(content);\n if (\n resource?.uri === resourceUri ||\n (resource && contents.length === 1)\n ) {\n return resource;\n }\n }\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to read MCP App resource ${resourceUri}: ${err?.message ?? err}`,\n );\n }\n return undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp-client/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP client module — symmetric counterpart to `@agent-native/core/mcp`\n * (the MCP server). Connects to local MCP servers configured in\n * `mcp.config.json` or the `MCP_SERVERS` env var and exposes their tools\n * to the agent-chat tool-use loop.\n */\n\nexport {\n loadMcpConfig,\n autoDetectMcpConfig,\n type McpConfig,\n type McpServerConfig,\n} from \"./config.js\";\n\nexport {\n McpClientManager,\n buildMcpToolName,\n parseMcpToolName,\n MCP_TOOL_PREFIX,\n type McpTool,\n type McpClientManagerOptions,\n} from \"./manager.js\";\n\nexport {\n listRemoteServers,\n addRemoteServer,\n addOAuthRemoteServer,\n addFirstPartyRemoteServer,\n isFirstPartyRemoteEndpointTrusted,\n removeRemoteServer,\n validateRemoteUrl,\n normalizeServerName,\n mergedConfigKey,\n parseMergedKey,\n hashEmail,\n toHttpServerConfig,\n toHttpServerConfigAsync,\n materializeHeaders,\n type RemoteMcpScope,\n type StoredRemoteMcpServer,\n} from \"./remote-store.js\";\n\nexport {\n finishMcpOAuthAuthorization,\n getMcpOAuthAccessToken,\n readMcpOAuthCredentials,\n saveMcpOAuthCredentials,\n startMcpOAuthAuthorization,\n type McpOAuthCallbackResult,\n type McpOAuthCredentialBundle,\n type McpOAuthDiscoveryState,\n type McpOAuthProviderOptions,\n type McpOAuthStartResult,\n} from \"./oauth-client.js\";\n\nexport {\n areBuiltinMcpCapabilitiesSupported,\n BUILTIN_MCP_CAPABILITIES,\n getBuiltinMcpCapability,\n isBuiltinMcpCapabilityAvailable,\n listSupportedBuiltinMcpCapabilities,\n normalizeBuiltinMcpCapabilityIds,\n toBuiltinMcpServerConfig,\n type BuiltinMcpCapability,\n type BuiltinMcpCapabilityId,\n} from \"./builtin-capabilities.js\";\n\nexport {\n builtinMcpCapabilitiesSettingsKey,\n listEnabledBuiltinMcpCapabilities,\n setEnabledBuiltinMcpCapabilities,\n setBuiltinMcpCapabilityEnabled,\n type StoredBuiltinMcpCapabilities,\n} from \"./builtin-store.js\";\n\nexport {\n mountMcpServersRoutes,\n buildMergedConfig,\n builtinMergedConfigKey,\n startMcpConfigRefresh,\n type ClientBuiltinCapability,\n} from \"./routes.js\";\n\nexport {\n mountMcpHubRoutes,\n listHubServers,\n getHubStatus,\n isHubServeEnabled,\n isHubConsumeEnabled,\n type HubServerRecord,\n type HubServersResponse,\n} from \"./hub-routes.js\";\n\nexport { fetchHubServers } from \"./hub-client.js\";\n\nexport { isMcpToolAllowedForRequest } from \"./visibility.js\";\nexport {\n callMcpTool,\n listVisibleMcpTools,\n McpAppApiError,\n type AppMcpTool,\n type ListVisibleMcpToolsOptions,\n} from \"./app-api.js\";\nimport { isMcpToolAllowedForRequest } from \"./visibility.js\";\nexport {\n classifyMcpToolCall,\n evaluateMcpToolCallPolicy,\n type McpToolCallClassification,\n type McpToolEffect,\n type McpToolFamily,\n type McpToolInvocationPolicy,\n type McpToolPolicyDecision,\n} from \"./tool-policy.js\";\nexport {\n configureScreenMemory,\n queryScreenMemoryContext,\n readScreenMemoryStatus,\n type ScreenMemoryConfig,\n type ScreenMemoryContextItem,\n type ScreenMemoryQueryResult,\n type ScreenMemoryStatus,\n} from \"./screen-memory-local.js\";\nexport {\n MCP_ACTION_RESULT_MARKER,\n isMcpActionResult,\n type AgentMcpAppPayload,\n type AgentMcpAppResourceContent,\n type McpActionResult,\n} from \"./app-result.js\";\nimport {\n getToolUiResourceUri,\n isToolVisibilityAppOnly,\n isToolVisibilityModelOnly,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\n\nimport { MCP_APP_MIME_TYPE } from \"../action.js\";\nimport type { EngineToolResultImagePart } from \"../agent/engine/types.js\";\n/**\n * Convert MCP tools into `ActionEntry` values suitable for registration in\n * the agent's action registry. Each tool is marked `http: false` so it's\n * never auto-mounted as an HTTP endpoint — MCP tools are agent-only.\n */\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport { normalizeToolResultImages } from \"../agent/tool-result-images.js\";\nimport {\n MCP_ACTION_RESULT_MARKER,\n toolForMcpAppPayload,\n type AgentMcpAppPayload,\n type AgentMcpAppResourceContent,\n type McpActionResult,\n} from \"./app-result.js\";\nimport type { McpClientManager, McpTool } from \"./manager.js\";\nimport {\n evaluateMcpToolCallPolicy,\n type McpToolInvocationPolicy,\n} from \"./tool-policy.js\";\n\nexport interface McpActionEntryOptions {\n invocationPolicy?: McpToolInvocationPolicy;\n}\n\nexport function mcpToolsToActionEntries(\n manager: McpClientManager,\n options: McpActionEntryOptions = {},\n): Record<string, ActionEntry> {\n const entries: Record<string, ActionEntry> = {};\n for (const tool of manager.getTools().filter(isVisibleToModel)) {\n entries[tool.name] = mcpToolToActionEntry(manager, tool, options);\n }\n return entries;\n}\n\n/**\n * Mutate a target action dict in place so it matches the current MCP tool set:\n * - adds new `mcp__*` keys that aren't in target,\n * - removes `mcp__*` keys that no longer exist in the manager,\n * - leaves non-MCP keys untouched.\n *\n * Used by the agent-chat plugin to keep its `prodActions` / `devActions`\n * registries in sync after `McpClientManager.reconfigure()` runs.\n */\nexport function syncMcpActionEntries(\n manager: McpClientManager,\n target: Record<string, ActionEntry>,\n): void {\n const current = new Set<string>();\n for (const tool of manager.getTools().filter(isVisibleToModel)) {\n current.add(tool.name);\n target[tool.name] = mcpToolToActionEntry(manager, tool);\n }\n for (const key of Object.keys(target)) {\n if (key.startsWith(\"mcp__\") && !current.has(key)) {\n delete target[key];\n }\n }\n}\n\nfunction mcpToolToActionEntry(\n manager: McpClientManager,\n tool: McpTool,\n options: McpActionEntryOptions = {},\n): ActionEntry {\n return {\n tool: {\n description: tool.description,\n parameters: tool.inputSchema as any,\n },\n http: false,\n ...(tool.annotations?.readOnlyHint === true ? { readOnly: true } : {}),\n run: async (args: Record<string, unknown>) => {\n // Defense-in-depth: even if a cross-scope MCP tool somehow makes it\n // into the LLM's visible tool list, reject invocation here so we never\n // execute a user's credentials on behalf of another user.\n if (!isMcpToolAllowedForRequest(tool.name)) {\n return buildMcpErrorActionResult(\n tool,\n args,\n `Error: MCP tool ${tool.name} is not available in the current request scope.`,\n );\n }\n if (options.invocationPolicy) {\n const decision = evaluateMcpToolCallPolicy(\n options.invocationPolicy,\n tool,\n args,\n );\n if (!decision.allowed) {\n return buildMcpErrorActionResult(\n tool,\n args,\n `Error: MCP tool ${tool.name} is unavailable in read-only mode: ${decision.reason}.`,\n );\n }\n }\n try {\n const result = await manager.callTool(tool.name, args);\n return await buildMcpActionResult(manager, tool, args, result);\n } catch (err: any) {\n return buildMcpErrorActionResult(\n tool,\n args,\n `Error calling MCP tool ${tool.name}: ${err?.message ?? err}`,\n );\n }\n },\n };\n}\n\nfunction isVisibleToModel(tool: McpTool): boolean {\n try {\n return !isToolVisibilityAppOnly(tool.raw as any);\n } catch {\n return true;\n }\n}\n\nexport function isVisibleToMcpApp(tool: McpTool): boolean {\n try {\n return !isToolVisibilityModelOnly(tool.raw as any);\n } catch {\n return true;\n }\n}\n\nexport function flattenMcpToolResult(result: unknown): string {\n if (\n result &&\n typeof result === \"object\" &&\n Array.isArray((result as any).content)\n ) {\n const parts = (result as any).content as Array<Record<string, any>>;\n const text = parts.map(formatMcpContentPart).join(\"\\n\");\n const fallback =\n text ||\n (hasStructuredContent(result)\n ? JSON.stringify((result as any).structuredContent, null, 2)\n : \"(no output)\");\n if ((result as any).isError) return `Error: ${fallback}`;\n return fallback;\n }\n return typeof result === \"string\" ? result : JSON.stringify(result);\n}\n\nfunction formatMcpContentPart(part: Record<string, any>): string {\n if (part?.type === \"text\" && typeof part.text === \"string\") {\n return part.text;\n }\n if (part?.type === \"image\") {\n return `[image: ${part?.mimeType ?? \"unknown\"}]`;\n }\n if (part?.type === \"resource\") {\n const resource = part.resource ?? {};\n const uri = typeof resource.uri === \"string\" ? ` ${resource.uri}` : \"\";\n return `[resource: ${resource.mimeType ?? \"unknown\"}${uri}]`;\n }\n if (part?.type === \"resource_link\") {\n const uri = typeof part.uri === \"string\" ? ` ${part.uri}` : \"\";\n return `[resource: ${part.mimeType ?? \"unknown\"}${uri}]`;\n }\n return JSON.stringify(part);\n}\n\nfunction hasStructuredContent(result: unknown): boolean {\n return (\n !!result &&\n typeof result === \"object\" &&\n Object.prototype.hasOwnProperty.call(result, \"structuredContent\")\n );\n}\n\n/**\n * Extract vision images from a raw MCP tool result so the model can SEE\n * screenshots/previews returned by external MCP tools instead of only the\n * `[image: <mime>]` placeholder that `flattenMcpToolResult` leaves in the\n * text. Shares the per-result caps with `_agentImages` (max count, max base64\n * size); over-cap or unsupported images stay placeholder-only. Never throws.\n */\nexport function extractMcpToolResultImages(\n result: unknown,\n): EngineToolResultImagePart[] {\n if (\n !result ||\n typeof result !== \"object\" ||\n !Array.isArray((result as any).content) ||\n (result as any).isError\n ) {\n return [];\n }\n const candidates = ((result as any).content as Array<Record<string, any>>)\n .filter((part) => part?.type === \"image\" && typeof part.data === \"string\")\n .map((part) => ({\n data: part.data as string,\n mediaType: typeof part.mimeType === \"string\" ? part.mimeType : undefined,\n }));\n return normalizeToolResultImages(candidates).images;\n}\n\nasync function buildMcpActionResult(\n manager: McpClientManager,\n tool: McpTool,\n input: Record<string, unknown>,\n raw: unknown,\n): Promise<McpActionResult> {\n const text = flattenMcpToolResult(raw);\n const mcpApp = await extractMcpAppPayload(manager, tool, input, raw);\n return {\n [MCP_ACTION_RESULT_MARKER]: true,\n text,\n raw,\n serverId: tool.source,\n toolName: tool.name,\n originalToolName: tool.originalName,\n input,\n ...(mcpApp ? { mcpApp } : {}),\n };\n}\n\nfunction buildMcpErrorActionResult(\n tool: McpTool,\n input: Record<string, unknown>,\n text: string,\n): McpActionResult {\n return {\n [MCP_ACTION_RESULT_MARKER]: true,\n text,\n raw: {\n isError: true,\n content: [{ type: \"text\", text }],\n },\n serverId: tool.source,\n toolName: tool.name,\n originalToolName: tool.originalName,\n input,\n };\n}\n\nasync function extractMcpAppPayload(\n manager: McpClientManager,\n tool: McpTool,\n input: Record<string, unknown>,\n raw: unknown,\n): Promise<AgentMcpAppPayload | undefined> {\n const inlineResource = findInlineMcpAppResource(raw);\n const resourceUri =\n inlineResource?.uri ??\n resourceUriFromTool(tool) ??\n resourceUriFromResult(raw);\n if (!resourceUri) return undefined;\n\n const resource =\n inlineResource ?? (await readMcpAppResource(manager, tool, resourceUri));\n\n return {\n serverId: tool.source,\n toolName: tool.name,\n originalToolName: tool.originalName,\n resourceUri,\n toolInput: input,\n toolResult:\n raw && typeof raw === \"object\"\n ? ({ ...(raw as Record<string, unknown>) } as Record<string, unknown>)\n : { content: [{ type: \"text\", text: String(raw ?? \"\") }] },\n tool: toolForMcpAppPayload(tool),\n ...(resource ? { resource } : {}),\n };\n}\n\nfunction resourceUriFromTool(tool: McpTool): string | undefined {\n try {\n return getToolUiResourceUri(tool.raw as any);\n } catch {\n return undefined;\n }\n}\n\nfunction resourceUriFromResult(raw: unknown): string | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const meta = (raw as any)._meta;\n const nested = meta?.ui?.resourceUri;\n if (typeof nested === \"string\" && nested.startsWith(\"ui://\")) return nested;\n const flat = meta?.[\"ui/resourceUri\"] ?? meta?.[\"ui.resourceUri\"];\n if (typeof flat === \"string\" && flat.startsWith(\"ui://\")) return flat;\n return findInlineMcpAppResource(raw)?.uri;\n}\n\nfunction findInlineMcpAppResource(\n raw: unknown,\n): AgentMcpAppResourceContent | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const content = Array.isArray((raw as any).content)\n ? ((raw as any).content as unknown[])\n : [];\n for (const part of content) {\n const resource = normalizeMcpAppResourceContent(part);\n if (resource) return resource;\n }\n return undefined;\n}\n\nfunction normalizeMcpAppResourceContent(\n part: unknown,\n): AgentMcpAppResourceContent | undefined {\n if (!part || typeof part !== \"object\") return undefined;\n const candidate =\n (part as any).type === \"resource\"\n ? (part as any).resource\n : ((part as any).resource ?? part);\n if (!candidate || typeof candidate !== \"object\") return undefined;\n const uri = (candidate as any).uri;\n if (typeof uri !== \"string\" || !uri.startsWith(\"ui://\")) return undefined;\n const mimeType =\n typeof (candidate as any).mimeType === \"string\"\n ? (candidate as any).mimeType\n : undefined;\n if (mimeType && !mimeType.includes(MCP_APP_MIME_TYPE)) return undefined;\n const text =\n typeof (candidate as any).text === \"string\"\n ? (candidate as any).text\n : undefined;\n const blob =\n typeof (candidate as any).blob === \"string\"\n ? (candidate as any).blob\n : undefined;\n const meta =\n (candidate as any)._meta && typeof (candidate as any)._meta === \"object\"\n ? ((candidate as any)._meta as Record<string, unknown>)\n : (part as any)._meta && typeof (part as any)._meta === \"object\"\n ? ((part as any)._meta as Record<string, unknown>)\n : undefined;\n return {\n uri,\n ...(mimeType ? { mimeType } : {}),\n ...(text ? { text } : {}),\n ...(blob ? { blob } : {}),\n ...(meta ? { _meta: meta } : {}),\n };\n}\n\nasync function readMcpAppResource(\n manager: McpClientManager,\n tool: McpTool,\n resourceUri: string,\n): Promise<AgentMcpAppResourceContent | undefined> {\n try {\n const result = await manager.readResourceForTool(tool.name, resourceUri);\n const contents = Array.isArray((result as any)?.contents)\n ? ((result as any).contents as unknown[])\n : [];\n for (const content of contents) {\n const resource = normalizeMcpAppResourceContent(content);\n if (\n resource?.uri === resourceUri ||\n (resource && contents.length === 1)\n ) {\n return resource;\n }\n }\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to read MCP App resource ${resourceUri}: ${err?.message ?? err}`,\n );\n }\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.1 client support for remote MCP servers.
|
|
3
|
+
*
|
|
4
|
+
* MCP servers advertise their OAuth endpoints through the standard protected
|
|
5
|
+
* resource and authorization-server metadata documents. The SDK handles the
|
|
6
|
+
* protocol details; this module owns the framework-specific encrypted storage
|
|
7
|
+
* and refresh boundary.
|
|
8
|
+
*/
|
|
9
|
+
import { type OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
10
|
+
import type { AuthorizationServerMetadata, OAuthClientInformationMixed, OAuthClientMetadata, OAuthProtectedResourceMetadata, OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
11
|
+
export interface McpOAuthDiscoveryState {
|
|
12
|
+
authorizationServerUrl: string;
|
|
13
|
+
authorizationServerMetadata?: AuthorizationServerMetadata;
|
|
14
|
+
resourceMetadata?: OAuthProtectedResourceMetadata;
|
|
15
|
+
resourceMetadataUrl?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface McpOAuthCredentialBundle {
|
|
18
|
+
serverUrl: string;
|
|
19
|
+
clientInformation: OAuthClientInformationMixed;
|
|
20
|
+
discoveryState?: McpOAuthDiscoveryState;
|
|
21
|
+
tokens: OAuthTokens;
|
|
22
|
+
tokenExpiresAt?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface McpOAuthStartResult {
|
|
25
|
+
authorizationUrl: URL;
|
|
26
|
+
codeVerifier: string;
|
|
27
|
+
state: string;
|
|
28
|
+
clientInformation: OAuthClientInformationMixed;
|
|
29
|
+
discoveryState?: McpOAuthDiscoveryState;
|
|
30
|
+
}
|
|
31
|
+
export interface McpOAuthCallbackResult {
|
|
32
|
+
credentials: McpOAuthCredentialBundle;
|
|
33
|
+
}
|
|
34
|
+
export interface McpOAuthProviderOptions {
|
|
35
|
+
serverUrl: string;
|
|
36
|
+
redirectUrl: string;
|
|
37
|
+
state: string;
|
|
38
|
+
clientInformation?: OAuthClientInformationMixed;
|
|
39
|
+
codeVerifier?: string;
|
|
40
|
+
discoveryState?: McpOAuthDiscoveryState;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A small adapter around the MCP SDK's OAuth provider interface. The route
|
|
44
|
+
* stores the adapter's state in an encrypted, short-lived browser cookie; the
|
|
45
|
+
* durable credential bundle is written only after the callback succeeds.
|
|
46
|
+
*/
|
|
47
|
+
export declare class McpOAuthClientProvider implements OAuthClientProvider {
|
|
48
|
+
private readonly redirectUrlValue;
|
|
49
|
+
private readonly stateValue;
|
|
50
|
+
private readonly metadata;
|
|
51
|
+
private clientInfo?;
|
|
52
|
+
private savedTokens?;
|
|
53
|
+
private savedCodeVerifier?;
|
|
54
|
+
private savedDiscovery?;
|
|
55
|
+
private authorizationUrl?;
|
|
56
|
+
constructor(options: McpOAuthProviderOptions);
|
|
57
|
+
get redirectUrl(): string;
|
|
58
|
+
get clientMetadata(): OAuthClientMetadata;
|
|
59
|
+
state(): string;
|
|
60
|
+
clientInformation(): OAuthClientInformationMixed | undefined;
|
|
61
|
+
saveClientInformation(info: OAuthClientInformationMixed): void;
|
|
62
|
+
tokens(): OAuthTokens | undefined;
|
|
63
|
+
saveTokens(tokens: OAuthTokens): void;
|
|
64
|
+
redirectToAuthorization(authorizationUrl: URL): void;
|
|
65
|
+
saveCodeVerifier(codeVerifier: string): void;
|
|
66
|
+
codeVerifier(): string;
|
|
67
|
+
saveDiscoveryState(state: {
|
|
68
|
+
authorizationServerUrl: string;
|
|
69
|
+
authorizationServerMetadata?: AuthorizationServerMetadata;
|
|
70
|
+
resourceMetadata?: OAuthProtectedResourceMetadata;
|
|
71
|
+
resourceMetadataUrl?: string;
|
|
72
|
+
}): void;
|
|
73
|
+
discoveryState(): McpOAuthDiscoveryState | undefined;
|
|
74
|
+
get authorizationRedirect(): URL | undefined;
|
|
75
|
+
get savedCodeVerifierValue(): string | undefined;
|
|
76
|
+
get savedTokensValue(): OAuthTokens | undefined;
|
|
77
|
+
get savedClientInformation(): OAuthClientInformationMixed | undefined;
|
|
78
|
+
}
|
|
79
|
+
export declare function startMcpOAuthAuthorization(options: McpOAuthProviderOptions & {
|
|
80
|
+
scope?: string;
|
|
81
|
+
}): Promise<McpOAuthStartResult>;
|
|
82
|
+
export declare function finishMcpOAuthAuthorization(options: McpOAuthProviderOptions & {
|
|
83
|
+
authorizationCode: string;
|
|
84
|
+
}): Promise<McpOAuthCallbackResult>;
|
|
85
|
+
export declare function tokenExpiresAt(tokens: OAuthTokens): number | undefined;
|
|
86
|
+
export declare function saveMcpOAuthCredentials(options: {
|
|
87
|
+
key: string;
|
|
88
|
+
scope: "user" | "org";
|
|
89
|
+
scopeId: string;
|
|
90
|
+
credentials: McpOAuthCredentialBundle;
|
|
91
|
+
}): Promise<void>;
|
|
92
|
+
export declare function readMcpOAuthCredentials(options: {
|
|
93
|
+
key: string;
|
|
94
|
+
scope: "user" | "org";
|
|
95
|
+
scopeId: string;
|
|
96
|
+
}): Promise<McpOAuthCredentialBundle | null>;
|
|
97
|
+
export declare function deleteMcpOAuthCredentials(options: {
|
|
98
|
+
key: string;
|
|
99
|
+
scope: "user" | "org";
|
|
100
|
+
scopeId: string;
|
|
101
|
+
}): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* Resolve an access token for the MCP manager. Refreshing happens only when a
|
|
104
|
+
* token is near expiry, so ordinary manager reconfiguration does not perform
|
|
105
|
+
* a network request for every connector.
|
|
106
|
+
*/
|
|
107
|
+
export declare function getMcpOAuthAccessToken(options: {
|
|
108
|
+
key: string;
|
|
109
|
+
scope: "user" | "org";
|
|
110
|
+
scopeId: string;
|
|
111
|
+
serverUrl: string;
|
|
112
|
+
}): Promise<string | null>;
|
|
113
|
+
//# sourceMappingURL=oauth-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-client.d.ts","sourceRoot":"","sources":["../../src/mcp-client/oauth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.1 client support for remote MCP servers.
|
|
3
|
+
*
|
|
4
|
+
* MCP servers advertise their OAuth endpoints through the standard protected
|
|
5
|
+
* resource and authorization-server metadata documents. The SDK handles the
|
|
6
|
+
* protocol details; this module owns the framework-specific encrypted storage
|
|
7
|
+
* and refresh boundary.
|
|
8
|
+
*/
|
|
9
|
+
import { auth, refreshAuthorization, } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
10
|
+
import { deleteOAuthTokens, getOAuthTokens, saveOAuthTokens, } from "../oauth-tokens/store.js";
|
|
11
|
+
import { validateRemoteUrl } from "./remote-url.js";
|
|
12
|
+
const TOKEN_EXPIRY_SKEW_MS = 60_000;
|
|
13
|
+
const MAX_OAUTH_REDIRECTS = 5;
|
|
14
|
+
function checkedRemoteUrl(value, label) {
|
|
15
|
+
const result = validateRemoteUrl(String(value));
|
|
16
|
+
if (!result.ok || !result.url) {
|
|
17
|
+
throw new Error(`MCP OAuth ${label} is not allowed: ${result.error ?? "invalid URL"}`);
|
|
18
|
+
}
|
|
19
|
+
return result.url;
|
|
20
|
+
}
|
|
21
|
+
function guardedOAuthFetch() {
|
|
22
|
+
return async (url, init) => {
|
|
23
|
+
let currentUrl = checkedRemoteUrl(url, "request");
|
|
24
|
+
let currentInit = { ...init, redirect: "manual" };
|
|
25
|
+
for (let redirectCount = 0;; redirectCount += 1) {
|
|
26
|
+
const response = await fetch(currentUrl, currentInit);
|
|
27
|
+
if (![301, 302, 303, 307, 308].includes(response.status)) {
|
|
28
|
+
return response;
|
|
29
|
+
}
|
|
30
|
+
if (redirectCount >= MAX_OAUTH_REDIRECTS) {
|
|
31
|
+
throw new Error("MCP OAuth redirect limit exceeded.");
|
|
32
|
+
}
|
|
33
|
+
const location = response.headers.get("location");
|
|
34
|
+
if (!location)
|
|
35
|
+
throw new Error("MCP OAuth redirect is missing a target.");
|
|
36
|
+
let nextUrl;
|
|
37
|
+
try {
|
|
38
|
+
nextUrl = checkedRemoteUrl(new URL(location, currentUrl), "redirect target");
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw new Error("MCP OAuth redirect target is not allowed.");
|
|
42
|
+
}
|
|
43
|
+
await response.body?.cancel().catch(() => undefined);
|
|
44
|
+
const nextHeaders = new Headers(currentInit.headers);
|
|
45
|
+
if (nextUrl.origin !== currentUrl.origin) {
|
|
46
|
+
nextHeaders.delete("authorization");
|
|
47
|
+
nextHeaders.delete("cookie");
|
|
48
|
+
nextHeaders.delete("proxy-authorization");
|
|
49
|
+
}
|
|
50
|
+
const nextInit = {
|
|
51
|
+
...currentInit,
|
|
52
|
+
headers: nextHeaders,
|
|
53
|
+
};
|
|
54
|
+
if (response.status === 303 ||
|
|
55
|
+
((response.status === 301 || response.status === 302) &&
|
|
56
|
+
(currentInit.method ?? "GET").toUpperCase() === "POST")) {
|
|
57
|
+
nextInit.method = "GET";
|
|
58
|
+
delete nextInit.body;
|
|
59
|
+
nextHeaders.delete("content-length");
|
|
60
|
+
nextHeaders.delete("content-type");
|
|
61
|
+
}
|
|
62
|
+
currentUrl = nextUrl;
|
|
63
|
+
currentInit = nextInit;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function validateDiscoveryUrls(state) {
|
|
68
|
+
checkedRemoteUrl(state.authorizationServerUrl, "authorization server");
|
|
69
|
+
if (state.resourceMetadataUrl) {
|
|
70
|
+
checkedRemoteUrl(state.resourceMetadataUrl, "resource metadata");
|
|
71
|
+
}
|
|
72
|
+
for (const url of state.resourceMetadata?.authorization_servers ?? []) {
|
|
73
|
+
checkedRemoteUrl(url, "discovered authorization server");
|
|
74
|
+
}
|
|
75
|
+
for (const field of [
|
|
76
|
+
"authorization_endpoint",
|
|
77
|
+
"token_endpoint",
|
|
78
|
+
"registration_endpoint",
|
|
79
|
+
"introspection_endpoint",
|
|
80
|
+
"revocation_endpoint",
|
|
81
|
+
]) {
|
|
82
|
+
const url = state.authorizationServerMetadata?.[field];
|
|
83
|
+
if (typeof url === "string") {
|
|
84
|
+
checkedRemoteUrl(url, `OAuth ${field}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function credentialOwner(options) {
|
|
89
|
+
return `${options.scope}:${options.scopeId}`;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A small adapter around the MCP SDK's OAuth provider interface. The route
|
|
93
|
+
* stores the adapter's state in an encrypted, short-lived browser cookie; the
|
|
94
|
+
* durable credential bundle is written only after the callback succeeds.
|
|
95
|
+
*/
|
|
96
|
+
export class McpOAuthClientProvider {
|
|
97
|
+
redirectUrlValue;
|
|
98
|
+
stateValue;
|
|
99
|
+
metadata;
|
|
100
|
+
clientInfo;
|
|
101
|
+
savedTokens;
|
|
102
|
+
savedCodeVerifier;
|
|
103
|
+
savedDiscovery;
|
|
104
|
+
authorizationUrl;
|
|
105
|
+
constructor(options) {
|
|
106
|
+
this.redirectUrlValue = options.redirectUrl;
|
|
107
|
+
this.stateValue = options.state;
|
|
108
|
+
this.clientInfo = options.clientInformation;
|
|
109
|
+
this.savedCodeVerifier = options.codeVerifier;
|
|
110
|
+
this.savedDiscovery = options.discoveryState;
|
|
111
|
+
this.metadata = {
|
|
112
|
+
redirect_uris: [options.redirectUrl],
|
|
113
|
+
token_endpoint_auth_method: "none",
|
|
114
|
+
grant_types: ["authorization_code"],
|
|
115
|
+
response_types: ["code"],
|
|
116
|
+
client_name: "Agent Native MCP connector",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
get redirectUrl() {
|
|
120
|
+
return this.redirectUrlValue;
|
|
121
|
+
}
|
|
122
|
+
get clientMetadata() {
|
|
123
|
+
return this.metadata;
|
|
124
|
+
}
|
|
125
|
+
state() {
|
|
126
|
+
return this.stateValue;
|
|
127
|
+
}
|
|
128
|
+
clientInformation() {
|
|
129
|
+
return this.clientInfo;
|
|
130
|
+
}
|
|
131
|
+
saveClientInformation(info) {
|
|
132
|
+
this.clientInfo = info;
|
|
133
|
+
}
|
|
134
|
+
tokens() {
|
|
135
|
+
return this.savedTokens;
|
|
136
|
+
}
|
|
137
|
+
saveTokens(tokens) {
|
|
138
|
+
this.savedTokens = tokens;
|
|
139
|
+
}
|
|
140
|
+
redirectToAuthorization(authorizationUrl) {
|
|
141
|
+
this.authorizationUrl = checkedRemoteUrl(authorizationUrl, "authorization redirect");
|
|
142
|
+
}
|
|
143
|
+
saveCodeVerifier(codeVerifier) {
|
|
144
|
+
this.savedCodeVerifier = codeVerifier;
|
|
145
|
+
}
|
|
146
|
+
codeVerifier() {
|
|
147
|
+
if (!this.savedCodeVerifier) {
|
|
148
|
+
throw new Error("MCP OAuth code verifier is missing");
|
|
149
|
+
}
|
|
150
|
+
return this.savedCodeVerifier;
|
|
151
|
+
}
|
|
152
|
+
saveDiscoveryState(state) {
|
|
153
|
+
validateDiscoveryUrls(state);
|
|
154
|
+
this.savedDiscovery = state;
|
|
155
|
+
}
|
|
156
|
+
discoveryState() {
|
|
157
|
+
return this.savedDiscovery;
|
|
158
|
+
}
|
|
159
|
+
get authorizationRedirect() {
|
|
160
|
+
return this.authorizationUrl;
|
|
161
|
+
}
|
|
162
|
+
get savedCodeVerifierValue() {
|
|
163
|
+
return this.savedCodeVerifier;
|
|
164
|
+
}
|
|
165
|
+
get savedTokensValue() {
|
|
166
|
+
return this.savedTokens;
|
|
167
|
+
}
|
|
168
|
+
get savedClientInformation() {
|
|
169
|
+
return this.clientInfo;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
export async function startMcpOAuthAuthorization(options) {
|
|
173
|
+
checkedRemoteUrl(options.serverUrl, "server");
|
|
174
|
+
const provider = new McpOAuthClientProvider(options);
|
|
175
|
+
const result = await auth(provider, {
|
|
176
|
+
serverUrl: options.serverUrl,
|
|
177
|
+
scope: options.scope,
|
|
178
|
+
fetchFn: guardedOAuthFetch(),
|
|
179
|
+
});
|
|
180
|
+
if (result !== "REDIRECT" || !provider.authorizationRedirect) {
|
|
181
|
+
throw new Error("MCP server did not start an interactive OAuth flow");
|
|
182
|
+
}
|
|
183
|
+
const clientInformation = provider.savedClientInformation;
|
|
184
|
+
if (!clientInformation) {
|
|
185
|
+
throw new Error("MCP OAuth client registration did not complete");
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
authorizationUrl: provider.authorizationRedirect,
|
|
189
|
+
codeVerifier: provider.savedCodeVerifierValue ?? provider.codeVerifier(),
|
|
190
|
+
state: options.state,
|
|
191
|
+
clientInformation,
|
|
192
|
+
discoveryState: provider.discoveryState(),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
export async function finishMcpOAuthAuthorization(options) {
|
|
196
|
+
checkedRemoteUrl(options.serverUrl, "server");
|
|
197
|
+
const provider = new McpOAuthClientProvider(options);
|
|
198
|
+
const result = await auth(provider, {
|
|
199
|
+
serverUrl: options.serverUrl,
|
|
200
|
+
authorizationCode: options.authorizationCode,
|
|
201
|
+
fetchFn: guardedOAuthFetch(),
|
|
202
|
+
});
|
|
203
|
+
if (result !== "AUTHORIZED" || !provider.savedTokensValue) {
|
|
204
|
+
throw new Error("MCP OAuth token exchange did not complete");
|
|
205
|
+
}
|
|
206
|
+
const tokens = provider.savedTokensValue;
|
|
207
|
+
return {
|
|
208
|
+
credentials: {
|
|
209
|
+
serverUrl: options.serverUrl,
|
|
210
|
+
clientInformation: provider.savedClientInformation,
|
|
211
|
+
discoveryState: provider.discoveryState(),
|
|
212
|
+
tokens,
|
|
213
|
+
tokenExpiresAt: tokenExpiresAt(tokens),
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
export function tokenExpiresAt(tokens) {
|
|
218
|
+
const expiresIn = Number(tokens.expires_in);
|
|
219
|
+
if (!Number.isFinite(expiresIn) || expiresIn <= 0)
|
|
220
|
+
return undefined;
|
|
221
|
+
return Date.now() + expiresIn * 1_000;
|
|
222
|
+
}
|
|
223
|
+
export async function saveMcpOAuthCredentials(options) {
|
|
224
|
+
checkedRemoteUrl(options.credentials.serverUrl, "server");
|
|
225
|
+
if (options.credentials.discoveryState) {
|
|
226
|
+
validateDiscoveryUrls(options.credentials.discoveryState);
|
|
227
|
+
}
|
|
228
|
+
await saveOAuthTokens("mcp", options.key, options.credentials, `${options.scope}:${options.scopeId}`);
|
|
229
|
+
}
|
|
230
|
+
export async function readMcpOAuthCredentials(options) {
|
|
231
|
+
const stored = await getOAuthTokens("mcp", options.key, credentialOwner(options));
|
|
232
|
+
if (!stored)
|
|
233
|
+
return null;
|
|
234
|
+
const parsed = stored;
|
|
235
|
+
if (typeof parsed.serverUrl !== "string" ||
|
|
236
|
+
!parsed.clientInformation ||
|
|
237
|
+
!parsed.tokens ||
|
|
238
|
+
typeof parsed.tokens.access_token !== "string") {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
if (!validateRemoteUrl(parsed.serverUrl).ok)
|
|
242
|
+
return null;
|
|
243
|
+
if (parsed.discoveryState) {
|
|
244
|
+
try {
|
|
245
|
+
validateDiscoveryUrls(parsed.discoveryState);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return parsed;
|
|
252
|
+
}
|
|
253
|
+
export async function deleteMcpOAuthCredentials(options) {
|
|
254
|
+
return ((await deleteOAuthTokens("mcp", options.key, credentialOwner(options))) > 0);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Resolve an access token for the MCP manager. Refreshing happens only when a
|
|
258
|
+
* token is near expiry, so ordinary manager reconfiguration does not perform
|
|
259
|
+
* a network request for every connector.
|
|
260
|
+
*/
|
|
261
|
+
export async function getMcpOAuthAccessToken(options) {
|
|
262
|
+
if (!validateRemoteUrl(options.serverUrl).ok)
|
|
263
|
+
return null;
|
|
264
|
+
const credentials = await readMcpOAuthCredentials(options);
|
|
265
|
+
if (!credentials || credentials.serverUrl !== options.serverUrl)
|
|
266
|
+
return null;
|
|
267
|
+
const accessToken = credentials.tokens.access_token;
|
|
268
|
+
if (typeof credentials.tokenExpiresAt !== "number" ||
|
|
269
|
+
credentials.tokenExpiresAt - Date.now() > TOKEN_EXPIRY_SKEW_MS) {
|
|
270
|
+
return accessToken;
|
|
271
|
+
}
|
|
272
|
+
const refreshToken = credentials.tokens.refresh_token;
|
|
273
|
+
const discovery = credentials.discoveryState;
|
|
274
|
+
if (!refreshToken || !discovery?.authorizationServerUrl) {
|
|
275
|
+
return accessToken;
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
const resource = discovery.resourceMetadata?.resource
|
|
279
|
+
? checkedRemoteUrl(discovery.resourceMetadata.resource, "resource")
|
|
280
|
+
: undefined;
|
|
281
|
+
const authorizationServerUrl = checkedRemoteUrl(discovery.authorizationServerUrl, "authorization server");
|
|
282
|
+
const refreshed = await refreshAuthorization(authorizationServerUrl, {
|
|
283
|
+
metadata: discovery.authorizationServerMetadata,
|
|
284
|
+
clientInformation: credentials.clientInformation,
|
|
285
|
+
refreshToken,
|
|
286
|
+
resource,
|
|
287
|
+
fetchFn: guardedOAuthFetch(),
|
|
288
|
+
});
|
|
289
|
+
const nextTokens = {
|
|
290
|
+
...credentials.tokens,
|
|
291
|
+
...refreshed,
|
|
292
|
+
...(refreshed.refresh_token
|
|
293
|
+
? { refresh_token: refreshed.refresh_token }
|
|
294
|
+
: credentials.tokens.refresh_token
|
|
295
|
+
? { refresh_token: credentials.tokens.refresh_token }
|
|
296
|
+
: {}),
|
|
297
|
+
};
|
|
298
|
+
const next = {
|
|
299
|
+
...credentials,
|
|
300
|
+
tokens: nextTokens,
|
|
301
|
+
tokenExpiresAt: tokenExpiresAt(nextTokens),
|
|
302
|
+
};
|
|
303
|
+
await saveMcpOAuthCredentials({
|
|
304
|
+
...options,
|
|
305
|
+
credentials: next,
|
|
306
|
+
});
|
|
307
|
+
return nextTokens.access_token;
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
// Keep the old token so the MCP request can return the provider's normal
|
|
311
|
+
// auth error. A single expired connector must not remove every server from
|
|
312
|
+
// the process-wide manager during a config refresh.
|
|
313
|
+
return accessToken;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=oauth-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-client.js","sourceRoot":"","sources":["../../src/mcp-client/oauth-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,IAAI,EACJ,oBAAoB,GAErB,MAAM,0CAA0C,CAAC;AASlD,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAO9B,SAAS,gBAAgB,CAAC,KAAmB,EAAE,KAAa;IAC1D,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,aAAa,KAAK,oBAAoB,MAAM,CAAC,KAAK,IAAI,aAAa,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC;AACpB,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,IAAI,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAClD,IAAI,WAAW,GAAgB,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAE/D,KAAK,IAAI,aAAa,GAAG,CAAC,GAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YACtD,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzD,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,IAAI,aAAa,IAAI,mBAAmB,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,CAAC;YACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAE1E,IAAI,OAAY,CAAC;YACjB,IAAI,CAAC;gBACH,OAAO,GAAG,gBAAgB,CACxB,IAAI,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,EAC7B,iBAAiB,CAClB,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAErD,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACrD,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;gBACzC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;gBACpC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC7B,WAAW,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,QAAQ,GAAgB;gBAC5B,GAAG,WAAW;gBACd,OAAO,EAAE,WAAW;aACrB,CAAC;YACF,IACE,QAAQ,CAAC,MAAM,KAAK,GAAG;gBACvB,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;oBACnD,CAAC,WAAW,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,EACzD,CAAC;gBACD,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC;gBACxB,OAAO,QAAQ,CAAC,IAAI,CAAC;gBACrB,WAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBACrC,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACrC,CAAC;YACD,UAAU,GAAG,OAAO,CAAC;YACrB,WAAW,GAAG,QAAQ,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,KAK9B;IACC,gBAAgB,CAAC,KAAK,CAAC,sBAAsB,EAAE,sBAAsB,CAAC,CAAC;IACvE,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;QAC9B,gBAAgB,CAAC,KAAK,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;IACnE,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,gBAAgB,EAAE,qBAAqB,IAAI,EAAE,EAAE,CAAC;QACtE,gBAAgB,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;IAC3D,CAAC;IACD,KAAK,MAAM,KAAK,IAAI;QAClB,wBAAwB;QACxB,gBAAgB;QAChB,uBAAuB;QACvB,wBAAwB;QACxB,qBAAqB;KACb,EAAE,CAAC;QACX,MAAM,GAAG,GACP,KAAK,CAAC,2BACP,EAAE,CAAC,KAAK,CAAC,CAAC;QACX,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,gBAAgB,CAAC,GAAG,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,OAAmD;IAC1E,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;AAC/C,CAAC;AAsCD;;;;GAIG;AACH,MAAM,OAAO,sBAAsB;IAChB,gBAAgB,CAAS;IACzB,UAAU,CAAS;IACnB,QAAQ,CAAsB;IACvC,UAAU,CAA+B;IACzC,WAAW,CAAe;IAC1B,iBAAiB,CAAU;IAC3B,cAAc,CAA0B;IACxC,gBAAgB,CAAO;IAE/B,YAAY,OAAgC;QAC1C,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;QAC5C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC;QAC5C,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;QAC9C,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,QAAQ,GAAG;YACd,aAAa,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;YACpC,0BAA0B,EAAE,MAAM;YAClC,WAAW,EAAE,CAAC,oBAAoB,CAAC;YACnC,cAAc,EAAE,CAAC,MAAM,CAAC;YACxB,WAAW,EAAE,4BAA4B;SAC1C,CAAC;IACJ,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,qBAAqB,CAAC,IAAiC;QACrD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,UAAU,CAAC,MAAmB;QAC5B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;IAC5B,CAAC;IAED,uBAAuB,CAAC,gBAAqB;QAC3C,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CACtC,gBAAgB,EAChB,wBAAwB,CACzB,CAAC;IACJ,CAAC;IAED,gBAAgB,CAAC,YAAoB;QACnC,IAAI,CAAC,iBAAiB,GAAG,YAAY,CAAC;IACxC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAED,kBAAkB,CAAC,KAKlB;QACC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,IAAI,qBAAqB;QACvB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAED,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAAqD;IAErD,gBAAgB,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,iBAAiB,EAAE;KAC7B,CAAC,CAAC;IACH,IAAI,MAAM,KAAK,UAAU,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,sBAAsB,CAAC;IAC1D,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IACD,OAAO;QACL,gBAAgB,EAAE,QAAQ,CAAC,qBAAqB;QAChD,YAAY,EAAE,QAAQ,CAAC,sBAAsB,IAAI,QAAQ,CAAC,YAAY,EAAE;QACxE,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,iBAAiB;QACjB,cAAc,EAAE,QAAQ,CAAC,cAAc,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAgE;IAEhE,gBAAgB,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,OAAO,EAAE,iBAAiB,EAAE;KAC7B,CAAC,CAAC;IACH,IAAI,MAAM,KAAK,YAAY,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,CAAC;IACzC,OAAO;QACL,WAAW,EAAE;YACX,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,iBAAiB,EAAE,QAAQ,CAAC,sBAAuB;YACnD,cAAc,EAAE,QAAQ,CAAC,cAAc,EAAE;YACzC,MAAM;YACN,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC;SACvC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAmB;IAChD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACpE,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAK7C;IACC,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC;QACvC,qBAAqB,CAAC,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,eAAe,CACnB,KAAK,EACL,OAAO,CAAC,GAAG,EACX,OAAO,CAAC,WAAiD,EACzD,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CACtC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAI7C;IACC,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,KAAK,EACL,OAAO,CAAC,GAAG,EACX,eAAe,CAAC,OAAO,CAAC,CACzB,CAAC;IACF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,MAAM,GAAG,MAA2C,CAAC;IAC3D,IACE,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QACpC,CAAC,MAAM,CAAC,iBAAiB;QACzB,CAAC,MAAM,CAAC,MAAM;QACd,OAAO,MAAM,CAAC,MAAM,CAAC,YAAY,KAAK,QAAQ,EAC9C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,qBAAqB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,MAAkC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAI/C;IACC,OAAO,CACL,CAAC,MAAM,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAK5C;IACC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,WAAW,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAE7E,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC;IACpD,IACE,OAAO,WAAW,CAAC,cAAc,KAAK,QAAQ;QAC9C,WAAW,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,EAC9D,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC;IACtD,MAAM,SAAS,GAAG,WAAW,CAAC,cAAc,CAAC;IAC7C,IAAI,CAAC,YAAY,IAAI,CAAC,SAAS,EAAE,sBAAsB,EAAE,CAAC;QACxD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,EAAE,QAAQ;YACnD,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC;YACnE,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,sBAAsB,GAAG,gBAAgB,CAC7C,SAAS,CAAC,sBAAsB,EAChC,sBAAsB,CACvB,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,sBAAsB,EAAE;YACnE,QAAQ,EAAE,SAAS,CAAC,2BAA2B;YAC/C,iBAAiB,EAAE,WAAW,CAAC,iBAAiB;YAChD,YAAY;YACZ,QAAQ;YACR,OAAO,EAAE,iBAAiB,EAAE;SAC7B,CAAC,CAAC;QACH,MAAM,UAAU,GAAgB;YAC9B,GAAG,WAAW,CAAC,MAAM;YACrB,GAAG,SAAS;YACZ,GAAG,CAAC,SAAS,CAAC,aAAa;gBACzB,CAAC,CAAC,EAAE,aAAa,EAAE,SAAS,CAAC,aAAa,EAAE;gBAC5C,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa;oBAChC,CAAC,CAAC,EAAE,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE;oBACrD,CAAC,CAAC,EAAE,CAAC;SACV,CAAC;QACF,MAAM,IAAI,GAA6B;YACrC,GAAG,WAAW;YACd,MAAM,EAAE,UAAU;YAClB,cAAc,EAAE,cAAc,CAAC,UAAU,CAAC;SAC3C,CAAC;QACF,MAAM,uBAAuB,CAAC;YAC5B,GAAG,OAAO;YACV,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,YAAY,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,2EAA2E;QAC3E,oDAAoD;QACpD,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC","sourcesContent":["/**\n * OAuth 2.1 client support for remote MCP servers.\n *\n * MCP servers advertise their OAuth endpoints through the standard protected\n * resource and authorization-server metadata documents. The SDK handles the\n * protocol details; this module owns the framework-specific encrypted storage\n * and refresh boundary.\n */\n\nimport {\n auth,\n refreshAuthorization,\n type OAuthClientProvider,\n} from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type {\n AuthorizationServerMetadata,\n OAuthClientInformationMixed,\n OAuthClientMetadata,\n OAuthProtectedResourceMetadata,\n OAuthTokens,\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\n\nimport {\n deleteOAuthTokens,\n getOAuthTokens,\n saveOAuthTokens,\n} from \"../oauth-tokens/store.js\";\nimport { validateRemoteUrl } from \"./remote-url.js\";\n\nconst TOKEN_EXPIRY_SKEW_MS = 60_000;\nconst MAX_OAUTH_REDIRECTS = 5;\n\ntype GuardedFetch = (\n url: string | URL,\n init?: RequestInit,\n) => Promise<Response>;\n\nfunction checkedRemoteUrl(value: string | URL, label: string): URL {\n const result = validateRemoteUrl(String(value));\n if (!result.ok || !result.url) {\n throw new Error(\n `MCP OAuth ${label} is not allowed: ${result.error ?? \"invalid URL\"}`,\n );\n }\n return result.url;\n}\n\nfunction guardedOAuthFetch(): GuardedFetch {\n return async (url, init) => {\n let currentUrl = checkedRemoteUrl(url, \"request\");\n let currentInit: RequestInit = { ...init, redirect: \"manual\" };\n\n for (let redirectCount = 0; ; redirectCount += 1) {\n const response = await fetch(currentUrl, currentInit);\n if (![301, 302, 303, 307, 308].includes(response.status)) {\n return response;\n }\n if (redirectCount >= MAX_OAUTH_REDIRECTS) {\n throw new Error(\"MCP OAuth redirect limit exceeded.\");\n }\n const location = response.headers.get(\"location\");\n if (!location) throw new Error(\"MCP OAuth redirect is missing a target.\");\n\n let nextUrl: URL;\n try {\n nextUrl = checkedRemoteUrl(\n new URL(location, currentUrl),\n \"redirect target\",\n );\n } catch {\n throw new Error(\"MCP OAuth redirect target is not allowed.\");\n }\n await response.body?.cancel().catch(() => undefined);\n\n const nextHeaders = new Headers(currentInit.headers);\n if (nextUrl.origin !== currentUrl.origin) {\n nextHeaders.delete(\"authorization\");\n nextHeaders.delete(\"cookie\");\n nextHeaders.delete(\"proxy-authorization\");\n }\n const nextInit: RequestInit = {\n ...currentInit,\n headers: nextHeaders,\n };\n if (\n response.status === 303 ||\n ((response.status === 301 || response.status === 302) &&\n (currentInit.method ?? \"GET\").toUpperCase() === \"POST\")\n ) {\n nextInit.method = \"GET\";\n delete nextInit.body;\n nextHeaders.delete(\"content-length\");\n nextHeaders.delete(\"content-type\");\n }\n currentUrl = nextUrl;\n currentInit = nextInit;\n }\n };\n}\n\nfunction validateDiscoveryUrls(state: {\n authorizationServerUrl: string;\n authorizationServerMetadata?: AuthorizationServerMetadata;\n resourceMetadata?: OAuthProtectedResourceMetadata;\n resourceMetadataUrl?: string;\n}): void {\n checkedRemoteUrl(state.authorizationServerUrl, \"authorization server\");\n if (state.resourceMetadataUrl) {\n checkedRemoteUrl(state.resourceMetadataUrl, \"resource metadata\");\n }\n for (const url of state.resourceMetadata?.authorization_servers ?? []) {\n checkedRemoteUrl(url, \"discovered authorization server\");\n }\n for (const field of [\n \"authorization_endpoint\",\n \"token_endpoint\",\n \"registration_endpoint\",\n \"introspection_endpoint\",\n \"revocation_endpoint\",\n ] as const) {\n const url = (\n state.authorizationServerMetadata as Record<string, unknown> | undefined\n )?.[field];\n if (typeof url === \"string\") {\n checkedRemoteUrl(url, `OAuth ${field}`);\n }\n }\n}\n\nfunction credentialOwner(options: { scope: \"user\" | \"org\"; scopeId: string }) {\n return `${options.scope}:${options.scopeId}`;\n}\n\nexport interface McpOAuthDiscoveryState {\n authorizationServerUrl: string;\n authorizationServerMetadata?: AuthorizationServerMetadata;\n resourceMetadata?: OAuthProtectedResourceMetadata;\n resourceMetadataUrl?: string;\n}\n\nexport interface McpOAuthCredentialBundle {\n serverUrl: string;\n clientInformation: OAuthClientInformationMixed;\n discoveryState?: McpOAuthDiscoveryState;\n tokens: OAuthTokens;\n tokenExpiresAt?: number;\n}\n\nexport interface McpOAuthStartResult {\n authorizationUrl: URL;\n codeVerifier: string;\n state: string;\n clientInformation: OAuthClientInformationMixed;\n discoveryState?: McpOAuthDiscoveryState;\n}\n\nexport interface McpOAuthCallbackResult {\n credentials: McpOAuthCredentialBundle;\n}\n\nexport interface McpOAuthProviderOptions {\n serverUrl: string;\n redirectUrl: string;\n state: string;\n clientInformation?: OAuthClientInformationMixed;\n codeVerifier?: string;\n discoveryState?: McpOAuthDiscoveryState;\n}\n\n/**\n * A small adapter around the MCP SDK's OAuth provider interface. The route\n * stores the adapter's state in an encrypted, short-lived browser cookie; the\n * durable credential bundle is written only after the callback succeeds.\n */\nexport class McpOAuthClientProvider implements OAuthClientProvider {\n private readonly redirectUrlValue: string;\n private readonly stateValue: string;\n private readonly metadata: OAuthClientMetadata;\n private clientInfo?: OAuthClientInformationMixed;\n private savedTokens?: OAuthTokens;\n private savedCodeVerifier?: string;\n private savedDiscovery?: McpOAuthDiscoveryState;\n private authorizationUrl?: URL;\n\n constructor(options: McpOAuthProviderOptions) {\n this.redirectUrlValue = options.redirectUrl;\n this.stateValue = options.state;\n this.clientInfo = options.clientInformation;\n this.savedCodeVerifier = options.codeVerifier;\n this.savedDiscovery = options.discoveryState;\n this.metadata = {\n redirect_uris: [options.redirectUrl],\n token_endpoint_auth_method: \"none\",\n grant_types: [\"authorization_code\"],\n response_types: [\"code\"],\n client_name: \"Agent Native MCP connector\",\n };\n }\n\n get redirectUrl(): string {\n return this.redirectUrlValue;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return this.metadata;\n }\n\n state(): string {\n return this.stateValue;\n }\n\n clientInformation(): OAuthClientInformationMixed | undefined {\n return this.clientInfo;\n }\n\n saveClientInformation(info: OAuthClientInformationMixed): void {\n this.clientInfo = info;\n }\n\n tokens(): OAuthTokens | undefined {\n return this.savedTokens;\n }\n\n saveTokens(tokens: OAuthTokens): void {\n this.savedTokens = tokens;\n }\n\n redirectToAuthorization(authorizationUrl: URL): void {\n this.authorizationUrl = checkedRemoteUrl(\n authorizationUrl,\n \"authorization redirect\",\n );\n }\n\n saveCodeVerifier(codeVerifier: string): void {\n this.savedCodeVerifier = codeVerifier;\n }\n\n codeVerifier(): string {\n if (!this.savedCodeVerifier) {\n throw new Error(\"MCP OAuth code verifier is missing\");\n }\n return this.savedCodeVerifier;\n }\n\n saveDiscoveryState(state: {\n authorizationServerUrl: string;\n authorizationServerMetadata?: AuthorizationServerMetadata;\n resourceMetadata?: OAuthProtectedResourceMetadata;\n resourceMetadataUrl?: string;\n }): void {\n validateDiscoveryUrls(state);\n this.savedDiscovery = state;\n }\n\n discoveryState(): McpOAuthDiscoveryState | undefined {\n return this.savedDiscovery;\n }\n\n get authorizationRedirect(): URL | undefined {\n return this.authorizationUrl;\n }\n\n get savedCodeVerifierValue(): string | undefined {\n return this.savedCodeVerifier;\n }\n\n get savedTokensValue(): OAuthTokens | undefined {\n return this.savedTokens;\n }\n\n get savedClientInformation(): OAuthClientInformationMixed | undefined {\n return this.clientInfo;\n }\n}\n\nexport async function startMcpOAuthAuthorization(\n options: McpOAuthProviderOptions & { scope?: string },\n): Promise<McpOAuthStartResult> {\n checkedRemoteUrl(options.serverUrl, \"server\");\n const provider = new McpOAuthClientProvider(options);\n const result = await auth(provider, {\n serverUrl: options.serverUrl,\n scope: options.scope,\n fetchFn: guardedOAuthFetch(),\n });\n if (result !== \"REDIRECT\" || !provider.authorizationRedirect) {\n throw new Error(\"MCP server did not start an interactive OAuth flow\");\n }\n const clientInformation = provider.savedClientInformation;\n if (!clientInformation) {\n throw new Error(\"MCP OAuth client registration did not complete\");\n }\n return {\n authorizationUrl: provider.authorizationRedirect,\n codeVerifier: provider.savedCodeVerifierValue ?? provider.codeVerifier(),\n state: options.state,\n clientInformation,\n discoveryState: provider.discoveryState(),\n };\n}\n\nexport async function finishMcpOAuthAuthorization(\n options: McpOAuthProviderOptions & { authorizationCode: string },\n): Promise<McpOAuthCallbackResult> {\n checkedRemoteUrl(options.serverUrl, \"server\");\n const provider = new McpOAuthClientProvider(options);\n const result = await auth(provider, {\n serverUrl: options.serverUrl,\n authorizationCode: options.authorizationCode,\n fetchFn: guardedOAuthFetch(),\n });\n if (result !== \"AUTHORIZED\" || !provider.savedTokensValue) {\n throw new Error(\"MCP OAuth token exchange did not complete\");\n }\n const tokens = provider.savedTokensValue;\n return {\n credentials: {\n serverUrl: options.serverUrl,\n clientInformation: provider.savedClientInformation!,\n discoveryState: provider.discoveryState(),\n tokens,\n tokenExpiresAt: tokenExpiresAt(tokens),\n },\n };\n}\n\nexport function tokenExpiresAt(tokens: OAuthTokens): number | undefined {\n const expiresIn = Number(tokens.expires_in);\n if (!Number.isFinite(expiresIn) || expiresIn <= 0) return undefined;\n return Date.now() + expiresIn * 1_000;\n}\n\nexport async function saveMcpOAuthCredentials(options: {\n key: string;\n scope: \"user\" | \"org\";\n scopeId: string;\n credentials: McpOAuthCredentialBundle;\n}): Promise<void> {\n checkedRemoteUrl(options.credentials.serverUrl, \"server\");\n if (options.credentials.discoveryState) {\n validateDiscoveryUrls(options.credentials.discoveryState);\n }\n await saveOAuthTokens(\n \"mcp\",\n options.key,\n options.credentials as unknown as Record<string, unknown>,\n `${options.scope}:${options.scopeId}`,\n );\n}\n\nexport async function readMcpOAuthCredentials(options: {\n key: string;\n scope: \"user\" | \"org\";\n scopeId: string;\n}): Promise<McpOAuthCredentialBundle | null> {\n const stored = await getOAuthTokens(\n \"mcp\",\n options.key,\n credentialOwner(options),\n );\n if (!stored) return null;\n const parsed = stored as Partial<McpOAuthCredentialBundle>;\n if (\n typeof parsed.serverUrl !== \"string\" ||\n !parsed.clientInformation ||\n !parsed.tokens ||\n typeof parsed.tokens.access_token !== \"string\"\n ) {\n return null;\n }\n if (!validateRemoteUrl(parsed.serverUrl).ok) return null;\n if (parsed.discoveryState) {\n try {\n validateDiscoveryUrls(parsed.discoveryState);\n } catch {\n return null;\n }\n }\n return parsed as McpOAuthCredentialBundle;\n}\n\nexport async function deleteMcpOAuthCredentials(options: {\n key: string;\n scope: \"user\" | \"org\";\n scopeId: string;\n}): Promise<boolean> {\n return (\n (await deleteOAuthTokens(\"mcp\", options.key, credentialOwner(options))) > 0\n );\n}\n\n/**\n * Resolve an access token for the MCP manager. Refreshing happens only when a\n * token is near expiry, so ordinary manager reconfiguration does not perform\n * a network request for every connector.\n */\nexport async function getMcpOAuthAccessToken(options: {\n key: string;\n scope: \"user\" | \"org\";\n scopeId: string;\n serverUrl: string;\n}): Promise<string | null> {\n if (!validateRemoteUrl(options.serverUrl).ok) return null;\n const credentials = await readMcpOAuthCredentials(options);\n if (!credentials || credentials.serverUrl !== options.serverUrl) return null;\n\n const accessToken = credentials.tokens.access_token;\n if (\n typeof credentials.tokenExpiresAt !== \"number\" ||\n credentials.tokenExpiresAt - Date.now() > TOKEN_EXPIRY_SKEW_MS\n ) {\n return accessToken;\n }\n\n const refreshToken = credentials.tokens.refresh_token;\n const discovery = credentials.discoveryState;\n if (!refreshToken || !discovery?.authorizationServerUrl) {\n return accessToken;\n }\n\n try {\n const resource = discovery.resourceMetadata?.resource\n ? checkedRemoteUrl(discovery.resourceMetadata.resource, \"resource\")\n : undefined;\n const authorizationServerUrl = checkedRemoteUrl(\n discovery.authorizationServerUrl,\n \"authorization server\",\n );\n const refreshed = await refreshAuthorization(authorizationServerUrl, {\n metadata: discovery.authorizationServerMetadata,\n clientInformation: credentials.clientInformation,\n refreshToken,\n resource,\n fetchFn: guardedOAuthFetch(),\n });\n const nextTokens: OAuthTokens = {\n ...credentials.tokens,\n ...refreshed,\n ...(refreshed.refresh_token\n ? { refresh_token: refreshed.refresh_token }\n : credentials.tokens.refresh_token\n ? { refresh_token: credentials.tokens.refresh_token }\n : {}),\n };\n const next: McpOAuthCredentialBundle = {\n ...credentials,\n tokens: nextTokens,\n tokenExpiresAt: tokenExpiresAt(nextTokens),\n };\n await saveMcpOAuthCredentials({\n ...options,\n credentials: next,\n });\n return nextTokens.access_token;\n } catch {\n // Keep the old token so the MCP request can return the provider's normal\n // auth error. A single expired connector must not remove every server from\n // the process-wide manager during a config refresh.\n return accessToken;\n }\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OAuthClientInformationMixed } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
2
|
+
import { type McpOAuthDiscoveryState } from "./oauth-client.js";
|
|
3
|
+
import { type RemoteMcpScope } from "./remote-store.js";
|
|
4
|
+
export interface McpOAuthFlow {
|
|
5
|
+
name: string;
|
|
6
|
+
url: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
scope: RemoteMcpScope;
|
|
9
|
+
scopeId: string;
|
|
10
|
+
owner: string;
|
|
11
|
+
orgId?: string;
|
|
12
|
+
redirectUri: string;
|
|
13
|
+
state: string;
|
|
14
|
+
codeVerifier: string;
|
|
15
|
+
clientInformation: OAuthClientInformationMixed;
|
|
16
|
+
discoveryState?: McpOAuthDiscoveryState;
|
|
17
|
+
returnUrl?: string;
|
|
18
|
+
expiresAt: number;
|
|
19
|
+
}
|
|
20
|
+
export interface McpOAuthRoutesOptions {
|
|
21
|
+
reconfigure: () => Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare function mountMcpOAuthRoutes(nitroApp: any, options: McpOAuthRoutesOptions): void;
|
|
24
|
+
export declare function isValidMcpOAuthFlow(flow: McpOAuthFlow, email: string, orgId: string | undefined, state: string): boolean;
|
|
25
|
+
//# sourceMappingURL=oauth-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-routes.d.ts","sourceRoot":"","sources":["../../src/mcp-client/oauth-routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0CAA0C,CAAC;AAkB5F,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAK3B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,2BAA2B,CAAC;IAC/C,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE,qBAAqB,GAC7B,IAAI,CA6BN;AA0LD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,GACZ,OAAO,CAcT"}
|