# MCP

arbitr exposes the published `/v1` API as a hosted [MCP](https://modelcontextprotocol.io/) server so a coding agent can call it as tools. Auth is the **same API key** as curl and the CLI — there is no OAuth login yet.

Use the [CLI](/getting-started/cli) for files on disk. MCP submit takes a public `https` URL, not a local path.

## Endpoint

```text
https://api-arbitr.straker.ai/mcp/
```

Streamable HTTP. Include the trailing slash. After you connect, the client lists the tools. They map to published `/v1` operations. Deprecated HTTP aliases are not tools.

## Auth

Mint a key under **Settings → API Keys**. See [Create an API key](/getting-started/create-an-api-key). For submit, poll, and download the key needs both `verify:submit` and `verify:read`. Send it on every MCP request as either:

```text
X-API-Key: abr_live_…
```

or `Authorization: Bearer abr_live_…`. A missing key fails at connect (`401`). Prefer interpolating `ARBITR_API_KEY` from the environment so the key is not committed or pasted into chat.

A test key (`abr_test_…`) works the same way. It does not run the pipeline — read [Test mode](/concepts/test-mode) first.

Check the key with `getCurrentKey` (or `arbitr me`) before you submit. That call works with any valid key.

## Cursor

Merge this into `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (user). Do not replace unrelated servers.

```json
{
  "mcpServers": {
    "arbitr": {
      "url": "https://api-arbitr.straker.ai/mcp/",
      "headers": {
        "X-API-Key": "${env:ARBITR_API_KEY}"
      }
    }
  }
}
```

Set `ARBITR_API_KEY` the same way as the CLI. Reload MCP if the server does not appear.

## Claude Code

```bash
claude mcp add --transport http arbitr https://api-arbitr.straker.ai/mcp/ \
  --header "X-API-Key: ${ARBITR_API_KEY}"
```

The shell must already export `ARBITR_API_KEY`. Do not put the plaintext key on the command line.

## Tools

CamelCase names match the published `/v1` `operationId`s. A new REST route does not become a tool until it is registered.

| Tool | Does | Scope |
| --- | --- | --- |
| `submitProject` | Create a project from a public `https` `file_url` | `verify:submit` |
| `getProject` | Poll one project's status | `verify:read` |
| `listProjects` | List projects (`page`, `limit`, optional `status`, `modified_after`) | `verify:read` |
| `listDeliverables` | List files for a completed project; returns download URLs, not bytes | `verify:read` |
| `createProjectResumption` | Resume after an intelligence-credit hold | `verify:submit` |
| `createReviewResumption` | Resume after a trust-credit hold | `verify:submit` |
| `listLanguages` | Supported lowercase BCP-47 codes | any valid key |
| `getCreditBalance` | Intelligence and trust balances | any valid key |
| `getCurrentKey` | Org, mode, and scopes for this key | any valid key |

Webhooks, MT models, and deprecated verb-path aliases (`/resume`, `/deliverables/zip`) are not tools.

## Submit vs the CLI

`submitProject` fetches **one** source file from a public `https` `file_url` after the key is validated. Local paths, inline bytes, and `http` URLs are rejected. For a file on disk, or more than one file, use `arbitr submit` or [Create a project](/guides/create-a-project).

The fetch is capped at **25 MB** (REST multipart allows 200 MB). Larger files need the CLI or REST.

| Argument | Required | Notes |
| --- | --- | --- |
| `file_url` | yes | Public `https` URL of the source document |
| `name` | yes | Shown in the arbitr UI |
| `source_language_code` | yes | Lowercase BCP-47, e.g. `en-us` |
| `target_language_codes` | yes | List of lowercase BCP-47 tags |
| `workflow` | yes | `AI_TRANSLATION` first; optional `TRANSLATION`, `EDIT` |
| `due_date` | no | `YYYY-MM-DD`. Informational only |
| `filename` | no | Override; otherwise derived from the URL |
| `idempotency_key` | no | Same contract as REST `Idempotency-Key` — see [Idempotency](/concepts/idempotency) |

The call spends credits. Locales are lowercase BCP-47 (`ko-kr`, not `ko`). Use `listLanguages` for the exact `bcp47` values.

## Typical flow

1. `submitProject` — copy `id` from the result.
2. Poll `getProject` until a terminal status. Stop on `completed` (download), `failed` / `cancelled` (stop), or `awaiting_payment` (top up, then `createProjectResumption` or `createReviewResumption`). See [Poll project status](/guides/poll-project-status).
3. `listDeliverables` once `status` is `completed`. Each item has a key-gated `download_url`. The payload also has `zip_download_url`.
4. Fetch those URLs with the same API key. For a single file, send `Accept: application/octet-stream` to get bytes rather than metadata. See [Download deliverables](/guides/download-deliverables).

Sleep a few seconds between `getProject` calls. Tight loops hit [rate limits](/concepts/rate-limits).

## Failures

| What you see | Typical cause |
| --- | --- |
| HTTP `401` `invalid_api_key` at connect | Missing `X-API-Key` / `Authorization: Bearer` |
| Tool error `invalid_api_key` | Unknown or revoked key |
| Tool error `missing_scope: verify:submit` | Key lacks `verify:submit` |
| Tool error with `422` / `402` / `429` | Same as the matching `/v1` failure |

Keep `request_id` if you contact [Support](/support).

## Coding agents

This page is the MCP playbook. Fetch it as markdown:

```text
https://arbitr.apidocumentation.com/getting-started/mcp/index.md
```

Do not submit a project during setup. Confirm the key with `getCurrentKey` (or `arbitr me`) first.
