Tandem for agents — capabilities overview

Read this first if you have never heard of Tandem. It explains what Tandem is, the shape of its resource model, how authentication works, and the shortest path from nothing to a running app.

What Tandem is

Tandem is a hosting platform that provisions the whole production stack for an app:

  • Deploy apps from Git — static sites, Node services, or any Dockerfile.
  • Host code — Tandem Git private repositories: standard HTTPS clone/push, a repository mutation API (read/commit without cloning), Drive-style sharing, migrate in/out of GitHub, and continuous single-primary “Mirror to GitHub” (never multi-master; diverged commits are backed up, never lost).
  • Custom domains + DNS — register or attach domains, manage zone records, automatic TLS.
  • Managed databases — per-tenant Postgres or MySQL, credentials injected as DATABASE_URL.
  • Object storage — S3-compatible buckets with scoped credentials.
  • Managed Redis — per-tenant Valkey instances, injected as REDIS_URL.
  • Email — custom-domain mailboxes (IMAP/SMTP/JMAP), a transactional send API, and inbound webhooks.
  • Web analytics — privacy-friendly, first-party pageview/visitor data.
  • Billing — subscriptions, invoices, usage, payment methods.

Humans and AI agents are first-class equals. An agent can create an organization, provision resources, deploy, and manage billing over the MCP server with no human pre-setup. A human can do the same in the portal. Neither is a second-class citizen; where one surface can’t yet do something the other can, that’s a temporary gap, not a design choice.

How you talk to Tandem

Everything in this overview is done by calling MCP tools.

What Value
MCP endpoint https://portal.launchtandem.com/mcp
Transport Streamable HTTP (JSON-RPC over HTTP POST)
Auth Authorization: Bearer <token> header
Token format tdm_ + 48 hex characters (treat like a password)

A tool call is a JSON-RPC tools/call:

{
  "jsonrpc": "2.0", "id": 1, "method": "tools/call",
  "params": { "name": "whoami", "arguments": {} }
}

The result comes back as a JSON-RPC envelope whose result.content[0].text is a JSON string — parse that for the tool’s payload. There are 140 tools; see the MCP tool reference for the full list.

The resource model

organization
└── project
    └── service ──── deployment (queued → building → healthy)
  • Organization — the top-level tenant and the unit of billing, membership, and ownership. Everything belongs to exactly one org.
  • Project — a group of related services (e.g. one app). Owns its repositories, databases, buckets, redis, and analytics.
  • Service — one deployable unit (a web app, an API, a worker). Each service gets an auto-assigned hostname <service>-<project-slug>.launchtandem.com and can have custom domains attached.
  • Deployment — one build+run of a service from a Git ref. Deployments move through queued → cloning → building → deploying → health_checking → healthy (or failed / rolled_back).

Resources that hang off an org or project and attach to services:

Resource Provision with Attaches to a service by injecting…
Database (Postgres/MySQL) provision_database DATABASE_URL
Object storage bucket create_bucket S3_ENDPOINT, S3_REGION, S3_BUCKET, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_FORCE_PATH_STYLE
Redis / Valkey provision_redis REDIS_URL
Mailbox provision_email EMAIL_* (IMAP + SMTP + JMAP)
Analytics provision_analytics TANDEM_ANALYTICS_WEBSITE_ID, TANDEM_ANALYTICS_SCRIPT_URL

The injected env-var key names are a stable contract — the value may change if a resource is migrated to a different backend, but the key never does. Injected vars take effect on the service’s next deploy or restart.

Org- and account-level resources: domains & DNS, members (humans and agents), limits/policies (per-principal action masks + approval thresholds), and billing (subscription, invoices, usage, payment method).

The auth & token model

A token carries two independent constraints:

  1. Actions — an allow-list of what the credential may do: read, manage, deploy, logs, restart, rollback, plus the Tandem Git source actions source:read, source:write, source:admin (deploy does NOT imply source access; new tokens mint them on by default, pre-existing tokens don’t have them). A bootstrap/owner token has all of them; a scoped token can be narrower.
  2. Org role — the principal’s role in the org: viewer < developer < admin < owner. Mutating tools state their required role (e.g. DNS edits need manage + developer; deletes need manage + admin). On Tandem Git repositories the role maps to capabilities (owner/admin → read+write+admin, developer → read+write, viewer → read), unioned with any explicit per-repo share grants.

Call whoami to see your identity, your org memberships, and the live action mask on your credential. Limits also apply to humans, not just agents — see Limits and policies.

The deploy gate

Before an org can deploy (or make a charge like buying a domain), it must pass the deploy gate: it needs a verified billing state and a verified recovery method. Check it with get_deploy_gate_status — it returns { billingVerified, recoveryVerified, recoveryMethod, blockers, allowed } so you can surface the exact missing step instead of trial-and-erroring.

  • Human-owner orgs typically satisfy recovery via the claim-email roundtrip (the owner clicks the link and sets a password).
  • AI-only orgs (created with create_own_organization) have no human owner, so they satisfy recovery with an Ed25519 recovery key: call register_recovery_key, sign the returned challenge, then verify_recovery_key.

Start from zero

The shortest path from no account to a running app:

  1. Bootstrap. Call create_account_and_claim_link anonymously (no auth). It creates an org, emails a human a claim link, and issues you an agent token bound to the new org. Persist it as a bearer header. (For an org you own with no human, use create_own_organization instead — then register + verify a recovery key.) Full walkthrough: Bootstrapping an account.
  2. Connect a repo. Have a GitHub App installation, then connect_repository and set_project_repository. Or read platform.yml and import_services. See Connecting a repo and Writing platform.yml.
  3. Provision what the app needs. provision_database, create_bucket, provision_redis, provision_email — each can auto-attach to a service via attachServiceId.
  4. Clear the deploy gate. get_deploy_gate_status; add billing / a recovery key if blocked.
  5. Deploy. create_deployment (one service) or deploy_project (all services in a project). Poll list_deployments / get_deployment; read view_logs.
  6. Give it a domain. check_domain_availabilitypurchase_domain, or attach_domain for a domain you already own. See Custom domains and DNS.

Where to go next