AI代理统一工作空间服务器

Maestro是一个MCP服务器,将异构机器群转变为AI代理的统一工作空间,支持跨平台SSH连接、命令执行、文件传输和代码代理分发。

  • by rmstxrx
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 rmstxrx/maestro-mcp

使用说明

🎼 大师MCP

Opus是一首值得由管弦乐队演奏的作品,由一位合适的大师指挥。

大师 是一个MCP服务器,它将异构机器群变成人工智能代理的统一工作空间。SSH连接到任何主机,跨平台运行命令,传输文件和调度编码代理——所有这些都是通过一个编排层完成的。

专为在多台机器上工作并希望他们的AI助手也这样做的开发人员/高级用户而设计。


为什么是大师?

大多数MCP SSH服务器连接到 一个主持人。配置主机名和密钥,即可进入。

但这不是真正的设置是如何工作的。你有一个运行Linux的GPU盒,一台旅行用的MacBook,一个带WSL的Windows工作站——每个都有不同的外壳、不同的路径、不同的功能。你不需要SSH。你需要一个 导体 他了解整个管弦乐队。

Maestro为您的AI代理提供了与您相同的心理模型:命名主机、持久连接、跨平台感知,以及在继续对话的同时将长时间运行的任务分派给编码代理的能力。


特性

  • 命名主机 具有每主机shell感知(Bash、PowerShell、WSL)
  • SSH控制主机 生命周期——具有自动重新连接和指数回退的持久多路复用连接
  • 本地路由 --集线器机器完全绕过SSH,以实现零开销的本地执行
  • 双模式执行 --内联命令(20秒,同步)用于快速操作,分阶段脚本(异步,tmux)用于长时间运行的任务
  • 直接文件I/O — read 和 write SSH上的小文件(≤4KB)具有硬超时
  • 转换继电器 --使用Bearer令牌身份验证通过HTTP端点推送/拉取较大的文件
  • 舰队状态 --通过自动重新连接对所有主机进行一次命令运行状况检查
  • 代理管弦乐队 --派遣 Codex CLI, 双子星命令行工具,或 克劳德代码 作为具有分类账跟踪、实时观察和指导的异步后台任务
  • 任务台账 --在重启后仍能保留任务历史,并自动修剪30天
  • 远程访问 (可选) --OAuth 2.1,带有PIN门控同意,用于通过HTTP暴露Maestro(例如,通过Cloudflare隧道从Claude.ai)

建筑

Maestro在一个 轮毂机 --一个可以通过SSH访问所有其他人。星形拓扑:每台主机都离集线器一跳。轮毂本身有标记 is_local: true 并且在本地执行,没有SSH开销。

调度代理(Codex、Gemini、Claude Code)在运行 集线器本地tmux窗口 SSH连接到目标主机。编排器可以观察它们的输出、发送击键并停止它们——所有这些都不需要进入代理的上下文。

              AI Agent (Claude.ai / Claude Code / Codex CLI)
                         │
                    MCP protocol
                    (stdio or HTTP)
                         │
                  ┌──────┴──────┐
                  │   Maestro   │  ← hub machine (is_local: true)
                  │  ┌────────┐ │
                  │  │ ledger │ │     persistent task history
                  │  └────────┘ │
                  │  ┌────────┐ │
                  │  │  tmux  │ │     agent dispatch windows
                  │  └────────┘ │
                  └──┬───┬───┬──┘
                     │   │   │
              SSH ControlMaster pool
                     │   │   │
                ┌────┘   │   └────┐
                ▼        ▼        ▼
            linux-box  win-pc   macbook
            (bash)     (pwsh)   (bash)
                         │
                         └─► WSL (ProxyCommand)

快速开始

先决条件

  • Python 3.12+
  • SSH配置为 ~/.ssh/config 远程主机的条目(建议使用ControlMaster)
  • MCP-SDK (pip install "mcp[cli]")

1.克隆并安装

git clone https://github.com/rmstxrx/maestro-mcp.git
cd maestro-mcp

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

2.定义您的车队

复制示例配置并对其进行编辑。 关键: hosts.yaml 和 .env 包含敏感数据(IP、主机名、PIN哈希和令牌)。默认情况下,它们被git忽略。 如果你打算将你的分叉推送到公共存储库,千万不要提交这些文件或硬编码敏感的拓扑细节。

cp hosts.example.yaml hosts.yaml
# hosts.yaml — define your machine fleet
hosts:
  workstation:
    alias: ssh-workstation        # must match a Host entry in ~/.ssh/config
    description: "Main dev box, Arch Linux"
    is_local: true                # hub machine — no SSH, direct execution

  gpu-box:
    alias: ssh-gpu
    description: "Training rig, Ubuntu 24.04"
    # shell: bash (default)

  macbook:
    alias: ssh-macbook
    description: "MacBook Pro, on the go"

  windows-pc:
    alias: ssh-winpc
    description: "Windows 11, PowerShell"
    shell: powershell

  windows-wsl:
    alias: ssh-winpc-wsl
    description: "WSL2 on windows-pc (ProxyCommand)"
    # shell: bash (default)

3.设置身份验证

# Generate a PIN hash for the OAuth consent gate
python -c "import hashlib; pin = input('Choose a PIN: '); print(hashlib.sha256(pin.encode()).hexdigest())"

创建您的 .env 文件:

cp .env.example .env
# Edit .env and paste your PIN hash
# .env
MAESTRO_AUTHORIZE_PIN_HASH="your_sha256_hash_here"
SSH_TIMEOUT=300
MAESTRO_ISSUER_URL=https://your-domain.example.com  # Required for HTTP transport
# MAESTRO_TRANSFER_ALLOWED_DIRS="~/,/tmp"           # Paths the relay can write to
# MAESTRO_DEFAULT_REPO=~/workspace                   # Default working dir for agents

4.跑步

# Local MCP client (stdio transport, for Codex CLI / Claude Code / Claude Desktop)
.venv/bin/python server.py --transport stdio

# Remote/cloud access (HTTP transport, for Claude.ai via tunnel)
.venv/bin/python server.py --transport streamable-http --port 8222 --host 127.0.0.1

5.连接您的AI客户端

克劳德代码:

claude mcp add maestro -- /path/to/maestro-mcp/.venv/bin/python /path/to/maestro-mcp/server.py --transport stdio

Codex CLI:

codex mcp add maestro -- /path/to/maestro-mcp/.venv/bin/python /path/to/maestro-mcp/server.py --transport stdio

克劳德桌面 (claude_desktop_config.json):

{
  "mcpServers": {
    "maestro": {
      "command": "/path/to/maestro-mcp/.venv/bin/python",
      "args": ["/path/to/maestro-mcp/server.py", "--transport", "stdio"]
    }
  }
}

Claude.ai (通过Cloudflare隧道或类似方式): 将MCP连接器指向您的隧道URL。Claude.ai客户端会自动处理OAuth同意。


工具参考

车队工具

工具 说明
exec 在任何主机上执行。 上线模式 (command=):同步SSH,20秒硬超时,直接返回stdout/stderr。 分段模式 (task_id=):在tmux中运行一个预置脚本,返回用于轮询的task_id。
read 从任何主机读取文件(≤4KB,超时10秒)。直接返回内容。
write 将文件写入任何主机(≤4KB,超时10秒)。通过stdin传输的内容。
status 通过自动重新连接进行车队健康检查。可选的 agents=True 以探测CLI可用性。
service 启动一个长时间运行的进程(vLLM、Jupyter等)。没有硬天花板——一直跑到停。
observe 从正在运行的任务的tmux窗格中捕获实时输出(约50行)。
steer 向正在运行的任务发送按键(审批提示、Ctrl+C、输入)。
stop 关闭正在运行的任务的tmux窗口。更新分类账。

代理乐团

工具 说明
dispatch 向任何主机发送编码代理(Codex、Gemini或Claude Code)。在集线器本地tmux窗口中运行。返回用于跟踪的task_id。
poll 检查已分派任务的状态。显示已用时间和加班标志。
tasks 从持久分类账中列出最近的任务。按状态、代理、主机或任务类型筛选。
prepare_relay 获取HTTP文件传输中继的临时承载令牌(1h TTL)。
gemini_sessions 列出主机上以前的Gemini CLI会话。

执行层

层级 工具 超时 用例
1 read / write 10秒 文件I/O小于4KB
2 exec 内联 20s 快速命令,无需推理
3 exec 分阶段 6小时 长脚本、构建、部署
4 dispatch 6小时 需要推理的代理任务

文件传输

Maestro提供了两种移动文件的机制:

直接输入输出 (read/write)--用于小文件(≤4KB)。使用SSH,在工具响应中返回内容。快速、简单、一次工具调用。

转换继电器 (prepare_relay +HTTP推/拉)——适用于较大的文件。中继端点接受多部分上传和流下载,并使用临时承载令牌进行身份验证。这使得大型文件内容不会出现在LLM上下文窗口中。

# Get a relay token (via MCP tool)
# prepare_relay → {"value": "abc123...", "ttl_seconds": 3600}

# Push a file to a host
curl -H "Authorization: Bearer abc123..." \
  -F "file=@local_file.py" \
  "https://your-maestro/transfer/push?host=gpu-box&remote_path=/home/user/file.py"

# Pull a file from a host
curl -H "Authorization: Bearer abc123..." \
  -o local_file.py \
  "https://your-maestro/transfer/pull?host=gpu-box&remote_path=/home/user/file.py"

SSH配置提示

Maestro依赖于您现有的 ~/.ssh/config。以下是车队使用的推荐设置:

# Global: enable ControlMaster for all hosts
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600
    ServerAliveInterval 30
    ServerAliveCountMax 3

# Direct hosts
Host ssh-gpu
    HostName 192.168.1.100
    User dev

Host ssh-macbook
    HostName macbook.local
    User user

# Windows host (PowerShell over OpenSSH)
Host ssh-winpc
    HostName 192.168.1.200
    User admin

# WSL via ProxyCommand through Windows host
Host ssh-winpc-wsl
    User user
    ProxyCommand ssh ssh-winpc "wsl -d Ubuntu -e nc localhost 22"
# Don't forget to create the sockets directory
mkdir -p ~/.ssh/sockets

部署

Docker Compose(推荐用于HTTP传输)

services:
  maestro:
    build: .
    container_name: maestro
    restart: unless-stopped
    ports:
      - "8222:8222"
    env_file:
      - ./config/.env
    volumes:
      - ./config/ssh:/mnt/ssh:ro          # SSH keys and config
      - ./config/hosts.yaml:/app/hosts.yaml:ro
      - ./state:/root/.maestro            # Task ledger, OAuth state
      # For is_local hub: mount host paths the relay needs to access
      # - /home/user/workspace:/home/user/workspace
      # - /tmp/maestro:/tmp/maestro

通过Cloudflare隧道进行曝光

如果你想让Claude.ai联系你的Maestro实例:

cloudflared tunnel --url http://localhost:8222

或者作为一个持久的命名隧道——参见 Cloudflare的文档.

作为systemd服务(stdio或HTTP)

# /etc/systemd/system/maestro.service
[Unit]
Description=Maestro MCP Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/maestro-mcp
EnvironmentFile=/path/to/maestro-mcp/.env
ExecStart=/path/to/maestro-mcp/.venv/bin/python server.py --transport streamable-http --port 8222
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

项目结构

maestro-mcp/
├── server.py                  # Entry point — FastMCP wiring, routes, middleware
├── maestro/
│   ├── tools/
│   │   ├── fleet.py           # Fleet tools: exec, read, write, status, observe, steer, stop, service
│   │   └── orchestra.py       # Agent dispatch: codex, gemini, claude, poll, tasks, prepare_relay
│   ├── client.py              # Client classification (remote/local/LAN/stdio)
│   ├── config.py              # MaestroConfig from environment
│   ├── hosts.py               # Host registry, status tracking, command wrapping
│   ├── mux.py                 # Hub-local tmux multiplexer for agent dispatch
│   ├── relay.py               # HTTP file transfer relay (push/pull/task results)
│   └── transport.py           # SSH execution layer (async_run, retries, connection lifecycle)
├── maestro_oauth.py           # OAuth 2.1 provider with PIN-gated consent
├── oauth_rewrite.py           # URL rewrite middleware for multi-origin OAuth
├── hosts.yaml                 # Your fleet definition (git-ignored)
├── hosts.example.yaml         # Example fleet config
├── .env                       # Secrets — PIN hash, tokens (git-ignored)
├── .env.example               # Template for .env
├── docker-compose.yml         # Docker deployment config
├── Dockerfile                 # Container build
├── requirements.txt           # Python dependencies
└── LICENSE                    # Apache 2.0

陷阱

  • Claude.ai工具过滤: Claude.ai的MCP连接器可以无声地过滤其名称或描述暗示凭证生成的工具。如果工具从发现中消失,请检查工具名称和描述中是否有以下术语 token, secret, key, auth, bearer,或 credential,然后重命名并消毒。过滤是基于意图的,而不是纯粹的关键字匹配。

  • 工具定义缓存: 重建Maestro容器后,您必须在Claude.ai设置中完全断开和重新连接MCP连接器。工具定义在OAuth会话级别缓存。

  • 背景预算: 工具响应使用LLM上下文。使用 exec 和 grep, head, tail, jq 用于外科阅读。使用 read 仅适用于4KB以下的文件。对于较大的文件,使用传输中继——响应只是 {"status": "ok"},接近于零的上下文成本。


起源

马埃斯特罗出生于需要。我在多台机器上工作——一台用于推理的Linux机器,一台用于培训的Windows PC,以及一台当我离开办公桌时使用的MacBook。我厌倦了我的人工智能助手一次只能看到一台机器,而我必须手动弥合差距。

最初的简单SSH中继发展成为一个完整的编排层:持久连接、跨平台shell感知、代理调度,最终从Claude.ai远程访问OAuth。这个名字很自然——如果模型是工具,就需要有人来执行。


许可证

Apache 2.0 --自由使用它,无所畏惧地贡献,不要将专利武器化。


贡献

欢迎捐款。如果你想和Maestro一起做点什么,我很想听听。

对于错误报告和功能请求,请打开问题。对于代码贡献,请打开一个PR,清楚地描述更改的内容和原因。