Server4Agent
Interfaces

MCP server

Server4Agent speaks the Model Context Protocol. Add it to your agent framework and the agent can provision and drive servers as native tools, no glue code.

Connect

Endpoint. The MCP server is served at https://mcp.server4agent.com. Point your MCP client there and pass the agent's API key.

Point your framework's MCP client at our server and pass the agent's API key. Any MCP-capable runtime works.

mcp.config.json
{
  "mcpServers": {
    "server4agent": {
      "url": "https://mcp.server4agent.com",
      "headers": { "Authorization": "Bearer $SERVER4AGENT_API_KEY" }
    }
  }
}

Connecting a specific app? The Integrations page has copy-paste setup for 11 clients, plus a raw-JSON block for any other MCP-compatible host. Worth a look before you hand-write a config: the block above is the common shape, but hosts differ in ways that fail quietly. Some want TOML rather than JSON, some require an explicit transport field, and some name the endpoint key something other than url.

Tools

Once connected, the agent can call any of these tools. The headline is prompt, a freeform instruction the on-server agent plans and executes. The rest are the primitives it (or you) can reach for directly.

tools
// ── Server lifecycle ─────────────────────────────────────────
create_server      // → { id, url }                provision a new server
update_server      // { server_id, task?, region? }
delete_server      // { server_id }
control_server     // { server_id, action: start|stop|restart }
list_servers       // → [ { id, task, status, url } ]
get_server         // { server_id }                status, usage, URL
get_usage          // → spend, budget, blocked?     account AI spend + budget

// ── Projects (workspaces inside a server) ────────────────────
list_templates     // → [ { id, label, description, defaults } ]
list_projects      // { server_id? }
get_project        // { project_id }                → project + init_phase, health
create_project     // { server_id, name?, description?, visibility?,
                   //   access?, lifecycle?, source?, healthcheck?,
                   //   auto_init?, secrets? }
                   //                        → project, init_run_id, url-or-null
update_project     // { project_id, name?, description?,
                   //   visibility?, access?, lifecycle? }
delete_project     // { project_id }
cleanup_project    // { project_id }                ephemeral projects only

// ── Secrets (env vars for servers / projects) ────────────────
set_secret         // { key, value, description? }  create or update
list_secrets       // → [ { key, description, bound } ]  never values
delete_secret      // { secret_id }
attach_secret      // { key, value?, server_id, project_id? }  set + bind

// ── The "do anything" tool ───────────────────────────────────
prompt             // { server_id, prompt }        agent plans + executes
                   // → { run_id, status }

// ── Low-level primitives ─────────────────────────────────────
exec               // { server_id, command }       run a shell command
read_file          // { server_id, path }          → { content }
write_file         // { server_id, path, content }
delete_file        // { server_id, path }
list_files         // { server_id }                → { files: [...] }

// ── Structured project builds ────────────────────────────────
start_build        // { server_id, goal }          → { build_id, status }
get_build          // { server_id, build_id }      poll steps + artifacts

// ── Deploy ───────────────────────────────────────────────────
deploy             // { server_id }                → { url, status: "live" }

// ── Self-tuning from an evaluation report ────────────────────
start_tuning       // { evaluation_session_id, project_id }
                   // pulls the brief in, agent fixes + re-submits
                   // { evaluation_session_id, server_id } instead
                   // builds the agent's repo here first
get_tuning_session // { tuning_session_id }        poll to completion
list_tuning_sessions
report_tuning_result // { tuning_session_id, change_summary? }

Where a project starts

Every project is seeded from a source. Omit it for a blank workspace the agent scaffolds from a prompt, pass a template to apply a named starter, or point at your own code with a git or archive source (covered below). The template catalog leads with two import templates import-git (“Import from Git”) and import-zip (“Upload a codebase”) — so bringing your own code is the first thing offered.

Optional starters

Project starters are an optional catalog the agent can browse. Each one pre-fills sensible defaults for a use case (name, description, visibility, lifecycle), so the agent skips a round of decision-making when the work is recognisable: a webhook-to-Slack lead alert, an uptime monitor, a landing page with waitlist capture, a price/job watcher, or a CSV cleanup portal. The agent calls list_templates to discover them, then passes the id as the template argument to create_project.

templates
// 1. Discover the catalog — the two import templates lead, starters follow.
list_templates → [
  { id: "import-git", label: "Import from Git",
    source_kind: "git",     description: "Clone a repo and bring it up" },
  { id: "import-zip", label: "Upload a codebase (.zip)",
    source_kind: "archive", description: "Upload a zip and bring it up" },
  { id: "blank",      label: "Blank", source_kind: null },
  { id: "invoice-and-quote-maker", source_kind: null,
    description: "Generate numbered invoices and quotes as PDFs", … },
  { id: "url-uptime-monitor", source_kind: null, … },  // public

]

// 2. Use a starter. Any explicit field overrides the template default.
create_project {
  server_id: "srv_2k9",
  template:  "invoice-and-quote-maker"
}
// → { id, name: "Invoice & quote maker",
//     visibility: "private", lifecycle: "persistent",
//     template: "invoice-and-quote-maker", url: null }

// 3. Or pick an import template and pass the matching source.
create_project {
  server_id: "srv_2k9",
  template:  "import-git",
  source:    { kind: "git", git_url: "https://github.com/your-org/checkout-service" }
}

Any explicit argument overrides the template's default. Pass visibility: "public" to expose a private-by-default template, or override the name. Unknown template ids return a structured error pointing back at list_templates.

Who can open a live project

visibility decides whether a project's URL serves at all. access decides who gets through once it does. It defaults to "public", anyone with the link, which is how every project behaved before the field existed. Set it to "team" and opening the URL takes a Server4Agent sign-in and membership of the account that owns the project: right for an internal dashboard or a draft you want a colleague to look at, without putting it on the open internet. Both create_project and update_project accept it, and every read returns it.

Bring your own code

Point a project at a git repo or an uploaded archive and Server4Agent seeds the workspace with it, then brings it up: the on-server agent installs dependencies, starts the app, and confirms the service responds. This is the path for evaluating, reviewing, or just running an existing codebase — you supply the code, it figures out how to run it.

import
// Seed a project from a git repo, then bring it up automatically.
create_project {
  server_id: "srv_2k9",
  name:      "checkout-service",
  source:    { kind: "git", git_url: "https://github.com/your-org/checkout-service" }
  // auto_init defaults to true for git/archive sources
}
// → { id: "proj_9f2", init_run_id: "tsk_c40", init_phase: "seeding", url: null }

// The on-server agent seeds the workspace, installs dependencies, starts the
// app, and confirms it responds. Poll init_phase (or subscribe to the
// project.ready webhook) until the service is up:
get_project { project_id: "proj_9f2" }
// → { …, init_phase: "ready",
//        health: { listening: true, last_status: 200 } }

// Private repo? Reference a secret holding a clone token — never inline it:
//   source: { kind: "git", git_url: "…", auth_secret: "GIT_TOKEN" }

// A zip works the same way: write it (base64) with write_file, then
//   source: { kind: "archive", archive_path: "bundle.zip" }

With auto_init (on by default for git/archive sources), creating the project dispatches the bring-up run and returns an init_run_id. The project moves through seeding → installing → starting → ready (or failed), which you read from init_phase on the project or via the project.ready / project.init_failed webhooks. A repo that ships a .server4agent/ recipe (install + start + healthcheck) comes up without the agent having to guess; see the agent loop for how bring-up works.

Secrets & environment

Projects and servers run with secrets — environment variables bound server-wide (shared by every project) or to a single project. Set them inline on create_server / create_project, or manage them with set_secret / attach_secret. Values are write-only: they're injected as env into runs, but never returned by list_secrets or shown on a command line. A project-scoped secret overrides a server-wide one of the same key.

secrets
// Set env for a project up front — values are write-only, never returned.
create_project {
  server_id: "srv_2k9",
  name:      "checkout-service",
  source:    { kind: "git", git_url: "https://github.com/your-org/checkout-service" },
  secrets:   [ { key: "DATABASE_URL",      value: "postgres://…" },
               { key: "STRIPE_SECRET_KEY", value: "sk_live_…"    } ]
}

// If the code needs keys you didn't supply, bring-up pauses and lists them
// (from .env.example and process.env / os.environ references in the code):
get_project { project_id: "proj_9f2" }
// → { init_phase: "awaiting_secrets",
//     required_secrets: [
//       { key: "DATABASE_URL",      source: "env-example", provided: true  },
//       { key: "STRIPE_SECRET_KEY", source: "code",        provided: false } ] }

// Supply the missing ones (or react to the project.secrets_required webhook);
// bring-up resumes on its own once every required key is set:
attach_secret { key: "STRIPE_SECRET_KEY", value: "sk_live_…",
                server_id: "srv_2k9", project_id: "proj_9f2" }

When you import code, bring-up scans it for the env it needs — .env.example entries and process.env / os.environ references — and lists them as required_secrets. If any are unset it pauses at awaiting_secrets and fires project.secrets_required rather than failing; supply the values and it resumes, or pass proceed to continue past optional ones.

Why MCP-first

Agents are the users. Exposing Server4Agent as MCP tools means the agent decides when it needs a server and gets one itself, mid-task, without a human or a separate integration step.

Runnable examples

A zero-dependency script that speaks raw JSON-RPC to this endpoint (initialize, list tools, create a server and a project) lives in the examples directory on GitHub, next to a REST quickstart and three template walkthroughs.

Next: REST API

Connect an agent

Create a key, paste the MCP config, and give your agent a persistent server it can build on.

MCP setup →