About Mcpx
Mcpx is an MCP server published by opentokenz in the AI category: mCPX 是运行在开发环境中的 MCP Runtime(网关)。ChatGPT、Claude、Cursor、Grok 及其他支持 Streamable HTTP 的 MCP 客户端,可以通过统一工具面理解项目、查看 Unified Diff、修改源码、运行任务、采集环境信息,并调用本地 MCP 与 Skill。.
The repository has 426 stars and 83 forks, with the last commit 6 days ago. Recent commit activity is the strongest signal that reported issues will get attention.
Install
git clone https://github.com/opentokenz/mcpxThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Mcpx
Powered by Claude · Grounded in docs
Security checks
Static checks derived from the repository 5 days ago. Heuristics on the source, not an audit.
- ✓README presentThe repository ships documentation.
- ✓License declaredUsable under a stated license.
- ✓Tests presentA test suite exists in the repository.
- ✓Dependencies pinnedA lockfile pins dependency versions.
- !No dynamic code executionSource scan found eval or shell execution. Review how tool inputs reach it before granting credentials.
1 check has not been run yet.
Releases
README
MCPX
MCPX 是运行在本地开发环境中的 MCP Runtime(网关)。它通过 Streamable HTTP 把本地 Workspace、源码、变更、命令、任务和扩展能力 安全地提供给 ChatGPT、Claude、Cursor、Grok 等 MCP 客户端。
MCPX 的重点不是增加一个聊天界面,而是提供一套可审计、可恢复、对模型友好 的开发工具协议:客户端可以跨连接恢复同一个 Remote Session,模型可以用文件 SHA、 Edit ID、Task ID 和能力版本避免重复读取和无效重试;Skill/MCP 的 revision 与 schema 一致性由 Runtime 内部管理。
能力概览
| 能力 | 说明 |
|---|---|
| Remote Session | 持久化 Workspace 会话、角色权限、事件、接力和跨客户端恢复 |
| Workspace | 注册多个项目,并在创建会话时显式绑定项目根目录 |
| Source | 文件窗口、批量读取、搜索、文件列表和有界上下文;返回 SHA-256 与编码/换行元数据 |
| Edit | 精确 replacement、批量变更、原子写、SHA 校验和格式保留 |
| Terminal | 执行命令或项目 Task;短命令内联返回,长命令持久化为 Task |
| Project Task | 从项目配置中发现测试、构建和检查任务,并解析诊断信息 |
| Workspace State | 读取 Git 状态、快照、差异、监听结果和项目记忆 |
| Extension | Session 建立时曝光 compact inventory,并通过统一 skill_tool / mcp_tool 按需 list、describe、call |
| Artifact | 注册、列出和分页读取测试报告、构建产物、覆盖率和日志 |
| Screenshot | 截取显示器或屏幕区域,并通过 MCP ImageContent 返回 |
| Security | OAuth、Bearer、Remote Session ACL、命令/文件策略和语义确认 |
| Observation | 通过本机 Socket 观察工具调用、Task、Edit 和操作事件 |
架构
flowchart LR
Client[ChatGPT / Claude / Cursor / Grok] -->|Streamable HTTP /mcp| Runtime[MCPX Runtime]
Runtime --> Session[Remote Session / ACL]
Runtime --> Tools[Core & Support Tools]
Runtime --> Plans[Plan]
Runtime --> Extension[Skill / Upstream MCP]
Runtime --> Observe[Observation / Audit]
Session --> Workspace[(Registered Workspace)]
Tools --> Workspace
Plans --> Tools
Extension --> Skills[Local Skills]
Extension --> Upstream[Upstream MCP Servers]
Runtime --> State[(SQLite State)]
Observe --> State
Tools --> RuntimeData[Task Logs / Artifacts / Snapshots]
MCPX 把客户端连接、持久化 Remote Session、Workspace 能力、执行编排和扩展发现放在同一个
Runtime 边界内;所有有状态操作都绑定 remote_session_id,并通过 SQLite、Task 日志、Artifact
与 Observation 保留可恢复和可审计的执行状态。
公开工具
tools/list 是工具名称、描述、参数 Schema 和 Annotation 的唯一权威来源。
当前公开工具共 15 个,分为 12 个 core tools 和 3 个 support tools:
| 领域 | 工具 | 主要用途 |
|---|---|---|
| Core | workspace |
零参数列出已注册 Workspace,供建立会话前选择 |
| Core | session |
创建、恢复或关闭 Remote Session;省略 action 默认 open/resume |
| Core | read |
读取、搜索、列举或组装 Workspace 源码上下文 |
| Core | edit |
创建、更新或重命名 Workspace 文件;使用 SHA revision guard 和幂等语义,不提供删除 |
| Core | move_out |
prepare 冻结明确的文件/目录/symlink manifest;用户确认后 submit 仅携带 confirmation_uuid |
| Core | observe |
查看 session、Execution Task、Plan Task、history 或 logs;Workspace 静态内容使用 read |
| Core | progress |
发布有业务意义的用户可见里程碑、等待、阻塞或失败状态 |
| Core | execute |
按策略执行命令或项目 Task,以及 attach、stop、stdin |
| Core | plan |
create、read、advance、complete、block、replan、deliver 持久化计划 |
| Core | artifact |
产物登记、列表和分片读取 |
| Core | skill_tool |
Skill 生命周期唯一入口:list、describe、call;Runtime 内部管理 revision |
| Core | mcp_tool |
MCP Server/Tool 唯一入口:list、describe、call;Runtime 内部管理 schema revision |
| Support | runtime_read |
读取运行时能力、项目摘要或适用指令 |
| Support | screenshot_capture |
按明确 purpose 截取显示器或屏幕区域 |
| Support | secret_provide |
按明确 purpose 提供仅驻留内存的 Secret |
workspace 和 session 负责发现 Workspace 与建立/恢复会话;进入 Workspace 后,源码变更、命令、
Plan、Artifact 等有状态操作都以服务端返回的完整 remote_session_id 为关联主键。runtime_read 可在参数足够时独立读取运行时能力、项目摘要或适用指令。
设计边界
MCPX 同时处理两类 Session:
| 标识 | 生命周期 | 用途 |
|---|---|---|
Mcp-Session-Id |
Streamable HTTP 传输层临时标识 | 连接和协议状态,重连或换客户端后可能变化 |
remote_session_id |
SQLite 持久化业务标识 | Workspace、角色、Edit、Task、Plan、文件快照和产物的主键 |
客户端应始终原样保存并复用服务端返回的 remote_session_id、edit_id、plan_id、
plan_task_id、execution_task_id、operation_id 和 artifact_id,不能自行缩写、猜测或从历史日志重建这些标识。
Skill/MCP 的 revision token 不再公开给模型;describe 与 call 之间的一致性由 Runtime 重新校验。
Plan Task 与执行 Task 是不同命名空间,不存在兼容的通用 task_id 字段。
MCPX 只提供 Streamable HTTP 的 /mcp 端点,不提供旧版 HTTP+SSE 的 /sse
或 /message 兼容端点。
部署教程
两篇教程都保持 MCPX 原生运行,保留对本地 Workspace、工具链、截图和扩展能力的访问。原生版直接运行 Caddy/frps/frpc;Docker Compose 版只容器化 Caddy/frps/frpc。两篇文档均包含 OpenAI / ChatGPT Remote MCP 配置示例与截图。
快速开始
环境要求
- Go 1.27.2 或更高版本,具体版本以
go.mod为准。 - 一个需要被 MCPX 管理的本地项目目录。
- 远程访问时需要 HTTPS 反向代理或其他受信任的网络入口。
从源码构建
git clone https://github.com/opentokenz/mcpx.git
cd mcpx
go build -o bin/mcpx ./cmd/mcpx-server
本地静态构建可以关闭 CGO:
CGO_ENABLED=0 go build -o bin/mcpx ./cmd/mcpx-server
普通 VCS 构建会从 Go build info 回填当前 Git revision(工作树有未提交变更时带 -dirty);
正式发布仍以 GoReleaser 的 linker flags 为权威来源,同时注入版本、commit 和真实 build time。
CI 会构建带 provenance 的二进制并通过 mcpx -version 校验 commit/date 未丢失。
启动服务
前台运行:
./bin/mcpx
后台运行:
./bin/mcpx -d
后台模式会记录 daemon 状态到 ~/.mcpx/mcpx-daemon.json,日志写入
~/.mcpx/logs/mcpx-daemon.log。再次启动前台服务或新的后台实例时,MCPX 会先停止
状态文件中仍存活的旧后台进程。
注册或更新一个 Workspace:
./bin/mcpx workspace register /path/to/your/project
服务启动时会校验每个已注册 Workspace 的根路径。若父目录尚不可用(例如外置
磁盘还未挂载),启动会等待该路径出现;等待超时后仍会保留注册并记录 warning,
不会把临时不可用当成已删除。父目录存在但目标目录已消失或不是目录的条目会被
从 config.yaml 中移除,因此已删除的 disposable worktree 不需要手工清理。
然后启动服务:
./bin/mcpx
默认监听地址和 MCP 端点:
http://127.0.0.1:9090/mcp
首次启动会在 ~/.mcpx/(可用 MCPX_HOME 覆盖)初始化运行时目录:
| 路径 | 用途 |
|---|---|
config.yaml |
全局监听、鉴权、安全策略和 Workspace 配置 |
.mcp.json |
全局上游 MCP Server 配置 |
logs/ |
JSONL 审计和运行日志 |
skills/ |
可选的本地 Skill 根目录 |
workspaces.example.yaml |
Workspace 配置示例 |
state/mcpx.db |
Remote Session、Edit、Task、Plan、快照和产物索引 |
tasks/ |
持久终端 Task 的日志文件 |
查看版本和命令帮助:
./bin/mcpx -version
./bin/mcpx -h
主要命令包括:
mcpx [flags] 启动 Streamable HTTP 服务
mcpx stop 停止后台服务
mcpx observe [flags] <name> 终端只读观测 Workspace 事件
mcpx workspace register <path> 注册或更新 Workspace(不启动服务)
mcpx oauth-register [url] 动态注册 OAuth 客户端
mcpx update [flags] 从 GitHub Release 检查并安装新版本
服务进程常用 flags 包括 -addr、-log-level、-log-format、-d 和 -version。
自更新支持:
./bin/mcpx update --check
./bin/mcpx update
./bin/mcpx update --version 0.9.6
update 会选择当前平台对应的 GitHub Release 产物,校验 checksums.txt 中的 SHA-256,
再验证下载后的二进制版本并替换当前可执行文件;访问 GitHub API 需要认证时可使用
GITHUB_TOKEN。
配置
全局配置
全局配置路径为 ~/.mcpx/config.yaml,可用 MCPX_HOME 改变根目录。
下面是一个偏保守的常用配置示例;相比首次生成的默认配置,它把未知命令的默认决策收紧为 confirm:
server:
host: 127.0.0.1
port: 9090
auth:
# open | bearer | oauth | dual
# 留空时:配置 token 则等同 bearer,否则等同 open。
mode: open
token: ""
oauth:
password: ""
server_url: ""
token_ttl: 86400
workspaces:
- name: my-app
path: /Users/you/code/my-app
description: "业务项目"
security:
commands:
# allow | confirm | deny
default: confirm
allow:
- ^pwd$
- ^ls\b
- ^git status
- ^git diff
confirm:
- ^git push
- ^docker
- ^npm install
deny:
- ^rm -rf /
files:
max_read_bytes: 1048576
max_patch_files: 20
max_patch_lines: 2000
deny:
- ^\.git/
limits:
max_result_bytes: 262144
首次生成配置的主要默认值包括:监听 127.0.0.1:9090;Streamable HTTP transport
空闲 Session TTL 为 24h;窗口读取安全预算为 1 MiB,显式 full 源文件硬上限为 4 MiB;
文件策略默认 max_patch_files=20、max_patch_lines=2000,而公开 edit 工具还有独立的
1000 changed-lines 硬上限;工具结果预算为 256 KiB;Terminal、File Watch、Skill 和上游 MCP
发现默认启用。状态保留任务默认每天运行一次,过程事件与终端 Task 默认保留 30 天,模型记忆事件
保留 180 天,环境快照保留 90 天。单个执行 Task 的观测输出最多持久化 32 MiB,超出后观测事件
会标记为截断;完整输出仍通过 Task 日志 Resource URI 读取。
需要特别注意:当前首次生成的 config.yaml 使用 security.commands.default: allow,同时内置
git push / docker / npm install 的 confirm 规则和 rm -rf / / mkfs / shutdown 的
deny 规则;auto_allow_readonly 未显式配置时也会自动允许受支持的只读命令。策略匹配顺序是
deny → confirm → allow → 只读自动放行 → default。共享环境或公网部署建议像上面的示例一样
把默认决策收紧为 confirm 或 deny。公网部署同时不要使用 auth.mode: open,应使用 oauth、
bearer 或 dual,并配置最小权限规则。
项目配置
项目根目录可以放置 .mcpx.yaml,用于覆盖项目描述、项目级安全规则、能力
开关和结果限制。进程级身份凭证不应写在项目配置中。
description: "项目说明"
security:
commands:
default: confirm
上游 MCP
全局配置使用 ~/.mcpx/.mcp.json。项目级按以下顺序合并,后出现的同名 Server 覆盖前面的:
{workspace}/.mcp.json{workspace}/.agents/mcp.json{workspace}/.mcpx/.mcp.json
缺失文件视为空配置。项目级同名 Server 覆盖全局配置;.mcpx/.mcp.json 是 MCPX 原生覆盖层,优先级最高。
{
"mcpServers": {
"github": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
Skill 发现
默认扫描 ~/.mcpx/skills、~/.agents/skills、~/.codex/skills、
~/.grok/skills 和项目 .skills。可以在全局配置中使用
discovery.skills.dirs 和 extra_dirs 增加或替换目录。
状态保留
state.retention 负责定期回收过期的观测、Task 日志、快照和临时记录。
观测事件和已完成 Task 不再因为 Remote Session 处于 active、idle 或 blocked
而永久跳过 TTL 和行数限制;运行中的 Task、被 execute Evidence 引用的 Task、未完成
Plan、未过期确认、有效幂等记录和仍被引用的快照会受到保护。command.output 按执行 Task
合并限制累计观测体量,超限后通过 Task 日志 Resource URI 恢复。保留策略只在全局
config.yaml 中生效。
接入 MCP 客户端
本地 Bearer 客户端
{
"mcpServers": {
"mcpx": {
"url": "http://127.0.0.1:9090/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
将 auth.mode 设置为 bearer,并在 auth.token 中配置 Token。仅本机临时
调试可以使用 open。
网页端 Remote MCP
网页端通常使用 OAuth。先通过反向代理暴露 HTTPS,再配置:
server:
disable_localhost_protection: true
trust_proxy_headers: true
auth:
mode: oauth
oauth:
password: "换成强口令"
server_url: "https://mcp.example.com"
然后将 https://mcp.example.com/mcp 添加到客户端(ChatGPT / Codex Remote MCP)。
OAuth 对齐 OpenAI MCP 鉴权约定 与 MCP Authorization(OAuth 2.1 + PKCE):
- 资源元数据:
/.well-known/oauth-protected-resource(及/mcp路径形态) - 授权服务器元数据:
/.well-known/oauth-authorization-server(含client_id_metadata_document_supported: true,优先 CIMD) - DCR:
POST /mcp/oauth/register(CIMD 不可用时仍可用) - 授权 / 换票:
/mcp/oauth/authorize、/mcp/oauth/token(resource参数 + S256)
ChatGPT 使用 CIMD(client_id 为 https://chatgpt.com/oauth/... 文档 URL)时,
服务端会拉取并校验元数据,并接受
https://chatgpt.com/connector/oauth/{callback_id} 与旧回调
https://chatgpt.com/connector_platform_oauth_redirect。
仍可用手动 DCR 预注册:
./bin/mcpx oauth-register 'https://chatgpt.com/connector/oauth/...'
# 或交互输入回调地址:
./bin/mcpx oauth-register
OAuth 发现与授权端点包括:
GET /.well-known/oauth-protected-resource
GET /.well-known/oauth-authorization-server
POST /mcp/oauth/register
GET|POST /mcp/oauth/authorize
POST /mcp/oauth/token
产品不内置公网隧道服务。反向代理负责 HTTPS、域名和网络暴露,MCPX 负责 MCP 协议、鉴权和 Workspace 访问控制。
握手探测
不要用裸 GET /mcp 判断服务是否可用,使用 MCP initialize 请求:
curl -sS -m 5 \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"0.1"}}}' \
http://127.0.0.1:9090/mcp
响应中出现 mcpx Server 信息表示协议握手成功。
推荐交互流程
1. 建立会话和能力缓存
- Workspace 名称未知时先调用零参数
workspace,从返回清单中选择项目。 - 使用
session(action="open", workspace="...")创建 Remote Session;省略action也默认 open。 - 保存服务端返回的完整
remote_session_id。恢复已有会话时再次调用session(action="open", remote_session_id="..."),不要改写、缩写或重建这个 ID。 sessionbootstrap 已返回工具能力、compact Skill/MCP inventory、适用指令、项目摘要和一组 Runtime revision; 不返回完整 Skill instructions 或 MCP Tool schema。需要单独刷新能力时调用runtime_read(view="capabilities");需要扩展详情时按需调用skill_tool/mcp_tool的describe。- 客户端可以缓存
tool_schema_revision、capability_manifest_revision、guidance_revision、instruction_revision、session_capability_revision和client_protocol_revision,再与后续 bootstrap /runtime_read返回值比较,按变化范围刷新本地缓存。Skill revision 与 MCP Tool schema revision 由 Runtime 在describe → call间维护和复核,不作为公开缓存字段。当前公开 Schema 不接受known_revisions参数。
ARC 2.0 将工具 effect 与 Agent 语义轨迹分开:purpose 只描述本次工具操作的作用,
plan_id、plan_task_id、execution_task_id 用于绑定业务上下文;operation_id 是可选的事件关联标识,不提供异步操作管理能力。Client Protocol Activity V3 直接嵌入会话内 MCP 工具参数:可选 activity 对象允许同一次调用同时提供 intent、hypothesis、evidence、conclusion、next、status,但只应填写本次发生实质变化的字段,不重复未变化内容。intent 是整个工作 turn 的目标并开启新 turn;hypothesis 是待验证且可被推翻的暂定判断;evidence 只写刚获得的可核验事实;conclusion 写由 evidence 支持的当前判断;next 表示立即要执行且与当前 tool call 对齐的动作;status 只用于无法归入前五类的阶段、等待或阻塞变化。Runtime 按固定顺序展开非空字段,并自动生成 turn_id、sequence、state=preparing_action、related_call_id。旧 /mcp/activity HTTP ingress 已移除。服务端只把已经接受并持久化的真实 Activity snapshot 放入 _meta["mcpx.result"].mcpx.result.context.activity 和观测数据;模型侧 structuredContent.context 不再重复 Activity snapshot。ARC 不直接复制 raw tool input,也不会从工具结果反推、伪造 Activity。reasoning_summary、progress_summary、next_step 不再属于 ARC context。
move_out(action="submit") 的业务参数只有 action、remote_session_id、confirmation_uuid;公共可选 activity 只记录公开工作轨迹,不改变 prepare 时由服务端冻结的业务语义。
progress 不作为每个普通工具调用的 heartbeat;过程只在有业务意义的里程碑、等待、阻塞或失败时发布。任务正常完成并准备给用户最终回复前,必须调用一次 progress(status="completed"),用 current 汇总完成状态、result 列出已验证结果。
终端观测使用普通 stdout/stderr pipe,不依赖 PTY、tmux 或 ConPTY。观测事件先写入
durable Store,再通过本地 JSONL 帧推送;observe --format=json、终端 text 渲染和
其他 JSONL 客户端消费同一事件。事件的 phase 表示 action_started、output、
result 或 error,语义上下文字段会在 JSONL、历史和 text observer 中保留。call_id 缺省回退为
request_id 用于内部请求关联;不同客户端接力时使用同一个 remote_session_id,并可结合
workspace 可调用 observe(view="history") 查询历史事件。plan_task_id、execution_task_id 和 operation_id 可用于筛选关联事件。
2. 读取源码
{
"remote_session_id": "rs_...",
"view": "file",
"path": "src/main.ts",
"mode": "window"
}
read(view="file") 返回:
sha256:后续 edit 的base_sha256,始终针对原始文件字节。format.charset:字符集,例如utf-8。format.bom:BOM 状态。format.line_ending和line_ending_counts:LF、CRLF、CR或mixed。format.final_newline:文件是否以换行符结尾。truncated、offset、line_byte_offset和limit:窗口读取状态;续读动作在模型侧统一位于structuredContent.actions。
当字节预算在一条逻辑行中间截断时,offset 会保持在该行,line_byte_offset 表示该行内模型侧 UTF-8 字节位置;服务端生成的 structuredContent.actions continuation 会同时携带二者。续读应原样复用 action arguments,不能只复制 next_offset,否则长行会从行首重复读取。
生成变更时必须保留这些格式元数据。带 UTF-16 BOM 的文件会先以 Unicode 文本呈现,
写回时恢复原字符集和 BOM。完整预览使用单个 path 和
mode="full";完整模式返回 mime_type、完整 SHA-256 和原始格式。源码扩展名
优先按文本处理,例如 TypeScript 返回 text/typescript,不会因系统 MIME 表
把 .ts 误判为 video/mp2t。图片使用 MCP ImageContent,二进制文件使用
Base64 数据。
已知多个文件时,使用同一次 read(view="file", items=[...]) 批量读取,
并通过 max_total_bytes 控制总预算。搜索、列表和上下文读取分别使用
view="search"、view="list" 和 view="context",不要为了确认一个已知路径
先重复列目录。
read(view="list") 同时返回两类结果:files 是递归普通文件分页;entries 是当前
scope 的第一层条目,并以 kind=file|directory|symlink|other 标记类型,不会展开目录内容。
清理“只保留某文件”的 Workspace 前,先读取根 scope 的 entries:只有
entries_complete=true 且 entries_policy_filtered=false 时才能把它当作完整可见根清单。
若存在 entries_next_cursor,按 entries_next_action 读取其余第一层条目;不要从
files 的首个分页推断顶层目录。
3. 修改文件
默认修改路径如下:
read(view="file") → edit → observe(view="diff", edit_id=...)
edit 接收 edits[],支持 create、update、rename;用户提出删除、移除或清理时必须使用专用的
move_out(action="prepare") → 用户确认 → move_out(action="submit") 流程,目标会安全移至操作系统回收站而非永久删除,update 优先使用
精确唯一 replacements。同一请求带 idempotency_key 时,重试返回原终态,
参数变化返回 IDEMPOTENCY_CONFLICT。精确字节写入使用 content_base64、newline_policy: "exact"
和必填的 expected_format: {charset, bom, line_ending},支持 create/update;update 仍须提供旧 base_sha256。
Base64 解码后的文本字节原样落盘,不补换行、不转换 BOM 或编码,也不能同时传入 content/replacements/range。
expected_format 约束最终格式,不触发转换;不匹配时拒绝写入。逻辑文本编辑可用 newline_policy: "preserve" 声明原格式保持语义。
实际成功写入返回 results[].readback,包含 byte_length、sha256、format 与最后最多 16 字节的 tail_hex;预演不返回落盘 readback。
幂等重放返回原操作回执,不声称重放时文件仍未被其他操作修改。
默认只返回有界 diff 预览;需要完整内容时
使用 observe(view="diff", edit_id, offset, limit) 分片读取。
生产限制和破坏性操作契约:完整 read 的源文件上限为 4 MiB,超大文件使用
mode="window" 流式读取;单次 read.items 最多 20 项;edit 最多 1000 条真实变更行。
read(view="list", path=...) 的 path 是硬作用域。
edit 只支持 create、update、rename;删除、移除或清理必须使用同一个 move_out 工具的两阶段 action,
禁止通过 execute、shell、glob 或 symlink 绕过:
move_out(action="prepare")接收 Workspace 内明确的file、directory或symlink目标。它严格只读, 只校验目录根路径,不扫描、哈希或返回目录子项;file 冻结 SHA,symlink 冻结链接文本摘要。响应只返回 最多 20 个显式目标预览、总目标数和 manifest SHA,因此数万文件目录不会撑大模型上下文。purpose必须先表达最终语义:仅检查就写“仅 prepare/仅预览”并停止;用户请求删除、移除或清理时 则从 prepare 开始明确写“安全移至系统回收站”,不能在 submit 时临时改写语义。- 服务端返回
confirmation_uuid、move_request_id、manifest_sha256、原始idempotency_key与expires_at供展示和审计;默认确认有效期为 30 分钟。同时返回 模型侧使用hints.preferred_behavior="ask_confirm"进入确认流程;submit 不作为可自动执行的普通 action。 - 网页端模型向用户展示冻结清单并询问;用户确认后,使用返回的
confirmation_uuid调用move_out(action="submit", remote_session_id=..., confirmation_uuid=...)。move_out(action="submit")的 strict schema 不接受purpose、workspace、targets、idempotency_key、manifest_sha256或其他 prepare 参数。 move_out(action="submit")按 UUID 从服务端取回并重新校验 Workspace 范围、manifest、文件 SHA、过期时间和 purpose;客户端无法覆盖这些冻结值。明确的directory是整体移出根,不扫描其后代;symlink(包括目录确认后被替换的 symlink)只移动链接入口,绝不跟随目标。通过校验后目标进入当前操作系统的 回收站:Windows 使用 Recycle Bin,macOS 使用 Finder Trash(必要时回退到用户~/.Trash),Linux 优先使用gio trash,其次trash-put,均不可用时按 FreeDesktop Trash 规范写入$XDG_DATA_HOME/Trash/{files,info}(未设置时使用~/.local/share/Trash)。返回字段仍使用quarantine_path/quarantine_location表示实际回收站位置或 URI;提交同时写入持久化审计。
安全移出能力支持明确指定的非空目录树和 symlink;目录内的 symlink、特殊文件不会阻断移动,也不会在
prepare 时被逐项核验或回传,但
absolute path、.. 越界和中间 symlink 仍拒绝。move_out 在 MCP tools/list 中采用保守的顶层声明:
readOnlyHint=false、destructiveHint=true、idempotentHint=true、openWorldHint=false;同时通过
mcpx/action_risk 标明 prepare 为 read-only/non-destructive、submit 为 destructive。提交前仍执行注册 Workspace、显式目标、revision guard、
目录不递归展开、symlink 不跟随、用户确认与持久化审计等安全约束;最终文件系统动作由平台回收站机制完成。
示例:
{
"remote_session_id": "rs_...",
"purpose": "根据用户要求修改首页标题",
"idempotency_key": "req-update-home-title-1",
"edits": [
{
"operation": "update",
"path": "src/App.vue",
"base_sha256": "sha256:...",
"replacements": [
{"match": "<h1>旧标题</h1>", "replacement": "<h1>新标题</h1>"}
]
}
]
}
普通变更保持原文件字符集、BOM、换行和末尾换行状态。版本冲突、匹配失败和策略
错误都会返回结构化 error.code、retryable 等错误事实;可执行 continuation/recovery 在模型侧统一放入 structuredContent.actions,不再在 data/error 中重复动作参数。
4. 执行命令和 Task
{
"remote_session_id": "rs_...",
"action": "run",
"command": "go test ./internal/server -count=1",
"purpose": "验证本次服务端变更",
"yield_time_ms": 10000
}
需要参数边界保真时,使用 execute(action="run", argv=["git", "commit", "-m", "修复中文 参数"], shell=false, ...)。
argv[0] 是可执行文件,其余元素原样传给进程,不经过 shell 或二次拆词;空参数、中文、引号和反斜杠均保留。
该模式与 command、task、runtime+script 互斥,必须显式传入 shell=false。
现有命令策略、用途、Workspace 范围、用户确认与幂等键仍生效;确认绑定完整 argv,重试须保留相同参数和 idempotency_key。
策略与审计中的命令文本仅用于展示和检查,实际执行始终使用原始数组。此能力不自动处理 GitHub 未知写入结果或 Git 传输恢复。
execute 的 command 模式支持用 &&、||、;、| 和换行组合简单命令。服务端会在启动 shell 之前解析全部 segment,逐段应用
deny / confirm / allow 策略并记录结构化 command_policy;任一 segment 为 deny 时整条命令拒绝,
任一 segment 为 confirm 时对整条冻结命令进行一次用户确认。只有全部 segment 通过,并且启用的
preflight audit 成功写入后,原始 command 才会一次性交给 shell。重定向留在所属段内一起审计。单个 &、
$() 和反引号命令替换、未加引号的 heredoc,以及悬空的 && / || / ; / | 仍然拒绝。
这里的“全部执行或拒绝”是策略与审计入口的原子 gate,不是文件系统事务或副作用回滚。shell 启动后仍保留
原始条件语义:a && b 只在 a 成功后执行 b,a || b 只在 a 失败后执行 b;已经执行的 segment
产生的副作用不会因后续 segment 失败而自动回滚。
execute(action="run") 默认等待短命令完成;超过等待窗口时返回 execution_task_id。后续
使用已知 ID:
observe(view="task", execution_task_id="task_...")
observe(view="logs", execution_task_id="task_...", stdout_offset=0, stderr_offset=0)
execute(action="attach", execution_task_id="task_...", yield_time_ms=30000)
长命令的状态和日志使用 observe 的 offset/next offset 续读;输出被截断时响应会
直接给出下一次调用模板。stop 和 stdin 通过 execute(action="stop|stdin")
完成,并重新执行权限与 Workspace 校验。
5. Plan、Artifact 与扩展
plan(action="create|read|advance|complete|block|replan|deliver") 只引用服务端
返回的 plan_id、plan_task_id 和结构化 evidence;create.tasks[].local_id 仅在创建请求内解析依赖。典型路径是:
plan(create) → plan(advance) → edit/execute → artifact(register) → plan(complete) → plan(deliver)
产物使用 artifact(action="register|list|read");注册时持久化 source_encoding/source_bom,读取时
source_offset/next_source_offset 始终使用源文件 byte 坐标。UTF-8/UTF-16 文本通过
delivery_encoding=utf-8 返回 text,二进制通过 delivery_encoding=base64 返回 base64,不会把任意字节伪装成文本。
session(action="open") 默认返回 compact extension_inventory:Skill 仅包含用于 relevance routing 的轻量信息,MCP 默认只到 Server 级,不注入完整 Skill instructions 或全部 MCP Tool schema。典型路径:
session(open)
→ skill_tool(action="list|describe|call", ...)
→ mcp_tool(action="list|describe|call", ...)
Skill:不知道有哪些能力时 list;知道名称但缺少使用规则时 describe;信息充分时直接 call。
MCP:不知道 Server 时 list;知道 Server 但不知道 Tools 时 list(server=...);缺少 Tool schema 时 describe;参数充分时 call。
模型不再提交 discovery_id / discovery_revision;Runtime 在 call 前重新检查当前 Skill revision 或 MCP Tool schema,发生变化时返回结构化 recovery,要求重新 describe。
skill_tool 与 mcp_tool 的顶层 MCP annotation 按最坏情况声明为可破坏、开放世界调用;Runtime 再根据本次选中的对象做实际决策。文档型 Skill,以及上游明确标注为只读且 closed-world 的 Tool 可直接调用;可执行 Skill、缺少风险 annotation 的上游 Tool,以及任何可写、可破坏或开放世界调用都会先返回 waiting_confirmation。用户确认后,使用相同业务参数并设置 user_confirmed=true 重试;服务端只接受与当前目标、revision、参数摘要和用途匹配的 pending confirmation。恢复动作不会回显 extension arguments,避免把可能的 Secret 写入错误响应或日志。
MCP 的 call 在同一个已初始化的上游实例内完成 tools/list、schema 校验和 tools/call,不会先检查实例 A、再执行实例 B。Session inventory 与 mcp_tool(action=list) 只返回 Server 名称、description 和状态,用于第一轮 relevance routing;完整 Tool schema 仍需按需 describe。
6. 统一响应
工具默认文本适合模型和宿主直接展示;机器结果同时保存在
structuredContent 和 ARC 元数据 _meta["mcpx.result"]。响应状态包括:
tools/list 为除 mcp_tool 外的 MCPX 工具公布 outputSchema,其描述的是实际返回的
structuredContent 公共结构(status、type、context、data、error、hints、actions),
并对有硬上限的工具通过 x-mcpx-limits 发布与 runtime_read(view="capabilities").limits 同源的限制。
mcp_tool 的 call 动作是上游工具的透明转发代理,其 structuredContent 忠实返回上游结果(可能是数组、对象或基础类型),
因此不声明单一对象的 outputSchema,避免客户端校验拒绝合法的上游非对象输出。
runtime_read(view="capabilities") 的 runtime 同时给出 version、build_commit、build_time、
tool_schema_revision 和 capability 版本信息;旧的顶层 revision alias 不再返回。正式 release/CI
构建由 linker flags 注入真实 build_commit 与 build_time;普通 VCS 构建至少回填 revision/dirty 状态。
| 状态 | 含义 |
|---|---|
succeeded |
操作已成功完成 |
accepted |
长命令已作为持久 Task 启动,按 execution_task_id 继续 |
waiting_confirmation |
需要先向用户展示摘要并获得明确确认 |
interrupted |
执行被中断,但可根据返回 ID 查询状态 |
failed |
业务、策略、版本或运行时失败,应按结构化错误恢复 |
大结果不会在多个字段中重复镜像。Task 日志和 Artifact 可通过以下 Resource URI
读取;Edit Diff 使用 observe(view="diff") 分页:
mcpx://remote-sessions/{remote_session_id}/tasks/{execution_task_id}/logs
mcpx://remote-sessions/{remote_session_id}/artifacts/{artifact_id}
ARC 2.0 的 structuredContent.context 保持精简,只携带当前结果真正存在的业务语义与关联字段:
{
"context": {
"purpose": "验证命令执行结果",
"plan_id": "pl_...",
"plan_task_id": "pt_...",
"execution_task_id": "task_...",
"operation_id": "op_..."
}
}
Activity snapshot 不再复制到模型侧 structuredContent.context;需要用户展示、审计或观测时,从 _meta["mcpx.result"].mcpx.result.context.activity 或 Runtime 观测数据读取。工具 timing 同样不在模型侧 structuredContent 重复,仍保留在 ARC trace metadata 与观测链路。字段不存在时不会为了填满结构而伪造。旧的 reasoning_summary、progress_summary、next_step 不属于公开 ARC context,
语义轨迹统一通过 activity 表达。progress 负责用户可见的阶段与终态:过程按需发布里程碑、等待、阻塞或失败;正常任务在最终回复前固定发布一次 completed,并在 result 中列出已验证结果。新的 session bootstrap 还会返回最新的 model progress state(若存在)。
终端文本按可用信息展示 purpose、最新 Activity 以及 Plan、Plan Task、Execution Task 和事件关联信息;-detail 再追加 call、path 等执行元数据。
本机终端观测
服务运行期间,可以在另一个终端只读观察指定 Workspace:
./bin/mcpx observe my-app
命令使用本机 Socket 订阅服务端事件,不启动第二个 HTTP 服务,不执行工具、命令 或文件修改。启动时回放历史事件,随后实时接收事件;断线后按 sequence 补偿。
可用参数:
-history int 回放最近事件数量,范围 1-100,默认 100
-format text|json 文本或一行一个 JSON 事件,默认 text
-detail 显示语义用途、关联 ID 和执行事实
-diff summary|preview|full 默认 full
-tool string 按工具过滤
-status string 按事件状态过滤
-operation string 按 operation_id 过滤
-path string 按文件路径过滤
示例:
./bin/mcpx observe -format json -history 100 my-app
./bin/mcpx observe -detail -diff full -tool edit my-app
默认 text 模式是持续追加的行式文本流,直接写入 stdout,在终端、管道或重定向场景均可使用;
json 模式每行输出一个完整 JSON 事件,适合脚本与日志采集。
文本流布局保持固定的缩进层级:
- 事件行:状态标记(
•/!/?)+ 语义动作(Read、Edited、Ran、Searched)+ 目标标签; - 事实与结果:2 空格缩进的子行,展示耗时、退出码、结果摘要与失败原因;
- 命令输出:4 空格缩进、行首带行号,并按 stdout / stderr 区分着色。
- Activity 使用单行紧凑格式
◇ Kind 内容,不显示事件时间或额外分隔符;连续 Activity 不插空行。工具调用的purpose使用同样的◇ Purpose 内容单行格式,并在对应工具块之前只显示一次。所有工具交互之间统一只保留一个空行,不输出独立分隔线或墙钟时间;超过终端宽度自动软换行。
颜色层级(ui-ux-pro-max 语义色规范):
- 状态标记使用状态色(失败红 / 等待确认黄 / 运行中蓝 / 成功回退工具色);
- 动作动词使用工具语义色(
Read青、Edited绿、Ran琥珀、Plan黄、Session品红); - 目标标签与结果值保持默认前景色,事实 key(
time、path、exit_code等)使用 muted 次级色; - 命令输出行号使用 muted 色,stdout 弱化(dim)、stderr 黄色;
- 支持真彩色终端时全部语义色升级为 true-color 变体,普通终端降级 ANSI 16 色,
NO_COLOR=1或非终端完全无色。
ARC 内容仍先显示 Read、Edited、Ran、Searched 等语义动作,再按实际存在的字段显示 Context(purpose、最新 Activity、Plan / Task 关联信息)、执行事实和结果;命令 stdout/stderr 带行号。重复的远端 *.started/*.completed notice 默认静默,只保留失败、取消等对人有用的最终结果。ARC 人类展示层继续按工具和状态使用稳定 ANSI 颜色,Diff 默认完整(-diff full),区分新增、删除和上下文;支持真彩色终端时使用真彩色,普通终端降级 ANSI 16 色。设置 NO_COLOR=1 可关闭颜色,COLORTERM=truecolor 或 24bit 启用真彩色;非终端(管道/重定向)自动关闭颜色。
-detail 会追加关联、call、path 等执行元数据;默认视图只展示必要事实,避免与事件行重复。机器处理、重定向或管道场景也可直接使用默认 text 模式,或选择 --format json 获取无格式的完整事件。
事件中保留 event_id、sequence、request_id、关联 ID、plan_task_id、
execution_task_id、edit_id、状态、耗时、路径、命令和截断标志等字段。
安全与数据边界
open只适合本机临时调试;公网必须使用bearer、oauth或dual。- 反向代理场景按需启用
disable_localhost_protection和trust_proxy_headers,并限制可信allowed_origins。 - Remote Session 使用
viewer、editor、approver和owner角色。 - 命令和文件都经过策略匹配;命令可允许、要求确认或拒绝,文件变更还会检查 SHA-256、路径和差异预算。
execute、Skill/MCP 等需要确认的调用可通过user_confirmed表达用户对同一冻结业务请求的确认, 服务端仍会重新执行权限与策略检查;move_out使用独立的prepare → confirmation_uuid → submit协议,submit只接受服务端签发的确认 UUID 和remote_session_id。secret_provide的明文值只在进程内短期使用,不写入 SQLite、Workspace 或日志。- SQLite、Task 日志、OAuth 客户端注册和 Token 密钥位于
~/.mcpx/,运行时使用 受限文件权限;不要把真实 Token、密码或 Secret 写入仓库和命令字符串。 - 截图默认通过 MCP 返回,不写入 Workspace 或 SQLite。
state.retention会清理过期过程事件、已完成 Task、快照和临时记录;运行中的 Task、 被executeEvidence 引用的 Task 和未完成交付状态仍受保护。观测输出超过单任务上限时, 使用 Task 日志 Resource URI 读取被截断部分。
项目开发
仓库结构:
cmd/mcpx-server 服务入口、后台模式、observe、workspace、oauth-register 和 update
internal/server HTTP Gateway、15 个公开工具、Resource、capability 与协议适配
internal/arc ARC 2.0 结果契约、structuredContent、呈现与 trace metadata
internal/remotesession Remote Session、角色、handoff 与持久化事件
internal/edit Edit 解析、原子写、格式保留和变更摘要
internal/deletion move_out 请求、确认凭据和安全移出状态
internal/terminal Execution Task 生命周期、日志、端口和诊断
internal/source 搜索、列表、上下文和批量读取
internal/screenshot 屏幕截图与 MCP 图像/产物返回
internal/observation 事件存储、本机观测、Activity 和终端渲染
internal/auth Bearer、OAuth、Principal 和 ACL
internal/config 全局/项目配置及 MCP/Skill 发现
internal/update GitHub Release 自更新、checksum 和二进制替换
docs/plans 实现计划
docs/specs 设计规格
提交前运行:
gofmt -w ./cmd ./internal
test -z "$(gofmt -l ./cmd ./internal)"
go test ./... -count=1
go test -race ./... -count=1
go vet ./...
CGO_ENABLED=0 go build -o bin/mcpx ./cmd/mcpx-server
git diff --check
更多分支、Pull Request 和发布要求见 CONTRIBUTING.md。
许可与使用边界
本项目使用 Apache License 2.0。MCPX 面向学习、研究和获得授权的 开发环境自动化。使用者需要自行确认 Workspace、命令、凭证、网络入口和数据的 授权范围;在生产环境使用前应完成安全评估、备份、最小权限配置和人工确认流程 验证。本文档不构成安全、法律、医疗、财务或其他专业建议。
Star History
致谢
感谢 LINUX DO 社区:学 AI,上 LINUX DO。
故障排查
- 启动后检查日志中的
endpoint、鉴权模式和 inventory(Workspace / Skill / MCP)。 - 客户端连不上时,先确认 URL 是
/mcp、客户端支持 Streamable HTTP、端口一致且 Token 有效。 401:检查Authorization、OAuth issuer、resource URL 和server_url。/sse或/mcp/sse返回404:这是预期行为;请把客户端改为 Streamable HTTP/mcp。- 客户端看不到新工具:刷新 MCP Server,必要时新建客户端会话以重新获取工具表。
- 截图失败:检查桌面会话、录屏权限和 Linux 截图后端。
Issue #823:Workspace Git 身份推进
带 run_id 的 Session Git 身份读取会在数据库中首次冻结 canonical path、remote 摘要、ref、HEAD/tree 与 Remote Session 关联。之后重新打开 Session 只接受相同身份,execute 的 expected_workspace 也必须匹配已冻结记录,不能通过传入刚观察到的新值绕过。
需要推进候选时,先制作并审核不改变分支的 commit 对象,再以 argv=["git","update-ref",完整冻结ref,新CommitSHA,旧HEAD] 和 workspace_transition={"operation_id":稳定ID,"head":新CommitSHA,"tree":精确treeSHA} 执行。新 commit 必须仅以旧 HEAD 为父提交;Runtime 核对对象及命令,保留 before/after 与 Task 关联,只有持久 Task exit=0 且后置 GitIdentity 完整吻合才原子推进一次。返回 confirmed 的 workspace_post_identity 可用于下一步 push;若 Task 尚在运行,完成后再次打开同一 run/Session 或提交后续明确身份时进行回读恢复。
没有执行回执、回读不同、执行失败或未知结果时不推进、不重新执行原 mutation。普通 git commit 后仅观察新 HEAD 不能成为证明;本合同用预制 commit 对象与带旧值条件的 update-ref 完成分支提交,避免在写入后猜测来源。该候选尚未通过独立 Runtime Review 或真实 Chat 验收。
README fetched from the repository 5 days ago. The original is authoritative.