# MCP tools

URL: https://briq.cloud/docs/mcp/tools

> Every tool the briq MCP server exposes, with input, output and an example call.

The server is at `https://api.briq.cloud/mcp`. Tools mirror the [REST API](https://briq.cloud/docs/api/overview).
Every result about a briq ends with its cost line:

```text
bq_7kq2m9x1p4ab db (postgres:16) running · …internal · cost so far … · sleeps at 18:42 UTC unless used
```

## briq\_run

Create and start a briq from a recipe or an image. Returns once it is ready: its healthcheck
passes, or without one its process has started.

| Field                                | Notes                                                                                                                                                                                                                                                                                             |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `recipe` or `image`                  | `recipe` names a [cookbook](https://briq.cloud/cookbook) entry; `image` is any public OCI image                                                                                                                                                                                                                     |
| `params`                             | Recipe parameters. A language recipe takes your code here: `params.files`, `params.env`. A recipe that keeps data takes `diskGb`, its volume's size                                                                                                                                               |
| `expose`                             | `"private"` for a URL only whoever has it can open, `"public"` for anyone. Publishes the recipe's front door, or the image's single port, and returns `URL`                                                                                                                                       |
| `name`                               | Unique in the stack. Default: the recipe's briq name, or the image name                                                                                                                                                                                                                           |
| `stack`                              | Default `default`; created if missing                                                                                                                                                                                                                                                             |
| `env`                                | Image only. A string, `{ "secret": "NAME" }` for a generated secret, or `{ "secret": "NAME", "value": "…" }` for a credential you already have. Plain values show in status: credentials always go as secrets                                                                                     |
| `cmd`, `entrypoint`, `ports`, `size` | Image only. Size `nano`, `small` (default), `medium`, `large`                                                                                                                                                                                                                                     |
| `files`                              | Image only. Absolute path → text or `{ "base64": "…" }`, written before the process starts. 64 files, 256 KB in all                                                                                                                                                                               |
| `volume`                             | Image only. `{ mount, gb? }`: a durable disk for data you cannot lose, 2 GB unless `gb` says more                                                                                                                                                                                                 |
| `healthcheck`                        | Image only. `{ cmd, timeoutMs? }`: `briq_run` waits until it passes                                                                                                                                                                                                                               |
| `sleep`                              | When it goes to sleep: after this long without use, a string such as `"30m"`, `"3h"`, `"7d"`, or `"never"` (always on, Pro plan and above). Never a number. Default `"1h"` on briq.cloud; with a recipe, every briq it makes gets the same. See [Sleep](https://briq.cloud/docs/concepts/lifecycle-and-sleep#sleep) |
| `wait`                               | Default `true`: return once ready, for up to two minutes. A briq still `creating` then is on its way: check `briq_status`                                                                                                                                                                         |

With `recipe`, the image-only fields are refused: pass them in `params`, as the recipe's
[cookbook](https://briq.cloud/cookbook) page lists them.

**Output**: the briqs (id, state, host, endpoints), the `outputs` (a recipe's connection strings,
secrets briq generated, `URL`), the cost line. A secret you passed in is not printed back.

```text
briq_run({ recipe: "postgres", params: { version: "16" } })
→ bq_7kq2m9x1p4ab db (postgres:16) running · …internal · cost so far … · sleeps at 18:42 UTC unless used
  outputs:
    DATABASE_URL=postgres://postgres:…@…internal:5432/app
```

## briq\_exec

Run a command in a briq. **Input**: `{ briq, cmd: string[], timeoutMs?, stdin? }`. `cmd` is an
argv run without a shell: `["psql", "-c", "select 1"]`, not `["psql -c 'select 1'"]` (that looks
for a program named after the whole line, and fails with exit 127); for pipes, globs, `&&` or
`$VARS`, pass `["sh", "-c", "…"]`. `timeoutMs`
60000 by default, at most 600000; keep the command under about 16 KB and send bigger input as
`stdin`. **Output**: exit code, stdout and stderr (stdout truncated at 32 KB). A sleeping briq is
woken first, so the call is slower. On a stopped briq, an error that says why: `invalid_state`
(409) after a stop or an exit (with the code), `quota_exceeded` or `payment_required` (402) while
a limit holds.

```text
briq_exec({ briq: "bq_7kq2m9x1p4ab", cmd: ["psql", "-U", "postgres", "-c", "select count(*) from orders"] })
→ exit 0
  count
  -----
  1284
  cost so far … · sleeps at 18:42 UTC unless used
```

## briq\_logs

**Input**: `{ briq, since?, limit? }` (`since` is the `next` cursor of a previous call, `limit` up
to 1000). **Output**: log lines and `next`.

## briq\_files\_put / briq\_files\_get

Write or read one file, base64, up to 1 MB each way. **Input**: `{ briq, path, contentBase64 }` /
`{ briq, path }`. A larger file is refused with a `validation` error that says so, in both
directions: move it from inside the briq instead (`git clone`, `curl`), or read part of it with
`briq_exec`. A 1 MB write takes up to half a minute. Writing one of the briq's
[boot files](https://briq.cloud/docs/concepts/briq#files) answers with a `warning`: the spec writes it again at the
next start.

A write answers with the file's `sha256`, and `verified: true` when the briq computed the same
digest from its disk (its image has `sha256sum`): compare it with your copy's. Line breaks in the
base64 are ignored; base64 whose length shows it was cut short is refused with a `validation`
error, rather than written and found broken later.

```text
briq_files_put({ briq: "bq_7kq2m9x1p4ab", path: "/seed.sql", contentBase64: "aW5zZXJ0…" })
briq_exec({ briq: "bq_7kq2m9x1p4ab", cmd: ["psql", "-U", "postgres", "-f", "/seed.sql"] })
```

## briq\_expose

Give the briq its HTTPS URL, on one port, or a TCP endpoint. **Input**: `{ briq, port,
protocol?, mode?, rotate? }`. `mode` is
`private`, a URL only whoever has it can open (it carries a secret checked before any request
reaches the briq), or `public`, open to anyone. Without `mode`, a URL the briq already has keeps
its mode, and a first URL is `public`.

* A briq has one URL. Its front door (the recipe's, or a briq's only port) publishes at once.
  Another port moves the URL there and restarts the machine: the processes start over, files on
  disk are kept, and the result carries a `note` saying so.
* `rotate: true` gives a private URL a new token: the URL stays, links and cookies with the old
  token stop working. A public URL has none to rotate.
* A briq declares at most 32 ports; exposing a new one past that is refused.
* `protocol` is `http` by default. A database protocol (`postgres`, `mysql`, `redis`, `mongodb`,
  `amqp`, `bolt`, `grpc`) makes a TCP endpoint: reachable from outside over TLS, for any
  briq. A recipe's database port refuses `http` and names its protocol. `mode` does not apply: the
  password is the gate. See
  [Connect to a database from outside](https://briq.cloud/docs/guides/connect-to-a-database-from-outside).

See [Expose a preview URL](https://briq.cloud/docs/guides/expose-a-preview-url).

```text
briq_expose({ briq: "bq_9a2fk3m8q1zt", port: 3000, mode: "private" })
→ exposed port 3000 (private): https://api-k7x3.briq.run/?briq_token=…
```

## briq\_fork

Copy a briq, or a whole stack, before a change you might want to undo. See
[Forks](https://briq.cloud/docs/concepts/fork).

| Field                 | Notes                                                                 |
| --------------------- | --------------------------------------------------------------------- |
| `briq` or `stack`     | `briq` forks one briq; `stack` alone forks the whole stack            |
| `name`                | One briq: the fork's name. Default `<name>-fork`                      |
| `stack` (with `briq`) | One briq: the stack to put the fork in. Default: the same             |
| `into`                | Whole stack: the new stack. Default `<stack>-fork`                    |
| `sleep`               | Default: the source's. A window longer than the key allows is refused |
| `wait`                | Default `true`                                                        |

**Output**: the forks, what each copied (`disk` or `config`), outputs pointing at the forks, the
cost line.

## briq\_stop / briq\_start / briq\_destroy

**Input**: `{ briq }`. Stop keeps the disk, volume and every other file; destroy removes it. Each
returns once the move lands (up to 30 s); a `stopping`, `starting` or `destroying` state means it
is still on its way, and calling again is safe. A briq stopped by `briq_stop` or its own exit stays
stopped until `briq_start`. One stopped by a limit sleeps once the limit clears. A sleeping one
needs neither: the next call or visit wakes it.

## briq\_set\_sleep

Change when a briq goes to sleep. **Input**: `{ briq, sleep, stack? }`: `sleep` as in `briq_run`,
`stack: true` for every briq of its stack. A running briq sleeps the new window from now; a
sleeping one keeps sleeping until its next use. Not needed for ordinary work: every call and every
visit already pushes the sleep back.

```text
briq_set_sleep({ briq: "bq_7kq2m9x1p4ab", sleep: "3h" })
→ bq_7kq2m9x1p4ab db (postgres:16) running · …internal · cost so far … · sleeps at 21:12 UTC unless used
```

## briq\_list / briq\_status

**Input**: `{ stack?, all? }` / `{ briq }`. **Output**: state (`running`, `sleeping`, `stopped`…),
image, host, cost and when it sleeps per briq; for one, also why it stopped (`stoppedReason`), its last process exit (`lastExit`),
endpoints, env (secrets masked) and boot files (path and size).

## briq\_quota

**Input**: `{}`. **Output**: spend today against the daily cap, credits left, live briqs and how
many more are allowed, allowed sizes, the longest sleep. The spend and the live briqs that count toward the
limit are this credential's own: an agent that signed in again has a new one, so briqs it started
before show in the team's count (`teamLiveBriqs`) and in `briq_list`, not in its own.

## briq\_catalog

**Input**: `{ name? }`. **Output**: every recipe with a one-line description; with `name`, every
parameter it takes (type, default, what it does), its outputs and briqs.

## briq\_docs

**Input**: `{ page? }`. Without `page`, the index of every docs, cookbook and legal page
([`/llms.txt`](https://briq.cloud/llms.txt)); with it, that page as Markdown: `concepts/fork`, `cookbook/postgres`,
`legal/dpa`.

## briq\_feedback

**Input**: `{ topic: "bug" | "idea" | "question", message }`. Emails the people who build briq.
For when briq does not do what these docs say, an error has no explanation (a 5xx), the docs miss
something, or there is an idea. The answer goes by email to the person who connected the agent
(or the team's owner), who also gets a copy; the team's audit log records it as `support.send`.
**Output**: the request id to quote, and who will get the answer. Five per ten minutes.

## Resources and prompts

* `briq://recipes/<name>`: a recipe's parameters, outputs and briqs.
* `briq://docs/<page>`: every page `briq_docs` can read.
* Prompt `briq_getting_started`: how to use the tools well (prefer recipes, reuse a stack, read
  the cost line, destroy what you created).

## Transport and auth

Streamable HTTP, stateless. Authentication follows the
[MCP authorization spec](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization):
a request without credentials gets `401` with `WWW-Authenticate` pointing at
`https://api.briq.cloud/.well-known/oauth-protected-resource/mcp`. The authorization server
(`https://app.briq.cloud/api/auth`) supports Client ID Metadata Documents, dynamic client
registration, PKCE (`S256`) and the `briq` and `offline_access` scopes. Access tokens last 30
days; refresh tokens 30 days from their last use, and each one works once. A client that signs in
with a device code (RFC 8628) gets a refresh token too, whatever scopes it asked for; a code
request that names no scope gets the ones the client registered. The code waits 15 minutes for
approval. A sign-in request refused for coming too often (`429`) says how
long to wait: `Retry-After`, and `retry_after_seconds` in the body. An API key
(`Authorization: Bearer bq_live_…`) works too.
