MCP server
Let Claude Code, Cursor, Codex and other MCP clients create and drive pols sandboxes through the pols mcp server.
The pols CLI includes an MCP (Model Context Protocol) server. Your MCP client starts it on your machine with pols mcp and talks to it over standard input and output; the server calls the pols API with your API key. Through it, an agent can create, stop, resume, fork and delete sandboxes, run commands, read and write files, and use the sandbox’s desktop and Chrome.
Set it up
Install the CLI and log in
curl -fsSL https://pols.so/install.sh | sh
pols loginpols mcp uses the key pols login stored, so your client configuration holds no secret. If Claude Code is installed, the install script and pols login offer to register the server for you.
Register the server with your client
Every client runs the same command: pols with the argument mcp. Desktop apps often do not see your shell’s PATH; if a client cannot find pols, use the full path that command -v pols prints.
Claude Code
claude mcp add --scope user pols -- pols mcp
To use POLS_API_KEY from your environment instead of pols login, add the server to a project’s .mcp.json and pass the variable through by reference:
{
"mcpServers": {
"pols": {
"command": "pols",
"args": ["mcp"],
"env": { "POLS_API_KEY": "${POLS_API_KEY}" }
}
}
}
Cursor
In ~/.cursor/mcp.json for all projects, or .cursor/mcp.json for one:
{
"mcpServers": {
"pols": { "command": "pols", "args": ["mcp"] }
}
}
To use POLS_API_KEY, add "env": { "POLS_API_KEY": "${env:POLS_API_KEY}" } to the entry.
Codex
codex mcp add pols -- pols mcp
Or in ~/.codex/config.toml, where env_vars passes POLS_API_KEY through when you use it instead of pols login:
[mcp_servers.pols]
command = "pols"
args = ["mcp"]
env_vars = ["POLS_API_KEY"]
Other clients
Any client that runs stdio servers takes the same command, pols with the arguments ["mcp"]. Never put the key itself into a configuration file; use pols login or a reference to an environment variable.
Tools
Sandboxes are named by ID or name. Lifecycle tools wait until the sandbox has arrived (up to wait_timeout_seconds, default 300) unless you set no_wait.
| Tool | Does | Hint to the client |
|---|---|---|
sandbox_create |
create a sandbox (name, size, template, env, secrets) and wait until it runs |
not destructive |
sandbox_list |
list the org’s sandboxes, newest first; include_deleted adds deleted ones |
read-only |
sandbox_get |
one sandbox with its size, status, desired state and last error | read-only |
sandbox_stats |
a sandbox’s CPU, memory and disk use, with the samples of the last hour | read-only |
org_stats |
CPU, memory and disk use summed over the running sandboxes | read-only |
vault_list |
names and kinds of the vault entries, never values | read-only |
sandbox_stop |
stop a sandbox; its disk is kept | destructive |
sandbox_resume |
resume a stopped sandbox | not destructive |
sandbox_fork |
fork a sandbox into a new running one; secrets adds vault entries |
not destructive |
sandbox_delete |
delete a sandbox and its disk | destructive |
sandbox_exec |
run a command (an argument array, such as ["bash", "-lc", "npm test"]) with cwd, env, root, stdin and timeout_seconds (default 600); returns exit code, stdout and stderr |
open world |
file_read |
read a file as UTF-8 text, or base64 for binary data; at most 1 MiB (max_bytes) |
read-only |
file_write |
create or overwrite a file (encoding utf-8 or base64, mode, root); the parent directory must exist |
may overwrite |
computer_screenshot |
a PNG of the whole 1920x1080 desktop, as image content | read-only |
computer_click, computer_double_click |
click a mouse button at x, y |
open world |
computer_drag |
drag with the left button from x, y to to_x, to_y |
open world |
computer_type |
type up to 10,000 characters into the focused window | open world |
computer_key |
press keys, such as Return, ctrl+l or Escape Tab Tab |
open world |
computer_scroll |
scroll up, down, left or right by 1 to 50 clicks at x, y |
open world |
browser_cdp |
a WebSocket URL for Playwright or Puppeteer to drive the sandbox’s Chrome, valid for 5 minutes | not destructive |
“Open world” tools run arbitrary commands or input in the sandbox, which may reach the internet. Your client may use the hints to decide which calls to confirm with you. Creating, forking and resuming start billed running time; ask your agent to stop sandboxes it no longer needs.
A non-zero exit code from sandbox_exec is a result, not a tool error.
Limits
sandbox_execreturns at most 512 KiB per output stream and setstruncatedwhen it cut the output.- A result larger than the MCP response size limit, such as a very long sandbox list or a large screenshot, comes back as an error instead of a partial result. Use the CLI or the API for those.
- Egress policies, templates, published ports, desktop links and SSH are not available over MCP. Use
pols new --egress,pols template,pols host,pols desktopandpols ssh.
Example
Ask your agent:
Create a small pols sandbox called demo, clone https://github.com/octocat/Hello-World
into it and show me the README. Stop the sandbox when you are done.
It calls the tools roughly in this order:
sandbox_create { "name": "demo", "size": "small" }
sandbox_exec { "sandbox": "demo", "command": ["bash", "-lc", "git clone https://github.com/octocat/Hello-World"] }
file_read { "sandbox": "demo", "path": "/home/user/Hello-World/README" }
sandbox_stop { "sandbox": "demo" }