mcpField
Y
Yapitalism

Yapitalism

本地服务
yapitalism.comAI 与智能体72 周前更新

关于 Yapitalism

Yapitalism 是供语音客户端操作终端编码 Agent 的本地 MCP 服务,并报告经验证的交付与任务轮次状态。回执用于区分已证实的处理和未经确认的写入。

主要功能

  1. 01语音客户端访问终端 Agent
  2. 02发送并等待 Agent 任务
  3. 03提供交付状态回执
  4. 04报告 Agent 轮次状态
  5. 05命名窗格并连接对等机器

适用场景

  1. 01离开办公桌时发送编码任务
  2. 02确认 Agent 是否收到请求
  3. 03发现需要用户输入的提示
  4. 04跨机器监看 Agent 会话

MCP 相关

MCP 服务提供列出、读取、发送消息、等待、命名、创建和恢复 Agent 窗格的工具。MCP 客户端在本地连接;配置的对等服务也可按机器命名空间提供窗格。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"aytuncyildizli-yapitalism": {
"command": "uvx",
"args": [
"yapitalism"
]
}
}
}
启动命令uvx yapitalism

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiyapitalism0.6.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Yapitalism

通过语音驱动终端编码 Agent,绝不让回复声称超出证据所能证明的内容。

你不在办公桌前。你开口说话;终端中的 Agent 开始工作;然后你会收到语音回复。那是你能得到的全部——你看不到屏幕。因此,最糟糕的失败不是程序崩溃,而是语音说“完成了”,你的文字却还未读地留在提示框中。

Yapitalism 是一款本地 MCP 服务,让语音客户端能够访问你的编码 Agent;它还配备了回执层,用于判定语音可以说什么。如果你在办公桌前,就看屏幕——它是为你不在时准备的。

公开预发布版。仅限本地使用。不会部署到生产环境,不支持外部消息传递,也不会自动化操作闭源客户端。

它如何协同工作

MCP client (Codex · Hermes · Claude Code · Claude Desktop · Cursor)
    │  MCP over loopback — no public endpoint, no OAuth, no relay
    ▼
yapitalism MCP server          panes_list · pane_read · pane_send
    │                          pane_await · pane_task
    │                          panes_name · panes_unname
    │                          panes_create · panes_resume · pane_clear
    ├── superset backend       local host-service over tRPC (127.0.0.1:48900)
    └── tmux backend           capture-pane / send-keys

它支持的 Agent:codex、claude、kimi、opencode——通过实际测量识别(在 tmux 上检查进程树,在 Superset 上使用主机自身的 Agent 注册表),绝不依赖调用方的声称。若窗格运行的是其他内容,则会拒绝操作,因为向 Shell 输入内容并按下 Enter 就是在运行命令。

语音客户端不会直接访问你的机器:它会驱动本地 Agent 会话,而该会话通过 127.0.0.1 与此服务通信。没有任何内容会暴露到网络上。

关键所在:回执

pane_send 返回的是判定结果,而不是含糊其辞。

含义
GREENAgent 回显了一次性标记。这可以证明它收到了文本并进行了处理——但这并不代表它随后完成的工作正确;没有任何回执能保证这一点,而此回执也无意作出这种保证。
YELLOW写入已成功;但未能证明文本已被处理。绝不要把它当成更好的结果。
RED后端拒绝了写入。没有内容到达终端。

YELLOW 正是这一机制的意义所在。从外部看,留在 Agent 输入框中但尚未提交的文本,与正在进行的工作毫无区别——同样的旋转指示器、同样滚动的输出、同样的 HTTP 200。若语音把它说成“完成了”,你可能要过好几个小时才会发现问题。

以下情况明确不算接受:HTTP 2xx、PTY 写入成功返回、终端输出发生变化、修订版本前进,或提示框回显了你输入的文字。

等待不等于失败

固定期限只能报告时间已到,不能说明 Agent 的状态。一个 Agent 思考一分钟后给出正确答案,其实一直都在被验证;若把这种情况判为 YELLOW,就会让操作者学会忽视 YELLOW。因此,等待采用的是空闲超时:只要窗格发生变化,计时就会重新开始,但仍受硬性上限约束。

窗格是否变化只决定是否继续等待,绝不能作为接受的证据——接受与否仍只由金丝雀标记判定。因此,YELLOW 会说明具体是哪种情况:

  • canary_timeout_pane_moving — 窗格文本仍在变化。名称反映了实际测量的内容:旋转指示器、时钟、日志尾部输出,或与目标 Agent 共用窗格的另一个 Agent,都可能导致这种情况,即使目标 Agent 什么也没做。它只是提示你可以再查看一次,绝不代表 Agent 正在工作。
  • canary_timeout_pane_still — 完全没有变化。

无法消除的限制是:如果 Agent 默默忽略了文本且没有输出任何内容,就没有任何机制能区分这种情况与 Agent 根本没有收到文本。验证需要 Agent 输出一些内容。

第二份回执:这一轮如何结束

送达只是基本要求;更昂贵的失败是:你以为 Agent 正在工作,它却对一个是非问题卡了 40 分钟。pane_await 会监视窗格,直到 Agent 的轮次结束,并说明结束方式;pane_task 则将发送和等待合并为一次调用——发出指令,离开一会儿,再回来查看以下结果之一:

轮次含义
ended提示词处于空闲状态,屏幕停止变化。此轮已结束——必须同时说明“这不代表工作正确”,绝不能说成“已完成”。
waiting_input阻塞式对话框占据了屏幕(信任/登录/确认)。阻塞流程的是你,而负载中的 tail 会带上问题,方便引用。
agent_error屏幕上出现已知的失败信息——Please run /login、401、速率限制——会直接指出,不会等到超时。
exited窗格中已没有运行中的 Agent。
running超时时仍在变化。尚无定论;可选择进一步查看。

判定为 ended 前,会再次验证 Agent 进程仍在运行:不能把已退出窗格上冻结的提示词当作一轮已结束来庆祝。

按传输方式确定谁可以写入

Bearer 令牌回答的是谁在调用,却从未回答过调用者可以做什么。从 0.5.0 起:stdio 客户端始终可以写入——操作系统允许客户端启动进程时,就已作出信任决定。默认关闭通过 HTTP 写入,每次拒绝都会说明如何解决:在那台机器上运行一次 yapitalism authority allow-http-writes(运行 yapitalism setup 时也会询问同样的问题,并打印 HTTP 注册行)。无论使用哪种传输方式,读取、监视和 doctor 都可正常使用;yapitalism-mcp --read-only 则会在所有地方关闭写入——先安装监视器,等它值得信任后再允许写入。每个写入结果都会带上其 origin。

在 tmux 中,发送路径还会固定获准 Agent 的身份(PID + 启动时间),并在按 Enter 前重新验证。如果 Agent 在输入和提交之间退出并返回 shell,文本会暂存,但绝不会提交——输入可以恢复,向 shell 按 Enter 则会执行命令。

检查发生在哪里

大多数时候,这不会改变你的操作,而且不会朗读出来。相关信息会显示在负载和 yapitalism setup 中;当出现问题、你想知道写入前实际检查了什么时,可以查看这些信息。

含义
host主机本身拒绝写入——检查和写入是同一项操作
client此进程先检查,再写入;对于它覆盖的范围检查有效,但不是原子操作
none不执行任何检查
{ "status": "GREEN",
  "client_guarantees": ["idempotent_dispatch", "empty_prompt_check"],
  "missing_guarantees": ["optimistic_revision"] }

yapitalism setup 会打印适用于你这台机器的表格。目前两个后端的大部分检查都属于 client:检查在这里进行,随后才执行写入,而不是由主机与写入原子地一并完成。tmux 完全无法进行版本检查。

**目前发布的 Superset 都不会自行强制执行这些检查,而此工具过去曾声称自己会。**它仅因一个名为 terminal.send 的过程被路由,就认定为“受保护”。Superset 实际提供的 terminal.send 接收 {terminalId, workspaceId, text, submit},不执行任何保护。现在,这些级别是根据主机自身的验证器要求确定的——名称和契约并不是一回事。

两个后端都能达到 GREEN,而无论使用哪种后端,GREEN 的含义都相同:Agent 发出了单次标记,因此它已收到文本并进行处理。该表格用于诊断机器,不必每次发送时都据此判断。

审查此仓库

无论你是本人,还是被人问到“我该安装这个吗?”的 Agent,都可以查看值得核实的声明及其出处——请自行验证,不要只听我们说:

  • 权限及其边界,包括共享机器暴露风险和故障时拒绝访问的 bearer 门禁:SECURITY.md。
  • 调用者绝对无法执行的操作(封闭的启动器表、拒绝非 Agent、拒绝被占用的提示词、按窗格串行化):src/yapitalism/mcp/tmux.py 和 src/yapitalism/mcp/backends/;每项防护都有一个以其所防止的故障命名的测试。
  • GREEN 声称了什么,又没有声称什么:上文的回执部分,以及 tests/test_canary.py,其中说明了为什么回显无法满足要求。
  • 本项目过去过度夸大的说法,以及按名称撤回这些说法的记录:CHANGELOG.md,0.2.0 至 0.2.4。

机器也是窗格

对等端是另一台机器上的 yapitalism 服务,以它自己的命名空间挂载:机器 studio 上的 codex 窗格 tmux:%0,在这里就是 studio:tmux:%0,位于同一个 panes_list 中,也可以通过同一个 pane_send 寻址。回执会原样传递——对等端在自己的终端旁验证了回执,而这一端只会给 ID 加上机器名称。

# on the peer (reachable over your tailnet):
YAPITALISM_MCP_HOST=100.x.y.z yapitalism-mcp   # tailnet bind requires the bearer gate

# on this machine:
yapitalism peers add studio http://100.x.y.z:8792/mcp --token-file <peer's token>

peers add 会先验证对等端能否作为 yapitalism 服务响应,然后才写入任何内容。除非明确指定 allow_public,否则会拒绝使用公共地址的对等端;tailnet 是传输方式,不代表信任关系——仍由对等端的 bearer token 决定谁可以调用。已配置的对等端会在 yapitalism doctor 中显示实时窗格数量。

也可以在对等端启动和恢复 Agent:panes_create 和 panes_resume 接受一个用于指定对等端的 machine 参数。对等端会运行自己的完整门禁链——远程启动 Agent 的权限比向 Agent 输入内容更大,因此它有自己的开关,默认关闭: 只需在对等端运行一次 yapitalism authority allow-remote-create。若要让对等端的服务在重启后继续运行,yapitalism service --host <its tailnet IP> 会输出已填好的 launchd plist 或 systemd unit;是否安装由你决定。

说名称,不说 ID

语音无法说出 mbp3:tmux:%2。只需将一个词绑定到窗格一次——

panes_name("billing", "tmux:%4")

——之后每个工具都可以使用 billing。绑定会记录命名时窗格运行的内容,并在每次使用时根据实时列表重新验证:tmux 会重复使用窗格 ID,因此如果窗格已消失或运行环境发生变化,名称会连同原因一起被拒绝,绝不会悄悄指向其他窗格。不进行模糊匹配——“大概是正确的 codex”不是有效目标。名称会显示在 panes_list 中对应的窗格上。

妥善使用

桥接 Agent 在有常驻指令时表现最佳——说出回执,绝不重新发送 YELLOW,并像称呼人一样给窗格命名。我们使用的准确提示词见 docs/operator-prompt.md;请将其粘贴到语音客户端的自定义指令中。

示例

六种工具可以组合成值得使用的监控器:权限监控(不会让任何事项静默地停在对话框中——它首次真正捕获到的问题,是某个 Agent 静默等待钱包交易审批)、服务提供商中断监控、每日结束摘要。可用的提示词见 docs/recipes.md。

安装

需要 Python 3.11+ 和 tmux,适用于 macOS 或 Linux —— 每次发布都会在纯净的 python:3.11-slim 容器中完整测试发送并验证的流程,而不只是默认认为它具备可移植性。所有操作都在你的机器上运行;不会向网络公开任何内容。

# 1. install
pipx install yapitalism        # or: uv tool install yapitalism / pip install yapitalism

# 2. start the server (loopback only — it refuses to bind anything else)
yapitalism-mcp

# 3. point your voice client's agent at it, in another shell
codex mcp add yapitalism --url http://127.0.0.1:8792/mcp

# 4. ask the tool what your machine can actually do
yapitalism setup

setup 会检查机器,而不是只打印“安装成功”:哪些后端可用、PATH 中有哪些 Agent CLI、Superset 主机是否在线以及运行的是哪个版本,并为你填写上面的保证表。除非你同意,否则它不会写入任何内容;如果你同意,它只会写入 Superset 清单,并明确指出仍缺少什么,以及每项对应的准确命令。

然后对语音应用说:“列出我的窗格”,再说:“把这个发送到 Codex 窗格”。任何 MCP 客户端的用法都相同 —— yapitalism setup 会针对运行它的那台机器,打印 Hermes、Claude Code、Claude Desktop 和 Cursor 的注册信息。

如果 8792 端口已被占用,可用 YAPITALISM_MCP_PORT 更改端口。YAPITALISM_TMUX_SOCKET 用于指定非默认的 tmux 服务端。HTTP 传输默认需要 Bearer 令牌 —— 回环地址不能作为用户边界,因此服务端会在首次启动时生成一个令牌,而 yapitalism setup 会打印包含该令牌的注册行。YAPITALISM_MCP_TOKEN 可覆盖该令牌;设置 YAPITALISM_MCP_INSECURE=1 可选择不使用令牌。stdio 无需令牌:操作系统已经决定哪些进程可以与生成的进程通信。

由客户端自行启动服务端的客户端

Codex 使用 URL。Claude Desktop、Cursor 和大多数其他 MCP 客户端则会生成进程,并通过 stdin/stdout 通信,因此应将它们指向 --stdio,而不要单独运行服务端:

{
  "mcpServers": {
    "yapitalism": {
      "command": "yapitalism-mcp",
      "args": ["--stdio"]
    }
  }
}

如果客户端无法继承你的 PATH,请使用 command -v yapitalism-mcp 返回的绝对路径 —— macOS 上的 GUI 应用通常无法继承该路径。对于只允许设置环境变量的客户端,设置 YAPITALISM_MCP_TRANSPORT=stdio 与使用该标志效果相同。

在 stdio 模式下,stdout 只能输出协议内容,因此服务端会抑制自身的启动横幅。如果用 shell 脚本包装它,该脚本也必须保持静默。

保持运行

服务端停止运行时,语音路由也会失效,因此应使用 init 系统运行,而不是在终端中运行。这两种单元都会以你的用户身份运行,绝不会以 root 身份运行:服务端可以读取你能看到的所有终端。

  • macOS —— .agents/launchd/。plist 是一个模板;其 README 中有一行 sed 命令,用于填入实际的二进制文件路径,因为 launchd 既不会搜索 PATH,也不会搜索 ~。
  • Linux —— .agents/systemd/,一个 --user 单元。systemctl --user enable --now yapitalism-mcp。

无论使用哪种方式,都要先终止任何 shell 实例,否则两个实例会争用 8792 端口,由谁胜出取决于时机。

Superset 终端(可选)

tmux 后端无需任何额外配置。Superset 需要一个权限为 0600、包含主机端点和令牌的清单 —— 你不必手动编写,因为 Superset 已经会写入所需内容:

yapitalism superset setup            # shows what it found and would do
yapitalism superset setup --confirm  # writes it

该命令会读取应用自身的 ~/.superset/host/<organizationId>/manifest.json,验证令牌是否可用于在线主机,选择默认终端,并写入 ~/.cache/superset-watch-voice/yapitalism-manifest.json(或 $YAPITALISM_SUPERSET_MANIFEST)。它不会自行猜测,而是会拒绝继续:源文件权限宽于 0600、清单指向已停止的进程,或有两个在线组织且无法选择时,都会导致操作停止。绝不会打印令牌。

没有清单时,panes_list 仍会返回你的 tmux 窗格,并在 errors 中报告 Superset 的情况 —— 无法访问的后端绝不会被悄悄报告为“没有终端”。

教会语音如何读出回执

.agents/skills/superset-operator/ 包含相应策略,防止模型把 YELLOW 擅自说成“已完成”,还会检查该策略与你的 Agent 实际加载的副本是否存在偏差。

收据核心,可独立运行

无需 MCP 服务也可使用五阶段模型:

  1. capture — 捕获了意图
  2. dispatch — 向具体目标尝试写入
  3. accept — 目标通过 canary 或明确确认表明已接受
  4. work — 观察到了实质性的 Agent 进展
  5. deliver — 向用户发送了最终更新

证据带有来源信息 — api、terminal_diff、ui_observation、user_report、inferred — 且 inferred 绝不能标记某个阶段为成功。

本项目缘起的事故是:音频会话仍然保持连接,语音进度播报却停止了;两个 180 秒的监视器 都看到终端停在版本 920118,canary 始终没有到达 — 与此同时,语音仍在暗示工作正在进行。这个产品不是“修复语音客户端”,而是绝不伪造 GREEN。

CLI 提供:doctor、receipt show、ledger verify|manifest|migrate 和 superset status|send。 要确认 superset send,必须复用试运行所生成的确切 client-token,在发送前立即创建快照, 拒绝版本已变更的情况,且绝不重试结果不明的 POST。

已知限制

坦率说明这些限制,因为夸大能力的收据系统还不如没有:

  • 无法检测尾部截断。 删除 ledger 的最后几行后,剩余前缀仍会通过验证。要发现这种情况, 需要在文件之外设置锚点 — 参见 docs/adr/0004。
  • Ledger 为自身提供证明。 哈希验证只能证明行未被编辑或重新排序;无法证明是谁写入的, 而完全伪造的 ledger 也能通过验证。
  • 没有任何后端能为 tmux 提供乐观版本保护。 这需要调用方提供预期值 —“仅当窗格仍与我读取 时一样时才写入” — 而 pane_send 不接受预期版本。先读取两次窗格、并在内容变化时拒绝写入, 属于名不副实的另一种保证,因此系统报告为 none,而非提供近似保证。
  • 在没有受保护主机的情况下,空提示词检查只是启发式判断。 它读取渲染后的屏幕,因此误判为 “空”就会把内容追加到某人的半成品文本后并提交合并。因此,除非能确信内容为空,否则一律拒绝, 包括无法读取的屏幕;此时可通过 pane_clear 继续操作。已在真实窗格上验证,但样本量不大。
  • 用于衡量的 Superset 是已发布的原版构建 — 其 terminal.send 不提供任何保护。自 0.2.4 起, 已多次在该运行中的主机上完成有证据的发送(观察到 canary,状态为 GREEN),既通过直接调用, 也通过完整 MCP 接口完成。受保护主机分支只针对记录下来的形态进行测试,因为没有已发布的构建 带有这些保护措施可供测试。
  • 受保护的 Superset 主机会对 Codex 占位文本过度拒绝,将 Agent 自己的建议行也计为已暂存输入, 因此会拒绝向这类窗格发送内容,清空也无济于事。收据会如实说明这一点,而不是建议清空。此问题 应由主机修复。
  • tmux 窗格的运行时信息可能会在检查与写入之间变得过时。 Superset 的运行时信息来自主机自身的 注册表,因此它的检查关卡可以在写入前运行,而非写入后。
  • canary 证明的内容远不及“已成功”。 它只能证明文本已到达某处,且该处随后回显了一次性标记 — 即已送达并得到确认。它无法证明 Agent 完成了工作、只做了该工作,或窗格就是你想要的那个。 GREEN 是送达收据,不是工作收据。
  • 发往同一窗格的并发发送会串行处理,而非排队。 第二次发送会等待第一次完成;不会被暂存、排序 或重试。如果语音客户端的发送速度超过终端的接收速度,它会阻塞自己的当前轮次,而不会交错发送。
  • 闭源客户端中的连接器语音行为没有文档记录,且可能在不另行通知的情况下发生变化。

仓库结构

src/yapitalism/mcp/       MCP server, backend registry, receipts, tmux driver
src/yapitalism/adapters/  Superset host-service client
src/yapitalism/           receipt core: model, canary, claims, ledger, CLI
tests/                    deterministic unit, replay, and real-tmux tests
fixtures/                 scrubbed incident replays
.agents/skills/           voice policy + drift check
.agents/launchd/          run the server as a login agent
docs/adr/                 load-bearing decisions
docs/architecture.md      component boundaries and evidence model

明确不涉及的目标

  • 对闭源语音客户端内部实现进行逆向工程或打补丁;
  • 虚构并不存在的后台轮次或推送 API;
  • 多租户 SaaS;
  • 自动发送电子邮件、私信或消息;
  • 将终端修订版本的变动视为命令已接受。

致谢

收据完整性核心由 @liri-ha 编写,其提交未经改写,直接保留于此。请参阅 CONTRIBUTORS.md。

安全

原始转录、终端文本和凭据不应存放在此代码库中。台账仅存储有界元数据、哈希和分类信息。包含持有者令牌的清单存放在代码库之外,文件权限为 0600,且只有在显式传入其路径时才会读取;绝不会打印该令牌。请参阅 SECURITY.md。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。