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

# Connect your agent

> Give Claude Code, Codex, Cursor, OpenCode or any MCP host a set of document tools, in one config block per client

anyformat speaks [MCP](https://modelcontextprotocol.io), so the agent you already use can parse documents, build workflows and read results without you writing any code. One endpoint, one key, one config block per client.

|               |                                           |
| ------------- | ----------------------------------------- |
| **URL**       | `https://api.anyformat.ai/mcp`            |
| **Transport** | Streamable HTTP                           |
| **Auth**      | `Authorization: Bearer <your af_... key>` |

Mint a key at [app.anyformat.ai/api-key](https://app.anyformat.ai/api-key) and export it before you start. The same key works on the REST API.

```bash theme={null}
export ANYFORMAT_API_KEY="af_..."
```

## Pick your client

<Tabs>
  <Tab title="Claude Code">
    One command, and `--scope user` makes it available in every project:

    ```bash theme={null}
    claude mcp add --transport http anyformat https://api.anyformat.ai/mcp \
      --header "Authorization: Bearer $ANYFORMAT_API_KEY" --scope user
    ```

    Or commit it to the project by writing `.mcp.json` in the repository root. Claude Code expands `${VAR}` from the environment, so the key stays out of the file:

    ```json theme={null}
    {
      "mcpServers": {
        "anyformat": {
          "type": "http",
          "url": "https://api.anyformat.ai/mcp",
          "headers": { "Authorization": "Bearer ${ANYFORMAT_API_KEY}" }
        }
      }
    }
    ```

    Confirm with `claude mcp list`.
  </Tab>

  <Tab title="Codex CLI">
    Add the server from the command line:

    ```bash theme={null}
    codex mcp add anyformat --url https://api.anyformat.ai/mcp
    ```

    Then put the header in `~/.codex/config.toml`. `env_http_headers` reads the value from the named environment variable, so the key is never written to the file:

    ```toml theme={null}
    [mcp_servers.anyformat]
    url = "https://api.anyformat.ai/mcp"
    env_http_headers = { "Authorization" = "ANYFORMAT_MCP_AUTH" }
    ```

    ```bash theme={null}
    export ANYFORMAT_MCP_AUTH="Bearer $ANYFORMAT_API_KEY"
    ```

    Confirm with `codex mcp list`, then restart Codex. A project-scoped `.codex/config.toml` works the same way in a trusted project.
  </Tab>

  <Tab title="Cursor">
    Add the server to `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one. Cursor expands `${env:VAR}`:

    ```json theme={null}
    {
      "mcpServers": {
        "anyformat": {
          "url": "https://api.anyformat.ai/mcp",
          "headers": { "Authorization": "Bearer ${env:ANYFORMAT_API_KEY}" }
        }
      }
    }
    ```
  </Tab>

  <Tab title="OpenCode">
    Add it to `opencode.json` as a remote server. OpenCode interpolates `{env:VAR}`:

    ```json theme={null}
    {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "anyformat": {
          "type": "remote",
          "url": "https://api.anyformat.ai/mcp",
          "enabled": true,
          "headers": { "Authorization": "Bearer {env:ANYFORMAT_API_KEY}" }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Claude Desktop and stdio-only hosts">
    A host that can only launch a local stdio process reaches the endpoint through a bridge. [`mcp-remote`](https://github.com/geelen/mcp-remote) is the Node one. Put the header value in an environment variable so the space in `Bearer ...` survives argument parsing:

    ```json theme={null}
    {
      "mcpServers": {
        "anyformat": {
          "command": "npx",
          "args": [
            "mcp-remote",
            "https://api.anyformat.ai/mcp",
            "--header",
            "Authorization:${AUTH_HEADER}"
          ],
          "env": { "AUTH_HEADER": "Bearer af_..." }
        }
      }
    }
    ```

    [`fastmcp-remote`](https://pypi.org/project/fastmcp-remote/) is the Python equivalent, run with `uvx`. It takes the header as one argument, so it needs no environment variable:

    ```bash theme={null}
    uvx fastmcp-remote https://api.anyformat.ai/mcp \
      --header "Authorization: Bearer $ANYFORMAT_API_KEY"
    ```

    Both bridges skip their own OAuth flow when you give them an `Authorization` header. For Claude Desktop the file is `claude_desktop_config.json`, under **Settings → Developer**.
  </Tab>

  <Tab title="Anything else">
    Any MCP host that lets you set a header on a streamable HTTP server will work. This handshake is the whole contract:

    ```bash theme={null}
    curl -X POST https://api.anyformat.ai/mcp \
      -H "Authorization: Bearer $ANYFORMAT_API_KEY" \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json, text/event-stream' \
      -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
    ```
  </Tab>
</Tabs>

<Note>
  The **Custom connectors** panel in Claude on the web, in Cowork and in Claude Desktop expects a remote server that speaks OAuth. anyformat authenticates with an API key header and has no OAuth flow today, so connect it from a client that can set a header, or through one of the stdio bridges above.
</Note>

## Check it worked

Ask the agent something only anyformat can answer:

> **"List my anyformat workflows."**

If the key is wrong you get an authentication error rather than an empty list. If the tools are missing entirely, the host has not reloaded its config: restart it.

## The first three things to ask

> **"Parse invoice.pdf with anyformat and save the markdown to invoice.md."**

> **"Build an anyformat workflow that pulls the invoice number, the total and the due date, then run every PDF in ./inbox through it and write the results to a CSV."**

> **"Which of my anyformat runs failed yesterday, and why?"**

The agent stages the local file, creates the workflow, runs the documents and polls until each run is terminal. [Agents over MCP](/guides/mcp) walks one real session call by call.

## What the agent can reach

Sixteen tools, split by what your key is allowed to do. A key with `read` scope only never sees the tools that write: they are absent from the tool list rather than failing when called.

| Group     | Tools                                                                           |
| --------- | ------------------------------------------------------------------------------- |
| Workflows | list, get, create, update, delete, list versions                                |
| Documents | stage files, upload documents, run a packet, get a packet, list packets, delete |
| Runs      | get a run, list runs                                                            |
| Reading   | parse a document, ask the knowledge base                                        |

The [MCP server reference](/api-reference-v3/mcp) has the full table, the scopes and the error shapes.

## Not using an agent?

The [Claude Code skill](/guides/coding-assistant) teaches Claude the workflow API without MCP, and the [SDKs](/api-reference-v3/sdks) do the same job from your own code.

## Next steps

<CardGroup cols={2}>
  <Card title="Agents over MCP" icon="robot" href="/guides/mcp">
    One real session, call by call, with every payload
  </Card>

  <Card title="MCP server reference" icon="plug" href="/api-reference-v3/mcp">
    Endpoint, auth, scopes and every tool
  </Card>
</CardGroup>
