You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Remote MCP OAuth (Microsoft Entra): calls fail after the access token expires while mcp.list still says connected; only restartServer recovers #5366
I use remote MCP servers protected by Microsoft Entra ID (Teams, Outlook mail) through the Copilot SDK (@github/copilot-sdk 1.0.24, runtime 1.0.101), with mcpOAuthTokenStorage: "persistent" and the runtime's own sign-in (mcp.oauth.login); the host never handles OAuth tokens.
What happens: roughly 60–90 minutes after sign-in (the Entra access-token lifetime), tool calls to these servers start failing as unauthorized. session.rpc.mcp.list() keeps reporting them as connected. The agent then decides it cannot use the server and carries on without it. rpc.mcp.restartServer({ name }) fixes it at once with no browser sign-in, so the stored refresh token is still valid.
Reproduced locally (no account involved): a local OAuth-protected MCP test server that issues 20-second access tokens, returns HTTP 401 on an expired token and supports refresh tokens. After the access token expires:
every call fails with "MCP OAuth challenge required (HTTP 401)";
mcp.list() stays connected for the whole time watched (60 s+);
on runtime 1.0.101 the runtime makes no refresh request of its own and never recovers; on runtime 1.0.103 it sends a needs-auth status event and retries refresh grants, but calls still keep failing;
restartServer makes the next call succeed.
Expected: like the VS Code MCP client, refresh the access token with the stored refresh token on a 401 (or shortly before expiry), retry the call once, and keep the server usable. At minimum, report the server as needs-auth/failed in mcp.list() instead of connected once its token is rejected.
Note: registering onMcpAuthRequest and answering { kind: "runtimeRefresh" } for reason refresh did not fix calls either in my test, and it changes the behaviour for initial requests (a stored sign-in no longer reconnects at start when initial is cancelled), so it is not a host-side workaround.
Environment: macOS 26 and Linux; SDK 1.0.24 / runtime 1.0.101, also checked on SDK 1.0.26 / runtime 1.0.103.
Activity