# HYBRD MCP token refresh (instructions for custom OAuth clients)

Use this skill only when you implement OAuth HTTP yourself: dynamic client registration, PKCE or the device flow, and token storage. Host connectors such as Claude, ChatGPT, Codex, Cursor, and VS Code refresh for you. Setup and first sign-in are covered by the [connection skill](https://www.hybrd.com/resources/mcp-setup/skill.md).

## Server contract

| Field | Value |
| --- | --- |
| Resource / audience | `https://mcp.hybrd.com/mcp` |
| Token endpoint | `https://mcp.hybrd.com/token` |
| Revocation endpoint | `https://mcp.hybrd.com/revoke` |
| Access-token lifetime | about 1 hour (read `expires_in`) |
| Refresh idle lifetime | 30 days |
| Refresh absolute lifetime | 90 days |

Send `resource=https://mcp.hybrd.com/mcp` on every grant: `/authorize`, the authorization-code `/token` exchange, the refresh-token `/token` call, and the device-code `/token` poll. Omitting it or sending a different value returns HTTP 400 `invalid_request`. HYBRD does not infer the resource from an earlier grant.

## Refresh an expired access token

Access tokens expire after about 1 hour. A 401 after a working connection is an expired access token until proven otherwise. Do not treat it as an incomplete sign-in when you already hold a refresh token.

On MCP HTTP 401 with `error=invalid_token`:

1. Make one `POST https://mcp.hybrd.com/token` request (form-encoded).
2. Send `grant_type=refresh_token`, `client_id`, the current `refresh_token`, and `resource=https://mcp.hybrd.com/mcp`.
3. Persist the new `access_token` and `refresh_token` before using them. Discard the old refresh token.
4. Retry the MCP request with the new access token.
5. Start a new sign-in (or device flow) only if refresh returns `invalid_grant`. Never retry the old refresh token.

## Single-use refresh tokens

Refresh tokens rotate and are single-use. A successful refresh consumes the old token. Reusing a consumed token revokes the whole refresh-token family, and the person must sign in again.

Do not share one refresh token across concurrent processes. Serialize refreshes per account behind a lock and persist the new pair before another caller can use it.

## Revoke on disconnect

`POST https://mcp.hybrd.com/revoke` (form-encoded) with `token` and `client_id`. Revoking either token in a pair revokes both.

## Never do this

- Do not omit `resource` on refresh.
- Do not retry refresh in a loop with the same token after `invalid_grant`.
- Do not refresh on a timer; refresh only on expiry or 401.
- Do not log access tokens, refresh tokens, authorization codes, device codes, or PKCE verifiers. Keep them in a keychain or encrypted secret store.

## Related

- Connection skill: https://www.hybrd.com/resources/mcp-setup/skill.md
- Human-readable setup page: https://www.hybrd.com/mcp
- MCP resource: https://mcp.hybrd.com/mcp
