Forum Discussion
New AI Foundry not sending refresh tokens to MCP (401 after access token expiration)
Hello,
When connecting an MCP server hosted as an Azure Function using OAuth Passthrough in New AI Foundry Playground, the connection is established successfully, the Microsoft login popup appears, authentication succeeds, and the first MCP request returns data correctly.
However, once the access token expires, the Playground and deployed AI Foundry agents to Copilot/Teams do not appear to refresh the token, despite offline_access being included in the requested scopes and a refresh URL being configured. All subsequent MCP calls fail with 401 Unauthorized until the connection is manually recreated.
For testing, we reduced the token lifetime to 10 minutes to make the issue easier to reproduce.
Impact
This prevents long-lived or repeated MCP usage in AI Foundry Playground because the connection becomes unusable after token expiry and requires manual reconnection.
MCP server host: Azure Function
MCP server configuration in New AI Foundry:
- Endpoint: https://mcp-test-obo-rls-fabric.azurewebsites.net/mcp
- Client ID: <client_id> (redacted)
- Auth URL: https://login.microsoftonline.com/tenant_id(redacted)/oauth2/v2.0/authorize
- Token URL: https://login.microsoftonline.com/tenant_id(redacted)/oauth2/v2.0/token
- Refresh URL: https://login.microsoftonline.com/tenant_id(redacted)/oauth2/v2.0/token
- Scopes: openid profile offline_access api://(App ID)/user_impersonation
Redirect URI: https://global.consent.azure-apim.net/redirect/(redacted)-fabric-rls-mcp
Error returned
tool_user_error: Authentication failed when connecting to the MCP server: https://mcp-test-obo-rls-fabric.azurewebsites.net:443/mcp : Response status code does not indicate success: 401 (Unauthorized). Response body: {"code":401,"message":"IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '03/30/2026 08:19:28', Current time (UTC): '03/30/2026 08:29:55'."}. Verify your authentication headers. Suggestions: First verify the required permissions. If the access token is expired or revoked, recreate the connection. If this connection is shared by other users or workflows, recreate it carefully to avoid disruption.
Function App / Identity Provider (Entra)
The Azure Function authentication configuration:
- Identity provider: Microsoft (MCP-Fabric-RLS-Server)
- App registration: MCP-Fabric-RLS-Server
- Supported account types: Single tenant
- Application (client) ID: App ID
- Client secret setting name: MICROSOFT_PROVIDER_AUTHENTICATION_SECRET
- Issuer URL: https://login.microsoftonline.com/tenant_id(redacted)/v2.0
- Redirect URI is added to App Authentication Redirect URI configuration as "Web".
Allowed token audiences
- api://App ID
- App ID
- https://mcp-test-obo-rls-fabric.azurewebsites.net
Additional checks enabled
- Allow requests from any application
- Allow requests from any identity
- Allow requests only from issuer tenant tenant_id (redacted)
Notes
- The first authenticated call succeeds, so the initial OAuth flow appears to be working.
- The failure only occurs after the access token expires.
- Because offline_access is requested and the refresh URL is configured, our expectation is that the client should refresh the token automatically.
- Our working hypothesis is that either:
- the refresh token is not being issued,
- the refresh token is not being stored/used by AI Foundry Playground, or
- OAuth Passthrough for MCP connections in this scenario does not currently support automatic refresh as expected.
Thank you for any assistance provided.
1 Reply
- LReisbergCopper Contributor
Hello,
I can confirm this exact issue in a different environment.Our setup:
- MCP server hosted on Azure App Service (not Azure Function)
- Authentication: OAuth Identity Passthrough configured in AI Foundry
- App Registration: Single tenant, Web redirect to global.consent.azure-apim.net, client secret set
- Token URL, Auth URL, and Refresh URL all correctly pointing to https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
- Scopes include offline_access
- Connection is called via the Responses API (POST /openai/responses) in Agent Reference Mode from a custom Node.js backend
Observed behavior:
- Initial OAuth consent works perfectly — user authenticates, MCP tools execute successfully
- After approximately 60–90 minutes (standard access token lifetime), all MCP calls fail
- The API returns response.mcp_list_tools.failed followed by a new oauth_consent_request
- After manually re-authenticating (clicking "Allow" in the consent popup), tools work again for another ~60–90 minutes
What we verified:
- Refresh URL is correctly configured (same as token URL, which is standard for Entra ID)
- Client secret is active and valid (expires 2028)
- offline_access is included in scopes
- The initial token exchange should provide both access_token and refresh_token (per OBO flow documentation)
Our conclusion aligns with yours: The API Hub stores the refresh token but never uses it to acquire a new access token when the original expires. This forces re-authentication every ~1 hour, making long-lived agent sessions impractical.
Workaround we implemented:
When our backend detects mcp_auth_expired (via SSE error event), we automatically create a new conversation and present the consent popup to the user. After re-authentication, we continue the original request in the fresh conversation. This works but requires user interaction every hour.We have tested with two separate MCP connections (created weeks apart) — the behavior is identical on both. This is clearly a platform-level issue with the API Hub's token lifecycle management.