Rightshold™ Sign up

Answers · MCP security

How do I health-check OAuth token refresh for an MCP server connection?

Last updated

TL;DR: Test the credential, not just the server. A probe that only opens a connection, or reuses an access token that is still valid, can stay green while the refresh token behind it is already dead. Users then find out the next morning when the agent can't connect. A useful check makes one authenticated, read-only MCP request with the token your client really uses, through the same code path and token store. It also tracks when the access token expires, when the last refresh succeeded and what the last refresh error was. Two OAuth rules shape the design. RFC 6749 says that when the server issues a new refresh token, the client must discard the old one, so save the new token before using it. RFC 9700 describes refresh token rotation: if an invalidated refresh token is presented, the server can't tell attacker from client and revokes the active one. So a health checker that holds its own copy of the refresh token, or refreshes at the same time as the client, can log the user out. Treat invalid_grant on refresh as 're-authorization needed', not as a transient error to retry.

What should I check, step by step?

1. Make the check an authenticated MCP request with the client's real token (for example tools/list), not an unauthenticated ping. The MCP spec requires a 401 for invalid or expired tokens, so a 401 here is a real finding.

  1. Run the check through the client's own token store and refresh code, with a lock so only one process refreshes a grant at a time. Never give the checker a separate copy of the refresh token.
  2. Write the new refresh token to storage before you use the new access token. RFC 6749 says the client MUST discard the old refresh token when a new one is issued, and with rotation the old one may already be invalid.
  3. Sort failures into groups: invalid_grant from the token endpoint (the refresh token is invalid, expired or revoked: alert and ask the user to re-authorize), a 403 with insufficient_scope from the MCP server (step-up authorization, not a refresh problem), and timeouts or 5xx (transient: retry with backoff).
  4. Record and alert on time until the access token expires (from expires_in), time since the last successful refresh, consecutive refresh failures and any invalid_grant.
  5. Handle connections with no refresh token at all. The MCP spec says clients MUST NOT assume refresh tokens will be issued. For those, warn before the access token expires.
  6. Know your provider's limits. Google, for example, says a refresh token can stop working after six months unused, when the user revokes access, or when a user passes 100 refresh tokens for one OAuth client (the oldest is invalidated without warning). Apps with an external user type in Testing status get refresh tokens that expire in 7 days unless they request only basic profile scopes.
  7. If you run the authorization server, or it offers token introspection (RFC 7662) to you, use its active field to tell revoked tokens apart from network failures.

Why a green check can hide a dead refresh token

Depending on the authorization server, an access token can keep working until it expires even after the refresh token behind it is revoked. A check that only uses the cached access token passes until that access token expires, and then every call fails at once.

What the MCP spec asks of clients and servers

The MCP authorization spec (2026-07-28) says clients that want refresh tokens MUST keep them confidential in transit and storage, SHOULD include refresh_token in their grant_types client metadata, MAY add offline_access to the scope when the authorization server lists it in scopes_supported, and MUST NOT assume refresh tokens will be issued.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Show me the public health receipts for listed MCP servers: whether each one answered its last probe, when, and how often it answered over the last 30 days.”

One-click setup

{
  "tool": "list_mcp_health",
  "arguments": {}
}

Rightshold probes the liveness of listed MCP servers and publishes the receipts. It never holds or refreshes your OAuth tokens and can't tell you whether your grant is still valid. Not legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'