> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chataigne.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP safety, pagination, and errors

> Build reliable Chataigne MCP clients with bounded results, optimistic writes, idempotency, and safe errors.

Chataigne treats model calls as untrusted boundary input. The server validates schemas, rate and size boundaries, real resource ownership, OAuth scopes, live roles and memberships before calling business logic.

## Response envelope

Successful tools return a short human-readable text block and structured data:

```json theme={null}
{
  "data": {
    "orders": []
  },
  "meta": {
    "request_id": "req_...",
    "next_cursor": "opaque-cursor",
    "truncated": false,
    "replayed": false
  }
}
```

Keep `request_id` when reporting a problem. MCP arguments, customer message text, transcript queries and idempotency keys are not written to application logs or Sentry.

## Pagination and limits

* List tools default to 20 records and accept at most 50.
* Cursors are opaque. Do not parse, edit or reuse them with different filters.
* Conversation detail accepts at most 100 messages.
* Analytics accepts at most eight metrics and a 366-day date range.
* Structured output is limited to 128 KiB; text summaries to 4 KiB.
* Each read tool allows 1,000 calls per minute per OAuth client/user; each write tool allows 500.
* Standard reads time out after 15 seconds, analytics after 30 seconds, and merchant mutations after 20 seconds.

If `meta.next_cursor` is present, pass it unchanged to the same tool with the same filters.

## Optimistic write preconditions

State-changing tools require the state the model previously observed. For example:

```json theme={null}
{
  "order_id": "ord_...",
  "status": "accepted",
  "expected_status": "received"
}
```

If another operator changes the order first, the server returns `MCP_EXPECTED_STATE_MISMATCH` or `ORDER_STATUS_PRECONDITION_FAILED`. Reload the resource, reconsider the requested change, and only then retry.

## Idempotency

External message, instruction, organization-creation, and location-creation tools require an `idempotency_key` between 8 and 255 characters. The key is scoped to OAuth client, delegated user and tool.

* The same key and same arguments replay the stored result for 24 hours.
* The same key with different arguments returns `MCP_IDEMPOTENCY_MISMATCH`.
* A concurrent duplicate returns `MCP_OPERATION_IN_PROGRESS` with a retry hint.
* Raw keys are hashed before Redis storage and never logged.

Use one new high-entropy application-generated key per intended effect. Reuse it only when retrying that exact effect.

## Error contract

Tool failures set `isError: true` and return:

```json theme={null}
{
  "data": {
    "error": {
      "code": "MCP_RESOURCE_FORBIDDEN",
      "category": "authorization",
      "retryable": false,
      "message": "The resource is unavailable or your delegated access is insufficient.",
      "request_id": "req_..."
    }
  },
  "meta": {
    "request_id": "req_..."
  }
}
```

Categories are `validation`, `authentication`, `authorization`, `not_found`, `conflict`, `rate_limit`, `timeout`, `dependency`, and `internal`.

| Code                          | Meaning                                   | Client action                                 |
| ----------------------------- | ----------------------------------------- | --------------------------------------------- |
| `MCP_SCOPE_REQUIRED`          | Required OAuth scope was not granted      | Reconnect and explicitly consent to the scope |
| `MCP_RESOURCE_FORBIDDEN`      | Scope, role or membership is insufficient | Do not retry unchanged                        |
| `MCP_RESOURCE_NOT_FOUND`      | Authorized resource was not found         | Verify the identifier                         |
| `MCP_CURSOR_INVALID`          | Cursor is malformed or used incorrectly   | Restart pagination                            |
| `MCP_EXPECTED_STATE_MISMATCH` | Resource changed after it was read        | Reload before deciding                        |
| `MCP_IDEMPOTENCY_MISMATCH`    | Key was reused for a different effect     | Use the original arguments or a new key       |
| `MCP_OPERATION_IN_PROGRESS`   | Identical effect is still running         | Retry after the supplied delay                |
| `MCP_TOOL_TIMEOUT`            | A read deadline expired                   | Retry or narrow the query                     |
| `MCP_OUTCOME_UNKNOWN`         | A write exceeded the client deadline      | Read the resource state; never retry blindly  |
| `MCP_OUTPUT_TOO_LARGE`        | Request is too broad                      | Narrow filters or paginate                    |
| `MCP_INTERNAL_ERROR`          | Unexpected safe failure                   | Retry once and report the request ID          |

## Deliberately unavailable operations

The restaurant surface does not expose payment capture, refund, cancellation/rejection, destructive deletion, bulk export, campaigns, credentials, provider synchronization, full onboarding or platform administration. Do not attempt to emulate omitted setup operations by combining restaurant tools.
