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

# MCP

> Govern MCP with one line: watch_mcp wraps an MCP client session, and every model call, tool call and retrieval lands on the trajectory.

Model Context Protocol servers, from the client side.

```python theme={"system"}
from rotascale.middleware import watch_mcp

session = watch_mcp(mcp_session, server="invoices")
```

That is the whole integration. From here every call the client makes is recorded
on the open trajectory.

## What is distinctive

Records a **manifest digest** of the server's tools on every session. A server that gains a tool between sessions is drift the platform can see, which is the supply-chain question MCP otherwise leaves open. For governing an MCP server without touching the agent, use the [proxy](/sdk/mcp-proxy) instead.

## In context

```python theme={"system"}
from rotascale import Rotascale

client = Rotascale()
agent = client.agent("refund-bot")

with client.witness(agent) as trajectory:
    trajectory.authorize(GRANT, {"tools": ["issue_refund"]}, amount_minor=4_500)
    # ... your MCP calls here, already wrapped ...
```

The `witness` block opens the trajectory and closes it on exit, including when
the body raises — an episode that ended badly is exactly the one worth having a
record of.

## Recording without content

```python theme={"system"}
watch_mcp(session, capture_content=False)
```

Shape and metadata only: model, latency, token counts, tool names. No prompt or
response text. The governed facts are unchanged.

<Tip>
  Authority is never asked for by an adapter. It stays an explicit
  `trajectory.authorize(...)` call, so importing a middleware can never become a
  spend decision. See [authorise an action](/guides/authorise-an-action).
</Tip>
