> ## Documentation Index
> Fetch the complete documentation index at: https://tesser.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Manifest reference

> Every field of a service's TOML file

A service is described by one TOML file at
`.claude/skills/devboxes/<service>.toml`. The filename is the service name,
which may contain lowercase letters, digits, `-`, and `_`. Service names are
shared across the org.

A manifest holds facts about the service: where its code lives, what ports it
listens on, how to set it up and start it, how to tell that it is healthy, and
what it depends on. Decisions such as when to restart, when to run tests, or
what else to install are made at the command line, not in the manifest.

## Minimal

```toml theme={"theme":"css-variables"}
ports = [3000]

[run]
setup = "pnpm install"
dev   = "pnpm dev"
```

## All fields

```toml theme={"theme":"css-variables"}
# .claude/skills/devboxes/api.toml

root  = "apps/api"           # working directory for the recipes, relative to the repo root
ports = [8080, 9229]         # ports the service listens on; the first is the primary port
size  = "large"              # box size its instances run on: small | standard | large | xlarge
box_address = true           # pages opened on bare localhost move to the box's own address

[run]
setup = "pnpm install"       # prepares the box; must be safe to run repeatedly
dev   = "pnpm dev"           # starts the server

[health]
path    = "/healthz"         # probed on the primary port; omit for a plain port check
timeout = "90s"              # how long to wait for the service to become healthy

[deps]
5001 = "worker"              # localhost:5001 on this box reaches worker's primary port
5432 = "db"                  # any TCP service
9091 = "search:9090"         # a specific port of a dependency

[env]
files    = [".env.local"]    # gitignored files that sync should include anyway
required = ["DATABASE_URL"]  # names only; values are set with `tesser env set`
```

## Field by field

| Field | Default | Meaning |
| - | - | - |
| `root` | `"."` | The working directory for `setup` and `dev`, relative to the repository root. In a monorepo, point it at the service's package. |
| `ports` | required | The loopback ports the service binds. The first one is the primary port: it is what a bare dependency binding reaches and what the health check probes. The service may bind loopback or all interfaces; Tesserc exposes the declared ports to the org's other boxes through the box's mesh ingress. |
| `size` | `"standard"` | The box size this service's instances launch on: `small` (1 vCPU, 4 GB), `standard` (2 vCPU, 8 GB), `large` (4 vCPU, 16 GB), or `xlarge` (8 vCPU, 32 GB). `tesser make <service> --size <size>` overrides it for one box. |
| `box_address` | `false` | When `true`, a page opened on bare `localhost:<port>` for one of this service's boxes moves to that box's own address, `http://box-<id>.localhost:<port>`, on the same path. Set it when the app only works on its box's address, for example a frontend that calls its API on another port with cookies. API calls and sockets are never moved. |
| `run.setup` | required | Runs before `dev` on every start, and on a shared instance's first boot, so it must be idempotent. `pnpm install` is the usual value. |
| `run.dev` | required | The command that starts the server. Dev boxes run it against the synced worktree; shared instances run it against the checked-out commit. |
| `health.path` | port check | An HTTP path that must return a 2xx status on the primary port before the instance counts as healthy. Without it, a process listening on the primary port is enough. |
| `health.timeout` | `"90s"` | How long `dev` and a shared instance rollover wait for the service to become healthy. Accepts values such as `"500ms"`, `"90s"`, or `"2m"`. |
| `[deps]` | none | Entries of the form `localPort = "service"` or `"service:port"`. Each key becomes a loopback port on this box (and on the laptop while this box is selected) that reaches the named service: the box it is wired to with `tesser wire`, otherwise the org's shared instance, which is started or woken before this service starts. |
| `env.files` | none | Gitignored files, relative to `root`, that sync ships anyway: on every sync to a dev box, and copied from the creating laptop's worktree when a shared instance is created. |
| `env.required` | none | Names of env variables a shared instance needs. Values are set with `tesser env set <service> KEY=VALUE`. Starting a shared instance with any of these unset fails with a message naming the missing variable. |

## Rules

* Bind declared ports however the app prefers. `127.0.0.1` and `0.0.0.0` both
  work, and Tesserc never binds them itself. Other boxes reach a declared port
  only through the box's mesh ingress, and the org's network exposes nothing
  else, so an all-interfaces bind is not public. Pin the port in the dev
  server's config so a collision fails loudly instead of silently drifting to
  the next port and breaking routing.
* The service's own `ports` and its `[deps]` keys share the box's loopback
  port space, so a port cannot appear in both.
* Ports 14650 and 14651 are reserved for the Tesserc mesh and are rejected in
  `ports` and `[deps]`.
* A service name that reads as a box id, such as `box-1a2b` or `box1a2b`, is
  rejected, because `<service>.localhost` would be ambiguous.
* `env.required` rejects names that can run code on the box, such as `PATH`,
  `NODE_OPTIONS`, and anything starting with `LD_` or `GIT_`. The full list is
  in [Services](https://tesser.sh/docs/services.md#secrets-for-shared-instances).
* When a repository has several manifests, `dev` requires the service name.
  When it has one, that service is the default. `make` without a service name
  always creates a workbench.
* Unknown keys are rejected, and the error message lists the keys that exist.
* Secret values do not belong in a manifest. The `[env]` table holds names and
  file lists only, because the manifest is committed to the repository.
* Dependencies are names, never addresses. Which box a name reaches is decided
  for each box at run time, as described in
  [Connect a frontend to a backend](https://tesser.sh/docs/wiring.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.