---
doc: MCP Agent Guide
version: 1.3.0
last_updated: 2026-11-15
applies_to: [all surfaces in config/docs.php]
decisions: [TD-01, TD-02]
---

# Connect Your Coding Agent to the Backend Docs (MCP)

> **In a hurry?** [MCP_APP_TEAM_KIT.md](MCP_APP_TEAM_KIT.md) has the Morvia-specific snippets and rules block ready to copy.

For the Flutter and React developers of the project apps who use an AI coding agent: Claude Code, Cursor, Codex, VS Code Copilot, Gemini CLI
or any other agent that supports MCP.

The backend publishes its documentation as a read-only **MCP server** called
`<project>-docs`, where `<project>` is the backend's project slug (from its `APP_NAME`,
e.g. `APP_NAME="My Shop"` → `my-shop-docs`). The `/docs` dashboard shows the exact name
and ready-to-copy snippets. Once your agent is connected, it reads the same files you see in
the browser at `{HOST}/docs`: the BRD, the project registry, the conventions,
the decisions, and the feature docs of every app. It is the same source, so the
agent and you always see the same version.

## Version history

| Version | Date | Summary |
|---------|------|---------|
| 1.3.0 | 2026-11-15 | Points to the copy-paste [MCP_APP_TEAM_KIT.md](MCP_APP_TEAM_KIT.md) for the Flutter and Vue teams. |
| 1.2.0 | 2026-11-11 | The server name is `<project>-docs` from the backend's `APP_NAME` (exact name on `/docs`); the stdio handle is `project-docs` (TD-06). |
| 1.1.0 | 2026-11-11 | `read-doc` `outline` and `section` (read one part of a long doc); the brief includes the feature doc's Quick reference and the per-feature BRD file (TD-05). |
| 1.0.0 | 2026-11-11 | First version: connection per agent, the mandatory reading order, the rules block for your app repo, the `get-integration-brief` tool and the `integrate-feature` prompt (TD-01). |

---

## 1. What your agent can read

| Source | Path in `docs/` | Why the agent needs it |
|--------|-----------------|------------------------|
| Project brain | `PROJECT_BRAIN.md` | Map of every feature: app, doc file, BRD IDs, phase, **status**, version. |
| API conventions | `API_CONVENTIONS.md` | Envelope `{status, message, data}`, `error_code`, pagination, headers, Dio/axios setup. |
| BRD | `brd/` | The business requirements (markdown version; the PDF is not readable over MCP). |
| Decisions | `DECISIONS.md` | Client decisions (D-n), answers to BRD gaps (DEC-xx), technical choices (TD-xx). **They override the BRD.** |
| App docs | `{surface}/` | One folder per app (`admin/`, `client/`, …): `README.md` + one file per feature. |
| Screens | `app_screens/{surface}/` | Design exports, named `{surface}--{feature}--{nn}-{screen}`. |
| Endpoint catalog | `postman-collection.json` | Generated from the live routes; read it through `list-endpoints` / `get-endpoint` (headers, parameters, body, field docs and validation rules). |

**When sources disagree**, follow them in this order: `DECISIONS.md` →
the feature doc → the BRD. The feature doc is your contract: it already applies
the decisions.

---

## 2. Before you connect

Ask the backend team for two values:

| Value | Local backend | Shared dev/staging server |
|-------|---------------|---------------------------|
| MCP URL | `http://localhost:8000/mcp/docs` | `https://{HOST}/mcp/docs` |
| Docs token | not needed | `DOCS_TOKEN` if the server sets one (it should on any internet-facing server), sent as `Authorization: Bearer <token>` |

The docs are served on every environment **except production**.

Keep the token out of git: put it in an environment variable and reference
the variable in your agent config, as shown below.

```bash
# ~/.zshrc or ~/.bashrc — only needed when the server has DOCS_TOKEN set
export PROJECT_DOCS_TOKEN="paste-the-token-here"
```

The browser viewer uses the same token: open `{HOST}/docs?token=<token>` once.
The `/docs` dashboard also shows ready-to-copy snippets with the right URL.

---

## 3. Connect your agent

Every agent needs the same three things: **HTTP transport** (also called
"streamable HTTP"), the **URL**, and the **Authorization header**. Leave the
header out when you connect to a local backend.

### Claude Code

```bash
claude mcp add --transport http <project>-docs https://{HOST}/mcp/docs \
  --header "Authorization: Bearer $PROJECT_DOCS_TOKEN"
```

Or share it with your team in the app repo's `.mcp.json` (the token stays in
each developer's environment):

```json
{
  "mcpServers": {
    "<project>-docs": {
      "type": "http",
      "url": "https://{HOST}/mcp/docs",
      "headers": { "Authorization": "Bearer ${PROJECT_DOCS_TOKEN}" }
    }
  }
}
```

### Cursor — `.cursor/mcp.json`

```json
{
  "mcpServers": {
    "<project>-docs": {
      "url": "https://{HOST}/mcp/docs",
      "headers": { "Authorization": "Bearer ${env:PROJECT_DOCS_TOKEN}" }
    }
  }
}
```

### VS Code (Copilot agent mode) — `.vscode/mcp.json`

```json
{
  "inputs": [
    { "id": "<project>-docs-token", "type": "promptString", "description": "Backend docs token", "password": true }
  ],
  "servers": {
    "<project>-docs": {
      "type": "http",
      "url": "https://{HOST}/mcp/docs",
      "headers": { "Authorization": "Bearer ${input:<project>-docs-token}" }
    }
  }
}
```

### Codex — `~/.codex/config.toml`

```toml
[mcp_servers.<project>-docs]
url = "https://{HOST}/mcp/docs"
bearer_token_env_var = "PROJECT_DOCS_TOKEN"
```

### Gemini CLI — `.gemini/settings.json`

```json
{
  "mcpServers": {
    "<project>-docs": {
      "httpUrl": "https://{HOST}/mcp/docs",
      "headers": { "Authorization": "Bearer $PROJECT_DOCS_TOKEN" }
    }
  }
}
```

### Other agents

Add an MCP server named `<project>-docs` with HTTP (streamable HTTP) transport,
the URL, and the header `Authorization: Bearer <token>`.

### Agent on the backend machine (stdio)

If your agent runs on the same machine as a checkout of this backend, it can
start the server itself, with no URL or token:

```json
{
  "mcpServers": {
    "<project>-docs": {
      "command": "php",
      "args": ["artisan", "mcp:start", "project-docs"],
      "cwd": "/path/to/project-backend"
    }
  }
}
```

---

## 4. Check the connection

1. Restart the agent (or reload its MCP servers). In Claude Code, `claude mcp list`
   must show `<project>-docs` as connected; in Cursor and VS Code the server shows a
   green status and **7 tools**.
2. Ask the agent:

   > Call `get-integration-brief` for surface `client` and show me the result.

   You should get a "Mandatory reading" checklist, the `client/README.md`
   overview, and the table of client features with their status.
3. Still failing? Test the server without the agent:

   ```bash
   curl -s https://{HOST}/mcp/docs \
     -H "Authorization: Bearer $PROJECT_DOCS_TOKEN" \
     -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
     -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
   ```

   A JSON list of tools means the server and the token are fine; the problem is
   the agent config. See [§8 Troubleshooting](#8-troubleshooting).

---

## 5. Make sure the agent always checks the docs

An agent only reads what it is told to read. The setup has four layers; use
all of them.

### 5.1 The server tells every agent (automatic)

When an agent connects, `<project>-docs` sends instructions that say: call
`get-integration-brief` first, and read `PROJECT_BRAIN.md`,
`API_CONVENTIONS.md`, the BRD, `DECISIONS.md`, the app's README and the feature
doc before writing integration code. You do not have to do anything for this.

### 5.2 One tool returns the required context

`get-integration-brief` (surface + feature) returns, in one call:

- the mandatory reading checklist;
- the app's `README.md` (`admin/`, `client/`, …);
- the feature's row from `PROJECT_BRAIN.md`, with its status: a feature that is
  not `ready` is flagged so the agent stops instead of guessing;
- the BRD sections for each of the feature's IDs, with their acceptance
  scenarios (AC-xx), business rules (BR-xx) and screen notes (SCR-xx);
- the `DECISIONS.md` rows the feature depends on.

So even an agent that reads nothing else has seen the BRD, the registry,
the decisions and the app docs for that feature.

### 5.3 Add the rules to your app repo (do this once)

Paste this block into your app repo's agent instructions file, so every task
starts with the docs. Use the file your agent reads:

| Agent | File in the app repo |
|-------|----------------------|
| Claude Code | `CLAUDE.md` |
| Codex, Antigravity, OpenCode | `AGENTS.md` |
| Cursor | `.cursor/rules/project-backend.mdc` (set `alwaysApply: true`) |
| VS Code Copilot | `.github/copilot-instructions.md` |
| Gemini CLI | `GEMINI.md` |

Set `SURFACE` to your app's surface from `PROJECT_BRAIN.md` §2 (e.g. `client` or `admin`).

```markdown
## Backend integration (<Project> API) — mandatory

The backend docs are served by the `<project>-docs` MCP server. This app's surface is `SURFACE`.

Before writing or changing any code that calls the <Project> API:
1. Call `get-integration-brief` with surface `SURFACE` and the feature you are working on.
2. The brief already contains the registry row, the feature doc's Quick reference, the
   BRD section and the decision rows. Read more only when you need it, one slice at a time:
   `read-doc` with `outline=true` then `section="…"` on the feature doc; `brd/features/<ID>.md`
   for the BRD; `API_CONVENTIONS.md` and `SURFACE/README.md` once per project, not per feature.
3. Use `get-endpoint` for every endpoint the code calls. Build request models from its
   field docs; build response models and error handling from the feature doc's real
   responses and error table (and from `get-endpoint` → `examples` when present).
4. When `get-endpoint` → `variables` is present, order the calls of a flow from it: each
   `uses` entry names the routes (`set_by`) whose response provides that value. Keep
   those values in app state; never hard-code an id or token from an example.
5. Only integrate features whose status is `ready` in `PROJECT_BRAIN.md`.
6. Never invent endpoints, fields, enum values or error codes. If the docs do not
   answer something, stop and list it as a question for the backend team.
7. If the BRD and the feature doc disagree, follow the feature doc and `DECISIONS.md`.
8. Before a feature is done, compare the code with the feature doc's
   "Integration checklist" and acceptance scenarios.
9. In your final summary, list the docs you read and their versions, and the
   endpoints (route names) the code calls.
```

### 5.4 Start feature work with the `integrate-feature` prompt

The server also provides a prompt that walks the agent through the whole
order: brief → registry → conventions → BRD → decisions → README and feature
doc → endpoints → code.

- **Claude Code:** `/mcp__<project>-docs__integrate-feature` then the surface and
  feature, e.g. `client auth`.
- **Other agents:** pick `integrate-feature` from the `<project>-docs` prompts list,
  or simply write: *"Use the <project>-docs integrate-feature workflow for the
  client auth feature."*

### 5.5 Review what the agent read

Rule 9 above makes the agent list the docs it read. If the list is missing
`PROJECT_BRAIN.md`, the BRD, `DECISIONS.md` or the feature doc, send it back.

---

## 6. Tool reference

| Tool | Arguments | Returns |
|------|-----------|---------|
| `get-integration-brief` | `surface` (required), `feature` (doc path, slug or BRD ID) | Reading checklist, app README, registry row and status, BRD sections + AC/BR/SCR rows, decision rows. Without `feature`: the app's feature list. |
| `list-features` | `surface`, `status` | `PROJECT_BRAIN.md` registry rows as JSON. |
| `list-docs` | `folder` (`brd`, `admin`, `client`, `app_screens`, …) | Files with title, size, last update. |
| `read-doc` | `path`, `outline`, `section`, `offset` | `outline=true`: the headings with their size. `section="Quick reference"`: only that section. Otherwise the document, long files in parts (pass the returned offset). **Use outline + section on long files.** |
| `search-docs` | `query`, `folder`, `limit` | Matching lines with file and line number, e.g. an `error_code`, a status value or `BR-13`. |
| `list-endpoints` | `surface` (`shared` or a surface), `query` | Method, path, route name, whether a Bearer token is needed. |
| `get-endpoint` | `method`, `path` (path or route name) | Headers, query/path parameters, example body, field docs (type, meaning, validation rules). Recorded response `examples` and `variables` appear once the backend records them. |

| Prompt | Arguments | Use |
|--------|-----------|-----|
| `integrate-feature` | `surface`, `feature` | Full integration workflow for one feature. |

Everything is read-only: the server never changes data and never calls the API
on your behalf. To try requests, use the API console at `{HOST}/tester`
(it has **Quick Auth** demo logins outside production).

`get-endpoint` for `POST admin.auth.login` returns (shortened):

```json
{
  "surface": "admin",
  "method": "POST",
  "path": "/api/v1/admin/auth/login",
  "route": "admin.auth.login",
  "auth": false,
  "headers": { "Accept": "application/json", "Content-Type": "application/json", "Accept-Language": "{{locale}}" },
  "body": { "mode": "raw", "raw": "{ \"login\": \"value\", \"password\": \"Password123!\" }" },
  "description": "**Route:** `admin.auth.login` … **Field documentation:** `login` — Email, string, required …",
  "variables": { "saves": [], "uses": [] },
  "examples": []
}
```

`{{token}}` in a header is the JWT of the signed-in app; `{{base_url}}` and
`{{locale}}` are collection variables. Never copy a token or id from an example
into app code.

---

## 7. Example session

> **You:** Integrate admin login.
>
> **Agent:** calls `get-integration-brief` (`admin`, `auth`) → reads the status and
> doc version from the registry → reads `API_CONVENTIONS.md`, `admin/README.md` and
> `admin/auth.md` → `get-endpoint` for `admin.auth.login` → builds the axios call,
> the request/response types and the 422 / 401 handling → lists the docs it read
> and the checklist items it covered.

If you ask for a feature that is not `ready` (or not in the registry yet), the
brief says so and the agent should stop and tell you.

---

## 8. Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| `401` / "Docs access token required" | Token missing or wrong | Check the env variable is set **in the shell that starts the agent**, and the header is `Authorization: Bearer <token>`. |
| `404` on `/mcp/docs` | Production server, or docs switched off | The docs are not served in production unless `DOCS_ENABLED=true` and `DOCS_TOKEN` are set; use the dev/staging server. |
| Server connected but no tools | Agent cached an old tool list | Restart the agent or reload MCP servers. |
| Agent answers without calling tools | Rules block not loaded | Add §5.3 to the agent's instructions file; start with the `integrate-feature` prompt. |
| A doc looks out of date | The server shows the docs of the backend version deployed there | Compare the doc's `version` with `CHANGELOG.md`; ask which server has the latest backend. |
| `read-doc` text ends with "Call read-doc again with offset …" | Long file | Normal; the agent reads the next part with that offset. |

Questions about a feature or a missing answer in the docs go to the backend
team; the decision is then recorded in `DECISIONS.md` and the feature doc.
