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

# Conventions

> How every Pomerado MCP and integration MCP tool returns results, marks its effect, takes idempotency keys and reports errors.

Every tool on the Pomerado MCP and on integration MCPs returns results, marks its effect, takes idempotency keys and reports errors the same way. Each tool's own page lists its arguments.

## Read the result

A tool returns JSON inside one text content item. Run, build and job tools return the [job object](/guides/jobs/job-object), the same object the REST API returns:

```json theme={null}
{
  "content": [
    {
      "type": "text",
      "text": "{\"id\":\"job_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190\",\"type\":\"run\",\"status\":\"running\",...,\"next\":{...}}"
    }
  ]
}
```

A complete MCP response doesn't mean the job has finished: check its `status`.

Use the tool names and input schemas that `tools/list` returns. The run tools take `input`, and `build_website_tool` takes `example_input`, as a JSON-encoded string; an integration MCP's own tools take `input` as plain JSON. A call with an argument the tool doesn't list is refused with `invalid_request`.

## Follow next

A live job also carries `next`, the exact call to make next. Follow it instead of calling the run again. See [Follow next](/guides/jobs/wait-for-a-result#follow-next).

## Check the effect

Each tool page states the tool's effect, which the tool's MCP annotations also carry:

* **Reads only:** the tool changes nothing, so clients may run it without asking and run several at once. `run_read_only_website_tool` refuses a tool that writes with `tool_not_read_only` before any job starts.
* **May change a website or your account:** clients usually ask the user before calling it.
* **May not be undoable:** the change may be permanent.

## Send an idempotency key

Send `idempotency_key` with every write.

Without a key, every call is a new website action. Reuse and conflicts are covered in [Retry a call safely](/guides/tools/retries-and-idempotency).

## Handle errors

A failed call sets `isError` to `true`. Its text is the [error object](/errors), plus `retry_after_seconds` when it is retryable:

```json theme={null}
{
  "error": {
    "code": "temporarily_unavailable",
    "message": "A Pomerado service this request needs did not answer, so nothing was done. Wait a few seconds and send the same request again.",
    "retryable": true,
    "docs_url": "https://docs.pomerado.ai/errors#temporarily_unavailable",
    "details": {}
  },
  "retry_after_seconds": 5
}
```

Branch on `code`, never on `message`. A run whose job failed is also an error result, carrying the job with its `error`.

<Accordion title="Details">
  * A rejected or expired access token answers HTTP `401`, and a missing permission HTTP `403`. Reconnect or ask for the permission.
  * A malformed protocol request answers a JSON-RPC error.
  * `write_possibly_accepted: true` marks a write sent without a key whose failure may follow an accepted write. Check the job before calling again.
</Accordion>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.