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

# MCP server

> Connect AI agents to Traffical over MCP — authentication, scopes, and the complete read and write tool reference.

Traffical exposes an **[MCP](https://modelcontextprotocol.io) server**. Connect an AI agent and it can read your [changes](/concepts/changes) — state, evidence, decision records — and, where governance permits, act: draft changes, propose or execute lifecycle transitions, and record assessments.

The server is **least-privilege by scope**, not read-only: a token's scopes bound what it can do, the [autonomy resolver](/governance/approvals-and-autonomy) narrows that at runtime, and a write mode that defaults to off gates every lifecycle transition. **Approvals stay with humans** — there is no `approve` tool; when an action needs a checkpoint, the agent raises a proposal and links you to the transition console in the [dashboard](/dashboard/changes).

<Note>
  The Changes surface is enabled per organization — if you don't see **Changes** in the dashboard sidebar, it isn't enabled for your organization yet.
</Note>

## Connect

Traffical provides your organization's MCP endpoint during onboarding — reach out if you don't have it yet.

### Claude Code

```bash theme={null}
claude mcp add --transport http traffical-changes <your-mcp-endpoint>
```

That's it — no key to paste. Claude Code discovers the authorization server via standard OAuth discovery and opens a browser sign-in with your Traffical account. Run `/mcp` inside Claude Code to authenticate or check connection status.

### Other MCP clients

Any MCP client that supports **streamable HTTP with OAuth discovery** works zero-config. Point it at your organization's MCP endpoint; the first 401 response carries a `WWW-Authenticate` header pointing at the server's OAuth discovery document (`/.well-known/oauth-protected-resource` on the endpoint's origin), which names the authorization server, and the client runs the standard OAuth flow from there.

Two transport details for client authors:

* The server speaks plain JSON-RPC 2.0 over `POST /mcp` — no sessions, no SSE streams (`GET /mcp` returns `405`).
* OAuth tokens are audience-bound (RFC 8707): the token must be minted for the MCP resource. Clients that follow the discovery flow get this right automatically.

### API key (headless agents, CI)

For agents that can't run a browser flow, use a **management API key** as a plain bearer token. The scope on the key decides what it can do:

```
Authorization: Bearer traffical_sk_...
```

Create one on your organization's **API Keys** page in the dashboard (in the sidebar when viewing your organization, or from the account menu). A read-only management key is exactly the `mgmt:read` scope; write scopes are granted deliberately. See [API key types](/api/overview#api-key-types) for how scopes work.

<Warning>
  SDK keys (scopes `sdk:read`/`sdk:write`) — including the key the CLI provisions into `.traffical/.env` — cannot read changes and will get a `403`. You need a management key with `mgmt:read` (read-only) or a write scope.
</Warning>

## Scopes

Three write scopes sit on top of the read scopes. `tools/list` is **scope-filtered**, so a token only sees the tools its scopes permit.

| Scope                                | Grants                                                                                                                    |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `mgmt:read` (and the `:read` scopes) | every read tool below — a read-only connection                                                                            |
| `changes:propose`                    | author draft changes, write proposals, assessments, annotations, request approval — can suggest, but never starts traffic |
| `changes:operate`                    | execute transitions (resolver-gated); refresh evidence                                                                    |
| `defaults:promote`                   | promote-to-default / complete-with-default — the highest-risk action keeps its own scope                                  |

You never mint these fine-grained scopes directly — they come from the coarse scope on the key, or from your role over OAuth. `mgmt:read` grants every `:read` scope; `mgmt:operate` (the **Lifecycle Operate Key** preset) grants all three write scopes; `admin` (**Full Access**) grants everything. A plain `mgmt:write` key grants none of the write scopes, and over OAuth only admins and owners carry them — members and viewers connect read-only. See [API key scopes](/governance/roles-and-permissions#api-key-scopes).

Scope is the durable ceiling; the [autonomy resolver](/governance/approvals-and-autonomy) narrows it again at runtime, per action.

## Tools

### Read tools

| Tool                                                      | Required scope    | Returns                                                                                                                                                                     |
| --------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `whoami`                                                  | *any token*       | The caller's identity, org, and reachable projects. Call it first to get a `projectId` for the other tools.                                                                 |
| `list_changes`                                            | `changes:read`    | Changes in the project — key, name, state, intent, lifecycle template, current phase                                                                                        |
| `get_change`                                              | `changes:read`    | One change in full: its phases, parameters, and executing policies                                                                                                          |
| `get_change_evidence`                                     | `changes:read`    | Evidence records (newest first): analysis artifacts with a recommendation, rationale, and provenance                                                                        |
| `get_change_decisions`                                    | `changes:read`    | The change's decision log: who decided each transition or annotation, why, and the evidence cited                                                                           |
| `get_measurement_plan`                                    | `changes:read`    | The resolved measurement plan: primary metrics, guardrails, diagnostics, per-phase rules, source protocols                                                                  |
| `preview_transition`                                      | `changes:read`    | The next lifecycle transition: availability, blockers, readiness checks, ranked plan options with runtime estimates                                                         |
| `get_change_stats`                                        | `changes:read`    | Process health over a trailing window: time to exposure, clean activation rate, guardrail catch rate, decision-log completeness                                             |
| `get_autonomy`                                            | `changes:read`    | Per transition kind, whether the caller may `execute` or `propose` right now, with the full reasoning                                                                       |
| `list_attention`                                          | `changes:read`    | Changes that need attention: pending approvals, actionable evidence recommendations, paused changes                                                                         |
| `get_project_decisions`                                   | `changes:read`    | Project-wide decision log                                                                                                                                                   |
| `resolve_change_preview`                                  | `changes:read`    | Plan a change before creating it: the computed risk class, recommended lifecycle template, matched certified protocols, and a plan preview. Call it before `create_change`. |
| `get_ai_overview`                                         | `projects:read`   | Program-level state: changes by state, adaptive policy counts, recent decision records                                                                                      |
| `list_parameters` / `get_parameter`                       | `parameters:read` | Parameters and their [surface](/concepts/surfaces) bindings                                                                                                                 |
| `list_metrics` / `get_metric`                             | `metrics:read`    | Metric definitions and results                                                                                                                                              |
| `get_policy_health`                                       | `policies:read`   | Rollout health for a policy                                                                                                                                                 |
| `list_surfaces`                                           | `surfaces:read`   | Placement [surfaces](/concepts/surfaces)                                                                                                                                    |
| `list_measurement_protocols` / `get_measurement_protocol` | `protocols:read`  | [Measurement protocols](/governance/measurement-protocols)                                                                                                                  |

`preview_transition` and `get_autonomy` are advisory — they show what *would* happen and why, but change nothing. Omit `kind` on `preview_transition` to preview the natural next step.

### Write tools

These appear in `tools/list` only when the token carries the scope.

| Tool                 | Required scope                                                             | Effect                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create_change`      | `changes:propose` (start needs `changes:operate`)                          | Author a **new change as a draft** from **existing** parameters — it cannot create parameters, layers, or policies. A draft serves no traffic; pass `start: true` to also request the canary start through the resolver. Returns the new `changeId` and a console link.                                                                                                                                                                                                          |
| `request_transition` | `changes:operate` (`defaults:promote` for promote / complete-with-default) | The single transition tool (start, advance, promote, complete, revert). The resolver decides `execute` vs `propose`; pass `mode: 'propose'` to force a checkpoint. Returns the outcome, the full resolver reasoning, and (when proposed) a console deep link. Proposals are idempotent on retry — a repeat returns the existing pending proposal instead of double-proposing. Executed transitions are not: a retry with `kind` omitted targets the *next* available transition. |
| `submit_assessment`  | `changes:propose`                                                          | Records an advisory `agent_assessment` evidence record, citing the measured evidence it interprets                                                                                                                                                                                                                                                                                                                                                                               |
| `annotate_change`    | `changes:propose`                                                          | Writes an `annotation` decision record                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `refresh_evidence`   | `changes:operate`                                                          | Recomputes the change's evidence from the latest stored analysis results                                                                                                                                                                                                                                                                                                                                                                                                         |
| `request_approval`   | `changes:propose`                                                          | Parks a transition in the human approval queue without proposing a specific auto-execution                                                                                                                                                                                                                                                                                                                                                                                       |

## How writes are governed

Even with a write scope, no transition executes unconditionally. The **autonomy resolver** evaluates each request and returns `execute` or `propose`, weighing the caller's scope, the change's computed risk class, the action's direction (risk-decreasing actions like revert are always auto-eligible), guardrail breaches, and whether measured evidence meets the plan's minimums — agent assessments never satisfy that gate. [Approvals and autonomy](/governance/approvals-and-autonomy) covers the full model.

Three connection-level guarantees:

* **No `approve` tool.** Approval happens only in the dashboard transition console, which makes it structurally human. A `proposed` result carries a `consoleUrl` deep link for review.
* **No certified protocol, no traffic.** A change whose plan matches no certified [measurement protocol](/governance/measurement-protocols) cannot begin serving traffic until a human approves a measurement plan.
* **Everything is audited.** Every MCP-originated write lands on the decision log as *"Agent, on behalf of `<human>`, via MCP."*

## Write mode

Lifecycle transitions are **off by default**. A global write mode gates every transition — `request_transition`, and `create_change`'s optional start — with per-organization enablement on top; the effective mode is the lower of the two:

| Mode       | Effect                                                                                                   |
| ---------- | -------------------------------------------------------------------------------------------------------- |
| `off`      | Transitions rejected outright — `create_change` still authors the draft, but its `start` leg is refused  |
| `advisory` | The resolver caps every transition at `propose` — nothing executes, but proposals and notifications flow |
| `execute`  | The resolver's `execute` decisions actually fire                                                         |

Write mode governs the actions that move traffic. The advisory writes — drafting changes, assessments, annotations, evidence refreshes, approval requests — serve no traffic and are bounded by their scopes instead, so they work in any mode.

Read-only tokens carry no write scope and cannot be replayed against write tools; every tool enforces the same per-project access checks as the management API.

## Companion agent skill

For Claude-family agents, the open-source **`traffical-changes`** skill ([github.com/traffical/skills](https://github.com/traffical/skills)) teaches the agent to use these tools well — and to respect the boundary that humans own approvals:

```bash theme={null}
npx skills add traffical/skills
```

It's the operate-time sibling of the build-time [Agent Skill](/tools/agent-skill), which covers parameters, SDK wiring, and config-as-code.

## Next steps

<CardGroup cols={2}>
  <Card title="Changes" icon="diagram-project" href="/concepts/changes">
    What a change is and how its measured lifecycle works.
  </Card>

  <Card title="Approvals and autonomy" icon="scale-balanced" href="/governance/approvals-and-autonomy">
    The full governance model behind execute vs propose.
  </Card>

  <Card title="Agent Skill" icon="robot" href="/tools/agent-skill">
    The build-time skill: setup, parametrizing code, SDK wiring, events.
  </Card>

  <Card title="API overview" icon="book-open" href="/api/overview">
    API key scopes and how authentication works.
  </Card>
</CardGroup>
