MCP Concepts
The model behind Picora’s MCP integration: who is allowed to call what, what it costs, and what happens when a tool changes. If you only want to wire a client up, start with the quickstart.
Two authentication models
Picora’s MCP server accepts two credentials. Both resolve to the same internal permission set, so a tool behaves identically either way.
| API Key (stdio) | OAuth 2.1 (remote) | |
|---|---|---|
| Format | sk_live_ + 32 chars | RS256 JWT Bearer token |
| Who issues it | You, from the dashboard | The authorization flow, after browser consent |
| Lifetime | Until you revoke it | Short-lived access token + rotating refresh token |
| Granularity | Three tiers, expanded to scopes | Scopes chosen per grant |
| Where it lives | Plaintext in a client config file | Client’s token store |
API Key tiers expand to scopes
An API Key carries a tier, which the server expands into the same dot-notation scopes OAuth uses:
| Key tier | Expands to |
|---|---|
read | media.read, kb.read, account.read, usage.read |
read_write | the above + media.write, kb.write |
read_write_delete | the above + media.delete |
This is why the two models are interchangeable: a read_write key and an OAuth token granted media.read media.write kb.read kb.write usage.read unlock exactly the same tools.
The seven scopes
| Scope | Grants | MCP tools |
|---|---|---|
media.read | List and inspect images, videos, audio | list_media, get_media |
media.write | Upload media, change title / visibility | upload_image, upload_video, upload_audio, update_media |
media.delete | Permanently delete media | delete_media |
kb.read | Read documents and knowledge bases | list_docs, get_doc, list_kbs, get_kb_manifest, read_kb_doc |
kb.write | Create, update and delete documents and KBs | upload_doc, delete_doc, create_kb, sync_kb |
usage.read | Read plan, storage and bandwidth counters | get_usage |
account.read | Read basic profile information | (none — no MCP tool needs it) |
Two tools — picora.help and picora.about — declare no scope at all. An agent can introspect what Picora offers before any credential exists, which is why “ask the assistant to call picora.help” is the standard smoke test.
Note that kb.write covers document deletion; there is no separate kb.delete. Media deletion is separate, because it is the most destructive thing an agent can do.
Older colon-style scope names (read:media, write:kb, …) are still resolved to their dot-notation equivalents, so clients configured against earlier releases keep working.
Plan gates
Scope answers “is this client allowed?”; the plan answers “does this account include the feature?”. They are checked independently.
Exactly one tool has a plan gate: picora.upload_video requires the Pro plan (Pro allows files up to 500 MB, Pro+ up to 2 GB). Everything else is available on any plan.
Some tools have limits that vary by plan without being gated:
| Limit | Trial | Pro | Pro+ |
|---|---|---|---|
| Audio file size | 50 MB | 100 MB | 500 MB |
| Knowledge bases | 5 | 50 | 500 |
| KB tombstone retention | 30 days | 30 days | 90 days |
Storage, bandwidth and document counts are also plan-dependent — call picora.get_usage to read the current state, and see plan comparison for the full matrix.
Order of checks
Before a tool executes, the server evaluates, in this order — the first failure short-circuits:
- Is the tool in the catalog? → otherwise
MCP_TOOL_NOT_FOUND - Does the token carry the required scopes? → otherwise
MCP_SCOPE_INSUFFICIENT, withmeta.requiredandmeta.missing - Does the plan satisfy the gate? → otherwise
MCP_PLAN_INSUFFICIENT, withmeta.required,meta.currentand an upgrade link - Is there rate-limit budget? → otherwise
RATE_LIMITED - Run the tool — business errors (
QUOTA_EXCEEDED,NOT_FOUND,VALIDATION_ERROR, …) come back from the underlying API
Because the metadata travels with the error, an agent can react intelligently: ask the user to re-authorize with a wider scope, or to upgrade, rather than simply reporting failure.
Rate limits
Every tool declares a rate-limit tier, and MCP calls consume the same buckets as direct HTTP calls — using a tool does not grant a separate allowance.
| Tier | Tools |
|---|---|
read | The 10 read-only tools |
mutation | update_media, delete_media, delete_doc, create_kb |
upload | upload_image, upload_video, upload_audio, upload_doc, sync_kb |
sync_kb counts as an upload because a single call can write up to 100 documents. See Rate Limits for the per-tier ceilings and the response headers that tell you how much budget is left.
There is also a per-minute MCP call limit and a monthly MCP call allowance included in each plan:
| Plan | MCP calls / minute | MCP calls / month included |
|---|---|---|
| Trial | 10 | 500 |
| Pro | 60 | 5,000 |
| Pro+ | 120 | 50,000 |
Metering
Each tool carries a billing tier. When metering is switched on, calls beyond the monthly allowance are drawn from your credit balance:
| Billing tier | Planned rate | Tools |
|---|---|---|
read | $0.001 per call | The 10 read-only tools |
write | $0.005 per call | The 9 upload / mutate / delete tools |
picora.help and picora.about declare no scope and are never charged. Prepaid credit packages carry a discount on metered calls — larger packages, larger discount. See credit wallet.
The tool catalog endpoint
GET https://api.picora.me/mcp/tools.json is public, unauthenticated, and cached at the edge for five minutes. It is the machine-readable source of truth:
curl -s https://api.picora.me/mcp/tools.json | jq '{version, totals}'{ "version": "v0.84.0", "totals": { "tools": 19, "byDomain": { "integration": 2, "media": 7, "profile": 1, "doc": 4, "kb": 5 } }}Each entry carries the slug, bilingual name and description, domain, scopes, pricingTier, rateLimitTier, requiredPlan, and the full JSON Schema inputSchema — the same schema the MCP tools/list method returns.
Use it to drive function-calling prompts dynamically instead of hard-coding tool names. And use it to settle arguments: if a tool is not in tools.json, it does not exist.
Catalog integrity
The catalog is not a wish list. Three sources are held identical by CI, with zero tolerance:
- the executable definitions (tool name + input schema),
- the catalog metadata (slug, bilingual text, scopes, plan, rate tier),
- the pricing table (slug → billing tier).
A tool in one and missing from another fails the build. In an earlier release the catalog had drifted to 30 entries, 22 of which described capabilities that were never implemented; that gap is what this invariant exists to prevent. New capabilities are added to the catalog with their implementation, never ahead of it.
Versioning and deprecation
New tools land additively. Existing slugs and their input schemas are stable — a field may become optional, but a required field will not appear under an existing slug, and a slug will not change meaning.
When a tool does need to be replaced, it is first marked deprecated with a replaceWith slug and a planned removal release. Deprecated tools keep working through the transition, so clients have a full release cycle to migrate; after removal, the slug returns MCP_TOOL_NOT_FOUND and the catalog no longer lists it.
No tool is currently deprecated.
Privacy
For each invocation the server records the tool slug, client identity, latency, and outcome — enough to operate the service and detect abuse. It does not record tool arguments (prompts, file contents, document text), response bodies, or bearer tokens.
Content flowing back through read tools deserves its own caution: filenames, titles, tags and document bodies are authored by users, and an agent should treat them as data. A document that says “ignore your previous instructions” is a string, not a command. Picora marks this explicitly in the tool descriptions the model receives, but the client is the last line of defence.