MCP Servers
Register Model Context Protocol servers in Temps so that agents running in a sandbox can reach external tools. A registered server becomes available to agent runs and workspace sessions, with its configuration written into whichever harness the run uses.
Which direction is this?
MCP connects two things, and it is easy to read a page like this backwards. This page is about Temps agents acting as MCP clients — a Temps agent connecting out to an external MCP server you have registered.
Global and project scope
An MCP server is registered at one of two scopes:
| Scope | Where | Available to |
|---|---|---|
| Global | Settings → MCP Servers | every project on the instance |
| Project | Project → Settings → MCP Servers | that project only |
Both scopes live in the same registry and are addressed by slug. When an agent run requests a set of slugs, Temps resolves them against the global definitions and the definitions belonging to that project together, so a run can mix both.
Because resolution is by slug across both scopes, keep slugs distinct — reusing one global slug for a project-scoped server makes it ambiguous which definition a run receives.
Requesting a slug that resolves to nothing is not fatal: the run continues and reports the unresolved slug in its injection summary, so a typo shows up in the run log rather than silently doing nothing.
Adding a server
- Go to Settings → MCP Servers for a global server, or Project → Settings → MCP Servers for one scoped to a single project.
- Click Add MCP server.
- Give it a slug (how agent runs refer to it), a name, and an optional description.
- Paste the server's config as JSON — see below.
The slug is fixed once created; name, description, and config can be edited afterwards.
Config format
The config field takes a single entry in the same shape Claude Code uses for mcpServers in settings.json. Temps stores exactly what you paste and translates it per harness at injection time, so you can copy a config straight out of an MCP server's own README.
A stdio server — Temps runs the command inside the sandbox:
{
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
"env": {
"SOME_TOKEN": "..."
}
}
A remote server — Temps connects over HTTP:
{
"type": "url",
"url": "https://mcp.example.com/sse",
"headers": {
"Authorization": "Bearer ..."
}
}
A stdio server's command runs inside the agent sandbox, not on the Temps host. Anything it needs must be fetchable from the sandbox — npx/bunx packages work well; a binary that only exists on your laptop will not.
Secrets
MCP configs routinely carry API tokens, so Temps treats three parts of the config as sensitive: url, every value under env, and every value under headers.
Stored configs are encrypted at rest. When a config is read back — in the list, in the detail view, over the API — those fields come back masked rather than in clear text. Empty values stay empty, so a masked field is always a field that really holds something.
To see one real value, use the reveal control beside the field. That is a separate request per field, and it:
- requires both
settings:readandsecrets:readpermission, - writes an audit log entry recording who revealed which field,
- is returned with
Cache-Control: no-store.
Editing a config does not require revealing it. Masked fields you leave alone keep their stored values, so you can change a command or add an arg without ever putting a token back on screen.
How configs reach the agent
When an agent run or workspace session starts, Temps resolves the requested slugs, merges them into a single mcpServers map, and writes it into the sandbox in the format the run's harness expects:
| Harness | Written as |
|---|---|
| Claude Code | mcpServers JSON under /home/temps/.claude |
| OpenAI Codex CLI | TOML in ~/.codex/config.toml |
| OpenCode | OpenCode's own MCP JSON |
The Claude Code JSON is always written; the harness-specific file is written in addition when the run uses Codex or OpenCode. This is why one stored config works across harnesses — you write it once in Claude Code's shape and Temps transcodes it.
Secret material is written outside /workspace. /workspace is bind-mounted from the cloned repository, so anything written there would follow the branch into a pull request — file-backed secrets are placed under /home/temps/.temps/secrets/ instead.
API reference
Both scopes expose the same operations. Global servers:
GET /api/v1/settings/mcp-servers
POST /api/v1/settings/mcp-servers
GET /api/v1/settings/mcp-servers/{slug}
PUT /api/v1/settings/mcp-servers/{slug}
DELETE /api/v1/settings/mcp-servers/{slug}
GET /api/v1/settings/mcp-servers/{slug}/config/{field}
Project-scoped servers use the same shapes under a project:
GET /api/v1/projects/{project_id}/mcp-servers
POST /api/v1/projects/{project_id}/mcp-servers
GET /api/v1/projects/{project_id}/mcp-servers/{slug}
PUT /api/v1/projects/{project_id}/mcp-servers/{slug}
DELETE /api/v1/projects/{project_id}/mcp-servers/{slug}
GET /api/v1/projects/{project_id}/mcp-servers/{slug}/config/{field}
Creating a server takes the slug, name, optional description, and config:
curl -X POST "https://your-instance/api/v1/settings/mcp-servers" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "filesystem",
"name": "Filesystem",
"description": "Read-only access to the workspace",
"config": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
}
}'
Updates are partial — send only name, description, or config. The final endpoint reveals one sensitive field, where {field} is url or a dotted path such as env.SOME_TOKEN.
Related
- AI Skills — the other half of what gets injected into an agent sandbox, and the supported way to point your own assistant at Temps.
- Agent Sandbox Secrets — how secret material is mounted into a sandbox.
- Sandboxes & Workspaces — where agent runs execute.