---
title: MCP — agents and IDEs
description: Connect Claude Code, Cursor, or any MCP client to ARCNM over HTTP with a bearer token.
---

# MCP for agents and IDEs

ARCNM ships a [Model Context Protocol](https://modelcontextprotocol.io)
server, auto-generated from the REST API. MCP-speaking agents and IDEs
can quote parts, inspect calculations, and read your data through typed
tools — without you writing glue code.

Endpoint: `https://api.arcnm.io/mcp-server/mcp` (HTTP transport,
bearer-JWT protected).

---

## Why MCP, not REST

If you're writing application code, use [REST](./api/index.md). Pick MCP
when **an agent is the client** (Claude, Cursor, custom runtimes): it
discovers tools automatically and routes arguments through structured
schemas.

---

## Authentication

The MCP server is a bearer-token protected resource. It publishes
[RFC 9728 protected-resource metadata](https://datatracker.ietf.org/doc/html/rfc9728)
at `/.well-known/oauth-protected-resource`. The verifier accepts **either**
credential in the `Authorization: Bearer …` header:

- an ARCNM **API key** (`ak_live_…` / `ak_test_…`) — recommended for
  agents: long-lived, revocable, scoped (tried first); or
- a tenant-scoped **session access token** (JWT, audience-pinned to
  `/api/v1`; refresh tokens and other-audience tokens are rejected).

There is no browser consent flow yet — you supply the credential to your
client explicitly. Mint an API key in the dashboard (Settings → API
keys) and pass it as the bearer token.

---

## Connect

### Claude Code (CLI)

```bash
claude mcp add -t http arcnm https://api.arcnm.io/mcp-server/mcp \
  --header "Authorization: Bearer $ARCNM_MCP_TOKEN"
```

### Cursor

Add to `~/.cursor/mcp.json` (or project-scoped `.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "arcnm": {
      "transport": {
        "type": "http",
        "url": "https://api.arcnm.io/mcp-server/mcp",
        "headers": { "Authorization": "Bearer ${ARCNM_MCP_TOKEN}" }
      }
    }
  }
}
```

Restart Cursor; tools appear under the MCP picker.

### Other clients

Any MCP-compliant HTTP client works. Point the transport at
`https://api.arcnm.io/mcp-server/mcp`, send the bearer header, and call
the standard `tools/list` / `resources/list` methods to discover the
surface.

---

## What's exposed

Tools and resources are derived from the REST API and filtered through
an explicit allow-list:

- **GET** endpoints (parts, calculations, environments, your own identity)
  appear as MCP **resources** / resource-templates.
- **Write** endpoints (create a part, create/run/quote a calculation,
  upload inputs) appear as MCP **tools**.

Tool and resource names are generated from the REST operation ids
(roughly `<tag>_<operation>`, e.g. a calculation create/quote/run tool
under the `parts` tag). **The authoritative list is whatever
`tools/list` returns for your token** — generate it from the live server
rather than hardcoding names.

> **What's never exposed.** Wallet and billing operations, plan changes,
> member invites/roster, API-key minting, the credential vault, SSO/SCIM,
> raw payment-provider webhooks, feature flags, auth/session primitives,
> and user create/delete/password changes. An agent with a tenant token
> cannot move money, escalate access, mint credentials, or rewrite the
> tenant — those stay human-dashboard-only by design.

Scopes mirror the [REST scope catalog](./authentication.md#scopes): a
token needs `parts:read` to read and `parts:write` to create or run a
calculation. Request the minimum the agent needs.

---

## Tool annotations

Each tool carries MCP annotations the agent uses to decide how to call
it:

- `openWorldHint` is set on tools.
- `idempotentHint` is `false` for `POST` / `PATCH`, `true` for `PUT`.
- `destructiveHint` and `idempotentHint` are `true` for `DELETE`.

A well-behaved agent confirms with the user before calling a
`destructiveHint` tool.

---

## Worked example — agent quotes a part

```
user: Quote this STEP file at lot size 50, on our production env.
      [attaches bracket.step]

agent: <calls the parts upload-and-quote tool>
       cad_file=<bytes>, part_number="BRACKET-001",
       lot_size=50, costing_environment_id=<prod env id>

agent: ← { id: "9d…", status: "queued" }

agent: <polls the get-calculation resource for 9d… until status=succeeded>

agent: Unit cost at lot size 50 is €12.84 (total €642.00, setup €52.50).
       The full breakdown is on the calculation's analytics blob.
```

The agent didn't write a line of REST glue.

---

## Rate limits & billing

MCP traffic is handled by the MCP server's own verification and is **not**
subject to the REST per-request quota bucket. You're billed for the
underlying billable operation (a successful calculation), not per tool
call — read-only tools and resources are free.

---

## Local development

Run a local backend and point your MCP client at
`http://localhost:8000/mcp-server/mcp` with a dev bearer token — an
`ak_test_…` API key works well locally. The MCP transport reads the
`Authorization: Bearer` header only (an API key or a session JWT); there
is no `X-API-Key` header path on the MCP server — that header is REST-only.

---

## See also

- [Authentication](./authentication.md) — bearer auth, scopes.
- [API reference](./api/index.md) — the REST surface MCP wraps.
- [Recipes → Quote a part](./recipes/quote-a-part.md) — end-to-end flow.
- [MCP spec](https://modelcontextprotocol.io) — the protocol itself.
