MCP reference
OpenApps MCP reference.
The contract for https://mcp.openapps.network/connect, the one connection for every app: transports, protocol versions, sign-in, scopes, the six tools, and the shape of results and errors. For a walkthrough, read the agents guide first.
Last updated: 5 October 2026
/connect is Building. It shares its host and its sign-in with OpenWallet's server, which is live at /mcp (moving to /openwallet) and documented in the OpenWallet tool reference. Rows below marked Live are true of that server today. Field names in the tool shapes may change before launch; this page will change with them.
Endpoint and protocol.
| Value | |
|---|---|
| Endpoint | https://mcp.openapps.network/connect Building. A trailing slash reaches the same server. |
| Transport | Streamable HTTP, POST only. GET and DELETE answer 405. No session id. |
| Protocol versions | 2026-07-28 (stateless, server/discover) and 2025-11-25 (the initialize handshake), side by side. A sunset date for the older one will be published here. |
| Server name | openapps, title OpenApps |
| Request size | Up to 1 MiB; larger requests are refused. Files go through uploads. |
| Time per call | Never more than 45 seconds. Long work is started, then polled. |
| Headers checked | MCP-Protocol-Version against the request's _meta; Mcp-Method and Mcp-Name against the body; Origin when present. |
| Tracing | A traceparent in _meta is carried into the run. |
Addresses on this host.
One host, one address per connection. No address is a prefix of another, so a token issued for one is never accepted at another.
| Address | What it is | Status |
|---|---|---|
/connect | Every app, six tools (this page) | Building |
/openwallet | OpenWallet's own tools | Building |
/mcp | OpenWallet's own tools, at their original address. Kept working after the move, because tokens already issued are bound to it. | Live |
/open… | One app on its own, named after the app: /openpdfedit, /openslides, … | Planned |
/ | A page for people, saying which address to use | Planned |
The host's other paths (/authorize, /token, /register, /revoke, the approval pages under /connect/…, /v1/…) are part of sign-in and runs, not MCP connections.
Discovery.
| Where | What | Status |
|---|---|---|
/.well-known/oauth-protected-resource/connect | Protected-resource metadata (RFC 9728) for /connect: which authorization server and scopes. Each address has its own, ending in its path. | Building |
/.well-known/oauth-protected-resource/mcp | The same, for OpenWallet's server at /mcp | Live |
/.well-known/oauth-authorization-server | Authorization-server metadata (RFC 8414) | Live |
/.well-known/mcp/server-card.json | Server card: name, remotes, protocol versions, tools, docs. Server cards are still a draft proposal, so the fields follow our reading of it. | Planned |
| MCP Registry | Listed as network.openapps/openapps, verified by DNS | Planned |
docs.openapps.network/llms.txt | A plain-text map of these docs for agents | Live |
Authorization.
OpenApps MCP is an OAuth 2.1 resource server, as the MCP authorization spec describes. The issuer is https://mcp.openapps.network, and the people behind each connection sign in with OpenWallet ID.
| Value | Status | |
|---|---|---|
| Grant | Authorization code with PKCE (S256 only), plus rotating refresh tokens | Live |
| Resource indicator | RFC 8707: ask for the resource you will call. Tokens are bound to it. | Live |
| Issuer in the response | RFC 9207 iss on the redirect | Live |
| Client registration | Dynamic client registration at /register | Live |
| Client ID metadata documents | Use an https URL you control as your client id, with no registration. Registration stays for older clients. | Planned |
| Access tokens | Short-lived, sent as Authorization: Bearer. Usable only at the resource they were issued for. | Live |
Without a token you may call server/discover, tools/list, openapps_find and openapps_feedback, at a lower rate limit. Anything else without the right token answers 401, or 403 if a scope is missing, with a header saying what to ask for:
WWW-Authenticate: Bearer resource_metadata="https://mcp.openapps.network/.well-known/oauth-protected-resource/connect", scope="apps:run"
Scopes
| Scope | Allows | Status |
|---|---|---|
wallet:read | See the agent wallet's status, balance and payments | Live |
wallet:pay | Ask OpenWallet to pay an x402 invoice within the person's limits | Live |
apps:run | Plan, start, watch and read receipts for operations | Building |
credits:spend | Pay for runs with the person's OpenApps credits, within their delegation | Building |
feedback:write | File feedback as the signed-in person; implied by any token | Planned |
The six tools.
Descriptions are fixed: they never include a caller's limits, today's prices or the size of the catalogue. The list is sorted by name, marked cacheScope: "public", and cached for a day.
| Tool | Read-only | Destructive | Idempotent | Open-world | Needs |
|---|---|---|---|---|---|
openapps_find | yes | no | yes | no | nothing |
openapps_plan | yes | no | no | no | apps:run |
openapps_start | no | yes | no | no | apps:run and a spend scope |
openapps_status | yes | no | yes | no | apps:run |
openapps_receipt | yes | no | yes | no | apps:run |
openapps_feedback | no | no | no | no | nothing |
openapps_start is marked destructive because a charge cannot be undone by the caller. A failed run is refunded by the system.
openapps_find
Search the catalogue, or fetch one operation's full contract.
{ "query": "split this PDF into invoices and pull the totals",
"filters": { "app": ["openextract"], "max_price_usd": 0.5,
"effects": ["reads", "writes"], "runs_on": "remote" },
"limit": 5, // 1–10
"cursor": "…" }
// or, for one operation's full contract:
{ "detail": "doc.extract_to_schema" }
Returns compact cards (id, app, title, summary, price.typical_usd, price.p95_usd, grade, effects, runs_on), total_matches and next_cursor. Signed in, it also returns the account's credits and remaining limits. When nothing matches, no_match suggests near misses. Queries can be in any of our eight languages.
openapps_plan
Turn a job and its inputs into a priced plan.
{ "intent": "one PDF per invoice, with the totals",
"files": [ { "file_id": "f_…" } ], // or { "url": "https://…" }
"policy": "balanced" } // best | balanced | cheapest
Returns plan_id, the quote, its classification, and needs_upload: a list of { name, accept, max_bytes, upload_url } for inputs still missing. A file path is refused.
openapps_start
{ "plan_id": "pl_…",
"authorization": { "kind": "credits" }, // OpenApps credits
// or { "kind": "openwallet", "max_usd": 0.5 } device-approved
"idempotency_key": "…", // required
"events": true } // optional AG-UI stream
Returns at once: run_id, state (queued, awaiting_approval or running), approval (url, expires_at) when the person must approve, events_url, and poll_after_ms. The same idempotency key for the same plan returns the same run.
openapps_status
{ "run_id": "run_…", "wait_ms": 30000 }. Holds for up to 45 seconds and returns as soon as the run changes: its state, step progress, what has been charged, and finished results as resource_links valid for one hour.
openapps_receipt
{ "run_id": "run_…" }. The Ed25519-signed receipt and how to verify it offline. The public keys are at https://mcp.openapps.network/v1/keys.
openapps_feedback
A report (kind, about, summary, details, expected, actual, error_code, contact_ok) returns ticket_id and status_url. { "ticket_id": "fb_…" } returns its state: received, triaged, planned, fixed_in a version, or wont_fix with a reason. The same report is accepted without MCP at POST https://mcp.openapps.network/v1/feedback. Limits: 20 reports an hour per token, 5 when anonymous.
Results and errors.
- Structured results come in
structuredContent, matching the tool'soutputSchema. The text block is a one-line summary, not the same JSON again. - Every result carries
_meta["network.openapps/manifest"], the SHA-256 of the canonical tool list. If it changes, the tools changed. - A malformed request or an unknown tool is a JSON-RPC
-32602. - Bad arguments, refusals and failures are a result with
isError: trueandstructuredContent: { code, message, retryable, details? }.codeis stable and snake_case;messageis for people.
| HTTP status | Meaning |
|---|---|
401 | No token, or not one for this resource. Read WWW-Authenticate. |
403 | The token is valid but lacks a scope. |
405 | GET or DELETE on /mcp. |
429 | Rate limited. Wait, then retry with the same idempotency key. |
MCP servers inside the apps.
Building Some apps also ship their own MCP server that runs on your machine over stdio, for people who run the app locally: OpenPdfEdit, OpenRedact, OpenExtract, OpenOCR, OpenSlides, OpenPhotoEdit and others. Each will document its own install line when it ships. They all follow the same rules, so an agent that has used one knows them all:
- Tool names are lower snake_case, verb first, and say what they act on:
redact_pdf,list_ocr_operations,undo_photo_edit. - Every tool has a title and all four annotations, and they are true.
- At most fifteen tools by default; more sit behind a start-up flag.
- They read and write only inside the folders you name when you start them, and take paths in and give paths out.
- Credentials, signing keys and which programs to run come from start-up flags or the environment, never from a tool argument the model fills in.
- Each has a
report_problemtool. A local server never sends anything on its own: it sends a report only if you started it with--feedbackor you confirm, and otherwise hands you the finished report to send yourself.