MCP Server
Endpoint
Section titled “Endpoint”The unsurf MCP server is available at:
https://unsurf-api.coey.dev/mcpIt uses the Streamable HTTP transport from the MCP specification. The server runs in stateless mode — each request is independent.
For full documentation of all tool inputs, outputs, and error types, see the MCP Tools reference.
Connecting from Claude Desktop
Section titled “Connecting from Claude Desktop”Add this to your Claude Desktop MCP config (~/.claude/mcp.json):
{ "mcpServers": { "unsurf": { "type": "streamable-http", "url": "https://unsurf-api.coey.dev/mcp" } }}Restart Claude Desktop. You should see unsurf listed under the MCP tools icon.
Connecting from Cursor
Section titled “Connecting from Cursor”Open Cursor Settings → MCP Servers → Add Server and enter:
| Field | Value |
|---|---|
| Name | unsurf |
| Transport | Streamable HTTP |
| URL | https://unsurf-api.coey.dev/mcp |
Cursor will discover the available tools automatically.
Local browser MCP
Section titled “Local browser MCP”Use the hosted MCP server for Cloudflare-side scout/search/plan work. Use the local stdio server when an agent should operate the Chrome session already open on your machine:
{ "mcpServers": { "unsurf-local": { "command": "unsurf-local-mcp" } }}The local server exposes two tools:
unsurf_local_sessions— list attachable local Chrome/CDP tabsunsurf_local_execute— run small browser action plans against the active attached browser, optionally recording an unsurf trace
This is the “browser is the auth” path: the tool does not mint credentials or create a new browser profile; it uses the session you already authenticated.
Connecting from a custom MCP client
Section titled “Connecting from a custom MCP client”Any client that supports the Streamable HTTP transport can connect. Point it at the /mcp endpoint and send standard JSON-RPC messages:
POST /mcpContent-Type: application/jsonAccept: application/json, text/event-streamThe server supports the initialize, tools/list, and tools/call methods.
Testing the connection
Section titled “Testing the connection”You can verify the MCP endpoint works with plain curl.
Initialize
Section titled “Initialize”curl -X POST https://unsurf-api.coey.dev/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "test", "version": "1.0" } } }'You should get back a response with serverInfo and capabilities.
List tools
Section titled “List tools”curl -X POST https://unsurf-api.coey.dev/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}'The response lists the registered tools. The hosted server includes scout, worker, heal, gallery, unsurf_search, and unsurf_execute; directory and agent-scout appear when their optional bindings are configured.
The trace-skill tool pair
Section titled “The trace-skill tool pair”Beyond the scout/worker/heal set, the MCP server exposes two tools that work with the record/observe/loop skills — a pair-pattern (search + execute) so agents have a small, stable surface to reason over:
unsurf_search
Section titled “unsurf_search”List recorded traces. Filter by owner, task substring, or visibility. Returns viewerUrl values with grants pre-minted, ready to open.
curl -X POST https://unsurf-api.coey.dev/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "unsurf_search", "arguments": { "q": "httpbin form", "limit": 5 } } }'unsurf_execute
Section titled “unsurf_execute”Run one of unsurf’s Worker-safe skills. Today:
loopPlan— synthesize a structuredLoopSpecfrom a natural-language goal via Kimi K2.6. Plan only; no browser drive. Feed the result to the localunsurf loopCLI (orloop()JS API) to actually record.
{ "jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": { "name": "unsurf_execute", "arguments": { "action": "loopPlan", "goal": "go to coey.dev, open the first project", "northStar": "Did the user land on a project detail page?" } }}Actions that need local Node APIs (actual record() via agent-browser, observeVideo() via ffmpeg) are CLI-only until the cloud recording provider lands (Phase 4 in NORTHSTAR.md).
Call a tool
Section titled “Call a tool”curl -X POST https://unsurf-api.coey.dev/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "scout", "arguments": { "url": "https://jsonplaceholder.typicode.com", "task": "discover all API endpoints" } } }'Self-hosting
Section titled “Self-hosting”When you deploy your own unsurf instance, the MCP endpoint is automatically available at /mcp on your worker URL.
-
Clone the repo and install dependencies:
Terminal window git clone https://github.com/acoyfellow/unsurf.gitcd unsurf && bun install -
Set the required environment variables (see Configuration):
Terminal window export ALCHEMY_PASSWORD="your-secret-password"export CLOUDFLARE_API_TOKEN="your-cf-token"export CLOUDFLARE_ACCOUNT_ID="your-cf-account-id" -
Deploy:
Terminal window bun run deploy -
Point your MCP clients at your worker URL:
https://unsurf.<your-subdomain>.workers.dev/mcp