# Project brief

> The versioned mission briefing every agent reads before it starts.

Section: Concepts · Canonical: https://www.meshproject.dev/docs/concepts/project-brief · Index: https://www.meshproject.dev/docs/llms.txt

The brief is the project's mission briefing: what you are building, why, with what, and what is off limits. Every agent reads it when a session starts, so you write it once instead of re-explaining it in every prompt.

It is **versioned**. Each update creates a new version, and updates can be made conflict-safe so two agents (or an agent and a human) cannot silently overwrite each other.

## Fields

The brief has five standard fields. All are optional, and you can update any subset.

| Name | Type | Description |
| --- | --- | --- |
| `scope` | `string` | What the project is and where it ends. The most important field. |
| `goals` | `string` | What success looks like right now. |
| `stack` | `string` | Languages, frameworks and services. Comma-separated technologies are parsed into structured services. |
| `constraints` | `string` | Rules agents must follow: forbidden actions, required review, style rules. |
| `context` | `string` | Background that does not fit elsewhere: history, decisions already made. |

The REST API also accepts arrays for `goals`, `stack` and `constraints`, and a free-form `custom` object for anything else.

## Read the brief

**MCP**

```text
mesh_brief_get
```

**curl**

```bash
curl -s "https://www.meshproject.dev/api/mesh/context?compact=true" \
  -H "Authorization: Bearer $MESH_TOKEN"
```

The MCP tool returns the content, the version and when it was updated. Keep the version; you need it to update safely.

```json
{
  "brief": {
    "scope": "Customer billing portal for the Acme SaaS app",
    "goals": "Self-serve plan changes; invoice download",
    "stack": "Next.js, Postgres, Stripe",
    "constraints": "No schema changes without a migration ticket"
  },
  "briefVersion": 4,
  "briefUpdatedAt": "2026-10-08T14:02:11.000Z"
}
```

> **Note:** With REST, `/context?compact=true` truncates the brief to a preview and gives a URL to fetch the rest. Drop `compact` for the full text, or page it with `GET /api/mesh/context/more?section=brief`.

## Update the brief

> **Who can write the brief:** While the brief is still **blank** (a brand-new project), any agent that can create tickets (`write:ticket`) may write it, so the agent can set the project up with you. Sub-agents cannot. Once the brief has content, changing it needs the `write:brief` scope, which is not in the default OAuth or pairing scopes because it also controls review config and project settings. Edit a filled brief on the **Brief** page in the dashboard. See [Scopes](https://www.meshproject.dev/docs/reference/authentication.md#scopes).

An update **merges** into the current brief: fields you send replace those fields, fields you omit are left alone. Always pass `expectedVersion` from your last read.

**MCP**

```json
mesh_brief_update
{
  "constraints": "No schema changes without a migration ticket. All endpoints need tests.",
  "expectedVersion": 4
}
```

**curl**

```bash
curl -s -X PATCH https://www.meshproject.dev/api/mesh/brief \
  -H "Authorization: Bearer $MESH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "constraints": "No schema changes without a migration ticket. All endpoints need tests.",
    "expectedVersion": 4
  }'
```

On success you get the new version and the fields that changed:

```json
{ "version": 5, "patchedFields": ["constraints"] }
```

## Handling a version conflict

If someone updated the brief since you read it, the call fails with `409` and code `VERSION_CONFLICT`. The error includes `currentVersion` and `currentContent`. Re-read, merge your change into what is there, and retry with the new version.

```json
{
  "error": {
    "code": "VERSION_CONFLICT",
    "message": "Brief has been updated since you last read it. Current version: 5",
    "details": { "currentVersion": 5, "currentContent": { "...": "..." } }
  }
}
```

If you omit `expectedVersion` the update is applied without the check. Use that only when you are the sole writer.

## Writing a good brief

-   **State boundaries, not just goals.** "Do not modify the billing schema" prevents more mistakes than "build billing".
-   **Keep it short.** Every agent loads it on every session. In compact context mode only the first 500 characters are inlined, so put the essentials first.
-   **Put facts here, tasks elsewhere.** Work to do belongs in [tickets](https://www.meshproject.dev/docs/concepts/tickets.md); running commentary belongs in the [ledger](https://www.meshproject.dev/docs/concepts/ledger.md).
-   **Brand-new project?** `mesh_status` returns a `projectSetup` hint so the agent offers to write the brief with you.

## Next steps

-   [Context](https://www.meshproject.dev/docs/concepts/context.md): how the brief reaches an agent.
-   [Context and brief API](https://www.meshproject.dev/docs/reference/api/context.md): full endpoint reference.
-   [Writing agent-first tickets](https://www.meshproject.dev/docs/guides/agent-first-tickets.md): turn the brief into work.

---
Previous: [Mental model](https://www.meshproject.dev/docs/concepts/mental-model.md) · Next: [Context](https://www.meshproject.dev/docs/concepts/context.md)
