> ## 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.

# Govern an MCP server

> Put a grant in front of tools an agent calls over MCP, including tools somebody else wrote.

MCP is where the governance problem gets sharper, because the tools an agent
reaches may not be yours. You are the authority layer for software you did not
write.

## Two shapes

<CardGroup cols={2}>
  <Card title="Proxy" icon="shuffle">
    Sit in front of an existing MCP server. Tool calls pass through and each one
    is authorised against a grant before it reaches the upstream.
  </Card>

  <Card title="Guarded server" icon="shield">
    Expose your own tools with authorisation built in, so there is no unguarded
    path to them at all.
  </Card>
</CardGroup>

```bash theme={"system"}
pip install rotascale-mcp
```

## Mapping tools to grants

The proxy resolves a grant per tool, so a server exposing ten tools is not one
authority. A read tool and a tool that moves money should not be behind the same
bound, and putting them there is the mistake this is meant to prevent.

## Untrusted by default

Content returned by a third-party MCP tool is untrusted unless you say
otherwise. That is the correct default here more than anywhere else: the whole
premise of an open tool ecosystem is that you did not write the thing on the
other end.

Where a tool result feeds an action requiring a clean context, gate 5 refuses it
and the record names the tool and the step. See
[Clean context](/concepts/clean-context).

## What OAuth scopes cannot do

An agent platform handing out OAuth scopes is granting a permission it cannot
recall and cannot bound. The scope has no ceiling, no expiry it controls, and no
attribution to a person.

A grant has all three, which is why the authority for an MCP tool call belongs
in the grant rather than in the token the tool accepts.

## Recording the call

```python theme={"system"}
t.tool_call("mcp:vendor.search", trusted=False, server="vendor-mcp")
```

The record carries which server, which tool, and whether its output was trusted,
so a reviewer can see the boundary the agent crossed rather than inferring it.
