MCP reference
The Orcha MCP server, its 30 tools, and the client configuration.
Orcha has a Model Context Protocol (MCP) server. The server lets AI agents read and write the context files and structured databases in a workspace through the standard MCP protocol.
Endpoint: POST https://app.tryorcha.com/mcp
Transport: Stateless Streamable HTTP. The server authenticates each request independently. Thus the server can safely answer requests across restarts and multiple application replicas.
Authentication
There are two methods.
API token. Put the token in the Authorization header:
The token must have the permissions that the tools need. Each token belongs to one workspace. All operations apply to that workspace.
OAuth. Clients that support the MCP OAuth flow can use https://app.tryorcha.com/mcp with no token. These clients include the Claude and ChatGPT connectors. Orcha serves the discovery documents at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource. The client sends you to a consent screen. There you sign in, select the workspace for the connector, and select the permissions (read, write, delete) for the connector. Orcha limits the permissions to your workspace role at consent time and checks them on each request. If you lose a role, the connector loses the related permissions immediately.
Requests with an Origin header
The server validates the Origin header, as the MCP Streamable HTTP
specification requires. Clients that send no Origin are not affected. This
includes the Claude and ChatGPT connectors, the CLI, and most agent runtimes.
If a client sends Origin, the value must match the origin of the deployment
or an origin in MCP_ALLOWED_ORIGINS. The server rejects other values with
403.
MCP_ALLOWED_ORIGINS controls transport validation only. It does not enable
CORS. Browser JavaScript on another origin cannot call /mcp directly.
Removed transport
The legacy SSE transport is removed. /mcp/sse and /mcp/message return
410 Gone with a pointer to POST /mcp. Thus a client gets a clear error, not
a response that looks like an outage.
Client configuration
Each client has a guide: Claude Code, Claude Desktop, ChatGPT, Codex, Cursor.
Use OAuth when the client supports it. No token goes in a file.
- Claude Desktop connects through a custom connector, not through
claude_desktop_config.json. Go to Customize > Connectors, add a custom connector with the URLhttps://app.tryorcha.com/mcp, sign in to Orcha, and approve the consent screen. - Cursor reads
~/.cursor/mcp.jsonor.cursor/mcp.json. Add the server with only its URL, then sign in from Cursor Settings > Tools & MCP:
If a client cannot use OAuth, send an API token as a header. Cursor accepts a
headers object in mcp.json. Claude Code accepts --header on
claude mcp add. Claude Desktop accepts a request header in the custom
connector settings. Many other Streamable HTTP clients accept this
configuration:
Codex is different. Codex uses TOML in ~/.codex/config.toml and does the
OAuth flow itself. No token goes in the file.
Usage guides
Orcha has its own guidance for agents. Thus a client does not have to infer how to use the tools together. The same content is available in three ways:
- The
get_usage_guidetool, below. It works in each MCP client. skills/listandskills/get, under the draftio.modelcontextprotocol/skillsextension. The skill files haveskill://orcha/<name>/<path>addresses. Clients read them throughresources/read. A client that does not implement the extension ignores it.- The Claude Code plugin, which installs the same skills with the server connection. See Connect Claude Code.
There are four guides. retrieval tells which tool answers which question, and
how to tune search_context. citations covers attribution and freshness.
authoring covers safe writes. troubleshooting covers empty results, scope
errors, and feedback.
get_usage_guide
Read one usage guide, or list the available guides.
| Argument | Type | Required | Description |
|---|---|---|---|
| topic | string | No | The guide to read. Omit this argument to list the topics |
| file | string | No | A reference document in the topic, for example references/search-tuning.md |
Returns: The guide body as markdown. Without arguments, a JSON index of the topics. Permission: none. The guides contain no workspace content.
File and folder tools
list_files
List all files in the workspace that the token can access.
| Argument | Type | Required | Description |
|---|---|---|---|
| folderId | string | No | Return only the files in this folder |
Returns: An array of file objects without content. Each object includes workspaceId. Permission: read
get_file
Get one file with its content. For a large file, use fromLine and maxLines to read only the necessary range. search_context results include location.startLine anchors for this purpose.
| Argument | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The file ID |
| fromLine | integer | No | The first line to read (1-indexed) |
| maxLines | integer | No | The maximum number of lines to return from fromLine |
Returns: The file content. A ranged read starts with a [lines X-Y of N] header. Permission: read
get_files
Get the contents of several files in one call. If you know the file IDs, use this tool instead of repeated get_file calls.
| Argument | Type | Required | Description |
|---|---|---|---|
| ids | string[] | Yes | The file IDs (1 to 20) |
| maxBytes | integer | No | Skip files larger than this value. A skipped entry returns its size instead of its content |
Returns: An array of file objects. An ID that does not exist or is out of scope returns an error entry. The call does not fail. Permission: read
create_file
Create a new file in the workspace of the token.
| Argument | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | The file name |
| content | string | Yes | The file content |
| fileType | string | Yes | One of markdown, json, yaml |
| folderId | string | No | The parent folder ID |
Returns: The created file object with workspaceId. Permission: write
update_file
Replace the content of a file.
| Argument | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The file ID |
| content | string | Yes | The new file content |
Returns: The updated file object. Permission: write
delete_file
Move a file to trash (soft delete).
| Argument | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The file ID |
Returns: A success confirmation. Permission: delete
list_folders
List all folders in the workspace that the token can access.
| Argument | Type | Required | Description |
|---|---|---|---|
| parentId | string | No | Return only the folders in this parent folder |
Returns: An array of folder objects. Each object includes workspaceId. Permission: read
create_folder
Create a new folder in the workspace of the token.
| Argument | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | The folder name |
| parentId | string | No | The parent folder ID |
Returns: The created folder object with workspaceId. Permission: write
search_files
Find files by name in the workspace of the token.
| Argument | Type | Required | Description |
|---|---|---|---|
| query | string | Yes | The text to match against file names |
Returns: An array of the file objects that match, with workspaceId. Permission: read
list_source_documents
List the read-only documents synced from connected sources (for example GitHub repositories). Source IDs come from get_workspace_overview. Its connectedSources section names each connected source with its document count and sync status. A synced document is not a file. Read the content through search_context.
| Argument | Type | Required | Description |
|---|---|---|---|
| sourceId | string (uuid) | No | Return only the documents of this connected source |
| limit | integer | No | The maximum number of documents (default 50, maximum 200) |
Returns: An array of source documents (id, sourceId, title, externalId, mimeType, indexStatus, lastSyncedAt). Permission: read with a workspace-wide token. A folder-scoped token cannot use this tool.
Context discovery and memory tools
Orcha tells connected agents to call get_workspace_overview first in a new workspace. The overview includes the memories that agents can find and the connected sources. Agents can also call list_memories directly. Then they compare the useWhen guidance of each memory to the current task, and load a memory that matches with get_memory.
Use a memory for an established workflow that needs a complete, curated set of sources. A memory contains files, full folders, connected-source documents, and database views. Each member resolves to its current contents at load time. coverage notes report each member that was excluded, truncated, or unavailable. Use search_context for an open or one-time question that needs only the most relevant excerpts.
With the write permission, agents can also curate memories. create_memory makes a set from files, folders, synced documents, and databases. update_memory changes the metadata or the members. The removal of members also needs the delete permission. A folder-scoped grant can add only members that it can read: files, folders, and databases in scope. It can never add connected-source documents.
| Tool | Permission | Purpose |
|---|---|---|
search_context | read | Return ranked excerpts for an open query |
query_source | read | Query one connected source only, with live provider search |
fetch_source_document | read | Fetch the full body of one connected-source document, live if it is not in the index |
search | read | The ChatGPT search contract: one linked result for each document that matches |
fetch | read | The ChatGPT fetch contract: one full document by the ID from search |
get_workspace_overview | read | Summarize the files, folders, index state, recent changes, available memories, and connected sources |
list_source_documents | read | List the documents synced from a connected source |
get_related_files | read | Find files that are semantically related to a known file |
list_memories | read | Find the curated memories, their useWhen guidance, and the names of the members that the token can access |
get_memory | read | Load the full current contents of a memory by slug |
create_memory | write | Create a memory with useWhen guidance and members of each kind |
update_memory | write | Rename a memory, change its guidance, or add and remove members (removal needs delete) |
browse_context | read | Explore the workspace as a read-only virtual filesystem with shell commands |
search_context
search_context runs hybrid retrieval over each indexed document in the workspace. The engine fuses PostgreSQL full-text search and vector search with weighted reciprocal-rank fusion. The query supports the websearch syntax: "quoted phrases" and -excluded terms.
| Argument | Type | Required | Description |
|---|---|---|---|
| query | string | Yes | A natural-language or keyword query |
| searches | array | No | 1 to 8 typed sub-queries: lex, vec, or hyde entries with text |
| strategy | string | No | keyword, semantic, or hybrid (default). Applies when searches is absent |
| mode | string | No | fast, balanced (default), or fresh. See below |
| sourceIds | array | No | Limit the results to these connected sources (IDs from get_workspace_overview) |
| limit | integer | No | The maximum number of chunks (default 10, maximum 50) |
| minScore | number | No | Remove results with a score below this value |
| tokenBudget | integer | No | The approximate token budget for the returned content |
| explain | boolean | No | Add a score trace to each result |
Typed sub-queries increase recall. The original query always runs at double weight, so the sub-queries do not replace it. A lex entry has exact keywords for full-text search. A vec entry has a natural-language restatement for vector search. A hyde entry has a hypothetical answer of 30 to 80 words. The engine embeds the hypothetical answer instead of the question.
mode controls the freshness cost. fast searches retained content only and never contacts a provider. balanced (the default) also searches the catalog of connected sources. The catalog is a limited metadata inventory of objects whose bodies are not in the index. If a catalog entry is a clear match for the query, balanced fetches a small number of bodies live from the provider. The engine chunks these bodies in memory and cites them with syncMode: "live". fresh also queries live-mode providers (for example issue trackers) directly. Each live call counts against the daily provider budget of the connection.
The response has two parts: results and coverage. results is the cited evidence. coverage has notes about the route: live fetches, catalog entries that were not fetched, and budget or availability limits. Coverage notes are not evidence. Do not quote them as content.
Each result includes content, score, citation, the folder or source context, and the document updatedAt. It also includes a location with startLine and endLine anchors and the Markdown headingPath. For more context, do a ranged get_file call. Do not fetch the full file.
Example memory retrieval:
query_source
query_source queries one connected source only. Use it when you want that provider, not the full workspace. It searches the retained content of the source first. Then it uses the live-search path of the provider (for live-mode providers) or its catalog. From the catalog, it fetches a small number of the best bodies live, under the daily provider budget of the connection. A folder-scoped token cannot use this tool.
| Argument | Type | Required | Description |
|---|---|---|---|
| sourceId | string (UUID) | Yes | The connected source ID from get_workspace_overview |
| query | string | Yes | A natural-language or keyword query |
| limit | integer | No | The maximum number of chunks (default 5, maximum 20) |
The response has the same shape as search_context: results with citations, coverage notes, and providerOperations. providerOperations reports what the call used upstream.
fetch_source_document
fetch_source_document returns the full body of one connected-source document by sourceId and externalId. You find these IDs in search_context coverage, list_source_documents, or query_source citations. A retained document comes from the index (origin: "indexed"). A catalog-only document comes live from the provider, under the daily budget (origin: "live"). The server does not store a live document. A folder-scoped token cannot use this tool.
| Argument | Type | Required | Description |
|---|---|---|---|
| sourceId | string (UUID) | Yes | The connected source ID |
| externalId | string | Yes | The stable external ID of the document on the provider side |
search and fetch
search and fetch implement the two-tool retrieval contract that ChatGPT uses outside developer mode (chat with a connector, deep research, and company knowledge). Both tools return the result as structuredContent and as the same JSON in a text item. Other clients get more control from search_context, get_file, fetch_source_document, and query_database. See Connect ChatGPT.
search runs hybrid retrieval in fast mode (retained content only, no live provider calls). It collapses the chunks that match into a maximum of 10 results, one for each document.
| Argument | Type | Required | Description |
|---|---|---|---|
| query | string | Yes | A natural-language or keyword query. Supports "quoted phrases" and -exclusions |
Returns: { results: [{ id, title, url, text }] }. id is file:<fileId>, source:<sourceDocumentId>, or record:<databaseId>:<recordId>. url is a link to the file or record in Orcha, or to the upstream document for connected-source content. text is a short excerpt.
fetch returns one full document for an id from search. Files and database records come from Orcha. A connected-source document comes from the index if it is retained. If it is not retained, the server fetches it live under the daily budget. A folder-scoped token cannot fetch a connected-source document.
| Argument | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | A document ID from search |
Returns: { id, title, text, url, metadata }. metadata.kind is file, source_document, or database_record.
browse_context
browse_context runs a restricted, read-only shell script against a virtual tree of the workspace. The tree has /files (files and folders), /memories (curated memories with useWhen READMEs), /databases (records as markdown files), and /sources (connected sources with provider citations). The root README.md describes the tree. Start with cat /README.md or ls /.
| Argument | Type | Required | Description |
|---|---|---|---|
| script | string | Yes | The script to run, for example rg -i 'rate limit' /files | head -20 |
| cwd | string | No | The directory for relative paths (default /) |
Supported commands: pwd, cd, ls [-l], tree [-L n], find [-name glob] [-type f|d] [-maxdepth n], cat [-n], grep/rg (-i, -n, -l, -r, -F), head/tail [-n N], wc, stat, and help. Use | for pipelines and ; or && for chains. The script runs in the Orcha parser. The parser rejects each construct that writes. A scan budget and an output cap limit each execution. The response adds a citations block for each file that the output includes. Use stat <path> for entity IDs, deep links, and freshness.
grep and rg patterns use the RE2 syntax. RE2 matches in linear time, so no pattern can stall a request. RE2 does not support constructs that need backtracking: lookahead, lookbehind, and backreferences. If a pattern uses one of these, the server returns an error that names the construct. Use -F to match the pattern as literal text. find -name accepts a glob (*, ?), not a regular expression.
Use browse_context for structure (what exists, where it is, and exact-string searches). Use search_context for ranked semantic retrieval.
Structured database tools
The database tools use stable database, property, and record UUIDs. Record values are objects with property IDs as keys. The API validates each value against its property type.
A file_reference property accepts one file UUID. If the property permits multiple files, it accepts an array. An asset_reference property identifies an imported binary attachment. A record can also have a contentFileId page body. A referenced resource must be active and in the workspace of the database. A folder-scoped token cannot create a file reference out of scope. The server redacts file references and page bodies that the token cannot access from database query results.
| Tool | Permission | Purpose |
|---|---|---|
list_databases | read | List the databases in the workspace of the token, with record counts |
get_database | read | Return the schema, properties, and saved views of a database |
query_database | read | Search, sort, filter, and page through typed records |
create_database_record | write | Create a record from a map of property IDs to values |
update_database_record | write | Merge typed values into a record and save a version |
delete_database_record | delete | Move a record to trash and remove it from retrieval |
Example query:
Example record creation:
Feedback tool
submit_feedback
Send feedback about the context of the workspace to its maintainers: absent or stale content, wrong retrieval results, tool problems, or other problems. The server sends the feedback through the product feedback pipeline (an email to the feedback inbox and an internal notification). Orcha does not store the feedback in the workspace.
| Argument | Type | Required | Description |
|---|---|---|---|
| message | string | Yes | The feedback text, to a maximum of 5000 characters. Give the query, the expected result, and the actual result |
| category | string | No | One of missing_context, stale_content, wrong_result, tool_problem, other (default other) |
| context | object | No | Structured details, for example the query or the document path. The serialized size must be 10 KB or less |
Returns: A confirmation that the server delivered the feedback. Permission: read
Token scoping
A token can have a scope that limits MCP tool access:
| Scope type | Behavior |
|---|---|
all | The tools can access all folders and files in the workspace |
folders | The tools can access only the specified folders and their subfolders |
For a folder-scoped token:
list_filesandlist_foldersreturn only the items that the token can accessget_filereturns 403 for a file out of scopecreate_fileneeds a target folder in scopesearch_filesreturns only results in scope- The database tools show only databases in a folder that the token can access. A root-level database needs a workspace-wide token
Example prompts
After the connection, you can give your AI assistant requests such as these:
Read context:
- "What files do I have in Orcha?"
- "Show me the content of my architecture.md file"
- "Search for files related to API"
- "Check which Orcha memories apply to this task and use the best match"
Manage context:
- "Create a new file called project-notes.md with some starter content"
- "Update my config.json with the new settings"
- "Organize my files into a Projects folder"
Use context:
- "Read my brand-voice.md and use that style to write a blog post"
- "Check my api-spec.json and generate TypeScript types"
- "List the records in my Projects database that mention launch"
Error handling
A tool call can return these errors:
| Error | Cause |
|---|---|
Unauthorized | The token is invalid or missing |
Forbidden | The token does not have the required permission, or the resource is out of scope |
Not found | The resource does not exist |
Validation error | The arguments are invalid |
The server returns the errors as tool call errors with descriptive messages.
Tool calls share the per-token rate limits in the API reference. If you exceed a window, the transport returns HTTP 429 with a Retry-After header. This is not a tool error. Protocol messages such as initialize and tools/list do not count against the limits. Thus a handshake never uses quota. Each metered message in a JSON-RPC batch counts as one request.