AI agents and MCP
Connect Claude Code, Cursor, Codex or a chat client to Camplax over MCP — eight tools, two sign-in paths, one bill.
Camplax is built for agents, not just people. An agent that can create a project in one call does not need a Vercel account and a Supabase account — it needs one endpoint: the Camplax MCP server.
https://camplax.dev/mcp (also mounted at /v1/mcp)
It speaks stateless streamable HTTP — one JSON-RPC 2.0 message per POST — and accepts MCP protocol 2025-06-18 or 2025-03-26. Run camplax mcp to print the setup for your client, or wire most clients in one line:
npx add-mcp https://camplax.dev/mcp
add-mcp writes the config entry for Claude Code, Cursor, Codex, VS Code and the rest. Clients that know OAuth will sign you in through the browser; for token auth add --header "Authorization: Bearer $CAMPLAX_TOKEN".
Two ways to authenticate
Which path you use depends on who is driving:
| Path | Credential | For |
|---|---|---|
| Bearer token | cx_cli_… from camplax login, or a cx_live_… project key | coding agents, CI, anything non-interactive |
| OAuth 2.1 + PKCE | cxm_… access token minted by a browser consent flow | chat clients — Claude Desktop, ChatGPT, remote connectors |
Bearer — coding agents
camplax login opens a browser once and writes a cx_cli_… token into the CLI config; in CI set CAMPLAX_TOKEN directly. No browser or CLI on the machine? Mint the same token in the console — Account → Access tokens → New token — which calls POST /v1/cli/tokens under a console session; the secret is shown once. Then point the agent at the endpoint with the token as a header:
# Claude Code
claude mcp add --transport http camplax https://camplax.dev/mcp \
--header "Authorization: Bearer $CAMPLAX_TOKEN"
// Cursor — .cursor/mcp.json
{
"mcpServers": {
"camplax": {
"url": "https://camplax.dev/mcp",
"headers": { "Authorization": "Bearer ${env:CAMPLAX_TOKEN}" }
}
}
}
A project API key also works as the bearer, scoped to one project: it can deploy and read that project — deploy needs the deploy scope — but it cannot create_project, import_project or probe_project. Those need a user credential.
Codex auto-discovers .agents/skills/camplax/SKILL.md; the same skill is published by the MCP endpoint as a resource.
OAuth — chat clients
Chat clients sign in with your Camplax account instead of a pasted token. Add https://camplax.dev/mcp as a connector; the client discovers the OAuth server, opens a browser, you approve access, and it holds an cxm_… token. Same endpoint, same tools.
Discovery documents live at:
https://camplax.dev/.well-known/oauth-authorization-server
https://camplax.dev/.well-known/oauth-authorization-server/mcp
https://camplax.dev/.well-known/oauth-protected-resource
https://camplax.dev/.well-known/oauth-protected-resource/mcp
https://camplax.dev/.well-known/mcp.json
The flow, if your client does not automate it:
- Register (RFC 7591):
POST /oauth/registerwithredirect_uris, optionalclient_name,grant_types,scope. Onlyauthorization_code/refresh_token, response typecode, auth methodnone, scopemcpare accepted;redirect_urismust behttps://or a loopbackhttp://localhost. Response201carriesclient_id— there is no client secret. Registration is also optional in the other direction: aclient_idmay simply be anhttps://URL hosting a Client ID Metadata Document — the server fetches it (one bounded request, cached briefly), requires the document'sclient_idto equal the URL, and treats itsredirect_urisas the allowlist. Discovery advertisesclient_id_metadata_document_supported; a pre-registered client always wins over a URL-shaped one. - Authorize:
GET /oauth/authorize?client_id=…&redirect_uri=…&response_type=code&code_challenge=…&code_challenge_method=S256&scope=mcp— S256 is the only PKCE method. Signed-out users are bounced through console sign-in first; then a consent page names the client and the redirect origin. Approving redirects back with acode. - Token:
POST /oauth/token(JSON or form) withgrant_type=authorization_code,code,client_id,code_verifier,redirect_uri. Response:access_token(cxm_…),refresh_token(cxr_…),token_type: "Bearer",expires_in,scope.
The lifetimes and rules that matter:
| Item | Value |
|---|---|
| Authorization code TTL | 10 minutes, single use |
| Access token TTL | 1 hour |
| Refresh token TTL | 30 days |
| Refresh rotation | every use mints a new pair; replaying an old refresh token revokes the grant |
| Scope | mcp only — one scope, the whole surface |
Token responses are Cache-Control: no-store. The unauthenticated /mcp request returns 401 with a WWW-Authenticate pointer to the protected-resource document, which is how clients find all of this on their own.
Scope the connection to one project
Two query params turn the shared endpoint into a per-project connector — the same pattern Supabase uses for its scoped MCP:
https://camplax.dev/mcp?project=my-app
https://camplax.dev/mcp?project=my-app&read_only=1
project=<slug>binds the connection.list_projectsreturns only that project, every tool that takesslugdefaults to it, and any other slug is rejected with aproject_scopeerror. The slug must resolve to a project the credential can already see — anything else is a flat404, so the parameter cannot probe for project names.read_onlymakes the connection a viewer — presence turns it on; only an explicitread_only=0(orfalse/no/off) turns it back off. Every tool not annotated read-only —create_project,import_project,deploy,probe_project— fails with aread_onlyerror. The tools are not merely hidden; the calls fail closed.
Use it when an agent only ever works on one app, or when a third-party agent should see but never touch: a bound, read-only connector cannot reach your other projects and cannot change this one.
The tools
Eight verbs cover context, shipping, migration and live verification. The catalog stays small on purpose — agents burn tokens on a 40-tool catalog and then call the wrong one.
| Tool | Arguments | What it does |
|---|---|---|
whoami | — | Which identity is connected: session, CLI token, OAuth token or API key, and its scopes |
list_projects | — | The projects this identity can see |
project_context | slug | Repo, build config, release evidence, permissions, secret names — never values |
create_project | name, slug, optional templateId | Provision a new app; starts in provisioning |
import_project | name, slug, optional siteUrl, sourceDatabaseUrl, githubRepo | Migrate a Vercel + Supabase app; the old site stays up |
deploy | slug, optional branch, sourceKey | Queue a production deploy; sourceKey (from PUT /v1/projects/:slug/source) ships an uploaded folder instead of a repo. Poll project_status |
project_status | slug | Provisioning, migration or deploy progress |
probe_project | slug, optional only | Bounded live checks per feature — pass, fail or skip |
A ready deploy is production evidence only when project_context.release.live is true — queued, building and deploying mean work in progress, not deployed.
No repo connected? project_context.nextAction will say so. Two ways to ship anyway: the owner connects GitHub once, or the agent deploys the local folder directly — run camplax deploy --local from the project directory (it packs, uploads and queues in one step), or do it by hand: PUT /v1/projects/:slug/source with a gzipped tar body, then deploy with the returned sourceKey.
Rate limits
Two buckets gate the endpoint, both 120 requests per minute: one per client IP (before auth, so forged bearers are cheap to refuse) and one per identity after it. OAuth endpoints have their own — 20 client registrations per IP per hour, 60 token calls per IP per minute. A 429 carries Retry-After.
What agents cannot do
Deliberately absent from the MCP: billing, creating API keys, deleting projects, and reading secret values. project_context returns secret names and presence only. There is no workaround, and that is the point — an agent can ship and verify an app without ever holding a secret or spending money.
Reading the docs
/llms.txt— the short agent briefing./llms-full.txt— every docs page in one file.- Every docs page has a markdown mirror:
/docs/getting-started.mdfor/docs/getting-started.html, and so on.
When MCP is unavailable, the same verbs exist on the CLI with --json — camplax deploy --json, camplax import --name <slug> --site <url> --db <postgres-url> --json, camplax probe --json. Never scrape the console HTML.