# Control tool access

Every MCP server in Catalyst has an **access policy** — an allow-list that decides which caller agents may use which tools. The policy is created automatically with each MCP server and starts **deny-all**: no caller can discover or call any tool until you grant access. You change it at runtime with the `diagrid mcpserver access` commands — no redeploy, no code change.

Catalyst enforces the policy at its [MCP proxy endpoint](https://docs.diagrid.io/develop/mcp/connect), on the hop between the caller and the server:

- **Discovery is filtered.** `tools/list` returns only the tools the calling agent is granted, so an unauthorized tool is invisible rather than merely un-callable.
- **Calls are gated.** An unauthorized `tools/call` is rejected with `403 Forbidden` before the request reaches the upstream server. With a full deny-all policy the MCP session itself is refused.

## Prerequisites

- An [`MCPServer`](https://docs.diagrid.io/operate/project-operations/mcp-servers) connection in your project.
- The [Diagrid CLI](https://docs.diagrid.io/references/catalyst/catalyst-cli-intro), authenticated with `diagrid login`.

## See the current policy

A new MCP server denies everything. Inspect its policy at any time:

```bash
# Full detail for one server
diagrid mcpserver access get mcp-server

# Every server's policy in the project
diagrid mcpserver access list
```

For a brand-new server, `get` reports a deny-all policy with no rules.

## Grant access to specific tools

Grant an agent access to one or more named tools. A rule is an allow-list entry: it names a **caller** (an agent, or `*` for any) and the **tools** it may use (names, or `*` for all).

```bash
diagrid mcpserver access grant mcp-server \
  --caller analyst-agent \
  --allow-tools add,echo \
  --wait
```

`analyst-agent` can now discover and call `add` and `echo`. Any other tool stays hidden in `tools/list` and returns `403` if called. Every other caller is still denied.

:::note
A policy change is rolled out to the data plane before it takes effect, which takes a few seconds. Apply one change at a time and pass `--wait`, or preview a verdict instantly with [`access test`](#preview-a-verdict).
:::

## Open a server to all callers

To allow every caller every tool — useful for a trusted internal server — use wildcards:

```bash
diagrid mcpserver access grant mcp-server --caller "*" --allow-tools "*" --wait
```

## Revoke access

Remove specific tool grants, or a caller's entire rule:

```bash
# Remove only the echo grant; analyst-agent keeps add
diagrid mcpserver access revoke mcp-server --caller analyst-agent --allow-tools echo

# Remove the caller's whole rule
diagrid mcpserver access revoke mcp-server --caller analyst-agent --all
```

## Preview a verdict

`access test` evaluates a hypothetical call locally with the same policy the data plane enforces. It does not call the upstream server and does not wait for a rollout, so it's the fastest way to confirm a rule before your agent runs:

```bash
diagrid mcpserver access test mcp-server \
  --caller analyst-agent \
  --tool get_weather_alert
# → ALLOWED: ...   or   DENIED: ...
```

## How the policy is structured

Under the hood, each MCP server has exactly one `MCPServerAccessPolicy` resource (`cra.diagrid.io/v1beta1`), named the same as the server and lifecycle-locked to it — Catalyst creates and deletes it with the server, and you edit only its rules through the CLI. You don't author this resource by hand; the structure below is what the `access` commands manage for you.

```yaml
apiVersion: cra.diagrid.io/v1beta1
kind: MCPServerAccessPolicy
metadata:
  name: mcp-server          # matches the MCPServer name (1:1)
spec:
  mcpServerRef: mcp-server
  rules:                    # empty ⇒ deny everything
    - callers:
        - appID: analyst-agent   # exact App ID, or "*" for any caller
      grants:
        - capability: tools       # the unit of authorization today
          names: ["add", "echo"]  # tool names, or "*" for all
```

A call is allowed only if some rule matches both the caller and the tool; otherwise it is denied.

## What's next

- [Connect an MCP client](https://docs.diagrid.io/develop/mcp/connect) — point your agent at the server and see the policy take effect.
- [Authentication](https://docs.diagrid.io/develop/mcp/mcp-authentication) — how callers authenticate to Catalyst and Catalyst to the upstream server.
- [Security and trust posture](https://docs.diagrid.io/concepts/mcp/mcp-security-posture) — the identity, authorization, and audit model behind these controls.
