# Errors and limits

What each kind of failure looks like, and how to retry safely.

## Connection errors

| Response | Meaning | What to do |
| --- | --- | --- |
| HTTP `401` with `WWW-Authenticate` | No token, or the token expired or was revoked | Let your client refresh, or sign in again. |
| HTTP `401` for a member who left Gravity | Access ended with their membership | Nothing. The account can't be used. |
| HTTP `403` with `error="insufficient_scope"` | The token doesn't include `matching:manage` | Sign in again and approve the connection. |
| HTTP `503` with `"MCP authorization is temporarily unavailable."` | Gravity's sign-in service is down | Try again later. |

## Tool errors

| What you get | Meaning | What to do |
| --- | --- | --- |
| `isError: true`, text starting `Input validation error: Invalid arguments for tool` | An argument is missing, misspelled, extra, or malformed. Nothing ran. | Fix the arguments. |
| JSON-RPC error `Tool ... not found` | The tool doesn't exist | Use a tool from the [tools overview](/docs/mcp/tools). |
| `null` or an empty list | Nothing you're allowed to see matched | Check the ID came from a tool result. Don't guess IDs. |
| `"status": "error"` with a `message`, and `isError: true` | The tool ran but couldn't do what you asked | Follow that tool's error table. |
| `isError: true`, text starting "The operation could not be completed." | Something unexpected went wrong | Read the goal to see whether the change happened before retrying. |

## Retries and request IDs

Reads are safe to repeat.

Writes take a `requestId`. If a write fails before you get a result, retry it with the same `requestId` and identical arguments. Gravity returns the original result without repeating the change, as long as the goal hasn't changed since. Calling with a used `requestId` and different arguments is rejected.

After any write error, read the goal again before deciding what to do next.

## Limits

| Limit | Value |
| --- | --- |
| Goal `text` | 2,000 characters |
| Private details (`additionalContext`) | 4,000 characters |
| Groups per goal | 100 |
| Running searches per goal | 1 |
| Access token lifetime | 1 hour |
| Staying connected (`offline_access`) | Until 90 days without use |

Sign-in endpoints are rate limited. If you see HTTP `429` while signing in, wait a minute and try again.

Each search does real work for every network it covers. Start one only when you're asked, and never in a loop. A `full` search on a goal that was already searched replaces matches nobody has acted on.

Results are plain JSON. A goal with many matches makes a large [`get_goal`](/docs/mcp/tools/get_goal) result, and [`get_goal_matches`](/docs/mcp/tools/get_goal_matches) is smaller.
