# How to Set Up the MCP Server: Claude Code, Cursor, Codex

> How to set up the MAS MCP server in Claude Code, Cursor or Codex: connect Android, mint a token from an API key, and run a macro from chat.

Source: https://automationmacro.com/docs/mcp (Integrate, updated 2026-09-04)

This page shows how to set up the Macro Automation Studio (MAS) MCP server in Claude Code, Cursor, Codex, Claude Desktop and any other MCP client. The server turns your Android devices into tools an AI client can call. It has two surfaces: the hosted server, with 25 tools on your cloud devices, and the free local connector, with 13 tools on the emulator or phone on your desk.

## Before you start

- For the hosted server: a MAS account with at least one cloud device, and an API key created in the app. See [API keys](/docs/api-keys).
- For the local connector: `adb` on your PATH, a running emulator with ADB switched on (or a phone with USB debugging), Python, and a checkout of the agent package. The app's **Integrations (MCP)** page shows the exact command and working directory.
- An MCP client that calls a remote server over streamable HTTP with a bearer header, or launches a stdio command.

## The two surfaces: cloud devices and a local Android adb MCP server

| | Hosted server | Local connector |
|---|---|---|
| How you reach it | `POST https://api.automationmacro.com/mcp` | `python -m masagent mcp` on your machine |
| Tools | 25 tools: device control, vision, macros and runs, agent authoring, app maps | 13 tools: device control and vision |
| Devices | Your cloud devices | Whatever `adb devices` lists |
| Auth | One-hour bearer token minted from an API key | None |
| Resources | `mas://docs/sdk-reference`, `mas://docs/house-library` | None |
| Cost | Cloud device time and AI credits are billed like the app; device tools carry no per-call charge | Free |

Both surfaces speak JSON-RPC 2.0 at protocol version `2025-06-18`: the hosted server over HTTPS on one stateless endpoint, one JSON reply per POST and no batch requests; the local connector over stdin and stdout, with no network calls of its own. Macro runs, agent authoring and app maps exist only on the hosted server. The full list is on the [tools reference](/docs/mcp/tools).

## Get an MCP bearer token for the hosted server

The hosted server uses OAuth client credentials. Your API key is the client secret; you exchange it for a short-lived access token and send that token as a bearer header. There is no browser sign-in: no login page, no redirect, and no authorization-code flow.

1. In MAS, open **Integrations (MCP)**. Under **Create an MCP credential**, enter a name, tick the scopes you want and click **Create credential & reveal key**. The **API Keys** page creates the same kind of key with an expiry choice. Copy the key now; it starts with `mas_` and is shown once.
2. Exchange the key for a token. Put the key in `MAS_API_KEY` and run:

```bash
curl -s -X POST https://api.automationmacro.com/api/mcp/oauth/token -d grant_type=client_credentials -d client_secret=$MAS_API_KEY
```

3. Read `access_token` from the reply and store it in `MAS_MCP_TOKEN`. The reply also carries `token_type` (`Bearer`), `expires_in` (`3600`) and `scope`, which echoes the key's scopes.

```json
{"access_token":"eyJhbGciOi...","token_type":"Bearer","expires_in":3600,"scope":"devices:control,macros:run,maps:read"}
```

The endpoint also accepts a JSON body or HTTP Basic auth with the key as the password. A revoked, expired or unknown key answers `401` with `invalid_client`. Tokens live one hour; run the command again for a new one. Discovery documents sit under `/.well-known` on the same host.

> [!NOTE]
> On Windows, run the command in Git Bash or WSL, or paste the key in place of `$MAS_API_KEY`. The token, not the key, goes into your client.

## How to set up the MCP server in Claude Code, Cursor and Codex

Each tab shows the hosted server first and the local connector second. Replace `<your token>` with your token, and point the local connector's working directory at the agent package checkout, as the **Integrations (MCP)** page shows.

<div class="doc-tabs" data-tabs="client">
<section data-tab="Claude Code">

Add the hosted server with the token in your environment:

```bash
claude mcp add --transport http mas https://api.automationmacro.com/mcp --header "Authorization: Bearer $MAS_MCP_TOKEN"
```

Add the local connector as a stdio server. Run this from a terminal opened in the agent package checkout so `python -m masagent` resolves:

```bash
claude mcp add mas-local -- python -m masagent mcp
```

To pin the connector to one emulator, pass its adb serial: `claude mcp add mas-local -e MAS_DEVICE=127.0.0.1:5555 -- python -m masagent mcp`. Without it, the connector uses the first device adb lists.

Check the result with `/mcp` inside Claude Code, then ask it to list your devices and take a screenshot.

</section>
<section data-tab="Cursor">

Cursor reads `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` for every project. The hosted server is a remote entry with a header; the local connector is a command:

```json
{
  "mcpServers": {
    "mas": {
      "url": "https://api.automationmacro.com/mcp",
      "headers": { "Authorization": "Bearer <your token>" }
    },
    "macro-automation-local": {
      "command": "python",
      "args": ["-m", "masagent", "mcp"],
      "cwd": "C:/path/to/macro-automation-agent"
    }
  }
}
```

When the token expires after an hour, mint a new one and update the file. Cursor's MCP settings show both servers and their tools.

</section>
<section data-tab="Codex">

Codex CLI adds a streamable HTTP server with `--url` and reads the bearer token from an environment variable:

```bash
codex mcp add mas --url https://api.automationmacro.com/mcp --bearer-token-env-var MAS_MCP_TOKEN
```

Add the local connector as a stdio command:

```bash
codex mcp add mas-local -- python -m masagent mcp
```

Both land in `~/.codex/config.toml`, where you can also set the connector's working directory:

```toml
[mcp_servers.mas]
url = "https://api.automationmacro.com/mcp"
bearer_token_env_var = "MAS_MCP_TOKEN"

[mcp_servers.mas-local]
command = "python"
args = ["-m", "masagent", "mcp"]
cwd = "C:/path/to/macro-automation-agent"
```

Export `MAS_MCP_TOKEN` before you start Codex. When the token expires, export a fresh one and restart.

</section>
<section data-tab="Claude Desktop">

Claude Desktop's config file launches local commands, so the local connector goes in directly. Paste the block the **Integrations (MCP)** page gives you:

```json
{
  "mcpServers": {
    "macro-automation-local": {
      "command": "python",
      "args": ["-m", "masagent", "mcp"],
      "cwd": "C:/path/to/macro-automation-agent"
    }
  }
}
```

Claude Desktop's remote connectors expect an interactive sign-in, which the MAS server does not offer, so the hosted server needs a local bridge that adds the header. The bridge's target is the same remote entry the other clients use:

```json
{
  "mcpServers": {
    "mas": {
      "url": "https://api.automationmacro.com/mcp",
      "headers": { "Authorization": "Bearer <your token>" }
    }
  }
}
```

Restart Claude Desktop after editing the file.

</section>
<section data-tab="Any client">

Send JSON-RPC 2.0 requests as `POST` to `https://api.automationmacro.com/mcp` with `Authorization: Bearer <your token>` and `Content-Type: application/json`. Each POST gets one JSON body back. Call `initialize`, then `tools/list`, then `tools/call`; resources come from `resources/list` and `resources/read`.

```bash
curl -s -X POST https://api.automationmacro.com/mcp \
  -H "Authorization: Bearer $MAS_MCP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

Most clients take the standard `mcpServers` shape, with a remote entry for the hosted server and a command for the local connector:

```json
{
  "mcpServers": {
    "mas": { "type": "http", "url": "https://api.automationmacro.com/mcp", "headers": { "Authorization": "Bearer <your token>" } },
    "mas-local": { "command": "python", "args": ["-m", "masagent", "mcp"] }
  }
}
```

The local connector needs no header; launch it from the agent checkout and pass `--device <serial>` or set `MAS_DEVICE` to choose the emulator.

</section>
</div>

## Try it

Ask your client to list devices: `list_devices` returns your cloud devices with their state on the hosted server, or what adb sees on the local connector. Then ask for a screenshot; the image comes back as MCP image content the model looks at directly.

On the hosted server every device tool needs a lease. `lease_device` opens a control session on one cloud device and returns a `lease_id`; `auto_start` boots a stopped device first. A lease renews on every call, expires after 10 idle minutes, and does not lock the device against a second client. `release_device` ends it and the device keeps running. The typical loop is `list_devices`, `lease_device`, `screenshot`, `tap` or `type_text`, then `release_device`.

Running a saved macro through `run_macro` costs zero AI credits. `author_macro` starts a MAS Agent session and spends credits as it works; see [MAS Agent](/docs/agent).

## Scopes

A key carries the scopes you tick when you create it; none ticked means full access. The hosted server checks the scope before every tool call and returns an error result when the token lacks it. The REST API ignores scopes.

| Scope | Tools it gates |
|---|---|
| `devices:control` | Device control and vision: leases, screenshots, taps, typing, keys, apps, OCR and template matching |
| `macros:run` | Macros and runs: list and read macros, start, check and stop runs |
| `macros:author` | Agent authoring: start, follow, answer and stop a session |
| `maps:read` | App maps: `get_map` |
| `runs:read` | Reserved; no tool requires it today |

## Troubleshooting

### 401 or invalid token

The endpoint answered `{"error":"invalid_token"}`: the `Authorization` header is missing, does not start with `Bearer `, carries the `mas_` key instead of a token, or carries an expired token. Mint a token and send that. A revoked or expired key fails earlier, at the token endpoint, with `invalid_client`; create a new key in the app.

### Token expired after an hour

Tokens live one hour and cannot be extended. Run the token command again. Codex reads the new value from the environment on restart; Cursor and Claude Desktop need it in the config file; Claude Code needs the server removed and re-added, because the shell expanded `$MAS_MCP_TOKEN` at add time.

### No devices listed

On the hosted server, `list_devices` returns your cloud devices; an empty list means the account has none. Create one on the **Cloud Devices** page; see [Cloud devices](/docs/cloud-devices). A stopped device can still be leased with `auto_start`. On the local connector, the tool returns what `adb devices` lists: switch ADB on in the emulator, confirm `adb devices` shows it, and check that `adb` is on the PATH of the process that launched the connector. The error "no device: none connected and no 'device' argument or $MAS_DEVICE" means nothing was found and no serial was named.

### Lease expired

A device tool answered "lease not found or expired". More than 10 idle minutes passed since the last call, the lease belongs to a different key owner, or the server restarted and dropped its in-memory leases. Call `lease_device` again and use the new `lease_id`; nothing on the device is lost.

## Next

The [tools reference](/docs/mcp/tools) lists every tool with its parameters, surface and scope. [API keys](/docs/api-keys) covers key expiry, revocation and limits. The [MCP page](/mcp) has the overview and the FAQ.
