MCP Integration
One HTTP MCP endpoint. Six tested clients. Twenty-nine tools, four prompts, four resources, all addressable from the editor. No sidecar, no daemon, no glue.
Connect once, pin a workspace via the
X-Xerotier-Workspace header, and your
AI tooling gains durable context about your
project, the same context the chat surface
already has. The header accepts either the
workspace's URL-safe external identifier
(ws_<hex>, the form you see in
the dashboard) or the internal workspace UUID, so
a value copied from a chat URL works without
translation.
Supported Clients
The endpoint is a standard streamable HTTP MCP
server (streamable HTTP is the default transport;
operators can pin the legacy transport via
XEROTIER_MCP_TRANSPORT=legacy, which
suppresses the streamable capability advertisement).
Any client that speaks the HTTP transport will work;
the following are explicitly tested and have
one-shot config bundles in the Xerotier dashboard:
- Claude Code, Anthropic's CLI coding assistant.
- Cursor, AI editor with first-class MCP support.
- opencode, Open-source coding agent.
- VS Code, Native MCP support (via the GitHub Copilot Chat extension).
- Claude Desktop, HTTP MCP support is partial; works for most read tools.
- OpenAI Codex, CLI coding agent; reads MCP servers from a TOML config.
Other HTTP-capable MCP clients work too; you may need to hand-author the configuration.
Quick Start
1. Pick a workspace on the chat page
Open /chat in the dashboard and select
the workspace you want to connect from the left
navigator. The Client tab in the right manager
column is workspace-scoped, it only appears once
a specific workspace is active (the "All" aggregate
view hides it).
2. Open the Client tab
In the right manager column's tab strip, click Client. The tab surfaces a catalog tier picker and one card per supported MCP client (Claude Code, Claude Desktop, Cursor, opencode, OpenAI Codex, VS Code).
3. Pick a catalog tier and download
Choose how much of the tool catalog this connection exposes (see Catalog Tiers below), then click Download next to your client. The file is a drop-in config fragment; each download rotates the workspace API key, so older bundles for the same workspace are automatically revoked.
4. Save the file at the path your client expects
Each card shows the exact path. Most clients use a
project-scoped file (opencode.json,
.mcp.json, .cursor/mcp.json,
.vscode/mcp.json,
.codex/config.toml) at your repo root;
Claude Desktop merges into a user-level config file
instead. Add the project-scoped file to your
.gitignore, the bundle carries your
workspace API key in the Authorization header and
should not land in version control.
-
Your client may surface prompts (as slash commands) and resources (as
@-mentions). See the Prompts and Resources sections below for syntax per client.
5. (Recommended) Drop in the companion rules file
The bundle README ships a short Xerotier
tool-use rules snippet, the same content opencode
and Codex inline automatically via their
instructions config field. For Claude
Code, Cursor, and VS Code, save the snippet at the
documented path
(.claude/CLAUDE.md,
.cursor/rules/xerotier.mdc with
alwaysApply: true, or
.github/copilot-instructions.md
respectively). Without the companion, the client
will sometimes ask you about workspace state
instead of calling the Xerotier tools to retrieve
it; with the companion, tool calls happen
autonomously. Claude Desktop has no project-scoped
rules surface and falls back to the tool
descriptions returned by tools/list.
CLI alternative: the
xeroctl mcp setup command in
xeroctl emits
the same per-client bundles from a terminal. The
current CLI generator covers Claude Code, Cursor,
opencode, and VS Code; Claude Desktop and OpenAI
Codex bundles are dashboard-only until the CLI
generator gains those renderers.
Configuration Examples
These are the shapes the dashboard's
Client tab emits (right-column
manager on the /chat page, once a
specific workspace is selected). Replace the
placeholders with values from your own download --
the <workspace_id> placeholder
accepts either the URL-safe
ws_<hex> form shown in the
dashboard or the internal workspace UUID.
Claude Code
Save as .mcp.json at your project root (project-scoped MCP file).
{
"mcpServers": {
"xerotier": {
"type": "http",
"url": "https://api.xerotier.ai/proj_ABC123/v1/mcp",
"headers": {
"Authorization": "Bearer <api_key>",
"X-Xerotier-Workspace": "<workspace_id>"
}
}
}
}
Cursor
Save as .cursor/mcp.json at your project root (or ~/.cursor/mcp.json for global). Cursor infers transport from the presence of url, no type field is needed on remote servers.
{
"mcpServers": {
"xerotier": {
"url": "https://api.xerotier.ai/proj_ABC123/v1/mcp",
"headers": {
"Authorization": "Bearer <api_key>",
"X-Xerotier-Workspace": "<workspace_id>"
}
}
}
}
opencode
{
"mcp": {
"xerotier": {
"type": "remote",
"url": "https://api.xerotier.ai/proj_ABC123/v1/mcp",
"enabled": true,
"oauth": false,
"timeout": 30000,
"headers": {
"Authorization": "Bearer <api_key>",
"X-Xerotier-Workspace": "<workspace_id>"
}
}
}
}
oauth: false disables opencode's automatic OAuth discovery probe so it trusts the headers block as the only auth path, without it, opencode would try an OAuth round-trip on the MCP URL before falling back. timeout: 30000 raises opencode's 5-second default for the initial tools/list fetch so cold-path connects do not abort prematurely.
VS Code
Save as .vscode/mcp.json at your project root. Requires the GitHub Copilot Chat extension, VS Code's MCP client lives in Copilot Chat's agent mode.
{
"servers": {
"xerotier": {
"type": "http",
"url": "https://api.xerotier.ai/proj_ABC123/v1/mcp",
"headers": {
"Authorization": "Bearer <api_key>",
"X-Xerotier-Workspace": "<workspace_id>"
}
}
}
}
OpenAI Codex
Save as .codex/config.toml at your project root (or merge the [mcp_servers.xerotier] table into ~/.codex/config.toml for global access). Codex's config is TOML, not JSON, transport is inferred from the presence of url.
# Xerotier MCP server configuration for OpenAI Codex.
[mcp_servers.xerotier]
url = "https://api.xerotier.ai/proj_ABC123/v1/mcp"
enabled = true
startup_timeout_sec = 30
tool_timeout_sec = 60
http_headers = { "Authorization" = "Bearer <api_key>", "X-Xerotier-Workspace" = "<workspace_id>" }
Operators who prefer env-var-based auth can swap the Authorization entry for bearer_token_env_var = "XEROTIER_API_KEY" and export the key as an environment variable on Codex's host.
Tools
Twenty-nine tools ship today, grouped by
xerotier.<namespace>. Most are
read-only; a handful persist into the pinned
workspace's knowledge graph or artifact store, and
four route into the governed XEM execution surface
(see Governed Execution below).
All are advertised on the standard MCP
tools/list response and dispatched via
tools/call. The server also answers the
standard ping JSON-RPC method, useful
as a lightweight client-side health probe.
memory.*
| Tool | Description |
|---|---|
xerotier.memory.search |
Semantic search across workspace content (memories, documents, artifacts, decisions, milestones). |
xerotier.memory.recall |
Recall workspace memories matching a query (semantic when an embedder is configured, chronological otherwise). |
xerotier.memory.save write |
Persist a workspace memory entry. The memory lands in the pinned workspace and surfaces in subsequent recall and semantic searches. |
workspace.*
| Tool | Description |
|---|---|
xerotier.workspace.list |
List workspaces in the authenticated project. |
xerotier.workspace.get |
Return the workspace pinned to the connection. |
xerotier.session.init |
Initialize a session and resolve the workspace binding for this connection (useful for clients that do not pass the workspace header on every call). |
artifact.*
| Tool | Description |
|---|---|
xerotier.artifact.create write |
Persist a workspace-scoped artifact. Returns {artifact_id, identifier, version, status}. |
xerotier.artifact.update write |
Write a new version of an existing artifact. The artifact must belong to the calling workspace. |
xerotier.artifact.read |
Read one artifact by id. Content over 1 MiB returns metadata only with content_truncated: true. |
xerotier.artifact.list |
List artifacts visible to the calling workspace. Optional chat_id narrows to a single chat; filter by artifact_type; paginate with limit and offset. |
intelligence.*
| Tool | Description |
|---|---|
xerotier.intelligence.brief |
Structured project-state briefing: decisions, blockers, milestones, connections, memories. |
xerotier.intelligence.timeline |
Project milestone timeline with optional type, date-range, and related-decision filters. |
xerotier.intelligence.decisions |
Search tracked project decisions (semantic when configured, chronological otherwise). |
xerotier.intelligence.analyze |
Synthesize a markdown brief of workspace context (documents, memories, artifacts, recent chats). |
xerotier.intelligence.graph |
Composite read of the workspace knowledge graph: decisions and milestones as nodes, relations as edges. |
xerotier.intelligence.relate write |
Create a typed relationship between two existing workspace entities. Both endpoints must already exist. |
xerotier.intelligence.track_decision write |
Record a load-bearing project decision in the workspace knowledge graph. |
xerotier.intelligence.track_milestone write |
Record a completed project milestone in the workspace timeline. |
calc.* & research.*
| Tool | Description |
|---|---|
xerotier.calc.evaluate |
Evaluate a math expression server-side. Deterministic; no external calls. |
xerotier.research.web_search |
Web search via the router's configured search backend. |
xerotier.research.fetch_url |
HTTP fetch with text and PDF extraction. Honours robots.txt; size-capped. |
xerotier.research.inspect_site |
Single-URL HTML and CSS inspection: palette, typography, layout structure. |
code.*
| Tool | Description |
|---|---|
xerotier.code.search |
GitHub code search via the router's configured GitHub token. |
xerotier.code.repo_overview |
Full GitHub repository overview: metadata, languages, README, file tree, recent commits. |
xerotier.code.repo_read |
Read specific files or list a directory inside a GitHub repository. |
exec.*
| Tool | Description |
|---|---|
xerotier.exec.invoke write |
Asynchronously invoke a XEM-advertised tool. Returns {invocation_id, status, approval_url?} immediately; poll until terminal. |
xerotier.exec.invoke_blocking write |
Streaming variant of invoke: completes in one round-trip and streams progress while running. |
xerotier.exec.poll |
Fetch the current state of an in-flight invocation by id. |
xerotier.exec.cancel |
Request cancellation of an in-flight invocation. Idempotent. |
Example: persist a memory
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "xerotier.memory.save",
"arguments": {
"content": "Shipped MCP M8 with sampling-based approvals.",
"category": "decision"
}
}
}
Example: invoke a XEM tool
The tool_name below is illustrative --
no deploy.staging XEM tool ships by
default. Substitute the name of a XEM tool your
operator has enrolled.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "xerotier.exec.invoke",
"arguments": {
"tool_name": "deploy.staging",
"arguments": {
"service": "router",
"ref": "main"
}
}
}
}
Catalog Tiers
Pick how much of the tool catalog this connection
exposes. The Client tab on the
/chat page and the API Keys create
form both surface the same picker; the chosen tier
is carried on the API key and applied to every
tools/list response served against it.
| Tier | What it admits |
|---|---|
| Core (10 tools) | Read-only baseline: workspace lookup, memory recall and save, calculator, session init, web research. |
| Exec (14 tools) | Core plus governed XEM execution (exec.invoke, exec.poll, exec.cancel, exec.invoke_blocking). |
| Intel (25 tools) | Core plus intelligence: knowledge graph, decisions, milestones, artifacts, GitHub code reads. |
| All (29 tools) | Full xerotier.* catalog. The default for new keys; pick a narrower tier when you want to expose only what a given client needs. |
Tools above the selected tier never appear in
tools/list and are rejected at
tools/call. Want to broaden or narrow
a key later? Mint a fresh key at the new tier --
each Client tab download rotates the workspace key
in place.
Governed Execution
The xerotier.exec.* tools front the
router's execution-plane mesh (XEM). XEM tools
cross a different trust boundary than the read and
write workspace tools above, a XEM tool can
deploy code, run shell commands, or touch other
services, so the router gates them more
carefully.
Approvals you can see
When a target XEM tool requires explicit human
approval,
xerotier.exec.invoke returns an
approval_url alongside the
invocation_id. Your editor surfaces
the URL; click it, approve in your browser, and
xerotier.exec.poll walks through
awaiting_approval into
running once the gate clears.
Clients that advertise the MCP
sampling capability can skip the
browser entirely: the server prompts your editor's
model to summarise the call and reply with
APPROVE or DENY. Clients
that advertise elicitation get a
workspace-binding prompt the same way, no
out-of-band confirmation step needed.
Destructive opt-in
Destructive XEM tools (deletes, irreversible
operations) are hidden from tools/list
by default. The API Keys create form has a
Allow destructive XEM tools
switch; keys minted with it on see destructive
entries, keys minted without it never do.
Idempotent retries
Each xerotier.exec.invoke call carries
an idempotency key derived from the API key, the
MCP session, the tool name, and the canonical
argument shape. A duplicate request within the
idempotency window returns the original
invocation_id instead of creating a
new one, so noisy client retries do not trigger a
second deploy.
Streaming vs. polling
Use xerotier.exec.invoke_blocking
when your client can stream a long-running
response; the call completes in one round-trip and
progress events arrive on the same stream. Use the
classic invoke / poll
pair when streaming is awkward or your client
prefers short-lived requests.
Prompts
MCP prompts are server-authored, user-triggered context primers. Clients surface them as slash commands (Claude Code, opencode, VS Code Copilot) or @-mentions (Cursor). Invoke a prompt to inject a pre-built block of messages into the conversation, equivalent to "one keystroke = run this tool sequence and paste the result."
Workspace binding required: every
prompt resolves against the pinned workspace. If the
connection has no workspace bound, the server
rejects prompts/get with an MCP
invalidRequest error and the canonical
message "Workspace not bound. Call
xerotier.session.init or set X-Xerotier-Workspace
header." Set the header on connect, or call
xerotier.session.init once per session.
| Name | Arguments | Effect | Required tier |
|---|---|---|---|
session.init |
none | Primes a fresh session with the current workspace's capabilities and intelligence summary. | Core |
brief |
none | Intelligence brief plus 5 most recent decisions. | Intel |
onboard |
topic (required) |
Curated context pack: memories + related entities + recent activity for the topic. | Intel |
save-this |
note (required) |
Fill-in form pre-populated with the note + recent memory slugs as link candidates. Caller invokes x_save_memory separately. |
Core |
Per-client invocation
| Client | Invocation |
|---|---|
| Claude Code | /mcp__xerotier__brief |
| opencode | /xerotier:brief |
| Cursor | @xerotier brief |
| VS Code Copilot | /mcp__xerotier__brief |
| Claude Desktop | Not currently surfaced as slash commands |
| OpenAI Codex | Not surfaced |
When to use prompts vs. tools: prompts are user-triggered context primers (the user fires them once to prime a session). Tools are model-driven actions called during normal reasoning. If you want one keystroke to set up context, use a prompt; if you want the model to act in the loop, use a tool.
Resources
MCP resources are URI-addressable, read-only data sources. Clients attach them to context via @-mention pickers or auto-attach UIs. Use a resource when you want the model to cite workspace state by URI rather than pasting the body inline.
xerotier://workspace/current/brief
xerotier://workspace/current/recent-decisions[?since=<duration>&limit=<n>]
xerotier://memory/<slug>
xerotier://artifact/<id>
| URI | Returns | MIME | Required tier |
|---|---|---|---|
workspace/current/brief | Always-current brief. | text/markdown | Intel |
workspace/current/recent-decisions | Rolling decisions feed. Query params: since (duration like 7d), limit (default 20). | text/markdown | Intel |
memory/{slug} | Single memory by slug. | text/markdown | Core |
artifact/{id} | Single artifact by id. | text/markdown | Core |
Per-client attachment
| Client | Syntax |
|---|---|
| Claude Code | @xerotier://memory/my-slug |
| opencode | @xerotier://memory/my-slug |
| Cursor | @-picker |
| VS Code Copilot | @xerotier://memory/my-slug |
| Claude Desktop | @-picker |
| OpenAI Codex | Not surfaced |
When to use resources vs. tools: resources are passive citations (the client attaches them; the model reads them). Tools are imperative reads with parameters. If you want the model to fetch state with parameters, use a tool; if you want a URI the conversation can reference, use a resource.
Security & Isolation
The MCP surface inherits every guardrail the rest of the router enforces.
Operator gating
The MCP route only mounts when
XEROTIER_MCP_ENABLED is on; on
deployments where the flag is off the
/v1/mcp path returns 404 and no
capability is advertised. Idle sessions expire after
XEROTIER_MCP_SESSION_TTL_SECONDS
(default 600s); raise it for long-lived editor
sessions that quiesce between tool calls or lower it
to shed dormant connections faster. Transport
advertisement follows
XEROTIER_MCP_TRANSPORT (default
streamable; set to legacy to suppress
the streamable capability for clients that misbehave
against it).
Inference scope per request
Every MCP call must present an API key that carries
the inference scope. The scope check
happens at admission, before any tool dispatcher
runs. Keys scoped only to management or read-only
surfaces cannot be used to reach MCP, even with the
right URL.
Workspace pinning with cross-project verification
The X-Xerotier-Workspace header pins
each MCP connection to exactly one workspace. The
header accepts either the URL-safe external
identifier (ws_<hex>, the form
the dashboard surfaces in chat URLs, the workspace
navigator, and the Client tab) or the internal
workspace UUID. Either way, the router resolves
the value to a workspace row and then runs two
independent verifications before accepting the
pin: the workspace must belong to the same project
the authenticated API key is scoped to (the
cross-project membership check) and must
sit in the API key's allowed-workspace list when
that list is set. A key cannot be tricked into
addressing a workspace it does not own, even if
the identifier is technically valid for some other
project on the platform.
Rotation on download
Every Client tab download mints a fresh API key for the workspace and revokes any prior active key with the same name. Leaked or stale bundles stop working the moment a new bundle for the same workspace is downloaded.
Per-client capability matrix
Each MCP client supports a different subset of the protocol surfaces. The matrix below is hand-maintained against vendor docs and is re-verified periodically; vendor support for sampling, elicitation, and roots changes faster than most of the protocol, so treat the cells as a snapshot rather than a contract.
| Client | tools | prompts | resources | sampling | elicitation | roots |
|---|---|---|---|---|---|---|
| Claude Code | yes | yes (slash) | yes (@) | no | yes | yes |
| opencode | yes | yes (slash) | yes (@) | no | no | no |
| Cursor | yes | yes (@) | no | no | yes | yes |
| VS Code Copilot | yes | yes (slash) | yes (@) | yes | yes | yes |
| Claude Desktop | yes | yes | yes (@) | no | no | yes |
| OpenAI Codex | yes | no | yes (@) | no | yes | no |