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

# MCP server

> Connect AI assistants to your ArcenPay account over the Model Context Protocol — a hosted read-only server plus a local agent server.

ArcenPay exposes **Model Context Protocol (MCP)** servers so assistants and
agents can work with your account. There are two surfaces, deliberately
separated:

| Server | What it can do | Runs where | Transport |
| - | - | - | - |
| **Local agent server** (`arcenpay-mcp`) | Payments, x402 fetches, session funding, mandates, escrow | Your machine (holds the agent's own key) | stdio |
| **Hosted server** (`/mcp`) | Read-only account data (companies, plans, subscriptions, entitlements, invoices, payment links, mandates, chains) | ArcenPay backend | Streamable HTTP |

The hosted server is intentionally **read-only**: it never moves funds and never
changes billing state. Payment execution stays on the local agent, which holds
the key. See the [Agent SDK MCP tools](/sdk/agent/mcp-tools) for the local
server.

## Enable the hosted server

The endpoint is **off by default** — existing deployments are unchanged until
you enable it.

| Env var | Required | Purpose |
| - | - | - |
| `MCP_SERVER_ENABLED` | Yes | Set to `true` to mount `/mcp`, `/.well-known/*`, and `/oauth/*` |
| `MCP_RESOURCE_URL` | Yes | Canonical HTTPS identifier of this MCP server (e.g. `https://api.arcenpay.com`) |
| `MCP_OAUTH_ISSUER` | — | OAuth issuer; defaults to `MCP_RESOURCE_URL` |
| `MCP_OAUTH_SECRET` | Yes (for OAuth) | HMAC signing secret for access tokens; empty disables OAuth (API-key auth still works) |
| `MCP_DOMAIN_CHALLENGE_TOKEN` | For ChatGPT listing | Served verbatim at `/.well-known/openai-apps-challenge` during submission |

The server mounts at `POST /mcp` (Streamable HTTP, stateless). The MCP surface is
exempt from the edge bot/shield protection (it is consumed by machine clients
such as OpenAI's verifier and the ChatGPT/Codex connectors).

## Authentication

Two credential types are accepted:

* **OAuth 2.1 access token** — used by ChatGPT connectors, which cannot send a
  static API key. Authorization-code + PKCE (`S256`), public clients via Client
  ID Metadata Documents (CIMD).
* **API key** (`Authorization: Bearer sk_/rk_…`) — for Claude/Cursor/Codex and
  server-to-server clients.

```bash theme={null}
curl -X POST https://api.arcenpay.com/mcp \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

Publishable (`pk_`) keys are rejected. Every tool is scoped to the caller's team
and environment; a team id is never taken from the request. Requests without a
valid credential receive `401` with a `WWW-Authenticate` challenge pointing at
the protected-resource metadata.

### OAuth flow

1. The client opens `GET /oauth/authorize` with the standard OAuth parameters.
2. If the user has no session, the backend hands off to the dashboard's
   **consent screen** (`app.arcenpay.com/oauth/authorize`). The user signs in
   **once** if needed, then clicks **Authorize** — no repeated login.
3. The backend issues an authorization code; the client exchanges it at
   `POST /oauth/token` for an access token (+ refresh token), which is then sent
   as `Authorization: Bearer …` on every MCP request.

| Endpoint | Purpose |
| - | - |
| `GET /.well-known/oauth-protected-resource` | Resource metadata (`resource`, `authorization_servers`, scopes) |
| `GET /.well-known/oauth-authorization-server` | Authorization-server metadata |
| `GET /.well-known/openai-apps-challenge` | Domain-verification token (ChatGPT plugin submission) |
| `GET /oauth/authorize` | Authorization code + PKCE; hands off to the consent screen |
| `POST /oauth/token` | Exchanges a code (or a refresh token) for an access token |

## Tools (read-only)

| Tool | Returns |
| - | - |
| `get_account` | Team id, environment, key type, permissions |
| `list_companies` / `get_company` | Customer companies in the workspace |
| `list_plans` / `list_addons` | Published catalog plans and add-ons |
| `get_subscription` | A company's subscription state (status, period, grace) |
| `check_entitlement` | Whether a company is entitled to a feature key |
| `list_invoices` / `get_invoice` / `get_invoice_download_url` | Invoices + a signed PDF URL |
| `list_payment_links` / `get_payment_link_spec` | Payment links and their agentic spec |
| `get_mandate_status` | Agent mandate status |
| `get_settlement_status` | Escrow settlement status |
| `list_chains` | Supported chains and deployed contracts |

All tools carry `readOnlyHint: true`.

## Connect a client

* **MCP Inspector:** `npx @modelcontextprotocol/inspector` → Streamable HTTP →
  `https://api.arcenpay.com/mcp`, add the `Authorization` header.
* **ChatGPT:** add the MCP server URL and choose **OAuth**; you'll get the
  one-click consent screen.
* **Claude / Cursor / Codex:** add a remote MCP server with the `/mcp` URL and an
  API-key `Authorization` header.

## ChatGPT plugin

A packaged plugin (`plugin.json` + `mcp.json` + `skills/`) points ChatGPT at
`https://api.arcenpay.com/mcp`. Only the **read-only** account tools are
submitted for listing — payment and lifecycle operations are never part of the
public plugin, per the host's commerce rules.

<Note>
  State-changing operations (creating payment links, changing plans, issuing
  mandates) are **not** part of this read-only surface. They are available to
  MCP clients that operate against your own infrastructure, and their
  public-listing eligibility is constrained by the host's commerce rules.
</Note>


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