# HYBRD MCP troubleshooting (instructions for AI agents)

You are reading this because an HYBRD MCP request failed. Find the failing case below before retrying anything. Most failures need zero retries or exactly one; a retry loop makes auth failures worse.

Setup and first sign-in are covered by the [connection skill](https://www.hybrd.com/resources/mcp-setup/skill.md). Refresh mechanics are covered by the [token refresh skill](https://www.hybrd.com/resources/mcp-token-refresh/skill.md). Host connectors such as Claude, ChatGPT, Codex, Cursor, and VS Code refresh for you; this page is for diagnosing the failure, including ones those clients surface.

## 401 / unauthorized

- **Before the person approved access:** expected, not an error. Finish the OAuth sign-in and wait for approval.
- **After a previously working connection:** the access token expired (about 1 hour lifetime). Refresh once with the current refresh token and `resource=https://mcp.hybrd.com/mcp` (see the [token refresh skill](https://www.hybrd.com/resources/mcp-token-refresh/skill.md)). Start a new sign-in only if refresh returns `invalid_grant`.

## `invalid_grant` on refresh

Three distinct causes. The `error_description` names the one you hit. All three end the same way: do not retry the old refresh token.

1. **Already used / rotated.** Refresh tokens are single-use. Reusing a consumed token revokes the whole token family. The usual cause is two processes refreshing with the same token: keep exactly one refresher per account behind a lock, persist the new pair before any other caller can use it, and start a new sign-in.
2. **Expired.** Refresh tokens expire after 30 days idle and 90 days absolute. Start a new sign-in (or device flow).
3. **Different client registration.** The error names the presenting `client_id` and says the token belongs to another registration. The token is valid but this `client_id` does not own it. Usual causes: the client re-registered at `POST https://mcp.hybrd.com/register` without updating its stored tokens, or two registrations share one token file. Fix: keep one registration per token file, use the tokens stored for the registration that received them, or start a new sign-in. Never retry this combination.

## `invalid_request` mentioning `resource`

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. HYBRD does not infer it from an earlier grant.

## Device flow polling

- **`authorization_pending`:** keep waiting `interval` seconds between polls.
- **`slow_down`:** you are polling too fast. Wait longer between polls.
- **`expired_token`:** the person did not approve within 5 minutes. Do not retry that `device_code`. Request a new one and show the person the new `user_code`.
- **`access_denied`:** the person declined. Stop and ask them before starting over.

## Missing scope

A tool reports a scope the grant lacks: explain what the tool needs, then ask the person to reconnect and approve the matching scope. See `scopes_supported` from the authorization server metadata and the `grantedScopes` returned by `get_account`.

## No active subscription

- **Outside ChatGPT/Codex:** call `get_stripe_checkout_link`, share the link, and retry after checkout. Links expire after 24 hours.
- **Inside ChatGPT/Codex:** the person needs an active HYBRD subscription (app.hybrd.com). Wait until `get_account` shows one.

## If a request fails in transit

If a request fails with a network error or an empty response, retry an idempotent read once. Never retry a refresh grant in a loop: a refresh the server already processed stays consumed, and replaying it revokes the token family.

## Token storage hygiene (custom OAuth clients)

- One client registration per token file. Re-registering returns a new `client_id`; update the stored tokens at the same time or the old refresh token stops working under the new identity.
- One refresher per account. Cron loops, reconnect logic, and manual scripts must not refresh concurrently.
- Refresh only on expiry or 401, never on a timer. A refresh that reports "not due" forever while calls return 401 means the stored timestamp logic is stale, not that the token is fresh.
- Never log tokens, codes, or verifiers. Keep them in a keychain or encrypted secret store.

## Related

- Connection skill: https://www.hybrd.com/resources/mcp-setup/skill.md
- Token refresh for custom OAuth clients: https://www.hybrd.com/resources/mcp-token-refresh/skill.md
- Human-readable setup page: https://www.hybrd.com/mcp
- MCP resource: https://mcp.hybrd.com/mcp
