---
name: build-with-buildra
description: Build, revise, preview, and publish apps in a person's Buildra account through its remote MCP server. Use when the person asks to create an app with Buildra or continue an existing Buildra project.
metadata:
  author: Buildra
  version: "1.0.0"
---

# Build with Buildra

Connect to `https://mcp.buildra.dev/mcp` using Streamable HTTP. The person signs
in at `https://app.buildra.dev` and approves the client. Authorization is issued
by `https://api.buildra.dev`; resource metadata is at
`https://mcp.buildra.dev/.well-known/oauth-protected-resource`.
Agents cannot sign up, create another account, or use a client-credentials grant.

Connection instructions: <https://buildra.dev/docs/agents>.

## Start or resume

Use the connected server's `tools/list`: only tools allowed by the granted scopes
are listed. Read each tool's current input schema before calling it.

- For an existing project, use `list_projects` and `get_project`. Resume its
  session instead of creating a duplicate project.
- If `get_credits` is available, check the balance and tier before starting work.
  Creating a project starts its first build turn and spends the person's credits.
  Each `send_message` starts or queues another turn and also spends credits.
- For a new project, call `create_project` with a concrete `prompt` (at most
  8,000 characters) and an optional title. Let Buildra choose a template unless
  the person needs a specific one; `list_templates` lists the choices. `scratch`
  is the fallback when classification is unsure.
- Save the returned `projectId`, `sessionId`, and `turnId`. The initial prompt is
  already running: do not send it again with `send_message`.
- Use a stable `idempotencyKey` for each logical create or message request. Reuse
  that key when retrying the same request after a transport failure; use a new key
  for a new instruction. Repeated sends with fresh keys can spend credits twice.

## Wait and answer

Call `wait_for_turn` with `projectId` and the returned `sessionId`. The default
wait is 45 seconds; `timeoutSeconds` can be at most 55 (the common MCP client
request timeout is 60 seconds). While you keep calling it, the project's runtime
is kept awake. Handle its `state`:

| State | Next action |
| --- | --- |
| `running` | The wait timed out while the build continues. Call `wait_for_turn` again for the same project/session. Do not restart the build. |
| `waiting_for_answer` | Read `pendingQuestion.questions`. When options carry design artboards, each option has a `previewUrl` and, when the server could render it, the result also contains one image per option (labelled by option). **Show the person the images, or the links when there are no images, and let them choose.** Obtain any missing preference, then call `answer_question` with the returned `rpcId` and wait again. |
| `ended` | Inspect `endedReason` and `lastAssistantText`. The answer carries `preview` (`url`, `expiresAt`) for web, API and phone projects and, for web projects, a screenshot image of the built app: **give the person the preview link and show the screenshot.** A turn that ended `blocked` hit the per-turn token budget; `interrupted` means it stopped for a question or a cancel. An ended turn does not by itself prove the app works. |
| `idle` | No active turn is available. Inspect `get_project` and `get_transcript` before deciding whether another message is needed. |

**An unanswered question leaves the turn waiting indefinitely.** Repeated polling
does not answer it. Preserve the question IDs and option values returned by the
server. The answer shape is:

```json
{
  "projectId": "<returned projectId>",
  "rpcId": "<pendingQuestion.rpcId>",
  "answers": [
    { "id": "<returned question id>", "selected": [], "custom": "Use the preference the person supplied." }
  ]
}
```

Use `selected` for offered choices or `custom` for free text. When the person has
delegated a choice and has no preference, use `selected: []` with
`custom: "No preference, you decide."`. Do not invent a preference they have not
delegated. `answer_question` and polling do not start another billable build turn.

To inspect details, use `get_transcript` and advance `afterSeq` with `nextSeq`
until `done`. Use `stop_turn` if the person asks to cancel. For a revision, call
`send_message` with the same `projectId`, then repeat the wait/answer loop.

## Preview and publish

After the turn ends, call `get_preview` and inspect the returned link when your
client can access it. Report checks you actually performed.

- `web` and `api` projects can return a share URL. It expires after 30 minutes by
  default (`ttlMinutes` accepts at most 60); request a new link after expiry.
- `phone` projects can also return `expoUrl` when the runtime provides one.
- **`terminal` and `none` projects have no preview URL.** Read the returned `note`
  and use the transcript/status to report the result. Never construct a URL.

If publishing is part of the person's request, call `publish`. Otherwise show
the preview and obtain their decision before making it public. A successful
`publish` request is accepted asynchronously (202); it is not a finished deploy.
Check `get_publication` until its status reports success or failure. Share only
the returned `url`, normally a `*.buildra.page` address. On failure, inspect
`lastError`; do not claim a live site. `not-publishable` means that project cannot
be published through this tool. Publishing remains subject to the account's
hosting/project limits; it does not start an AI build turn.

## Limits and recovery

The person's credit balance and per-turn spending cap still apply. Each approved
agent connection also has a daily build-turn ceiling: **Free 30, Pro 300**, reset
on the UTC day. This is a ceiling on turns, not free credits. The service's default
rate limit is 60 tool calls per minute per connection.

- `agent-daily-limit`: stop starting turns. Report `limit`, `used`, and `resetsAt`
  when supplied; do not reconnect to bypass the ceiling.
- `out-of-credits`: stop paid work and use `get_credits` to report the balance and
  returned `topUpUrl`, if that tool is granted. The person handles billing.
- `insufficient_scope`: explain the missing permission and let the person
  authorize it. Do not substitute another account or credential.
- `invalid_token`: reconnect through the client's OAuth flow. Revoked access
  cannot be recovered by retrying the same token.
- A rate limit or transient transport error: respect the retry delay and reuse
  the same idempotency key for the same mutation. If it keeps failing, report
  the last state and error instead of starting repeated billable turns.

The person can revoke access at
<https://app.buildra.dev/settings?tab=agents> (Settings → Connected agents).
Revocation blocks subsequent authorized requests and refreshes; it does not
delete projects or undo a publication.
