MCP tools
The Appbricx MCP server exposes 24 tools to Claude Code, Cursor and any MCP client. Each is a thin shell over the developer API, so a tool answers exactly what the matching HTTP endpoint and CLI command answer.
On this page
- Connect
- Identity and projects
- whoami
- get_guide
- list_projects
- create_project
- get_project
- Contract loop
- get_contract
- check_contract
- apply_contract
- patch_contract
- check_component
- verify
- screenshot
- deploy
- sign_in_providers
- Read the running app
- query_data
- logs
- describe_schema
- tail
- Operate the running app
- sql
- edit_rows
- snapshots
- deploys
- run
- secrets
Connect
Streamable HTTP at https://appbricx.com/api/mcp (self-hosted: your API origin plus /mcp). The client signs in through the browser (OAuth) on first connect, or sends a personal access token as a bearer. Add ?project=<id> (or the x-appbricx-project header) to pin a project: project_id becomes optional and table, workflow and role arguments become enums of the project's current names.
{
"mcpServers": {
"appbricx": {
"type": "http",
"url": "https://appbricx.com/api/mcp?project=<project-id>"
}
}
}verify, deploy, snapshot restores and rollbacks take minutes. After about 45 seconds they answer { status: "running" }; calling the same tool again joins the same run instead of starting a second one. A tool result with status 400 or above is flagged isError.
Resource appbricx://docs/guide: How to write, check, apply and verify an appbricx contract.
Identity and projects
whoamiread-only
Who am I. The signed-in user, the token's scopes and its workspace(s).
- Scope
- any token
- Output
- The signed-in user, credential kind, scopes and workspaces.
Input schema
No arguments.
{
"name": "whoami",
"arguments": {}
}{
"userId": "u_1",
"email": "dev@example.com",
"auth": "pat",
"scopes": [
"read",
"apply",
"deploy"
],
"workspaces": [
{
"id": "6a1f…",
"name": "Acme",
"role": "owner"
}
]
}Source: services/api/src/mcp/server.ts:127
get_guideread-only
Contract guide. The contract reference for authors (markdown). Without a section: the loop, rules, contract shape, access and workflows, plus an index. With a section id: that part (pages, blocks, coordinates, seeds, patch ops, icons). The whole guide is also the appbricx://docs/guide resource.
- Scope
- any token
- Output
- Markdown. Without section: the loop, rules, contract shape, access and workflows, plus an index of sections. With section: that part.
Input schema
| Name | Type | Description |
|---|---|---|
sectionoptional | string | (one of the guide's section ids) |
{
"name": "get_guide",
"arguments": {
"section": "components"
}
}# appbricx contract guide
Loop: get_contract → edit → check_contract …Source: services/api/src/mcp/server.ts:134
list_projectsread-only
List projects. Projects this token can reach (newest first).
- Scope
- any token
- Output
- Projects the token can reach, newest first.
Input schema
No arguments.
{
"name": "list_projects",
"arguments": {}
}{
"projects": [
{
"id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"name": "Tablefor",
"slug": "tablefor",
"workspace_id": "6a1f…",
"updated_at": "…"
}
]
}Source: services/api/src/mcp/server.ts:141
create_projectwrites
Create project. Create an empty project in the token's workspace. Then apply_contract to build it. Needs the apply scope.
- Scope
- apply
- Output
- The new project's id, name and slug.
- Errors
- FORBIDDEN_SCOPE without apply.
Input schema
| Name | Type | Description |
|---|---|---|
namerequired | string | (min 1, max 100) |
descriptionoptional | string | (max 2000) |
{
"name": "create_project",
"arguments": {
"name": "Tablefor",
"description": "Table bookings for a small restaurant"
}
}{
"project": {
"id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"name": "Tablefor",
"slug": "tablefor",
"workspaceId": "6a1f…"
}
}Source: services/api/src/mcp/server.ts:147
get_projectread-only
Project state. Whether the project has been built, the last build failure if any, and its preview path.
- Scope
- any token
- Output
- Whether the project is built, the last build failure, and the preview path.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
{
"name": "get_project",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b"
}
}{
"project": {
"id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"name": "Tablefor"
},
"state": {
"built": true,
"lastError": null
},
"previewPath": "/preview/3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b/"
}Source: services/api/src/mcp/server.ts:153
Contract loop
get_contractread-only
Get contract. The project's current contract (null before the first apply). Seeds come back as "UNCHANGED" — rows live in the database; use query_data to read them.
- Scope
- any token
- Output
- The current contract (null before the first apply). Seeds come back as "UNCHANGED".
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
{
"name": "get_contract",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b"
}
}{
"contract": {
"app": {
"name": "Tablefor"
},
"entities": [
{
"name": "bookings"
}
],
"seeds": "UNCHANGED"
},
"built": true
}Source: services/api/src/mcp/server.ts:160
check_contractread-only
Check contract. Normalize a contract and report errors (must be empty to apply), fixes (what the normalizer matched or filled — make them explicit) and warnings. No side effects.
- Scope
- any token
- Output
- The check report: errors (must be empty to apply), fixes, warnings.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
contractrequired | object | The contract JSON: { app: { name, tagline }, personas: [{ id, kind: 'staff'|'consumer' }], entities: [{ name, fields: [{ name, type, enum_values?, ref?, optional? }], access?, owner_refs? }], seeds?, pages?, workflows? } — see appbricx://docs/guide |
{
"name": "check_contract",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"contract": {
"app": {
"name": "Tablefor"
},
"personas": [
{
"id": "staff",
"kind": "staff"
}
],
"entities": [
{
"name": "bookings",
"fields": [
{
"name": "date",
"type": "date"
}
]
}
]
}
}
}{
"report": {
"ok": true,
"errors": [],
"fixes": [
"entities.bookings.fields.status: enum_values filled from seeds"
],
"warnings": []
}
}Source: services/api/src/mcp/server.ts:167
apply_contractwrites
Apply contract. Build the DEV environment from a full contract: database created or evolved additively (rows kept), pages compiled, workflows armed. Returns the check report, a build summary with demo sign-ins per role, and warnings. 422 = contract invalid (see report). Needs the apply scope.
- Scope
- apply
- Output
- The check report, a build summary with demo sign-ins per role, and warnings. A tool error with 422 means the contract is invalid (see report).
- Errors
- CONTRACT_INVALID (422), PROJECT_BUSY (409), HAND_EDITED_FILES (409, pass force), BUILD_FAILED (500).
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
contractrequired | object | The contract JSON: { app: { name, tagline }, personas: [{ id, kind: 'staff'|'consumer' }], entities: [{ name, fields: [{ name, type, enum_values?, ref?, optional? }], access?, owner_refs? }], seeds?, pages?, workflows? } — see appbricx://docs/guide |
forceoptional | boolean | Overwrite compiled files you edited by hand (they are backed up first) |
{
"name": "apply_contract",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"contract": {
"app": {
"name": "Tablefor"
}
}
}
}{
"report": {
"ok": true,
"errors": []
},
"summary": "Built 4 tables, 9 pages, 2 workflows. Demo sign-ins: staff@demo.app",
"warnings": []
}Source: services/api/src/mcp/server.ts:174
patch_contractwrites
Patch contract. Apply typed edit ops to the current contract, then rebuild (dry_run: report only). Ops: add_entity {name, fields[], personas?} · adopt_table {table, personas?, access?, title?, label_field?, page?} (a table made by hand with SQL becomes an entity; columns read from the dev database, rows kept) · add_field {entity, field} · update_field {entity, name, enum_values?, optional?} · remove_field {entity, name} · set_workflow {workflow} · remove_workflow {id} · add_page {page} · set_page {page, title?, icon?, personas?, layout?, form?} · remove_page {page} · set_component {component} (add/replace by name; code components carry source) · remove_component {name} · set_entity {entity, access?, owner_refs?, actor_ref?, label_field?} · set_demo_logins {logins[{persona,row}]} · set_app {theme?, direction?, nav_style?, density?, brand_color?, auth?} · edit_component {name, edits[{find, replace}]} (part of a code component's source; each find must occur exactly once).
- Scope
- apply
- Output
- As apply_contract, for the patched contract (dry_run: the report only).
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
editsrequired | Array<object> | Ops, each { op: ..., ... } (min 1, max 50) |
dry_runoptional | boolean | |
forceoptional | boolean |
{
"name": "patch_contract",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"edits": [
{
"op": "add_field",
"entity": "bookings",
"field": {
"name": "party_size",
"type": "number"
}
}
],
"dry_run": false
}
}{
"report": {
"ok": true,
"errors": []
},
"summary": "Added bookings.party_size"
}Source: services/api/src/mcp/server.ts:184
check_componentread-only
Check a custom component. Run one custom code component through every gate — static import/capability allowlist, strict TypeScript against the real kit types, compile, and a sandboxed server render with the sample props and with empty props. Seconds, no project change. Use it before putting the component into the contract. See get_guide section "components" for the standard signature (props + app: AppHandle).
- Scope
- any token
- Output
- Which gates passed, or the failing stage and its errors.
Input schema
| Name | Type | Description |
|---|---|---|
namerequired | string | PascalCase component name — the default export must use it |
sourcerequired | string | The whole TSX file |
sampleoptional | object | Props the render gate uses (same as the component's "sample") |
{
"name": "check_component",
"arguments": {
"name": "OpenNow",
"source": "import type { AppHandle } from \"@app/kit/primitives\";\nexport default function OpenNow({ app }: { app?: AppHandle }) {\n return <p>Open until 22:00</p>;\n}",
"sample": {}
}
}{
"ok": true,
"passed": [
"static",
"types",
"compile",
"render"
]
}Source: services/api/src/mcp/server.ts:199
verifyread-only
Verify. Run appbricx verify on the DEV environment (takes a few minutes: if it answers status "running", call verify again to get the result): static (contract, reachability, typecheck) → data (demo sign-ins, role × table permission matrix with rolled-back writes, signed-out access, workflows armed) → browser. Each failing check has evidence and a fix. 'skipped' is never 'pass'.
- Scope
- any token
- Output
- The verify report: static, data and browser stages, each failing check with evidence and a fix. Answers { status: "running" } after about 45 seconds; call again to join the same run.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
{
"name": "verify",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b"
}
}{
"report": {
"status": "fail",
"stages": [
{
"name": "data",
"status": "fail",
"checks": [
{
"id": "rls.customer.bookings.update",
"status": "fail",
"evidence": "customer updated another customer's booking",
"fix": "set access.update to own"
}
]
}
]
}
}Source: services/api/src/mcp/server.ts:210
screenshotread-only
Screenshot the app. See the app as a user does: opens the DEV preview in a real browser at phone size (390×844 unless you pass width/height), signed in as a demo role (default: the first persona; pass a persona id or a demo login email) or as="guest" to see the sign-in screen, goes to `route`, and returns the PNG plus page errors, horizontal overflow and the visible text. Use it after apply_contract to check every screen against your reference — layout, colours, fonts, nothing cut off — and fix what you see.
- Scope
- any token
- Output
- An image (PNG) plus JSON: route, persona, page errors, horizontal overflow and the visible text.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
routeoptional | string | App route, e.g. /people or /chat/<id> (default: where sign-in lands) |
asoptional | string | Persona id, demo login email, or "guest" (signed out) |
widthoptional | integer | (min 320, max 1600) |
heightoptional | integer | (min 480, max 1200) |
full_pageoptional | boolean | Capture the whole scrollable page |
{
"name": "screenshot",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"route": "/bookings",
"as": "customer",
"width": 390
}
}{
"route": "/bookings",
"as": "staff",
"errors": [],
"overflowX": 0,
"text": "Bookings · Today · 3 tables free"
}Source: services/api/src/mcp/server.ts:217
deploywrites
Deploy. Publish the app to https://<subdomain>.<publish domain> (takes a few minutes: if it answers status "running", call deploy again to get the result). Runs verify first and refuses on red unless skip_verify. Pass `subdomain` to choose a meaningful host name (e.g. "tablefor"); omitted, the project keeps the one it has. Needs the deploy scope.
- Scope
- deploy
- Output
- The deployment id, live URL, status, duration and the verify report. Answers { status: "running" } after about 45 seconds; call again to join.
- Errors
- VERIFY_FAILED (422) unless skip_verify; SUBDOMAIN_TAKEN, INVALID_SUBDOMAIN; a deployment already in progress (409).
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
environmentoptional | "production" | "preview" | |
allow_destructiveoptional | boolean | Confirm destructive schema changes on promote |
skip_verifyoptional | boolean | |
subdomainoptional | string | One DNS label: lowercase letters, digits, single hyphens (e.g. "tablefor"). Name it after the app. |
demo_resetoptional | boolean | Demo mode, for an app whose demo logins are public: true puts the published data and accounts back to the preview's every night; false stops it. |
{
"name": "deploy",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"subdomain": "tablefor"
}
}{
"deploymentId": "d_9",
"url": "https://tablefor.apps.appbricx.com",
"status": "live",
"durationMs": 142000
}Source: services/api/src/mcp/server.ts:267
sign_in_providerswrites
Sign-in providers. Read or change the app's social sign-in. With no `provider`, lists Google and GitHub and whether each is on. {provider: "google", enabled: true} turns on Continue with Google through Appbricx's own Google client (no Google Cloud setup). Pass client: "own" with client_id and client_secret to use your own OAuth client (register https://<app host>/__appbricx/auth/oauth/<provider>/callback). The contract switch `auth.google` does the same on apply. Changing needs the apply scope.
- Scope
- read to list; apply to change
- Output
- Google and GitHub and whether each is on.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
provideroptional | "google" | "github" | |
enabledoptional | boolean | |
clientoptional | "platform" | "own" | |
client_idoptional | string | |
client_secretoptional | string |
{
"name": "sign_in_providers",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"provider": "google",
"enabled": true
}
}{
"providers": [
{
"provider": "google",
"enabled": true,
"client": "platform"
},
{
"provider": "github",
"enabled": false
}
]
}Source: services/api/src/mcp/server.ts:281
Read the running app
query_dataread-only
Query data. Read rows from a table in the DEV database (read-only, max 200). Filters are equality on column values.
- Scope
- any token
- Output
- Up to 200 rows of a dev table.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
entityrequired | string | Entity (table) name, as in the contract's entities[].name On a pinned connection this is an enum of the project's current names. |
whereoptional | object | Column → value equality filters |
order_byoptional | string | Column to order by (default created_at) |
descoptional | boolean | Descending (default true) |
limitoptional | integer | (min 1, max 200) |
{
"name": "query_data",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"entity": "bookings",
"where": {
"status": "confirmed"
},
"limit": 10
}
}{
"table": "bookings",
"rows": [
{
"id": "b_1",
"date": "2026-10-12",
"status": "confirmed"
}
],
"rowCount": 1
}Source: services/api/src/mcp/server.ts:242
logsread-only
Workflow logs. Recent workflow runs (status, error, last log lines) and in-app notifications for the project.
- Scope
- any token
- Output
- Recent runs with their last log lines, and notifications.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
workflowoptional | string | Only this workflow's runs On a pinned connection this is an enum of the project's current names. |
limitoptional | integer | (min 1, max 200) |
{
"name": "logs",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"workflow": "send-invoice",
"limit": 10
}
}{
"runs": [
{
"workflow_id": "send-invoice",
"status": "failed",
"error": "SMTP timeout",
"log": []
}
],
"notifications": []
}Source: services/api/src/mcp/server.ts:256
describe_schemaread-only
Describe schema. The real schema of the dev or prod database: tables with columns (type, nullable, default), primary and foreign keys, unique and check constraints, indexes, triggers and policies; views, functions and enums in the public schema. Each table's origin says whether the contract manages it (contract), Appbricx made it (platform), it is an internal _appbricx_* runtime table (internal), or it was made by hand (hand-made, for example with sql). Columns of contract tables are marked managedByContract.
- Scope
- read
- Output
- Tables (columns, keys, constraints, indexes, triggers, policies, origin), views, functions and enums.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
envoptional | "dev" | "prod" | Database environment: "dev" (the preview, default) or "prod" (the published app) |
{
"name": "describe_schema",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"env": "prod"
}
}{
"env": "dev",
"tables": [
{
"name": "bookings",
"origin": "contract",
"columns": [
{
"name": "date",
"type": "date",
"managedByContract": true
}
]
}
]
}Source: services/api/src/mcp/server.ts:337
tailread-only
Tail events and requests. Recent activity of the running app. kind "events": change events (row writes) and topic messages; "requests": the app's runtime requests (every error and about 10% of the rest, 7 days); "errors": only 4xx/5xx requests. since: 15m, 2h, 1d or an ISO time. Paths only, never bodies, query strings or tokens.
- Scope
- read
- Output
- events (change events and topic messages), requests, or errors, newest first. Paths only.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
kindrequired | "events" | "requests" | "errors" | |
envoptional | "dev" | "prod" | Database environment: "dev" (the preview, default) or "prod" (the published app) |
sinceoptional | string | |
limitoptional | integer | (min 1, max 500) |
{
"name": "tail",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"kind": "errors",
"env": "prod",
"since": "2h"
}
}{
"kind": "errors",
"env": "prod",
"requests": [
{
"at": "…",
"method": "POST",
"path": "/__appbricx/api/v1/bookings",
"status": 422,
"error": "RULE_REFUSED"
}
]
}Source: services/api/src/mcp/server.ts:395
Operate the running app
sqlwrites
Run SQL. Run SQL against the dev or prod database like the builder's SQL editor: several statements in one transaction, DDL and DML, as the tenant admin (past row-level security). Returns rows (max 1000, of the last statement that returned rows), rowCount, each statement with its command and row count, and durationMs. A script that only reads runs in a rolled-back transaction and needs the read scope; writes need apply on dev and deploy on prod. Before any write on prod a database snapshot is taken and its id returned as snapshotId (undo with snapshots {action: "restore"}). Use it to hand-tune the schema (indexes, views, functions, triggers, extra tables or columns): contract apply and publish keep hand-made objects. Check the result with describe_schema. Catalog names (pg_catalog, information_schema) are refused: use describe_schema.
- Scope
- read for read-only scripts; writes need apply on dev and deploy on prod
- Output
- rows (1000 max, of the last statement that returned rows), rowCount, each statement with its command and row count, durationMs, and snapshotId for prod writes.
- Errors
- STMT_FORBIDDEN for catalog names (use describe_schema); a failing statement rolls back the whole script; SNAPSHOT_FAILED (503) leaves prod untouched.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
sqlrequired | string | One or more SQL statements (min 1) |
envoptional | "dev" | "prod" | Database environment: "dev" (the preview, default) or "prod" (the published app) |
{
"name": "sql",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"sql": "create index if not exists bookings_date on bookings(date)",
"env": "prod"
}
}{
"rows": [
{
"n": 128
}
],
"rowCount": 1,
"statements": [
{
"sql": "select count(*)::int as n from bookings",
"command": "SELECT",
"rowCount": 1
}
],
"env": "dev",
"readOnly": true,
"durationMs": 9
}Source: services/api/src/mcp/server.ts:303
edit_rowswrites
Edit rows. Insert, update or delete rows through the app's own data API, so the access rules, before-write rules, lifecycle guards, row-level security and change events (workflows on entity events) behave as in the app. insert: rows (1 to 100). update: id or ids plus patch. delete: id or ids. as: "admin" (default) writes elevated, past row-level security, like the Backend tab; as: {role} acts as an app user holding that persona role, with that role's access. Returns one result per row. Needs apply on dev and deploy on prod; a prod write takes a database snapshot first (snapshotId).
- Scope
- apply on dev; deploy on prod
- Output
- One result per row, succeeded and failed counts, and snapshotId on prod.
- Errors
- NO_PERSONA (409) when nobody holds the role; TABLE_FORBIDDEN; per-row RULE_REFUSED and E_LIFECYCLE_DIRECT_WRITE.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
tablerequired | string | Table (entity) name On a pinned connection this is an enum of the project's current names. |
envoptional | "dev" | "prod" | Database environment: "dev" (the preview, default) or "prod" (the published app) |
oprequired | "insert" | "update" | "delete" | |
rowsoptional | Array<object> | Rows to insert (min 1, max 100) |
idoptional | string | number | Row id to update or delete |
idsoptional | Array<string | number> | Row ids to update or delete (min 1, max 100) |
patchoptional | object | Column values to set (update) |
asoptional | "admin" | { role: string; user_id?: string } |
{
"name": "edit_rows",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"table": "bookings",
"op": "insert",
"rows": [
{
"date": "2026-10-13",
"party_size": 4
}
],
"as": {
"role": "customer"
}
}
}{
"table": "bookings",
"env": "dev",
"op": "insert",
"as": "admin",
"succeeded": 1,
"failed": 0,
"results": [
{
"ok": true,
"id": "b_9",
"row": {
"id": "b_9",
"date": "2026-10-13"
}
}
]
}Source: services/api/src/mcp/server.ts:316
snapshotswrites
Database snapshots. List, take or restore database snapshots (pg_dump) of dev or prod. Every publish and every agent write on prod takes one automatically. list needs read; create needs apply (default env prod); restore needs deploy, replaces the whole database with the snapshot, and first snapshots the current state (undoSnapshotId) so a restore can be undone.
- Scope
- list: read; create: apply; restore: deploy
- Output
- list: snapshots. create: the new snapshot. restore: restored id, env and undoSnapshotId.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
actionrequired | "list" | "create" | "restore" | |
envoptional | "dev" | "prod" | |
idoptional | string | Snapshot id to restore (from list) |
{
"name": "snapshots",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"action": "restore",
"id": "prod-2026-10-12T09-00-00Z-a1b2"
}
}{
"restored": "prod-2026-10-12T09-00-00Z-a1b2",
"env": "prod",
"undoSnapshotId": "prod-2026-10-12T09-31-12Z-e5f6"
}Source: services/api/src/mcp/server.ts:344
deployswrites
Deploy history. List the project's deployments (status, url, git sha, timing), or roll what's live back to an earlier successful deployment (its stored build, else a rebuild of its git sha; if it answers status "running", call again with the same deploymentId). Rollback switches files only: roll the database back with snapshots. list needs read; rollback needs deploy.
- Scope
- list: read; rollback: deploy
- Output
- list: deployments. rollback: the URL and how it was restored (stored build or rebuild).
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
actionrequired | "list" | "rollback" | |
deploymentIdoptional | string | The deployment to roll back to (from list) |
environmentoptional | "production" | "preview" | |
limitoptional | integer | (min 1, max 100) |
{
"name": "deploys",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"action": "list",
"limit": 5
}
}{
"deployments": [
{
"id": "d_9",
"environment": "production",
"status": "live",
"url": "https://tablefor.apps.appbricx.com"
}
]
}Source: services/api/src/mcp/server.ts:359
runwrites
Run workflows. action "workflow": run workflow `id` now with `input` against env (default dev). Returns runId, plus status and result when it finishes within 30s (else call get_run). Server functions (on: {call: true}) run inline as `as` (a persona) or signed out; other workflows are queued, acting as `as` when given. Needs apply on dev, deploy on prod. action "get_run": one run with its log (runId). action "dead_letters": jobs that used up their retries. action "replay": queue dead letters again (ids, default all; apply, or deploy when a job ran on prod).
- Scope
- workflow: apply on dev, deploy on prod; get_run and dead_letters: read; replay: apply (deploy for prod jobs)
- Output
- workflow: runId, status and result when it finishes within 30 seconds. get_run: the run with its log. dead_letters: jobs. replay: replayed and skipped ids.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
actionrequired | "workflow" | "get_run" | "dead_letters" | "replay" | |
idoptional | string | Workflow id (action workflow) On a pinned connection this is an enum of the project's current names. |
inputoptional | object | The workflow's input (its trigger payload) |
envoptional | "dev" | "prod" | Database environment: "dev" (the preview, default) or "prod" (the published app) |
asoptional | { role: string; user_id?: string } | |
runIdoptional | string | Run id (action get_run) |
idsoptional | Array<string> | Dead-letter job ids (action replay) |
limitoptional | integer | (min 1, max 200) |
{
"name": "run",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"action": "workflow",
"id": "send-invoice",
"input": {
"order": "b_1"
},
"env": "dev"
}
}{
"runId": "4f0a…",
"status": "succeeded",
"finished": true,
"result": {
"sent": true
},
"error": null
}Source: services/api/src/mcp/server.ts:375
secretswrites
Secrets. The app's secrets (project env vars) that workflows read with ctx.secrets.get(name). list: names, env and updated-at, never values (also which names the app declares and which are missing). set: name + value (env "dev", "prod" or "all", default all; ctx.secrets reads prod or all). delete: name (env limits it to one). set and delete need the apply scope and a workspace owner or admin token.
- Scope
- list: read; set and delete: apply plus a workspace owner or admin token
- Output
- list: names, env, scope and updated-at (never values), declared and missing names. set: created or updated. delete: the envs removed.
Input schema
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project id (from list_projects or create_project) (uuid) |
actionrequired | "list" | "set" | "delete" | |
nameoptional | string | |
valueoptional | string | |
envoptional | "dev" | "prod" | "all" |
{
"name": "secrets",
"arguments": {
"project_id": "3b7e9a52-6c1d-4f0e-9a8b-2c4d6e8f0a1b",
"action": "set",
"name": "SHIPPO_KEY",
"value": "shippo_live_…",
"env": "all"
}
}{
"secrets": [
{
"name": "STRIPE_KEY",
"scope": "project",
"env": "prod",
"secret": true
}
],
"declaredByApp": [
"STRIPE_KEY"
],
"missing": []
}Source: services/api/src/mcp/server.ts:408