MCP
MCP overview
Every primitive exposed as MCP tools over Streamable HTTP or stdio, scoped to one group.
Primitives exposes every primitive as a Model Context Protocol tool. Any MCP client, such as Claude Code, Cursor or your own agent loop, gets every primitive in a group (as many databases, filesystems, queues, memories, vaults, key-value stores and object stores as it holds) with no glue code.
How it works
| Endpoint | Auth | |
|---|---|---|
| Cloud | https://mcp.useprimitives.com/mcp | A pk_ API key, or OAuth sign-in |
Local (primitives dev) | http://localhost:7777/mcp/<group> | None. ?tools=kv_*,storage_* narrows the tools |
| Local, stdio | primitives mcp --group <name> | None |
The HTTP endpoint uses the Streamable HTTP transport. In the cloud, every request authenticates with an API key:
Authorization: Bearer $PRIMITIVES_API_KEYThe cloud URL is the same for every group: the credential decides which one a session reaches. Give an agent an API key scoped to its group, so the key for agent-42 can never reach agent-43, and limited to the tools it needs. A key for every group names one in the X-Primitives-Group header. MCP clients you use yourself, such as Claude, Claude Code or Cursor, can connect with only the URL and sign in with OAuth, picking the group and tools on the consent page. See Auth & scoping.
On your own machine, primitives dev needs no credential: the group comes from the path (see Local access without a token).
Every tool call runs through the same REST API the SDKs use, in-process, with the caller's credential, narrowed to that one tool. Validation, permissions and the audit trail are therefore identical for MCP, REST and the SDKs.
What the agent gets
| Area | Tools |
|---|---|
| Group | primitive_list, primitive_create, primitive_snapshot, primitive_fork |
| Database | db_query, db_exec, db_branch |
| Filesystem | fs_read, fs_write, fs_search, fs_fork |
| Queue | queue_send, queue_receive, queue_ack |
| Memory | memory_remember, memory_recall, memory_forget |
| Vault | vault_list, vault_use |
Agents discover, then use. primitive_list returns the group's primitives (id, name, type, paused); every db_, fs_, queue_, memory_ and vault_ tool, plus primitive_snapshot and primitive_fork, then takes one argument primitive: the id or the name from that list. When the group has exactly one primitive of the tool's type, primitive can be left out. An unknown, ambiguous or wrong-type primitive returns an error telling the agent to call primitive_list. primitive_create lets the agent add a primitive of its own and returns its { id, name, type }:
{ "type": "db", "name": "scratch" }tools/list returns only the tools the credential allows. Every tool declares MCP annotations: read-only tools set readOnlyHint, so clients can auto-approve them and still ask before a write. Results come back as JSON text and as structuredContent. Errors come back as tool results with isError set and text like tool_not_allowed: this caller may not use db_exec. The tools reference lists every tool and its arguments.
MCP or SDK?
They are two views of the same group, so you can mix them:
- Use MCP when the model itself should decide when to query, write files or remember things.
- Use the SDK in your orchestrator to create groups, seed data and read results.
A common pattern: your server creates the group and its primitives and seeds them through the SDK with its workspace key, then gives the agent an API key scoped to that group and nothing else.
const p = new Primitives({ token: process.env.PRIMITIVES_API_KEY }); // workspace key, server only
const group = await p.groups.create({ name: 'agent-42' });
await group.db.create('main');
await group.memory.create('notes');
const workspace = await group.fs.create('workspace');
await workspace.write('/task.md', taskDescription);
// A key created in the dashboard, scoped to agent-42 and db_*, fs_*, memory_*
await startAgent({
mcpUrl: 'https://mcp.useprimitives.com/mcp',
apiKey: process.env.AGENT_42_API_KEY,
});Next steps
- Connect a client: Claude Code, Cursor, stdio clients and your own loop.
- Tools reference: every tool, its arguments and whether it writes.
- Auth & scoping: scoped API keys, OAuth and tool allowlists.