← Back to home Docs

MCP server

spawnpoint is agent-native: it ships a first-class Model Context Protocol server. Your agent connects to it and deploys itself.

Most people don't need this page. The Claude Code plugin wires all of this up for you, skill-driven. This is the underlying reference, for building your own client or debugging.

Endpoint

Connect

Start here. One command wires spawnpoint into every coding agent on your machine and writes the config for you. Do not hand-edit an MCP config file: the installer knows the right path, the right format, and the right endpoint for each agent, and it is the only path we test.
curl -fsSL https://getspawnpoint.com/install | bash

It detects Claude Code, Codex CLI, Cursor, opencode, GitHub Copilot CLI, VS Code Copilot, and jcode, and sets up each one it finds. Limit it to one with SPAWNPOINT_AGENT=claude|codex|cursor. Point it at a local dev server with SPAWNPOINT_URL=http://localhost:8080.

Then sign in once, in the browser, for each agent. Find yours below.

Claude Code

  1. Run the installer:
    curl -fsSL https://getspawnpoint.com/install | bash
    It also adds the spawnpoint plugin, so "deploy this" works as a skill.
  2. Restart Claude Code.
  3. Run /mcp, choose spawnpoint, choose Authenticate, and approve in the browser.

Then say "deploy this" and you get a link back.

Cursor

  1. Run the installer:
    curl -fsSL https://getspawnpoint.com/install | bash
    It writes Cursor's MCP config for you.
  2. Run cursor-agent mcp login spawnpoint, or open Cursor's MCP settings and approve spawnpoint.

Do not write Cursor's MCP config by hand. The installer puts it in the right place with the right endpoint, and hand-editing still leaves the browser sign-in to do.

Codex CLI

  1. Run the installer:
    curl -fsSL https://getspawnpoint.com/install | bash
    It runs codex mcp add for you.
  2. Run codex mcp login spawnpoint.

opencode

  1. Run the installer:
    curl -fsSL https://getspawnpoint.com/install | bash
  2. Run opencode mcp auth spawnpoint.

GitHub Copilot CLI

  1. Run the installer:
    curl -fsSL https://getspawnpoint.com/install | bash
  2. Run copilot, use any spawnpoint tool, and approve the browser sign-in when it prompts.

VS Code Copilot

  1. Run the installer:
    curl -fsSL https://getspawnpoint.com/install | bash
  2. Open Copilot Chat in agent mode, start the spawnpoint server, and sign in from the browser prompt.

jcode

  1. Run the installer:
    curl -fsSL https://getspawnpoint.com/install | bash
    It writes the spawnpoint entry into ~/.jcode/mcp.json.
  2. Use any spawnpoint tool; mcp-remote opens the browser sign-in on first use.

jcode speaks stdio-only MCP today, so the installer bridges it to spawnpoint's hosted endpoint through the mcp-remote npm package, which needs Node (npx) on your PATH. On a headless machine with no browser, create an API token and add "--header" and "Authorization: Bearer spk_live_your_token" to the entry's args instead.

Any other MCP client

The installer does not know your client, so this is the one case where you configure it yourself. Every OAuth-capable MCP client needs only the URL, and will prompt you to sign in:

{
  "mcpServers": {
    "spawnpoint": {
      "url": "https://app.getspawnpoint.com/mcp"
    }
  }
}

Wiring a supported agent by hand, if you must: claude mcp add --transport http --scope user spawnpoint <url>/mcp, codex mcp add spawnpoint --url <url>/mcp, opencode mcp add spawnpoint --url <url>/mcp, copilot mcp add spawnpoint <url>/mcp, code --add-mcp '{"name":"spawnpoint","type":"http","url":"<url>/mcp"}'.

Environments with no browser

Clients that cannot do OAuth send a token instead:

{
  "mcpServers": {
    "spawnpoint": {
      "url": "https://app.getspawnpoint.com/mcp",
      "headers": { "Authorization": "Bearer spk_live_your_token" }
    }
  }
}

Every call is scoped to the account that authorized it.

Copilot coding agent (the cloud agent working GitHub issues) has no browser, so it uses a token: create an API token, store it as a Copilot agents secret named COPILOT_MCP_SPAWNPOINT_TOKEN, and add spawnpoint to the repository's MCP configuration (Settings → Copilot → MCP servers) with an Authorization header that references it.

Tools

Thirteen tools, one job each:

deploy_project

Input:

deploy_project({
  "name": "invoice-tool",
  "runtime": "node",
  "entrypoint": "server.js",
  "files": [
    { "path": "server.js", "content": "require('http').createServer(...)" },
    { "path": "package.json", "content": "{ \"name\": \"invoice-tool\" }" }
  ]
})
// → { "project_id": "proj_…", "url": "https://spawn-….run.openrelay.inc", "status": "spawning" }

The call returns immediately; provisioning finishes in the background. Poll get_project until the status leaves spawning.

create_upload

Inline files are right for a small app the agent just wrote. For files that already exist on disk (or any binary asset), inlining means the agent regenerates every byte as output, which is slow and costs tokens. The upload path moves the bytes over HTTP instead:

create_upload()
// → { "upload_id": "upl_…", "upload_url": "https://…/api/uploads/upl_…",
//     "command": "tar czf - --exclude .git --exclude node_modules . | curl -fsS -T - \"…\"", "note": "…" }

Run the returned command from the app's directory (it tars and uploads in seconds), then call deploy_project with upload_id instead of files. The URL takes a gzipped tar, works exactly once, and expires in 30 minutes; the bundle limit is 20 MiB, and .git and node_modules must be excluded (dependencies install on the machine from package.json or requirements.txt). A rejected archive does not spend the URL: fix the tar and re-run the command.

set_visibility

set_visibility({ "project_id": "proj_…", "visibility": "public" })
// → { "project_id": "proj_…", "visibility": "public", "share_url": "https://…" }

New projects are private by default: only you and the emails you share with (verified by a one-time code, no account needed) can open the link. Flip to public to let anyone with the link view; flip back any time. The share URL never changes either way, and a flip takes effect immediately.

share_project

share_project({ "project_id": "proj_…", "email": "friend@example.com" })
// → { "project_id": "proj_…", "shared_with": ["friend@example.com"],
//     "share_url": "https://…", "note": "an invite email with the link is on its way to …" }

Adds one person to a private project's allow list. They get an invite email with the link, and the first time they open it they verify with a one-time code sent to that address: no account needed. Takes effect immediately. Up to 50 people per project; re-adding someone already on the list is harmless and sends no second email.

unshare_project

unshare_project({ "project_id": "proj_…", "email": "friend@example.com" })
// → { "project_id": "proj_…", "shared_with": [], "note": "… can no longer open the link" }

Removes one viewer. Revocation is instant: the gate checks the list on every request.

get_project

get_project({ "project_id": "proj_…" })
// → { "project_id": "proj_…", "name": "…", "status": "running", "url": "https://…", "health": "ok" }
// on a failed deploy, status is "error" and an "error" field says why

get_project_logs

get_project_logs({ "project_id": "proj_…" })
// → { "kind": "push", "log": "=== upload ===\n=== install ===\n…" }
get_project_logs({ "project_id": "proj_…", "kind": "runtime" })
// → { "kind": "runtime", "log": "<the app's journal tail>" }

push (the default) is the last deploy's combined output: upload, dependency install, and start. When a deploy errors, the installer's own output is usually the explanation. runtime fetches the last 200 lines of the app's journal live from the machine. A note field explains an empty log (nothing recorded yet, or the machine is gone).

list_projects

list_projects()
// → { "projects": [ { "project_id": "proj_…", "name": "…", "status": "running", "url": "https://…", "health": "ok" } ] }

terminate_project

terminate_project({ "project_id": "proj_…" })
// → { "status": "terminated" }

Runtimes

Your app listens on port 8080. spawnpoint runs it for you:

Dependencies install automatically: ship requirements.txt (python) or package.json (node) at the bundle root and spawnpoint installs them on the machine before starting the app, so Flask, Express, and friends just work. Apps run under a supervisor that restarts them after crashes and machine reboots.

Hosted and live. The installer registers https://app.getspawnpoint.com/mcp for you, and sign-in is one browser approval. The beta is open: sign in with your email and deploy.