# MCP for your agents

> Let Claude Code, Codex or any MCP client see and work with your machines through Muxen.

Everything you do in Muxen, an AI agent can do too. Muxen ships an [MCP](https://modelcontextprotocol.io) server with 88 tools: your machines, sessions, workspaces, files, logs, services, GitHub, runners, VMs, schedules and cloud machines. Ask your agent “which of my machines is low on disk?” or “run the tests on Linux” and it works it out with Muxen.

1. **Your agent**: Claude Code, Codex, Cursor or any MCP client, on this computer.
2. **<code>muxen mcp</code>**: Muxen’s MCP server, started by your agent. It speaks JSON over stdio.
3. **Muxen on this computer**: The same engine the app uses, with the same config, logins and keys.
4. **Your machines**: Reached over ssh or a direct connection, as the app reaches them.

*The MCP server runs on your computer. Nothing new is opened on your machines for it.*

## Set it up

First make sure the `muxen` command is installed: on a Mac, **Settings › General › Command line**; on Windows, the installer offers it. Then print setup snippets that point at your copy:

```
muxen mcp --print-config
```

### Claude Code

```
claude mcp add muxen -- muxen mcp
```

### Codex

In `~/.codex/config.toml`:

```
[mcp_servers.muxen]
command = "muxen"
args = ["mcp"]
```

### Claude Desktop, Cursor and other clients

```
{ "mcpServers": { "muxen": { "command": "muxen", "args": ["mcp"] } } }
```

If your client can’t find `muxen` on its PATH, use the full path that `muxen mcp --print-config` prints.

The app, the CLI and any number of MCP servers can run at once. They share the files in Muxen’s config folder and pick up each other’s changes.

## What to ask

You don’t need to name tools. Some things that work well:

- “What needs attention on my machines?”
- “Why is the runner on beacon offline?”
- “Run the test suite on Linux and tell me what fails.”
- “Start Claude Code on mac-studio in ~/code/api and have it fix issue 632.”
- “What is the Codex session on beacon asking?”
- “Which container is using the most memory on the NAS?”
- “How much did my agents use this week, at API prices?”
- “Copy the build from beacon to my Downloads folder.”

## What it will and won’t do without asking

The tools act on your real machines, as you. The MCP server hands every agent guidance when it connects: read freely, and confirm before changing things.

- **Read-only**, fine to do any time: status and machine checks, lists, logs, ports, processes, screenshots, reading sessions, usage.
- **Only when you asked for exactly that**: installing or removing runners, starting or stopping services and containers, killing processes, typing into sessions or desktops, running commands on several machines, git pushes, VMs and schedules.
- **Costs money**: cloud machines bill by the hour. An agent should tell you the size and price and get your OK before `cloud_create`.

Editing Muxen’s own list of machines (add, remove, rename, connect) only changes `config.toml`, never the machine.

> **Warning:** Your agent client’s permission prompts still apply. Leave approval on for the tools that change things until you trust how your agent uses them.

## The tools

| Area | Tools |
|---|---|
| Overview | `status` (start here), `get_machine`, `check_machines`, `get_settings`, `update_settings` |
| Machines | `list_ssh_hosts`, `add_machine`, `remove_machine`, `rename_machine`, `connect_machine`, `machine_connection`, `direct_connection`, `wake_machine`, `machine_power` |
| Agent sessions | `session_list`, `session_start`, `session_read`, `session_send`, `session_question`, `session_answer`, `session_rename`, `session_restart`, `session_stop` |
| Workspaces | `workspace_create`, `workspace_list`, `workspace_get`, `workspace_exec`, `workspace_read_file`, `workspace_write_file`, `workspace_list_files`, `workspace_changes`, `workspace_sync`, `workspace_destroy`, `workspace_allow` |
| Files | `list_files`, `copy_files` |
| Several machines | `run_on_machines` |
| Logs, services, Docker | `log_sources`, `logs_read`, `machine_services`, `service_action`, `docker_run`, `docker_pull`, `compose_project`, `compose_action` |
| Processes and ports | `machine_processes`, `process_signal`, `machine_ports` |
| Desktops | `desktop_screenshot`, `desktop_input`, `desktop_displays`, `desktop_add_display`, `desktop_remove_display`, `desktop_set_display` |
| GitHub and code | `github_inbox`, `github_repos`, `github_repo`, `github_item`, `github_favorite`, `github_accounts`, `github_use_account`, `local_checkouts`, `git_status`, `git_setup`, `git_sync` |
| Runners and jobs | `github_scopes`, `list_runners`, `list_jobs`, `install_runners`, `runner_action`, `cancel_run` |
| VMs | `vm_options`, `vm_create`, `vm_destroy` |
| Schedules | `schedule_list`, `schedule_save`, `schedule_delete`, `schedule_run`, `schedule_log` |
| Cloud machines | `cloud_options`, `cloud_create`, `cloud_power`, `cloud_usage`, `cloud_destroy` |
| Usage | `agent_usage` |
| Long operations | `get_operation`, `list_operations`, `cancel_operation` |

Every tool describes itself to your agent, so it knows the arguments without this page.

## Ids

| Thing | Looks like |
|---|---|
| Machine | `mac-studio`: a slug of its name. The display name works too. |
| Runner | `mac-studio/mac-studio-01`, or `github/<name>` for one GitHub knows but no machine lists. |
| Agent session | `beacon/claude-3f9a` |
| Workspace | `ws-7f3a2c` |

## Results and errors

Every tool returns JSON. The state can be a few minutes old: `status` uses the last machine check, and says when that was. An agent that needs it fresh calls `check_machines`; checks are read-only.

Failures come back with a `code` the agent can act on:

| Code | Means |
|---|---|
| `not_found` | No machine, runner, session or workspace by that id. |
| `invalid` | A bad argument. |
| `busy` | The machine is already doing a changing operation. One at a time per machine; wait and retry. |
| `github` | GitHub refused, often for a missing permission. |
| `unreachable` | The machine didn’t answer. |
| `operation_failed` | The command ran and failed; the log says why. |
| `internal` | A bug in Muxen. |

Many errors also carry a `hint`, often the exact command that fixes the problem, such as `gh auth refresh -h github.com -s admin:org`. Agents are told to pass it to you as is.

Long operations (installing runners, copying files, creating a VM) wait until they finish and return the end of their log. With `wait: false` the agent gets an operation id instead and checks on it with `get_operation`.

## Without MCP

An agent that can run shell commands but doesn’t speak MCP can use the [command line](https://muxin.dev/docs/cli) instead. Add `--json` to any command for the same results the MCP tools return.
