MCP server
spawnpoint is agent-native: it ships a first-class Model Context Protocol server. Your agent connects to it and deploys itself.
Endpoint
- URL: your spawnpoint's origin plus
/mcp. spawnpoint runs on your machine today, so the default ishttp://localhost:8080/mcp; there is no MCP endpoint at spawnpoint.lol. - Transport: Streamable HTTP (the current hosted-server standard)
- Auth: OAuth 2.1 (PKCE, dynamic client registration), advertised from the endpoint via
.well-knowndiscovery. A long-livedspk_live_…API token as a bearer credential also works.
Connect
The installer detects the coding agents on your machine (Claude Code, Codex CLI, Cursor) and wires spawnpoint into each of them:
curl -fsSL https://spawnpoint.lol/install | bashOne browser sign-in per agent finishes the job:
- Claude Code: restart it, run
/mcp→ spawnpoint → Authenticate. (The installer also adds the plugin, so "deploy this" is skill-driven.) - Codex:
codex mcp login spawnpoint - Cursor:
cursor-agent mcp login spawnpoint, or approve spawnpoint in the IDE's MCP settings.
Wiring by hand instead: claude mcp add --transport http --scope user spawnpoint <url>/mcp, codex mcp add spawnpoint --url <url>/mcp, or for Cursor add it to ~/.cursor/mcp.json. Any other OAuth-capable MCP client needs only the URL and will prompt you to sign in:
{
"mcpServers": {
"spawnpoint": {
"url": "http://localhost:8080/mcp"
}
}
}
Clients that can't do OAuth send a token instead:
{
"mcpServers": {
"spawnpoint": {
"url": "http://localhost:8080/mcp",
"headers": { "Authorization": "Bearer spk_live_your_token" }
}
}
}
Every call is scoped to the account that authorized it.
Tools
Three tools, one job each:
deploy_project: deploy an app, get a public URLlist_projects: list your projects and their URLsterminate_project: stop a project and free its URL
deploy_project
Input:
name: a short project nameruntime:static,node, orpython(defaultstatic)entrypoint: file to run fornode/python(e.g.server.js,main.py)files: array of{ path, content }making up the appenv: optional environment variables
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": "running" }
list_projects
list_projects()
// → { "projects": [ { "project_id": "proj_…", "name": "…", "status": "running", "url": "https://…" } ] }
terminate_project
terminate_project({ "project_id": "proj_…" })
// → { "status": "terminated" }
Runtimes
Your app listens on port 8080. spawnpoint runs it for you:
- static: files are served as a static site.
- node:
node <entrypoint>(your server binds:8080). - python:
python3 <entrypoint>(your server binds:8080).