# MCP server

Connect your own Payer account to an AI assistant and ask about your money. Read-only, scoped to what you approve, and revocable at any time.

Payer runs a remote [Model Context Protocol](https://modelcontextprotocol.io) server, so you can connect your own Payer account to an AI assistant and ask about your money in plain language: what you spent last month, where it went, which bills are outstanding.

It is **read-only**. No tool on this server sends money, pays a bill, or changes anything in your account. Money movement needs confirmation on your own enrolled device, which is precisely the thing an assistant cannot do on your behalf.

## Endpoint

| | |
| --- | --- |
| Server | `https://mcp.payer.app/mcp` |
| Transport | Streamable HTTP, stateless |
| Metadata | `https://mcp.payer.app/.well-known/oauth-protected-resource` |

Most MCP clients only need the server URL. They read the metadata document to find out where to send you to sign in.

## What it can do

| Tool | Returns |
| --- | --- |
| `get_balance` | Your available wallet balance in MVR. |
| `list_transactions` | Your transaction history, filterable and paginated. |
| `get_transaction` | One transaction in full, by id. |
| `get_spending_insights` | Totals and spending by merchant and category, for a month or a year. |
| `list_service_accounts` | Your saved utility and telecom accounts. |
| `list_bills` | Outstanding and recent bills on one of those accounts. |

## Scopes

You approve scopes when you connect, and the token you approve decides which tools exist. The server lists only the tools your scopes permit, so an assistant never sees a tool that would fail when it called it.

| Scope | You are asked for | Unlocks |
| --- | --- | --- |
| `balances:read` | View your account balances | `get_balance` |
| `transactions:read` | View your transaction history | `list_transactions`, `get_transaction`, `get_spending_insights` |
| `accounts:read` | View your saved utility accounts and their bills | `list_service_accounts`, `list_bills` |

Three absences are deliberate:

- **No payment scopes.** Sending money requires per-transaction confirmation from your enrolled device. A scope cannot stand in for it, and an assistant that has just read a bill is exactly the case that rule exists for.
- **No `kyc:read`.** Nothing here needs your identity-document status, so nothing here asks for it.
- **No merchant access.** A connection acts as you, the person. Merchant data sits behind a [secret key](/developers/docs/authentication) and a merchant session, and neither is reachable from this server.

## Connect from Claude Code

A [personal access token](/developers/docs/personal-tokens) is the quickest route, because Claude Code can send a fixed header. Issue one from **Account → Tokens** in your dashboard with the scopes you want, then:

```bash title="Add the Payer MCP server"
claude mcp add --transport http payer https://mcp.payer.app/mcp \
  --header "Authorization: Bearer pat_..."
```

A PAT was never issued for one particular server, so it is accepted on its scopes alone. It carries the same access you already have over Payer's GraphQL API, and it expires: you set the lifetime when you create it, up to 365 days.

## Connect from claude.ai

Add a custom connector pointing at `https://mcp.payer.app/mcp`. Claude reads the metadata document, sends you to the Payer Connect consent screen to sign in and approve the scopes, and exchanges the result for a token behind the scenes.

Payer does not run dynamic client registration, so every client that can ask for your consent was registered by a person here. If you are setting up a connector and need client credentials, email [support@payer.mv](mailto:support@payer.mv).

## How the authorization works

The server is an OAuth 2.0 resource server and nothing else. It holds no credential of its own that can read your data, so it reaches exactly what your token reaches and no further.

```text title="What happens when you connect"
1. Client → reads /.well-known/oauth-protected-resource
2. Client → sends you to Payer Connect to sign in and consent
3. Payer  → issues an access token bound to https://mcp.payer.app/mcp
4. Client → calls the server with that token on every request
5. Server → asks the Payer API what the token holds, then reads as you
```

The token is bound to this server as its audience ([RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707)), so a token you approved for the MCP server cannot be replayed against anything else at Payer, and a token minted elsewhere is refused here. The full OAuth2 flow, for apps that act on other people's behalf, is on the [OAuth2 apps](/developers/docs/oauth) page.

## Disconnecting

**A personal access token:** delete it from **Account → Tokens**. It stops working immediately, everywhere it was used.

**A connected app:** revoking the connection ends the standing consent and every access and refresh token issued under it, in one step. A token that outlived its consent would make a disconnect button a lie, so both go together.

## One thing worth knowing

Transaction descriptions, merchant names and bill details are text written by other people and other systems. When an assistant reads them back to you, treat that as information to check rather than as instructions to act on, the same way you would treat the contents of an email.
