# MCP endpoint

> Serve MCP at /mcp on zidane-server, so Claude Code, Cursor or another agent drives its sessions with a token.

A server can serve MCP at `/mcp`. An MCP client, such as Claude Code, Cursor or another agent, then drives the server's sessions with two tools, `sessions` and `interactions`. They are the verbs an [orchestrator](https://zidane.si/docs/orchestration.md) session holds. MCP is off by default.

## Turn it on

## 1. Start the server with MCP

```bash
zidane server start --mcp
```

`ZIDANE_SERVER_MCP=1` or `"mcp": true` in `server.json` does the same ([configuration](https://zidane.si/docs/server-config.md)). `zidane server setup --mcp` turns it on in a guided setup.

## 2. Create a token for the client

```bash
zidane server token create --name mcp --scope chat
```

A `chat` token drives sessions and answers questions, plans and tool approvals. The guided setup creates this token for you and prints it once.

## 3. Add the server to the client

```bash
claude mcp add --transport http zidane https://zidane.example.com/mcp --header "Authorization: Bearer zds_…"
```

For Cursor, in `.cursor/mcp.json`:

```json
{ "mcpServers": { "zidane": { "url": "https://zidane.example.com/mcp", "headers": { "Authorization": "Bearer zds_…" } } } }
```

## The tools

| Tool | Verb | Does |
| - | - | - |
| `sessions` | `create` | start a session in a directory with a first prompt (environment: where it runs, e.g. {"kind": "worktree", "branch": "fix/login"} for its own branch and worktree; default local). Returns its sessionId and link. Do NOT wait for it; you will receive a <session-event> in this conversation when it finishes, fails, or needs a decision. |
| `sessions` | `send` | give a running or idle session a new prompt (queued if it is mid-run). |
| `sessions` | `steer` | inject guidance into a session's CURRENT run at its next turn boundary. |
| `sessions` | `cancel` | interrupt a session's run. |
| `sessions` | `read` | a summary of a session; title, cwd, state (idle/running/blocked), last message (cut at 600 characters), turn count, link. full: true returns the whole last message: use it to get a worker's complete report. |
| `sessions` | `list` | other sessions with live status, newest first, capped at 30 by default (raise with limit, max 100); the list may be PARTIAL. worker=true marks the ones you created. |
| `sessions` | `transcript` | the last N turns (default 10, max 50) as plain text, each cut at 1200 characters; full: true returns them whole. |
| `sessions` | `wait` | return once a session is idle or blocked, or after timeout seconds (default 30, max 50). For callers that do not receive <session-event>s; with events, never wait. |
| `sessions` | `events` | search what happened in other sessions (runs that ended, sessions waiting for an answer), newest first: filter by sessionId, status (done/error/cancelled/needs-attention), text, since (an event seq), limit (default 20). Only the sessions you created or sent to report into this conversation; look everything else up here when it matters. |
| `interactions` | `pending` | the prompts waiting for an answer, of one session (sessionId) or all: requestId, sessionId, kind (question/plan/approval), summary, payload (the questions and choices, the plan, or the tool and its input). |
| `interactions` | `answer` | answer one by requestId. The first answer wins: if the person or another orchestrator answered first, you are told so. |

An MCP client may also create orchestrators: `create` takes `tools` and `subscribe` ([orchestrators](https://zidane.si/docs/orchestration.md#orchestrators)). It gets no events, so it calls `wait` (at most 50 seconds, under common client timeouts) and calls again.

## Security

Each tool call runs as a connection that holds the token:

- The token's scope is checked for each call, and refusals go to the audit log.
- The sessions the token creates are tagged with it. Revoking the token stops what it started, and its next call gets a 401.
- The same checks as a WebSocket connection apply: browser origin, proxy and rate limit.
- No token, or a wrong one, gets a 401. A machine token gets a 403.

The [security page](https://zidane.si/docs/server-security.md) covers tokens and scopes.
