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

# AI agents (MCP)

Geopera exposes its operations to AI agents through the **Model Context Protocol (MCP)**.
The MCP gateway turns the kernel's operation registry into a catalog of tools — one tool
per operation — so an agent (Claude Desktop, an IDE assistant, your own MCP client) can
search imagery, place orders, run analytics, and manage data with the *same* auth,
scopes, validation, and provenance as any other client.

## How it works

The gateway is a standalone process that reads the kernel's reflected OpenAPI and
projects each operation into an MCP tool. It imports nothing from the backend — it's
just another client of the same `POST /v1/op/{operation_id}` surface the REST API, the
SDKs, and the portal use. Because the OpenAPI is a projection of the registry, the tool
set tracks the registry by construction: **add an operation, get a tool**, with no extra
wiring.

What the projection adds on top of the raw operations:

- **Tool name = `operation_id`.** `orders.archive.place` is the tool name — the canonical
  kernel identity, so there's no separate naming scheme to learn.
- **Safety hints from the side-effect tier.** Each tool is annotated from the operation's
  `x-side-effect`: `read` operations get a `readOnlyHint`, `destructive` operations get a
  `destructiveHint`. An agent can reason about whether a call is safe *before* it makes
  it.
- **Streaming operations excluded.** Operations that return NDJSON or binary streams
  (`x-raw-response`) don't fit the request → single-result tool model and are excluded;
  their non-streaming siblings are exposed instead.

## Run the gateway

The gateway connects over stdio by default (how Claude Desktop and most MCP clients
attach):

```bash
GEOPERA_API_URL=https://api.geopera.com \
GEOPERA_API_TOKEN=<your-jwt> \
python server.py
```

Set `MCP_TRANSPORT=http` to expose an HTTP endpoint instead of stdio. The token is a
normal Geopera access token (obtain it via the OIDC token endpoint — see
[Authentication](/api-reference/authentication)), so the agent acts as whatever principal
that token represents, with exactly that principal's scopes. An agent can do nothing the
token couldn't do directly.

## What an agent can do

Because every operation is a tool, an agent can drive complete workflows:

- **Discover** — `catalog.search`, `items.search`, `analytics.operations.list` (read,
  safe).
- **Estimate** — `orders.archive.estimate`, `orders.tasking.estimate` (read, safe — get a
  price before spending).
- **Act** — `orders.archive.place`, `processing.create_and_dispatch`, `billing.topup`
  (spend; flagged so the agent knows real money / credits move).
- **Analyse** — `analytics.execute` (run change detection, zonal stats, indices over
  items).

The same scope and provenance guarantees apply. An agent calling `orders.archive.place`
needs `orders:write`; the order it places is recorded with full lineage; a payment
problem comes back as a `402` it can reason about. Nothing about the agent path is a
lesser-governed shortcut.

## Why this is safe by design

The governance lives in the kernel, not in the client. So an agent gets the same
treatment as the portal or an SDK:

- it can't invoke an operation it lacks the scope for,
- it can't skip input validation or produce data without recording provenance,
- and the side-effect tier is surfaced as a tool annotation, so a well-behaved agent
  surfaces destructive or money-moving actions for confirmation before calling them.

This is the practical reason the operation model matters for agents: the safety
properties are intrinsic to the capability, so exposing capabilities to an autonomous
caller doesn't require a second, parallel safety system.
