Skip to content
  • Follow System
  • English
  • 中文

MCP Tool Reference

Every tool Picora exposes over MCP, with its exact input schema. AI clients read this automatically via tools/list; this page is the human-readable copy.

The machine-readable source is https://api.picora.me/mcp/tools.json — it carries the same inputSchema objects documented below.

How to read this page

  • Scope — the OAuth scope the token must carry. With an API Key, scopes are derived from the key tier: read → all *.read; read_write → adds media.write + kb.write; read_write_delete → adds media.delete. See Concepts.
  • Billing tierread or write, used for per-call metering. Metering is not enabled today; all calls are free.
  • Rate tier — which HTTP rate-limit bucket the call consumes: read, mutation or upload. See Rate Limits.
  • Plan — minimum plan. Only one tool has a plan gate.
  • Required columns mark fields the server rejects the call without.

All 19 tools

ToolPurposeScopeBilling tierRate tierPlan
picora.helpList available tools and usage patterns(none)readreadany
picora.aboutService metadata, docs URL, version(none)readreadany
picora.upload_imageUpload an image, get a permanent CDN URLmedia.writewriteuploadany
picora.upload_videoUpload a video (async transcoding)media.writewriteuploadpro
picora.upload_audioUpload an audio file (synchronous)media.writewriteuploadany
picora.list_mediaList images / videos / audiomedia.readreadreadany
picora.get_mediaDetail for one media itemmedia.readreadreadany
picora.update_mediaRename or change visibilitymedia.writewritemutationany
picora.delete_mediaPermanently delete mediamedia.deletewritemutationany
picora.get_usagePlan, storage, bandwidth countersusage.readreadreadany
picora.upload_docUpload a Markdown documentkb.writewriteuploadany
picora.list_docsList Markdown documentskb.readreadreadany
picora.get_docDocument metadata, optionally contentkb.readreadreadany
picora.delete_docDelete Markdown documentskb.writewritemutationany
picora.list_kbsList knowledge baseskb.readreadreadany
picora.create_kbCreate a knowledge basekb.writewritemutationany
picora.get_kb_manifestFile manifest of a knowledge basekb.readreadreadany
picora.read_kb_docRead one file inside a knowledge basekb.readreadreadany
picora.sync_kbBatch upsert / delete / move in a KBkb.writewriteuploadany

File sources (shared by all upload tools)

upload_image, upload_video, upload_audio and upload_doc all take the file the same way. Provide exactly one of:

FieldTypeNotes
filePathstringAbsolute local path, e.g. /Users/x/Desktop/cat.jpg. stdio only — the remote server has no filesystem access. Relative paths are rejected.
urlstring (uri)Publicly reachable http/https URL; the server downloads it (max 100 MB). Private/internal addresses are rejected.
base64stringBase64 file content, recommended under 2 MB. A data:*;base64, prefix is accepted and stripped. Requires filename.
filenamestringFilename with extension, e.g. "cat.jpg". Required with base64, ignored otherwise.

Passing two sources at once is a validation error.


Integration tools

These two require no scope and no authentication decision — an agent can call them before the user has granted anything, to find out what is available.

picora.help

Overview of every Picora MCP tool, grouped by capability (media / docs / kb / usage), plus authentication options and documentation links.

Scope (none) · Billing tier read · Rate tier read · Plan any

Input — no parameters.

Use it when you are unsure which Picora tool fits, or the user asks “what can Picora do?”. Call it first in an unfamiliar session.

Don’t use it for service metadata like version or region — that’s picora.about.

Typical errors — none; read-only with no side effects.

picora.about

Basic information about the Picora service: what it is, documentation URL, API base endpoints, and tool package version.

Scope (none) · Billing tier read · Rate tier read · Plan any

Input — no parameters.

Use it when the user asks “what is Picora?” or you need service metadata (which region/endpoint am I talking to, which tool version is loaded).

Don’t use it for discovering tools — that’s picora.help.

Typical errors — none; read-only with no side effects.


Media tools

picora.upload_image

Upload an image to Picora cloud hosting and get back a permanent CDN URL that never expires. Supports JPEG / PNG / WebP / GIF / AVIF up to 20 MB.

Scope media.write · Billing tier write · Rate tier upload · Plan any

Input

FieldTypeRequiredNotes
filePathstringone-ofAbsolute local path (stdio only)
urlstring (uri)one-ofPublic file URL, fetched server-side, max 100 MB
base64stringone-ofBase64 content, recommended < 2 MB; needs filename
filenamestringwith base64Filename with extension
isPublicbooleannoPublicly accessible. Default true
tagsstring[]noMax 10 tags, each ≤ 50 chars

Use it when the user asks to upload, host or share an image, or wants a permanent URL for a picture.

Don’t use it for videos (upload_video), audio (upload_audio) or Markdown (upload_doc).

Typical errorsQUOTA_EXCEEDED (image storage full), INVALID_MIME (unsupported format), VALIDATION_ERROR (no file source, or two at once), MCP_SCOPE_INSUFFICIENT (key is read-only).

picora.upload_video

Upload a video (mp4 / mov / avi). Transcoding is asynchronous: the call returns immediately with status: "processing".

Scope media.write · Billing tier write · Rate tier upload · Plan pro (Pro ≤ 500 MB, Pro+ ≤ 2 GB)

Input

FieldTypeRequiredNotes
titlestringyesDisplay title, 1–255 chars
filePathstringone-ofAbsolute local path (stdio only)
urlstring (uri)one-ofPublic file URL, fetched server-side, max 100 MB
base64stringone-ofBase64 content, recommended < 2 MB; needs filename
filenamestringwith base64Filename with extension
isPublicbooleannoPublicly accessible. Default true

Use it when the user asks to upload or share a video. Afterwards, poll picora.get_media (or list_media filtered by type: "video") until status becomes "ready" — only then does a playbackUrl exist. Short clips typically take 1–3 minutes; HD/4K takes longer.

Don’t use it for images or audio, and don’t report success to the user while status is still processing.

Typical errorsPLAN_REQUIRED / MCP_PLAN_INSUFFICIENT (free or trial account), QUOTA_EXCEEDED (video storage), VALIDATION_ERROR (file too large for the plan, missing title).

picora.upload_audio

Upload an audio file (mp3 / m4a / wav / flac / ogg). Unlike video this is synchronous — when the call returns, the audio is immediately playable.

Scope media.write · Billing tier write · Rate tier upload · Plan any (per-file caps: Trial 50 MB / Pro 100 MB / Pro+ 500 MB)

Input

FieldTypeRequiredNotes
titlestringyesDisplay title, 1–255 chars
filePathstringone-ofAbsolute local path (stdio only)
urlstring (uri)one-ofPublic file URL, fetched server-side, max 100 MB
base64stringone-ofBase64 content, recommended < 2 MB; needs filename
filenamestringwith base64Filename with extension
isPublicbooleannoPublicly accessible. Default true

Use it when the user wants to host a podcast episode, music track or voice recording. For MP3 (ID3v2) and FLAC, embedded cover art plus bitrate and duration are extracted automatically; other formats get a per-format default thumbnail and null bitrate / durationSeconds.

Don’t use it for images or videos.

Typical errorsQUOTA_EXCEEDED (audio storage), INVALID_MIME, VALIDATION_ERROR (file exceeds the per-plan cap, missing title).

picora.list_media

List uploaded media newest-first, with cursor pagination. Omit type for a unified mixed list.

Scope media.read · Billing tier read · Rate tier read · Plan any

Input

FieldTypeRequiredNotes
type"image" | "video" | "audio"noFilter by media type; omit for all
limitintegerno1–50, default 20
cursorstringnonextCursor from the previous response
querystringnoFuzzy match on filename / title, ≤ 255 chars

Use it when the user asks to list, show or find their media, or you need to poll several videos’ transcode status at once.

Don’t use it for fetching one known item — get_media is cheaper and returns the same detail.

Typical errorsVALIDATION_ERROR (limit out of range, malformed cursor), MCP_SCOPE_INSUFFICIENT.

picora.get_media

Metadata for a single media item, addressed by id and type.

Scope media.read · Billing tier read · Rate tier read · Plan any

Input

FieldTypeRequiredNotes
idstringyes11-char nanoid for images, 21-char for video / audio
type"image" | "video" | "audio"yesRequired to route to the right endpoint

Use it when the user asks for details on a specific item — and specifically to check whether a video finished transcoding: read the status field (processing / ready / failed).

Don’t use it for browsing; use list_media when you don’t already have the id.

Typical errorsNOT_FOUND (wrong id, or right id with the wrong type), VALIDATION_ERROR.

picora.update_media

Change the title or visibility of an existing media item. The server invalidates its cache, so subsequent reads see the new values immediately.

Scope media.write · Billing tier write · Rate tier mutation · Plan any

Input

FieldTypeRequiredNotes
idstringyesMedia id (11- or 21-char nanoid)
type"image" | "video" | "audio"yesMedia type
titlestringnoNew title, ≤ 255 chars. Omit to leave unchanged
isPublicbooleannoNew visibility. Omit to leave unchanged

Use it when the user says “rename this video”, “make this image private”, “publish this audio”. Pass at least one of title / isPublic.

Don’t use it for editing filename or image tags — those are not editable here.

Typical errorsNOT_FOUND, VALIDATION_ERROR (neither title nor isPublic supplied), MCP_SCOPE_INSUFFICIENT.

picora.delete_media

Permanently remove media from object storage, database and cache. Irreversible — no trash, no undo, and the CDN URLs start returning 404.

Scope media.delete · Billing tier write · Rate tier mutation · Plan any

Input

FieldTypeRequiredNotes
itemsarrayyes1–100 objects, each { id: string, type: "image" | "video" | "audio" }. Mixed types allowed
dryRunbooleannoDefault true — preview only. false actually deletes

Use it only via the two-step protocol:

  1. Call with dryRun: true (the default) to preview exactly what would be removed.
  2. Show the user that list and get explicit confirmation.
  3. Only after the user says yes, call again with dryRun: false.

Don’t use it for hiding content from the public — update_media with isPublic: false is reversible, deletion is not.

Typical errorsMCP_SCOPE_INSUFFICIENT (needs a read_write_delete key; read_write cannot delete), NOT_FOUND (an id in the batch does not exist), VALIDATION_ERROR (more than 100 items).


Usage tools

picora.get_usage

The account’s current plan plus storage, bandwidth and upload counters.

Scope usage.read · Billing tier read · Rate tier read · Plan any

Input — no parameters.

Use it when the user asks “how much storage have I used?”, “what plan am I on?”, “how much bandwidth this month?” — or before a large batch upload, to check there is room.

Don’t report raw byte counts back to the user: all byte values are integers, so format them (2147483648 → 2 GB). Bandwidth figures are estimates — CDN cache hits are not counted, so a small gap versus billing is expected.

Typical errorsMCP_SCOPE_INSUFFICIENT (token lacks usage.read).


Document tools

These operate on standalone documents — flat Markdown files that are not inside a knowledge base. For files organised under paths in a workspace, use the KB tools.

picora.upload_doc

Upload a Markdown document (.md / .markdown, max 5 MB) and get a permanent URL.

Scope kb.write · Billing tier write · Rate tier upload · Plan any

Input

FieldTypeRequiredNotes
filePathstringone-ofAbsolute local path (stdio only)
urlstring (uri)one-ofPublic file URL, fetched server-side, max 100 MB
base64stringone-ofBase64 content; needs filename
filenamestringwith base64Filename with extension
titlestringno≤ 200 chars. Takes priority over frontmatter / H1 / filename
tagsstring[]noMax 10 tags, each ≤ 32 chars. Takes priority over frontmatter tags
isPublicbooleannoDefault false. Public docs are readable at /v1/docs/:id/raw without auth
rewriteImagesbooleannoDecode and re-host inline base64 images. Default true

Behaviours worth knowing

  • Content is read as UTF-8, 5 MB maximum.
  • Inline data: image embeds are re-uploaded to Picora CDN URLs — this consumes the image quota too.
  • Links already pointing at Picora (e.g. media.picora.me) are left alone.
  • file:// and relative paths inside the Markdown are kept as-is, with a warning.
  • YAML frontmatter (--- … ---) is parsed for title / tags / public hints; the original content is preserved.
  • Idempotent: identical content returns the existing document id with duplicate: true, and does not consume quota again.

Use it when the user wants to publish, host or share a Markdown note, or wants a permanent URL for one.

Don’t use it for images, generic binary files, or files that belong inside a KB directory tree (use sync_kb).

Typical errorsQUOTA_EXCEEDED (document count limit), VALIDATION_ERROR (over 5 MB, no file source).

picora.list_docs

List standalone Markdown documents. Returns metadata only — never content.

Scope kb.read · Billing tier read · Rate tier read · Plan any

Input

FieldTypeRequiredNotes
limitnumberno1–50, default 20
cursorstringnonextCursor from the previous response
querystringnoTitle fuzzy match, ≤ 100 chars (no full-text search yet)
tagstringnoSingle tag, or comma-separated for OR semantics. ≤ 200 chars
isPublicbooleannoFilter by visibility; omit for all
sortcreated_desc | created_asc | updated_desc | updated_ascnoDefault created_desc

Use it when the user asks “what docs do I have?”, “find my notes about X”, “list documents tagged Y”.

Don’t use it for reading the Markdown itself — follow up with get_doc and includeContent: true.

Typical errorsVALIDATION_ERROR (limit out of range, malformed cursor).

picora.get_doc

Metadata for one standalone document, optionally with its full Markdown text.

Scope kb.read · Billing tier read · Rate tier read · Plan any

Input

FieldTypeRequiredNotes
idstringyesExactly 21 characters (nanoid)
includeContentbooleannoAlso fetch the raw Markdown. Default false

Use it when you have a document id and need its metadata, or its body to summarise or edit. Content above 5 MB is truncated to 4.99 MB with truncated: true; for very large documents fetch /v1/docs/:id/raw over HTTP instead.

Don’t use it for documents inside a knowledge base addressed by path — that’s read_kb_doc.

Typical errorsNOT_FOUND, VALIDATION_ERROR (id is not 21 characters).

picora.delete_doc

Delete one or more standalone Markdown documents. Irreversible.

Scope kb.write · Billing tier write · Rate tier mutation · Plan any

Input

FieldTypeRequiredNotes
idsstring[]yes1–50 document ids, each exactly 21 characters
dryRunbooleannoDefault true — returns a willDelete preview. Set false only after user confirmation

Use it with the same two-step protocol as delete_media: preview → confirm with the user → delete.

Note: embedded images that were uploaded into the user’s image quota are not cascaded — an image may be referenced by several documents, so orphan cleanup is handled separately.

Typical errorsMCP_SCOPE_INSUFFICIENT (needs a delete-capable key), NOT_FOUND, VALIDATION_ERROR (more than 50 ids).


Knowledge base tools

A knowledge base (KB) is a named workspace holding documents under relative paths — a cloud folder tree. The usual flow is list_kbsget_kb_manifestread_kb_docsync_kb.

picora.list_kbs

List the account’s knowledge bases, with cursor pagination.

Scope kb.read · Billing tier read · Rate tier read · Plan any

Input

FieldTypeRequiredNotes
limitnumberno1–50, default 20
cursorstringnonextCursor from the previous response
sortupdated_at | namenoDefault updated_at (descending)
typeall | creator | outputnocreator = personal workspaces, output = publishable output KBs. Omit for all

Use it first in any KB workflow — you need a kbId before you can call get_kb_manifest, read_kb_doc or sync_kb.

Don’t use it for listing flat standalone documents; that’s list_docs.

Typical errorsVALIDATION_ERROR (limit out of range).

picora.create_kb

Create a new knowledge base.

Scope kb.write · Billing tier write · Rate tier mutation · Plan any (KB count limit: Trial 5 / Pro 50 / Pro+ 500)

Input

FieldTypeRequiredNotes
namestringyesDisplay name, 1–120 chars
slugstringnoPath-friendly id ^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$. Derived from name when omitted. Immutable after creation
descriptionstringno≤ 500 chars
kbTypecreator | outputnoDefault creator. Immutable after creation

Use it when the user asks for a new KB / workspace / notebook for synced documents.

Don’t use it for uploading a single standalone document (upload_doc) or writing files into an existing KB (sync_kb).

Typical errorsKB_LIMIT_REACHED (plan KB limit), CONFLICT (slug taken), VALIDATION_ERROR (name empty or slug malformed).

picora.get_kb_manifest

The file manifest of a KB: every document’s relativePath, sourceHash, sizeBytes and updatedAt. Metadata only, no content.

Scope kb.read · Billing tier read · Rate tier read · Plan any

Input

FieldTypeRequiredNotes
kbIdstringyes21-char nanoid from list_kbs
sincestring (date-time)noIncremental watermark, ISO 8601. Omit for a full listing
cursorstringnonextCursor from the previous response
limitnumberno1–1000, default 500

Use it as the entry point for browsing a KB’s directory structure and discovering file paths — before read_kb_doc (to find the exact path) and before sync_kb (to get baseUpdatedAt for optimistic locking).

  • Full mode (no since): all active documents; soft-deleted ones excluded.
  • Incremental mode (since set): entries changed after that time, including soft-deleted ones (deletedAt non-null). Store the response’s serverTime and use it as the next since.
  • Sync protocol v2 (header Picora-Sync-Version: 2) also returns tombstones — hard-deleted documents retained for 30 days (90 for Pro+) so other clients can drop their local copies.
  • One page per call, sorted by updatedAt descending. Keep calling with cursor: <nextCursor> while it is non-null.

Don’t use it for reading file content (read_kb_doc) or listing KBs themselves (list_kbs).

Typical errorsNOT_FOUND (unknown kbId), VALIDATION_ERROR (since not ISO 8601, limit out of range).

picora.read_kb_doc

Read the raw text of a single document inside a KB, addressed by its relative path.

Scope kb.read · Billing tier read · Rate tier read · Plan any

Input

FieldTypeRequiredNotes
kbIdstringyes21-char nanoid from list_kbs
pathstringyesPOSIX relative path, 1–1024 chars, e.g. notes/idea.md or .claude/memory.md. No leading /, no ..

Use it after get_kb_manifest has revealed the paths. Returns the full text plus sourceHash (SHA-256 of content) and updatedAt — keep that updatedAt and pass it as baseUpdatedAt in a later sync_kb upsert to avoid conflicts. Content over 5 MB is truncated with truncated: true.

Don’t guess paths — discover them via get_kb_manifest first. And don’t use this with a document id; standalone documents use get_doc.

Typical errorsNOT_FOUND (no such path in that KB), VALIDATION_ERROR (leading /, .. traversal, path too long).

picora.sync_kb

Batch-write into a KB: up to 100 operations per call, each one an upsert, delete or move.

Scope kb.write · Billing tier write · Rate tier upload · Plan any

Input

FieldTypeRequiredNotes
kbIdstringyes21-char nanoid from list_kbs
opsarrayyes1–100 operations, each of the three shapes below

upsert — create or overwrite content at a path:

FieldTypeRequiredNotes
op"upsert"yes
relativePathstringyesPOSIX relative path, ≤ 1024 chars. No leading /, no ..
contentstringyesFull document text (UTF-8)
sourceHashstringnoSHA-256 hex (64 lowercase chars) of content; computed for you when omitted
baseUpdatedAtstring (date-time)noOptimistic lock — the updatedAt you last saw. Omit only when creating a new path
titlestringno≤ 200 chars
tagsstring[]noMax 10, each ≤ 32 chars
isPublicbooleannoDefault private

delete — soft-delete a path:

FieldTypeRequiredNotes
op"delete"yes
relativePathstringyesPath of the document to delete
baseUpdatedAtstring (date-time)noOptimistic lock; omitting it on an existing doc yields a BASE_MISSING conflict

move — rename or relocate; content and document id are unchanged:

FieldTypeRequiredNotes
op"move"yes
fromPathstringyesCurrent path
toPathstringyesNew path; must not be occupied by an active document
baseUpdatedAtstring (date-time)noOptimistic lock on the source document

Use it to save, update, reorganise or remove files inside a KB.

Don’t use it for standalone documents outside a KB (upload_doc / delete_doc), or to create the KB itself (create_kb).

Conflict semantics — read this before you write any sync loop

Operations apply independently. The call returns HTTP 200 with three arrays — applied, conflicts, skipped. Partial success is normal, so always inspect conflicts.

baseUpdatedAt is the optimistic lock: pass the updatedAt you last saw from get_kb_manifest or read_kb_doc. Omitting it means “create new”.

Conflict codeMeaningResolution
BASE_MISSINGNo baseUpdatedAt given but the path already exists — rejected instead of silently overwritingRead the current version, then resend with its updatedAt
REMOTE_NEWERYour baseUpdatedAt is stale; the server kept its newer versionRe-read with read_kb_doc, merge yourself, resend
REMOTE_DELETEDThe server deleted the document in the meantimeDecide whether to recreate it
MOVE_SOURCE_MISSINGfromPath does not existRe-check the manifest
MOVE_TARGET_EXISTStoPath is occupied by an active documentPick another path, or delete the target first

The server never merges content. Resolution is always: re-read, then resend with a fresh baseUpdatedAt.

Side effects — writes documents (new paths consume the document-count quota), soft-deletes, or moves them. move and delete leave tombstones so other synced clients drop stale local copies. Upserting identical content at the same path is de-duplicated server-side, and re-sending a delete for an already-deleted path lands in skipped — so retrying a whole batch is safe.

Typical errorsQUOTA_EXCEEDED (document count), NOT_FOUND (unknown kbId), VALIDATION_ERROR (over 100 ops, malformed path, bad sourceHash).


Gate errors common to every tool

Before a tool runs, the server checks the catalog, the token’s scopes, and the plan — in that order.

CodeMeaning
MCP_TOOL_NOT_FOUNDThe slug is not in the catalog — check tools.json, or the tool may not be deployed yet
MCP_SCOPE_INSUFFICIENTToken is missing a scope; meta.required and meta.missing list which
MCP_PLAN_INSUFFICIENTThe plan gate failed; meta.required and meta.current say which plan is needed
RATE_LIMITEDThe rate-limit bucket for this tier is exhausted — back off and retry

See Concepts for the full authentication and rate-limit model.