MCP tool reference

Every Tandem MCP tool, grouped by domain. 163 tools total. Each row is a one-line purpose plus its key parameters — * marks a required parameter. Descriptions are faithful to the live tool definitions; call a tool with only its schema-required args to start.

All calls go to POST https://portal.launchtandem.com/mcp as JSON-RPC tools/call with an Authorization: Bearer tdm_… header. Only create_account_and_claim_link and create_own_organization work without auth. See Connecting agents for client setup and Capabilities overview for the resource model.

Common gating shorthand used below: read/manage = the token action required; viewer/developer/admin/owner = the org role required.

The free trial, in one paragraph

A new organization starts on the preview tier: a 14-day free trial that really deploys, with no payment method at all. Its allowance is 1 service, 1 database, 1 bucket; custom domains, domain purchase/transfer, outbound email and managed Redis are excluded outright (a card does not buy them — a subscription does). Domain renewal is allowed with a card, so a domain you already own can never lapse. At expiry, deploys are blocked (preview_expired) and containers are reclaimed — nothing is deleted: code, databases, files, env vars and domains survive, and create_subscription restores and redeploys everything automatically (resume_service is the per-service fallback). Upgrading is always two calls: set_payment_method, then create_subscription — the card is not the upgrade. Call whoami to read all of this per org before you plan.

Identity, bootstrap & recovery

Tool Purpose Key params
pillar_directory Map of the five Tandem pillars (launch/work/speak/grow/profit) — per pillar: name, status (live/beta/coming_soon), base URL, MCP endpoint (null until live; plannedMcpUrl for future homes), and auth. The same tdm_ bearer token works on every pillar’s MCP server. See The Tandem suite. No action gate.
whoami Call this first. Your identity + username (for a human to add you to an org), your credential’s live action mask, and per-org entitlements: tier (preview = 14-day free trial, paid = subscribed), entitlement (trial/trial_expired/paid/comped), trialActive/trialExpiresAt, canDeploy + deployBlockers, trialAllowances (used vs limit for services/DBs/buckets), lockedUntilSubscribed, and nextStep. Plan against these instead of discovering limits by hitting errors.
create_account_and_claim_link (no auth) Create an org + human owner, email a claim link; anonymous calls also mint an agent token bound to this session. ownerEmail*, organizationName*, ownerDisplayName
create_own_organization (no auth) Create an org owned by YOU (the agent) with no human owner; mints an owner token. Then register + verify a recovery key before deploying. organizationName*
get_claim_status Poll an org’s claim status → { claimed, paid, customDomain }. organizationId*
get_deploy_gate_status Check whether an org can deploy → { billingVerified, recoveryVerified, recoveryMethod, trialActive, trialExpiresAt, blockers, allowed }. Blockers: recovery_unverified, preview_expired, billing_unverified — the last two are both cleared by set_payment_method then create_subscription (a card alone does not lift the gate). read + membership. organizationId*
register_recovery_key Register an Ed25519 public key (SPKI); returns a challenge to sign. manage. organizationId*, label*, publicKey*
verify_recovery_key Submit the Ed25519 signature over the challenge to activate the key. manage. keyId*, signature*
list_recovery_keys List an org’s recovery keys (no public-key material). read. organizationId*
revoke_recovery_key Revoke a verified recovery key. manage. keyId*

Projects

Tool Purpose Key params
list_projects List projects visible to the caller (scoped by token / memberships). Each row includes an accurate deployment_count.
create_project Create a project in an org; optionally link a connected repo. slug*, name*, environment, repositoryId, organizationId
rename_project Rename a project; changing slug rewrites every platform hostname + DNS + Caddy and returns hostnameChanges[]. manage + developer. projectId*, name, slug
delete_project Cascade-delete a project and every service, bucket, and database in it. Irrevocable. manage + admin. projectId*, confirmSlug*

Services

Tool Purpose Key params
list_services List services, optionally filtered by projectId. projectId
read_service_config Read a service’s type, paths, healthcheck, domains, and env-var keys (values not returned). serviceId*
import_services Bulk-create services in a project from service definitions (e.g. read_platform_yml output); auto-attaches platform hostnames. projectId*, services*
restart_service Restart the current healthy deployment’s container; Caddy re-points to the new port. restart. serviceId*
rollback_service Roll back to a previous healthy deployment (reuses the prior image, skips build). rollback. serviceId*, targetDeploymentId
resume_service Bring a suspended service back online (suspension = the org’s free trial ended and its containers were reclaimed; nothing is deleted). Subscribing resumes automatically, so this is the fallback for when that failed. Requires the org to pass the deploy gate. deploy + developer. serviceId*
delete_service Scoped cascade-delete of one service (deployments, env vars, domains, attachment rows). Preserves the buckets/DBs/redis/mailboxes/domains themselves; the analytics site is kept as external by default (analytics=keep|delete). manage + admin. serviceId*, confirmName, analytics

Deployments & logs

Tool Purpose Key params
create_deployment Queue a deployment for a service. deploy. serviceId*, gitRef, gitSha
deploy_preview Queue a preview deployment from a branch/ref (metadata.kind='preview'). deploy. serviceId*, gitRef*, gitSha
deploy_project Deploy every service in a project at one gitRef (the “Deploy all” fan-out). deploy. projectId*, gitRef
list_deployments List recent deployments (newest first) with state, git ref/sha, image ref, timestamps, errorMessage. serviceId*, limit
get_deployment Read one deployment incl. buildLog (build failures) and containerLog (runtime failures) — always check both. deploymentId*
view_logs Fetch recent container logs for the current healthy deployment. serviceId*, tail

GitHub & repositories

Auto-deploy on push is silent by design when it succeeds — but if the org fails the deploy gate (expired trial, unconfirmed billing, unverified recovery), the push is skipped, not queued. The platform emails the org owners once per day when that happens and writes a github.push.auto_deploy.blocked_notice audit row naming the blocker, the remedy and the skipped services. Pushes resume deploying automatically once the blocker clears; no re-push is needed.

Tool Purpose Key params
list_github_installations List GitHub App installations visible to the caller.
list_installation_repositories List repos granted to a specific installation (cached 5 min). installationId*
list_repositories List repos already connected to the caller’s org(s); hasInstallation flags platform.yml / auto-deploy support.
connect_repository Connect a repo from an installation into an org. manage + developer. installationId*, githubRepoNodeId*, organizationId
set_project_repository Set a project’s deploy source: a connected GitHub/URL repo (repositoryId, manage) OR a Tandem Git repo (tandemGitRepoId, source:write — works for a standalone repo too). + optional auto-deploy branch. developer. projectId*, one of repositoryId/tandemGitRepoId, deployBranch
read_platform_yml Fetch + parse platform.yml from a connected repo → services ready to import. repositoryId*, ref

Git repositories (Tandem Git)

Tandem’s own private git hosting: standard HTTPS clone/push (username git, password = an access token or your deployment token). Agent credentials gate on the dedicated source:read / source:write / source:admin actions (minted default-on with new tokens); per-repo access = org role (owner/admin → all, developer → read+write, viewer → read) plus explicit share grants. See Tandem Git.

Tool Purpose Key params
create_git_repo Create a private repo; init: "template" (default) seeds platform.yml + README + .gitignore so the first push can deploy, "empty" creates a bare repo. Pass asProjectSource: {newProject} or {projectId} to wire the new repo up as a project’s deploy source in the same call — zero GitHub required, and a push to the deploy branch auto-deploys exactly like a GitHub-linked project. source:write + developer. name*, organizationId, projectId, description, init, asProjectSource
list_git_repos List repos you can read (all your orgs + repos shared with you; narrow by org/project) with clone URL, default branch, archived flag, and your caps. source:read. organizationId, projectId
read_git_repository Read without cloning — what: tree (directory listing, recursive optional), file (base64 content + isBinary), commits (paged history via limit/cursor, optional path filter), branches. source:read. repo*, what*, ref, path, recursive, limit, cursor
commit_git_changes Apply up to 200 put/delete/move operations as ONE atomic commit; baseSha gives optimistic concurrency (stale → ref_conflict + currentSha), createBranchFrom creates the branch first. source:write + repo write access. repo*, branch*, message*, operations*, baseSha, createBranchFrom
share_git_repo Drive-style sharing: grant independent canRead/canWrite/canAdmin to a principal or email (unknown email → account + setup link), or revoke: true to remove. source:admin + repo admin access. repo*, principalId|email, canRead, canWrite, canAdmin, revoke
import_repository Migrate a repository INTO Tandem Git (one-time copy). source: {githubRepositoryId} copies an existing GitHub-connected repo (repointProject: true switches its project(s) onto the new Tandem repo); source: {url} clones any public https git URL (tandemRepoName required; optional project: {name} or {id}). Async — poll with get_source_status. Never copies refs/pull/*. source:write + developer + unscoped agent credential. source*, tandemRepoName, repointProject, project, organizationId
export_repository_to_github Migrate a Tandem repo OUT to GitHub (one-time copy). githubRepoNodeId must name an EMPTY repo you created yourself (App tokens can’t create repos or overwrite history — verified by the worker before pushing). then: "repoint" switches the project(s) to the GitHub repo afterward. Async — poll with get_source_status. source:write + developer + unscoped agent credential. repo*, installationId*, githubRepoNodeId*, then
get_source_status Poll a migrate job (jobId) or a repo’s most recent one plus its mirror link state (repo) — state/progress/error, and if mirrored: mode, status, lag, last error. source:read. repo|jobId
configure_git_mirror Continuous “Mirror to GitHub” (single-primary, never multi-master — not the one-time import/export above). action: enable (requires mode + github: {githubRepositoryId} or {installationId, githubRepoNodeId}) starts it; pause/resume toggle; switch_primary runs a final sync then flips authority (diverged commits backed up, never lost); disable stops mirroring (both repos stay intact). source:admin + org admin + unscoped agent credential. repo*, action*, mode, github

Environment variables

Tool Purpose Key params
list_env_vars List a service’s env-var keys, scopes, and masked previews (never full values). serviceId*
set_env_var Set/overwrite one env var (encrypted at rest). scope = runtime (default) / build / both. serviceId*, key*, value*, scope
set_env_vars Bulk-set env vars in one atomic call — paste a whole .env as content, or pass vars. Prefer this over repeated set_env_var. replaceAll also deletes keys not in the call (file-sync). serviceId*, content, vars, scope, replaceAll
delete_env_var Delete an env var by key (applies on next deploy/restart). serviceId*, key*

Databases (Postgres / MySQL)

Tool Purpose Key params
list_databases Discover databases (the entry point — every other DB tool needs a databaseId). Non-secret metadata + service attachments; org-wide rows add projectSlug/organizationSlug. Omit projectId to list across all visible orgs. projectId
get_database Fetch one DB’s non-secret metadata by UUID. databaseId*
provision_database Provision a tenant DB + user; auto-creates DATABASE_URL on the service. kind picks the engine. projectId*, kind, label, attachServiceId
reveal_database_credentials Full internal credential bundle (host/port/db/user/password/URL). Audit-logged. databaseId*
reveal_database_public_credentials Credentials with the public host for external access (only connects from an allowlisted IP). Audit-logged. databaseId*
query_database Run SQL against the DB as the tenant role (full read/write; the portal SQL runner’s equivalent). Multiple statements allowed — last result set returned. Audit-logged. manage + developer. databaseId*, sql*, maxRows
export_database Enqueue a full dump of the DB (schema + data) to a .sql file — the portal’s Export button equivalent. Returns the job (state queued); the worker runs pg_dump/mysqldump. Audit-logged. manage + developer. databaseId*
list_database_allowlist List the DB’s public-access IP allowlist (CIDRs). databaseId*
add_database_allowlist Grant a CIDR public access (firewall + engine-level grant); optional ttlHours. databaseId*, cidr*, label, ttlHours
remove_database_allowlist Revoke an allowlist entry by id. databaseId*, entryId*
delete_database Drop the DB + role, remove DATABASE_URL from attached services. Irreversible. manage + developer. databaseId*, confirmName

Object storage (S3-compatible buckets)

Tool Purpose Key params
create_bucket Create a bucket + scoped creds; optionally inject the six S3_* env vars on a service. projectId*, label, attachServiceId
list_buckets List buckets in a project and which services each is attached to. projectId*
attach_bucket_to_service Inject the six S3_* env vars on a service (idempotent). bucketId*, serviceId*
detach_bucket_from_service Remove the S3_* env vars; bucket + objects kept. bucketId*, serviceId*
reveal_bucket_credentials Full bucket credential bundle (endpoint/region/keys). Audit-logged. bucketId*
delete_bucket Delete a bucket (must be empty first); revokes creds, removes S3_* vars. No undo. bucketId*
set_bucket_cors Replace the bucket’s CORS policy (browser-only; not access control). A "*" origin is rejected unless allowAnyOrigin: true. Audit-logged. bucketId*, rules*, allowAnyOrigin
get_bucket_cors Read the bucket’s CORS rules (no endpoint/creds). bucketId*

Redis / Valkey

Tool Purpose Key params
provision_redis Provision a managed Valkey instance (async — poll list_redis for ready). tier = small/default/large. Subject to deploy gate + RAM budget. projectId*, label, tier, attachServiceId
list_redis List instances with status/tier/persistence and attached services (poll for ready). projectId*
reveal_redis_credentials Host/port/password + full REDIS_URL (only when ready). Audit-logged. redisId*
attach_redis_to_service Inject REDIS_URL on a service (idempotent; must be ready). redisId*, serviceId*
detach_redis_from_service Remove REDIS_URL; instance + data kept. redisId*, serviceId*
delete_redis Tear down the instance + data volume (async). No undo. redisId*

Email

Email is custom-domain-only — onboard a domain before creating mailboxes or sending. See Email for the full flow.

Tool Purpose Key params
add_email_domain Onboard a custom domain for send+receive; returns DNS records (MX, DKIM, SPF, DMARC). projectId*, domain*
list_email_domains List onboarded email domains + SES/DKIM/inbound status. projectId*
verify_email_domain Re-check a domain’s verification against SES + DNS. domainId*
remove_email_domain Remove an onboarded domain (refuses if mailboxes remain). domainId*
set_dmarc_reporting Configure DMARC aggregate-reporting ownership (no lock-in): managed (Tandem collector), external (your own rua), or both. Provisions/removes the external-destination auth record. mode*, domainId|domain+projectId, externalRua
get_dmarc_summary Email Health for one domain: DMARC pass-rate, failing sources, reporter coverage, and advisory (safeToQuarantine / safeToReject). Use before tightening policy. domainId|domain+projectId, sinceDays
set_dmarc_policy Set the published DMARC policy p= nonequarantinereject (and back) — managed + reversible. Tightening gated on get_dmarc_summary advisory unless force=true. Managed/both only (external hosts its own _dmarc). Reporting rua preserved. policy*, domainId|domain+projectId, force
create_email_api_key Create a transactional send-API key (Bearer for POST /api/email/send); returned once. Optional allowedDomains. projectId*, name*, allowedDomains
list_email_api_keys List send-API keys (never the secret). projectId*
revoke_email_api_key Revoke a send-API key by id. projectId*, keyId*
provision_email Provision a real mailbox (IMAP+SMTP+JMAP) on an onboarded domain; optionally inject EMAIL_* on a service. projectId*, domain*, localPart, label, attachServiceId
list_emails List mailboxes in a project (address, DNS status, attachments). No passwords. projectId*
attach_email_to_service Inject EMAIL_* (IMAP+SMTP+JMAP) on a service (idempotent). mailboxId*, serviceId*
detach_email_from_service Remove EMAIL_*; mailbox + mail kept. mailboxId*, serviceId*
reveal_email_credentials Full connection profile (IMAP/SMTP host/port/user/password + JMAP url/token). Audit-logged. mailboxId*
rotate_email_credentials Rotate the mailbox password (set or auto-generate); re-injects into attached services. mailboxId*, password
delete_email Delete a mailbox (all stored mail lost); tears down domain DNS if it was the last one. No undo. mailboxId*
set_email_inbound_webhook Forward inbound mail as HMAC-signed JSON POSTs to a URL; returns a signing secret once. mailboxId*, url*
get_email_inbound_webhook Show the mailbox’s webhook config (secret never returned). mailboxId*
remove_email_inbound_webhook Stop forwarding; mail still arrives in the mailbox. mailboxId*
share_mailbox Grant a principal capabilities on a mailbox: view/categorize/manage/send (independent — send-only and categorize-only are valid). Unknown email → creates a mail-only account (no org) + emails a setup link; they set a password and land in the shared mailbox (invited:true in the response). Re-share replaces caps. mailboxId*, principalId|email, canView*, canCategorize*, canManage*, canSend*
revoke_mailbox_grant Revoke a subject’s grant (disappears from their webmail on next sync); history kept. mailboxId*, principalId|email
list_mailbox_grants Who has access to a mailbox + each subject’s caps, incl. pending invites. mailboxId*

Domains

Tool Purpose Key params
list_domains List everything domain-related for the org in one call: registrations (Tandem-registered apexes — carries the domainOrderId that renew_domain/set_domain_auto_renew take, plus status, expiresAt, autoRenew, attachedServices; in-flight purchases/transfers included so you can poll an approval or transfer), externalZones (DNS hosted here but bought elsewhere), attachedHostnames (hostname → service, kind platform|custom, verified, redirect). Read-only. read + any role. organizationId, includeInFlight
check_domain_availability Check availability + registrar price for hostnames or a stem across default TLDs. Read-only. hostnames, stem
purchase_domain Register a domain + attach it to a service. Paid plans credit the first year (Pro 1, Scale 3, capped at $15); returns costCents (charged), creditAppliedCents, renewalPriceCents (undiscounted — always disclose it). Owner runs synchronously; others get an approvalUrl. manage; deploy gate + a chargeable card (not covered by the free trial). organizationId*, hostname*, serviceId
attach_domain Attach an already-owned or external hostname to a service (auto A record for subdomains of a Tandem-registered apex; else DNS instructions + automatic recheck until it resolves). manage + developer. serviceId*, hostname*
verify_domain Force an immediate DNS recheck for an attached custom hostname (the sweep also rechecks automatically); activates the domain when DNS resolves. manage + developer. hostname*
reassign_domain Move an attached hostname to another service in the same org in one step (keeps DNS verification; routes refresh automatically). manage + developer. hostname*, serviceId*
detach_domain Detach a hostname from its service (unpublishes the platform A record, discards verification state; a Tandem registration itself is untouched). Prefer reassign_domain for moves. manage + developer. hostname*
renew_domain Renew a Tandem-registered domain one year (payment + approval path). manage + developer; deploy gate + a chargeable card (not covered by the free trial). organizationId*, domainOrderId, hostname, years
set_domain_auto_renew Toggle auto-renew (no charge, no deploy gate). manage + developer. organizationId*, autoRenew*, domainOrderId, hostname
transfer_domain Transfer a domain in from another registrar (charges one year; needs EPP authCode). manage + developer; deploy gate + a chargeable card (not covered by the free trial). organizationId*, hostname*, authCode*, projectId, serviceId

SMS & phone numbers (US/CA)

Numbers, A2P compliance, and messaging over Telnyx. Call get_sms_setup_status first for any number — it is the one status tool that says exactly what is pending and which tool resumes it, and whether production sends are allowed yet (canSend). Same org-role gates and Wave-1 stores as the /api/sms/* REST surface. When Telnyx is unconfigured every tool returns sms_unavailable.

Recommended flow: search_phone_numberspurchase_phone_number → a compliance path (toll-free = fastest/free; or 10DLC = higher throughput) → send_sms. Sends are blocked until compliance is approved (the error carries the setupStatus).

Tool Purpose Key params
search_phone_numbers Search buyable US/CA inventory. read + developer. type* (local|toll_free), countryCode, areaCode, locality, administrativeArea, contains, organizationId
purchase_phone_number Buy a number (lazily creates the org messaging profile). Owner-under-threshold buys synchronously; others get an approvalUrl. manage + developer; deploy gate. e164*, numberType*, label, organizationId
list_phone_numbers List the org’s numbers, each with unified setupStatus + attachments. read + viewer. organizationId
release_phone_number Detach from all services + give up at the carrier (irreversible). manage + developer. numberId*, confirm* (the number’s E.164)
register_sms_brand Register the org’s 10DLC brand (one per org). Standard = EIN + companyName; SOLE_PROPRIETOR = name + mobilePhone, returns otpRequired. manage + developer; deploy gate. entityType*, displayName*, companyName, ein, firstName, lastName, mobilePhone, address fields, organizationId
confirm_sms_brand_otp Submit the sole-prop mobile OTP PIN (expires 24 h). Degrades to action_required if Telnyx can’t automate it. manage + developer. brandId*, pin*, organizationId
create_sms_campaign Submit a 10DLC campaign under an approved brand. Validated locally first (returns errors on failure — no charge); $15/submission so approval-gated (approvalUrl over threshold). manage + developer; deploy gate. brandId*, usecase*, description*, sampleMessages*, messageFlow*, keywords, organizationId
assign_number_to_campaign Link a number to a campaign (enforces the 49/campaign T-Mobile cap). manage + developer. campaignId*, numberId*
submit_tollfree_verification Submit the toll-free verification (fastest/free path). Validated locally (full state name, additionalInformation, ≥1 opt-in evidence URL, EIN). manage + developer. business/contact fields, phoneNumbers*, useCase*, optInWorkflowImageUrls*, messageVolume*, additionalInformation*, organizationId
get_sms_setup_status THE status tool — unified state + reason + concrete remediation + the exact next tool + canSend. Call first. read + viewer. numberId*
send_sms Send SMS/MMS from an owned number. Compliance-gated (allowPending for a pending toll-free number); enforces rate limit + the acting principal’s spend cap. Returns segments + estimated cost. manage + developer. numberId|from, to*, text, mediaUrls, allowPending, organizationId
list_sms_messages List messages (bodies decrypted for the owner), newest first. read + viewer. numberId, direction, status, limit, organizationId
attach_phone_number_to_service Inject the SMS_* runtime env vars (URL/key/number/webhook-secret) on a service. Idempotent. manage + developer. numberId*, serviceId*
detach_phone_number_from_service Remove the injected SMS_* env vars. manage + developer. numberId*, serviceId*
set_sms_inbound_webhook Point inbound messages + delivery events at your HTTPS URL (HMAC X-Tandem-Signature); returns the signing secret once. manage + developer. numberId*, url*
remove_sms_inbound_webhook Stop forwarding inbound (messages still stored). manage + developer. numberId*

DNS records

Tool Purpose Key params
list_dns_records List records in the zone owning a hostname (+ zone metadata). Read-only. read. hostname*
create_dns_record Create a record (A/AAAA/CNAME/ALIAS/NS/TXT/MX/SRV/CAA). manage + developer. hostname*, name*, type*, content*, priority, weight, port, flags, tag, ttl
update_dns_record Replace a record by id (full desired fields, not a patch). manage + developer. hostname*, recordId*, name*, type*, content*
delete_dns_record Delete a record by id (platform-managed records protected). manage + developer. hostname*, recordId*
take_over_dns_record Claim a Tandem-managed web-serving record (apex/www, service routing) so your org edits it from then on — for hosting the site elsewhere while Tandem stays the nameserver. manage + developer. hostname*, recordId*
import_dns_zone Bulk-import a BIND zone file (e.g. cPanel whmapi1 dumpzone) into an already-adopted zone. Skips SOA/NS; platform-RRset collisions reported (not created) for take-over then re-import; dryRun returns the diff without writing. manage + developer. hostname*, zoneFile*, dryRun

Web analytics

Tool Purpose Key params
provision_analytics Enable Tandem Analytics on a service; injects the two TANDEM_ANALYTICS_* vars; returns the install <script>. serviceId*
provision_external_analytics Enable analytics for a site hosted anywhere (no service, no env vars — the returned <script> is the whole integration). Idempotent per (project, domain). projectId*, domain*
convert_analytics_to_external Rebind a service’s site as standalone external — same website id, full history preserved. Use when an app moves off Tandem. serviceId*, domain
set_analytics_custom_host First-party upgrade: serve the tag from the site’s own domain (default analytics.<domain>); auto-publishes DNS when the zone is hosted here, else returns the record to add. serviceId/siteId, host
verify_analytics_custom_host Check the custom host resolves to the platform and activate it (route + cert publish; snippet switches over). serviceId/siteId
remove_analytics_custom_host Drop the custom host; the assigned host keeps serving so installed tags keep working. serviceId/siteId
get_analytics_install_snippet Return the install <script> for a site. serviceId or siteId
list_analytics List a project’s analytics sites, service-bound and external (kind, externalDomain, site id). projectId*
disable_analytics Disable a site (removes vars + website + data). serviceId or siteId
get_analytics_summary Headline metrics over a window (pageviews/visitors/visits/bounces vs previous window). serviceId/siteId, range, startTime, endTime, filters
get_analytics_breakdown Top values for one axis (type = referrer/country/url/device/event/…). serviceId/siteId, type*, limit
get_analytics_timeseries Pageviews + sessions over time bucketed by unit (hour/day/month). serviceId/siteId, unit, timezone, range
get_analytics_realtime Visitors active right now (~last 5 min). serviceId/siteId
get_analytics_markers Timeline of deploys + domain/DNS changes from the audit log (pair with timeseries). serviceId/siteId, range

delete_service also accepts analytics: keep|deletekeep (default) converts the service’s site to external so the history survives the deletion.

Members

Tool Purpose Key params
list_members List an org’s members (humans + agents) with role/email/setup status. read. organizationId*
invite_member Invite a human by email with a role (owner-invite of an existing account is a pending invitation). manage + admin. organizationId*, email*, role*, displayName
set_member_role Change a member’s role (by userId or principalId; can’t demote the only owner). manage + admin. organizationId*, role*, userId, principalId
remove_member Remove a member (can’t remove the only owner). manage + admin. organizationId*, userId, principalId

Limits & policies

Tool Purpose Key params
get_limits Read a principal’s action mask, spend cap, and approval threshold. Omit principalId for your own live mask; omit organizationId for the global row. organizationId, principalId
set_limits Set a principal’s limits (actionMask can only narrow). Org-scoped needs owner; global needs platform admin. manage. principalId*, organizationId, actionMask, spendCapCents, spendPeriod, approvalThresholdCents

Billing

Tool Purpose Key params
get_billing_status Read funding provider, tier (preview = the free trial, which does deploy; paid = subscribed), previewExpiresAt, billing/deploy-gate flags, customer + default payment method, subscription, blockers. hasPaymentMethod and tier are independent — a card does not move an org off preview. read + viewer. organizationId*
get_subscription Read the latest subscription (plan/status/period/cancelAtPeriodEnd). { subscription: null } just means the org is on (or has lapsed from) the free trial. read + viewer. organizationId*
list_invoices List invoices newest-first, live from the provider (hosted + PDF links). read + viewer. organizationId*, limit
get_usage Summarize tier + previewExpiresAt/previewServiceLimit + billable resource counts (services/DBs/buckets/domains) + application egress over the last 30 days (egress30d: bytes, gb, metered). metered: false means egress was not measured for the org, not that it was zero. Also returns 30-day daily averages for the two gauge metrics: services30d (avgDaily, metered) — the average billable services held per day, distinct from the live resources.services count — and dbStorage30d (avgDailyBytes, avgDailyGb, metered) for tenant-database storage. Each gauge’s metered: false means no sample was recorded (poller off, or every database unreachable); the average is meaningless then and must not be read as zero usage. On a trial, compare the live counts against the 1 service / 1 database / 1 bucket allowance. Also returns currentPeriod: the projected overage for THIS calendar month from the shared usage aggregator (the same computation the invoice and the allotment warnings use), with per-metric used/included/overageQuantity/unitPriceCents/overageCents in each metric’s billable unit (GB-month, “1,000 emails”, service-month, GB), the flat SMS addOns (no allotment; charge from published rates), and projectedOverageCents (unitPriceCents: null means the plan doesn’t meter that metric). And overagePeriods — overage close-out history newest-window-first (periodStart, periodEnd, mode shadow|live, status, totalOverageCents, providerInvoiceId); mode: "shadow" rows are “what you WOULD be billed” before real charging is enabled, and the list is empty until the overage engine is turned on. Display only — nothing here charges or blocks. Mirrors the portal Billing → Usage + “Projected overage this period” cards. read + viewer. organizationId*
set_payment_method Begin attaching a payment method (hosted setupUrl + SetupIntent; no charge). Step 1 of 2 — a card alone leaves the org on the trial; follow with create_subscription. manage + owner. organizationId*
list_plans List subscribable plans (allotments, metered overages) with BOTH cadences priced: monthlyPriceCents, annualPriceCents, per-interval intervals.{month,year}.{offered,priceCents,priceAvailable}, and annualSavings (cents / percent / months free). read + admin. organizationId*
create_subscription Upgrade the org to a paid plan (idempotent). The only call that ends the trial: lifts preview_expired, drops the trial resource caps, un-suspends + redeploys reclaimed services, and unlocks custom domains, outbound email and managed Redis. Needs a card on file (else card_requiredset_payment_method). planCode defaults to pro when available. interval is month (default) or year for annual billing — check list_plans first, an unavailable cadence returns plan_price_not_configured. Does NOT switch an existing subscription between cadences. manage + owner. organizationId*, planCode, interval
change_plan Move an org’s active subscription to a different plan in place (e.g. starterpro, proscale) — a plan change, not cancel+resubscribe. Swaps the subscription’s price and prorates the mid-cycle switch (credit for unused time on the old plan, prorated charge for the new). Requires an active subscription (no_active_subscription otherwise — use create_subscription first). Errors: plan_unknown, same_plan, plan_price_not_configured (check list_plans). interval month (default) or year. manage + owner. organizationId*, planCode*, interval
defer_org_billing Platform admin only. Defer an org’s billing until a date — charge them, but not before then (typically a client who prepaid a previous host through that date). Applies immediately to an existing subscription and is also recorded for a not-yet-subscribed org to pick up at subscribe time; enforced provider-side as a trial, so billing resumes automatically. Distinct from the billingEnabled comp switch (comp = never charge, deferral = start later; an org may carry both) and from the free trial (which precedes any subscription). Domain fees still charge, and deferral does not credit already-paid time. deferUntil: null clears it. manage + platform admin. organizationId*, deferUntil*, reason

Annual billing. Interval is a dimension of a plan’s price, not a separate plan: annual Pro and monthly Pro grant identical entitlements (services, allotments, domain credits) and differ only in price and cadence. Annual is priced at 10x the monthly rate (“2 months free”). Included allotments are always per calendar month — an annual Pro org gets 10 GB storage per month, not 120 GB for the year; list_plans states this as allotmentPeriod: "month". The portal Billing page offers the same monthly/yearly choice to humans.

Support tickets

Support is staffed by humans and AI agents; set handlerPreference (human / agent / any) to say who you want. There is no push channel on MCP — poll list_support_tickets and check unread. Requesters are also notified by email (agent-opened tickets email the org owners) and, if configured, an org webhook.

Tool Purpose Key params
open_support_ticket Open a ticket with the platform team (platform-side problems, questions, escalations). manage + developer. subject*, body*, organizationId, priority, handlerPreference, projectId, serviceId
list_support_tickets List the org’s tickets, newest activity first; unread=true means support replied since last read — poll this. read + viewer. organizationId, status, includeClosed
get_support_ticket Read a ticket’s full thread; reading marks it read for your org. read + viewer. ticketId*
reply_support_ticket Reply and/or close (close:true); replying to a waiting/resolved ticket reopens it. manage + developer. ticketId*, body, close
get_support_webhook Show the org’s ticket-update webhook config (secret never returned). read + admin. organizationId
set_support_webhook Register an HTTPS endpoint for HMAC-signed support.ticket.updated POSTs (verify X-Tandem-Signature); secret returned once; url:null removes. manage + admin. url*, organizationId
admin_list_support_tickets PLATFORM ADMIN: the cross-org support queue; filter by status/handlerPreference/unreadOnly. status, handlerPreference, organizationId, unreadOnly, includeClosed
admin_get_support_ticket PLATFORM ADMIN: full thread including internal notes; marks platform-side read. ticketId*
admin_reply_support_ticket PLATFORM ADMIN: reply to the requester (notifies them), or internal:true for a platform-only note. ticketId*, body*, internal
admin_update_support_ticket PLATFORM ADMIN: triage — set status (resolved notifies requester), assign to a platform-admin principal, set priority. ticketId*, status, assigneePrincipalId, assigneeDisplay, priority