{"record":{"id":"2544ba6c87500866","repo":"github/copilot-sdk","slug":"received-mcp-oauth-request-without-a-registered-mc","errorCode":null,"errorMessage":"Received MCP OAuth request without a registered MCP auth handler. SessionId=${this.sessionId}, RequestId=${data.requestId}","messagePattern":"Received MCP OAuth request without a registered MCP auth handler\\. SessionId=(.+?), RequestId=(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"nodejs/src/session.ts","lineNumber":1033,"sourceCode":"        } else if (event.type === \"permission.requested\") {\n            const { requestId, permissionRequest, resolvedByHook } = event.data as {\n                requestId: string;\n                permissionRequest: PermissionRequest;\n                resolvedByHook?: boolean;\n            };\n            if (resolvedByHook) {\n                return; // Already resolved by a permissionRequest hook; no client action needed.\n            }\n            if (this.permissionHandler) {\n                void this._executePermissionAndRespond(requestId, permissionRequest);\n            }\n        } else if (event.type === \"mcp.oauth_required\") {\n            const data = event.data as McpAuthRequest | undefined;\n            if (!data?.requestId) {\n                return;\n            }\n            if (!this.mcpAuthHandler) {\n                console.warn(\n                    \"Received MCP OAuth request without a registered MCP auth handler. \" +\n                        `SessionId=${this.sessionId}, RequestId=${data.requestId}`\n                );\n                return;\n            }\n            void this._executeMcpAuthAndRespond(data);\n        } else if (event.type === \"command.execute\") {\n            const { requestId, commandName, command, args } = event.data as {\n                requestId: string;\n                command: string;\n                commandName: string;\n                args: string;\n            };\n            void this._executeCommandAndRespond(requestId, commandName, command, args);\n        } else if (event.type === \"elicitation.requested\") {\n            if (this.elicitationHandler) {\n                const { message, requestedSchema, mode, elicitationSource, url, requestId } =\n                    event.data;","sourceCodeStart":1015,"sourceCodeEnd":1051,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/nodejs/src/session.ts#L1015-L1051","documentation":"When the server emits an mcp.oauth_required event, CopilotSession needs a registered MCP auth handler to perform the OAuth flow and respond. If this.mcpAuthHandler is not set, the session logs this warning and drops the request, so the MCP tool that requires OAuth will remain unauthenticated and likely fail on subsequent calls.","triggerScenarios":"A session event stream delivers an mcp.oauth_required event (with a requestId) while the application never registered a handler via the MCP auth handler registration API on CopilotSession.","commonSituations":"Using MCP servers that require OAuth without wiring an auth handler; upgrading the library where MCP OAuth support was added and not updating session setup; test harnesses that construct CopilotSession without full MCP configuration.","solutions":["Register an MCP auth handler on the session before starting it (the callback receives the McpAuthRequest and must complete the OAuth flow and respond).","If no MCP OAuth usage is intended, ensure the connected MCP servers are configured with pre-provisioned credentials so no oauth_required event is emitted.","Check that the handler registration happens before any events are processed - registering after the event is lost does not help; re-issue the MCP request.","Inspect data.requestId in the logs to identify which MCP server triggered the flow."],"exampleFix":"// before\nconst session = new CopilotSession({ /* no mcpAuthHandler */ });\n// after\nconst session = new CopilotSession({\n  mcpAuthHandler: async (request) => {\n    const token = await myOAuthFlow(request);\n    return { accessToken: token };\n  }\n});","handlingStrategy":"fallback","validationCode":"if (typeof session.getMcpAuthHandler?.() !== 'function') {\n  throw new Error('MCP auth handler must be registered before handling oauth_required events');\n}","typeGuard":"function hasMcpAuthHandler(s: CopilotSession): boolean {\n  return typeof (s as { mcpAuthHandler?: unknown }).mcpAuthHandler === 'function';\n}","tryCatchPattern":"session.onMcpAuthRequest?.(async (data) => {\n  if (!data?.requestId) return;\n  try {\n    const token = await performOAuth(data);\n    await respondWithToken(data.requestId, token);\n  } catch (err) {\n    console.error('MCP OAuth flow failed', err);\n  }\n});","preventionTips":["Always register the MCP auth handler in session setup when using MCP servers","Register the handler before the session starts consuming events","Cover MCP OAuth flows in integration tests","Pin client/server versions so event schemas match"],"tags":["oauth","mcp","missing-handler","authentication"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}