# MCP tools

> The tools the Rytiv MCP server offers, with their parameters and annotations, generated from the server's tool table.

The Rytiv MCP server at `https://api.rytiv.app/v1/mcp` answers `tools/list` with these 11 tools. This page is generated from the same table, so names, parameters and limits are exactly what your agent sees. To connect an agent, see the [quickstart](https://docs.rytiv.com/quickstart.md).

Every tool acts as the organization of the token that signed the request. A name that belongs to another organization is answered exactly like a name that does not exist.

In Claude Code, with the server added under the name `rytiv`, every tool is called `mcp__rytiv__<tool>`, for example `mcp__rytiv__list_apps`.

| Tool | What it does | Effect |
| --- | --- | --- |
| `search_docs` | Search the Rytiv documentation | reads |
| `list_apps` | List apps | reads |
| `deploy_app` | Deploy an app | changes or replaces |
| `get_logs` | Read the logs of an app | reads |
| `set_env` | Set environment variables | changes or replaces |
| `create_postgres` | Create a Postgres database | creates |
| `create_branch` | Branch a Postgres database | creates |
| `execute_sql` | Run SQL against a Postgres database | changes or replaces |
| `computer_create` | Create a computer | creates |
| `computer_exec` | Run a command in a computer | changes or replaces |
| `computer_snapshot` | Snapshot a computer | creates |

> **Annotations are hints:** `readOnlyHint`, `destructiveHint`, `idempotentHint` and `openWorldHint` tell your client which calls to confirm with you. `openWorldHint` is `false` on every tool: none of them reaches outside your own organization on Rytiv.

## `search_docs`

**Search the Rytiv documentation.** Answers questions about how Rytiv works: apps, machines, deploys, Postgres and its branches, computers, secrets, limits, EU data residency. Use it before guessing a field name or a limit. Local knowledge base, no request leaves Rytiv.

### Input

- `query` (string, optional, at most 200 characters): What you want to know, in words. Empty returns the table of contents.
- `limit` (integer, optional, 1 to 20): How many entries to return (1 to 20, default 5).

### Output

- `entries` (array of object, always)
- `query` (string, if present)

### Annotations

`readOnlyHint`: `true`, `openWorldHint`: `false`

## `list_apps`

**List apps.** Lists the apps of your org with the URL each one answers on. This is the entry point: an app is what a machine, a database and a deploy belong to.

### Input

- `label` (array of string, optional, 0 to 8 items): Optional label filter, e.g. [`role=db`]. Several terms are ANDed.

### Output

- `apps` (array of object, always)

### Annotations

`readOnlyHint`: `true`, `openWorldHint`: `false`

## `deploy_app`

**Deploy an app.** Deploys an image to an app and answers with the URL it is reachable on. A rolling deploy: a new machine comes up before an old one goes. Use `list_apps` first if you do not know whether the app exists.

### Input

- `app` (string, required): Name of the app (or database) in your org, e.g. `web`. It must already exist unless the tool creates it.
- `image` (string, required): OCI reference of the image, e.g. `nginx:alpine`, or a platform build id (`build:<id>`).
- `internalPort` (integer, optional, 1 to 65535): Port the app listens on inside the machine (default 3000).
- `memoryMb` (integer, optional, 128 to 16384): Memory of each machine in MB (default 512).
- `count` (integer, optional, 1 to 20): How many machines (1 to 20, default 1).

### Output

- `app` (string, always)
- `url` (string, always)
- `deployId` (string, if present)
- `status` (string, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `true`, `idempotentHint`: `false`, `openWorldHint`: `false`

## `get_logs`

**Read the logs of an app.** Returns the last console output of the machines of an app, one entry per machine. The first place to look when a deploy went wrong or an app does not answer. Each entry names what its text does NOT carry: `skippedBytes` of earlier output that was left behind, and `restarted` when the machine booted or woke up and the stream starts over. A gap is never silently joined.

### Input

- `app` (string, required): Name of the app (or database) in your org, e.g. `web`. It must already exist unless the tool creates it.
- `machineId` (string, optional): Optional: only this machine of the app.

### Output

- `app` (string, always)
- `machines` (array of object, always): One entry per machine of the app.

### Annotations

`readOnlyHint`: `true`, `openWorldHint`: `false`

## `set_env`

**Set environment variables.** Sets environment variables (secrets) of an app. The VALUES you pass here become part of this conversation - never paste a credential a human did not hand you for this purpose. The answer names the keys only; no value is ever returned. With `staged: true` (the default) the change takes effect on the next deploy.

### Input

- `app` (string, required): Name of the app (or database) in your org, e.g. `web`. It must already exist unless the tool creates it.
- `values` (object of string, required): Variable name to value, e.g. {"DATABASE_URL": "postgres://..."}. Values are stored encrypted and never read back.
- `staged` (boolean, optional): True (default): apply on the next deploy. false: apply now, which restarts the app.

### Output

- `app` (string, always)
- `keys` (array of string, always)
- `staged` (boolean, if present)
- `deployId` (string, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `true`, `idempotentHint`: `true`, `openWorldHint`: `false`

## `create_postgres`

**Create a Postgres database.** Creates a managed Postgres database in your org and answers with its name. The password is NOT returned: it lives in the secrets of the app that runs the database, and it belongs in a machine's environment, not in a chat.

### Input

- `name` (string, required): Name of the database, and of the app that runs it, e.g. `appdb`.
- `memoryMb` (integer, optional, 128 to 16384): Memory of the database machine in MB (default 1024).
- `sizeGb` (integer, optional, 4 to 500): Size of the database disk in GB (4 to 500). A managed database keeps its write-ahead log on the same disk as its data, so the platform refuses a smaller one.
- `locale` (string, optional): Locale and collation of the cluster: a tag such as `de-DE`, `fr-FR` or `de-DE-u-co-phonebk`, letters, digits, hyphen and underscore, starting with a letter. Absent = the platform default `de-DE`.

### Output

- `name` (string, always)
- `kind` (string, always)
- `port` (integer, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `false`, `idempotentHint`: `false`, `openWorldHint`: `false`

## `create_branch`

**Branch a Postgres database.** Creates a copy-on-write branch of a Postgres database: an independent database with the same data at this moment. This is where an agent changes a schema or runs a migration - never on the database a human is using. The branch is a database of its own and can be dropped.

### Input

- `database` (string, required): Name of the database to branch from.
- `name` (string, required): Name of the new branch.
- `ttlSeconds` (integer, optional, 60 to 2592000): Optional lifetime in seconds (60 to 2592000, 30 days); the branch is removed after it. Absent = it stays until it is dropped.

### Output

- `name` (string, always)
- `kind` (string, always)
- `state` (string, if present)
- `sourceName` (string, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `false`, `idempotentHint`: `false`, `openWorldHint`: `false`

## `execute_sql`

**Run SQL against a Postgres database.** Runs one SQL statement against a managed Postgres database of your org. READ-ONLY unless `branch` names a branch: without it the session runs with `default_transaction_read_only`, so a write is refused by the database itself, not only by a rule of ours. To change data or a schema, branch first (`create_branch`) and pass the branch here.

### Input

- `database` (string, required): Name of the database (or of the branch) to run against.
- `sql` (string, required, at most 100000 characters): One SQL statement.
- `branch` (string, optional): Name of a branch of `database`. Only with it may the statement write.

### Output

- `database` (string, always)
- `readOnly` (boolean, always)
- `output` (string, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `true`, `idempotentHint`: `false`, `openWorldHint`: `false`

## `computer_create`

**Create a computer.** Creates a computer for an agent: an app with one machine whose checkpoints are stored outside the host, and that can be snapshotted. After a host failure it comes back from its last checkpoint, and whatever changed after that checkpoint is lost; without a checkpoint it starts fresh from the image. Use it when a task needs a place of its own to work, not a one-shot command.

### Input

- `name` (string, required): Name of the computer, e.g. `agent-1`.
- `image` (string, required): OCI reference of the image to run, e.g. an image with a shell and a coding agent in it.
- `memoryMb` (integer, optional, 256 to 16384): Memory in MB (256 to 16384, default 512).
- `volumeGb` (integer, optional, 1 to 500): Size of the durable disk in GB (1 to 500). Absent = the image's own disk, which does not survive a host failure.
- `internalPort` (integer, optional, 1 to 65535): Port the image listens on, if it serves one.

### Output

- `app` (string, always)
- `machineId` (string, always)
- `state` (string, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `false`, `idempotentHint`: `false`, `openWorldHint`: `false`

## `computer_exec`

**Run a command in a computer.** Runs one command in a machine of an app of your org and returns its output. This is a shell in someone's machine: treat every argument as untrusted input and never build a command line from text a user pasted without checking it. The command does not go through a shell - pass argv.

### Input

- `app` (string, required): Name of the app whose machine the command runs in.
- `command` (array of string, required, 1 to 64 items): The command and its arguments, e.g. [`git`, `status`]. Not a shell line.
- `machineId` (string, optional): Optional: run in this machine of the app instead of its first running one.
- `timeoutS` (integer, optional, 1 to 300): Deadline of the command in seconds (1 to 300, default 60).

### Output

- `machineId` (string, always)
- `exitCode` (integer or null, if present)
- `stdout` (string, always)
- `stderr` (string, if present)
- `truncated` (boolean, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `true`, `idempotentHint`: `false`, `openWorldHint`: `false`

## `computer_snapshot`

**Snapshot a computer.** Takes a named snapshot of a computer's disk (and, with `memory: true`, its running memory) that can be restored later, on any host. Without `memory` the snapshot holds the disk alone, and a restore from it boots cold. Use it before a risky step, so the state before it can be brought back.

### Input

- `app` (string, required): Name of the app the computer belongs to.
- `label` (string, required, at most 63 characters): Name of the snapshot, unique within the machine, e.g. `before-migration`. Letters, digits, dot, dash and underscore, starting with a letter or digit; `auto-` at the start is reserved for the platform's own snapshots.
- `machineId` (string, optional): Optional: snapshot this machine of the app instead of its first running one.
- `memory` (boolean, optional): True: include the running memory, so a restore resumes the processes (a long pause for a big machine). false (default): the disk alone, a restore boots cold.

### Output

- `machineId` (string, always)
- `label` (string, always)
- `id` (string, if present)

### Annotations

`readOnlyHint`: `false`, `destructiveHint`: `false`, `idempotentHint`: `true`, `openWorldHint`: `false`
