进程管理工具

MCP Runner是一个用于启动、交互和监控长期运行进程的工具,支持多会话并发、持久化日志和实时监控。

  • by murphysean
  • Rust
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 murphysean/mcp-runner

使用说明

MCP转轮

其中,我编写了一个模型上下文协议(MCP)服务器,该服务器封装了长时间运行的命令,允许代理启动、交互和监视HTTP服务器、调试器或复杂编译任务等进程。

特性

  • 多个并发会话:同时运行多个命令,每个命令都有一个唯一的会话ID
  • 持续日志记录:所有输出记录到 /tmp 文件
  • 增量输出读数:仅返回上次读取后的新输出
  • 灵活的标准错误处理:将stderr与stdout组合或将它们分开
  • 自动清理:当进程退出并且所有输出都被消耗时,会话会自动清理
  • HTTP监控:localhost:8089上的Web界面,用于查看活动会话及其输出
  • 原始字节输入:通过字节数组发送控制字符(Ctrl-A、Ctrl-X等)
  • 等待答复:发送输入后阻塞,收集输出直到空闲
  • MCP 征集:直接提示用户输入密码/秘密,而不会将其暴露给LLM
  • MCP记录:通过MCP日志通知(行缓冲、ANSI剥离)选择进程输出的实时日志流
  • MCP进度:期间的进度通知 await_response_ms 阻塞(当客户端提供进度令牌时)
  • MCP提示:picocom、GDB和Black Magic Probe工作流的内置指南

安装

来自GitHub(推荐)

cargo install --git https://github.com/murphysean/mcp-runner.git

从源代码构建

git clone https://github.com/murphysean/mcp-runner.git
cd mcp-runner
cargo build --release

二进制文件将位于 target/release/mcp-runner

用法

克劳德代码

添加到您的Claude代码配置中 ~/.claude/settings.json:

{
  "mcpServers": {
    "runner": {
      "command": "/path/to/mcp-runner"
    }
  }
}

或者在中使用特定于项目的配置 .claude/settings.json 在您的项目目录中。

基罗

添加到您的Kiro MCP配置中。在Kiro,导航到 设置>MCP服务器 并添加:

{
  "runner": {
    "command": "/path/to/mcp-runner"
  }
}

或者,在以下位置创建或编辑MCP配置文件 ~/.kiro/mcp.json:

{
  "mcpServers": {
    "runner": {
      "command": "/path/to/mcp-runner"
    }
  }
}

其他MCP客户端

添加到MCP客户端配置中:

{
  "mcpServers": {
    "runner": {
      "command": "/path/to/mcp-runner"
    }
  }
}

可用工具

start_command

启动新的命令会话。

参数:

  • command (string,必填):要执行的命令
  • args (字符串数组,可选):命令参数
  • split_stderr (boolean,可选):如果为true,则将stderr与stdout分开(默认值:false)
  • use_pty (布尔值,可选):在伪终端内生成(picocom、gdb TUI等交互式程序需要)
  • stream_log (布尔值,可选):通过MCP日志通知实时将流程输出流式传输到客户端日志。标准输出线发送至 info 级别,标准错误 warning 水平。记录器名称为 session/{id}/stdout 或 session/{id}/stderr默认值:false。

退货: 会话ID

例子:

{
  "command": "python3",
  "args": ["-m", "http.server", "8000"],
  "split_stderr": false
}

send_input

将输入发送到正在运行的命令的stdin。支持文本、原始字节和MCP获取密码。

参数:

  • session_id (字符串,必填):会话ID
  • input (字符串,可选):要发送的文本。Enter/换行符会自动附加会话类型(管道与PTY)的正确行尾。在附加Enter之前,尾部空格会被修剪。
  • bytes (u8数组,可选):要发送的原始字节(例如。 [1, 24] 对于Ctrl-A和Ctrl-X)。没有附加自动Enter。
  • no_enter (boolean,可选):如果为true,则按原样发送文本,不附加Enter。用于部分输入、标签完成等。
  • elicit (布尔值,可选):如果为true,则通过MCP引导直接提示用户(密码永远不会接触LLM)。Enter是自动附加的。
  • elicit_message (字符串,可选):用于启发的自定义提示消息
  • await_response_ms (u64,可选):阻止并收集输出,直到这么多毫秒没有新数据到达

至少一个 input, bytes,或 elicit: true 必须提供。如果 input 如果存在,它优先于 bytes. await_response_ms 与任何输入模式组合。

当 await_response_ms 处于活动状态,客户端提供 _meta.progressToken 在请求中,每秒都会发送进度通知,其中包含经过的时间和收集的字节数。

自动输入行为: 使用时 input,Enter会自动附加——只需发送命令文本即可。根据会话类型选择正确的行尾(\n 对于管道, \r\n PTY)。任何尾随空格(包括 \n 或 \r\n 你可能已经添加了)先修剪,所以 "ls", "ls\n",以及 "ls\r\n" 所有人的行为都一样。

要禁止自动输入,请设置 no_enter: trueThe bytes 参数从不自动附加Enter。

示例:

{"session_id": "1", "input": "print('hello')", "await_response_ms": 1000}
{"session_id": "1", "bytes": [1, 24]}
{"session_id": "1", "elicit": true, "elicit_message": "Enter the sudo password"}

send_signal

向正在运行的命令发送Unix信号(例如,用于中断gdb)。

参数:

  • session_id (字符串,必填):会话ID
  • signal (字符串,必填):信号名称(SIGINT、SIGTERM、SIGKILL、SIGSTOP、SIGCONT、SIGHUP、SIGQUIT)

注: 仅在Unix系统上受支持。

read_output

读取自上次读取以来的新stdout数据。

参数:

  • session_id (字符串,必填):会话ID
  • strip_ansi (布尔值,可选):从输出中删除ANSI转义序列(默认值:true)

退货: 新的输出文本(默认情况下去掉ANSI)

read_stderr

读取自上次读取以来的新stderr数据(仅当 split_stderr 这是真的)。

参数:

  • session_id (字符串,必填):会话ID
  • strip_ansi (布尔值,可选):从输出中删除ANSI转义序列(默认值:true)

退货: 新的stderr文本(默认情况下删除ANSI)

stop_command

停止正在运行的命令。

参数:

  • session_id (字符串,必填):会话ID

delete_session

删除会话并清理其日志文件。如果仍在运行,请先停止进程。

参数:

  • session_id (字符串,必填):会话ID

get_status

获取命令会话的状态。

参数:

  • session_id (字符串,必填):会话ID

退货: 运行状态和退出代码(如果已完成)

HTTP端点

MCP运行器在localhost:8089上提供了一个HTTP接口,用于监控会话:

  • GET / --列出所有会话及其状态和链接
  • GET /session/{id}/stdout --查看当前stdout内容
  • GET /session/{id}/stderr --查看当前stderr内容
  • GET /session/{id}/stdout/stream --stdout的SSE流(如 tail -f)
  • GET /session/{id}/stderr/stream --stderr的SSE流(如 tail -f)
  • GET /session/{id}/stdout/follow --带有自动滚动SSE输出的实时HTML页面
  • GET /session/{id}/stderr/follow --带有自动滚动SSE输出的实时HTML页面
  • GET /session/{id}/input --HTML表单,用于向流程发送文本输入
  • POST /session/{id}/input --向流程提交文本输入
  • GET /session/{id}/password --发送密码输入的HTML表单(掩码字段)
  • POST /session/{id}/password --向流程提交密码输入
  • DELETE /session/{id} --删除会话

ANSI转义码处理

HTTP端点以三种模式处理ANSI转义码(颜色、粗体等):

查询参数 行为
(默认) 将ANSI转换为样式化HTML(颜色、粗体等)
?raw=1 保持ANSI代码不变
?strip=1 剥离ANSI代码,纯文本

示例:

  • GET /session/1/stdout --带有样式输出的HTML
  • GET /session/1/stdout?raw=1 --带有ANSI代码的原始输出
  • GET /session/1/stdout?strip=1 --无ANSI的纯文本

对于SSE流,默认情况下会将ANSI转换为HTML。使用 ?raw=1 保留ANSI代码或 ?strip=1 对于纯文本:

  • GET /session/1/stdout/stream --HTML转换输出
  • GET /session/1/stdout/stream?raw=1 --带有ANSI代码的原始输出
  • GET /session/1/stdout/stream?strip=1 --无ANSI的纯文本

SSE流媒体

这 /session/{id}/stdout/stream 和 /session/{id}/stderr/stream 端点使用服务器发送事件(SSE)实时流式传输输出:

id: 1
data: Hello, world!

id: 2
data: Another line

event: done
data: [process exited]
  • 每个事件都有一个 id 包含从1开始的行号的字段(与编辑器行号匹配)
  • 这 data 字段包含一整行输出
  • 部分行(尚未用换行符终止)将被保留,直到完成
  • 当进程退出时,最终 event: done 消息已发送

从最后一行开始的简历: 包含 Last-Event-ID 带有接收到的最后一个行号的标头:

curl -H "Last-Event-ID: 42" http://localhost:8089/session/1/stdout/stream

JavaScript示例:

const source = new EventSource('/session/1/stdout/stream');
source.onmessage = (e) => console.log(`Line ${e.lastEventId}: ${e.data}`);
source.addEventListener('done', () => source.close());

可用提示

picocom_guide

picocom串行终端使用指南。涵盖了连接到设备、读取输出以及使用原始字节控制序列(Ctrl-a Ctrl-X)优雅退出= [1, 24]).

gdb_guide

通过命令包装器使用GDB的指南。包括启动GDB、使用以下命令发送命令 await_response_ms,使用SIGINT中断执行,以及常见的调试命令。

blackmagic_probe_guide

Black Magic Probe设备调试指南。涵盖探测发现、连接 target extended-remote,SWD在并行picocom会话中扫描、闪烁、调试和监控UART输出。

示例工作流程

  1. 启动web服务器:

    Tool: start_command
    Args: {"command": "python3", "args": ["-m", "http.server", "8000"]}
    Returns: session_id: "1"
    
  2. 检查输出:

    Tool: read_output
    Args: {"session_id": "1"}
    Returns: "Serving HTTP on 0.0.0.0 port 8000..."
    
  3. 检查状态:

    Tool: get_status
    Args: {"session_id": "1"}
    Returns: {"running": true, "exit_code": null}
    
  4. 停止服务器:

    Tool: stop_command
    Args: {"session_id": "1"}
    

实现细节

  • 日志文件创建于 /tmp/mcp_cmd_<session_id>_stdout.log 和 _stderr.log
  • 每个会话在内存中跟踪读取位置
  • 进程退出后会话会持续,因此可以查看输出;使用 delete_session 清理
  • 当MCP服务器关闭时,所有会话都会终止

全部

  • [x] HTTP流:用于实时stdout/stderr流的SSE端点(/session/{id}/stdout/stream, /session/{id}/stderr/stream)
  • [x] HTTP关注页面:显示SSE流的实时HTML页面(/session/{id}/stdout/follow, /session/{id}/stderr/follow)
  • [x] MCP资源:将会话stdout/stderr作为可订阅的MCP资源公开(session://1/stdout).通过推送更新 notify_resource_updated.
  • [x] MCP日志记录通知:通过以下方式实时将流程输出流式传输到客户端登录 notify_logging_message,因此代理可以被动地监视长时间运行的构建或服务器,而无需调用 read_output.
  • [x] 进度通知:发送 notify_progress 更新时 await_response_ms 正在阻塞,因此客户端可以显示经过的时间或解析的构建进度。

许可证

麻省理工学院