---
title: "Put your coding agent behind Anlyon"
description: "Point Claude Code or Cursor at Anlyon instead of directly at an MCP server, and get approvals and receipts on what it does. No app to build and no end users."
icon: "shield"
---

A coding agent connected straight to an MCP server holds your token and can call every tool on it, with nothing between a wrong call and your production data. Put Anlyon in between. The agent connects to Anlyon alone, Anlyon holds the credential, and each call goes through your approvals and leaves a receipt.

There is no app to build and no end users. The calls use your own connection.

**This only works if the agent has no other way to reach the server.** [Step 5](#5-remove-the-direct-route) is the step that makes the rest count.

## How it cuts risk and effort

- **A wrong call waits for you.** A tool that needs approval sends nothing until a person decides, and that decision is bound to the exact request.
- **The agent sees only what you adopted.** A tool you did not adopt is not offered through Anlyon, and one that changes after you reviewed it stops working until you adopt it again.
- **The token leaves the agent's reach.** Anlyon adds it when the call goes out.
- **You get a record.** Each call leaves a receipt you can read later, in one place across every server.
- **One command sets it up.** Your agent can do most of it. You make the decisions.

## 1. Point your agent at Anlyon

In your project:

```bash title="Claude Code"
npx @anlyonhq/cli setup claude-code
```

```bash title="Cursor"
npx @anlyonhq/cli setup cursor
```

This adds the `anlyon` server to `.mcp.json` or `.cursor/mcp.json`. The file holds a URL and no secret, so it is safe to commit. It also lists the servers your agent can still reach directly, with the command to remove each one. Keep that list for step 5.

Then sign in from your agent, which opens a browser:

- **Claude Code:** run `/mcp`, choose `anlyon` and authenticate.
- **Cursor:** open **Settings**, then **MCP**, and connect `anlyon`.

Keep the key `anlyon` in the config. Hosts prefix a tool's name with its server's key and limit the total, and Anlyon fits its tool names to that key.

## 2. Register the server

Log in, then give the CLI the server's address. Your agent can run these too.

```bash
npx @anlyonhq/cli auth login
npx @anlyonhq/cli mcp add https://mcp.example.com/mcp --header "Authorization: Bearer {{secret:EXAMPLE}}"
```

Fill in the command by how the server signs you in:

| The server takes | Do this |
| --- | --- |
| A token | Store it in the console's **Secrets**, give it an allowed host that matches the server, and pass `--header "Authorization: Bearer {{secret:NAME}}"`. Naming a secret needs the `secrets:read` scope. A person signs that off before the token is sent. |
| An OAuth sign-in | Pass `--oauth`, with `--client-id` if you registered a client with the vendor. A person signs that off, then connects an account on the server's page in the console. |
| Nothing | Pass only the URL. |

The address comes from the vendor's documentation.

Only remote servers using MCP's Streamable HTTP transport can go behind Anlyon. A server your agent starts as a local process cannot.

## 3. Choose the tools and sign them off

```bash
npx @anlyonhq/cli mcp tools example
npx @anlyonhq/cli mcp adopt example list_issues delete_issue
```

`adopt` prints a link and exits 15. A workspace admin opens it, reads each tool's definition, and approves or rejects. **Nothing your agent holds can approve it**, including a key or a login with every scope. That is the point: an agent cannot widen what it may do. See [Sign-offs](/trust-control/sign-offs).

The class shown for a tool is a suggestion from what the server says, and server text is untrusted, so read what a tool does before you adopt it. By default, a tool suggested as `irreversible` or `destructive` waits for approval on every call. To gate everything, pass `--approval all`.

## 4. See the tools in your agent

Each adopted tool appears as `action_<server>-<tool>`, for example `action_example-list_issues`. A very long name is shortened to fit what hosts accept, and ends in a short hash.

Anlyon's list updates within 30 seconds, but a host may keep the list it read when it connected. If a new tool does not appear, reconnect: run `/mcp` in Claude Code, or toggle the server in Cursor's settings. Until then the agent can use `invoke_action` with the action's name.

## 5. Remove the direct route

**An agent that can still reach the server directly bypasses Anlyon.** No approval or receipt applies to that call. Anlyon cannot see it and cannot stop it. So:

1. **Remove the server from your agent's config.** `anlyon setup` lists what it finds in the project's config and your user config, with the command for each. Check for anything else your host loads, such as plugins or extensions.
2. **Remove the credential from the agent's reach.** Take the token out of the config, `.env` files and the shell environment your agent runs in. Better, revoke it and create a new one that Anlyon alone holds. A token the agent can read is a token it can use from a script, whatever its MCP config says.
3. **Check other routes.** A vendor's CLI that is already signed in on your machine, such as `gh`, is a direct route too. Sign it out, or use your host's permission settings to stop your agent running it.

Run `anlyon setup claude-code` or `anlyon setup cursor` again to check the list is empty. It reads MCP config only, so it cannot see a token or a CLI login elsewhere on your machine.

## What a gated call looks like

1. Your agent calls the tool. Nothing is sent. It gets back `Awaiting human approval` and an approval id, and should tell you it is waiting.
2. You decide in the console under **Approvals**, or in [Slack](/trust-control/slack-approvals). Anlyon asks someone other than you when it can: you decide your own agent's request only when nobody else in the environment can.
3. Your agent calls `wait_for_approval`, which waits up to 45 seconds by default and answers `pending` if you have not decided. It calls again.
4. Once you approve, the exact request goes out by itself, and `wait_for_approval` returns the outcome as `invocation`. If you deny, or the approval expires, nothing is ever sent.

A host can put its own limit on how long one tool call may run. Asking for more than the default with `timeoutSeconds` (up to 120) can run into it, and then the call fails while the approval stays open. The approval is not lost: your agent can call `check_approval` with the same id.

## What this does not do

- **It governs calls that go through Anlyon, and only those.** See [step 5](#5-remove-the-direct-route).
- **Remote servers only.** Streamable HTTP over https. No stdio.
- **Receipts grade `acknowledged`.** The server answered. Anlyon does not read the change back, so these never grade `confirmed`. See [Receipts and grades](/execution/outcomes).
- **The suggested class is a suggestion.** It comes from what the server says about itself.
- **Some tools are loosely checked.** Anlyon checks each call's input against the tool's JSON Schema. A tool whose schema it cannot check in full, such as one that points to another file, is still adopted, marked **Loosely checked**: its arguments only have to be a JSON object, and approval is suggested for it. See [How a tool's input is checked](/execution/mcp-servers#how-a-tools-input-is-checked).
- **Your agent can still do damage through what you adopt.** A tool you adopted without approval runs without asking. Use approvals for anything that writes.

## Fix what you will meet

| What you see | Why | What to do |
| --- | --- | --- |
| Exit 15 from `anlyon mcp adopt` | A person has to approve it | Open the link it printed |
| A new tool does not appear | The host kept the list it read at connection | Reconnect the server |
| `Unknown action tool` | The tool was disabled, archived or not adopted | Run `anlyon mcp tools <name>` |
| Tool result naming `tool_changed` | The server changed the tool after you adopted it. Nothing was sent | `anlyon mcp tools <name> --refresh`, then adopt it again |
| `No one has connected <server>` | The server signs people in and no account is connected | Connect one on the server's page in the console |
| `"status": "connect_required"` naming the server | The call was made for an end user (`--end-user` or `ANLYON_END_USER`) who has not connected it. Nothing was sent | Open `connectUrl` as that user, or leave the end user out to use your own connection |
| A tool call times out during `wait_for_approval` | The host's own limit on a tool call | Call `check_approval` with the same id, and use a shorter `timeoutSeconds` |
| `.mcp.json is not plain JSON` | `anlyon setup` will not rewrite a file it cannot read | Fix the file, or add the server by hand |

## Related

- [Govern a remote MCP server](/execution/mcp-servers): the full reference for registering and adopting
- [MCP servers](/agents/mcp-servers): every tool Anlyon's server offers
- [Claude Code](/agents/claude-code) and [Cursor](/agents/cursor): other ways to connect, such as an API key
- [Sign-offs](/trust-control/sign-offs): how a person approves what an agent asks for
- [Approvals](/trust-control/approvals)
