{"openapi":"3.1.0","info":{"title":"Automo Build API","version":"1.3.0","description":"The machine surface of Automo Build, the AI app builder. All capability calls go through the MCP endpoint (Model Context Protocol, Streamable HTTP): tools are discovered live via tools/list after OAuth sign-in. This document describes that endpoint, the OAuth 2.1 authorization server that protects it, and the discovery documents around them. Start at the server card or the protected-resource metadata; the site overview for agents is https://automo.build/llms.txt; agent registration is walked through at https://automo.build/auth.md.\n\nRate limits: the unauthenticated endpoints answer with RateLimit-Policy, RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds), counted per client IP. MCP tool calls carry the same headers for the connection's read, write or spawn budget. Past the limit the answer is 429 with Retry-After.\n\nIdempotency: POST /agent/identity accepts an Idempotency-Key header (16 to 255 printable characters, a UUID is ideal). A retry with the same key and body answers about the same registration instead of opening a second one; the same key with a different body is refused with 422.\n\nVersioning and deprecation: the MCP endpoint is versioned by the MCP-Protocol-Version header, whose values are MCP revision dates; every revision listed for it is served from the same URL. info.version follows semantic versioning: additions bump the minor version, breaking changes the major. Before a protocol revision or an operation is removed it is marked deprecated in this document and its responses carry Deprecation (RFC 9745) and Sunset (RFC 8594) headers for at least 90 days.","contact":{"name":"Automo Build","url":"https://automo.build/contact","email":"support@automo.ai"}},"servers":[{"url":"https://mcp.automo.build"}],"security":[{"oauth2":["workspaces:read","projects:read","projects:write","prompts:write","sessions:read","sessions:write","reviews:read","reviews:write","playbooks:read","playbooks:run","playbooks:write","deployments:read","deployments:write","chat:read","billing:write"]}],"components":{"securitySchemes":{"oauth2":{"type":"oauth2","description":"Automo Build OAuth 2.1: authorization code with PKCE (S256). Clients register by Client ID Metadata Document (the client_id is an HTTPS URL); there is no dynamic client registration. Tokens are JWTs bound to the resource URL, one hour, with rotating refresh tokens.","flows":{"authorizationCode":{"authorizationUrl":"https://mcp.automo.build/oauth/authorize","tokenUrl":"https://mcp.automo.build/oauth/token","refreshUrl":"https://mcp.automo.build/oauth/token","scopes":{"workspaces:read":"List workspace memberships, whoami, switch the current workspace","projects:read":"List and search projects, project status, env var names, screenshots, deployment history","projects:write":"Create projects, wake sandboxes, share and clone links","prompts:write":"Prompt a project's main agent","sessions:read":"Read any agent session the user can read in the app","sessions:write":"Open, continue and stop agent sessions (CTO, Doctor, Security, QA, Architect, builder spawns)","reviews:read":"The sign-off state of builder work: cards, verdicts, fixes, whose move it is","reviews:write":"Promote, ask a reviewer, hand fixes to the builder, approve or cancel a review","playbooks:read":"List playbooks and read their runs","playbooks:run":"Run a playbook","playbooks:write":"Create and edit playbooks","deployments:read":"Pending publish, deployment status and history","deployments:write":"Propose and approve deployments, publish","chat:read":"Read project chat history","billing:write":"Put a workspace on the Free plan"}}}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and body answer about the same registration. 16 to 255 printable characters.","schema":{"type":"string","minLength":16,"maxLength":255}},"McpProtocolVersion":{"name":"MCP-Protocol-Version","in":"header","required":false,"description":"The MCP revision the client speaks, negotiated at initialize and sent on every later request.","schema":{"type":"string","enum":["2026-07-28","2025-11-25"]}}},"headers":{"RateLimitPolicy":{"description":"The limit and its window, as \"<limit>;w=<seconds>\"","schema":{"type":"string"}},"RateLimitLimit":{"description":"Requests allowed in the current window","schema":{"type":"integer"}},"RateLimitRemaining":{"description":"Requests left in the current window","schema":{"type":"integer"}},"RateLimitReset":{"description":"Seconds until the window frees a request","schema":{"type":"integer"}},"RetryAfter":{"description":"Seconds to wait before retrying","schema":{"type":"integer"}}},"responses":{"TooManyRequests":{"description":"Rate limited; wait Retry-After seconds","headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}},"schemas":{"AgentRegistration":{"type":"object","description":"A registration. identity_assertion answers with an identity_assertion to exchange at the token endpoint (jwt-bearer grant); service_auth and anonymous answer with claim materials, and the agent polls the token endpoint with the claim grant until the user confirms the code.","properties":{"registration_id":{"type":"string","format":"uuid"},"registration_type":{"type":"string","enum":["identity_assertion","service_auth","anonymous"]},"identity_assertion":{"type":"string","description":"Exchange with grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer"},"assertion_expires":{"type":"string","format":"date-time"},"scopes":{"type":"array","items":{"type":"string"}},"pre_claim_scopes":{"type":"array","items":{"type":"string"},"description":"Always empty: nothing is spendable before the claim"},"claim_url":{"type":"string","format":"uri","description":"Where to restart the claim ceremony"},"claim_token":{"type":"string","description":"Polls the token endpoint with the claim grant; shown once"},"claim_token_expires":{"type":"string","format":"date-time"},"post_claim_scopes":{"type":"array","items":{"type":"string"}},"claim":{"$ref":"#/components/schemas/ClaimCode"}},"required":["registration_id","registration_type"]},"ClaimCode":{"type":"object","description":"The code the user confirms at verification_uri; poll no faster than interval seconds","properties":{"user_code":{"type":"string","pattern":"^[0-9]{6}$"},"expires_in":{"type":"integer"},"verification_uri":{"type":"string","format":"uri"},"interval":{"type":"integer"}},"required":["user_code","expires_in","verification_uri","interval"]},"InteractionRequired":{"type":"object","description":"The provider identity needs its account holder to confirm; carries claim materials","properties":{"error":{"type":"string","const":"interaction_required"},"error_description":{"type":"string"},"registration_id":{"type":"string","format":"uuid"},"registration_type":{"type":"string","const":"identity_assertion"},"claim_url":{"type":"string","format":"uri","description":"Where to restart the claim ceremony"},"claim_token":{"type":"string","description":"Polls the token endpoint with the claim grant; shown once"},"claim_token_expires":{"type":"string","format":"date-time"},"post_claim_scopes":{"type":"array","items":{"type":"string"}},"claim":{"$ref":"#/components/schemas/ClaimCode"}},"required":["error","registration_id","claim_token"]},"OAuthError":{"type":"object","description":"RFC 6749 error body","properties":{"error":{"type":"string"},"error_description":{"type":"string"}},"required":["error"]},"TokenResponse":{"type":"object","properties":{"access_token":{"type":"string","description":"JWT, ES256, one hour"},"token_type":{"type":"string","const":"Bearer"},"expires_in":{"type":"integer"},"refresh_token":{"type":"string","description":"Opaque, single-use, rotates on refresh"},"scope":{"type":"string","description":"Space-separated granted scopes"},"identity_assertion":{"type":"string","description":"Claim grant only: the assertion for later jwt-bearer sign-ins"},"assertion_expires":{"type":"string","format":"date-time"}},"required":["access_token","token_type","expires_in"]}}},"paths":{"/mcp":{"post":{"operationId":"mcp","summary":"The MCP endpoint (Streamable HTTP)","description":"Model Context Protocol, revision 2026-07-28 (legacy 2025-11-25 served from the same URL). Every capability of Automo Build is an MCP tool: list them with tools/list after sign-in. Unauthenticated requests answer 401 with a WWW-Authenticate challenge whose resource_metadata URL starts OAuth discovery. Narrower catalog profiles are served at /mcp/core and /mcp/observe.","security":[{"oauth2":["workspaces:read","projects:read","projects:write","prompts:write","sessions:read","sessions:write","reviews:read","reviews:write","playbooks:read","playbooks:run","playbooks:write","deployments:read","deployments:write","chat:read","billing:write"]}],"parameters":[{"$ref":"#/components/parameters/McpProtocolVersion"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"A JSON-RPC 2.0 MCP message","properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"oneOf":[{"type":"string"},{"type":"integer"}]},"method":{"type":"string","description":"e.g. tools/list, tools/call"},"params":{"type":"object","additionalProperties":true}},"required":["jsonrpc","method"]}}}},"responses":{"200":{"description":"JSON-RPC response or SSE stream, per the MCP Streamable HTTP transport","content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"oneOf":[{"type":"string"},{"type":"integer"}]},"result":{"type":"object","additionalProperties":true},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}}},"required":["jsonrpc"]}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"401":{"description":"Missing or invalid token; WWW-Authenticate carries resource_metadata"},"403":{"description":"Token lacks a required scope; WWW-Authenticate names the scopes still needed"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/.well-known/oauth-protected-resource/mcp":{"get":{"operationId":"getProtectedResourceMetadata","summary":"RFC 9728 protected-resource metadata","description":"Names the resource and its authorization server, and lists scopes_supported.","responses":{"200":{"description":"Protected-resource metadata","content":{"application/json":{"schema":{"type":"object","properties":{"resource":{"type":"string","format":"uri"},"resource_name":{"type":"string"},"authorization_servers":{"type":"array","items":{"type":"string","format":"uri"}},"bearer_methods_supported":{"type":"array","items":{"type":"string"}},"scopes_supported":{"type":"array","items":{"type":"string"}}},"required":["resource","authorization_servers"]}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/.well-known/oauth-authorization-server":{"get":{"operationId":"getAuthorizationServerMetadata","summary":"RFC 8414 authorization-server metadata","responses":{"200":{"description":"Authorization-server metadata, including the agent_auth registration block","content":{"application/json":{"schema":{"type":"object","properties":{"issuer":{"type":"string","format":"uri"},"authorization_endpoint":{"type":"string","format":"uri"},"token_endpoint":{"type":"string","format":"uri"},"revocation_endpoint":{"type":"string","format":"uri"},"jwks_uri":{"type":"string","format":"uri"},"grant_types_supported":{"type":"array","items":{"type":"string"}},"scopes_supported":{"type":"array","items":{"type":"string"}},"agent_auth":{"type":"object","description":"Agent registration endpoints (auth.md protocol)","properties":{"skill":{"type":"string","format":"uri"},"identity_endpoint":{"type":"string","format":"uri"},"claim_endpoint":{"type":"string","format":"uri"},"events_endpoint":{"type":"string","format":"uri"},"identity_types_supported":{"type":"array","items":{"type":"string"}}}}},"required":["issuer","token_endpoint"]}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/.well-known/mcp-server-card.json":{"get":{"operationId":"getServerCard","summary":"MCP server card","description":"Pre-connection discovery: transport, auth, catalog summary and branding.","responses":{"200":{"description":"Server card","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"websiteUrl":{"type":"string","format":"uri"},"remotes":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["type","url"]}}},"required":["name","remotes"]}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/.well-known/jwks.json":{"get":{"operationId":"getJwks","summary":"JWKS for access-token verification","responses":{"200":{"description":"JSON Web Key Set","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"kty":{"type":"string"},"crv":{"type":"string"},"kid":{"type":"string"},"x":{"type":"string"},"y":{"type":"string"}},"required":["kty","kid"]}}},"required":["keys"]}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/oauth/authorize":{"get":{"operationId":"authorize","summary":"OAuth 2.1 authorization endpoint","description":"Authorization code with PKCE. The client_id is an HTTPS Client ID Metadata Document URL. The person consents on app.automo.build; the code returns to redirect_uri.","parameters":[{"name":"response_type","in":"query","required":true,"schema":{"type":"string","const":"code"}},{"name":"client_id","in":"query","required":true,"schema":{"type":"string","format":"uri"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","format":"uri"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}},{"name":"code_challenge","in":"query","required":true,"schema":{"type":"string"}},{"name":"code_challenge_method","in":"query","required":true,"schema":{"type":"string","const":"S256"}},{"name":"resource","in":"query","required":false,"schema":{"type":"string","format":"uri"}}],"responses":{"302":{"description":"Redirect to consent, then to redirect_uri with code and iss"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/oauth/token":{"post":{"operationId":"token","summary":"OAuth 2.1 token endpoint","description":"Code exchange and refresh, plus the two agent-registration grants: jwt-bearer exchanges an identity_assertion, and the claim grant is polled with a claim_token (authorization_pending, then slow_down if polled faster than the interval) until the user confirms.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token","urn:ietf:params:oauth:grant-type:jwt-bearer","urn:workos:agent-auth:grant-type:claim"]},"code":{"type":"string"},"redirect_uri":{"type":"string","format":"uri"},"client_id":{"type":"string"},"code_verifier":{"type":"string"},"refresh_token":{"type":"string"},"resource":{"type":"string","format":"uri"},"assertion":{"type":"string","description":"jwt-bearer grant: the identity_assertion from registration"},"claim_token":{"type":"string","description":"claim grant: poll until the user confirms"}},"required":["grant_type"]}}}},"responses":{"200":{"description":"Access token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"400":{"description":"invalid_grant, authorization_pending, slow_down and friends","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/oauth/revoke":{"post":{"operationId":"revoke","summary":"RFC 7009 revocation endpoint","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string"},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"]}},"required":["token"]}}}},"responses":{"200":{"description":"Revoked (also for unknown tokens, per RFC 7009)","headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/agent/identity":{"post":{"operationId":"registerAgent","summary":"Register an agent for its user (auth.md)","description":"Three methods. identity_assertion: an enabled agent provider vouches for its signed-in user with an ID-JAG. service_auth: the agent names the user by email and the user confirms a code. anonymous: no identity and no credentials until the user claims it. Retries are safe with Idempotency-Key.","security":[],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["identity_assertion","service_auth","anonymous"]},"assertion_type":{"type":"string","const":"urn:ietf:params:oauth:token-type:id-jag","description":"identity_assertion only"},"assertion":{"type":"string","description":"identity_assertion only: the provider-signed ID-JAG"},"login_hint":{"type":"string","format":"email","description":"service_auth only: the user's email"}},"required":["type"]}}}},"responses":{"200":{"description":"Registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegistration"}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"400":{"description":"invalid_request or issuer_not_enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"401":{"description":"The provider identity needs its account holder to confirm","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InteractionRequired"}}}},"409":{"description":"The registration behind this Idempotency-Key is claimed, revoked or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"422":{"description":"This Idempotency-Key was sent with a different body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/agent/identity/claim":{"post":{"operationId":"restartClaim","summary":"Restart the claim ceremony with a fresh code","description":"For a pending registration whose code expired or was lost. Invalidates the previous code.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"claim_token":{"type":"string"},"email":{"type":"string","format":"email","description":"Optional: the account the user will confirm with"}},"required":["claim_token"]}}}},"responses":{"200":{"description":"A fresh code","content":{"application/json":{"schema":{"type":"object","properties":{"registration_id":{"type":"string","format":"uuid"},"claim_attempt_id":{"type":"string","format":"uuid"},"status":{"type":"string","const":"initiated"},"expires_at":{"type":"string","format":"date-time"},"claim_attempt":{"$ref":"#/components/schemas/ClaimCode"}},"required":["registration_id","status","claim_attempt"]}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"400":{"description":"invalid_claim_token, claimed_or_in_flight or claim_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/agent/events":{"post":{"operationId":"receiveProviderEvent","summary":"Security event receiver for agent providers (RFC 8935)","description":"An enabled provider delivers identity-assertion-revoked as a signed SET; the matching registrations are revoked.","security":[],"requestBody":{"required":true,"content":{"application/secevent+jwt":{"schema":{"type":"string","description":"The SET, a provider-signed JWT"}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{}}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"400":{"description":"Unverifiable or from an issuer that is not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/openapi.json":{"get":{"operationId":"getOpenApi","summary":"This document","responses":{"200":{"description":"OpenAPI 3.1","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}}}}