<!-- Source: https://docs.geopera.com/api-reference/sdks/mcp/authentication · Markdown for LLMs -->

# MCP authentication & token modes

An MCP client connects to Geopera in one of two ways, and every tool call it makes is forwarded upstream as `Authorization: Bearer …` on a `POST /v1/op/{operation_id}` request. Whatever token reaches Geopera is validated by the same rules as any direct API call: a `gpra_` API key or a session token (obtained by signing in to Geopera). See [Authentication](/api-reference/authentication) for how those tokens resolve, and [Scopes](/api-reference/scopes) for what a given token is allowed to call.

## The two modes at a glance

| Mode   | You connect to        | Caller identity               | Each tool call runs as                    |
| ------ | --------------------- | ----------------------------- | ----------------------------------------- |
| Hosted | the hosted MCP URL    | browser sign-in               | you, with your own scopes and audit trail |
| Local  | a local stdio process | a `gpra_` API key you provide | the identity behind that key              |

## Mode A — hosted (sign in through your browser)

This is the product endpoint: one server, `https://mcp.geopera.com/mcp/`, that any user connects to. The MCP client opens a browser sign-in flow; once you sign in to Geopera, the agent acts as _you_. Every tool call runs with your scopes, your audit trail, and your provenance — no keys are copy-pasted.

Connecting from a client: add the remote server `https://mcp.geopera.com/mcp/` and approve the sign-in prompt. The client handles the sign-in flow automatically, and from then on each call the agent makes is attributed to you.

## Mode B — local (stdio with a `gpra_` key)

This is how a desktop MCP client (Claude Desktop, Claude Code) launches the gateway per user. You provide two things: the Geopera API URL and a token. Every upstream call is made with that one static token, so every tool call runs as the identity behind it.

Set:

- `GEOPERA_API_URL` — the Geopera API the gateway talks to (`https://api.geopera.com`).
- `GEOPERA_API_TOKEN` — a minted `gpra_` API key.

```bash
GEOPERA_API_URL=https://api.geopera.com \
GEOPERA_API_TOKEN=gpra_your_key_here \
geopera-mcp
```

Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
	"mcpServers": {
		"geopera": {
			"command": "geopera-mcp",
			"env": {
				"GEOPERA_API_URL": "https://api.geopera.com",
				"GEOPERA_API_TOKEN": "gpra_your_key_here"
			}
		}
	}
}
```

Every tool call therefore runs as the identity behind that one token. If `GEOPERA_API_TOKEN` is unset, tool calls go upstream unauthenticated and will be rejected.

## Choosing a mode

|          | Hosted                                               | Local                                                       |
| -------- | ---------------------------------------------------- | ----------------------------------------------------------- |
| Identity | each user signs in; the agent acts as them           | a single `gpra_` key for the process                        |
| Best for | letting multiple users connect, per-user attribution | a single user, headless or desktop, who already holds a key |
| Setup    | add the hosted URL, approve the sign-in prompt       | set `GEOPERA_API_URL` + `GEOPERA_API_TOKEN`                 |

## Admin and internal operations are never exposed

Regardless of which mode you use, the MCP surface is the customer-safe set of operations. Admin, internal, and diagnostics operations are not registered as MCP tools at all — there is no tool for them, so no token (not even a privileged one) can reach them through an MCP client.

This is independent of scopes. The token you connect with still carries [scopes](/api-reference/scopes), and a tool that _does_ exist will still be rejected upstream if your token lacks the required scope.

## Worked example: hosted, end to end

A user connects Claude to the hosted endpoint and asks it to run a read operation. The credential flow:

```http
POST /v1/op/orders.list HTTP/1.1
Host: api.geopera.com
Authorization: Bearer <your session token>
Content-Type: application/json

{}
```

1. The MCP client connects to `https://mcp.geopera.com/mcp/` and you sign in to Geopera through your browser.
2. The client calls a tool (say `orders.list`).
3. The call is forwarded upstream as `Authorization: Bearer <your token>`.
4. Geopera validates the token, applies your scopes, runs `orders.list`, and records the action against you.

If you instead run locally over stdio, those steps collapse to a single static `GEOPERA_API_TOKEN` on every call, and every action is attributed to whatever identity that key represents.

## Failure modes and gotchas

- **Local with no `GEOPERA_API_TOKEN`** — every tool call goes upstream unauthenticated and is rejected. Set a `gpra_` key.
- **Expired or revoked token** — the call is rejected; mint or rotate a key, or sign in again in hosted mode.
- **Auth errors** surface as RFC 7807/9457 problem+json. See [Errors](/api-reference/errors) for the shape and how to interpret an authentication or authorization failure.

## Related

- [Authentication](/api-reference/authentication) — how `gpra_` keys and session tokens resolve.
- [Scopes](/api-reference/scopes) — what a given token is permitted to call.
- [Operations](/api-reference/operations) — the operation surface the MCP tools mirror.
- [Errors](/api-reference/errors) — the problem+json contract for auth failures.
