{"serverInfo":{"name":"orbit-mcp","version":"0.1.0"},"authentication":{"required":true,"schemes":["oauth2"]},"tools":[{"description":"Put material on an app's board (POST /api/v1/scratchpads/<board>/cards). This is how a file reaches Orbit: pass `url` for a file on the public web, or `data_base64` for bytes you hold, and it is stored and placed as a card — a picture becomes an image card, anything else becomes a file card. The ceiling is 32 MB.\n\n`public` decides who may read the bytes: true returns a `content_url` that answers without a token, which is what a page rendering an `<img>` needs, and what a screenshot of that page needs. It is false by default.\n\n`link` keeps a web address instead — a page, a video, a competitor's site. Nothing is downloaded; the address is the material, and a bare host like `acme.com` is accepted.\n\nWithout a file or a link, pass `kind` and `content` for an ordinary card — a `prompt` holding an ask, or a `text` note. The card is placed beside what is already on the board.","inputSchema":{"type":"object","properties":{"alt":{"type":"string","description":"What the file shows, for a reader who cannot see it."},"content":{"type":"object","description":"Kind-specific payload for a card carrying no file, e.g. `{\"text\": \"...\"}` for a prompt."},"public":{"type":"boolean","description":"Serve the file's bytes without a token."},"idempotency_key":{"type":"string","description":"Retry-safety key; reuse the same key to safely retry an identical request."},"title":{"type":"string","description":"Card title. Defaults to the filename for a file."},"filename":{"type":"string","description":"Name to record, e.g. `logo.svg`."},"data_base64":{"type":"string","description":"The bytes, base64. A `data:<mime>;base64,<data>` url is accepted as written."},"link":{"type":"string","description":"A web address to keep as a link card. Nothing is downloaded."},"kind":{"type":"string","enum":["prompt","text","image","file","website"],"description":"Card kind. Required when no file or link is given; decided for you otherwise."},"app":{"type":"string","description":"App id — places the card on that app's board."},"url":{"type":"string","description":"Public http(s) address of a file to fetch."},"scratchpad":{"type":"string","description":"Board id (from orbit_list_scratchpads) — places the card on that board, app or no app. Pass this or `app`."}},"required":[]},"outputSchema":{"type":"object","properties":{"y":{"type":"number"},"content_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"content":{"type":"object","additionalProperties":{}},"width":{"oneOf":[{"type":"number"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"z":{"type":"integer"},"status":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"x":{"type":"number"},"artifact_kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"height":{"oneOf":[{"type":"number"},{"type":"null"}]},"props":{"type":"object","additionalProperties":{}}},"required":["id","scratchpad_id","kind","content","props","x","y","z","created_at"],"additionalProperties":false},"name":"orbit_add_card","title":"Add a card","annotations":{"readOnlyHint":false,"destructiveHint":false,"title":"Add a card"}},{"description":"Insert a catalog recipe on the server (POST /api/v1/workspaces/<id>/recipes). The server creates the node batch, grafts page recipes under the existing Page root, validates every node, and returns minted ids. This avoids expanding the recipe into model output.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Target workspace id."},"slug":{"type":"string","description":"Recipe slug."},"parent_id":{"type":"string","description":"Optional parent node id."},"dry_run":{"type":"boolean","description":"Preflight only."},"idempotency_key":{"type":"string","description":"Retry-safety key; reuse the same key to safely retry an identical request."}},"required":["id","slug"]},"outputSchema":{"type":"object","properties":{"applied":{"type":"boolean"},"slug":{"type":"string"},"kind":{"type":"string"},"node_ids":{"type":"object","additionalProperties":{"type":"string","format":"uuid"}},"issues":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"in":{"type":"string"},"index":{"type":"integer"},"kind":{"type":"string"},"reason":{"type":"string"},"ref":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["in","index","kind","reason","ref"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"in":{"type":"string"},"index":{"type":"integer"},"kind":{"type":"string"},"reason":{"type":"string"},"ref":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["in","index","kind","reason","ref"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"warnings":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"class":{"type":"string"},"indices":{"type":"array","items":{"type":"integer"}},"reason":{"type":"string"}},"required":["kind","class","indices","reason"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"class":{"type":"string"},"indices":{"type":"array","items":{"type":"integer"}},"reason":{"type":"string"}},"required":["kind","class","indices","reason"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]}},"required":["applied","slug","kind","node_ids","issues","warnings"],"additionalProperties":false},"name":"orbit_apply_recipe","title":"Apply recipe","annotations":{"readOnlyHint":false,"destructiveHint":false,"title":"Apply recipe"}},{"description":"Archive an Orbit app (POST /api/v1/apps/<id>/archive) — the soft delete. The app and its workspaces persist and stay queryable, and orbit_unarchive_app restores it. An org has a limited number of app slots, which an archived app no longer occupies.\n\nArchiving does not stop anything, so it is refused with a 409 `app-deployment-live` while any of the app's deployments is still up; the live ones are on that response as `deployments`. Stop each with the deployment stop endpoint first, then archive — that order is also what keeps the org's free slot from staying held by an app nobody can see.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"App id (UUID)."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"idea_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"archived":{"type":"boolean"},"slug":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"settings":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"icon":{"oneOf":[{"type":"string"},{"type":"null"}]},"themes":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"title":{"type":"string"},"updated_at":{"type":"string"},"preview":{"oneOf":[{"type":"string"},{"type":"null"}]},"locales":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"}},"required":["id","org_id","slug","title","icon","archived","settings","themes","locales","created_at","updated_at"],"additionalProperties":false},"name":"orbit_archive_app","title":"Archive app","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Archive app"}},{"description":"Cancel a workflow execution (POST /api/v1/executions/<id>/cancel). The run stops where it is and its status is persisted as `cancelled`; whatever it already wrote to the app's data or sent to a connected service stays done.\n\nCancelling a run that already finished is idempotent — it answers 200 with the run's real outcome.\n\nA 409 `execution-not-cancellable` means the run is live on another api instance, or its handle was orphaned by a restart, so it cannot be stopped from here.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Execution id (from orbit_create_run)."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"workspace_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"app_id":{"type":"string","format":"uuid"},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string"},"result":{},"id":{"type":"string","format":"uuid"},"error":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"seq":{"type":"integer"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","org_id","app_id","workspace_id","status","seq","created_at","updated_at"],"additionalProperties":false},"name":"orbit_cancel_run","title":"Cancel workflow run","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Cancel workflow run"}},{"description":"Create an Orbit app (POST /api/v1/apps). `slug` is derived from `title` when omitted. Returns the new app, which is seeded with three workspaces: an empty mockup that owns `/`, a workflow, and the entity workspace. Build the first screen into that mockup rather than creating another one.","inputSchema":{"type":"object","properties":{"org":{"type":"string","description":"Org id to create the app in."},"title":{"type":"string","description":"Human-readable app name (1-200 chars)."},"slug":{"type":"string","description":"URL-safe id, unique in the org (default: derived from title)."},"icon":{"type":"string","description":"Single-glyph emoji icon."},"description":{"type":"string","description":"Short blurb."},"idempotency_key":{"type":"string","description":"Retry-safety key; reuse the same key to safely retry an identical request."}},"required":["org","title"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"idea_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"archived":{"type":"boolean"},"slug":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"settings":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"icon":{"oneOf":[{"type":"string"},{"type":"null"}]},"themes":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"title":{"type":"string"},"updated_at":{"type":"string"},"preview":{"oneOf":[{"type":"string"},{"type":"null"}]},"locales":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"}},"required":["id","org_id","slug","title","icon","archived","settings","themes","locales","created_at","updated_at"],"additionalProperties":false},"name":"orbit_create_app","title":"Create app","annotations":{"readOnlyHint":false,"destructiveHint":false,"title":"Create app"}},{"description":"Trigger a deployment for an app (POST /api/v1/apps/<app>/deployments; defaults to a free dev launch; pass env=prod to go live), putting it online at its URL. Returns the building row immediately; progress arrives through orbit_get_deployment and orbit_get_deployment_events. A paid tier draws on the org's prepaid wallet. On a 409 deployment-plan-approval-required the schema change is disruptive: error.plan.steps describes it (removed fields are skipped rather than dropped, so data is preserved) and error.plan.hash is the token that approves exactly those changes. A 422 deployment-plan-blocked is never approvable and means the app's data model itself needs changing.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id to deploy."},"env":{"type":"string","enum":["dev","uat","prod"],"description":"Target env (default dev) — prod must be asked for by name."},"tier":{"type":"string","enum":["free","hobby","starter","growth","scale"],"description":"Hosting tier (default free)."},"force":{"type":"boolean","description":"On a free launch, evict whatever app currently holds the org's free slot — that app goes offline."},"plan_hash":{"type":"string","description":"Approval token for a disruptive schema change — set to a prior 409's error.plan.hash to approve exactly those changes. Safe/additive deploys need no plan_hash."},"idempotency_key":{"type":"string","description":"Retry-safety key; reuse the same key to safely retry an identical request."}},"required":["app"]},"outputSchema":{"type":"object","properties":{"slug":{"oneOf":[{"type":"string"},{"type":"null"}]},"stage":{"oneOf":[{"type":"string"},{"type":"null"}]},"issues":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"workspace_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["kind","workspace_id","title","reason","message"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"workspace_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["kind","workspace_id","title","reason","message"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"started_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"completed_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"events":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"org_id":{"type":"string","format":"uuid"},"ip_address":{"oneOf":[{"type":"string"},{"type":"null"}]},"app_id":{"type":"string","format":"uuid"},"history":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"triggered_by":{"oneOf":[{"type":"string"},{"type":"null"}]},"outcome":{"oneOf":[{"type":"string"},{"type":"null"}]},"error_code":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["at","bundle_url","bundle_version","triggered_by","outcome","error_code"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"triggered_by":{"oneOf":[{"type":"string"},{"type":"null"}]},"outcome":{"oneOf":[{"type":"string"},{"type":"null"}]},"error_code":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["at","bundle_url","bundle_version","triggered_by","outcome","error_code"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"phase":{"type":"string"},"public_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"env":{"type":"string"},"last_heartbeat_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"provider_app_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"updated_at":{"type":"string"},"status":{"type":"string"},"id":{"type":"string","format":"uuid"},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"error":{"oneOf":[{"type":"object","properties":{},"additionalProperties":false},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"domain":{"oneOf":[{"type":"string"},{"type":"null"}]},"version":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","app_id","org_id","env","phase","status","issues","events","history","version","created_at","updated_at"],"additionalProperties":false},"name":"orbit_create_deployment","title":"Deploy app","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Deploy app"}},{"description":"Trigger a workflow run (POST /api/v1/workspaces/<ws>/executions). A workflow is server-side logic that can write to the app's data and call services it is connected to, so a run has real side effects. Returns the building row immediately; progress and result arrive through orbit_get_run and orbit_get_run_events.","inputSchema":{"type":"object","properties":{"workspace":{"type":"string","description":"Workflow workspace id (from orbit_list_workspaces kind=workflow)."},"inputs":{"type":"object","description":"JSON inputs for the workflow start node."},"idempotency_key":{"type":"string","description":"Retry-safety key; reuse the same key to safely retry an identical request."}},"required":["workspace"]},"outputSchema":{"type":"object","properties":{"workspace_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"app_id":{"type":"string","format":"uuid"},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string"},"result":{},"id":{"type":"string","format":"uuid"},"error":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"seq":{"type":"integer"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","org_id","app_id","workspace_id","status","seq","created_at","updated_at"],"additionalProperties":false},"name":"orbit_create_run","title":"Run workflow","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Run workflow"}},{"description":"Create a workspace (POST /api/v1/apps/<app>/workspaces); the server seeds its root node. A mockup workspace is one screen, a workflow workspace one piece of server-side logic, and the entity workspace the app's data model. A new app already owns a mockup for its first screen, so call this for an ADDITIONAL screen — check orbit_list_workspaces first.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id to create the workspace in."},"kind":{"type":"string","enum":["mockup","workflow","entity"],"description":"Workspace kind."},"title":{"type":"string","description":"Human-readable workspace name."},"props":{"type":"object","description":"Props for the seeded root node, e.g. {\"slug\":\"/about\"}."}},"required":["app","kind","title"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"archived":{"type":"boolean"},"org_id":{"type":"string","format":"uuid"},"root_node_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"app_id":{"type":"string","format":"uuid"},"settings":{"type":"object","additionalProperties":{}},"title":{"type":"string"},"updated_at":{"type":"string"},"nodes":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"idx":{"type":"integer"},"component":{"type":"string"},"props":{"type":"object","additionalProperties":{}},"hidden":{"type":"boolean"},"archived":{"type":"boolean"}},"required":["id","parent_id","idx","component","props","hidden","archived"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"idx":{"type":"integer"},"component":{"type":"string"},"props":{"type":"object","additionalProperties":{}},"hidden":{"type":"boolean"},"archived":{"type":"boolean"}},"required":["id","parent_id","idx","component","props","hidden","archived"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"created_at":{"type":"string"}},"required":["id","org_id","app_id","kind","title","settings","archived","root_node_id","created_at","updated_at","nodes"],"additionalProperties":false},"name":"orbit_create_workspace","title":"Create workspace","annotations":{"readOnlyHint":false,"destructiveHint":false,"title":"Create workspace"}},{"description":"Create, update and remove a workspace's nodes as one atomic batch (POST /api/v1/workspaces/<id>/nodes) — the nodes are what a screen is made of. The batch either applies whole or applies not at all: one bad row fails everything and nothing commits.\n\nA real apply maps each label to a minted UUID under `node_ids`. A `dry_run` reports the same issues but commits nothing, so `node_ids` comes back empty.\n\n`component` must name a component that the workspace can render. An unknown name fails the whole batch. The error is an `unknown-component` issue, and it names the closest valid component.\n\nThe response also reports non-fatal `warnings` about each authored `class` prop. `unknown-utility` means the class does not exist and emits no CSS. `off-theme-color` means the class is a raw palette value instead of a theme token. A warning never blocks a commit.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Workspace id whose nodes the batch applies to."},"batch":{"type":"object","description":"Atomic batch of node upserts and removes.","properties":{"upserts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"UUID of an existing node to update, or a temp label matching ^[a-z][a-z0-9_]{0,63}$ that mints a new one."},"parent_id":{"type":"string","description":"Parent node: a UUID already in the workspace, or a label minted in this batch. A new node needs one. Only the root has none, and the root cannot be re-parented."},"idx":{"type":"integer","description":"Sibling position, 0-based, 0 by default. The caller owns ordering, so an insert mid-list also sends the displaced siblings' new idx."},"component":{"type":"string","description":"Renderer dispatch key, e.g. `Box`. A new node needs one."},"props":{"type":"object","description":"The node's props, replaced wholesale — merge before sending. A visible string is always `content`, never `text` or `label`. Styling is Tailwind on `class`."},"hidden":{"type":"boolean","description":"Hide the node from the canvas without archiving it."},"archived":{"type":"boolean","description":"Set false to restore a node a previous batch removed. Each descendant is restored explicitly."}},"required":["id"]},"description":"Rows to create or update, applied in order."},"removes":{"type":"array","items":{"type":"string","format":"uuid","description":"Node UUID — a temp label is not one."},"description":"Node UUIDs to remove. A removal archives the node and its descendants, and an upsert with `archived` false restores it."}}},"dry_run":{"type":"boolean","description":"Preflight only — report issues without committing."},"idempotency_key":{"type":"string","description":"Retry-safety key; reuse the same key to safely retry an identical request."}},"required":["id","batch"]},"outputSchema":{"type":"object","properties":{"applied":{"type":"boolean"},"node_ids":{"type":"object","additionalProperties":{"type":"string","format":"uuid"}},"issues":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"in":{"type":"string"},"index":{"type":"integer"},"kind":{"type":"string"},"reason":{"type":"string"},"ref":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["in","index","kind","reason","ref"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"in":{"type":"string"},"index":{"type":"integer"},"kind":{"type":"string"},"reason":{"type":"string"},"ref":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["in","index","kind","reason","ref"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"warnings":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"class":{"type":"string"},"indices":{"type":"array","items":{"type":"integer"}},"reason":{"type":"string"}},"required":["kind","class","indices","reason"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"class":{"type":"string"},"indices":{"type":"array","items":{"type":"integer"}},"reason":{"type":"string"}},"required":["kind","class","indices","reason"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]}},"required":["applied","node_ids","issues","warnings"],"additionalProperties":false},"name":"orbit_edit_nodes","title":"Edit a workspace's nodes","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Edit a workspace's nodes"}},{"description":"Get one Orbit app by id (GET /api/v1/apps/<id>).","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"App id (UUID)."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"idea_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"archived":{"type":"boolean"},"slug":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"settings":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"icon":{"oneOf":[{"type":"string"},{"type":"null"}]},"themes":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"title":{"type":"string"},"updated_at":{"type":"string"},"preview":{"oneOf":[{"type":"string"},{"type":"null"}]},"locales":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"}},"required":["id","org_id","slug","title","icon","archived","settings","themes","locales","created_at","updated_at"],"additionalProperties":false},"name":"orbit_get_app","title":"Get app","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get app"}},{"description":"Get an app's theme vocabulary (GET /api/v1/apps/<app>/theme): the active color/font tokens plus the on-theme utility classes they generate (bg-/text-/border-<name>). These semantic tokens follow the app's light/dark theme; a raw Tailwind palette such as bg-slate-900 renders but is fixed to one theme, which is what orbit_edit_nodes reports as an off-theme-color warning.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id (UUID) from orbit_list_apps."}},"required":["app"]},"outputSchema":{"type":"object","properties":{"tokens":{"type":"object","additionalProperties":{}},"classes":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["items"]}]},"palettes":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["items"]}]},"note":{"type":"string"}},"required":["tokens","classes","palettes","note"],"additionalProperties":false},"name":"orbit_get_app_theme","title":"Get app theme","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get app theme"}},{"description":"Get one block by slug (GET /api/v1/blocks/<slug>) — its component name, declared props and composition rules.","inputSchema":{"type":"object","properties":{"slug":{"type":"string","description":"Block slug."}},"required":["slug"]},"outputSchema":{"type":"object","properties":{"description":{"type":"string"},"category":{"type":"string"},"anatomy":{"type":"object","additionalProperties":{}},"slug":{"type":"string"},"node":{"type":"string"},"component":{"type":"string"},"title":{"type":"string"},"kind":{"type":"string"},"body":{"type":"object","additionalProperties":{}},"props":{"anyOf":[{"type":"array","items":{}},{"type":"object","additionalProperties":{}}]}},"required":["slug","kind","title","description","props","anatomy","body"],"additionalProperties":false},"name":"orbit_get_block","title":"Get block","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get block"}},{"description":"Get a deployment by id (GET /api/v1/deployments/<id>). A deployment's phase is terminal once it has succeeded or failed; until then it is still building.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Deployment id."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"slug":{"oneOf":[{"type":"string"},{"type":"null"}]},"stage":{"oneOf":[{"type":"string"},{"type":"null"}]},"issues":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"workspace_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["kind","workspace_id","title","reason","message"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"workspace_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["kind","workspace_id","title","reason","message"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"started_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"completed_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"events":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"org_id":{"type":"string","format":"uuid"},"ip_address":{"oneOf":[{"type":"string"},{"type":"null"}]},"app_id":{"type":"string","format":"uuid"},"history":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"triggered_by":{"oneOf":[{"type":"string"},{"type":"null"}]},"outcome":{"oneOf":[{"type":"string"},{"type":"null"}]},"error_code":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["at","bundle_url","bundle_version","triggered_by","outcome","error_code"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"triggered_by":{"oneOf":[{"type":"string"},{"type":"null"}]},"outcome":{"oneOf":[{"type":"string"},{"type":"null"}]},"error_code":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["at","bundle_url","bundle_version","triggered_by","outcome","error_code"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"phase":{"type":"string"},"public_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"env":{"type":"string"},"last_heartbeat_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"provider_app_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"updated_at":{"type":"string"},"status":{"type":"string"},"id":{"type":"string","format":"uuid"},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"error":{"oneOf":[{"type":"object","properties":{},"additionalProperties":false},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"domain":{"oneOf":[{"type":"string"},{"type":"null"}]},"version":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","app_id","org_id","env","phase","status","issues","events","history","version","created_at","updated_at"],"additionalProperties":false},"name":"orbit_get_deployment","title":"Get deployment","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get deployment"}},{"description":"Read a deployment's event log (GET /api/v1/deployments/<id>/events). `after_seq` acts as a resume cursor, returning only newer events.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Deployment id."},"after_seq":{"type":"integer","description":"Only events after this seq."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_get_deployment_events","title":"Read deployment events","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Read deployment events"}},{"description":"Read a deployment's logs (GET /api/v1/deployments/<id>/logs).","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Deployment id."},"tail":{"type":"integer","description":"Number of trailing log lines."},"since":{"type":"string","description":"Only logs since this timestamp."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"logs":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"ts":{"type":"string"},"level":{"type":"string"},"line":{"type":"string"}},"required":["ts","level","line"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"string"},"level":{"type":"string"},"line":{"type":"string"}},"required":["ts","level","line"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"error":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["logs","error"],"additionalProperties":false},"name":"orbit_get_deployment_logs","title":"Read deployment logs","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Read deployment logs"}},{"description":"Read the motion registry; no /api/v1/ request. Returns the node prop motion is authored on, the preset and trigger names, the duration/easing token scale, and the named recipes.","inputSchema":{"type":"object","properties":{},"required":[]},"outputSchema":{"type":"object","properties":{"area":{"type":"string"},"authored_at":{"type":"string"},"presets":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["items"]}]},"triggers":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["items"]}]},"tokens":{"type":"object","additionalProperties":{}},"kinds":{"oneOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"note":{"type":"string"}},"required":["items"]}]},"recipes":{"oneOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"note":{"type":"string"}},"required":["items"]}]}},"required":["area","authored_at","presets","triggers","tokens","kinds","recipes"],"additionalProperties":false},"name":"orbit_get_motion","title":"Get motion vocabulary","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get motion vocabulary"}},{"description":"Get one recipe by slug (GET /api/v1/recipes/<slug>). The default `outline` view returns compact flat operations. Use `summary` for metadata only and `full` only when exact nested composition data is necessary.","inputSchema":{"type":"object","properties":{"slug":{"type":"string","description":"Recipe slug (from orbit_search_recipes)."},"view":{"type":"string","enum":["summary","outline","full"],"description":"Detail level. Default outline."}},"required":["slug"]},"outputSchema":{"type":"object","properties":{"slug":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"blocks":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["items"]}]},"composition":{"type":"object","additionalProperties":{}},"family":{"type":"string"},"category":{"type":"string"}},"required":["slug","kind","title","description","blocks"],"additionalProperties":false},"name":"orbit_get_recipe","title":"Get recipe","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get recipe"}},{"description":"Get a workflow execution by id (GET /api/v1/executions/<id>). Once terminal it carries `result` on success or `error` on failure.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Execution id."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"workspace_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"app_id":{"type":"string","format":"uuid"},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string"},"result":{},"id":{"type":"string","format":"uuid"},"error":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"seq":{"type":"integer"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","org_id","app_id","workspace_id","status","seq","created_at","updated_at"],"additionalProperties":false},"name":"orbit_get_run","title":"Get workflow run","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get workflow run"}},{"description":"Read an execution's event log (GET /api/v1/executions/<id>/events). `after_seq` acts as a resume cursor.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Execution id."},"after_seq":{"type":"integer","description":"Only events after this seq."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"node_id":{},"outputs":{},"result":{},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_get_run_events","title":"Read workflow run events","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Read workflow run events"}},{"description":"Get one board — the surface an app is thought out on: every card on it and every wire between them (GET /api/v1/apps/<app>/scratchpad, or GET /api/v1/scratchpads/<id>).\n\nName the app as `app` for the board that app is built on. Name the board as `id` for a board directly, which is how a board belonging to no app is read. Pass one of the two.\n\nA card holding a file names it in `content`, and `content_url` is where those bytes are served when the file is public — that url is what an image node's `src` holds.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id — reads the board that app is built on."},"id":{"type":"string","description":"Board id (from orbit_list_scratchpads) — reads that board, app or no app."}},"required":[]},"outputSchema":{"type":"object","properties":{"slug":{"oneOf":[{"type":"string"},{"type":"null"}]},"org_id":{"type":"string","format":"uuid"},"app_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"settings":{"type":"object","additionalProperties":{}},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"cards":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"y":{"type":"number"},"content_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"content":{"type":"object","additionalProperties":{}},"width":{"oneOf":[{"type":"number"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"z":{"type":"integer"},"status":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"x":{"type":"number"},"artifact_kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"height":{"oneOf":[{"type":"number"},{"type":"null"}]},"props":{"type":"object","additionalProperties":{}}},"required":["id","scratchpad_id","kind","content","props","x","y","z","created_at"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"y":{"type":"number"},"content_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"content":{"type":"object","additionalProperties":{}},"width":{"oneOf":[{"type":"number"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"z":{"type":"integer"},"status":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"x":{"type":"number"},"artifact_kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"height":{"oneOf":[{"type":"number"},{"type":"null"}]},"props":{"type":"object","additionalProperties":{}}},"required":["id","scratchpad_id","kind","content","props","x","y","z","created_at"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"links":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"from_id":{"type":"string","format":"uuid"},"label":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"to_port":{"type":"string"},"from_port":{"type":"string"},"idx":{"type":"integer"},"to_id":{"type":"string","format":"uuid"},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","scratchpad_id","from_id","to_id","kind","from_port","to_port","idx","created_at"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"from_id":{"type":"string","format":"uuid"},"label":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"to_port":{"type":"string"},"from_port":{"type":"string"},"idx":{"type":"integer"},"to_id":{"type":"string","format":"uuid"},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","scratchpad_id","from_id","to_id","kind","from_port","to_port","idx","created_at"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]}},"required":["id","org_id","app_id","settings","cards","links","created_at"],"additionalProperties":false},"name":"orbit_get_scratchpad","title":"Get a scratchpad","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get a scratchpad"}},{"description":"Read the shader registry; no /api/v1/ request. With no argument, returns a compact index of every shader kind. With `shader`, returns that kind's parameters, defaults, and presets.","inputSchema":{"type":"object","properties":{"shader":{"type":"string","description":"Exact shader kind, from the index. Omit for the index itself."}},"required":[]},"outputSchema":{"type":"object","properties":{"area":{"type":"string"},"authored_at":{"type":"string"},"kinds":{"oneOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"note":{"type":"string"}},"required":["items"]}]},"shader":{"type":"string"},"definition":{"type":"object","additionalProperties":{}},"params":{"oneOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"note":{"type":"string"}},"required":["items"]}]},"defaults":{"type":"object","additionalProperties":{}},"presets":{"oneOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"note":{"type":"string"}},"required":["items"]}]}},"required":["area","authored_at"],"additionalProperties":false},"name":"orbit_get_shaders","title":"Get shader vocabulary","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get shader vocabulary"}},{"description":"Read how much of an app is translated (GET /api/v1/apps/<app>/translations). One call answers all of it: `locales` names the languages the app serves, and with no `locale` argument `summary` carries a row per language with its `total`, `pending` and `run_status`.\n\nName a `locale` and the reply describes that one instead: `plan` is `{total, pending, orphans}`, `run` is its newest run, and `strings` holds the stored strings — each an authored English `source` and its `content`, with `status` `machine`, `reviewed` or `stale`. A `reviewed` string is a person's own wording and no run overwrites it.\n\nAdd `pending` and `strings` carries what the language still needs instead: the authored English with no translation yet, each with the `source_key` to submit it under and `content` null. That is the read for translating the app yourself — the keys go straight back to orbit_translate_app as `strings`.\n\nThis is also where a started run is watched: `run.status` moves queued → running → succeeded | failed, and `plan.pending` falls as strings land. `run_id` addresses one specific run rather than the language's newest.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id (UUID) from orbit_list_apps."},"locale":{"type":"string","description":"One language, e.g. `fr`. Omit for a summary of every language the app offers."},"pending":{"type":"boolean","description":"Return what the language still NEEDS instead of what it has — the authored English awaiting translation, each with the `source_key` to submit it under. Needs `locale`."},"status":{"type":"string","enum":["machine","reviewed","stale"],"description":"Only stored strings with this review status. Ignored with `pending`."},"run_id":{"type":"string","format":"uuid","description":"Report this exact run instead of the language's newest."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Max rows to fetch. 1-100. The tool result itself carries at most 25 items whatever this says — page with `offset` to read past that."},"offset":{"type":"integer","minimum":0,"description":"Results to skip (pagination)."}},"required":["app"]},"outputSchema":{"type":"object","properties":{"locales":{"type":"object","properties":{"active":{"type":"string"},"available":{"type":"array","items":{"type":"string"}},"glossary":{"type":"array","items":{"type":"string"}}},"required":["active","available","glossary"],"additionalProperties":false},"locale":{"oneOf":[{"type":"string"},{"type":"null"}]},"plan":{"oneOf":[{"type":"object","properties":{"total":{"type":"integer"},"pending":{"type":"integer"},"orphans":{"type":"integer"}},"required":["total","pending","orphans"],"additionalProperties":false},{"type":"null"}]},"run":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"locale":{"type":"string"},"status":{"type":"string","enum":["queued","running","succeeded","failed","cancelled"]},"attempt":{"type":"integer"},"max_attempts":{"type":"integer"},"error":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","locale","status","attempt","max_attempts","error"],"additionalProperties":false},{"type":"null"}]},"summary":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string"},"total":{"type":"integer"},"pending":{"type":"integer"},"orphans":{"type":"integer"},"run_status":{"oneOf":[{"type":"string","enum":["queued","running","succeeded","failed","cancelled"]},{"type":"null"}]}},"required":["locale","total","pending","orphans","run_status"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string"},"total":{"type":"integer"},"pending":{"type":"integer"},"orphans":{"type":"integer"},"run_status":{"oneOf":[{"type":"string","enum":["queued","running","succeeded","failed","cancelled"]},{"type":"null"}]}},"required":["locale","total","pending","orphans","run_status"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"strings":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"format":{"type":"string"},"locale":{"type":"string"},"content":{"oneOf":[{"type":"string"},{"type":"null"}]},"source":{"type":"string"},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"source_key":{"type":"string"},"status":{"oneOf":[{"type":"string","enum":["machine","reviewed","stale"]},{"type":"null"}]},"id":{"oneOf":[{"type":"string"},{"type":"null"}]},"context":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","locale","source_key","source","content","status","format","context","updated_at"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"format":{"type":"string"},"locale":{"type":"string"},"content":{"oneOf":[{"type":"string"},{"type":"null"}]},"source":{"type":"string"},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"source_key":{"type":"string"},"status":{"oneOf":[{"type":"string","enum":["machine","reviewed","stale"]},{"type":"null"}]},"id":{"oneOf":[{"type":"string"},{"type":"null"}]},"context":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","locale","source_key","source","content","status","format","context","updated_at"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["locales","locale","plan","run","summary","strings","limit","offset"],"additionalProperties":false},"name":"orbit_get_translations","title":"Read translations","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Read translations"}},{"description":"Get an org's wallet position (GET /api/v1/orgs/<org>/wallet) — balance, usable and refundable amounts in cents. `usable` is what a paid deployment can draw on.","inputSchema":{"type":"object","properties":{"org":{"type":"string","description":"Org id."}},"required":["org"]},"outputSchema":{"type":"object","properties":{"balance":{"type":"integer"},"usable":{"type":"integer"},"refundable":{"type":"integer"},"capacity":{"type":"integer"},"currency":{"oneOf":[{"type":"string"},{"type":"null"}]},"status":{"oneOf":[{"type":"string"},{"type":"null"}]},"dunning_since":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["balance","usable","refundable","capacity"],"additionalProperties":false},"name":"orbit_get_wallet","title":"Get wallet balance","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get wallet balance"}},{"description":"Get one window of a workspace's nodes (GET /api/v1/workspaces/<id>). The default `outline` view keeps each node's id, parent, component and user-visible props, and drops its styling and wiring; use `full` for an exact prop edit. Reads the first 25 nodes unless `limit` says otherwise. Every reply carries `node_count` and `truncated` — page with `offset` while `truncated` is true.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Workspace id."},"view":{"type":"string","enum":["outline","full"],"description":"Node detail. Default outline."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Max rows to fetch. 1-100. The tool result itself carries at most 25 items whatever this says — page with `offset` to read past that."},"offset":{"type":"integer","minimum":0,"description":"Results to skip (pagination)."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"archived":{"type":"boolean"},"limit":{"type":"integer"},"offset":{"type":"integer"},"org_id":{"type":"string","format":"uuid"},"root_node_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"app_id":{"type":"string","format":"uuid"},"settings":{"type":"object","additionalProperties":{}},"title":{"type":"string"},"updated_at":{"type":"string"},"nodes":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"idx":{"type":"integer"},"component":{"type":"string"},"props":{"type":"object","additionalProperties":{}},"hidden":{"type":"boolean"},"archived":{"type":"boolean"}},"required":["id","parent_id","idx","component","props","hidden","archived"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"idx":{"type":"integer"},"component":{"type":"string"},"props":{"type":"object","additionalProperties":{}},"hidden":{"type":"boolean"},"archived":{"type":"boolean"}},"required":["id","parent_id","idx","component","props","hidden","archived"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"truncated":{"type":"boolean"},"node_count":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","org_id","app_id","kind","title","settings","archived","root_node_id","created_at","updated_at","nodes","node_count","limit","offset","truncated"],"additionalProperties":false},"name":"orbit_get_workspace","title":"Get workspace","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Get workspace"}},{"description":"Wire one card on a board to another (POST /api/v1/scratchpads/<board>/links). `reference`, the default, records that one card informed the other. `input` compiles to a dependency a run reads. Both cards must be on the same board.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id — wires two cards on that app's board."},"scratchpad":{"type":"string","description":"Board id (from orbit_list_scratchpads) — wires two cards on that board. Pass this or `app`."},"from":{"type":"string","description":"Card id the wire leaves."},"to":{"type":"string","description":"Card id the wire enters."},"kind":{"type":"string","enum":["reference","input"],"description":"Wire kind. `reference` by default."},"label":{"type":"string","description":"What the wire means, shown on the board."},"idempotency_key":{"type":"string","description":"Retry-safety key; reuse the same key to safely retry an identical request."}},"required":["from","to"]},"outputSchema":{"type":"object","properties":{"from_id":{"type":"string","format":"uuid"},"label":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"to_port":{"type":"string"},"from_port":{"type":"string"},"idx":{"type":"integer"},"to_id":{"type":"string","format":"uuid"},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","scratchpad_id","from_id","to_id","kind","from_port","to_port","idx","created_at"],"additionalProperties":false},"name":"orbit_link_cards","title":"Link two cards","annotations":{"readOnlyHint":false,"destructiveHint":false,"title":"Link two cards"}},{"description":"List Orbit apps (GET /api/v1/apps). Scope with `org`; omit to use the token's default org.","inputSchema":{"type":"object","properties":{"org":{"type":"string","description":"Org id to scope the list."}},"required":[]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"idea_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"archived":{"type":"boolean"},"slug":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"settings":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"icon":{"oneOf":[{"type":"string"},{"type":"null"}]},"themes":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"title":{"type":"string"},"updated_at":{"type":"string"},"preview":{"oneOf":[{"type":"string"},{"type":"null"}]},"locales":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"}},"required":["id","org_id","slug","title","icon","archived","settings","themes","locales","created_at","updated_at"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_list_apps","title":"List apps","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"List apps"}},{"description":"List an app's deployments (GET /api/v1/apps/<app>/deployments).","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id to list deployments for."}},"required":["app"]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"slug":{"oneOf":[{"type":"string"},{"type":"null"}]},"stage":{"oneOf":[{"type":"string"},{"type":"null"}]},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"workspace_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["kind","workspace_id","title","reason","message"],"additionalProperties":false}},"started_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"completed_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"events":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},"org_id":{"type":"string","format":"uuid"},"ip_address":{"oneOf":[{"type":"string"},{"type":"null"}]},"app_id":{"type":"string","format":"uuid"},"history":{"type":"array","items":{"type":"object","properties":{"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"triggered_by":{"oneOf":[{"type":"string"},{"type":"null"}]},"outcome":{"oneOf":[{"type":"string"},{"type":"null"}]},"error_code":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["at","bundle_url","bundle_version","triggered_by","outcome","error_code"],"additionalProperties":false}},"phase":{"type":"string"},"public_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"env":{"type":"string"},"last_heartbeat_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"provider_app_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"updated_at":{"type":"string"},"status":{"type":"string"},"id":{"type":"string","format":"uuid"},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"error":{"oneOf":[{"type":"object","properties":{},"additionalProperties":false},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"domain":{"oneOf":[{"type":"string"},{"type":"null"}]},"version":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","app_id","org_id","env","phase","status","issues","events","history","version","created_at","updated_at"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_list_deployments","title":"List deployments","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"List deployments"}},{"description":"List the org's boards, most recently touched first (GET /api/v1/scratchpads). Each row says what a board is and what it belongs to; its cards and wires are not included.\n\nA board belongs to an app or to nobody. The one with no app is where a person thinks before an app exists, and this is the only place its id appears — every other board tool starts from an app.","inputSchema":{"type":"object","properties":{"org":{"type":"string","description":"Org id to scope the list. Omit to list across every org you belong to."}},"required":[]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"app_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"slug":{"oneOf":[{"type":"string"},{"type":"null"}]},"settings":{"type":"object","additionalProperties":{}},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","org_id","app_id","settings","created_at","updated_at"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_list_scratchpads","title":"List scratchpads","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"List scratchpads"}},{"description":"List an org's secrets (GET /api/v1/orgs/<org>/secrets) — metadata only; values are write-only and never returned by any endpoint.","inputSchema":{"type":"object","properties":{"org":{"type":"string","description":"Org id."}},"required":["org"]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"accessed_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"key_version":{"oneOf":[{"type":"integer"},{"type":"null"}]},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"status":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"provider":{"oneOf":[{"type":"string"},{"type":"null"}]},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","org_id","name","status"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_list_secrets","title":"List secrets","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"List secrets"}},{"description":"List an app's workspaces (GET /api/v1/apps/<app>/workspaces). Filter by `kind`.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id to list workspaces for."},"kind":{"type":"string","enum":["mockup","workflow","entity"],"description":"Filter by workspace kind."}},"required":["app"]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"title":{"type":"string"},"archived":{"type":"boolean"},"root_node_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","kind","title","archived","root_node_id","created_at","updated_at"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_list_workspaces","title":"List workspaces","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"List workspaces"}},{"description":"Screenshot an Orbit app (GET /api/v1/apps/<id>/preview.png). Renders the app's LIVE design-time state — as currently authored, not the last deploy — and returns a PNG image, so the result of an edit is visible without deploying. Defaults to the home page at 1280x800, which is the mode to use for reading copy or checking spacing. Set full_page only to judge overall layout: it captures the whole page, and a tall capture is downscaled hard before you see it, so text in it is not reliable.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"App id (UUID)."},"page":{"type":"string","description":"Page slug to render, e.g. \"/pricing\". Omit for the home page."},"width":{"type":"integer","description":"Viewport width in CSS px (default 1280)."},"height":{"type":"integer","description":"Viewport height in CSS px (default 800)."},"dpr":{"type":"integer","description":"Retina scale factor 1-3 (default 1)."},"full_page":{"type":"boolean","description":"Capture the whole page as a layout overview (default false). Bounded to 1280x8000; text in a tall capture is not legible."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"app":{"type":"string","format":"uuid"},"page":{"type":"string"}},"required":["app","page"]},"name":"orbit_preview_app","title":"Preview app screenshot","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Preview app screenshot"}},{"description":"Rename or archive a workspace (PATCH /api/v1/workspaces/<id>). `title` renames it; `archived` true archives and false restores. Archiving is reversible and archived workspaces stay readable. It changes the workspace itself and nothing inside it: a workspace's nodes are a separate resource, applied as a batch.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Workspace id."},"title":{"type":"string","description":"New title (1-200 chars)."},"archived":{"type":"boolean","description":"True to archive, false to restore."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"archived":{"type":"boolean"},"limit":{"type":"integer"},"offset":{"type":"integer"},"org_id":{"type":"string","format":"uuid"},"root_node_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"app_id":{"type":"string","format":"uuid"},"settings":{"type":"object","additionalProperties":{}},"title":{"type":"string"},"updated_at":{"type":"string"},"nodes":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"idx":{"type":"integer"},"component":{"type":"string"},"props":{"type":"object","additionalProperties":{}},"hidden":{"type":"boolean"},"archived":{"type":"boolean"}},"required":["id","parent_id","idx","component","props","hidden","archived"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"idx":{"type":"integer"},"component":{"type":"string"},"props":{"type":"object","additionalProperties":{}},"hidden":{"type":"boolean"},"archived":{"type":"boolean"}},"required":["id","parent_id","idx","component","props","hidden","archived"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"truncated":{"type":"boolean"},"node_count":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","org_id","app_id","kind","title","settings","archived","root_node_id","created_at","updated_at","nodes","node_count","limit","offset","truncated"],"additionalProperties":false},"name":"orbit_rename_workspace","title":"Rename or archive workspace","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Rename or archive workspace"}},{"description":"Search the block catalog (GET /api/v1/blocks). A block is one component that an app screen is built from. The catalog holds UI primitives and workflow units together. The `kind` filter separates them. `component` is a screen primitive. `node`, `integration` and `database` are workflow units.","inputSchema":{"type":"object","properties":{"q":{"type":"string","description":"Search term. BM25 over the catalog."},"kind":{"type":"string","enum":["component","node","integration","database","action","trigger"],"description":"`component` is a UI primitive; `node` / `integration` / `database` are workflow units; `action` / `trigger` are the operations an integration provides."},"node":{"type":"string","description":"Restrict to the actions/triggers of one node, e.g. `github`."},"category":{"type":"string","description":"Restrict to a palette category, e.g. `forms`, `layout`."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Max rows to fetch. 1-100. The tool result itself carries at most 25 items whatever this says — page with `offset` to read past that."},"offset":{"type":"integer","minimum":0,"description":"Results to skip (pagination)."}},"required":[]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"node":{"type":"string"}},"required":["slug","kind","title","description"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_search_blocks","title":"Search blocks","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Search blocks"}},{"description":"Search the stock-photo catalog (GET /api/v1/images). Each result carries an `attribution` string. The licence requires that string wherever the image appears. Each result also carries a `copy_space` value. That value names the side of the photo that is plain enough for headline text. A value of `none` means the photo is busy at every edge.","inputSchema":{"type":"object","properties":{"q":{"type":"string","description":"Search term. BM25 over title, description and keywords."},"category":{"type":"string","description":"Topic set: agency, ai, automotive, avatars, backgrounds, beauty, construction, creative, devtools, ecommerce, education, events, fintech, fitness, food, groceries, healthcare, home-services, logistics, marketing, nonprofit, people, pets, portraits, product, professional, realestate, restaurant, saas, sustainability, trades, travel, wedding, wellness. A sub-specialty (dental, legal, plumbing) is searchable via `q`, not here."},"role":{"type":"string","enum":["hero","feature","background","avatar","testimonial"],"description":"Placement: hero (top band) | feature (beside copy) | background (behind content) | avatar (a face) | testimonial (a person beside a quote)."},"orientation":{"type":"string","enum":["landscape","portrait","square"],"description":"Filter by orientation."},"copy_space":{"type":"string","enum":["left","right","top","bottom","center","none"],"description":"Only photos with room for headline text on this side."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Max rows to fetch. 1-100. The tool result itself carries at most 25 items whatever this says — page with `offset` to read past that."},"offset":{"type":"integer","minimum":0,"description":"Results to skip (pagination)."}},"required":[]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"role":{"oneOf":[{"type":"string"},{"type":"null"}]},"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"thumb":{"oneOf":[{"type":"string"},{"type":"null"}]},"category":{"oneOf":[{"type":"string"},{"type":"null"}]},"copy_space":{"oneOf":[{"type":"string"},{"type":"null"}]},"aspect":{"oneOf":[{"type":"string"},{"type":"null"}]},"slug":{"type":"string"},"color":{"oneOf":[{"type":"string"},{"type":"null"}]},"alt":{"oneOf":[{"type":"string"},{"type":"null"}]},"width":{"oneOf":[{"type":"integer"},{"type":"null"}]},"orientation":{"oneOf":[{"type":"string"},{"type":"null"}]},"src":{"oneOf":[{"type":"string"},{"type":"null"}]},"blurhash":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"attribution":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"height":{"oneOf":[{"type":"integer"},{"type":"null"}]}},"required":["slug","title","description","category","role","orientation","aspect","width","height","color","blurhash","copy_space","src","alt","attribution"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_search_images","title":"Search stock photos","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Search stock photos"}},{"description":"Search the recipe catalog (GET /api/v1/recipes) — prebuilt compositions of blocks, ranging from one section of a screen to a whole page. A recipe is reference material, not a thing to install: read one with orbit_get_recipe to see how a pattern is composed, then author the screen with orbit_edit_nodes.","inputSchema":{"type":"object","properties":{"q":{"type":"string","description":"Search term."},"kind":{"type":"string","enum":["section","page","example","template"],"description":"`section` and `page` are the composable patterns; `example` is a single-block variant; `template` is a whole-app starting point."},"family":{"type":"string","description":"Variant family, e.g. header."},"category":{"type":"string","description":"Broader bucket, e.g. marketing."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Max rows to fetch. 1-100. The tool result itself carries at most 25 items whatever this says — page with `offset` to read past that."},"offset":{"type":"integer","minimum":0,"description":"Results to skip (pagination)."}},"required":[]},"outputSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"family":{"type":"string"}},"required":["slug","kind","title","description"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]},"name":"orbit_search_recipes","title":"Search recipes","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Search recipes"}},{"description":"Stop a deployment (POST /api/v1/deployments/<id>/stop). The hosting provider tears the deployment down, the row's phase becomes `stopped` and its `public_url` is cleared, so the app goes offline and its address stops answering. The deployment row itself stays readable, and a fresh orbit_create_deployment puts the app back online.\n\nAn app cannot be archived while any of its deployments is up: that is the 409 `app-deployment-live` on orbit_archive_app, and a stop on each live deployment is what clears it.\n\nA 409 `deployment-not-provisioned` means the deployment never reached the provider, so there is nothing to tear down.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Deployment id (from orbit_list_deployments)."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"slug":{"oneOf":[{"type":"string"},{"type":"null"}]},"stage":{"oneOf":[{"type":"string"},{"type":"null"}]},"issues":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"workspace_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["kind","workspace_id","title","reason","message"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"workspace_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"message":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["kind","workspace_id","title","reason","message"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"started_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"completed_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"events":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"from":{"type":"object","additionalProperties":{}},"to":{"type":"object","additionalProperties":{}},"reason":{"oneOf":[{"type":"string"},{"type":"null"}]},"detail":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["seq","at","type","from","to","reason","detail"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"org_id":{"type":"string","format":"uuid"},"ip_address":{"oneOf":[{"type":"string"},{"type":"null"}]},"app_id":{"type":"string","format":"uuid"},"history":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"triggered_by":{"oneOf":[{"type":"string"},{"type":"null"}]},"outcome":{"oneOf":[{"type":"string"},{"type":"null"}]},"error_code":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["at","bundle_url","bundle_version","triggered_by","outcome","error_code"],"additionalProperties":false}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"at":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"triggered_by":{"oneOf":[{"type":"string"},{"type":"null"}]},"outcome":{"oneOf":[{"type":"string"},{"type":"null"}]},"error_code":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["at","bundle_url","bundle_version","triggered_by","outcome","error_code"],"additionalProperties":false}},"note":{"type":"string"}},"required":["items"]}]},"phase":{"type":"string"},"public_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"env":{"type":"string"},"last_heartbeat_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"provider_app_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"updated_at":{"type":"string"},"status":{"type":"string"},"id":{"type":"string","format":"uuid"},"bundle_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"error":{"oneOf":[{"type":"object","properties":{},"additionalProperties":false},{"type":"null"}]},"bundle_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"domain":{"oneOf":[{"type":"string"},{"type":"null"}]},"version":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","app_id","org_id","env","phase","status","issues","events","history","version","created_at","updated_at"],"additionalProperties":false},"name":"orbit_stop_deployment","title":"Stop deployment","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Stop deployment"}},{"description":"Store your own translations for one of an app's languages (POST /api/v1/apps/<app>/translations). `strings` is `{source_key: text}`, and the keys come from orbit_get_translations with `pending` — read the authored English, translate it, send it back. The strings are stored exactly as sent: no model is asked, nothing is spent, and the org needs no AI provider connected.\n\nThe language must already be on the app's `available` list — add it with orbit_update_app first, or the call is refused with 422 `locale-not-offered`. The app's own authored language is refused too: its pages already serve that text.\n\nA key the app's text no longer hashes to comes back in `unknown` rather than being stored, and a string a person reviewed is left alone. `pending` in the reply is re-counted from the app itself, so it is what the language still needs after this call rather than arithmetic on what was sent. Sending the same strings again updates the same rows, so a repeat is safe.\n\nPass `model` to record who wrote them. Rows are stored as `machine` with that provenance, so a person's later correction still wins. The translations reach the public when the app is next deployed.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id (UUID) from orbit_list_apps."},"locale":{"type":"string","description":"A language from the app's `available` list, e.g. `fr`."},"strings":{"type":"object","description":"The translations, keyed by `source_key`: `{\"4171546eb9a0ffb1\": \"Bienvenue\"}`. Read the keys with orbit_get_translations using `pending`."},"model":{"type":"string","description":"Who wrote these translations — recorded on each row as its only trace of provenance. Pass your own model id."}},"required":["app","locale","strings"]},"outputSchema":{"type":"object","properties":{"run_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"stored":{"type":"integer"},"unknown":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["items"]}]},"locale":{"type":"string"},"status":{"type":"string","enum":["queued","running","succeeded","failed","cancelled"]},"total":{"type":"integer"},"pending":{"type":"integer"}},"required":["run_id","stored","unknown","locale","status","total","pending"],"additionalProperties":false},"name":"orbit_translate_app","title":"Translate app","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Translate app"}},{"description":"Restore an archived Orbit app (POST /api/v1/apps/<id>/unarchive).","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"App id (UUID)."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"idea_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"archived":{"type":"boolean"},"slug":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"settings":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"icon":{"oneOf":[{"type":"string"},{"type":"null"}]},"themes":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"title":{"type":"string"},"updated_at":{"type":"string"},"preview":{"oneOf":[{"type":"string"},{"type":"null"}]},"locales":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"}},"required":["id","org_id","slug","title","icon","archived","settings","themes","locales","created_at","updated_at"],"additionalProperties":false},"name":"orbit_unarchive_app","title":"Restore app","annotations":{"readOnlyHint":false,"destructiveHint":false,"title":"Restore app"}},{"description":"Change an app's own fields (PATCH /api/v1/apps/<id>): `title`, `icon`, `description`, `preview`, `settings`, `themes`, `locales`. Send only what changes; anything omitted is left alone, and a field the api does not own is dropped rather than stored.\n\n`settings` and `themes` REPLACE the stored map, so merge client-side before sending one. `locales` is the exception and merges, because its keys have different writers: `active` is the language the app is authored in, `available` are the other languages it serves, `glossary` are names a translator must leave alone. Sending `locales: {\"available\": [\"fr\", \"pt-BR\"]}` adds those two languages and keeps the rest of the map.\n\nA language code is BCP-47 in canonical case — `fr`, `pt-BR`, `zh-Hans`. An unusable one is refused with 422 `invalid-locale` naming it, and nothing is stored. Adding a language does not translate anything; translate the strings yourself and store them with orbit_translate_app.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"App id (UUID) from orbit_list_apps."},"title":{"type":"string","description":"Human-readable app name (1-200 chars)."},"icon":{"type":"string","description":"Single-glyph emoji icon."},"description":{"type":"string","description":"Short blurb."},"preview":{"type":"string","description":"Preview image url."},"settings":{"type":"object","description":"App-level settings. Replaces the stored map."},"themes":{"type":"object","description":"Theme catalog. Replaces the stored map."},"locales":{"type":"object","description":"The languages the app serves — `{\"available\": [\"fr\"]}`. Merges over the stored map rather than replacing it."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"idea_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"archived":{"type":"boolean"},"slug":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"settings":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"icon":{"oneOf":[{"type":"string"},{"type":"null"}]},"themes":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"title":{"type":"string"},"updated_at":{"type":"string"},"preview":{"oneOf":[{"type":"string"},{"type":"null"}]},"locales":{"oneOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"}},"required":["id","org_id","slug","title","icon","archived","settings","themes","locales","created_at","updated_at"],"additionalProperties":false},"name":"orbit_update_app","title":"Update app","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Update app"}},{"description":"Change what a card holds, where it sits, or both (PATCH /api/v1/cards/<id>). Send only the fields that change: one left out stays as it is, and one carrying null is cleared.\n\nA card's content and its layout advance on separate revisions, so rewriting a card and moving it are two writes that cannot overwrite one another — a person dragging the card keeps their position while the text changes under it.\n\n`archived` true takes the card off the board and false puts it back. Nothing is deleted, so a removal is recoverable, and the wires touching the card go with it.","inputSchema":{"type":"object","properties":{"y":{"type":"number","description":"Board position."},"archived":{"type":"boolean","description":"True removes the card from the board, false restores it."},"content":{"type":"object","description":"Kind-specific payload, replaced wholesale — merge before sending."},"width":{"type":"number"},"title":{"type":"string","description":"The card's heading."},"z":{"type":"integer","description":"Stacking order."},"status":{"type":"string","enum":["draft","ready","failed","accepted"],"description":"How the card's last run ended, and whether somebody approved what it holds."},"id":{"type":"string","description":"Card id (from orbit_get_scratchpad)."},"x":{"type":"number","description":"Board position."},"height":{"type":"number"},"props":{"type":"object","description":"Presentation options, replaced wholesale."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"y":{"type":"number"},"content_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"content":{"type":"object","additionalProperties":{}},"width":{"oneOf":[{"type":"number"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"z":{"type":"integer"},"status":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"x":{"type":"number"},"artifact_kind":{"oneOf":[{"type":"string"},{"type":"null"}]},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"height":{"oneOf":[{"type":"number"},{"type":"null"}]},"props":{"type":"object","additionalProperties":{}}},"required":["id","scratchpad_id","kind","content","props","x","y","z","created_at"],"additionalProperties":false},"name":"orbit_update_card","title":"Edit or remove a card","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Edit or remove a card"}},{"description":"Relabel a wire, change what kind it is, or take it off the board (PATCH /api/v1/links/<id>). `reference` records that one card informed another; `input` compiles to a dependency a run reads.\n\nA wire's endpoints are fixed. Joining two different cards is a different wire, so remove this one with `archived` and make that one with orbit_link_cards.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Link id (from orbit_get_scratchpad)."},"kind":{"type":"string","enum":["reference","input"]},"label":{"type":"string","description":"What the wire means, shown on the board."},"idx":{"type":"integer","description":"Order among the wires sharing a port."},"props":{"type":"object","description":"Presentation options, replaced wholesale."},"archived":{"type":"boolean","description":"True removes the wire, false restores it."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"from_id":{"type":"string","format":"uuid"},"label":{"oneOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"to_port":{"type":"string"},"from_port":{"type":"string"},"idx":{"type":"integer"},"to_id":{"type":"string","format":"uuid"},"scratchpad_id":{"type":"string","format":"uuid"},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","scratchpad_id","from_id","to_id","kind","from_port","to_port","idx","created_at"],"additionalProperties":false},"name":"orbit_update_link","title":"Edit or remove a link","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Edit or remove a link"}},{"description":"Rename the board or change its settings (PATCH /api/v1/scratchpads/<id>). `archived` true takes the whole board off the shelf and false puts it back; everything on it stays readable either way.\n\nThis changes the board itself and nothing on it — a card or a wire is edited by its own id.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Scratchpad id (from orbit_get_scratchpad)."},"title":{"type":"string","description":"What the board is called."},"description":{"type":"string","description":"What the board is for."},"settings":{"type":"object","description":"Replaced wholesale — merge before sending."},"archived":{"type":"boolean","description":"True archives the board, false restores it."}},"required":["id"]},"outputSchema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"app_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"title":{"oneOf":[{"type":"string"},{"type":"null"}]},"slug":{"oneOf":[{"type":"string"},{"type":"null"}]},"settings":{"type":"object","additionalProperties":{}},"created_at":{"oneOf":[{"type":"string"},{"type":"null"}]},"updated_at":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","org_id","app_id","settings","created_at","updated_at"],"additionalProperties":false},"name":"orbit_update_scratchpad","title":"Rename or archive a scratchpad","annotations":{"readOnlyHint":false,"destructiveHint":true,"title":"Rename or archive a scratchpad"}},{"description":"Verify an app from GET /api/v1/apps/<app>/workspaces and GET /api/v1/workspaces/<id> without returning full node trees. Checks roots, the `/` home route, duplicate routes, and truncated reads. Returns compact issues.","inputSchema":{"type":"object","properties":{"app":{"type":"string","description":"App id to verify."}},"required":["app"]},"outputSchema":{"type":"object","properties":{"valid":{"type":"boolean"},"issues":{"oneOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"note":{"type":"string"}},"required":["items"]}]},"workspaces":{"type":"integer"},"nodes":{"type":"integer"},"routes":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["items"]}]}},"required":["valid","issues","workspaces","nodes","routes"],"additionalProperties":false},"name":"orbit_verify_app","title":"Verify app structure","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Verify app structure"}},{"description":"Show the authenticated Orbit identity (GET /api/v1/me) — the caller's profile and the orgs it belongs to. Confirms the token is valid.","inputSchema":{"type":"object","properties":{},"required":[]},"outputSchema":{"type":"object","properties":{"active_account_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"email":{"type":"string"},"first_name":{"type":"string"},"settings":{"oneOf":[{"type":"object","properties":{},"additionalProperties":false},{"type":"null"}]},"updated_at":{"type":"string"},"id":{"type":"string","format":"uuid"},"active_org_id":{"oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"last_name":{"oneOf":[{"type":"string"},{"type":"null"}]},"image":{"oneOf":[{"type":"string"},{"type":"null"}]},"created_at":{"type":"string"}},"required":["id","email","first_name","settings","created_at","updated_at"],"additionalProperties":false},"name":"orbit_whoami","title":"Who am I","annotations":{"readOnlyHint":true,"destructiveHint":false,"title":"Who am I"}}],"prompts":[{"description":"Deploy an existing Orbit app and watch it to completion.","arguments":[{"name":"app","description":"The app id (or name) to deploy.","required":true},{"name":"env","description":"Target env: dev | uat | prod (default dev).","required":false}],"name":"deploy_app"},{"description":"Plan and build a new Orbit app from an idea, end to end with the orbit_* tools.","arguments":[{"name":"idea","description":"What the app should be (e.g. 'a landing page for a coffee subscription').","required":true},{"name":"deploy","description":"\"true\" to also deploy the app once content is ready.","required":false}],"name":"scaffold_app"}],"resources":[]}