@earendil-works/pi-mcp 0.99.2 → 1.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.0] - 2026-10-01
4
+
5
+ ### Added
6
+
7
+ - Added an `authorizationServerMetadataUrl` option to `authorizeMcp()` to use a configured authorization server metadata document instead of discovery ([#10172](https://github.com/earendil-works/pi/issues/10172)).
8
+ - Added an `iss` option to `authorizeMcp()`. The authorization code is only exchanged when `iss` names the flow's authorization server, or is absent and the server's metadata does not set `authorization_response_iss_parameter_supported` (RFC 9207).
9
+ - Added `stepUpScope()`, which combines the scopes of an `insufficient_scope` challenge with the scopes granted so far.
10
+
11
+ ### Fixed
12
+
13
+ - Fixed OAuth token and client registration responses with an empty or `null` optional field (such as `"scope": ""`) failing with `Invalid scope` and similar errors; such fields are now treated as absent ([#10266](https://github.com/earendil-works/pi/issues/10266)).
14
+ - Fixed `expires_in: null` in a token response marking the access token as already expired.
15
+ - Fixed invalid URLs in protected resource metadata aborting OAuth discovery instead of falling back to the MCP server's origin.
16
+ - Fixed an empty requested scope, from `scope=""` in a `WWW-Authenticate` challenge or an empty `scopes_supported`, overriding the next scope source.
17
+ - Fixed list pagination failing with a duplicate cursor error when a server ends pagination with `nextCursor: ""` or `null`.
18
+ - Fixed step-up authorization in `adaptOAuthProvider()` requesting only the scopes of the `insufficient_scope` challenge. The new token lost the scopes granted before, so other requests failed with `insufficient_scope` again. Tokens now record their granted scope, which is the requested scope when the token response omits `scope`.
19
+
3
20
  ## [0.99.2] - 2026-09-30
4
21
 
5
22
  ### Fixed
package/dist/client.js CHANGED
@@ -26,10 +26,11 @@ function validateListPage(method, key, value, isItem) {
26
26
  if (!isObject(item) || !isItem(item))
27
27
  throw invalid(`Invalid entry in MCP ${method} result`);
28
28
  }
29
- if (value.nextCursor !== undefined && typeof value.nextCursor !== "string") {
29
+ // Some servers end pagination with `null` or `""` instead of omitting the cursor.
30
+ const nextCursor = value.nextCursor === null || value.nextCursor === "" ? undefined : value.nextCursor;
31
+ if (nextCursor !== undefined && typeof nextCursor !== "string")
30
32
  throw invalid(`Invalid MCP ${method} cursor`);
31
- }
32
- return { items, ...(value.nextCursor === undefined ? {} : { nextCursor: value.nextCursor }) };
33
+ return { items, ...(nextCursor === undefined ? {} : { nextCursor }) };
33
34
  }
34
35
  const isTool = (tool) => typeof tool.name === "string" && isObject(tool.inputSchema);
35
36
  // `name` is required by the spec, but some servers omit it; the URI stands in.
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CallToolResult } from \"./protocol/content.ts\";\nimport {\n\tisJsonRpcId,\n\tisJsonRpcNotification,\n\tisJsonRpcRequest,\n\tisJsonRpcResponse,\n\tisObject,\n\tJSON_RPC_ERROR_CODES,\n\ttype JsonRpcId,\n\ttype JsonRpcMessage,\n\ttype JsonRpcRequest,\n\ttype JsonRpcResponse,\n\tMcpAbortError,\n\tMcpConnectionClosedError,\n\tMcpError,\n\tMcpTimeoutError,\n\ttoError,\n} from \"./protocol/jsonrpc.ts\";\nimport {\n\ttype ClientCapabilities,\n\ttype Implementation,\n\ttype InitializeResult,\n\tLATEST_PROTOCOL_VERSION,\n\ttype ListResourcesResult,\n\ttype ListResourceTemplatesResult,\n\ttype ProgressNotification,\n\ttype ReadResourceResult,\n\ttype Resource,\n\ttype ResourceTemplate,\n\ttype Root,\n\ttype ServerCapabilities,\n\tSUPPORTED_PROTOCOL_VERSIONS,\n\ttype SupportedProtocolVersion,\n\ttype Tool,\n} from \"./protocol/types.ts\";\nimport type { McpTransport } from \"./transports/transport.ts\";\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\nconst MAX_LIST_PAGES = 1_000;\n\ntype ClientState = \"idle\" | \"connecting\" | \"connected\" | \"closed\";\ntype NotificationListener = (params: unknown) => void;\ntype ErrorListener = (error: Error) => void;\ntype CloseListener = () => void;\ntype RequestHandler = (params: unknown, context: { signal: AbortSignal }) => unknown | Promise<unknown>;\n\nexport interface McpClientOptions extends Implementation {\n\tcapabilities?: ClientCapabilities;\n\tprotocolVersion?: SupportedProtocolVersion;\n\trequestTimeoutMs?: number;\n\troots?: readonly Root[] | (() => readonly Root[] | Promise<readonly Root[]>);\n}\n\nexport interface McpRequestOptions {\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n\tonProgress?: (progress: ProgressNotification) => void;\n}\n\ninterface PendingRequest {\n\tresolve: (value: unknown) => void;\n\treject: (reason: unknown) => void;\n\ttimeoutMs: number;\n\ttimer: ReturnType<typeof setTimeout> | undefined;\n\tsignal: AbortSignal | undefined;\n\tonAbort: () => void;\n\tcancellable: boolean;\n\tonProgress: ((progress: ProgressNotification) => void) | undefined;\n\tprogressToken: JsonRpcId | undefined;\n}\n\nfunction validateInitializeResult(value: unknown): InitializeResult {\n\tif (\n\t\t!isObject(value) ||\n\t\ttypeof value.protocolVersion !== \"string\" ||\n\t\t!isObject(value.capabilities) ||\n\t\t!isObject(value.serverInfo) ||\n\t\ttypeof value.serverInfo.name !== \"string\" ||\n\t\ttypeof value.serverInfo.version !== \"string\" ||\n\t\t(value.instructions !== undefined && typeof value.instructions !== \"string\")\n\t) {\n\t\tthrow new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Invalid MCP initialize result\");\n\t}\n\treturn value as unknown as InitializeResult;\n}\n\nfunction invalid(message: string): McpError {\n\treturn new McpError(JSON_RPC_ERROR_CODES.invalidRequest, message);\n}\n\n/** One page of a paginated list: the items under `key`, each checked by `isItem`. */\nfunction validateListPage(\n\tmethod: string,\n\tkey: string,\n\tvalue: unknown,\n\tisItem: (item: Record<string, unknown>) => boolean,\n): { items: Record<string, unknown>[]; nextCursor?: string } {\n\tconst items = isObject(value) ? value[key] : undefined;\n\tif (!isObject(value) || !Array.isArray(items)) throw invalid(`Invalid MCP ${method} result`);\n\tfor (const item of items) {\n\t\tif (!isObject(item) || !isItem(item)) throw invalid(`Invalid entry in MCP ${method} result`);\n\t}\n\tif (value.nextCursor !== undefined && typeof value.nextCursor !== \"string\") {\n\t\tthrow invalid(`Invalid MCP ${method} cursor`);\n\t}\n\treturn { items, ...(value.nextCursor === undefined ? {} : { nextCursor: value.nextCursor }) };\n}\n\nconst isTool = (tool: Record<string, unknown>) => typeof tool.name === \"string\" && isObject(tool.inputSchema);\n// `name` is required by the spec, but some servers omit it; the URI stands in.\nconst isResource = (resource: Record<string, unknown>) =>\n\ttypeof resource.uri === \"string\" && (resource.name === undefined || typeof resource.name === \"string\");\nconst isResourceTemplate = (template: Record<string, unknown>) =>\n\ttypeof template.uriTemplate === \"string\" && (template.name === undefined || typeof template.name === \"string\");\n\nfunction toResource(item: Record<string, unknown>): Resource {\n\treturn { ...item, name: item.name ?? item.uri } as Resource;\n}\n\nfunction toResourceTemplate(item: Record<string, unknown>): ResourceTemplate {\n\treturn { ...item, name: item.name ?? item.uriTemplate } as ResourceTemplate;\n}\n\nfunction pageCursor(page: { nextCursor?: string }): { nextCursor?: string } {\n\treturn page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor };\n}\n\nfunction validateReadResourceResult(value: unknown): ReadResourceResult {\n\tif (!isObject(value) || !Array.isArray(value.contents)) throw invalid(\"Invalid MCP resources/read result\");\n\tfor (const contents of value.contents) {\n\t\tif (\n\t\t\t!isObject(contents) ||\n\t\t\ttypeof contents.uri !== \"string\" ||\n\t\t\t(typeof contents.text !== \"string\" && typeof contents.blob !== \"string\")\n\t\t) {\n\t\t\tthrow invalid(\"Invalid contents in MCP resources/read result\");\n\t\t}\n\t}\n\treturn value as unknown as ReadResourceResult;\n}\n\n/** `content` is required by the spec, but servers that only return `structuredContent` omit it (the SDK defaults it too). */\nfunction validateCallToolResult(value: unknown): CallToolResult {\n\tif (!isObject(value) || (value.content !== undefined && !Array.isArray(value.content))) {\n\t\tthrow new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Invalid MCP tools/call result\");\n\t}\n\tif (value.structuredContent !== undefined && !isObject(value.structuredContent)) {\n\t\tthrow new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Invalid MCP tools/call structured content\");\n\t}\n\treturn (value.content === undefined ? { ...value, content: [] } : value) as unknown as CallToolResult;\n}\n\nexport class McpClient {\n\treadonly options: Readonly<McpClientOptions>;\n\tprivate state: ClientState = \"idle\";\n\tprivate transport: McpTransport | undefined;\n\tprivate nextRequestId = 1;\n\tprivate serverInfoValue: Implementation | undefined;\n\tprivate serverCapabilitiesValue: ServerCapabilities | undefined;\n\tprivate instructionsValue: string | undefined;\n\tprivate protocolVersionValue: string | undefined;\n\tprivate pending = new Map<JsonRpcId, PendingRequest>();\n\tprivate progressRequests = new Map<JsonRpcId, JsonRpcId>();\n\tprivate incoming = new Map<JsonRpcId, AbortController>();\n\tprivate requestHandlers = new Map<string, RequestHandler>();\n\tprivate notificationListeners = new Map<string, Set<NotificationListener>>();\n\tprivate errorListeners = new Set<ErrorListener>();\n\tprivate closeListeners = new Set<CloseListener>();\n\tprivate disposers: (() => void)[] = [];\n\n\tconstructor(options: McpClientOptions) {\n\t\tthis.options = Object.freeze({ ...options });\n\t\tthis.requestHandlers.set(\"ping\", () => ({}));\n\t\tconst roots = options.roots;\n\t\tif (roots) {\n\t\t\tthis.requestHandlers.set(\"roots/list\", async () => ({\n\t\t\t\troots: [...(typeof roots === \"function\" ? await roots() : roots)],\n\t\t\t}));\n\t\t}\n\t}\n\n\tget connectionState(): ClientState {\n\t\treturn this.state;\n\t}\n\n\tget serverInfo(): Implementation | undefined {\n\t\treturn this.serverInfoValue;\n\t}\n\n\tget serverCapabilities(): ServerCapabilities | undefined {\n\t\treturn this.serverCapabilitiesValue;\n\t}\n\n\tget instructions(): string | undefined {\n\t\treturn this.instructionsValue;\n\t}\n\n\tget protocolVersion(): string | undefined {\n\t\treturn this.protocolVersionValue;\n\t}\n\n\tasync connect(transport: McpTransport): Promise<InitializeResult> {\n\t\tif (this.state !== \"idle\") throw new Error(`Cannot connect MCP client in ${this.state} state`);\n\t\tthis.state = \"connecting\";\n\t\tthis.transport = transport;\n\t\tthis.disposers = [\n\t\t\ttransport.onMessage((message) => this.handleMessage(message)),\n\t\t\t// Transport errors are reported only. Pending requests fail when the transport closes.\n\t\t\ttransport.onError((error) => this.emitError(error)),\n\t\t\ttransport.onClose(() => this.handleTransportClose()),\n\t\t];\n\n\t\ttry {\n\t\t\tawait transport.start();\n\t\t\tconst capabilities: ClientCapabilities = { ...this.options.capabilities };\n\t\t\tif (this.options.roots && capabilities.roots === undefined) capabilities.roots = {};\n\t\t\tconst result = validateInitializeResult(\n\t\t\t\tawait this.requestInternal(\n\t\t\t\t\t\"initialize\",\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocolVersion: this.options.protocolVersion ?? LATEST_PROTOCOL_VERSION,\n\t\t\t\t\t\tcapabilities,\n\t\t\t\t\t\tclientInfo: {\n\t\t\t\t\t\t\tname: this.options.name,\n\t\t\t\t\t\t\tversion: this.options.version,\n\t\t\t\t\t\t\t...(this.options.title === undefined ? {} : { title: this.options.title }),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{},\n\t\t\t\t\ttrue,\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (!(SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(result.protocolVersion)) {\n\t\t\t\tthrow new Error(`MCP server selected unsupported protocol version ${result.protocolVersion}`);\n\t\t\t}\n\t\t\tthis.protocolVersionValue = result.protocolVersion;\n\t\t\tthis.serverInfoValue = result.serverInfo;\n\t\t\tthis.serverCapabilitiesValue = result.capabilities;\n\t\t\tthis.instructionsValue = result.instructions;\n\t\t\ttransport.setProtocolVersion?.(result.protocolVersion);\n\t\t\tawait this.notifyInternal(\"notifications/initialized\", undefined, true);\n\t\t\tthis.state = \"connected\";\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tawait this.close().catch(() => {});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\trequest<Result = unknown>(\n\t\tmethod: string,\n\t\tparams?: Record<string, unknown>,\n\t\toptions: McpRequestOptions = {},\n\t): Promise<Result> {\n\t\treturn this.requestInternal(method, params, options, false) as Promise<Result>;\n\t}\n\n\tnotify(method: string, params?: Record<string, unknown>): Promise<void> {\n\t\treturn this.notifyInternal(method, params, false);\n\t}\n\n\tsetRequestHandler(method: string, handler: RequestHandler): () => void {\n\t\tthis.requestHandlers.set(method, handler);\n\t\treturn () => {\n\t\t\tif (this.requestHandlers.get(method) === handler) this.requestHandlers.delete(method);\n\t\t};\n\t}\n\n\tonNotification(method: string, listener: NotificationListener): () => void {\n\t\tconst listeners = this.notificationListeners.get(method) ?? new Set<NotificationListener>();\n\t\tthis.notificationListeners.set(method, listeners);\n\t\tlisteners.add(listener);\n\t\treturn () => {\n\t\t\tlisteners.delete(listener);\n\t\t\tif (listeners.size === 0) this.notificationListeners.delete(method);\n\t\t};\n\t}\n\n\tonError(listener: ErrorListener): () => void {\n\t\tthis.errorListeners.add(listener);\n\t\treturn () => this.errorListeners.delete(listener);\n\t}\n\n\t/** Called once when the connection closes, whether the transport dropped or `close()` was called. */\n\tonClose(listener: CloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tasync ping(options: McpRequestOptions = {}): Promise<void> {\n\t\tawait this.request(\"ping\", undefined, options);\n\t}\n\n\tasync listTools(options: McpRequestOptions = {}): Promise<Tool[]> {\n\t\treturn (await this.listAll(\"tools/list\", \"tools\", isTool, options)) as unknown as Tool[];\n\t}\n\n\t/** Every resource, following `nextCursor` through all pages. */\n\tasync listResources(options: McpRequestOptions = {}): Promise<Resource[]> {\n\t\treturn (await this.listAll(\"resources/list\", \"resources\", isResource, options)).map(toResource);\n\t}\n\n\t/** One page of resources, starting at `cursor`. */\n\tasync listResourcesPage(cursor?: string, options: McpRequestOptions = {}): Promise<ListResourcesResult> {\n\t\tconst page = await this.listPage(\"resources/list\", \"resources\", isResource, cursor, options);\n\t\treturn { resources: page.items.map(toResource), ...pageCursor(page) };\n\t}\n\n\t/** Every resource template, following `nextCursor` through all pages. */\n\tasync listResourceTemplates(options: McpRequestOptions = {}): Promise<ResourceTemplate[]> {\n\t\tconst templates = await this.listAll(\n\t\t\t\"resources/templates/list\",\n\t\t\t\"resourceTemplates\",\n\t\t\tisResourceTemplate,\n\t\t\toptions,\n\t\t);\n\t\treturn templates.map(toResourceTemplate);\n\t}\n\n\t/** One page of resource templates, starting at `cursor`. */\n\tasync listResourceTemplatesPage(\n\t\tcursor?: string,\n\t\toptions: McpRequestOptions = {},\n\t): Promise<ListResourceTemplatesResult> {\n\t\tconst page = await this.listPage(\n\t\t\t\"resources/templates/list\",\n\t\t\t\"resourceTemplates\",\n\t\t\tisResourceTemplate,\n\t\t\tcursor,\n\t\t\toptions,\n\t\t);\n\t\treturn { resourceTemplates: page.items.map(toResourceTemplate), ...pageCursor(page) };\n\t}\n\n\tasync readResource(uri: string, options: McpRequestOptions = {}): Promise<ReadResourceResult> {\n\t\treturn validateReadResourceResult(await this.request(\"resources/read\", { uri }, options));\n\t}\n\n\tprivate async listPage(\n\t\tmethod: string,\n\t\tkey: string,\n\t\tisItem: (item: Record<string, unknown>) => boolean,\n\t\tcursor: string | undefined,\n\t\toptions: McpRequestOptions,\n\t): Promise<{ items: Record<string, unknown>[]; nextCursor?: string }> {\n\t\treturn validateListPage(\n\t\t\tmethod,\n\t\t\tkey,\n\t\t\tawait this.request(method, cursor === undefined ? undefined : { cursor }, options),\n\t\t\tisItem,\n\t\t);\n\t}\n\n\t/** Every item of a paginated list method. */\n\tprivate async listAll(\n\t\tmethod: string,\n\t\tkey: string,\n\t\tisItem: (item: Record<string, unknown>) => boolean,\n\t\toptions: McpRequestOptions,\n\t): Promise<Record<string, unknown>[]> {\n\t\tconst items: Record<string, unknown>[] = [];\n\t\tconst cursors = new Set<string>();\n\t\tlet cursor: string | undefined;\n\t\tfor (let pageNumber = 0; pageNumber < MAX_LIST_PAGES; pageNumber++) {\n\t\t\tconst page = await this.listPage(method, key, isItem, cursor, options);\n\t\t\titems.push(...page.items);\n\t\t\tif (page.nextCursor === undefined) return items;\n\t\t\tif (cursors.has(page.nextCursor))\n\t\t\t\tthrow new Error(`MCP ${method} returned duplicate cursor: ${page.nextCursor}`);\n\t\t\tcursors.add(page.nextCursor);\n\t\t\tcursor = page.nextCursor;\n\t\t}\n\t\tthrow new Error(`MCP ${method} exceeded ${MAX_LIST_PAGES} pages`);\n\t}\n\n\tasync callTool(\n\t\tname: string,\n\t\targs?: Record<string, unknown>,\n\t\toptions: McpRequestOptions = {},\n\t): Promise<CallToolResult> {\n\t\treturn validateCallToolResult(\n\t\t\tawait this.request(\"tools/call\", { name, ...(args === undefined ? {} : { arguments: args }) }, options),\n\t\t);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tconst transport = this.transport;\n\t\tthis.transport = undefined;\n\t\tthis.disposeTransportListeners();\n\t\tthis.markClosed(new McpConnectionClosedError());\n\t\tawait transport?.close();\n\t}\n\n\tprivate async requestInternal(\n\t\tmethod: string,\n\t\tparams: Record<string, unknown> | undefined,\n\t\toptions: McpRequestOptions,\n\t\tallowConnecting: boolean,\n\t): Promise<unknown> {\n\t\tconst transport = this.requireTransport(allowConnecting);\n\t\tif (options.signal?.aborted) throw new McpAbortError();\n\t\tconst id = this.nextRequestId++;\n\t\tconst progressToken = options.onProgress ? id : undefined;\n\t\tconst requestParams =\n\t\t\tprogressToken === undefined\n\t\t\t\t? params\n\t\t\t\t: { ...params, _meta: { ...(isObject(params?._meta) ? params._meta : {}), progressToken } };\n\t\tconst message: JsonRpcRequest = {\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tid,\n\t\t\tmethod,\n\t\t\t...(requestParams === undefined ? {} : { params: requestParams }),\n\t\t};\n\t\treturn new Promise<unknown>((resolve, reject) => {\n\t\t\tconst entry: PendingRequest = {\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t\ttimeoutMs: options.timeoutMs ?? this.options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,\n\t\t\t\ttimer: undefined,\n\t\t\t\tsignal: options.signal,\n\t\t\t\t// The spec forbids cancelling `initialize`.\n\t\t\t\tonAbort: () =>\n\t\t\t\t\tthis.cancelPending(\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tnew McpAbortError(),\n\t\t\t\t\t\tmethod !== \"initialize\",\n\t\t\t\t\t\tString(options.signal?.reason ?? \"Aborted\"),\n\t\t\t\t\t),\n\t\t\t\tcancellable: method !== \"initialize\",\n\t\t\t\tonProgress: options.onProgress,\n\t\t\t\tprogressToken,\n\t\t\t};\n\t\t\tthis.pending.set(id, entry);\n\t\t\tif (progressToken !== undefined) this.progressRequests.set(progressToken, id);\n\t\t\toptions.signal?.addEventListener(\"abort\", entry.onAbort, { once: true });\n\t\t\tthis.armTimeout(id, entry);\n\t\t\ttransport.send(message).catch((error) => this.cancelPending(id, error, false));\n\t\t});\n\t}\n\n\tprivate async notifyInternal(\n\t\tmethod: string,\n\t\tparams: Record<string, unknown> | undefined,\n\t\tallowConnecting: boolean,\n\t): Promise<void> {\n\t\tawait this.requireTransport(allowConnecting).send({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tmethod,\n\t\t\t...(params === undefined ? {} : { params }),\n\t\t});\n\t}\n\n\tprivate requireTransport(allowConnecting: boolean): McpTransport {\n\t\tif (this.transport && (this.state === \"connected\" || (allowConnecting && this.state === \"connecting\"))) {\n\t\t\treturn this.transport;\n\t\t}\n\t\tthrow new McpConnectionClosedError(`MCP client is ${this.state}`);\n\t}\n\n\tprivate handleMessage(message: JsonRpcMessage): void {\n\t\tif (isJsonRpcResponse(message)) {\n\t\t\tthis.handleResponse(message);\n\t\t\treturn;\n\t\t}\n\t\tif (isJsonRpcRequest(message)) {\n\t\t\tvoid this.handleRequest(message);\n\t\t\treturn;\n\t\t}\n\t\tif (isJsonRpcNotification(message)) {\n\t\t\tthis.handleNotification(message.method, message.params);\n\t\t\treturn;\n\t\t}\n\t\tthis.emitError(new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Received invalid JSON-RPC message\"));\n\t}\n\n\tprivate handleResponse(message: JsonRpcResponse): void {\n\t\tconst entry = this.pending.get(message.id);\n\t\tif (!entry) {\n\t\t\tthis.emitError(new Error(`Received response for unknown MCP request ${String(message.id)}`));\n\t\t\treturn;\n\t\t}\n\t\tthis.removePending(message.id, entry);\n\t\tif (\"error\" in message) entry.reject(new McpError(message.error.code, message.error.message, message.error.data));\n\t\telse entry.resolve(message.result);\n\t}\n\n\tprivate async handleRequest(message: JsonRpcRequest): Promise<void> {\n\t\tconst transport = this.transport;\n\t\tif (!transport) return;\n\t\tconst handler = this.requestHandlers.get(message.method);\n\t\tif (!handler) {\n\t\t\tawait transport\n\t\t\t\t.send({\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\tid: message.id,\n\t\t\t\t\terror: { code: JSON_RPC_ERROR_CODES.methodNotFound, message: `Method not found: ${message.method}` },\n\t\t\t\t})\n\t\t\t\t.catch((error) => this.emitError(error));\n\t\t\treturn;\n\t\t}\n\t\tconst controller = new AbortController();\n\t\tthis.incoming.set(message.id, controller);\n\t\ttry {\n\t\t\tconst result = await handler(message.params, { signal: controller.signal });\n\t\t\tawait transport.send({ jsonrpc: \"2.0\", id: message.id, result: result ?? {} });\n\t\t} catch (error) {\n\t\t\tconst responseError =\n\t\t\t\terror instanceof McpError\n\t\t\t\t\t? { code: error.code, message: error.message, data: error.data }\n\t\t\t\t\t: { code: JSON_RPC_ERROR_CODES.internalError, message: toError(error).message };\n\t\t\tawait transport\n\t\t\t\t.send({ jsonrpc: \"2.0\", id: message.id, error: responseError })\n\t\t\t\t.catch((sendError) => this.emitError(sendError));\n\t\t} finally {\n\t\t\tthis.incoming.delete(message.id);\n\t\t}\n\t}\n\n\tprivate handleNotification(method: string, params: unknown): void {\n\t\tif (method === \"notifications/progress\") this.handleProgress(params);\n\t\telse if (method === \"notifications/cancelled\") this.handleCancelled(params);\n\t\tfor (const listener of this.notificationListeners.get(method) ?? []) {\n\t\t\ttry {\n\t\t\t\tlistener(params);\n\t\t\t} catch (error) {\n\t\t\t\tthis.emitError(error);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleProgress(params: unknown): void {\n\t\tif (!isObject(params) || !isJsonRpcId(params.progressToken) || typeof params.progress !== \"number\") return;\n\t\tconst requestId = this.progressRequests.get(params.progressToken);\n\t\tconst entry = requestId === undefined ? undefined : this.pending.get(requestId);\n\t\tif (requestId === undefined || !entry) return;\n\t\tthis.armTimeout(requestId, entry);\n\t\ttry {\n\t\t\tentry.onProgress?.(params as unknown as ProgressNotification);\n\t\t} catch (error) {\n\t\t\tthis.emitError(error);\n\t\t}\n\t}\n\n\tprivate handleCancelled(params: unknown): void {\n\t\tif (isObject(params) && isJsonRpcId(params.requestId)) this.incoming.get(params.requestId)?.abort(params.reason);\n\t}\n\n\tprivate armTimeout(id: JsonRpcId, entry: PendingRequest): void {\n\t\tif (entry.timer) clearTimeout(entry.timer);\n\t\tif (!Number.isFinite(entry.timeoutMs) || entry.timeoutMs <= 0) return;\n\t\tentry.timer = setTimeout(() => {\n\t\t\tthis.cancelPending(id, new McpTimeoutError(entry.timeoutMs), entry.cancellable, \"Request timed out\");\n\t\t}, entry.timeoutMs);\n\t}\n\n\tprivate cancelPending(id: JsonRpcId, error: unknown, notifyServer: boolean, reason?: string): void {\n\t\tconst entry = this.pending.get(id);\n\t\tif (!entry) return;\n\t\tthis.removePending(id, entry);\n\t\tentry.reject(error);\n\t\tif (notifyServer && this.transport) {\n\t\t\tvoid this.transport\n\t\t\t\t.send({\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\tmethod: \"notifications/cancelled\",\n\t\t\t\t\tparams: { requestId: id, ...(reason ? { reason } : {}) },\n\t\t\t\t})\n\t\t\t\t.catch((sendError) => this.emitError(sendError));\n\t\t}\n\t}\n\n\tprivate removePending(id: JsonRpcId, entry: PendingRequest): void {\n\t\tthis.pending.delete(id);\n\t\tif (entry.timer) clearTimeout(entry.timer);\n\t\tif (entry.progressToken !== undefined) this.progressRequests.delete(entry.progressToken);\n\t\tentry.signal?.removeEventListener(\"abort\", entry.onAbort);\n\t}\n\n\tprivate rejectPending(error: unknown): void {\n\t\tfor (const [id, entry] of this.pending) {\n\t\t\tthis.removePending(id, entry);\n\t\t\tentry.reject(error);\n\t\t}\n\t}\n\n\tprivate handleTransportClose(): void {\n\t\tthis.markClosed(new McpConnectionClosedError());\n\t}\n\n\t/** Idempotent: rejects in-flight requests, aborts server requests we are serving, and flips the state. */\n\tprivate markClosed(error: Error): void {\n\t\tconst wasClosed = this.state === \"closed\";\n\t\tthis.state = \"closed\";\n\t\tthis.rejectPending(error);\n\t\tfor (const controller of this.incoming.values()) controller.abort(error);\n\t\tthis.incoming.clear();\n\t\tif (wasClosed) return;\n\t\tfor (const listener of [...this.closeListeners]) {\n\t\t\ttry {\n\t\t\t\tlistener();\n\t\t\t} catch (listenerError) {\n\t\t\t\tthis.emitError(listenerError);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate emitError(error: unknown): void {\n\t\tconst normalized = toError(error);\n\t\tfor (const listener of this.errorListeners) listener(normalized);\n\t}\n\n\tprivate disposeTransportListeners(): void {\n\t\tfor (const dispose of this.disposers.splice(0)) dispose();\n\t}\n}\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CallToolResult } from \"./protocol/content.ts\";\nimport {\n\tisJsonRpcId,\n\tisJsonRpcNotification,\n\tisJsonRpcRequest,\n\tisJsonRpcResponse,\n\tisObject,\n\tJSON_RPC_ERROR_CODES,\n\ttype JsonRpcId,\n\ttype JsonRpcMessage,\n\ttype JsonRpcRequest,\n\ttype JsonRpcResponse,\n\tMcpAbortError,\n\tMcpConnectionClosedError,\n\tMcpError,\n\tMcpTimeoutError,\n\ttoError,\n} from \"./protocol/jsonrpc.ts\";\nimport {\n\ttype ClientCapabilities,\n\ttype Implementation,\n\ttype InitializeResult,\n\tLATEST_PROTOCOL_VERSION,\n\ttype ListResourcesResult,\n\ttype ListResourceTemplatesResult,\n\ttype ProgressNotification,\n\ttype ReadResourceResult,\n\ttype Resource,\n\ttype ResourceTemplate,\n\ttype Root,\n\ttype ServerCapabilities,\n\tSUPPORTED_PROTOCOL_VERSIONS,\n\ttype SupportedProtocolVersion,\n\ttype Tool,\n} from \"./protocol/types.ts\";\nimport type { McpTransport } from \"./transports/transport.ts\";\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\nconst MAX_LIST_PAGES = 1_000;\n\ntype ClientState = \"idle\" | \"connecting\" | \"connected\" | \"closed\";\ntype NotificationListener = (params: unknown) => void;\ntype ErrorListener = (error: Error) => void;\ntype CloseListener = () => void;\ntype RequestHandler = (params: unknown, context: { signal: AbortSignal }) => unknown | Promise<unknown>;\n\nexport interface McpClientOptions extends Implementation {\n\tcapabilities?: ClientCapabilities;\n\tprotocolVersion?: SupportedProtocolVersion;\n\trequestTimeoutMs?: number;\n\troots?: readonly Root[] | (() => readonly Root[] | Promise<readonly Root[]>);\n}\n\nexport interface McpRequestOptions {\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n\tonProgress?: (progress: ProgressNotification) => void;\n}\n\ninterface PendingRequest {\n\tresolve: (value: unknown) => void;\n\treject: (reason: unknown) => void;\n\ttimeoutMs: number;\n\ttimer: ReturnType<typeof setTimeout> | undefined;\n\tsignal: AbortSignal | undefined;\n\tonAbort: () => void;\n\tcancellable: boolean;\n\tonProgress: ((progress: ProgressNotification) => void) | undefined;\n\tprogressToken: JsonRpcId | undefined;\n}\n\nfunction validateInitializeResult(value: unknown): InitializeResult {\n\tif (\n\t\t!isObject(value) ||\n\t\ttypeof value.protocolVersion !== \"string\" ||\n\t\t!isObject(value.capabilities) ||\n\t\t!isObject(value.serverInfo) ||\n\t\ttypeof value.serverInfo.name !== \"string\" ||\n\t\ttypeof value.serverInfo.version !== \"string\" ||\n\t\t(value.instructions !== undefined && typeof value.instructions !== \"string\")\n\t) {\n\t\tthrow new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Invalid MCP initialize result\");\n\t}\n\treturn value as unknown as InitializeResult;\n}\n\nfunction invalid(message: string): McpError {\n\treturn new McpError(JSON_RPC_ERROR_CODES.invalidRequest, message);\n}\n\n/** One page of a paginated list: the items under `key`, each checked by `isItem`. */\nfunction validateListPage(\n\tmethod: string,\n\tkey: string,\n\tvalue: unknown,\n\tisItem: (item: Record<string, unknown>) => boolean,\n): { items: Record<string, unknown>[]; nextCursor?: string } {\n\tconst items = isObject(value) ? value[key] : undefined;\n\tif (!isObject(value) || !Array.isArray(items)) throw invalid(`Invalid MCP ${method} result`);\n\tfor (const item of items) {\n\t\tif (!isObject(item) || !isItem(item)) throw invalid(`Invalid entry in MCP ${method} result`);\n\t}\n\t// Some servers end pagination with `null` or `\"\"` instead of omitting the cursor.\n\tconst nextCursor = value.nextCursor === null || value.nextCursor === \"\" ? undefined : value.nextCursor;\n\tif (nextCursor !== undefined && typeof nextCursor !== \"string\") throw invalid(`Invalid MCP ${method} cursor`);\n\treturn { items, ...(nextCursor === undefined ? {} : { nextCursor }) };\n}\n\nconst isTool = (tool: Record<string, unknown>) => typeof tool.name === \"string\" && isObject(tool.inputSchema);\n// `name` is required by the spec, but some servers omit it; the URI stands in.\nconst isResource = (resource: Record<string, unknown>) =>\n\ttypeof resource.uri === \"string\" && (resource.name === undefined || typeof resource.name === \"string\");\nconst isResourceTemplate = (template: Record<string, unknown>) =>\n\ttypeof template.uriTemplate === \"string\" && (template.name === undefined || typeof template.name === \"string\");\n\nfunction toResource(item: Record<string, unknown>): Resource {\n\treturn { ...item, name: item.name ?? item.uri } as Resource;\n}\n\nfunction toResourceTemplate(item: Record<string, unknown>): ResourceTemplate {\n\treturn { ...item, name: item.name ?? item.uriTemplate } as ResourceTemplate;\n}\n\nfunction pageCursor(page: { nextCursor?: string }): { nextCursor?: string } {\n\treturn page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor };\n}\n\nfunction validateReadResourceResult(value: unknown): ReadResourceResult {\n\tif (!isObject(value) || !Array.isArray(value.contents)) throw invalid(\"Invalid MCP resources/read result\");\n\tfor (const contents of value.contents) {\n\t\tif (\n\t\t\t!isObject(contents) ||\n\t\t\ttypeof contents.uri !== \"string\" ||\n\t\t\t(typeof contents.text !== \"string\" && typeof contents.blob !== \"string\")\n\t\t) {\n\t\t\tthrow invalid(\"Invalid contents in MCP resources/read result\");\n\t\t}\n\t}\n\treturn value as unknown as ReadResourceResult;\n}\n\n/** `content` is required by the spec, but servers that only return `structuredContent` omit it (the SDK defaults it too). */\nfunction validateCallToolResult(value: unknown): CallToolResult {\n\tif (!isObject(value) || (value.content !== undefined && !Array.isArray(value.content))) {\n\t\tthrow new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Invalid MCP tools/call result\");\n\t}\n\tif (value.structuredContent !== undefined && !isObject(value.structuredContent)) {\n\t\tthrow new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Invalid MCP tools/call structured content\");\n\t}\n\treturn (value.content === undefined ? { ...value, content: [] } : value) as unknown as CallToolResult;\n}\n\nexport class McpClient {\n\treadonly options: Readonly<McpClientOptions>;\n\tprivate state: ClientState = \"idle\";\n\tprivate transport: McpTransport | undefined;\n\tprivate nextRequestId = 1;\n\tprivate serverInfoValue: Implementation | undefined;\n\tprivate serverCapabilitiesValue: ServerCapabilities | undefined;\n\tprivate instructionsValue: string | undefined;\n\tprivate protocolVersionValue: string | undefined;\n\tprivate pending = new Map<JsonRpcId, PendingRequest>();\n\tprivate progressRequests = new Map<JsonRpcId, JsonRpcId>();\n\tprivate incoming = new Map<JsonRpcId, AbortController>();\n\tprivate requestHandlers = new Map<string, RequestHandler>();\n\tprivate notificationListeners = new Map<string, Set<NotificationListener>>();\n\tprivate errorListeners = new Set<ErrorListener>();\n\tprivate closeListeners = new Set<CloseListener>();\n\tprivate disposers: (() => void)[] = [];\n\n\tconstructor(options: McpClientOptions) {\n\t\tthis.options = Object.freeze({ ...options });\n\t\tthis.requestHandlers.set(\"ping\", () => ({}));\n\t\tconst roots = options.roots;\n\t\tif (roots) {\n\t\t\tthis.requestHandlers.set(\"roots/list\", async () => ({\n\t\t\t\troots: [...(typeof roots === \"function\" ? await roots() : roots)],\n\t\t\t}));\n\t\t}\n\t}\n\n\tget connectionState(): ClientState {\n\t\treturn this.state;\n\t}\n\n\tget serverInfo(): Implementation | undefined {\n\t\treturn this.serverInfoValue;\n\t}\n\n\tget serverCapabilities(): ServerCapabilities | undefined {\n\t\treturn this.serverCapabilitiesValue;\n\t}\n\n\tget instructions(): string | undefined {\n\t\treturn this.instructionsValue;\n\t}\n\n\tget protocolVersion(): string | undefined {\n\t\treturn this.protocolVersionValue;\n\t}\n\n\tasync connect(transport: McpTransport): Promise<InitializeResult> {\n\t\tif (this.state !== \"idle\") throw new Error(`Cannot connect MCP client in ${this.state} state`);\n\t\tthis.state = \"connecting\";\n\t\tthis.transport = transport;\n\t\tthis.disposers = [\n\t\t\ttransport.onMessage((message) => this.handleMessage(message)),\n\t\t\t// Transport errors are reported only. Pending requests fail when the transport closes.\n\t\t\ttransport.onError((error) => this.emitError(error)),\n\t\t\ttransport.onClose(() => this.handleTransportClose()),\n\t\t];\n\n\t\ttry {\n\t\t\tawait transport.start();\n\t\t\tconst capabilities: ClientCapabilities = { ...this.options.capabilities };\n\t\t\tif (this.options.roots && capabilities.roots === undefined) capabilities.roots = {};\n\t\t\tconst result = validateInitializeResult(\n\t\t\t\tawait this.requestInternal(\n\t\t\t\t\t\"initialize\",\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocolVersion: this.options.protocolVersion ?? LATEST_PROTOCOL_VERSION,\n\t\t\t\t\t\tcapabilities,\n\t\t\t\t\t\tclientInfo: {\n\t\t\t\t\t\t\tname: this.options.name,\n\t\t\t\t\t\t\tversion: this.options.version,\n\t\t\t\t\t\t\t...(this.options.title === undefined ? {} : { title: this.options.title }),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{},\n\t\t\t\t\ttrue,\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (!(SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(result.protocolVersion)) {\n\t\t\t\tthrow new Error(`MCP server selected unsupported protocol version ${result.protocolVersion}`);\n\t\t\t}\n\t\t\tthis.protocolVersionValue = result.protocolVersion;\n\t\t\tthis.serverInfoValue = result.serverInfo;\n\t\t\tthis.serverCapabilitiesValue = result.capabilities;\n\t\t\tthis.instructionsValue = result.instructions;\n\t\t\ttransport.setProtocolVersion?.(result.protocolVersion);\n\t\t\tawait this.notifyInternal(\"notifications/initialized\", undefined, true);\n\t\t\tthis.state = \"connected\";\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tawait this.close().catch(() => {});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\trequest<Result = unknown>(\n\t\tmethod: string,\n\t\tparams?: Record<string, unknown>,\n\t\toptions: McpRequestOptions = {},\n\t): Promise<Result> {\n\t\treturn this.requestInternal(method, params, options, false) as Promise<Result>;\n\t}\n\n\tnotify(method: string, params?: Record<string, unknown>): Promise<void> {\n\t\treturn this.notifyInternal(method, params, false);\n\t}\n\n\tsetRequestHandler(method: string, handler: RequestHandler): () => void {\n\t\tthis.requestHandlers.set(method, handler);\n\t\treturn () => {\n\t\t\tif (this.requestHandlers.get(method) === handler) this.requestHandlers.delete(method);\n\t\t};\n\t}\n\n\tonNotification(method: string, listener: NotificationListener): () => void {\n\t\tconst listeners = this.notificationListeners.get(method) ?? new Set<NotificationListener>();\n\t\tthis.notificationListeners.set(method, listeners);\n\t\tlisteners.add(listener);\n\t\treturn () => {\n\t\t\tlisteners.delete(listener);\n\t\t\tif (listeners.size === 0) this.notificationListeners.delete(method);\n\t\t};\n\t}\n\n\tonError(listener: ErrorListener): () => void {\n\t\tthis.errorListeners.add(listener);\n\t\treturn () => this.errorListeners.delete(listener);\n\t}\n\n\t/** Called once when the connection closes, whether the transport dropped or `close()` was called. */\n\tonClose(listener: CloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tasync ping(options: McpRequestOptions = {}): Promise<void> {\n\t\tawait this.request(\"ping\", undefined, options);\n\t}\n\n\tasync listTools(options: McpRequestOptions = {}): Promise<Tool[]> {\n\t\treturn (await this.listAll(\"tools/list\", \"tools\", isTool, options)) as unknown as Tool[];\n\t}\n\n\t/** Every resource, following `nextCursor` through all pages. */\n\tasync listResources(options: McpRequestOptions = {}): Promise<Resource[]> {\n\t\treturn (await this.listAll(\"resources/list\", \"resources\", isResource, options)).map(toResource);\n\t}\n\n\t/** One page of resources, starting at `cursor`. */\n\tasync listResourcesPage(cursor?: string, options: McpRequestOptions = {}): Promise<ListResourcesResult> {\n\t\tconst page = await this.listPage(\"resources/list\", \"resources\", isResource, cursor, options);\n\t\treturn { resources: page.items.map(toResource), ...pageCursor(page) };\n\t}\n\n\t/** Every resource template, following `nextCursor` through all pages. */\n\tasync listResourceTemplates(options: McpRequestOptions = {}): Promise<ResourceTemplate[]> {\n\t\tconst templates = await this.listAll(\n\t\t\t\"resources/templates/list\",\n\t\t\t\"resourceTemplates\",\n\t\t\tisResourceTemplate,\n\t\t\toptions,\n\t\t);\n\t\treturn templates.map(toResourceTemplate);\n\t}\n\n\t/** One page of resource templates, starting at `cursor`. */\n\tasync listResourceTemplatesPage(\n\t\tcursor?: string,\n\t\toptions: McpRequestOptions = {},\n\t): Promise<ListResourceTemplatesResult> {\n\t\tconst page = await this.listPage(\n\t\t\t\"resources/templates/list\",\n\t\t\t\"resourceTemplates\",\n\t\t\tisResourceTemplate,\n\t\t\tcursor,\n\t\t\toptions,\n\t\t);\n\t\treturn { resourceTemplates: page.items.map(toResourceTemplate), ...pageCursor(page) };\n\t}\n\n\tasync readResource(uri: string, options: McpRequestOptions = {}): Promise<ReadResourceResult> {\n\t\treturn validateReadResourceResult(await this.request(\"resources/read\", { uri }, options));\n\t}\n\n\tprivate async listPage(\n\t\tmethod: string,\n\t\tkey: string,\n\t\tisItem: (item: Record<string, unknown>) => boolean,\n\t\tcursor: string | undefined,\n\t\toptions: McpRequestOptions,\n\t): Promise<{ items: Record<string, unknown>[]; nextCursor?: string }> {\n\t\treturn validateListPage(\n\t\t\tmethod,\n\t\t\tkey,\n\t\t\tawait this.request(method, cursor === undefined ? undefined : { cursor }, options),\n\t\t\tisItem,\n\t\t);\n\t}\n\n\t/** Every item of a paginated list method. */\n\tprivate async listAll(\n\t\tmethod: string,\n\t\tkey: string,\n\t\tisItem: (item: Record<string, unknown>) => boolean,\n\t\toptions: McpRequestOptions,\n\t): Promise<Record<string, unknown>[]> {\n\t\tconst items: Record<string, unknown>[] = [];\n\t\tconst cursors = new Set<string>();\n\t\tlet cursor: string | undefined;\n\t\tfor (let pageNumber = 0; pageNumber < MAX_LIST_PAGES; pageNumber++) {\n\t\t\tconst page = await this.listPage(method, key, isItem, cursor, options);\n\t\t\titems.push(...page.items);\n\t\t\tif (page.nextCursor === undefined) return items;\n\t\t\tif (cursors.has(page.nextCursor))\n\t\t\t\tthrow new Error(`MCP ${method} returned duplicate cursor: ${page.nextCursor}`);\n\t\t\tcursors.add(page.nextCursor);\n\t\t\tcursor = page.nextCursor;\n\t\t}\n\t\tthrow new Error(`MCP ${method} exceeded ${MAX_LIST_PAGES} pages`);\n\t}\n\n\tasync callTool(\n\t\tname: string,\n\t\targs?: Record<string, unknown>,\n\t\toptions: McpRequestOptions = {},\n\t): Promise<CallToolResult> {\n\t\treturn validateCallToolResult(\n\t\t\tawait this.request(\"tools/call\", { name, ...(args === undefined ? {} : { arguments: args }) }, options),\n\t\t);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tconst transport = this.transport;\n\t\tthis.transport = undefined;\n\t\tthis.disposeTransportListeners();\n\t\tthis.markClosed(new McpConnectionClosedError());\n\t\tawait transport?.close();\n\t}\n\n\tprivate async requestInternal(\n\t\tmethod: string,\n\t\tparams: Record<string, unknown> | undefined,\n\t\toptions: McpRequestOptions,\n\t\tallowConnecting: boolean,\n\t): Promise<unknown> {\n\t\tconst transport = this.requireTransport(allowConnecting);\n\t\tif (options.signal?.aborted) throw new McpAbortError();\n\t\tconst id = this.nextRequestId++;\n\t\tconst progressToken = options.onProgress ? id : undefined;\n\t\tconst requestParams =\n\t\t\tprogressToken === undefined\n\t\t\t\t? params\n\t\t\t\t: { ...params, _meta: { ...(isObject(params?._meta) ? params._meta : {}), progressToken } };\n\t\tconst message: JsonRpcRequest = {\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tid,\n\t\t\tmethod,\n\t\t\t...(requestParams === undefined ? {} : { params: requestParams }),\n\t\t};\n\t\treturn new Promise<unknown>((resolve, reject) => {\n\t\t\tconst entry: PendingRequest = {\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t\ttimeoutMs: options.timeoutMs ?? this.options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,\n\t\t\t\ttimer: undefined,\n\t\t\t\tsignal: options.signal,\n\t\t\t\t// The spec forbids cancelling `initialize`.\n\t\t\t\tonAbort: () =>\n\t\t\t\t\tthis.cancelPending(\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tnew McpAbortError(),\n\t\t\t\t\t\tmethod !== \"initialize\",\n\t\t\t\t\t\tString(options.signal?.reason ?? \"Aborted\"),\n\t\t\t\t\t),\n\t\t\t\tcancellable: method !== \"initialize\",\n\t\t\t\tonProgress: options.onProgress,\n\t\t\t\tprogressToken,\n\t\t\t};\n\t\t\tthis.pending.set(id, entry);\n\t\t\tif (progressToken !== undefined) this.progressRequests.set(progressToken, id);\n\t\t\toptions.signal?.addEventListener(\"abort\", entry.onAbort, { once: true });\n\t\t\tthis.armTimeout(id, entry);\n\t\t\ttransport.send(message).catch((error) => this.cancelPending(id, error, false));\n\t\t});\n\t}\n\n\tprivate async notifyInternal(\n\t\tmethod: string,\n\t\tparams: Record<string, unknown> | undefined,\n\t\tallowConnecting: boolean,\n\t): Promise<void> {\n\t\tawait this.requireTransport(allowConnecting).send({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tmethod,\n\t\t\t...(params === undefined ? {} : { params }),\n\t\t});\n\t}\n\n\tprivate requireTransport(allowConnecting: boolean): McpTransport {\n\t\tif (this.transport && (this.state === \"connected\" || (allowConnecting && this.state === \"connecting\"))) {\n\t\t\treturn this.transport;\n\t\t}\n\t\tthrow new McpConnectionClosedError(`MCP client is ${this.state}`);\n\t}\n\n\tprivate handleMessage(message: JsonRpcMessage): void {\n\t\tif (isJsonRpcResponse(message)) {\n\t\t\tthis.handleResponse(message);\n\t\t\treturn;\n\t\t}\n\t\tif (isJsonRpcRequest(message)) {\n\t\t\tvoid this.handleRequest(message);\n\t\t\treturn;\n\t\t}\n\t\tif (isJsonRpcNotification(message)) {\n\t\t\tthis.handleNotification(message.method, message.params);\n\t\t\treturn;\n\t\t}\n\t\tthis.emitError(new McpError(JSON_RPC_ERROR_CODES.invalidRequest, \"Received invalid JSON-RPC message\"));\n\t}\n\n\tprivate handleResponse(message: JsonRpcResponse): void {\n\t\tconst entry = this.pending.get(message.id);\n\t\tif (!entry) {\n\t\t\tthis.emitError(new Error(`Received response for unknown MCP request ${String(message.id)}`));\n\t\t\treturn;\n\t\t}\n\t\tthis.removePending(message.id, entry);\n\t\tif (\"error\" in message) entry.reject(new McpError(message.error.code, message.error.message, message.error.data));\n\t\telse entry.resolve(message.result);\n\t}\n\n\tprivate async handleRequest(message: JsonRpcRequest): Promise<void> {\n\t\tconst transport = this.transport;\n\t\tif (!transport) return;\n\t\tconst handler = this.requestHandlers.get(message.method);\n\t\tif (!handler) {\n\t\t\tawait transport\n\t\t\t\t.send({\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\tid: message.id,\n\t\t\t\t\terror: { code: JSON_RPC_ERROR_CODES.methodNotFound, message: `Method not found: ${message.method}` },\n\t\t\t\t})\n\t\t\t\t.catch((error) => this.emitError(error));\n\t\t\treturn;\n\t\t}\n\t\tconst controller = new AbortController();\n\t\tthis.incoming.set(message.id, controller);\n\t\ttry {\n\t\t\tconst result = await handler(message.params, { signal: controller.signal });\n\t\t\tawait transport.send({ jsonrpc: \"2.0\", id: message.id, result: result ?? {} });\n\t\t} catch (error) {\n\t\t\tconst responseError =\n\t\t\t\terror instanceof McpError\n\t\t\t\t\t? { code: error.code, message: error.message, data: error.data }\n\t\t\t\t\t: { code: JSON_RPC_ERROR_CODES.internalError, message: toError(error).message };\n\t\t\tawait transport\n\t\t\t\t.send({ jsonrpc: \"2.0\", id: message.id, error: responseError })\n\t\t\t\t.catch((sendError) => this.emitError(sendError));\n\t\t} finally {\n\t\t\tthis.incoming.delete(message.id);\n\t\t}\n\t}\n\n\tprivate handleNotification(method: string, params: unknown): void {\n\t\tif (method === \"notifications/progress\") this.handleProgress(params);\n\t\telse if (method === \"notifications/cancelled\") this.handleCancelled(params);\n\t\tfor (const listener of this.notificationListeners.get(method) ?? []) {\n\t\t\ttry {\n\t\t\t\tlistener(params);\n\t\t\t} catch (error) {\n\t\t\t\tthis.emitError(error);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleProgress(params: unknown): void {\n\t\tif (!isObject(params) || !isJsonRpcId(params.progressToken) || typeof params.progress !== \"number\") return;\n\t\tconst requestId = this.progressRequests.get(params.progressToken);\n\t\tconst entry = requestId === undefined ? undefined : this.pending.get(requestId);\n\t\tif (requestId === undefined || !entry) return;\n\t\tthis.armTimeout(requestId, entry);\n\t\ttry {\n\t\t\tentry.onProgress?.(params as unknown as ProgressNotification);\n\t\t} catch (error) {\n\t\t\tthis.emitError(error);\n\t\t}\n\t}\n\n\tprivate handleCancelled(params: unknown): void {\n\t\tif (isObject(params) && isJsonRpcId(params.requestId)) this.incoming.get(params.requestId)?.abort(params.reason);\n\t}\n\n\tprivate armTimeout(id: JsonRpcId, entry: PendingRequest): void {\n\t\tif (entry.timer) clearTimeout(entry.timer);\n\t\tif (!Number.isFinite(entry.timeoutMs) || entry.timeoutMs <= 0) return;\n\t\tentry.timer = setTimeout(() => {\n\t\t\tthis.cancelPending(id, new McpTimeoutError(entry.timeoutMs), entry.cancellable, \"Request timed out\");\n\t\t}, entry.timeoutMs);\n\t}\n\n\tprivate cancelPending(id: JsonRpcId, error: unknown, notifyServer: boolean, reason?: string): void {\n\t\tconst entry = this.pending.get(id);\n\t\tif (!entry) return;\n\t\tthis.removePending(id, entry);\n\t\tentry.reject(error);\n\t\tif (notifyServer && this.transport) {\n\t\t\tvoid this.transport\n\t\t\t\t.send({\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\tmethod: \"notifications/cancelled\",\n\t\t\t\t\tparams: { requestId: id, ...(reason ? { reason } : {}) },\n\t\t\t\t})\n\t\t\t\t.catch((sendError) => this.emitError(sendError));\n\t\t}\n\t}\n\n\tprivate removePending(id: JsonRpcId, entry: PendingRequest): void {\n\t\tthis.pending.delete(id);\n\t\tif (entry.timer) clearTimeout(entry.timer);\n\t\tif (entry.progressToken !== undefined) this.progressRequests.delete(entry.progressToken);\n\t\tentry.signal?.removeEventListener(\"abort\", entry.onAbort);\n\t}\n\n\tprivate rejectPending(error: unknown): void {\n\t\tfor (const [id, entry] of this.pending) {\n\t\t\tthis.removePending(id, entry);\n\t\t\tentry.reject(error);\n\t\t}\n\t}\n\n\tprivate handleTransportClose(): void {\n\t\tthis.markClosed(new McpConnectionClosedError());\n\t}\n\n\t/** Idempotent: rejects in-flight requests, aborts server requests we are serving, and flips the state. */\n\tprivate markClosed(error: Error): void {\n\t\tconst wasClosed = this.state === \"closed\";\n\t\tthis.state = \"closed\";\n\t\tthis.rejectPending(error);\n\t\tfor (const controller of this.incoming.values()) controller.abort(error);\n\t\tthis.incoming.clear();\n\t\tif (wasClosed) return;\n\t\tfor (const listener of [...this.closeListeners]) {\n\t\t\ttry {\n\t\t\t\tlistener();\n\t\t\t} catch (listenerError) {\n\t\t\t\tthis.emitError(listenerError);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate emitError(error: unknown): void {\n\t\tconst normalized = toError(error);\n\t\tfor (const listener of this.errorListeners) listener(normalized);\n\t}\n\n\tprivate disposeTransportListeners(): void {\n\t\tfor (const dispose of this.disposers.splice(0)) dispose();\n\t}\n}\n"]}
@@ -17,6 +17,8 @@ export declare function discoverAuthorizationServerMetadata(authorizationServerU
17
17
  }): Promise<AuthorizationServerMetadata | undefined>;
18
18
  export declare function discoverOAuthServerInfo(serverUrl: string | URL, options?: {
19
19
  resourceMetadataUrl?: URL;
20
+ /** Metadata document to use instead of discovery. It is trusted as configured, so its issuer is not checked. */
21
+ authorizationServerMetadataUrl?: URL;
20
22
  fetch?: McpFetch;
21
23
  skipIssuerValidation?: boolean;
22
24
  }): Promise<OAuthServerInfo>;
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/oauth/discovery.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EACN,KAAK,2BAA2B,EAChC,KAAK,cAAc,EACnB,KAAK,8BAA8B,EACnC,KAAK,eAAe,EAGpB,MAAM,YAAY,CAAC;AAqBpB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAiB1E;AAQD,wBAAsB,iCAAiC,CACtD,SAAS,EAAE,MAAM,GAAG,GAAG,EACvB,OAAO,GAAE;IAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;CAAO,GAC9F,OAAO,CAAC,8BAA8B,CAAC,CAoBzC;AAED,wBAAgB,qCAAqC,CACpD,sBAAsB,EAAE,MAAM,GAAG,GAAG,GAClC;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAA;CAAE,EAAE,CASxC;AAED,wBAAsB,mCAAmC,CACxD,sBAAsB,EAAE,MAAM,GAAG,GAAG,EACpC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,QAAQ,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1F,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAmBlD;AAED,wBAAsB,uBAAuB,CAC5C,SAAS,EAAE,MAAM,GAAG,GAAG,EACvB,OAAO,GAAE;IACR,mBAAmB,CAAC,EAAE,GAAG,CAAC;IAC1B,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAC1B,GACJ,OAAO,CAAC,eAAe,CAAC,CAmB1B;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,CAIjE;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,EAAE,QAAQ,CAAC,EAAE,8BAA8B,GAAG,MAAM,GAAG,SAAS,CAarH"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/oauth/discovery.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EACN,KAAK,2BAA2B,EAChC,KAAK,cAAc,EACnB,KAAK,8BAA8B,EACnC,KAAK,eAAe,EAGpB,MAAM,YAAY,CAAC;AAsBpB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAiB1E;AAQD,wBAAsB,iCAAiC,CACtD,SAAS,EAAE,MAAM,GAAG,GAAG,EACvB,OAAO,GAAE;IAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;CAAO,GAC9F,OAAO,CAAC,8BAA8B,CAAC,CAoBzC;AAED,wBAAgB,qCAAqC,CACpD,sBAAsB,EAAE,MAAM,GAAG,GAAG,GAClC;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAA;CAAE,EAAE,CASxC;AAED,wBAAsB,mCAAmC,CACxD,sBAAsB,EAAE,MAAM,GAAG,GAAG,EACpC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,QAAQ,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1F,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAmBlD;AAED,wBAAsB,uBAAuB,CAC5C,SAAS,EAAE,MAAM,GAAG,GAAG,EACvB,OAAO,GAAE;IACR,mBAAmB,CAAC,EAAE,GAAG,CAAC;IAC1B,gHAAgH;IAChH,8BAA8B,CAAC,EAAE,GAAG,CAAC;IACrC,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAC1B,GACJ,OAAO,CAAC,eAAe,CAAC,CA6B1B;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,CAIjE;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,EAAE,QAAQ,CAAC,EAAE,8BAA8B,GAAG,MAAM,GAAG,SAAS,CAarH"}
@@ -19,7 +19,8 @@ function pathSuffix(pathname) {
19
19
  }
20
20
  function field(header, name) {
21
21
  const match = header.match(new RegExp(String.raw `(?:^|[,\s])${name}=(?:"([^"]*)"|([^\s,]+))`, "i"));
22
- return match?.[1] ?? match?.[2];
22
+ // An empty value (`scope=""`) carries no information, so it counts as absent.
23
+ return match?.[1] || match?.[2] || undefined;
23
24
  }
24
25
  export function parseWwwAuthenticate(header) {
25
26
  if (!header)
@@ -109,6 +110,16 @@ export async function discoverOAuthServerInfo(serverUrl, options = {}) {
109
110
  if (error instanceof TypeError)
110
111
  throw error;
111
112
  }
113
+ if (options.authorizationServerMetadataUrl) {
114
+ const url = options.authorizationServerMetadataUrl;
115
+ const response = await fetchMetadata(url, options.fetch ?? globalThis.fetch, LATEST_PROTOCOL_VERSION);
116
+ if (!response.ok) {
117
+ discard(response);
118
+ throw new Error(`HTTP ${response.status} loading authorization server metadata from ${url}`);
119
+ }
120
+ const metadata = parseAuthorizationServerMetadata(await response.json());
121
+ return { authorizationServerUrl: metadata.issuer, authorizationServerMetadata: metadata, resourceMetadata };
122
+ }
112
123
  const authorizationServerUrl = resourceMetadata?.authorization_servers?.[0] ?? String(new URL("/", serverUrl));
113
124
  return {
114
125
  authorizationServerUrl,
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/oauth/discovery.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0 src/client/auth.ts.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to remove Zod/CORS shims and enforce authorization-server issuer validation.\n */\n\nimport type { McpFetch } from \"../auth-provider.ts\";\nimport { LATEST_PROTOCOL_VERSION } from \"../protocol/types.ts\";\nimport { OAuthIssuerMismatchError } from \"./errors.ts\";\nimport {\n\ttype AuthorizationServerMetadata,\n\ttype OAuthChallenge,\n\ttype OAuthProtectedResourceMetadata,\n\ttype OAuthServerInfo,\n\tparseAuthorizationServerMetadata,\n\tparseProtectedResourceMetadata,\n} from \"./types.ts\";\n\nfunction discard(response: Response | undefined): void {\n\tvoid response?.body?.cancel().catch(() => {});\n}\n\n/** 4xx and 502 mean \"not here\", so discovery tries the next candidate URL. */\nfunction isDiscoveryMiss(status: number): boolean {\n\treturn (status >= 400 && status < 500) || status === 502;\n}\n\n/** Path suffix for `/.well-known/<kind><path>`; empty for the root path. */\nfunction pathSuffix(pathname: string): string {\n\treturn pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n}\n\nfunction field(header: string, name: string): string | undefined {\n\tconst match = header.match(new RegExp(String.raw`(?:^|[,\\s])${name}=(?:\"([^\"]*)\"|([^\\s,]+))`, \"i\"));\n\treturn match?.[1] ?? match?.[2];\n}\n\nexport function parseWwwAuthenticate(header: string | null): OAuthChallenge {\n\tif (!header) return {};\n\tconst scheme = header.trimStart().split(/\\s+/, 1)[0]?.toLowerCase();\n\tif (scheme !== \"bearer\" && scheme !== \"dpop\") return {};\n\tconst resourceMetadata = field(header, \"resource_metadata\");\n\tlet resourceMetadataUrl: URL | undefined;\n\tif (resourceMetadata) {\n\t\ttry {\n\t\t\tresourceMetadataUrl = new URL(resourceMetadata);\n\t\t} catch {}\n\t}\n\treturn {\n\t\tresourceMetadataUrl,\n\t\tscope: field(header, \"scope\"),\n\t\terror: field(header, \"error\"),\n\t\terrorDescription: field(header, \"error_description\"),\n\t};\n}\n\nasync function fetchMetadata(url: URL, fetch: McpFetch, protocolVersion: string): Promise<Response> {\n\treturn fetch(url, {\n\t\theaders: { Accept: \"application/json\", \"MCP-Protocol-Version\": protocolVersion },\n\t});\n}\n\nexport async function discoverProtectedResourceMetadata(\n\tserverUrl: string | URL,\n\toptions: { resourceMetadataUrl?: string | URL; protocolVersion?: string; fetch?: McpFetch } = {},\n): Promise<OAuthProtectedResourceMetadata> {\n\tconst server = new URL(serverUrl);\n\tconst fetch = options.fetch ?? globalThis.fetch;\n\tconst version = options.protocolVersion ?? LATEST_PROTOCOL_VERSION;\n\tlet response = await fetchMetadata(\n\t\toptions.resourceMetadataUrl\n\t\t\t? new URL(options.resourceMetadataUrl)\n\t\t\t: new URL(`/.well-known/oauth-protected-resource${pathSuffix(server.pathname)}`, server.origin),\n\t\tfetch,\n\t\tversion,\n\t);\n\tif (!options.resourceMetadataUrl && server.pathname !== \"/\" && isDiscoveryMiss(response.status)) {\n\t\tdiscard(response);\n\t\tresponse = await fetchMetadata(new URL(\"/.well-known/oauth-protected-resource\", server.origin), fetch, version);\n\t}\n\tif (!response.ok) {\n\t\tdiscard(response);\n\t\tthrow new Error(`HTTP ${response.status} loading OAuth protected resource metadata`);\n\t}\n\treturn parseProtectedResourceMetadata(await response.json());\n}\n\nexport function buildAuthorizationServerDiscoveryUrls(\n\tauthorizationServerUrl: string | URL,\n): { url: URL; type: \"oauth\" | \"oidc\" }[] {\n\tconst issuer = new URL(authorizationServerUrl);\n\tconst path = pathSuffix(issuer.pathname);\n\tconst urls: { url: URL; type: \"oauth\" | \"oidc\" }[] = [\n\t\t{ url: new URL(`/.well-known/oauth-authorization-server${path}`, issuer.origin), type: \"oauth\" },\n\t\t{ url: new URL(`/.well-known/openid-configuration${path}`, issuer.origin), type: \"oidc\" },\n\t];\n\tif (path) urls.push({ url: new URL(`${path}/.well-known/openid-configuration`, issuer.origin), type: \"oidc\" });\n\treturn urls;\n}\n\nexport async function discoverAuthorizationServerMetadata(\n\tauthorizationServerUrl: string | URL,\n\toptions: { fetch?: McpFetch; protocolVersion?: string; skipIssuerValidation?: boolean } = {},\n): Promise<AuthorizationServerMetadata | undefined> {\n\tconst fetch = options.fetch ?? globalThis.fetch;\n\tfor (const { url } of buildAuthorizationServerDiscoveryUrls(authorizationServerUrl)) {\n\t\tconst response = await fetchMetadata(url, fetch, options.protocolVersion ?? LATEST_PROTOCOL_VERSION);\n\t\tif (!response.ok) {\n\t\t\tdiscard(response);\n\t\t\tif (isDiscoveryMiss(response.status)) continue;\n\t\t\tthrow new Error(`HTTP ${response.status} loading authorization server metadata from ${url}`);\n\t\t}\n\t\tconst metadata = parseAuthorizationServerMetadata(await response.json());\n\t\tif (!options.skipIssuerValidation) {\n\t\t\tconst expected = String(authorizationServerUrl);\n\t\t\t// URL parsing adds a trailing slash to bare origins, so compare without one on either side.\n\t\t\tconst trim = (value: string) => (value.endsWith(\"/\") ? value.slice(0, -1) : value);\n\t\t\tif (trim(metadata.issuer) !== trim(expected)) throw new OAuthIssuerMismatchError(expected, metadata.issuer);\n\t\t}\n\t\treturn metadata;\n\t}\n\treturn undefined;\n}\n\nexport async function discoverOAuthServerInfo(\n\tserverUrl: string | URL,\n\toptions: {\n\t\tresourceMetadataUrl?: URL;\n\t\tfetch?: McpFetch;\n\t\tskipIssuerValidation?: boolean;\n\t} = {},\n): Promise<OAuthServerInfo> {\n\tlet resourceMetadata: OAuthProtectedResourceMetadata | undefined;\n\ttry {\n\t\tresourceMetadata = await discoverProtectedResourceMetadata(serverUrl, {\n\t\t\tresourceMetadataUrl: options.resourceMetadataUrl,\n\t\t\tfetch: options.fetch,\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof TypeError) throw error;\n\t}\n\tconst authorizationServerUrl = resourceMetadata?.authorization_servers?.[0] ?? String(new URL(\"/\", serverUrl));\n\treturn {\n\t\tauthorizationServerUrl,\n\t\tauthorizationServerMetadata: await discoverAuthorizationServerMetadata(authorizationServerUrl, {\n\t\t\tfetch: options.fetch,\n\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t}),\n\t\tresourceMetadata,\n\t};\n}\n\nexport function resourceUrlFromServerUrl(value: string | URL): URL {\n\tconst url = new URL(value);\n\turl.hash = \"\";\n\treturn url;\n}\n\nexport function selectResource(serverUrl: string | URL, metadata?: OAuthProtectedResourceMetadata): string | undefined {\n\tif (!metadata) return undefined;\n\tconst requested = resourceUrlFromServerUrl(serverUrl);\n\tconst configured = new URL(metadata.resource);\n\tif (requested.origin !== configured.origin) {\n\t\tthrow new Error(`Protected resource ${metadata.resource} does not match MCP server ${requested}`);\n\t}\n\tconst requestedPath = requested.pathname.endsWith(\"/\") ? requested.pathname : `${requested.pathname}/`;\n\tconst configuredPath = configured.pathname.endsWith(\"/\") ? configured.pathname : `${configured.pathname}/`;\n\tif (!requestedPath.startsWith(configuredPath)) {\n\t\tthrow new Error(`Protected resource ${metadata.resource} does not match MCP server ${requested}`);\n\t}\n\treturn metadata.resource;\n}\n"]}
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/oauth/discovery.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0 src/client/auth.ts.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to remove Zod/CORS shims and enforce authorization-server issuer validation.\n */\n\nimport type { McpFetch } from \"../auth-provider.ts\";\nimport { LATEST_PROTOCOL_VERSION } from \"../protocol/types.ts\";\nimport { OAuthIssuerMismatchError } from \"./errors.ts\";\nimport {\n\ttype AuthorizationServerMetadata,\n\ttype OAuthChallenge,\n\ttype OAuthProtectedResourceMetadata,\n\ttype OAuthServerInfo,\n\tparseAuthorizationServerMetadata,\n\tparseProtectedResourceMetadata,\n} from \"./types.ts\";\n\nfunction discard(response: Response | undefined): void {\n\tvoid response?.body?.cancel().catch(() => {});\n}\n\n/** 4xx and 502 mean \"not here\", so discovery tries the next candidate URL. */\nfunction isDiscoveryMiss(status: number): boolean {\n\treturn (status >= 400 && status < 500) || status === 502;\n}\n\n/** Path suffix for `/.well-known/<kind><path>`; empty for the root path. */\nfunction pathSuffix(pathname: string): string {\n\treturn pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n}\n\nfunction field(header: string, name: string): string | undefined {\n\tconst match = header.match(new RegExp(String.raw`(?:^|[,\\s])${name}=(?:\"([^\"]*)\"|([^\\s,]+))`, \"i\"));\n\t// An empty value (`scope=\"\"`) carries no information, so it counts as absent.\n\treturn match?.[1] || match?.[2] || undefined;\n}\n\nexport function parseWwwAuthenticate(header: string | null): OAuthChallenge {\n\tif (!header) return {};\n\tconst scheme = header.trimStart().split(/\\s+/, 1)[0]?.toLowerCase();\n\tif (scheme !== \"bearer\" && scheme !== \"dpop\") return {};\n\tconst resourceMetadata = field(header, \"resource_metadata\");\n\tlet resourceMetadataUrl: URL | undefined;\n\tif (resourceMetadata) {\n\t\ttry {\n\t\t\tresourceMetadataUrl = new URL(resourceMetadata);\n\t\t} catch {}\n\t}\n\treturn {\n\t\tresourceMetadataUrl,\n\t\tscope: field(header, \"scope\"),\n\t\terror: field(header, \"error\"),\n\t\terrorDescription: field(header, \"error_description\"),\n\t};\n}\n\nasync function fetchMetadata(url: URL, fetch: McpFetch, protocolVersion: string): Promise<Response> {\n\treturn fetch(url, {\n\t\theaders: { Accept: \"application/json\", \"MCP-Protocol-Version\": protocolVersion },\n\t});\n}\n\nexport async function discoverProtectedResourceMetadata(\n\tserverUrl: string | URL,\n\toptions: { resourceMetadataUrl?: string | URL; protocolVersion?: string; fetch?: McpFetch } = {},\n): Promise<OAuthProtectedResourceMetadata> {\n\tconst server = new URL(serverUrl);\n\tconst fetch = options.fetch ?? globalThis.fetch;\n\tconst version = options.protocolVersion ?? LATEST_PROTOCOL_VERSION;\n\tlet response = await fetchMetadata(\n\t\toptions.resourceMetadataUrl\n\t\t\t? new URL(options.resourceMetadataUrl)\n\t\t\t: new URL(`/.well-known/oauth-protected-resource${pathSuffix(server.pathname)}`, server.origin),\n\t\tfetch,\n\t\tversion,\n\t);\n\tif (!options.resourceMetadataUrl && server.pathname !== \"/\" && isDiscoveryMiss(response.status)) {\n\t\tdiscard(response);\n\t\tresponse = await fetchMetadata(new URL(\"/.well-known/oauth-protected-resource\", server.origin), fetch, version);\n\t}\n\tif (!response.ok) {\n\t\tdiscard(response);\n\t\tthrow new Error(`HTTP ${response.status} loading OAuth protected resource metadata`);\n\t}\n\treturn parseProtectedResourceMetadata(await response.json());\n}\n\nexport function buildAuthorizationServerDiscoveryUrls(\n\tauthorizationServerUrl: string | URL,\n): { url: URL; type: \"oauth\" | \"oidc\" }[] {\n\tconst issuer = new URL(authorizationServerUrl);\n\tconst path = pathSuffix(issuer.pathname);\n\tconst urls: { url: URL; type: \"oauth\" | \"oidc\" }[] = [\n\t\t{ url: new URL(`/.well-known/oauth-authorization-server${path}`, issuer.origin), type: \"oauth\" },\n\t\t{ url: new URL(`/.well-known/openid-configuration${path}`, issuer.origin), type: \"oidc\" },\n\t];\n\tif (path) urls.push({ url: new URL(`${path}/.well-known/openid-configuration`, issuer.origin), type: \"oidc\" });\n\treturn urls;\n}\n\nexport async function discoverAuthorizationServerMetadata(\n\tauthorizationServerUrl: string | URL,\n\toptions: { fetch?: McpFetch; protocolVersion?: string; skipIssuerValidation?: boolean } = {},\n): Promise<AuthorizationServerMetadata | undefined> {\n\tconst fetch = options.fetch ?? globalThis.fetch;\n\tfor (const { url } of buildAuthorizationServerDiscoveryUrls(authorizationServerUrl)) {\n\t\tconst response = await fetchMetadata(url, fetch, options.protocolVersion ?? LATEST_PROTOCOL_VERSION);\n\t\tif (!response.ok) {\n\t\t\tdiscard(response);\n\t\t\tif (isDiscoveryMiss(response.status)) continue;\n\t\t\tthrow new Error(`HTTP ${response.status} loading authorization server metadata from ${url}`);\n\t\t}\n\t\tconst metadata = parseAuthorizationServerMetadata(await response.json());\n\t\tif (!options.skipIssuerValidation) {\n\t\t\tconst expected = String(authorizationServerUrl);\n\t\t\t// URL parsing adds a trailing slash to bare origins, so compare without one on either side.\n\t\t\tconst trim = (value: string) => (value.endsWith(\"/\") ? value.slice(0, -1) : value);\n\t\t\tif (trim(metadata.issuer) !== trim(expected)) throw new OAuthIssuerMismatchError(expected, metadata.issuer);\n\t\t}\n\t\treturn metadata;\n\t}\n\treturn undefined;\n}\n\nexport async function discoverOAuthServerInfo(\n\tserverUrl: string | URL,\n\toptions: {\n\t\tresourceMetadataUrl?: URL;\n\t\t/** Metadata document to use instead of discovery. It is trusted as configured, so its issuer is not checked. */\n\t\tauthorizationServerMetadataUrl?: URL;\n\t\tfetch?: McpFetch;\n\t\tskipIssuerValidation?: boolean;\n\t} = {},\n): Promise<OAuthServerInfo> {\n\tlet resourceMetadata: OAuthProtectedResourceMetadata | undefined;\n\ttry {\n\t\tresourceMetadata = await discoverProtectedResourceMetadata(serverUrl, {\n\t\t\tresourceMetadataUrl: options.resourceMetadataUrl,\n\t\t\tfetch: options.fetch,\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof TypeError) throw error;\n\t}\n\tif (options.authorizationServerMetadataUrl) {\n\t\tconst url = options.authorizationServerMetadataUrl;\n\t\tconst response = await fetchMetadata(url, options.fetch ?? globalThis.fetch, LATEST_PROTOCOL_VERSION);\n\t\tif (!response.ok) {\n\t\t\tdiscard(response);\n\t\t\tthrow new Error(`HTTP ${response.status} loading authorization server metadata from ${url}`);\n\t\t}\n\t\tconst metadata = parseAuthorizationServerMetadata(await response.json());\n\t\treturn { authorizationServerUrl: metadata.issuer, authorizationServerMetadata: metadata, resourceMetadata };\n\t}\n\tconst authorizationServerUrl = resourceMetadata?.authorization_servers?.[0] ?? String(new URL(\"/\", serverUrl));\n\treturn {\n\t\tauthorizationServerUrl,\n\t\tauthorizationServerMetadata: await discoverAuthorizationServerMetadata(authorizationServerUrl, {\n\t\t\tfetch: options.fetch,\n\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t}),\n\t\tresourceMetadata,\n\t};\n}\n\nexport function resourceUrlFromServerUrl(value: string | URL): URL {\n\tconst url = new URL(value);\n\turl.hash = \"\";\n\treturn url;\n}\n\nexport function selectResource(serverUrl: string | URL, metadata?: OAuthProtectedResourceMetadata): string | undefined {\n\tif (!metadata) return undefined;\n\tconst requested = resourceUrlFromServerUrl(serverUrl);\n\tconst configured = new URL(metadata.resource);\n\tif (requested.origin !== configured.origin) {\n\t\tthrow new Error(`Protected resource ${metadata.resource} does not match MCP server ${requested}`);\n\t}\n\tconst requestedPath = requested.pathname.endsWith(\"/\") ? requested.pathname : `${requested.pathname}/`;\n\tconst configuredPath = configured.pathname.endsWith(\"/\") ? configured.pathname : `${configured.pathname}/`;\n\tif (!requestedPath.startsWith(configuredPath)) {\n\t\tthrow new Error(`Protected resource ${metadata.resource} does not match MCP server ${requested}`);\n\t}\n\treturn metadata.resource;\n}\n"]}
@@ -5,8 +5,9 @@ export declare class OAuthError extends Error {
5
5
  }
6
6
  export declare class OAuthIssuerMismatchError extends Error {
7
7
  readonly expected: string;
8
- readonly received: string;
9
- constructor(expected: string, received: string);
8
+ /** `undefined` when an authorization response lacks the `iss` parameter its server promised (RFC 9207). */
9
+ readonly received: string | undefined;
10
+ constructor(expected: string, received: string | undefined);
10
11
  }
11
12
  export declare class OAuthInsecureEndpointError extends Error {
12
13
  readonly endpoint: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/oauth/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAW,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAK3D;CACD;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IAClD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAK7C;CACD;AAED,qBAAa,0BAA2B,SAAQ,KAAK;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAI3B;CACD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAKvC;CACD;AAED,qBAAa,kCAAmC,SAAQ,KAAK;IAC5D,cAGC;CACD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/oauth/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAW,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAK3D;CACD;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IAClD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2GAA2G;IAC3G,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,YAAY,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAOzD;CACD;AAED,qBAAa,0BAA2B,SAAQ,KAAK;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAI3B;CACD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAKvC;CACD;AAED,qBAAa,kCAAmC,SAAQ,KAAK;IAC5D,cAGC;CACD"}
@@ -10,9 +10,10 @@ export class OAuthError extends Error {
10
10
  }
11
11
  export class OAuthIssuerMismatchError extends Error {
12
12
  expected;
13
+ /** `undefined` when an authorization response lacks the `iss` parameter its server promised (RFC 9207). */
13
14
  received;
14
15
  constructor(expected, received) {
15
- super(`OAuth issuer mismatch: expected ${JSON.stringify(expected)}, received ${JSON.stringify(received)}`);
16
+ super(`OAuth issuer mismatch: expected ${JSON.stringify(expected)}, received ${received === undefined ? "none" : JSON.stringify(received)}`);
16
17
  this.name = "OAuthIssuerMismatchError";
17
18
  this.expected = expected;
18
19
  this.received = received;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/oauth/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC3B,IAAI,CAAS;IACb,QAAQ,CAAqB;IAEtC,YAAY,IAAY,EAAE,OAAe,EAAE,QAAiB;QAC3D,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACzC,QAAQ,CAAS;IACjB,QAAQ,CAAS;IAE1B,YAAY,QAAgB,EAAE,QAAgB;QAC7C,KAAK,CAAC,mCAAmC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC3G,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC3C,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC3B,KAAK,CAAC,4DAA4D,QAAQ,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IACvC,MAAM,CAAS;IACf,IAAI,CAAS;IAEtB,YAAY,MAAc,EAAE,IAAY;QACvC,KAAK,CAAC,wDAAwD,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;CACD;AAED,MAAM,OAAO,kCAAmC,SAAQ,KAAK;IAC5D;QACC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,GAAG,oCAAoC,CAAC;IAClD,CAAC;CACD","sourcesContent":["export class OAuthError extends Error {\n\treadonly code: string;\n\treadonly errorUri: string | undefined;\n\n\tconstructor(code: string, message: string, errorUri?: string) {\n\t\tsuper(message || code);\n\t\tthis.name = \"OAuthError\";\n\t\tthis.code = code;\n\t\tthis.errorUri = errorUri;\n\t}\n}\n\nexport class OAuthIssuerMismatchError extends Error {\n\treadonly expected: string;\n\treadonly received: string;\n\n\tconstructor(expected: string, received: string) {\n\t\tsuper(`OAuth issuer mismatch: expected ${JSON.stringify(expected)}, received ${JSON.stringify(received)}`);\n\t\tthis.name = \"OAuthIssuerMismatchError\";\n\t\tthis.expected = expected;\n\t\tthis.received = received;\n\t}\n}\n\nexport class OAuthInsecureEndpointError extends Error {\n\treadonly endpoint: string;\n\n\tconstructor(endpoint: string) {\n\t\tsuper(`Refusing to send OAuth credentials to non-HTTPS endpoint ${endpoint}`);\n\t\tthis.name = \"OAuthInsecureEndpointError\";\n\t\tthis.endpoint = endpoint;\n\t}\n}\n\nexport class OAuthRegistrationError extends Error {\n\treadonly status: number;\n\treadonly body: string;\n\n\tconstructor(status: number, body: string) {\n\t\tsuper(`OAuth dynamic client registration failed with status ${status}: ${body}`);\n\t\tthis.name = \"OAuthRegistrationError\";\n\t\tthis.status = status;\n\t\tthis.body = body;\n\t}\n}\n\nexport class McpOAuthAuthorizationRequiredError extends Error {\n\tconstructor() {\n\t\tsuper(\"MCP OAuth authorization requires user interaction\");\n\t\tthis.name = \"McpOAuthAuthorizationRequiredError\";\n\t}\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/oauth/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC3B,IAAI,CAAS;IACb,QAAQ,CAAqB;IAEtC,YAAY,IAAY,EAAE,OAAe,EAAE,QAAiB;QAC3D,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACzC,QAAQ,CAAS;IAC1B,2GAA2G;IAClG,QAAQ,CAAqB;IAEtC,YAAY,QAAgB,EAAE,QAA4B;QACzD,KAAK,CACJ,mCAAmC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CACrI,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC3C,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC3B,KAAK,CAAC,4DAA4D,QAAQ,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IACvC,MAAM,CAAS;IACf,IAAI,CAAS;IAEtB,YAAY,MAAc,EAAE,IAAY;QACvC,KAAK,CAAC,wDAAwD,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;CACD;AAED,MAAM,OAAO,kCAAmC,SAAQ,KAAK;IAC5D;QACC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,GAAG,oCAAoC,CAAC;IAClD,CAAC;CACD","sourcesContent":["export class OAuthError extends Error {\n\treadonly code: string;\n\treadonly errorUri: string | undefined;\n\n\tconstructor(code: string, message: string, errorUri?: string) {\n\t\tsuper(message || code);\n\t\tthis.name = \"OAuthError\";\n\t\tthis.code = code;\n\t\tthis.errorUri = errorUri;\n\t}\n}\n\nexport class OAuthIssuerMismatchError extends Error {\n\treadonly expected: string;\n\t/** `undefined` when an authorization response lacks the `iss` parameter its server promised (RFC 9207). */\n\treadonly received: string | undefined;\n\n\tconstructor(expected: string, received: string | undefined) {\n\t\tsuper(\n\t\t\t`OAuth issuer mismatch: expected ${JSON.stringify(expected)}, received ${received === undefined ? \"none\" : JSON.stringify(received)}`,\n\t\t);\n\t\tthis.name = \"OAuthIssuerMismatchError\";\n\t\tthis.expected = expected;\n\t\tthis.received = received;\n\t}\n}\n\nexport class OAuthInsecureEndpointError extends Error {\n\treadonly endpoint: string;\n\n\tconstructor(endpoint: string) {\n\t\tsuper(`Refusing to send OAuth credentials to non-HTTPS endpoint ${endpoint}`);\n\t\tthis.name = \"OAuthInsecureEndpointError\";\n\t\tthis.endpoint = endpoint;\n\t}\n}\n\nexport class OAuthRegistrationError extends Error {\n\treadonly status: number;\n\treadonly body: string;\n\n\tconstructor(status: number, body: string) {\n\t\tsuper(`OAuth dynamic client registration failed with status ${status}: ${body}`);\n\t\tthis.name = \"OAuthRegistrationError\";\n\t\tthis.status = status;\n\t\tthis.body = body;\n\t}\n}\n\nexport class McpOAuthAuthorizationRequiredError extends Error {\n\tconstructor() {\n\t\tsuper(\"MCP OAuth authorization requires user interaction\");\n\t\tthis.name = \"McpOAuthAuthorizationRequiredError\";\n\t}\n}\n"]}
@@ -21,8 +21,15 @@ export interface OAuthClientProvider {
21
21
  export interface OAuthFlowOptions {
22
22
  serverUrl: string | URL;
23
23
  authorizationCode?: string;
24
+ /** `iss` parameter of the authorization response that delivered `authorizationCode` (RFC 9207). */
25
+ iss?: string;
24
26
  scope?: string;
25
27
  resourceMetadataUrl?: URL;
28
+ /**
29
+ * Authorization server metadata document to use instead of discovery, for servers that advertise a
30
+ * wrong authorization server or none. It is trusted as configured. Must use https, except on loopback.
31
+ */
32
+ authorizationServerMetadataUrl?: URL;
26
33
  fetch?: McpFetch;
27
34
  skipIssuerValidation?: boolean;
28
35
  /**
@@ -64,6 +71,12 @@ export declare function exchangeAuthorizationCode(authorizationServerUrl: string
64
71
  export declare function refreshAuthorization(authorizationServerUrl: string | URL, options: TokenRequestOptions & {
65
72
  refreshToken: string;
66
73
  }): Promise<OAuthTokens>;
74
+ /**
75
+ * Scopes for a step-up authorization: the challenged scopes plus the ones granted so far, since a
76
+ * challenge may list only the missing scopes and a token with just those would lose access the old
77
+ * one had (SEP-2350). Without challenged scopes, `undefined` lets the flow pick its default.
78
+ */
79
+ export declare function stepUpScope(granted: string | undefined, challenged: string | undefined): string | undefined;
67
80
  export declare function authorizeMcp(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult>;
68
81
  /**
69
82
  * Auth provider for `StreamableHttpTransport`. After a 401 it refreshes the tokens, or throws
@@ -1 +1 @@
1
- {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { isObject } from "../protocol/jsonrpc.js";
7
7
  import { discoverAuthorizationServerMetadata, discoverOAuthServerInfo, parseWwwAuthenticate, selectResource, } from "./discovery.js";
8
- import { McpOAuthAuthorizationRequiredError, OAuthError, OAuthInsecureEndpointError, OAuthRegistrationError, } from "./errors.js";
8
+ import { McpOAuthAuthorizationRequiredError, OAuthError, OAuthInsecureEndpointError, OAuthIssuerMismatchError, OAuthRegistrationError, } from "./errors.js";
9
9
  import { parseClientInformation, parseOAuthTokens, } from "./types.js";
10
10
  function loopback(hostname) {
11
11
  return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1";
@@ -127,8 +127,24 @@ export async function refreshAuthorization(authorizationServerUrl, options) {
127
127
  const tokens = await tokenRequest(authorizationServerUrl, options, new URLSearchParams({ grant_type: "refresh_token", refresh_token: options.refreshToken }));
128
128
  return { refresh_token: options.refreshToken, ...tokens };
129
129
  }
130
+ function withScope(tokens, scope) {
131
+ return tokens.scope === undefined && scope ? { ...tokens, scope } : tokens;
132
+ }
133
+ /**
134
+ * Scopes for a step-up authorization: the challenged scopes plus the ones granted so far, since a
135
+ * challenge may list only the missing scopes and a token with just those would lose access the old
136
+ * one had (SEP-2350). Without challenged scopes, `undefined` lets the flow pick its default.
137
+ */
138
+ export function stepUpScope(granted, challenged) {
139
+ if (!challenged)
140
+ return undefined;
141
+ const scopes = [granted, challenged].flatMap((scope) => scope?.split(/\s+/).filter(Boolean) ?? []);
142
+ return [...new Set(scopes)].join(" ");
143
+ }
130
144
  async function runFlow(provider, options) {
131
- const cached = await provider.discoveryState?.();
145
+ const metadataUrl = options.authorizationServerMetadataUrl && secureEndpoint(options.authorizationServerMetadataUrl);
146
+ // With a configured metadata URL, discovery is not cached, so changing the URL applies at once.
147
+ const cached = metadataUrl ? undefined : await provider.discoveryState?.();
132
148
  const discovered = cached?.authorizationServerUrl
133
149
  ? {
134
150
  authorizationServerUrl: cached.authorizationServerUrl,
@@ -141,16 +157,20 @@ async function runFlow(provider, options) {
141
157
  }
142
158
  : await discoverOAuthServerInfo(options.serverUrl, {
143
159
  resourceMetadataUrl: options.resourceMetadataUrl,
160
+ authorizationServerMetadataUrl: metadataUrl,
144
161
  fetch: options.fetch,
145
162
  skipIssuerValidation: options.skipIssuerValidation,
146
163
  });
147
- await provider.saveDiscoveryState?.({
148
- ...discovered,
149
- ...(options.resourceMetadataUrl ? { resourceMetadataUrl: options.resourceMetadataUrl.href } : {}),
150
- });
164
+ if (!metadataUrl) {
165
+ await provider.saveDiscoveryState?.({
166
+ ...discovered,
167
+ ...(options.resourceMetadataUrl ? { resourceMetadataUrl: options.resourceMetadataUrl.href } : {}),
168
+ });
169
+ }
151
170
  const metadata = discovered.authorizationServerMetadata;
152
171
  const resource = selectResource(options.serverUrl, discovered.resourceMetadata);
153
- const scope = options.scope ?? discovered.resourceMetadata?.scopes_supported?.join(" ") ?? provider.clientMetadata.scope;
172
+ // `||`, not `??`: an empty scope (for example from `scopes_supported: []`) falls through to the next source.
173
+ const scope = options.scope || discovered.resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
154
174
  let client = await provider.clientInformation();
155
175
  if (!client) {
156
176
  if (options.authorizationCode)
@@ -182,13 +202,21 @@ async function runFlow(provider, options) {
182
202
  fetch: options.fetch,
183
203
  };
184
204
  if (options.authorizationCode) {
205
+ // RFC 9207: never send a code from another authorization server to this one.
206
+ const iss = options.iss;
207
+ if (metadata && (iss !== undefined || metadata.authorization_response_iss_parameter_supported)) {
208
+ if (iss !== metadata.issuer)
209
+ throw new OAuthIssuerMismatchError(metadata.issuer, iss);
210
+ }
185
211
  const tokens = await exchangeAuthorizationCode(discovered.authorizationServerUrl, {
186
212
  ...tokenOptions,
187
213
  code: options.authorizationCode,
188
214
  codeVerifier: await provider.codeVerifier(),
189
215
  redirectUrl: provider.redirectUrl,
190
216
  });
191
- await provider.saveTokens(tokens);
217
+ // A response without `scope` grants the requested scope (RFC 6749 §5.1). Recorded so a step-up can
218
+ // keep it. Callers pass the options of the authorization request, so `scope` is what was requested.
219
+ await provider.saveTokens(withScope(tokens, scope));
192
220
  return "AUTHORIZED";
193
221
  }
194
222
  const existing = options.skipRefresh ? undefined : await provider.tokens();
@@ -198,7 +226,8 @@ async function runFlow(provider, options) {
198
226
  ...tokenOptions,
199
227
  refreshToken: existing.refresh_token,
200
228
  });
201
- await provider.saveTokens(tokens);
229
+ // A refresh without `scope` keeps the scope of the grant (RFC 6749 §6).
230
+ await provider.saveTokens(withScope(tokens, existing.scope));
202
231
  return "AUTHORIZED";
203
232
  }
204
233
  catch (error) {
@@ -255,13 +284,14 @@ export function adaptOAuthProvider(provider) {
255
284
  if (current !== undefined && current !== context.token)
256
285
  return;
257
286
  }
258
- inFlight ??= authorizeMcp(provider, {
287
+ inFlight ??= Promise.resolve(insufficientScope ? provider.tokens() : undefined)
288
+ .then((granted) => authorizeMcp(provider, {
259
289
  serverUrl: context.serverUrl,
260
290
  resourceMetadataUrl: challenge.resourceMetadataUrl,
261
- scope: challenge.scope,
291
+ scope: insufficientScope ? stepUpScope(granted?.scope, challenge.scope) : challenge.scope,
262
292
  fetch: context.fetch,
263
293
  skipRefresh: insufficientScope,
264
- })
294
+ }))
265
295
  .then((result) => {
266
296
  if (result === "REDIRECT")
267
297
  throw new McpOAuthAuthorizationRequiredError();
@@ -1 +1 @@
1
- {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0 src/client/auth.ts.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to remove SDK/Zod dependencies and use WebCrypto for PKCE.\n */\n\nimport type { AuthProvider, McpFetch, UnauthorizedContext } from \"../auth-provider.ts\";\nimport { isObject } from \"../protocol/jsonrpc.ts\";\nimport {\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tparseWwwAuthenticate,\n\tselectResource,\n} from \"./discovery.ts\";\nimport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthRegistrationError,\n} from \"./errors.ts\";\nimport {\n\ttype AuthorizationServerMetadata,\n\ttype OAuthClientInformation,\n\ttype OAuthClientInformationFull,\n\ttype OAuthClientInformationMixed,\n\ttype OAuthClientMetadata,\n\ttype OAuthDiscoveryState,\n\ttype OAuthTokens,\n\tparseClientInformation,\n\tparseOAuthTokens,\n} from \"./types.ts\";\n\nexport type AddClientAuthentication = (\n\theaders: Headers,\n\tparams: URLSearchParams,\n\turl: string | URL,\n\tmetadata?: AuthorizationServerMetadata,\n) => void | Promise<void>;\n\nexport interface OAuthClientProvider {\n\treadonly redirectUrl: string | URL;\n\treadonly clientMetadata: OAuthClientMetadata;\n\treadonly clientMetadataUrl?: string;\n\tstate?(): string | Promise<string>;\n\tclientInformation(): OAuthClientInformationMixed | undefined | Promise<OAuthClientInformationMixed | undefined>;\n\tsaveClientInformation?(information: OAuthClientInformationMixed): void | Promise<void>;\n\ttokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined>;\n\tsaveTokens(tokens: OAuthTokens): void | Promise<void>;\n\tredirectToAuthorization(url: URL): void | Promise<void>;\n\tsaveCodeVerifier(verifier: string): void | Promise<void>;\n\tcodeVerifier(): string | Promise<string>;\n\taddClientAuthentication?: AddClientAuthentication;\n\tinvalidateCredentials?(kind: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"): void | Promise<void>;\n\tsaveDiscoveryState?(state: OAuthDiscoveryState): void | Promise<void>;\n\tdiscoveryState?(): OAuthDiscoveryState | undefined | Promise<OAuthDiscoveryState | undefined>;\n}\n\nexport interface OAuthFlowOptions {\n\tserverUrl: string | URL;\n\tauthorizationCode?: string;\n\tscope?: string;\n\tresourceMetadataUrl?: URL;\n\tfetch?: McpFetch;\n\tskipIssuerValidation?: boolean;\n\t/**\n\t * Go straight to the authorization redirect instead of refreshing stored tokens, for example when the\n\t * server asks for scopes the current grant lacks (a refresh keeps the old scope).\n\t */\n\tskipRefresh?: boolean;\n}\n\nexport type OAuthFlowResult = \"AUTHORIZED\" | \"REDIRECT\";\ntype ClientAuthMethod = \"client_secret_basic\" | \"client_secret_post\" | \"none\";\n\nexport interface TokenRequestOptions {\n\tmetadata?: AuthorizationServerMetadata;\n\tclientInformation: OAuthClientInformationMixed;\n\tresource?: string;\n\taddClientAuthentication?: AddClientAuthentication;\n\tfetch?: McpFetch;\n}\n\nfunction loopback(hostname: string): boolean {\n\treturn hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\" || hostname === \"::1\";\n}\n\nfunction secureEndpoint(value: string | URL): URL {\n\tconst url = new URL(value);\n\tif (url.protocol !== \"https:\" && !loopback(url.hostname)) throw new OAuthInsecureEndpointError(url.href);\n\treturn url;\n}\n\nfunction selectClientAuthMethod(information: OAuthClientInformationMixed, supported: string[]): ClientAuthMethod {\n\tconst hinted = \"token_endpoint_auth_method\" in information ? information.token_endpoint_auth_method : undefined;\n\tif (\n\t\thinted &&\n\t\t[\"client_secret_basic\", \"client_secret_post\", \"none\"].includes(hinted) &&\n\t\t(supported.length === 0 || supported.includes(hinted))\n\t) {\n\t\treturn hinted as ClientAuthMethod;\n\t}\n\tif (supported.length === 0) return information.client_secret ? \"client_secret_basic\" : \"none\";\n\tif (information.client_secret && supported.includes(\"client_secret_basic\")) return \"client_secret_basic\";\n\tif (information.client_secret && supported.includes(\"client_secret_post\")) return \"client_secret_post\";\n\tif (supported.includes(\"none\")) return \"none\";\n\treturn information.client_secret ? \"client_secret_post\" : \"none\";\n}\n\nfunction applyClientAuthentication(\n\tmethod: ClientAuthMethod,\n\tinformation: OAuthClientInformation,\n\theaders: Headers,\n\tparams: URLSearchParams,\n): void {\n\tif (method === \"client_secret_basic\") {\n\t\tif (!information.client_secret) throw new Error(\"client_secret_basic requires a client secret\");\n\t\theaders.set(\n\t\t\t\"Authorization\",\n\t\t\t`Basic ${Buffer.from(`${information.client_id}:${information.client_secret}`).toString(\"base64\")}`,\n\t\t);\n\t} else {\n\t\tparams.set(\"client_id\", information.client_id);\n\t\tif (method === \"client_secret_post\" && information.client_secret)\n\t\t\tparams.set(\"client_secret\", information.client_secret);\n\t}\n}\n\nasync function pkce(): Promise<{ verifier: string; challenge: string }> {\n\tconst bytes = crypto.getRandomValues(new Uint8Array(32));\n\tconst verifier = Buffer.from(bytes).toString(\"base64url\");\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(verifier));\n\treturn { verifier, challenge: Buffer.from(digest).toString(\"base64url\") };\n}\n\nexport async function startAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientInformation: OAuthClientInformationMixed;\n\t\tredirectUrl: string | URL;\n\t\tscope?: string;\n\t\tstate?: string;\n\t\tresource?: string;\n\t},\n): Promise<{ authorizationUrl: URL; codeVerifier: string }> {\n\tconst metadata = options.metadata;\n\tif (metadata && !metadata.response_types_supported.includes(\"code\")) {\n\t\tthrow new Error(\"Authorization server does not support authorization codes\");\n\t}\n\tif (metadata?.code_challenge_methods_supported && !metadata.code_challenge_methods_supported.includes(\"S256\")) {\n\t\tthrow new Error(\"Authorization server does not support PKCE S256\");\n\t}\n\tconst url = new URL(metadata?.authorization_endpoint ?? new URL(\"/authorize\", authorizationServerUrl));\n\tconst { verifier, challenge } = await pkce();\n\turl.searchParams.set(\"response_type\", \"code\");\n\turl.searchParams.set(\"client_id\", options.clientInformation.client_id);\n\turl.searchParams.set(\"code_challenge\", challenge);\n\turl.searchParams.set(\"code_challenge_method\", \"S256\");\n\turl.searchParams.set(\"redirect_uri\", String(options.redirectUrl));\n\tif (options.state) url.searchParams.set(\"state\", options.state);\n\tif (options.scope) url.searchParams.set(\"scope\", options.scope);\n\tif (options.scope?.split(/\\s+/).includes(\"offline_access\")) url.searchParams.set(\"prompt\", \"consent\");\n\tif (options.resource) url.searchParams.set(\"resource\", options.resource);\n\treturn { authorizationUrl: url, codeVerifier: verifier };\n}\n\nasync function tokenRequest(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions,\n\tparams: URLSearchParams,\n): Promise<OAuthTokens> {\n\tconst url = secureEndpoint(options.metadata?.token_endpoint ?? new URL(\"/token\", authorizationServerUrl));\n\tconst headers = new Headers({ Accept: \"application/json\", \"content-type\": \"application/x-www-form-urlencoded\" });\n\tif (options.resource) params.set(\"resource\", options.resource);\n\tif (options.addClientAuthentication) {\n\t\tawait options.addClientAuthentication(headers, params, url, options.metadata);\n\t} else {\n\t\tapplyClientAuthentication(\n\t\t\tselectClientAuthMethod(\n\t\t\t\toptions.clientInformation,\n\t\t\t\toptions.metadata?.token_endpoint_auth_methods_supported ?? [],\n\t\t\t),\n\t\t\toptions.clientInformation,\n\t\t\theaders,\n\t\t\tparams,\n\t\t);\n\t}\n\tconst response = await (options.fetch ?? globalThis.fetch)(url, { method: \"POST\", headers, body: params });\n\tconst text = await response.text();\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(text);\n\t} catch {}\n\t// Servers may report OAuth errors with any status, so check the body before the status.\n\tif (isObject(value) && typeof value.error === \"string\") {\n\t\tthrow new OAuthError(\n\t\t\tvalue.error,\n\t\t\ttypeof value.error_description === \"string\" ? value.error_description : value.error,\n\t\t\ttypeof value.error_uri === \"string\" ? value.error_uri : undefined,\n\t\t);\n\t}\n\tif (!response.ok) throw new OAuthError(\"server_error\", `HTTP ${response.status}: ${text}`);\n\treturn parseOAuthTokens(value);\n}\n\nexport async function registerClient(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientMetadata: OAuthClientMetadata;\n\t\tscope?: string;\n\t\tfetch?: McpFetch;\n\t},\n): Promise<OAuthClientInformationFull> {\n\tconst endpoint = options.metadata?.registration_endpoint;\n\tif (options.metadata && !endpoint)\n\t\tthrow new Error(\"Authorization server does not support dynamic client registration\");\n\tconst response = await (options.fetch ?? globalThis.fetch)(\n\t\tnew URL(endpoint ?? new URL(\"/register\", authorizationServerUrl)),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Accept: \"application/json\", \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ ...options.clientMetadata, ...(options.scope ? { scope: options.scope } : {}) }),\n\t\t},\n\t);\n\tif (!response.ok) throw new OAuthRegistrationError(response.status, await response.text());\n\treturn parseClientInformation(await response.json());\n}\n\nexport async function exchangeAuthorizationCode(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { code: string; codeVerifier: string; redirectUrl: string | URL },\n): Promise<OAuthTokens> {\n\treturn tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode: options.code,\n\t\t\tcode_verifier: options.codeVerifier,\n\t\t\tredirect_uri: String(options.redirectUrl),\n\t\t}),\n\t);\n}\n\nexport async function refreshAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { refreshToken: string },\n): Promise<OAuthTokens> {\n\tconst tokens = await tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({ grant_type: \"refresh_token\", refresh_token: options.refreshToken }),\n\t);\n\treturn { refresh_token: options.refreshToken, ...tokens };\n}\n\nasync function runFlow(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\tconst cached = await provider.discoveryState?.();\n\tconst discovered = cached?.authorizationServerUrl\n\t\t? {\n\t\t\t\tauthorizationServerUrl: cached.authorizationServerUrl,\n\t\t\t\tauthorizationServerMetadata:\n\t\t\t\t\tcached.authorizationServerMetadata ??\n\t\t\t\t\t(await discoverAuthorizationServerMetadata(cached.authorizationServerUrl, {\n\t\t\t\t\t\tfetch: options.fetch,\n\t\t\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t\t\t})),\n\t\t\t\tresourceMetadata: cached.resourceMetadata,\n\t\t\t}\n\t\t: await discoverOAuthServerInfo(options.serverUrl, {\n\t\t\t\tresourceMetadataUrl: options.resourceMetadataUrl,\n\t\t\t\tfetch: options.fetch,\n\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t});\n\tawait provider.saveDiscoveryState?.({\n\t\t...discovered,\n\t\t...(options.resourceMetadataUrl ? { resourceMetadataUrl: options.resourceMetadataUrl.href } : {}),\n\t});\n\tconst metadata = discovered.authorizationServerMetadata;\n\tconst resource = selectResource(options.serverUrl, discovered.resourceMetadata);\n\tconst scope =\n\t\toptions.scope ?? discovered.resourceMetadata?.scopes_supported?.join(\" \") ?? provider.clientMetadata.scope;\n\tlet client = await provider.clientInformation();\n\tif (!client) {\n\t\tif (options.authorizationCode) throw new Error(\"OAuth client information is missing during code exchange\");\n\t\tif (metadata?.client_id_metadata_document_supported && provider.clientMetadataUrl) {\n\t\t\tconst url = new URL(provider.clientMetadataUrl);\n\t\t\tif (url.protocol !== \"https:\" || url.pathname === \"/\") throw new Error(\"Invalid OAuth client metadata URL\");\n\t\t\tclient = { client_id: provider.clientMetadataUrl };\n\t\t\tawait provider.saveClientInformation?.(client);\n\t\t} else {\n\t\t\tif (!provider.saveClientInformation) throw new Error(\"OAuth client information cannot be persisted\");\n\t\t\tclient = await registerClient(discovered.authorizationServerUrl, {\n\t\t\t\tmetadata,\n\t\t\t\tclientMetadata: provider.clientMetadata,\n\t\t\t\tscope,\n\t\t\t\tfetch: options.fetch,\n\t\t\t});\n\t\t\tawait provider.saveClientInformation(client);\n\t\t}\n\t}\n\tconst tokenOptions: TokenRequestOptions = {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tresource,\n\t\taddClientAuthentication: provider.addClientAuthentication,\n\t\tfetch: options.fetch,\n\t};\n\tif (options.authorizationCode) {\n\t\tconst tokens = await exchangeAuthorizationCode(discovered.authorizationServerUrl, {\n\t\t\t...tokenOptions,\n\t\t\tcode: options.authorizationCode,\n\t\t\tcodeVerifier: await provider.codeVerifier(),\n\t\t\tredirectUrl: provider.redirectUrl,\n\t\t});\n\t\tawait provider.saveTokens(tokens);\n\t\treturn \"AUTHORIZED\";\n\t}\n\tconst existing = options.skipRefresh ? undefined : await provider.tokens();\n\tif (existing?.refresh_token) {\n\t\ttry {\n\t\t\tconst tokens = await refreshAuthorization(discovered.authorizationServerUrl, {\n\t\t\t\t...tokenOptions,\n\t\t\t\trefreshToken: existing.refresh_token,\n\t\t\t});\n\t\t\tawait provider.saveTokens(tokens);\n\t\t\treturn \"AUTHORIZED\";\n\t\t} catch (error) {\n\t\t\tif (error instanceof OAuthInsecureEndpointError) throw error;\n\t\t\tif (error instanceof OAuthError && error.code !== \"server_error\") throw error;\n\t\t}\n\t}\n\tconst state = await provider.state?.();\n\tconst authorization = await startAuthorization(discovered.authorizationServerUrl, {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tredirectUrl: provider.redirectUrl,\n\t\tscope,\n\t\tstate,\n\t\tresource,\n\t});\n\tawait provider.saveCodeVerifier(authorization.codeVerifier);\n\tawait provider.redirectToAuthorization(authorization.authorizationUrl);\n\treturn \"REDIRECT\";\n}\n\nexport async function authorizeMcp(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\ttry {\n\t\treturn await runFlow(provider, options);\n\t} catch (error) {\n\t\tif (error instanceof OAuthError && [\"invalid_client\", \"unauthorized_client\"].includes(error.code)) {\n\t\t\tawait provider.invalidateCredentials?.(\"all\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tif (error instanceof OAuthError && error.code === \"invalid_grant\") {\n\t\t\tawait provider.invalidateCredentials?.(\"tokens\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Auth provider for `StreamableHttpTransport`. After a 401 it refreshes the tokens, or throws\n * `McpOAuthAuthorizationRequiredError` when the user has to authorize (again). Concurrent 401s share\n * one refresh, and a request whose token was already replaced is just retried: with rotating refresh\n * tokens, a second refresh with the old refresh token would fail and discard the new grant.\n */\nexport function adaptOAuthProvider(provider: OAuthClientProvider): AuthProvider {\n\tlet inFlight: Promise<void> | undefined;\n\treturn {\n\t\ttoken: async () => (await provider.tokens())?.access_token,\n\t\tonUnauthorized: async (context: UnauthorizedContext) => {\n\t\t\tconst challenge = parseWwwAuthenticate(context.response.headers.get(\"www-authenticate\"));\n\t\t\tconst insufficientScope = challenge.error === \"insufficient_scope\";\n\t\t\tif (!insufficientScope && !inFlight && context.token !== undefined) {\n\t\t\t\tconst current = (await provider.tokens())?.access_token;\n\t\t\t\tif (current !== undefined && current !== context.token) return;\n\t\t\t}\n\t\t\tinFlight ??= authorizeMcp(provider, {\n\t\t\t\tserverUrl: context.serverUrl,\n\t\t\t\tresourceMetadataUrl: challenge.resourceMetadataUrl,\n\t\t\t\tscope: challenge.scope,\n\t\t\t\tfetch: context.fetch,\n\t\t\t\tskipRefresh: insufficientScope,\n\t\t\t})\n\t\t\t\t.then((result) => {\n\t\t\t\t\tif (result === \"REDIRECT\") throw new McpOAuthAuthorizationRequiredError();\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tinFlight = undefined;\n\t\t\t\t});\n\t\t\tawait inFlight;\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0 src/client/auth.ts.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to remove SDK/Zod dependencies and use WebCrypto for PKCE.\n */\n\nimport type { AuthProvider, McpFetch, UnauthorizedContext } from \"../auth-provider.ts\";\nimport { isObject } from \"../protocol/jsonrpc.ts\";\nimport {\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tparseWwwAuthenticate,\n\tselectResource,\n} from \"./discovery.ts\";\nimport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthIssuerMismatchError,\n\tOAuthRegistrationError,\n} from \"./errors.ts\";\nimport {\n\ttype AuthorizationServerMetadata,\n\ttype OAuthClientInformation,\n\ttype OAuthClientInformationFull,\n\ttype OAuthClientInformationMixed,\n\ttype OAuthClientMetadata,\n\ttype OAuthDiscoveryState,\n\ttype OAuthTokens,\n\tparseClientInformation,\n\tparseOAuthTokens,\n} from \"./types.ts\";\n\nexport type AddClientAuthentication = (\n\theaders: Headers,\n\tparams: URLSearchParams,\n\turl: string | URL,\n\tmetadata?: AuthorizationServerMetadata,\n) => void | Promise<void>;\n\nexport interface OAuthClientProvider {\n\treadonly redirectUrl: string | URL;\n\treadonly clientMetadata: OAuthClientMetadata;\n\treadonly clientMetadataUrl?: string;\n\tstate?(): string | Promise<string>;\n\tclientInformation(): OAuthClientInformationMixed | undefined | Promise<OAuthClientInformationMixed | undefined>;\n\tsaveClientInformation?(information: OAuthClientInformationMixed): void | Promise<void>;\n\ttokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined>;\n\tsaveTokens(tokens: OAuthTokens): void | Promise<void>;\n\tredirectToAuthorization(url: URL): void | Promise<void>;\n\tsaveCodeVerifier(verifier: string): void | Promise<void>;\n\tcodeVerifier(): string | Promise<string>;\n\taddClientAuthentication?: AddClientAuthentication;\n\tinvalidateCredentials?(kind: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"): void | Promise<void>;\n\tsaveDiscoveryState?(state: OAuthDiscoveryState): void | Promise<void>;\n\tdiscoveryState?(): OAuthDiscoveryState | undefined | Promise<OAuthDiscoveryState | undefined>;\n}\n\nexport interface OAuthFlowOptions {\n\tserverUrl: string | URL;\n\tauthorizationCode?: string;\n\t/** `iss` parameter of the authorization response that delivered `authorizationCode` (RFC 9207). */\n\tiss?: string;\n\tscope?: string;\n\tresourceMetadataUrl?: URL;\n\t/**\n\t * Authorization server metadata document to use instead of discovery, for servers that advertise a\n\t * wrong authorization server or none. It is trusted as configured. Must use https, except on loopback.\n\t */\n\tauthorizationServerMetadataUrl?: URL;\n\tfetch?: McpFetch;\n\tskipIssuerValidation?: boolean;\n\t/**\n\t * Go straight to the authorization redirect instead of refreshing stored tokens, for example when the\n\t * server asks for scopes the current grant lacks (a refresh keeps the old scope).\n\t */\n\tskipRefresh?: boolean;\n}\n\nexport type OAuthFlowResult = \"AUTHORIZED\" | \"REDIRECT\";\ntype ClientAuthMethod = \"client_secret_basic\" | \"client_secret_post\" | \"none\";\n\nexport interface TokenRequestOptions {\n\tmetadata?: AuthorizationServerMetadata;\n\tclientInformation: OAuthClientInformationMixed;\n\tresource?: string;\n\taddClientAuthentication?: AddClientAuthentication;\n\tfetch?: McpFetch;\n}\n\nfunction loopback(hostname: string): boolean {\n\treturn hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\" || hostname === \"::1\";\n}\n\nfunction secureEndpoint(value: string | URL): URL {\n\tconst url = new URL(value);\n\tif (url.protocol !== \"https:\" && !loopback(url.hostname)) throw new OAuthInsecureEndpointError(url.href);\n\treturn url;\n}\n\nfunction selectClientAuthMethod(information: OAuthClientInformationMixed, supported: string[]): ClientAuthMethod {\n\tconst hinted = \"token_endpoint_auth_method\" in information ? information.token_endpoint_auth_method : undefined;\n\tif (\n\t\thinted &&\n\t\t[\"client_secret_basic\", \"client_secret_post\", \"none\"].includes(hinted) &&\n\t\t(supported.length === 0 || supported.includes(hinted))\n\t) {\n\t\treturn hinted as ClientAuthMethod;\n\t}\n\tif (supported.length === 0) return information.client_secret ? \"client_secret_basic\" : \"none\";\n\tif (information.client_secret && supported.includes(\"client_secret_basic\")) return \"client_secret_basic\";\n\tif (information.client_secret && supported.includes(\"client_secret_post\")) return \"client_secret_post\";\n\tif (supported.includes(\"none\")) return \"none\";\n\treturn information.client_secret ? \"client_secret_post\" : \"none\";\n}\n\nfunction applyClientAuthentication(\n\tmethod: ClientAuthMethod,\n\tinformation: OAuthClientInformation,\n\theaders: Headers,\n\tparams: URLSearchParams,\n): void {\n\tif (method === \"client_secret_basic\") {\n\t\tif (!information.client_secret) throw new Error(\"client_secret_basic requires a client secret\");\n\t\theaders.set(\n\t\t\t\"Authorization\",\n\t\t\t`Basic ${Buffer.from(`${information.client_id}:${information.client_secret}`).toString(\"base64\")}`,\n\t\t);\n\t} else {\n\t\tparams.set(\"client_id\", information.client_id);\n\t\tif (method === \"client_secret_post\" && information.client_secret)\n\t\t\tparams.set(\"client_secret\", information.client_secret);\n\t}\n}\n\nasync function pkce(): Promise<{ verifier: string; challenge: string }> {\n\tconst bytes = crypto.getRandomValues(new Uint8Array(32));\n\tconst verifier = Buffer.from(bytes).toString(\"base64url\");\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(verifier));\n\treturn { verifier, challenge: Buffer.from(digest).toString(\"base64url\") };\n}\n\nexport async function startAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientInformation: OAuthClientInformationMixed;\n\t\tredirectUrl: string | URL;\n\t\tscope?: string;\n\t\tstate?: string;\n\t\tresource?: string;\n\t},\n): Promise<{ authorizationUrl: URL; codeVerifier: string }> {\n\tconst metadata = options.metadata;\n\tif (metadata && !metadata.response_types_supported.includes(\"code\")) {\n\t\tthrow new Error(\"Authorization server does not support authorization codes\");\n\t}\n\tif (metadata?.code_challenge_methods_supported && !metadata.code_challenge_methods_supported.includes(\"S256\")) {\n\t\tthrow new Error(\"Authorization server does not support PKCE S256\");\n\t}\n\tconst url = new URL(metadata?.authorization_endpoint ?? new URL(\"/authorize\", authorizationServerUrl));\n\tconst { verifier, challenge } = await pkce();\n\turl.searchParams.set(\"response_type\", \"code\");\n\turl.searchParams.set(\"client_id\", options.clientInformation.client_id);\n\turl.searchParams.set(\"code_challenge\", challenge);\n\turl.searchParams.set(\"code_challenge_method\", \"S256\");\n\turl.searchParams.set(\"redirect_uri\", String(options.redirectUrl));\n\tif (options.state) url.searchParams.set(\"state\", options.state);\n\tif (options.scope) url.searchParams.set(\"scope\", options.scope);\n\tif (options.scope?.split(/\\s+/).includes(\"offline_access\")) url.searchParams.set(\"prompt\", \"consent\");\n\tif (options.resource) url.searchParams.set(\"resource\", options.resource);\n\treturn { authorizationUrl: url, codeVerifier: verifier };\n}\n\nasync function tokenRequest(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions,\n\tparams: URLSearchParams,\n): Promise<OAuthTokens> {\n\tconst url = secureEndpoint(options.metadata?.token_endpoint ?? new URL(\"/token\", authorizationServerUrl));\n\tconst headers = new Headers({ Accept: \"application/json\", \"content-type\": \"application/x-www-form-urlencoded\" });\n\tif (options.resource) params.set(\"resource\", options.resource);\n\tif (options.addClientAuthentication) {\n\t\tawait options.addClientAuthentication(headers, params, url, options.metadata);\n\t} else {\n\t\tapplyClientAuthentication(\n\t\t\tselectClientAuthMethod(\n\t\t\t\toptions.clientInformation,\n\t\t\t\toptions.metadata?.token_endpoint_auth_methods_supported ?? [],\n\t\t\t),\n\t\t\toptions.clientInformation,\n\t\t\theaders,\n\t\t\tparams,\n\t\t);\n\t}\n\tconst response = await (options.fetch ?? globalThis.fetch)(url, { method: \"POST\", headers, body: params });\n\tconst text = await response.text();\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(text);\n\t} catch {}\n\t// Servers may report OAuth errors with any status, so check the body before the status.\n\tif (isObject(value) && typeof value.error === \"string\") {\n\t\tthrow new OAuthError(\n\t\t\tvalue.error,\n\t\t\ttypeof value.error_description === \"string\" ? value.error_description : value.error,\n\t\t\ttypeof value.error_uri === \"string\" ? value.error_uri : undefined,\n\t\t);\n\t}\n\tif (!response.ok) throw new OAuthError(\"server_error\", `HTTP ${response.status}: ${text}`);\n\treturn parseOAuthTokens(value);\n}\n\nexport async function registerClient(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientMetadata: OAuthClientMetadata;\n\t\tscope?: string;\n\t\tfetch?: McpFetch;\n\t},\n): Promise<OAuthClientInformationFull> {\n\tconst endpoint = options.metadata?.registration_endpoint;\n\tif (options.metadata && !endpoint)\n\t\tthrow new Error(\"Authorization server does not support dynamic client registration\");\n\tconst response = await (options.fetch ?? globalThis.fetch)(\n\t\tnew URL(endpoint ?? new URL(\"/register\", authorizationServerUrl)),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Accept: \"application/json\", \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ ...options.clientMetadata, ...(options.scope ? { scope: options.scope } : {}) }),\n\t\t},\n\t);\n\tif (!response.ok) throw new OAuthRegistrationError(response.status, await response.text());\n\treturn parseClientInformation(await response.json());\n}\n\nexport async function exchangeAuthorizationCode(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { code: string; codeVerifier: string; redirectUrl: string | URL },\n): Promise<OAuthTokens> {\n\treturn tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode: options.code,\n\t\t\tcode_verifier: options.codeVerifier,\n\t\t\tredirect_uri: String(options.redirectUrl),\n\t\t}),\n\t);\n}\n\nexport async function refreshAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { refreshToken: string },\n): Promise<OAuthTokens> {\n\tconst tokens = await tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({ grant_type: \"refresh_token\", refresh_token: options.refreshToken }),\n\t);\n\treturn { refresh_token: options.refreshToken, ...tokens };\n}\n\nfunction withScope(tokens: OAuthTokens, scope: string | undefined): OAuthTokens {\n\treturn tokens.scope === undefined && scope ? { ...tokens, scope } : tokens;\n}\n\n/**\n * Scopes for a step-up authorization: the challenged scopes plus the ones granted so far, since a\n * challenge may list only the missing scopes and a token with just those would lose access the old\n * one had (SEP-2350). Without challenged scopes, `undefined` lets the flow pick its default.\n */\nexport function stepUpScope(granted: string | undefined, challenged: string | undefined): string | undefined {\n\tif (!challenged) return undefined;\n\tconst scopes = [granted, challenged].flatMap((scope) => scope?.split(/\\s+/).filter(Boolean) ?? []);\n\treturn [...new Set(scopes)].join(\" \");\n}\n\nasync function runFlow(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\tconst metadataUrl = options.authorizationServerMetadataUrl && secureEndpoint(options.authorizationServerMetadataUrl);\n\t// With a configured metadata URL, discovery is not cached, so changing the URL applies at once.\n\tconst cached = metadataUrl ? undefined : await provider.discoveryState?.();\n\tconst discovered = cached?.authorizationServerUrl\n\t\t? {\n\t\t\t\tauthorizationServerUrl: cached.authorizationServerUrl,\n\t\t\t\tauthorizationServerMetadata:\n\t\t\t\t\tcached.authorizationServerMetadata ??\n\t\t\t\t\t(await discoverAuthorizationServerMetadata(cached.authorizationServerUrl, {\n\t\t\t\t\t\tfetch: options.fetch,\n\t\t\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t\t\t})),\n\t\t\t\tresourceMetadata: cached.resourceMetadata,\n\t\t\t}\n\t\t: await discoverOAuthServerInfo(options.serverUrl, {\n\t\t\t\tresourceMetadataUrl: options.resourceMetadataUrl,\n\t\t\t\tauthorizationServerMetadataUrl: metadataUrl,\n\t\t\t\tfetch: options.fetch,\n\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t});\n\tif (!metadataUrl) {\n\t\tawait provider.saveDiscoveryState?.({\n\t\t\t...discovered,\n\t\t\t...(options.resourceMetadataUrl ? { resourceMetadataUrl: options.resourceMetadataUrl.href } : {}),\n\t\t});\n\t}\n\tconst metadata = discovered.authorizationServerMetadata;\n\tconst resource = selectResource(options.serverUrl, discovered.resourceMetadata);\n\t// `||`, not `??`: an empty scope (for example from `scopes_supported: []`) falls through to the next source.\n\tconst scope =\n\t\toptions.scope || discovered.resourceMetadata?.scopes_supported?.join(\" \") || provider.clientMetadata.scope;\n\tlet client = await provider.clientInformation();\n\tif (!client) {\n\t\tif (options.authorizationCode) throw new Error(\"OAuth client information is missing during code exchange\");\n\t\tif (metadata?.client_id_metadata_document_supported && provider.clientMetadataUrl) {\n\t\t\tconst url = new URL(provider.clientMetadataUrl);\n\t\t\tif (url.protocol !== \"https:\" || url.pathname === \"/\") throw new Error(\"Invalid OAuth client metadata URL\");\n\t\t\tclient = { client_id: provider.clientMetadataUrl };\n\t\t\tawait provider.saveClientInformation?.(client);\n\t\t} else {\n\t\t\tif (!provider.saveClientInformation) throw new Error(\"OAuth client information cannot be persisted\");\n\t\t\tclient = await registerClient(discovered.authorizationServerUrl, {\n\t\t\t\tmetadata,\n\t\t\t\tclientMetadata: provider.clientMetadata,\n\t\t\t\tscope,\n\t\t\t\tfetch: options.fetch,\n\t\t\t});\n\t\t\tawait provider.saveClientInformation(client);\n\t\t}\n\t}\n\tconst tokenOptions: TokenRequestOptions = {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tresource,\n\t\taddClientAuthentication: provider.addClientAuthentication,\n\t\tfetch: options.fetch,\n\t};\n\tif (options.authorizationCode) {\n\t\t// RFC 9207: never send a code from another authorization server to this one.\n\t\tconst iss = options.iss;\n\t\tif (metadata && (iss !== undefined || metadata.authorization_response_iss_parameter_supported)) {\n\t\t\tif (iss !== metadata.issuer) throw new OAuthIssuerMismatchError(metadata.issuer, iss);\n\t\t}\n\t\tconst tokens = await exchangeAuthorizationCode(discovered.authorizationServerUrl, {\n\t\t\t...tokenOptions,\n\t\t\tcode: options.authorizationCode,\n\t\t\tcodeVerifier: await provider.codeVerifier(),\n\t\t\tredirectUrl: provider.redirectUrl,\n\t\t});\n\t\t// A response without `scope` grants the requested scope (RFC 6749 §5.1). Recorded so a step-up can\n\t\t// keep it. Callers pass the options of the authorization request, so `scope` is what was requested.\n\t\tawait provider.saveTokens(withScope(tokens, scope));\n\t\treturn \"AUTHORIZED\";\n\t}\n\tconst existing = options.skipRefresh ? undefined : await provider.tokens();\n\tif (existing?.refresh_token) {\n\t\ttry {\n\t\t\tconst tokens = await refreshAuthorization(discovered.authorizationServerUrl, {\n\t\t\t\t...tokenOptions,\n\t\t\t\trefreshToken: existing.refresh_token,\n\t\t\t});\n\t\t\t// A refresh without `scope` keeps the scope of the grant (RFC 6749 §6).\n\t\t\tawait provider.saveTokens(withScope(tokens, existing.scope));\n\t\t\treturn \"AUTHORIZED\";\n\t\t} catch (error) {\n\t\t\tif (error instanceof OAuthInsecureEndpointError) throw error;\n\t\t\tif (error instanceof OAuthError && error.code !== \"server_error\") throw error;\n\t\t}\n\t}\n\tconst state = await provider.state?.();\n\tconst authorization = await startAuthorization(discovered.authorizationServerUrl, {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tredirectUrl: provider.redirectUrl,\n\t\tscope,\n\t\tstate,\n\t\tresource,\n\t});\n\tawait provider.saveCodeVerifier(authorization.codeVerifier);\n\tawait provider.redirectToAuthorization(authorization.authorizationUrl);\n\treturn \"REDIRECT\";\n}\n\nexport async function authorizeMcp(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\ttry {\n\t\treturn await runFlow(provider, options);\n\t} catch (error) {\n\t\tif (error instanceof OAuthError && [\"invalid_client\", \"unauthorized_client\"].includes(error.code)) {\n\t\t\tawait provider.invalidateCredentials?.(\"all\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tif (error instanceof OAuthError && error.code === \"invalid_grant\") {\n\t\t\tawait provider.invalidateCredentials?.(\"tokens\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Auth provider for `StreamableHttpTransport`. After a 401 it refreshes the tokens, or throws\n * `McpOAuthAuthorizationRequiredError` when the user has to authorize (again). Concurrent 401s share\n * one refresh, and a request whose token was already replaced is just retried: with rotating refresh\n * tokens, a second refresh with the old refresh token would fail and discard the new grant.\n */\nexport function adaptOAuthProvider(provider: OAuthClientProvider): AuthProvider {\n\tlet inFlight: Promise<void> | undefined;\n\treturn {\n\t\ttoken: async () => (await provider.tokens())?.access_token,\n\t\tonUnauthorized: async (context: UnauthorizedContext) => {\n\t\t\tconst challenge = parseWwwAuthenticate(context.response.headers.get(\"www-authenticate\"));\n\t\t\tconst insufficientScope = challenge.error === \"insufficient_scope\";\n\t\t\tif (!insufficientScope && !inFlight && context.token !== undefined) {\n\t\t\t\tconst current = (await provider.tokens())?.access_token;\n\t\t\t\tif (current !== undefined && current !== context.token) return;\n\t\t\t}\n\t\t\tinFlight ??= Promise.resolve(insufficientScope ? provider.tokens() : undefined)\n\t\t\t\t.then((granted) =>\n\t\t\t\t\tauthorizeMcp(provider, {\n\t\t\t\t\t\tserverUrl: context.serverUrl,\n\t\t\t\t\t\tresourceMetadataUrl: challenge.resourceMetadataUrl,\n\t\t\t\t\t\tscope: insufficientScope ? stepUpScope(granted?.scope, challenge.scope) : challenge.scope,\n\t\t\t\t\t\tfetch: context.fetch,\n\t\t\t\t\t\tskipRefresh: insufficientScope,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.then((result) => {\n\t\t\t\t\tif (result === \"REDIRECT\") throw new McpOAuthAuthorizationRequiredError();\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tinFlight = undefined;\n\t\t\t\t});\n\t\t\tawait inFlight;\n\t\t},\n\t};\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  export { type OAuthCallback, type OAuthCallbackPage, OAuthCallbackServer, type OAuthCallbackServerOptions, } from "./callback.ts";
2
2
  export { buildAuthorizationServerDiscoveryUrls, discoverAuthorizationServerMetadata, discoverOAuthServerInfo, discoverProtectedResourceMetadata, parseWwwAuthenticate, resourceUrlFromServerUrl, selectResource, } from "./discovery.ts";
3
3
  export { McpOAuthAuthorizationRequiredError, OAuthError, OAuthInsecureEndpointError, OAuthIssuerMismatchError, OAuthRegistrationError, } from "./errors.ts";
4
- export { type AddClientAuthentication, adaptOAuthProvider, authorizeMcp, exchangeAuthorizationCode, type OAuthClientProvider, type OAuthFlowOptions, type OAuthFlowResult, refreshAuthorization, registerClient, startAuthorization, type TokenRequestOptions, } from "./flow.ts";
4
+ export { type AddClientAuthentication, adaptOAuthProvider, authorizeMcp, exchangeAuthorizationCode, type OAuthClientProvider, type OAuthFlowOptions, type OAuthFlowResult, refreshAuthorization, registerClient, startAuthorization, stepUpScope, type TokenRequestOptions, } from "./flow.ts";
5
5
  export { McpOAuthProvider, type McpOAuthProviderOptions, type McpOAuthState, type McpOAuthStateStore, MemoryOAuthStateStore, } from "./provider.ts";
6
6
  export type { AuthorizationServerMetadata, OAuthChallenge, OAuthClientInformation, OAuthClientInformationFull, OAuthClientInformationMixed, OAuthClientMetadata, OAuthDiscoveryState, OAuthProtectedResourceMetadata, OAuthServerInfo, OAuthTokens, } from "./types.ts";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,KAAK,0BAA0B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,KAAK,mBAAmB,GACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,qBAAqB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,8BAA8B,EAC9B,eAAe,EACf,WAAW,GACX,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,KAAK,0BAA0B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,KAAK,mBAAmB,GACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,qBAAqB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,8BAA8B,EAC9B,eAAe,EACf,WAAW,GACX,MAAM,YAAY,CAAC"}
@@ -1,6 +1,6 @@
1
1
  export { OAuthCallbackServer, } from "./callback.js";
2
2
  export { buildAuthorizationServerDiscoveryUrls, discoverAuthorizationServerMetadata, discoverOAuthServerInfo, discoverProtectedResourceMetadata, parseWwwAuthenticate, resourceUrlFromServerUrl, selectResource, } from "./discovery.js";
3
3
  export { McpOAuthAuthorizationRequiredError, OAuthError, OAuthInsecureEndpointError, OAuthIssuerMismatchError, OAuthRegistrationError, } from "./errors.js";
4
- export { adaptOAuthProvider, authorizeMcp, exchangeAuthorizationCode, refreshAuthorization, registerClient, startAuthorization, } from "./flow.js";
4
+ export { adaptOAuthProvider, authorizeMcp, exchangeAuthorizationCode, refreshAuthorization, registerClient, startAuthorization, stepUpScope, } from "./flow.js";
5
5
  export { McpOAuthProvider, MemoryOAuthStateStore, } from "./provider.js";
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,mBAAmB,GAEnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEN,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EAIzB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,GAElB,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAIhB,qBAAqB,GACrB,MAAM,eAAe,CAAC","sourcesContent":["export {\n\ttype OAuthCallback,\n\ttype OAuthCallbackPage,\n\tOAuthCallbackServer,\n\ttype OAuthCallbackServerOptions,\n} from \"./callback.ts\";\nexport {\n\tbuildAuthorizationServerDiscoveryUrls,\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tdiscoverProtectedResourceMetadata,\n\tparseWwwAuthenticate,\n\tresourceUrlFromServerUrl,\n\tselectResource,\n} from \"./discovery.ts\";\nexport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthIssuerMismatchError,\n\tOAuthRegistrationError,\n} from \"./errors.ts\";\nexport {\n\ttype AddClientAuthentication,\n\tadaptOAuthProvider,\n\tauthorizeMcp,\n\texchangeAuthorizationCode,\n\ttype OAuthClientProvider,\n\ttype OAuthFlowOptions,\n\ttype OAuthFlowResult,\n\trefreshAuthorization,\n\tregisterClient,\n\tstartAuthorization,\n\ttype TokenRequestOptions,\n} from \"./flow.ts\";\nexport {\n\tMcpOAuthProvider,\n\ttype McpOAuthProviderOptions,\n\ttype McpOAuthState,\n\ttype McpOAuthStateStore,\n\tMemoryOAuthStateStore,\n} from \"./provider.ts\";\nexport type {\n\tAuthorizationServerMetadata,\n\tOAuthChallenge,\n\tOAuthClientInformation,\n\tOAuthClientInformationFull,\n\tOAuthClientInformationMixed,\n\tOAuthClientMetadata,\n\tOAuthDiscoveryState,\n\tOAuthProtectedResourceMetadata,\n\tOAuthServerInfo,\n\tOAuthTokens,\n} from \"./types.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,mBAAmB,GAEnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEN,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EAIzB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,WAAW,GAEX,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAIhB,qBAAqB,GACrB,MAAM,eAAe,CAAC","sourcesContent":["export {\n\ttype OAuthCallback,\n\ttype OAuthCallbackPage,\n\tOAuthCallbackServer,\n\ttype OAuthCallbackServerOptions,\n} from \"./callback.ts\";\nexport {\n\tbuildAuthorizationServerDiscoveryUrls,\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tdiscoverProtectedResourceMetadata,\n\tparseWwwAuthenticate,\n\tresourceUrlFromServerUrl,\n\tselectResource,\n} from \"./discovery.ts\";\nexport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthIssuerMismatchError,\n\tOAuthRegistrationError,\n} from \"./errors.ts\";\nexport {\n\ttype AddClientAuthentication,\n\tadaptOAuthProvider,\n\tauthorizeMcp,\n\texchangeAuthorizationCode,\n\ttype OAuthClientProvider,\n\ttype OAuthFlowOptions,\n\ttype OAuthFlowResult,\n\trefreshAuthorization,\n\tregisterClient,\n\tstartAuthorization,\n\tstepUpScope,\n\ttype TokenRequestOptions,\n} from \"./flow.ts\";\nexport {\n\tMcpOAuthProvider,\n\ttype McpOAuthProviderOptions,\n\ttype McpOAuthState,\n\ttype McpOAuthStateStore,\n\tMemoryOAuthStateStore,\n} from \"./provider.ts\";\nexport type {\n\tAuthorizationServerMetadata,\n\tOAuthChallenge,\n\tOAuthClientInformation,\n\tOAuthClientInformationFull,\n\tOAuthClientInformationMixed,\n\tOAuthClientMetadata,\n\tOAuthDiscoveryState,\n\tOAuthProtectedResourceMetadata,\n\tOAuthServerInfo,\n\tOAuthTokens,\n} from \"./types.ts\";\n"]}
@@ -15,6 +15,8 @@ export interface AuthorizationServerMetadata {
15
15
  token_endpoint_auth_methods_supported?: string[];
16
16
  code_challenge_methods_supported?: string[];
17
17
  client_id_metadata_document_supported?: boolean;
18
+ /** Whether authorization responses carry an `iss` parameter (RFC 9207). */
19
+ authorization_response_iss_parameter_supported?: boolean;
18
20
  [key: string]: unknown;
19
21
  }
20
22
  export interface OAuthTokens {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/oauth/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/oauth/types.ts"],"names":[],"mappings":"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"}
@@ -18,13 +18,17 @@ function requiredString(value, name) {
18
18
  throw new Error(`Invalid ${name}`);
19
19
  return value;
20
20
  }
21
+ /** Treats `null` and `""` as absent: servers send them for fields they have no value for, like `scope: ""`. */
22
+ function absent(value) {
23
+ return value === undefined || value === null || value === "";
24
+ }
21
25
  function optionalString(value, name) {
22
- if (value === undefined)
26
+ if (absent(value))
23
27
  return undefined;
24
28
  return requiredString(value, name);
25
29
  }
26
30
  function optionalStrings(value, name) {
27
- if (value === undefined)
31
+ if (value === undefined || value === null)
28
32
  return undefined;
29
33
  if (!Array.isArray(value) || value.some((item) => typeof item !== "string"))
30
34
  throw new Error(`Invalid ${name}`);
@@ -32,13 +36,16 @@ function optionalStrings(value, name) {
32
36
  }
33
37
  function safeUrl(value, name) {
34
38
  const text = requiredString(value, name);
39
+ // URL parsing throws a `TypeError`, which discovery reserves for network failures.
40
+ if (!URL.canParse(text))
41
+ throw new Error(`Invalid ${name}`);
35
42
  const url = new URL(text);
36
43
  if (["javascript:", "data:", "vbscript:"].includes(url.protocol))
37
44
  throw new Error(`Invalid ${name}`);
38
45
  return text;
39
46
  }
40
47
  function optionalUrl(value, name) {
41
- return value === undefined ? undefined : safeUrl(value, name);
48
+ return absent(value) ? undefined : safeUrl(value, name);
42
49
  }
43
50
  export function parseProtectedResourceMetadata(value) {
44
51
  const input = object(value, "OAuth protected resource metadata");
@@ -68,11 +75,15 @@ export function parseAuthorizationServerMetadata(value) {
68
75
  client_id_metadata_document_supported: typeof input.client_id_metadata_document_supported === "boolean"
69
76
  ? input.client_id_metadata_document_supported
70
77
  : undefined,
78
+ authorization_response_iss_parameter_supported: typeof input.authorization_response_iss_parameter_supported === "boolean"
79
+ ? input.authorization_response_iss_parameter_supported
80
+ : undefined,
71
81
  });
72
82
  }
73
83
  export function parseOAuthTokens(value) {
74
84
  const input = object(value, "OAuth token response");
75
- const expires = input.expires_in === undefined ? undefined : Number(input.expires_in);
85
+ // `Number(null)` is 0, which would mark the token as expired at once.
86
+ const expires = absent(input.expires_in) ? undefined : Number(input.expires_in);
76
87
  if (expires !== undefined && !Number.isFinite(expires))
77
88
  throw new Error("Invalid expires_in");
78
89
  return compact({
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/oauth/types.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to use dependency-free structural validation.\n */\n\nimport { isObject } from \"../protocol/jsonrpc.ts\";\n\nexport interface OAuthProtectedResourceMetadata {\n\tresource: string;\n\tauthorization_servers?: string[];\n\tscopes_supported?: string[];\n\t[key: string]: unknown;\n}\n\nexport interface AuthorizationServerMetadata {\n\tissuer: string;\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tregistration_endpoint?: string;\n\tscopes_supported?: string[];\n\tresponse_types_supported: string[];\n\tgrant_types_supported?: string[];\n\ttoken_endpoint_auth_methods_supported?: string[];\n\tcode_challenge_methods_supported?: string[];\n\tclient_id_metadata_document_supported?: boolean;\n\t[key: string]: unknown;\n}\n\nexport interface OAuthTokens {\n\taccess_token: string;\n\ttoken_type: string;\n\texpires_in?: number;\n\tscope?: string;\n\trefresh_token?: string;\n\tid_token?: string;\n}\n\nexport interface OAuthClientMetadata {\n\tredirect_uris: string[];\n\ttoken_endpoint_auth_method?: string;\n\tgrant_types?: string[];\n\tresponse_types?: string[];\n\tclient_name?: string;\n\tclient_uri?: string;\n\tlogo_uri?: string;\n\tscope?: string;\n\tcontacts?: string[];\n\ttos_uri?: string;\n\tpolicy_uri?: string;\n\tjwks_uri?: string;\n\tjwks?: unknown;\n\tsoftware_id?: string;\n\tsoftware_version?: string;\n\tsoftware_statement?: string;\n}\n\nexport interface OAuthClientInformation {\n\tclient_id: string;\n\tclient_secret?: string;\n\tclient_id_issued_at?: number;\n\tclient_secret_expires_at?: number;\n}\n\nexport type OAuthClientInformationFull = OAuthClientInformation & OAuthClientMetadata;\nexport type OAuthClientInformationMixed = OAuthClientInformation | OAuthClientInformationFull;\n\nexport interface OAuthDiscoveryState {\n\tauthorizationServerUrl: string;\n\tauthorizationServerMetadata?: AuthorizationServerMetadata;\n\tresourceMetadata?: OAuthProtectedResourceMetadata;\n\tresourceMetadataUrl?: string;\n}\n\nexport interface OAuthServerInfo {\n\tauthorizationServerUrl: string;\n\tauthorizationServerMetadata?: AuthorizationServerMetadata;\n\tresourceMetadata?: OAuthProtectedResourceMetadata;\n}\n\nexport interface OAuthChallenge {\n\tresourceMetadataUrl?: URL;\n\tscope?: string;\n\terror?: string;\n\terrorDescription?: string;\n}\n\nfunction object(value: unknown, name: string): Record<string, unknown> {\n\tif (!isObject(value)) throw new Error(`Invalid ${name}`);\n\treturn value;\n}\n\n/** Drops `undefined` values so optional fields are absent rather than present-but-undefined. */\nfunction compact<T extends object>(value: T): T {\n\treturn Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined)) as T;\n}\n\nfunction requiredString(value: unknown, name: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) throw new Error(`Invalid ${name}`);\n\treturn value;\n}\n\nfunction optionalString(value: unknown, name: string): string | undefined {\n\tif (value === undefined) return undefined;\n\treturn requiredString(value, name);\n}\n\nfunction optionalStrings(value: unknown, name: string): string[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value) || value.some((item) => typeof item !== \"string\")) throw new Error(`Invalid ${name}`);\n\treturn [...value];\n}\n\nfunction safeUrl(value: unknown, name: string): string {\n\tconst text = requiredString(value, name);\n\tconst url = new URL(text);\n\tif ([\"javascript:\", \"data:\", \"vbscript:\"].includes(url.protocol)) throw new Error(`Invalid ${name}`);\n\treturn text;\n}\n\nfunction optionalUrl(value: unknown, name: string): string | undefined {\n\treturn value === undefined ? undefined : safeUrl(value, name);\n}\n\nexport function parseProtectedResourceMetadata(value: unknown): OAuthProtectedResourceMetadata {\n\tconst input = object(value, \"OAuth protected resource metadata\");\n\treturn compact({\n\t\t...input,\n\t\tresource: safeUrl(input.resource, \"OAuth protected resource metadata resource\"),\n\t\tauthorization_servers: optionalStrings(input.authorization_servers, \"authorization_servers\")?.map((url) =>\n\t\t\tsafeUrl(url, \"authorization server URL\"),\n\t\t),\n\t\tscopes_supported: optionalStrings(input.scopes_supported, \"scopes_supported\"),\n\t});\n}\n\nexport function parseAuthorizationServerMetadata(value: unknown): AuthorizationServerMetadata {\n\tconst input = object(value, \"authorization server metadata\");\n\tconst responseTypes = optionalStrings(input.response_types_supported, \"response_types_supported\");\n\tif (!responseTypes) throw new Error(\"Invalid response_types_supported\");\n\treturn compact({\n\t\t...input,\n\t\tissuer: safeUrl(input.issuer, \"authorization server issuer\"),\n\t\tauthorization_endpoint: safeUrl(input.authorization_endpoint, \"authorization endpoint\"),\n\t\ttoken_endpoint: safeUrl(input.token_endpoint, \"token endpoint\"),\n\t\tregistration_endpoint: optionalUrl(input.registration_endpoint, \"registration endpoint\"),\n\t\tscopes_supported: optionalStrings(input.scopes_supported, \"scopes_supported\"),\n\t\tresponse_types_supported: responseTypes,\n\t\tgrant_types_supported: optionalStrings(input.grant_types_supported, \"grant_types_supported\"),\n\t\ttoken_endpoint_auth_methods_supported: optionalStrings(\n\t\t\tinput.token_endpoint_auth_methods_supported,\n\t\t\t\"token_endpoint_auth_methods_supported\",\n\t\t),\n\t\tcode_challenge_methods_supported: optionalStrings(\n\t\t\tinput.code_challenge_methods_supported,\n\t\t\t\"code_challenge_methods_supported\",\n\t\t),\n\t\tclient_id_metadata_document_supported:\n\t\t\ttypeof input.client_id_metadata_document_supported === \"boolean\"\n\t\t\t\t? input.client_id_metadata_document_supported\n\t\t\t\t: undefined,\n\t});\n}\n\nexport function parseOAuthTokens(value: unknown): OAuthTokens {\n\tconst input = object(value, \"OAuth token response\");\n\tconst expires = input.expires_in === undefined ? undefined : Number(input.expires_in);\n\tif (expires !== undefined && !Number.isFinite(expires)) throw new Error(\"Invalid expires_in\");\n\treturn compact({\n\t\taccess_token: requiredString(input.access_token, \"access_token\"),\n\t\ttoken_type: requiredString(input.token_type, \"token_type\"),\n\t\texpires_in: expires,\n\t\tscope: optionalString(input.scope, \"scope\"),\n\t\trefresh_token: optionalString(input.refresh_token, \"refresh_token\"),\n\t\tid_token: optionalString(input.id_token, \"id_token\"),\n\t});\n}\n\nexport function parseClientInformation(value: unknown): OAuthClientInformationFull {\n\tconst input = object(value, \"OAuth client registration response\");\n\treturn compact({\n\t\t...(input as unknown as OAuthClientMetadata),\n\t\tclient_id: requiredString(input.client_id, \"client_id\"),\n\t\tclient_secret: optionalString(input.client_secret, \"client_secret\"),\n\t\tclient_id_issued_at: typeof input.client_id_issued_at === \"number\" ? input.client_id_issued_at : undefined,\n\t\tclient_secret_expires_at:\n\t\t\ttypeof input.client_secret_expires_at === \"number\" ? input.client_secret_expires_at : undefined,\n\t\tredirect_uris: optionalStrings(input.redirect_uris, \"redirect_uris\") ?? [],\n\t});\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/oauth/types.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to use dependency-free structural validation.\n */\n\nimport { isObject } from \"../protocol/jsonrpc.ts\";\n\nexport interface OAuthProtectedResourceMetadata {\n\tresource: string;\n\tauthorization_servers?: string[];\n\tscopes_supported?: string[];\n\t[key: string]: unknown;\n}\n\nexport interface AuthorizationServerMetadata {\n\tissuer: string;\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tregistration_endpoint?: string;\n\tscopes_supported?: string[];\n\tresponse_types_supported: string[];\n\tgrant_types_supported?: string[];\n\ttoken_endpoint_auth_methods_supported?: string[];\n\tcode_challenge_methods_supported?: string[];\n\tclient_id_metadata_document_supported?: boolean;\n\t/** Whether authorization responses carry an `iss` parameter (RFC 9207). */\n\tauthorization_response_iss_parameter_supported?: boolean;\n\t[key: string]: unknown;\n}\n\nexport interface OAuthTokens {\n\taccess_token: string;\n\ttoken_type: string;\n\texpires_in?: number;\n\tscope?: string;\n\trefresh_token?: string;\n\tid_token?: string;\n}\n\nexport interface OAuthClientMetadata {\n\tredirect_uris: string[];\n\ttoken_endpoint_auth_method?: string;\n\tgrant_types?: string[];\n\tresponse_types?: string[];\n\tclient_name?: string;\n\tclient_uri?: string;\n\tlogo_uri?: string;\n\tscope?: string;\n\tcontacts?: string[];\n\ttos_uri?: string;\n\tpolicy_uri?: string;\n\tjwks_uri?: string;\n\tjwks?: unknown;\n\tsoftware_id?: string;\n\tsoftware_version?: string;\n\tsoftware_statement?: string;\n}\n\nexport interface OAuthClientInformation {\n\tclient_id: string;\n\tclient_secret?: string;\n\tclient_id_issued_at?: number;\n\tclient_secret_expires_at?: number;\n}\n\nexport type OAuthClientInformationFull = OAuthClientInformation & OAuthClientMetadata;\nexport type OAuthClientInformationMixed = OAuthClientInformation | OAuthClientInformationFull;\n\nexport interface OAuthDiscoveryState {\n\tauthorizationServerUrl: string;\n\tauthorizationServerMetadata?: AuthorizationServerMetadata;\n\tresourceMetadata?: OAuthProtectedResourceMetadata;\n\tresourceMetadataUrl?: string;\n}\n\nexport interface OAuthServerInfo {\n\tauthorizationServerUrl: string;\n\tauthorizationServerMetadata?: AuthorizationServerMetadata;\n\tresourceMetadata?: OAuthProtectedResourceMetadata;\n}\n\nexport interface OAuthChallenge {\n\tresourceMetadataUrl?: URL;\n\tscope?: string;\n\terror?: string;\n\terrorDescription?: string;\n}\n\nfunction object(value: unknown, name: string): Record<string, unknown> {\n\tif (!isObject(value)) throw new Error(`Invalid ${name}`);\n\treturn value;\n}\n\n/** Drops `undefined` values so optional fields are absent rather than present-but-undefined. */\nfunction compact<T extends object>(value: T): T {\n\treturn Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined)) as T;\n}\n\nfunction requiredString(value: unknown, name: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) throw new Error(`Invalid ${name}`);\n\treturn value;\n}\n\n/** Treats `null` and `\"\"` as absent: servers send them for fields they have no value for, like `scope: \"\"`. */\nfunction absent(value: unknown): value is undefined | null | \"\" {\n\treturn value === undefined || value === null || value === \"\";\n}\n\nfunction optionalString(value: unknown, name: string): string | undefined {\n\tif (absent(value)) return undefined;\n\treturn requiredString(value, name);\n}\n\nfunction optionalStrings(value: unknown, name: string): string[] | undefined {\n\tif (value === undefined || value === null) return undefined;\n\tif (!Array.isArray(value) || value.some((item) => typeof item !== \"string\")) throw new Error(`Invalid ${name}`);\n\treturn [...value];\n}\n\nfunction safeUrl(value: unknown, name: string): string {\n\tconst text = requiredString(value, name);\n\t// URL parsing throws a `TypeError`, which discovery reserves for network failures.\n\tif (!URL.canParse(text)) throw new Error(`Invalid ${name}`);\n\tconst url = new URL(text);\n\tif ([\"javascript:\", \"data:\", \"vbscript:\"].includes(url.protocol)) throw new Error(`Invalid ${name}`);\n\treturn text;\n}\n\nfunction optionalUrl(value: unknown, name: string): string | undefined {\n\treturn absent(value) ? undefined : safeUrl(value, name);\n}\n\nexport function parseProtectedResourceMetadata(value: unknown): OAuthProtectedResourceMetadata {\n\tconst input = object(value, \"OAuth protected resource metadata\");\n\treturn compact({\n\t\t...input,\n\t\tresource: safeUrl(input.resource, \"OAuth protected resource metadata resource\"),\n\t\tauthorization_servers: optionalStrings(input.authorization_servers, \"authorization_servers\")?.map((url) =>\n\t\t\tsafeUrl(url, \"authorization server URL\"),\n\t\t),\n\t\tscopes_supported: optionalStrings(input.scopes_supported, \"scopes_supported\"),\n\t});\n}\n\nexport function parseAuthorizationServerMetadata(value: unknown): AuthorizationServerMetadata {\n\tconst input = object(value, \"authorization server metadata\");\n\tconst responseTypes = optionalStrings(input.response_types_supported, \"response_types_supported\");\n\tif (!responseTypes) throw new Error(\"Invalid response_types_supported\");\n\treturn compact({\n\t\t...input,\n\t\tissuer: safeUrl(input.issuer, \"authorization server issuer\"),\n\t\tauthorization_endpoint: safeUrl(input.authorization_endpoint, \"authorization endpoint\"),\n\t\ttoken_endpoint: safeUrl(input.token_endpoint, \"token endpoint\"),\n\t\tregistration_endpoint: optionalUrl(input.registration_endpoint, \"registration endpoint\"),\n\t\tscopes_supported: optionalStrings(input.scopes_supported, \"scopes_supported\"),\n\t\tresponse_types_supported: responseTypes,\n\t\tgrant_types_supported: optionalStrings(input.grant_types_supported, \"grant_types_supported\"),\n\t\ttoken_endpoint_auth_methods_supported: optionalStrings(\n\t\t\tinput.token_endpoint_auth_methods_supported,\n\t\t\t\"token_endpoint_auth_methods_supported\",\n\t\t),\n\t\tcode_challenge_methods_supported: optionalStrings(\n\t\t\tinput.code_challenge_methods_supported,\n\t\t\t\"code_challenge_methods_supported\",\n\t\t),\n\t\tclient_id_metadata_document_supported:\n\t\t\ttypeof input.client_id_metadata_document_supported === \"boolean\"\n\t\t\t\t? input.client_id_metadata_document_supported\n\t\t\t\t: undefined,\n\t\tauthorization_response_iss_parameter_supported:\n\t\t\ttypeof input.authorization_response_iss_parameter_supported === \"boolean\"\n\t\t\t\t? input.authorization_response_iss_parameter_supported\n\t\t\t\t: undefined,\n\t});\n}\n\nexport function parseOAuthTokens(value: unknown): OAuthTokens {\n\tconst input = object(value, \"OAuth token response\");\n\t// `Number(null)` is 0, which would mark the token as expired at once.\n\tconst expires = absent(input.expires_in) ? undefined : Number(input.expires_in);\n\tif (expires !== undefined && !Number.isFinite(expires)) throw new Error(\"Invalid expires_in\");\n\treturn compact({\n\t\taccess_token: requiredString(input.access_token, \"access_token\"),\n\t\ttoken_type: requiredString(input.token_type, \"token_type\"),\n\t\texpires_in: expires,\n\t\tscope: optionalString(input.scope, \"scope\"),\n\t\trefresh_token: optionalString(input.refresh_token, \"refresh_token\"),\n\t\tid_token: optionalString(input.id_token, \"id_token\"),\n\t});\n}\n\nexport function parseClientInformation(value: unknown): OAuthClientInformationFull {\n\tconst input = object(value, \"OAuth client registration response\");\n\treturn compact({\n\t\t...(input as unknown as OAuthClientMetadata),\n\t\tclient_id: requiredString(input.client_id, \"client_id\"),\n\t\tclient_secret: optionalString(input.client_secret, \"client_secret\"),\n\t\tclient_id_issued_at: typeof input.client_id_issued_at === \"number\" ? input.client_id_issued_at : undefined,\n\t\tclient_secret_expires_at:\n\t\t\ttypeof input.client_secret_expires_at === \"number\" ? input.client_secret_expires_at : undefined,\n\t\tredirect_uris: optionalStrings(input.redirect_uris, \"redirect_uris\") ?? [],\n\t});\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-mcp",
3
- "version": "0.99.2",
3
+ "version": "1.0.0",
4
4
  "description": "Standalone Model Context Protocol client for pi and other applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",