@mcp-z/client 2.0.0 → 2.1.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.
Files changed (62) hide show
  1. package/dist/cjs/auth/capability-discovery.js +11 -5
  2. package/dist/cjs/auth/capability-discovery.js.map +1 -1
  3. package/dist/cjs/auth/types.d.cts +11 -0
  4. package/dist/cjs/auth/types.d.ts +11 -0
  5. package/dist/cjs/auth/types.js.map +1 -1
  6. package/dist/cjs/client-helpers.d.cts +5 -6
  7. package/dist/cjs/client-helpers.d.ts +5 -6
  8. package/dist/cjs/client-helpers.js +8 -8
  9. package/dist/cjs/client-helpers.js.map +1 -1
  10. package/dist/cjs/connection/connect-client.d.cts +1 -11
  11. package/dist/cjs/connection/connect-client.d.ts +1 -11
  12. package/dist/cjs/connection/connect-client.js +20 -41
  13. package/dist/cjs/connection/connect-client.js.map +1 -1
  14. package/dist/cjs/connection/existing-process-transport.d.cts +1 -2
  15. package/dist/cjs/connection/existing-process-transport.d.ts +1 -2
  16. package/dist/cjs/connection/existing-process-transport.js +3 -3
  17. package/dist/cjs/connection/existing-process-transport.js.map +1 -1
  18. package/dist/cjs/dcr/dcr-authenticator.d.cts +30 -4
  19. package/dist/cjs/dcr/dcr-authenticator.d.ts +30 -4
  20. package/dist/cjs/dcr/dcr-authenticator.js +57 -24
  21. package/dist/cjs/dcr/dcr-authenticator.js.map +1 -1
  22. package/dist/cjs/lib/url-utils.d.cts +17 -0
  23. package/dist/cjs/lib/url-utils.d.ts +17 -0
  24. package/dist/cjs/lib/url-utils.js +20 -0
  25. package/dist/cjs/lib/url-utils.js.map +1 -1
  26. package/dist/cjs/response-wrappers.d.cts +1 -1
  27. package/dist/cjs/response-wrappers.d.ts +1 -1
  28. package/dist/cjs/response-wrappers.js.map +1 -1
  29. package/dist/cjs/search/search.d.cts +1 -1
  30. package/dist/cjs/search/search.d.ts +1 -1
  31. package/dist/cjs/search/search.js.map +1 -1
  32. package/dist/esm/auth/capability-discovery.js +11 -5
  33. package/dist/esm/auth/capability-discovery.js.map +1 -1
  34. package/dist/esm/auth/types.d.ts +11 -0
  35. package/dist/esm/auth/types.js.map +1 -1
  36. package/dist/esm/client-helpers.d.ts +5 -6
  37. package/dist/esm/client-helpers.js +8 -8
  38. package/dist/esm/client-helpers.js.map +1 -1
  39. package/dist/esm/connection/connect-client.d.ts +1 -11
  40. package/dist/esm/connection/connect-client.js +12 -32
  41. package/dist/esm/connection/connect-client.js.map +1 -1
  42. package/dist/esm/connection/existing-process-transport.d.ts +1 -2
  43. package/dist/esm/connection/existing-process-transport.js +1 -1
  44. package/dist/esm/connection/existing-process-transport.js.map +1 -1
  45. package/dist/esm/dcr/dcr-authenticator.d.ts +30 -4
  46. package/dist/esm/dcr/dcr-authenticator.js +56 -23
  47. package/dist/esm/dcr/dcr-authenticator.js.map +1 -1
  48. package/dist/esm/lib/url-utils.d.ts +17 -0
  49. package/dist/esm/lib/url-utils.js +32 -0
  50. package/dist/esm/lib/url-utils.js.map +1 -1
  51. package/dist/esm/response-wrappers.d.ts +1 -1
  52. package/dist/esm/response-wrappers.js.map +1 -1
  53. package/dist/esm/search/search.d.ts +1 -1
  54. package/dist/esm/search/search.js.map +1 -1
  55. package/package.json +3 -3
  56. package/dist/cjs/monkey-patches.d.cts +0 -6
  57. package/dist/cjs/monkey-patches.d.ts +0 -6
  58. package/dist/cjs/monkey-patches.js +0 -233
  59. package/dist/cjs/monkey-patches.js.map +0 -1
  60. package/dist/esm/monkey-patches.d.ts +0 -6
  61. package/dist/esm/monkey-patches.js +0 -32
  62. package/dist/esm/monkey-patches.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/connection/connect-client.ts"],"sourcesContent":["/**\n * connect-mcp-client.ts\n *\n * Helper to connect MCP SDK clients to servers with intelligent transport inference.\n * Automatically detects transport type from URL protocol or type field.\n */\n\nimport '../monkey-patches.ts';\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport getPort from 'get-port';\nimport { probeAuthCapabilities } from '../auth/index.ts';\nimport { DCR_CAPABILTY_DISCOVERY_TIMEOUT } from '../constants.ts';\nimport { DcrAuthenticator, type DcrAuthenticatorOptions } from '../dcr/index.ts';\nimport type { ServerProcess } from '../spawn/spawn-server.ts';\nimport type { ServersConfig } from '../spawn/spawn-servers.ts';\n\n/**\n * Minimal interface for connecting to servers.\n * Only needs config and servers map for connection logic.\n */\ninterface RegistryLike {\n config: ServersConfig;\n servers: Map<string, ServerProcess>;\n}\n\nimport type { McpServerEntry, TransportType } from '../types.ts';\nimport { logger as defaultLogger, type Logger } from '../utils/logger.ts';\nimport { ExistingProcessTransport } from './existing-process-transport.ts';\nimport { waitForHttpReady } from './wait-for-http-ready.ts';\n\n/**\n * Wrap promise with timeout - throws if promise takes too long\n * Clears timeout when promise completes to prevent hanging event loop\n * @param promise - Promise to wrap\n * @param ms - Timeout in milliseconds\n * @param operation - Description of operation for error message\n * @returns Promise result or timeout error\n */\nasync function withTimeout<T>(promise: Promise<T>, ms: number, operation: string): Promise<T> {\n let timeoutId: NodeJS.Timeout;\n\n return Promise.race([\n promise.finally(() => clearTimeout(timeoutId)),\n new Promise<T>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(`Timeout after ${ms}ms: ${operation}`)), ms);\n }),\n ]);\n}\n\n/**\n * Extract the \"server base\" by removing a trailing `/mcp` path segment if present.\n * Examples:\n * - https://example.com/mcp -> https://example.com\n * - https://example.com/sheets/mcp -> https://example.com/sheets\n * - https://example.com/sheets/mcp/ -> https://example.com/sheets\n * - https://example.com/sheets -> https://example.com/sheets\n */\nexport function extractBaseUrl(mcpUrl: string): string {\n const url = new URL(mcpUrl);\n\n // Ignore query/hash for base URL purposes\n url.search = '';\n url.hash = '';\n\n // Normalize path segments (removes empty segments from leading/trailing slashes)\n const segments = url.pathname.split('/').filter(Boolean);\n\n // If last segment is exactly \"mcp\", drop it\n if (segments[segments.length - 1] === 'mcp') {\n segments.pop();\n }\n\n // Rebuild pathname; empty means root\n url.pathname = segments.length ? `/${segments.join('/')}` : '';\n\n // Return without trailing slash (except root origin)\n const out = url.origin + url.pathname;\n return out === url.origin ? out : out.replace(/\\/+$/, '');\n}\n\n/**\n * Infer transport type from server configuration with validation.\n *\n * Priority:\n * 1. Explicit type field (if present)\n * 2. URL protocol (if URL present): http://, https://\n * 3. Default to 'stdio' (if neither present)\n *\n * @param config - Server configuration\n * @returns Transport type\n * @throws Error if configuration is invalid or has conflicts\n */\nfunction inferTransportType(config: McpServerEntry): TransportType {\n // Priority 1: Explicit type field\n if (config.type) {\n // Validate consistency with URL if both present\n if (config.url) {\n const url = new URL(config.url);\n const protocol = url.protocol;\n\n if ((protocol === 'http:' || protocol === 'https:') && config.type !== 'http' && config.type !== 'sse-ide') {\n throw new Error(`Conflicting transport: URL protocol '${protocol}' requires type 'http', but got '${config.type}'`);\n }\n }\n\n // Return normalized type\n if (config.type === 'http' || config.type === 'sse-ide') return 'http';\n if (config.type === 'stdio') return 'stdio';\n\n throw new Error(`Unsupported transport type: ${config.type}`);\n }\n\n // Priority 2: Infer from URL protocol\n if (config.url) {\n const url = new URL(config.url);\n const protocol = url.protocol;\n\n if (protocol === 'http:' || protocol === 'https:') {\n return 'http';\n }\n throw new Error(`Unsupported URL protocol: ${protocol}`);\n }\n\n // Priority 3: Default to stdio\n return 'stdio';\n}\n\n/**\n * Connect MCP SDK client to server with full readiness handling.\n * @internal - Use registry.connect() instead\n *\n * **Completely handles readiness**: transport availability + MCP protocol handshake.\n *\n * Transport is intelligently inferred and handled:\n * - **Stdio servers**: Direct MCP connect (fast for spawned processes)\n * - **HTTP servers**: Transport polling (/mcp endpoint) + MCP connect\n * - **Registry result**: Handles both spawned and external servers\n *\n * Returns only when server is fully MCP-ready (initialize handshake complete).\n *\n * @param registryOrConfig - Result from createServerRegistry() or servers config object\n * @param serverName - Server name from servers config\n * @returns Connected MCP SDK Client (guaranteed ready)\n *\n * @example\n * // Using registry (recommended)\n * const registry = createServerRegistry({ echo: { command: 'node', args: ['server.ts'] } });\n * const client = await registry.connect('echo');\n * // Server is fully ready - transport available + MCP handshake complete\n *\n * @example\n * // HTTP server readiness (waits for /mcp polling + MCP handshake)\n * const registry = createServerRegistry(\n * { http: { type: 'http', url: 'http://localhost:3000/mcp', start: {...} } },\n * { dialects: ['start'] }\n * );\n * const client = await registry.connect('http');\n * // 1. Waits for HTTP server to respond on /mcp\n * // 2. Performs MCP initialize handshake\n * // 3. Returns ready client\n */\nexport async function connectMcpClient(\n registryOrConfig: RegistryLike | ServersConfig,\n serverName: string,\n options?: {\n dcrAuthenticator?: Partial<DcrAuthenticatorOptions>;\n logger?: Logger;\n }\n): Promise<Client> {\n // Detect whether we have a RegistryLike instance or just config\n const isRegistry = 'servers' in registryOrConfig && registryOrConfig.servers instanceof Map;\n const serversConfig: ServersConfig = isRegistry ? (registryOrConfig as RegistryLike).config : (registryOrConfig as ServersConfig);\n const registry = isRegistry ? (registryOrConfig as RegistryLike) : undefined;\n const logger = options?.logger ?? defaultLogger;\n\n const serverConfig = serversConfig[serverName];\n\n if (!serverConfig) {\n const available = Object.keys(serversConfig).join(', ');\n throw new Error(`Server '${serverName}' not found in config. Available servers: ${available || 'none'}`);\n }\n\n // Infer transport type with validation\n const transportType = inferTransportType(serverConfig);\n\n // Create MCP client\n const client = new Client({ name: 'mcp-cli-client', version: '1.0.0' }, { capabilities: {} });\n\n // Connect based on inferred transport\n if (transportType === 'stdio') {\n // Check if we have a spawned process in the registry\n const serverHandle = registry?.servers.get(serverName);\n\n if (serverHandle) {\n // Reuse the already-spawned process\n const transport = new ExistingProcessTransport(serverHandle.process);\n await client.connect(transport);\n } else {\n // No registry or server not in registry - spawn new process directly\n // This is the standard fallback when process management is not used\n if (!serverConfig.command) {\n throw new Error(`Server '${serverName}' has stdio transport but missing 'command' field`);\n }\n\n const transport = new StdioClientTransport({\n command: serverConfig.command,\n args: serverConfig.args || [],\n env: serverConfig.env || {},\n });\n\n // client.connect() performs initialize handshake - when it resolves, server is ready\n await client.connect(transport);\n }\n } else if (transportType === 'http') {\n if (!('url' in serverConfig) || !serverConfig.url) {\n throw new Error(`Server '${serverName}' has http transport but missing 'url' field`);\n }\n\n // Check if this is a freshly spawned HTTP server (from registry)\n // that might not be ready yet - transport readiness check needed\n const isSpawnedHttp = registry?.servers.has(serverName);\n\n if (isSpawnedHttp) {\n logger.debug(`[connectMcpClient] waiting for HTTP server '${serverName}' at ${serverConfig.url}`);\n await waitForHttpReady(serverConfig.url);\n logger.debug(`[connectMcpClient] HTTP server '${serverName}' ready`);\n }\n\n const url = new URL(serverConfig.url);\n\n // Check for DCR support and handle authentication automatically\n const baseUrl = extractBaseUrl(serverConfig.url);\n const capabilities = await withTimeout(probeAuthCapabilities(baseUrl), DCR_CAPABILTY_DISCOVERY_TIMEOUT, 'DCR capability discovery');\n\n let authToken: string | undefined;\n\n if (capabilities.supportsDcr) {\n logger.debug(`🔐 Server '${serverName}' supports DCR authentication`);\n\n // Get available port and create the exact redirect URI to use\n const port = await getPort();\n const redirectUri = `http://localhost:${port}/callback`;\n\n // Handle authentication using DcrAuthenticator with fully resolved redirectUri\n const authenticator = new DcrAuthenticator({\n headless: false,\n redirectUri,\n logger,\n ...options?.dcrAuthenticator,\n });\n\n // Ensure we have valid tokens (performs DCR + OAuth if needed)\n const tokens = await authenticator.ensureAuthenticated(baseUrl, capabilities);\n authToken = tokens.accessToken;\n\n logger.debug(`✅ Authentication complete for '${serverName}'`);\n } else {\n logger.debug(`â„šī¸ Server '${serverName}' does not support DCR - connecting without authentication`);\n }\n\n try {\n // Try modern Streamable HTTP first (protocol version 2025-03-26)\n // Merge static headers from config with DCR auth headers (DCR Authorization takes precedence)\n const staticHeaders = serverConfig.headers || {};\n const dcrHeaders = authToken ? { Authorization: `Bearer ${authToken}` } : {};\n const mergedHeaders = { ...staticHeaders, ...dcrHeaders };\n\n const transportOptions =\n Object.keys(mergedHeaders).length > 0\n ? {\n requestInit: {\n headers: mergedHeaders,\n },\n }\n : undefined;\n\n const transport = new StreamableHTTPClientTransport(url, transportOptions);\n // Type assertion: SDK transport has sessionId: string | undefined but Transport expects string\n // This is safe at runtime - the undefined is valid per MCP spec\n await withTimeout(client.connect(transport as unknown as Transport), 30000, 'StreamableHTTP connection');\n } catch (error) {\n // Fall back to SSE transport (MCP protocol version 2024-11-05)\n // SSE is a standard MCP transport used by many servers (e.g., FastMCP ecosystem)\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Fast-fail: Don't try SSE if connection was refused (server not running)\n // Check error.cause.code for ECONNREFUSED (fetch errors wrap the actual error in cause)\n const cause = error instanceof Error ? (error as Error & { cause?: { code?: string } }).cause : undefined;\n const isConnectionRefused = cause?.code === 'ECONNREFUSED' || errorMessage.includes('Connection refused');\n\n if (isConnectionRefused) {\n // Clean up client resources before throwing\n await client.close().catch(() => {});\n throw new Error(`Server not running at ${url}`);\n }\n\n // Check for known errors that indicate SSE fallback is needed\n const shouldFallback =\n errorMessage.includes('Missing session ID') || // FastMCP specific\n errorMessage.includes('404') || // Server doesn't have streamable HTTP endpoint\n errorMessage.includes('405'); // Method not allowed\n\n if (shouldFallback) {\n logger.warn(`Streamable HTTP failed (${errorMessage}), falling back to SSE transport`);\n } else {\n logger.warn('Streamable HTTP connection failed, trying SSE transport as fallback');\n }\n\n // Create new client for SSE transport (required per SDK pattern)\n const sseClient = new Client({ name: 'mcp-cli-client', version: '1.0.0' }, { capabilities: {} });\n\n // SSE transport with merged headers (static + DCR auth)\n // Reuse the same header merging logic as Streamable HTTP\n const staticHeaders = serverConfig.headers || {};\n const dcrHeaders = authToken ? { Authorization: `Bearer ${authToken}` } : {};\n const mergedHeaders = { ...staticHeaders, ...dcrHeaders };\n\n const sseTransportOptions =\n Object.keys(mergedHeaders).length > 0\n ? {\n requestInit: {\n headers: mergedHeaders,\n },\n }\n : undefined;\n\n const sseTransport = new SSEClientTransport(url, sseTransportOptions);\n\n try {\n await withTimeout(sseClient.connect(sseTransport), 30000, 'SSE connection');\n // Return SSE client instead of original\n return sseClient;\n } catch (sseError) {\n // SSE connection failed - clean up both clients before throwing\n await Promise.all([client.close().catch(() => {}), sseClient.close().catch(() => {})]);\n throw sseError;\n }\n }\n }\n\n return client; // Guaranteed ready when returned\n}\n"],"names":["connectMcpClient","extractBaseUrl","withTimeout","promise","ms","operation","timeoutId","Promise","race","finally","clearTimeout","_","reject","setTimeout","Error","mcpUrl","url","URL","search","hash","segments","pathname","split","filter","Boolean","length","pop","join","out","origin","replace","inferTransportType","config","type","protocol","registryOrConfig","serverName","options","isRegistry","serversConfig","registry","logger","serverConfig","available","transportType","client","serverHandle","transport","isSpawnedHttp","baseUrl","capabilities","authToken","port","redirectUri","authenticator","tokens","staticHeaders","dcrHeaders","mergedHeaders","transportOptions","error","errorMessage","cause","isConnectionRefused","shouldFallback","sseClient","sseTransportOptions","sseTransport","sseError","servers","Map","undefined","defaultLogger","Object","keys","Client","name","version","get","ExistingProcessTransport","process","connect","command","StdioClientTransport","args","env","has","debug","waitForHttpReady","probeAuthCapabilities","DCR_CAPABILTY_DISCOVERY_TIMEOUT","supportsDcr","getPort","DcrAuthenticator","headless","dcrAuthenticator","ensureAuthenticated","accessToken","headers","Authorization","requestInit","StreamableHTTPClientTransport","message","String","code","includes","close","catch","warn","SSEClientTransport","all"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/connection/connect-client.ts"],"sourcesContent":["/**\n * connect-mcp-client.ts\n *\n * Helper to connect MCP SDK clients to servers with intelligent transport inference.\n * Automatically detects transport type from URL protocol or type field.\n */\n\nimport type { Transport } from '@modelcontextprotocol/client';\nimport { Client, SSEClientTransport, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';\nimport { StdioClientTransport } from '@modelcontextprotocol/client/stdio';\nimport getPort from 'get-port';\nimport { probeAuthCapabilities } from '../auth/index.ts';\nimport { DCR_CAPABILTY_DISCOVERY_TIMEOUT } from '../constants.ts';\nimport { DcrAuthenticator, type DcrAuthenticatorOptions } from '../dcr/index.ts';\nimport { normalizeUrl } from '../lib/url-utils.ts';\nimport type { ServerProcess } from '../spawn/spawn-server.ts';\nimport type { ServersConfig } from '../spawn/spawn-servers.ts';\n\n/**\n * Minimal interface for connecting to servers.\n * Only needs config and servers map for connection logic.\n */\ninterface RegistryLike {\n config: ServersConfig;\n servers: Map<string, ServerProcess>;\n}\n\nimport type { McpServerEntry, TransportType } from '../types.ts';\nimport { logger as defaultLogger, type Logger } from '../utils/logger.ts';\nimport { ExistingProcessTransport } from './existing-process-transport.ts';\nimport { waitForHttpReady } from './wait-for-http-ready.ts';\n\n/**\n * Wrap promise with timeout - throws if promise takes too long\n * Clears timeout when promise completes to prevent hanging event loop\n * @param promise - Promise to wrap\n * @param ms - Timeout in milliseconds\n * @param operation - Description of operation for error message\n * @returns Promise result or timeout error\n */\nasync function withTimeout<T>(promise: Promise<T>, ms: number, operation: string): Promise<T> {\n let timeoutId: NodeJS.Timeout;\n\n return Promise.race([\n promise.finally(() => clearTimeout(timeoutId)),\n new Promise<T>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(`Timeout after ${ms}ms: ${operation}`)), ms);\n }),\n ]);\n}\n\n/**\n * Infer transport type from server configuration with validation.\n *\n * Priority:\n * 1. Explicit type field (if present)\n * 2. URL protocol (if URL present): http://, https://\n * 3. Default to 'stdio' (if neither present)\n *\n * @param config - Server configuration\n * @returns Transport type\n * @throws Error if configuration is invalid or has conflicts\n */\nfunction inferTransportType(config: McpServerEntry): TransportType {\n // Priority 1: Explicit type field\n if (config.type) {\n // Validate consistency with URL if both present\n if (config.url) {\n const url = new URL(config.url);\n const protocol = url.protocol;\n\n if ((protocol === 'http:' || protocol === 'https:') && config.type !== 'http' && config.type !== 'sse-ide') {\n throw new Error(`Conflicting transport: URL protocol '${protocol}' requires type 'http', but got '${config.type}'`);\n }\n }\n\n // Return normalized type\n if (config.type === 'http' || config.type === 'sse-ide') return 'http';\n if (config.type === 'stdio') return 'stdio';\n\n throw new Error(`Unsupported transport type: ${config.type}`);\n }\n\n // Priority 2: Infer from URL protocol\n if (config.url) {\n const url = new URL(config.url);\n const protocol = url.protocol;\n\n if (protocol === 'http:' || protocol === 'https:') {\n return 'http';\n }\n throw new Error(`Unsupported URL protocol: ${protocol}`);\n }\n\n // Priority 3: Default to stdio\n return 'stdio';\n}\n\n/**\n * Connect MCP SDK client to server with full readiness handling.\n * @internal - Use registry.connect() instead\n *\n * **Completely handles readiness**: transport availability + MCP protocol handshake.\n *\n * Transport is intelligently inferred and handled:\n * - **Stdio servers**: Direct MCP connect (fast for spawned processes)\n * - **HTTP servers**: Transport polling (/mcp endpoint) + MCP connect\n * - **Registry result**: Handles both spawned and external servers\n *\n * Returns only when server is fully MCP-ready (initialize handshake complete).\n *\n * @param registryOrConfig - Result from createServerRegistry() or servers config object\n * @param serverName - Server name from servers config\n * @returns Connected MCP SDK Client (guaranteed ready)\n *\n * @example\n * // Using registry (recommended)\n * const registry = createServerRegistry({ echo: { command: 'node', args: ['server.ts'] } });\n * const client = await registry.connect('echo');\n * // Server is fully ready - transport available + MCP handshake complete\n *\n * @example\n * // HTTP server readiness (waits for /mcp polling + MCP handshake)\n * const registry = createServerRegistry(\n * { http: { type: 'http', url: 'http://localhost:3000/mcp', start: {...} } },\n * { dialects: ['start'] }\n * );\n * const client = await registry.connect('http');\n * // 1. Waits for HTTP server to respond on /mcp\n * // 2. Performs MCP initialize handshake\n * // 3. Returns ready client\n */\nexport async function connectMcpClient(\n registryOrConfig: RegistryLike | ServersConfig,\n serverName: string,\n options?: {\n dcrAuthenticator?: Partial<DcrAuthenticatorOptions>;\n logger?: Logger;\n }\n): Promise<Client> {\n // Detect whether we have a RegistryLike instance or just config\n const isRegistry = 'servers' in registryOrConfig && registryOrConfig.servers instanceof Map;\n const serversConfig: ServersConfig = isRegistry ? (registryOrConfig as RegistryLike).config : (registryOrConfig as ServersConfig);\n const registry = isRegistry ? (registryOrConfig as RegistryLike) : undefined;\n const logger = options?.logger ?? defaultLogger;\n\n const serverConfig = serversConfig[serverName];\n\n if (!serverConfig) {\n const available = Object.keys(serversConfig).join(', ');\n throw new Error(`Server '${serverName}' not found in config. Available servers: ${available || 'none'}`);\n }\n\n // Infer transport type with validation\n const transportType = inferTransportType(serverConfig);\n\n // Create MCP client\n const client = new Client({ name: 'mcp-cli-client', version: '1.0.0' }, { capabilities: {} });\n\n // Connect based on inferred transport\n if (transportType === 'stdio') {\n // Check if we have a spawned process in the registry\n const serverHandle = registry?.servers.get(serverName);\n\n if (serverHandle) {\n // Reuse the already-spawned process\n const transport = new ExistingProcessTransport(serverHandle.process);\n await client.connect(transport);\n } else {\n // No registry or server not in registry - spawn new process directly\n // This is the standard fallback when process management is not used\n if (!serverConfig.command) {\n throw new Error(`Server '${serverName}' has stdio transport but missing 'command' field`);\n }\n\n const transport = new StdioClientTransport({\n command: serverConfig.command,\n args: serverConfig.args || [],\n env: serverConfig.env || {},\n });\n\n // client.connect() performs initialize handshake - when it resolves, server is ready\n await client.connect(transport);\n }\n } else if (transportType === 'http') {\n if (!('url' in serverConfig) || !serverConfig.url) {\n throw new Error(`Server '${serverName}' has http transport but missing 'url' field`);\n }\n\n // Check if this is a freshly spawned HTTP server (from registry)\n // that might not be ready yet - transport readiness check needed\n const isSpawnedHttp = registry?.servers.has(serverName);\n\n if (isSpawnedHttp) {\n logger.debug(`[connectMcpClient] waiting for HTTP server '${serverName}' at ${serverConfig.url}`);\n await waitForHttpReady(serverConfig.url);\n logger.debug(`[connectMcpClient] HTTP server '${serverName}' ready`);\n }\n\n const url = new URL(serverConfig.url);\n\n // Check for DCR support and handle authentication automatically\n // The canonical MCP server URI, path segment and all. Both calls below need\n // the server's identity, not its deployment root: discovery uses the path to\n // find resource-specific metadata (RFC 9728 sub-path), and the authenticator\n // audience-binds tokens to it (RFC 8707). Handing either the `/mcp`-stripped\n // base names a different resource, which authorization servers that validate\n // the `resource` indicator reject as `invalid_target`.\n const mcpServerUrl = normalizeUrl(serverConfig.url);\n const capabilities = await withTimeout(probeAuthCapabilities(mcpServerUrl), DCR_CAPABILTY_DISCOVERY_TIMEOUT, 'DCR capability discovery');\n\n let authToken: string | undefined;\n\n if (capabilities.supportsDcr) {\n logger.debug(`🔐 Server '${serverName}' supports DCR authentication`);\n\n // Get available port and create the exact redirect URI to use\n const port = await getPort();\n const redirectUri = `http://localhost:${port}/callback`;\n\n // Handle authentication using DcrAuthenticator with fully resolved redirectUri\n const authenticator = new DcrAuthenticator({\n headless: false,\n redirectUri,\n logger,\n ...options?.dcrAuthenticator,\n });\n\n // Ensure we have valid tokens (performs DCR + OAuth if needed)\n const tokens = await authenticator.ensureAuthenticated(mcpServerUrl, capabilities);\n authToken = tokens.accessToken;\n\n logger.debug(`✅ Authentication complete for '${serverName}'`);\n } else {\n logger.debug(`â„šī¸ Server '${serverName}' does not support DCR - connecting without authentication`);\n }\n\n try {\n // Try modern Streamable HTTP first (protocol version 2025-03-26)\n // Merge static headers from config with DCR auth headers (DCR Authorization takes precedence)\n const staticHeaders = serverConfig.headers || {};\n const dcrHeaders = authToken ? { Authorization: `Bearer ${authToken}` } : {};\n const mergedHeaders = { ...staticHeaders, ...dcrHeaders };\n\n const transportOptions =\n Object.keys(mergedHeaders).length > 0\n ? {\n requestInit: {\n headers: mergedHeaders,\n },\n }\n : undefined;\n\n const transport = new StreamableHTTPClientTransport(url, transportOptions);\n // Type assertion: SDK transport has sessionId: string | undefined but Transport expects string\n // This is safe at runtime - the undefined is valid per MCP spec\n await withTimeout(client.connect(transport as unknown as Transport), 30000, 'StreamableHTTP connection');\n } catch (error) {\n // Fall back to SSE transport (MCP protocol version 2024-11-05)\n // SSE is a standard MCP transport used by many servers (e.g., FastMCP ecosystem)\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Fast-fail: Don't try SSE if connection was refused (server not running)\n // Check error.cause.code for ECONNREFUSED (fetch errors wrap the actual error in cause)\n const cause = error instanceof Error ? (error as Error & { cause?: { code?: string } }).cause : undefined;\n const isConnectionRefused = cause?.code === 'ECONNREFUSED' || errorMessage.includes('Connection refused');\n\n if (isConnectionRefused) {\n // Clean up client resources before throwing\n await client.close().catch(() => {});\n throw new Error(`Server not running at ${url}`);\n }\n\n // Check for known errors that indicate SSE fallback is needed\n const shouldFallback =\n errorMessage.includes('Missing session ID') || // FastMCP specific\n errorMessage.includes('404') || // Server doesn't have streamable HTTP endpoint\n errorMessage.includes('405'); // Method not allowed\n\n if (shouldFallback) {\n logger.warn(`Streamable HTTP failed (${errorMessage}), falling back to SSE transport`);\n } else {\n logger.warn('Streamable HTTP connection failed, trying SSE transport as fallback');\n }\n\n // Create new client for SSE transport (required per SDK pattern)\n const sseClient = new Client({ name: 'mcp-cli-client', version: '1.0.0' }, { capabilities: {} });\n\n // SSE transport with merged headers (static + DCR auth)\n // Reuse the same header merging logic as Streamable HTTP\n const staticHeaders = serverConfig.headers || {};\n const dcrHeaders = authToken ? { Authorization: `Bearer ${authToken}` } : {};\n const mergedHeaders = { ...staticHeaders, ...dcrHeaders };\n\n const sseTransportOptions =\n Object.keys(mergedHeaders).length > 0\n ? {\n requestInit: {\n headers: mergedHeaders,\n },\n }\n : undefined;\n\n const sseTransport = new SSEClientTransport(url, sseTransportOptions);\n\n try {\n await withTimeout(sseClient.connect(sseTransport), 30000, 'SSE connection');\n // Return SSE client instead of original\n return sseClient;\n } catch (sseError) {\n // SSE connection failed - clean up both clients before throwing\n await Promise.all([client.close().catch(() => {}), sseClient.close().catch(() => {})]);\n throw sseError;\n }\n }\n }\n\n return client; // Guaranteed ready when returned\n}\n"],"names":["connectMcpClient","withTimeout","promise","ms","operation","timeoutId","Promise","race","finally","clearTimeout","_","reject","setTimeout","Error","inferTransportType","config","type","url","URL","protocol","registryOrConfig","serverName","options","isRegistry","serversConfig","registry","logger","serverConfig","available","transportType","client","serverHandle","transport","isSpawnedHttp","mcpServerUrl","capabilities","authToken","port","redirectUri","authenticator","tokens","staticHeaders","dcrHeaders","mergedHeaders","transportOptions","error","errorMessage","cause","isConnectionRefused","shouldFallback","sseClient","sseTransportOptions","sseTransport","sseError","servers","Map","undefined","defaultLogger","Object","keys","join","Client","name","version","get","ExistingProcessTransport","process","connect","command","StdioClientTransport","args","env","has","debug","waitForHttpReady","normalizeUrl","probeAuthCapabilities","DCR_CAPABILTY_DISCOVERY_TIMEOUT","supportsDcr","getPort","DcrAuthenticator","headless","dcrAuthenticator","ensureAuthenticated","accessToken","headers","Authorization","length","requestInit","StreamableHTTPClientTransport","message","String","code","includes","close","catch","warn","SSEClientTransport","all"],"mappings":"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"}
@@ -4,8 +4,7 @@
4
4
  * MCP transport that wraps an existing child process for stdio communication.
5
5
  * Used when connecting to servers already spawned by initServers().
6
6
  */
7
- import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
8
- import type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
7
+ import type { JSONRPCMessage, Transport } from '@modelcontextprotocol/client';
9
8
  import type { ChildProcess } from 'child_process';
10
9
  /**
11
10
  * Transport that communicates with an existing child process via stdio.
@@ -4,8 +4,7 @@
4
4
  * MCP transport that wraps an existing child process for stdio communication.
5
5
  * Used when connecting to servers already spawned by initServers().
6
6
  */
7
- import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
8
- import type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
7
+ import type { JSONRPCMessage, Transport } from '@modelcontextprotocol/client';
9
8
  import type { ChildProcess } from 'child_process';
10
9
  /**
11
10
  * Transport that communicates with an existing child process via stdio.
@@ -13,7 +13,7 @@ Object.defineProperty(exports, "ExistingProcessTransport", {
13
13
  return ExistingProcessTransport;
14
14
  }
15
15
  });
16
- var _stdio = require("@modelcontextprotocol/sdk/shared/stdio.js");
16
+ var _client = require("@modelcontextprotocol/client");
17
17
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
18
18
  try {
19
19
  var info = gen[key](arg);
@@ -152,7 +152,7 @@ var ExistingProcessTransport = /*#__PURE__*/ function() {
152
152
  throw new Error('Child process must have stdin and stdout pipes');
153
153
  }
154
154
  this._process = process;
155
- this._readBuffer = new _stdio.ReadBuffer();
155
+ this._readBuffer = new _client.ReadBuffer();
156
156
  }
157
157
  var _proto = ExistingProcessTransport.prototype;
158
158
  /**
@@ -253,7 +253,7 @@ var ExistingProcessTransport = /*#__PURE__*/ function() {
253
253
  reject(new Error('stdin is not available'));
254
254
  return;
255
255
  }
256
- var json = (0, _stdio.serializeMessage)(message);
256
+ var json = (0, _client.serializeMessage)(message);
257
257
  if (_this._process.stdin.write(json)) {
258
258
  resolve();
259
259
  } else {
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/connection/existing-process-transport.ts"],"sourcesContent":["/**\n * existing-process-transport.ts\n *\n * MCP transport that wraps an existing child process for stdio communication.\n * Used when connecting to servers already spawned by initServers().\n */\n\nimport { ReadBuffer, serializeMessage } from '@modelcontextprotocol/sdk/shared/stdio.js';\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';\nimport type { ChildProcess } from 'child_process';\n\n/**\n * Transport that communicates with an existing child process via stdio.\n * Does NOT spawn a new process - uses the one provided.\n */\nexport class ExistingProcessTransport implements Transport {\n private _process: ChildProcess;\n private _readBuffer: ReadBuffer;\n private _dataHandler: ((chunk: Buffer) => void) | null = null;\n private _errorHandler: ((error: Error) => void) | null = null;\n\n // Transport interface callbacks\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n constructor(process: ChildProcess) {\n if (!process.stdin || !process.stdout) {\n throw new Error('Child process must have stdin and stdout pipes');\n }\n\n this._process = process;\n this._readBuffer = new ReadBuffer();\n }\n\n /**\n * Start the transport - sets up stdio listeners on existing process.\n */\n async start(): Promise<void> {\n return new Promise((resolve, reject) => {\n // Listen for process events\n this._process.on('error', (error) => {\n this.onerror?.(error);\n reject(error);\n });\n\n this._process.on('close', () => {\n this.onclose?.();\n });\n\n // Create and save data handler for close\n this._dataHandler = (chunk: Buffer) => {\n this._readBuffer.append(chunk);\n this.processReadBuffer();\n };\n\n // Create and save error handler for close\n this._errorHandler = (error: Error) => {\n this.onerror?.(error);\n };\n\n // Listen for stdout data (MCP messages)\n this._process.stdout?.on('data', this._dataHandler);\n this._process.stdout?.on('error', this._errorHandler);\n this._process.stdin?.on('error', this._errorHandler);\n\n // Process is already running - resolve immediately\n resolve();\n });\n }\n\n /**\n * Process buffered messages from stdout.\n */\n private processReadBuffer(): void {\n while (true) {\n try {\n const message = this._readBuffer.readMessage();\n if (message === null) {\n break;\n }\n this.onmessage?.(message);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n }\n\n /**\n * Close the transport - close without killing the shared process.\n * The process is managed by the cluster and may have other active connections.\n */\n async close(): Promise<void> {\n if (this._dataHandler) {\n this._process.stdout?.off('data', this._dataHandler);\n this._dataHandler = null;\n }\n\n if (this._errorHandler) {\n this._process.stdout?.off('error', this._errorHandler);\n this._process.stdin?.off('error', this._errorHandler);\n this._errorHandler = null;\n }\n\n this._readBuffer.clear();\n }\n\n /**\n * Send a message to the server via stdin.\n */\n async send(message: JSONRPCMessage): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this._process.stdin) {\n reject(new Error('stdin is not available'));\n return;\n }\n\n const json = serializeMessage(message);\n\n if (this._process.stdin.write(json)) {\n resolve();\n } else {\n this._process.stdin.once('drain', resolve);\n }\n });\n }\n}\n"],"names":["ExistingProcessTransport","process","_dataHandler","_errorHandler","stdin","stdout","Error","_process","_readBuffer","ReadBuffer","start","Promise","resolve","reject","on","error","onerror","onclose","chunk","append","processReadBuffer","message","readMessage","onmessage","close","off","clear","send","json","serializeMessage","write","once"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/connection/existing-process-transport.ts"],"sourcesContent":["/**\n * existing-process-transport.ts\n *\n * MCP transport that wraps an existing child process for stdio communication.\n * Used when connecting to servers already spawned by initServers().\n */\n\nimport type { JSONRPCMessage, Transport } from '@modelcontextprotocol/client';\nimport { ReadBuffer, serializeMessage } from '@modelcontextprotocol/client';\nimport type { ChildProcess } from 'child_process';\n\n/**\n * Transport that communicates with an existing child process via stdio.\n * Does NOT spawn a new process - uses the one provided.\n */\nexport class ExistingProcessTransport implements Transport {\n private _process: ChildProcess;\n private _readBuffer: ReadBuffer;\n private _dataHandler: ((chunk: Buffer) => void) | null = null;\n private _errorHandler: ((error: Error) => void) | null = null;\n\n // Transport interface callbacks\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n constructor(process: ChildProcess) {\n if (!process.stdin || !process.stdout) {\n throw new Error('Child process must have stdin and stdout pipes');\n }\n\n this._process = process;\n this._readBuffer = new ReadBuffer();\n }\n\n /**\n * Start the transport - sets up stdio listeners on existing process.\n */\n async start(): Promise<void> {\n return new Promise((resolve, reject) => {\n // Listen for process events\n this._process.on('error', (error) => {\n this.onerror?.(error);\n reject(error);\n });\n\n this._process.on('close', () => {\n this.onclose?.();\n });\n\n // Create and save data handler for close\n this._dataHandler = (chunk: Buffer) => {\n this._readBuffer.append(chunk);\n this.processReadBuffer();\n };\n\n // Create and save error handler for close\n this._errorHandler = (error: Error) => {\n this.onerror?.(error);\n };\n\n // Listen for stdout data (MCP messages)\n this._process.stdout?.on('data', this._dataHandler);\n this._process.stdout?.on('error', this._errorHandler);\n this._process.stdin?.on('error', this._errorHandler);\n\n // Process is already running - resolve immediately\n resolve();\n });\n }\n\n /**\n * Process buffered messages from stdout.\n */\n private processReadBuffer(): void {\n while (true) {\n try {\n const message = this._readBuffer.readMessage();\n if (message === null) {\n break;\n }\n this.onmessage?.(message);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n }\n\n /**\n * Close the transport - close without killing the shared process.\n * The process is managed by the cluster and may have other active connections.\n */\n async close(): Promise<void> {\n if (this._dataHandler) {\n this._process.stdout?.off('data', this._dataHandler);\n this._dataHandler = null;\n }\n\n if (this._errorHandler) {\n this._process.stdout?.off('error', this._errorHandler);\n this._process.stdin?.off('error', this._errorHandler);\n this._errorHandler = null;\n }\n\n this._readBuffer.clear();\n }\n\n /**\n * Send a message to the server via stdin.\n */\n async send(message: JSONRPCMessage): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this._process.stdin) {\n reject(new Error('stdin is not available'));\n return;\n }\n\n const json = serializeMessage(message);\n\n if (this._process.stdin.write(json)) {\n resolve();\n } else {\n this._process.stdin.once('drain', resolve);\n }\n });\n }\n}\n"],"names":["ExistingProcessTransport","process","_dataHandler","_errorHandler","stdin","stdout","Error","_process","_readBuffer","ReadBuffer","start","Promise","resolve","reject","on","error","onerror","onclose","chunk","append","processReadBuffer","message","readMessage","onmessage","close","off","clear","send","json","serializeMessage","write","once"],"mappings":"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"}
@@ -39,7 +39,9 @@ export declare class DcrAuthenticator {
39
39
  * Ensure server is authenticated, performing DCR and OAuth if needed
40
40
  * Proactively refreshes tokens if they're within 5 minutes of expiry
41
41
  *
42
- * @param baseUrl - Base URL of the server (e.g., https://example.com)
42
+ * @param mcpServerUrl - The MCP server's canonical URL, exactly as configured,
43
+ * with its path intact (`https://example.com/mcp`). Not a deployment root:
44
+ * the path is what identifies the resource an issued token is bound to.
43
45
  * @param capabilities - Auth capabilities from .well-known endpoint
44
46
  * @returns Valid token set ready to use
45
47
  *
@@ -48,11 +50,30 @@ export declare class DcrAuthenticator {
48
50
  * @example
49
51
  * const authenticator = new DcrAuthenticator({ redirectUri: 'http://localhost:3000/callback' });
50
52
  * const tokens = await authenticator.ensureAuthenticated(
51
- * 'https://example.com',
53
+ * 'https://example.com/mcp',
52
54
  * capabilities
53
55
  * );
54
56
  */
55
- ensureAuthenticated(baseUrl: string, capabilities: AuthCapabilities): Promise<TokenSet>;
57
+ ensureAuthenticated(mcpServerUrl: string, capabilities: AuthCapabilities): Promise<TokenSet>;
58
+ /**
59
+ * The three things a server URL is used for here, kept apart on purpose.
60
+ *
61
+ * They were one value once, and collapsing them is what sent an authorization
62
+ * server the wrong audience: `resource` was derived from the deployment root,
63
+ * so a server at `https://host/mcp` was asked to mint a token for
64
+ * `https://host`, and any server that validates the indicator answered
65
+ * `invalid_target`.
66
+ *
67
+ * - `serverBaseUrl` builds the server's own endpoints (`/oauth/verify`), so a
68
+ * trailing `/mcp` comes off.
69
+ * - `resource` is the RFC 8707 audience. The resource server names itself in
70
+ * its RFC 9728 metadata; that name wins. Only when no such document exists
71
+ * do we fall back to the URL we were configured with.
72
+ * - `storeKey` identifies the credential locally. It stays the configured URL
73
+ * rather than the discovered `resource`, so it can be computed without a
74
+ * network round trip - `deleteTokens` has only the URL to work from.
75
+ */
76
+ private resolveUrls;
56
77
  /**
57
78
  * Handle authentication for self-hosted DCR servers
58
79
  * Self-hosted servers manage their own token storage via /oauth/verify
@@ -68,9 +89,14 @@ export declare class DcrAuthenticator {
68
89
  private refreshTokens;
69
90
  /**
70
91
  * Deletes both stored token families for a server, across every issuer they were bound to.
92
+ *
93
+ * Takes the same `mcpServerUrl` that {@link DcrAuthenticator.ensureAuthenticated}
94
+ * was given - keys are built from the configured URL, never from the discovered
95
+ * RFC 8707 resource, precisely so this can find them without doing discovery.
96
+ *
71
97
  * @throws CredentialBindingError if the configured store cannot enumerate keys.
72
98
  */
73
- deleteTokens(baseUrl: string): Promise<void>;
99
+ deleteTokens(mcpServerUrl: string): Promise<void>;
74
100
  /** Discards a stored credential that is not bound to `issuer` (SEP-2352), including one stored before issuer binding existed. */
75
101
  private loadTokens;
76
102
  private buildFlowOptions;
@@ -39,7 +39,9 @@ export declare class DcrAuthenticator {
39
39
  * Ensure server is authenticated, performing DCR and OAuth if needed
40
40
  * Proactively refreshes tokens if they're within 5 minutes of expiry
41
41
  *
42
- * @param baseUrl - Base URL of the server (e.g., https://example.com)
42
+ * @param mcpServerUrl - The MCP server's canonical URL, exactly as configured,
43
+ * with its path intact (`https://example.com/mcp`). Not a deployment root:
44
+ * the path is what identifies the resource an issued token is bound to.
43
45
  * @param capabilities - Auth capabilities from .well-known endpoint
44
46
  * @returns Valid token set ready to use
45
47
  *
@@ -48,11 +50,30 @@ export declare class DcrAuthenticator {
48
50
  * @example
49
51
  * const authenticator = new DcrAuthenticator({ redirectUri: 'http://localhost:3000/callback' });
50
52
  * const tokens = await authenticator.ensureAuthenticated(
51
- * 'https://example.com',
53
+ * 'https://example.com/mcp',
52
54
  * capabilities
53
55
  * );
54
56
  */
55
- ensureAuthenticated(baseUrl: string, capabilities: AuthCapabilities): Promise<TokenSet>;
57
+ ensureAuthenticated(mcpServerUrl: string, capabilities: AuthCapabilities): Promise<TokenSet>;
58
+ /**
59
+ * The three things a server URL is used for here, kept apart on purpose.
60
+ *
61
+ * They were one value once, and collapsing them is what sent an authorization
62
+ * server the wrong audience: `resource` was derived from the deployment root,
63
+ * so a server at `https://host/mcp` was asked to mint a token for
64
+ * `https://host`, and any server that validates the indicator answered
65
+ * `invalid_target`.
66
+ *
67
+ * - `serverBaseUrl` builds the server's own endpoints (`/oauth/verify`), so a
68
+ * trailing `/mcp` comes off.
69
+ * - `resource` is the RFC 8707 audience. The resource server names itself in
70
+ * its RFC 9728 metadata; that name wins. Only when no such document exists
71
+ * do we fall back to the URL we were configured with.
72
+ * - `storeKey` identifies the credential locally. It stays the configured URL
73
+ * rather than the discovered `resource`, so it can be computed without a
74
+ * network round trip - `deleteTokens` has only the URL to work from.
75
+ */
76
+ private resolveUrls;
56
77
  /**
57
78
  * Handle authentication for self-hosted DCR servers
58
79
  * Self-hosted servers manage their own token storage via /oauth/verify
@@ -68,9 +89,14 @@ export declare class DcrAuthenticator {
68
89
  private refreshTokens;
69
90
  /**
70
91
  * Deletes both stored token families for a server, across every issuer they were bound to.
92
+ *
93
+ * Takes the same `mcpServerUrl` that {@link DcrAuthenticator.ensureAuthenticated}
94
+ * was given - keys are built from the configured URL, never from the discovered
95
+ * RFC 8707 resource, precisely so this can find them without doing discovery.
96
+ *
71
97
  * @throws CredentialBindingError if the configured store cannot enumerate keys.
72
98
  */
73
- deleteTokens(baseUrl: string): Promise<void>;
99
+ deleteTokens(mcpServerUrl: string): Promise<void>;
74
100
  /** Discards a stored credential that is not bound to `issuer` (SEP-2352), including one stored before issuer binding existed. */
75
101
  private loadTokens;
76
102
  private buildFlowOptions;
@@ -474,17 +474,17 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
474
474
  /**
475
475
  * Detect if server is self-hosted DCR (vs external OAuth provider)
476
476
  * Self-hosted servers have their own OAuth endpoints and manage token storage
477
- */ _proto.detectSelfHostedMode = function detectSelfHostedMode(baseUrl) {
477
+ */ _proto.detectSelfHostedMode = function detectSelfHostedMode(mcpServerUrl) {
478
478
  return _async_to_generator(function() {
479
479
  return _ts_generator(this, function(_state) {
480
480
  try {
481
481
  // Self-hosted DCR servers typically run their own OAuth server
482
482
  // Check if this is a self-hosted instance by testing OAuth metadata
483
- // For now, assume self-hosted if baseUrl matches common localhost patterns
483
+ // For now, assume self-hosted if the URL matches common localhost patterns
484
484
  // TODO: Implement proper self-hosted detection logic
485
485
  return [
486
486
  2,
487
- baseUrl.includes('localhost') || baseUrl.includes('127.0.0.1')
487
+ mcpServerUrl.includes('localhost') || mcpServerUrl.includes('127.0.0.1')
488
488
  ];
489
489
  } catch (_error) {
490
490
  return [
@@ -502,7 +502,9 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
502
502
  * Ensure server is authenticated, performing DCR and OAuth if needed
503
503
  * Proactively refreshes tokens if they're within 5 minutes of expiry
504
504
  *
505
- * @param baseUrl - Base URL of the server (e.g., https://example.com)
505
+ * @param mcpServerUrl - The MCP server's canonical URL, exactly as configured,
506
+ * with its path intact (`https://example.com/mcp`). Not a deployment root:
507
+ * the path is what identifies the resource an issued token is bound to.
506
508
  * @param capabilities - Auth capabilities from .well-known endpoint
507
509
  * @returns Valid token set ready to use
508
510
  *
@@ -511,10 +513,10 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
511
513
  * @example
512
514
  * const authenticator = new DcrAuthenticator({ redirectUri: 'http://localhost:3000/callback' });
513
515
  * const tokens = await authenticator.ensureAuthenticated(
514
- * 'https://example.com',
516
+ * 'https://example.com/mcp',
515
517
  * capabilities
516
518
  * );
517
- */ _proto.ensureAuthenticated = function ensureAuthenticated(baseUrl, capabilities) {
519
+ */ _proto.ensureAuthenticated = function ensureAuthenticated(mcpServerUrl, capabilities) {
518
520
  return _async_to_generator(function() {
519
521
  var isSelfHosted;
520
522
  return _ts_generator(this, function(_state) {
@@ -522,39 +524,65 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
522
524
  case 0:
523
525
  return [
524
526
  4,
525
- this.detectSelfHostedMode(baseUrl)
527
+ this.detectSelfHostedMode(mcpServerUrl)
526
528
  ];
527
529
  case 1:
528
530
  isSelfHosted = _state.sent();
529
531
  if (isSelfHosted) {
530
532
  return [
531
533
  2,
532
- this.ensureAuthenticatedSelfHosted(baseUrl, capabilities)
534
+ this.ensureAuthenticatedSelfHosted(mcpServerUrl, capabilities)
533
535
  ];
534
536
  }
535
537
  return [
536
538
  2,
537
- this.ensureAuthenticatedExternal(baseUrl, capabilities)
539
+ this.ensureAuthenticatedExternal(mcpServerUrl, capabilities)
538
540
  ];
539
541
  }
540
542
  });
541
543
  }).call(this);
542
544
  };
543
545
  /**
546
+ * The three things a server URL is used for here, kept apart on purpose.
547
+ *
548
+ * They were one value once, and collapsing them is what sent an authorization
549
+ * server the wrong audience: `resource` was derived from the deployment root,
550
+ * so a server at `https://host/mcp` was asked to mint a token for
551
+ * `https://host`, and any server that validates the indicator answered
552
+ * `invalid_target`.
553
+ *
554
+ * - `serverBaseUrl` builds the server's own endpoints (`/oauth/verify`), so a
555
+ * trailing `/mcp` comes off.
556
+ * - `resource` is the RFC 8707 audience. The resource server names itself in
557
+ * its RFC 9728 metadata; that name wins. Only when no such document exists
558
+ * do we fall back to the URL we were configured with.
559
+ * - `storeKey` identifies the credential locally. It stays the configured URL
560
+ * rather than the discovered `resource`, so it can be computed without a
561
+ * network round trip - `deleteTokens` has only the URL to work from.
562
+ */ _proto.resolveUrls = function resolveUrls(mcpServerUrl, capabilities) {
563
+ var _capabilities_resource;
564
+ var storeKey = (0, _urlutilsts.normalizeUrl)(mcpServerUrl);
565
+ return {
566
+ serverBaseUrl: (0, _urlutilsts.extractBaseUrl)(mcpServerUrl),
567
+ resource: (_capabilities_resource = capabilities.resource) !== null && _capabilities_resource !== void 0 ? _capabilities_resource : storeKey,
568
+ storeKey: storeKey
569
+ };
570
+ };
571
+ /**
544
572
  * Handle authentication for self-hosted DCR servers
545
573
  * Self-hosted servers manage their own token storage via /oauth/verify
546
- */ _proto.ensureAuthenticatedSelfHosted = function ensureAuthenticatedSelfHosted(baseUrl, capabilities) {
574
+ */ _proto.ensureAuthenticatedSelfHosted = function ensureAuthenticatedSelfHosted(mcpServerUrl, capabilities) {
547
575
  return _async_to_generator(function() {
548
- var allowLoopback, issuer, resource, dcrTokenKey, tokens, verifyUrl, verifyResponse, verifyData, _error, port, client, flowOptions, verifyUrl1, verifyResponse1, verifyData1, error;
576
+ var allowLoopback, issuer, _this_resolveUrls, serverBaseUrl, resource, storeKey, dcrTokenKey, tokens, verifyUrl, verifyResponse, verifyData, _error, port, client, flowOptions, verifyUrl1, verifyResponse1, verifyData1, error;
549
577
  return _ts_generator(this, function(_state) {
550
578
  switch(_state.label){
551
579
  case 0:
552
580
  // Loopback trust for every discovery-derived fetch below, computed from
553
581
  // the server we're talking to, never from capabilities' endpoints (see discovery-fetch.ts).
554
- allowLoopback = (0, _discoveryfetchts.isLoopbackUrl)(baseUrl);
582
+ allowLoopback = (0, _discoveryfetchts.isLoopbackUrl)(mcpServerUrl);
555
583
  issuer = requireIssuer(capabilities);
556
- resource = (0, _urlutilsts.normalizeUrl)(baseUrl);
557
- dcrTokenKey = "dcr-tokens:".concat(issuer, ":").concat(resource);
584
+ _this_resolveUrls = this.resolveUrls(mcpServerUrl, capabilities), serverBaseUrl = _this_resolveUrls.serverBaseUrl, resource = _this_resolveUrls.resource, storeKey = _this_resolveUrls.storeKey;
585
+ dcrTokenKey = "dcr-tokens:".concat(issuer, ":").concat(storeKey);
558
586
  return [
559
587
  4,
560
588
  this.loadTokens(dcrTokenKey, issuer)
@@ -573,7 +601,7 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
573
601
  ,
574
602
  7
575
603
  ]);
576
- verifyUrl = "".concat(baseUrl, "/oauth/verify");
604
+ verifyUrl = "".concat(serverBaseUrl, "/oauth/verify");
577
605
  return [
578
606
  4,
579
607
  fetch(verifyUrl, {
@@ -659,7 +687,7 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
659
687
  ,
660
688
  16
661
689
  ]);
662
- verifyUrl1 = "".concat(baseUrl, "/oauth/verify");
690
+ verifyUrl1 = "".concat(serverBaseUrl, "/oauth/verify");
663
691
  return [
664
692
  4,
665
693
  fetch(verifyUrl1, {
@@ -711,17 +739,17 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
711
739
  });
712
740
  }).call(this);
713
741
  };
714
- /** Handles authentication for external (non-self-hosted) OAuth providers. */ _proto.ensureAuthenticatedExternal = function ensureAuthenticatedExternal(baseUrl, capabilities) {
742
+ /** Handles authentication for external (non-self-hosted) OAuth providers. */ _proto.ensureAuthenticatedExternal = function ensureAuthenticatedExternal(mcpServerUrl, capabilities) {
715
743
  return _async_to_generator(function() {
716
- var allowLoopback, issuer, resource, tokenKey, tokens, _error, port, client, flowOptions;
744
+ var allowLoopback, issuer, _this_resolveUrls, resource, storeKey, tokenKey, tokens, _error, port, client, flowOptions;
717
745
  return _ts_generator(this, function(_state) {
718
746
  switch(_state.label){
719
747
  case 0:
720
748
  // See ensureAuthenticatedSelfHosted - same loopback trust rule.
721
- allowLoopback = (0, _discoveryfetchts.isLoopbackUrl)(baseUrl);
749
+ allowLoopback = (0, _discoveryfetchts.isLoopbackUrl)(mcpServerUrl);
722
750
  issuer = requireIssuer(capabilities);
723
- resource = (0, _urlutilsts.normalizeUrl)(baseUrl);
724
- tokenKey = "tokens:".concat(issuer, ":").concat(resource);
751
+ _this_resolveUrls = this.resolveUrls(mcpServerUrl, capabilities), resource = _this_resolveUrls.resource, storeKey = _this_resolveUrls.storeKey;
752
+ tokenKey = "tokens:".concat(issuer, ":").concat(storeKey);
725
753
  return [
726
754
  4,
727
755
  this.loadTokens(tokenKey, issuer)
@@ -866,14 +894,19 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
866
894
  };
867
895
  /**
868
896
  * Deletes both stored token families for a server, across every issuer they were bound to.
897
+ *
898
+ * Takes the same `mcpServerUrl` that {@link DcrAuthenticator.ensureAuthenticated}
899
+ * was given - keys are built from the configured URL, never from the discovered
900
+ * RFC 8707 resource, precisely so this can find them without doing discovery.
901
+ *
869
902
  * @throws CredentialBindingError if the configured store cannot enumerate keys.
870
- */ _proto.deleteTokens = function deleteTokens(baseUrl) {
903
+ */ _proto.deleteTokens = function deleteTokens(mcpServerUrl) {
871
904
  return _async_to_generator(function() {
872
905
  var suffix, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, _value1, key, err;
873
906
  return _ts_generator(this, function(_state) {
874
907
  switch(_state.label){
875
908
  case 0:
876
- suffix = ":".concat((0, _urlutilsts.normalizeUrl)(baseUrl));
909
+ suffix = ":".concat((0, _urlutilsts.normalizeUrl)(mcpServerUrl));
877
910
  if (!this.tokenStore.iterator) {
878
911
  throw new CredentialBindingError('Token store does not support key enumeration, which issuer-keyed credentials require');
879
912
  }
@@ -965,7 +998,7 @@ var DcrAuthenticator = /*#__PURE__*/ function() {
965
998
  7
966
999
  ];
967
1000
  case 13:
968
- this.logger.debug("\uD83D\uDDD1ī¸ Deleted tokens for ".concat(baseUrl));
1001
+ this.logger.debug("\uD83D\uDDD1ī¸ Deleted tokens for ".concat(mcpServerUrl));
969
1002
  return [
970
1003
  2
971
1004
  ];