VoltageInputMcp
VoltageInputMcp
一个 MCP 服务器,让前沿模型以输入速度而非工具调用速度驱动计算机。
问题
计算机使用工具每次操作都要与远程模型往返一次。截图上传、决策下发、一次点击。这对填写表单没问题,但对任何需要快速连续输入序列的场景毫无用处——玩游戏、操作模态对话框、驱动时间轴、任何第三个输入依赖于前两个已经落地的 UI。瓶颈不是模型的智能。而是智能在 800 毫秒之外,而输入需要间隔 8 毫秒。
答案的形态
将决策与执行分离,把执行放在与键盘同一台机器上。
┌─────────────────────────────────────────────────────────────────┐
│ Layer 1 — the orchestrator (Claude, or any MCP client) │
│ Writes a Playbook: states, what to look for, what is allowed, │
│ when to move on. Thinks once, up front. Watches and corrects. │
└───────────────────────────┬─────────────────────────────────────┘
│ MCP
┌───────────────────────────▼─────────────────────────────────────┐
│ Layer 2 — two small local models, on your GPU │
│ │
│ vision (Qwen2.5-VL-3B) "of these specific things, │
│ which are on screen, and where?" │
│ actuator (Qwen3-1.7B) "given that, which inputs?" │
│ │
│ Neither plans. Both answer one closed question per cycle. │
└───────────────────────────┬─────────────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────────────┐
│ safety governor → /dev/uinput → the actual desktop │
└─────────────────────────────────────────────────────────────────┘编排器是大脑。小模型是手臂。手臂不聪明,也从不被要求聪明。
速度实际上来自哪里
不是来自小模型速度快——一个 3B VLM 仍然需要约 300 毫秒。它来自四件事,按影响从大到小排列:
突发(Bursts)。 执行器不发出单个输入。它发出一个突发:一个由专用执行器运行、无模型参与的定时输入程序。
g:0;c:l;w:150;t:"README.md";k:enter;w:80;k:ctrl+s那是一次决策和七个输入,跨越约 400 毫秒,精确到毫秒级调度。一个 40 动作的突发仍然只花一次决策。输入速率由突发决定,而非模型。
反射(Reflexes)。 在决策之间,以微秒级触发廉价屏幕探针——一个像素、一个区域平均值——完全不需要模型。
{"id": "heal", "when": "probe('health') < 0.25", "do": "k:q;w:60", "cooldown_ms": 800}跳过感知。 大多数循环看到的屏幕没有变化。一个 40 微秒的帧差决定是花 300 毫秒在视觉模型上,还是复用上一次的观察结果。在普通桌面工作中,这会在大多数循环中跳过 VLM。
提示缓存局部性。 提示按静态优先排序,使 llama.cpp 复用 KV 缓存,只对变化的尾部重新预填充。
为什么小模型虽小却可靠
因为它们不被要求可靠——它们被约束。
在 llama.cpp 下,两个模型都根据GBNF 语法生成,该语法每个循环根据当前状态重新生成。语法不是建议。它屏蔽 logits,使得只有延续有效解析的 token 可达。具体来说,执行器不能:
发出格式错误的突发
命名策略拒绝的键——该键不在语法中
引用未被观察到的元素——索引范围是根据本循环的元素数量构建的
提出 Playbook 未声明的状态转换
而视觉模型不能凭空发明 UI 元素名称:其标签词汇表是你编写的 watch 列表,外加一小套通用集合。因此 sees("address bar") 守卫比较的是封闭词汇表,而不是 3B 模型随意产出的任何名词。
没有重试循环,也没有防御性 JSON 解析,因为格式错误的输出不是不太可能——而是不可表示。
Playbook
你不给小模型一个目标。你给它们一个状态机。转换是守卫表达式,由运行时求值,而非模型。
{
"name": "open_downloads",
"goal": "Open the file manager at ~/Downloads. Delete nothing, confirm nothing.",
"initial": "launch",
"policy": {
"dry_run": true,
"allow_verbs": ["g", "c", "k", "t", "w"],
"deny_labels": ["delete", "trash", "confirm", "empty trash"]
},
"budget": { "max_cycles": 60, "max_seconds": 90 },
"states": {
"launch": {
"brief": "Open the application launcher and start the file manager.",
"watch": ["application launcher", "search field", "file manager icon"],
"on_enter": "k:meta;w:400",
"transitions": [
{ "when": "sees('search field')", "to": "type_name" },
{ "when": "cycles() > 6", "to": "@failure", "note": "launcher never opened" }
]
},
"navigate": {
"brief": "Focus the location bar with ctrl+l, type the path, press Enter.",
"watch": ["location bar", "file list", "error message"],
"on_enter": "k:ctrl+l;w:200",
"transitions": [
{ "when": "text('Downloads')", "to": "@success" },
{ "when": "sees('error message')", "to": "@failure" }
]
}
},
"success_when": "text('Downloads') and not flag('loading')"
}voltage_reference 返回完整的 DSL、JSON schema 和守卫函数表,因此编排器无需阅读本仓库即可编写 Playbook。
性能调优
以下所有数字都是在参考机器(RTX 3050 6 GB 笔记本,llama.cpp 下的 Qwen2.5-VL-3B + Qwen3-1.7B)上实测的,而非推导。
两个模型都受解码限制。输出 token 是唯一重要的杠杆。
这出乎意料——设计最初假设视觉受预填充限制,但事实并非如此。预填充实测约 28 毫秒且平坦,从 448×252 到 896×504 不变。解码运行在约 22 毫秒/token。因此:
项目 | 成本 |
一个输出 token | 约 22 毫秒 |
一个报告的元素 | 约 21 个 token ≈ 500 毫秒 |
视觉,2 个元素 | 约 1.0 秒 |
视觉,4 个元素 | 约 2.2 秒 |
执行器,缓存前缀 | 140–400 毫秒,取决于 note 长度 |
三个后果,每一个都改变了一个默认值:
max_elements是视觉成本的主导因素。 默认值为 3。提高到 6 每个感知循环增加约 1.5 秒。将其设置为你守卫实际测试的数量。缩小
downscale_to没有帮助,通常反而有害。 448×252 实测比 896×504 慢 2.5 倍——图像越模糊,模型越不确定,因此输出更多 token。使用能容纳的最大尺寸。执行器的
note字段占其延迟的 55%。 它纯粹是诊断性的,48 字符时实测 412 毫秒/循环,而 12 字符时为 184 毫秒,0 字符时为 140 毫秒。现在默认为 12。
元素编码为 [label_index, x1, y1, x2, y2] 而非 {"l":"address bar","b":[...],"c":0.9},原因相同——实测减少 27–29% 的 token,降低 32–41% 的延迟。索引到封闭的 watch 词汇表也更安全:模型根本无法拼写标签,更不用说拼错了。
GBNF 求值在 CPU 上每个采样 token 运行一次,因此执行器比视觉模型获得更多 CPU 线程,尽管完全 GPU 卸载——而限制 allow_keys 不仅是安全优化,也是延迟优化。
两个设置如果错误会静默失败:
构建时设置
GGML_CUDA_FA_ALL_QUANTS=ON。 我们使用q8_0KV 缓存和闪存注意力提供服务。没有这个标志,llama.cpp 不会为该 KV 组合编译 FA 内核,并回退到慢速路径——没有错误,只是神秘地糟糕的数字。scripts/build-llama.sh会设置它。运行时设置
GGML_CUDA_ENABLE_UNIFIED_MEMORY=0。 如果为1,VRAM 溢出会静默地溢出到 PCIe 而不是失败。一切正常但慢约 10 倍。serve.sh将其固定为关闭。
测量而非猜测:
.venv/bin/voltage bench它使用循环使用的精确提示形状驱动两个后端,并报告冷启动与提示缓存延迟、三种输入尺寸下每视觉 token 的毫秒数,以及这些所隐含的循环时间。提示缓存加速低于约 1.5 倍意味着有动态内容泄漏到提示前缀中。
比较模型
显而易见的实验——"哪个模型写突发更好"——衡量的是错误的东西。语法已经保证每个突发都是有效的,所以更大的模型不能在语法上获胜。真正决定配置是否可用的是:
接地准确性。 一个快 200 毫秒但偏了 40 像素的模型毫无用处——点击会落空。以屏幕像素的中心距离衡量,而非 IoU,因为点击落在中心。
约束下的决策质量。 给定相同的观察,它是否选择正确的合法动作,以及它是否将整个序列链接到一个突发中,而不是每个循环发出一个胆小的动作?
延迟,只有在 1 和 2 可接受之后才重要。
.venv/bin/voltage fixture desktop # capture a real screen
.venv/bin/voltage compare # score whatever is running now地面真值来自由编排模型标注的真实截图——这与系统在运行时使用的参考相同。合成 UI 是一个陷阱:画出来的矩形在训练于真实界面的模型眼中不像按钮,因此针对它评分衡量的是错误的技能。
结果跨运行累积,因此工作流是:服务配置文件 A → compare → 服务配置文件 B → compare → 读取表格。voltage compare --list 无需重新运行即可打印。
夹具是你自己的,不提交。如果你的截图包含任何私密内容,请将 fixtures/ 添加到 .gitignore。
学习循环
针对陌生目标的第一个 Playbook 几乎从不是正确的。重要的是失败是具体的,并且下一次尝试从上一次学到的开始。
voltage_reference(section="loop") the loop itself, and what each failure means
voltage_reference(section="bursts") the burst cookbook: chaining, timing, game patterns
voltage_capture / voltage_observe look before writing — check your labels exist
voltage_validate_playbook dead guards, unreachable states, caught statically
voltage_run(dry_run=true) real models, real screen, nothing injected
voltage_diagnose(run_id) ← what to change, not raw data
voltage_learn(target=..., note=...) record it; persists across sessions
voltage_lessons(target=...) recall it before the next playbookvoltage_diagnose 是使这成为循环的关键部分。 它计算日志暗示但未陈述的内容,并为每项命名对应的编辑。在一次卡住的 Minecraft 运行中:
[BLOCKER] label_never_seen never reported: ['crosshair', 'health bar']
[BLOCKER] input_not_landing 14 bursts executed, but the screen never changed
[BLOCKER] state_never_left 'mine' ran 14 cycles and never transitioned
[PROBLEM] timid_bursts bursts averaged 1.0 actions
[HINT] vision_every_cycle vision ran on 100% of cycles它存在的意义在于区分:从未运行的突发和运行了但没起作用的突发在摘要中看起来相同,但原因无关。 前者是策略或语法问题。后者是窗口焦点、指针模式或忽略合成输入的应用程序。Diagnose 通过检查执行后帧是否实际变化来区分它们。
应用最高严重性的发现,重新运行,再次诊断。一次只改一个——同时改多个会使下一次诊断无法解读。
经验跨会话持久化,按目标为键,因此游戏的第二个 Playbook 从第一个发现的探针坐标和可用标签名称开始:
voltage_learn(target="minecraft", kind="label",
note="vision reports 'hotbar' reliably but never 'crosshair'")
voltage_learn(target="minecraft", kind="timing",
note="block placement needs w:100 after right click or it does not register")安全
生成输入的是一个 1.7B 模型。治理层不是建议性的:每个突发都经过它,包括反射突发和你自己编写的突发。
dry_run是默认值。 新的 Playbook 解析、检查并记录每个突发,同时不触碰任何东西。整个突发拒绝。 半执行一个预期的序列比不执行更糟。
deny_labels拒绝点击任何名为 Delete / Confirm / Purchase / Allow 的东西,无论它出现在哪里——这能捕获在意外位置弹出的对话框。区域围栏、键允许列表、被拒绝的和弦(
ctrl+alt+delete、alt+f4)、被拒绝的文本模式(rm -rf、sudo)、突发大小和每秒输入数上限。四个独立的停止机制:
voltage stop(写入文件——可通过 SSH 工作)、在循环卡住时在自己的线程上触发的安全定时器、物理输入竞争(触摸真实鼠标即停止),以及 Playbook 预算。按住的键始终释放——中止时、崩溃时、超时时。在
d:shift和u:shift之间中断的运行绝不能留下 Shift 卡住。
安装
从零到可用,两条命令。
Linux / macOS
git clone https://github.com/casualkre/voltage-input-mcp && cd voltage-input-mcp && ./install.shWindows(PowerShell)
git clone https://github.com/casualkre/voltage-input-mcp; cd voltage-input-mcp; powershell -ExecutionPolicy Bypass -File .\install.ps1然后,在任一系统上:
voltage setupinstall.sh 处理 Python、系统包、venv 和你的 PATH,并打印需要 root 权限的确切 sudo 命令,而不是请求它。然后 voltage setup 检测你已有的内容,只下载缺失的部分,启动模型服务器,并向你的 AI 客户端注册——运行每一步,而不是描述它。十到二十五分钟,几乎全部是下载时间。可安全重新运行;它会从上次中断的地方继续。
然后只需运行:
voltageSetup 检测你已有的内容并从那里继续。 它不假设起点:它探测你的操作系统、GPU、是否安装了 llama.cpp 或 Ollama、已拉取了哪些模型、输入和捕获是否工作、MCP 服务器是否已注册——然后只规划实际剩余步骤,并说明哪些需要你决定、哪些它可以直接做。如果你已有 Ollama,它会使用它。如果两个后端都没有,它用两行解释权衡并让你选择。
无参数运行会打开交互式控制台:实时状态、按依赖顺序修复未就绪内容的引导式设置、模型切换器、配置编辑器、一键注册 Claude Code,以及诊断。下面的每个子命令仍然可以非交互式工作,因此脚本和 CI 不受影响。
██╗ ██╗ ██████╗ ██╗ ████████╗ █████╗ ██████╗ ███████╗
██║ ██║██╔═══██╗██║ ╚══██╔══╝██╔══██╗██╔════╝ ██╔════╝
██║ ██║██║ ██║██║ ██║ ███████║██║ ███╗█████╗
╚██╗ ██╔╝██║ ██║██║ ██║ ██╔══██║██║ ██║██╔══╝
╚████╔╝ ╚██████╔╝███████╗██║ ██║ ██║╚██████╔╝███████╗
╚═══╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
── status ──────────────────────────────────────────────
ok input device /dev/uinput
ok vision model http://127.0.0.1:8080
ok actuator model http://127.0.0.1:8081
ok mcp registered claude mcp list
ok voltage on PATH ~/.local/bin/voltage实验性配置文件
在 voltage → models 中单独列出,每个都在你必须接受的警告之后。它们存在是因为测量使权衡可预测:解码在约 22 毫秒/token 占主导地位,并随激活参数扩展,因此缩小模型确实会提高循环速率。代价是接地准确性。
profile | models | VRAM | trade |
| SmolVLM-500M + Qwen3-0.6B | ~2.2 GB | 3–4× 循环速率,接地(grounding)几乎不可用 |
| Qwen2.5-VL-3B + Qwen3-0.6B | ~3.8 GB | 决策更快,接地不变 |
| Qwen2.5-VL-32B + Qwen3-14B | ~34 GB | 最佳接地,1–2.5 秒/循环 |
| Qwen2.5-VL-32B + Qwen3-30B-A3B | ~43 GB | 30B 容量,~3B 解码速度 |
| 3B + 0.6B 在 CPU 上 | 无 | 无需 GPU 即可工作,每循环数秒 |
有两个值得单独说明:
hyper 是危险的那个。 SmolVLM-500M 不是接地模型。它会返回
边界框,而且经常是错的——而错误的边界框就是点到错误的位置,而不是
优雅降级。只在 watch 为空(由探针和反射完成实际工作)时使用它,
或者当每次点击都被 click_allow_regions 和
require_target_element 围栏保护时使用。
beefy_moe 是有趣的那个。 Qwen3-30B-A3B 是一个混合专家模型,有 ~3B
激活参数,因此它以大约 3B 的速度解码,同时以 30B 的容量进行推理——
而解码恰恰是这个循环的瓶颈。在相似的延迟下,它比稠密的 14B 是更好的执行器。
问题在于内存:只有激活的专家是快的,权重不是,所以全部 30B 仍然必须驻留在内存中。
recommend() 永远不会返回实验性 profile,并且有测试强制执行这一点。
自定义模型 profile
内置 profile 覆盖的是开发此项目所用的机器,而不是你的机器。从
voltage → profiles 添加你自己的,或者编辑配置文件旁边的 profiles.toml:
[my_rig]
description = "RTX 4090"
[my_rig.vision]
hf_repo = "ggml-org/Qwen2.5-VL-7B-Instruct-GGUF"
hf_file = "Qwen2.5-VL-7B-Instruct-Q4_K_M.gguf"
mmproj_file = "mmproj-Qwen2.5-VL-7B-Instruct-Q8_0.gguf"
params_b = 7.0
weights_mb = 4700
n_ctx = 4096
port = 8080
[my_rig.actuator]
hf_repo = "unsloth/Qwen3-4B-Instruct-2507-GGUF"
hf_file = "Qwen3-4B-Instruct-2507-Q4_K_M.gguf"
params_b = 4.0
weights_mb = 2500
port = 8081自定义 profile 按名称覆盖内置 profile,因此将一个命名为 lean 会重新调整
内置 profile 的参数,而无需分叉整个包。对于 Ollama 后端,使用 ollama_tag
而不是 hf_repo/hf_file。
有一个槽位很挑剔,另一个则不然。视觉模型必须能够在请求时发出接地边界框—— Qwen2.5-VL、Qwen3-VL、InternVL、MiniCPM-V 和 UI-TARS 都可以;而普通的 图像描述模型会漂亮地描述你的屏幕,却把边界框放在错误的位置。 执行器则很宽容:在 GBNF 语法下,它只是在少数几个合法的 续写选项中选择,所以几乎任何称职的 1B+ 指令模型都能工作。
Shell 命令 vs MCP 工具
两个不同的表面,混淆它们是最常见的第一个绊脚石:
调用方式 | 样子 | |
shell 命令 | 在终端中输入,带空格 |
|
MCP 工具 | 向 Claude 请求,带下划线 |
|
voltage_doctor 是 Claude 命名空间中的工具名,而不是磁盘上的程序。在终端中输入它
总会显示"未知命令"。请让 Claude 来运行它。
这会检查 /dev/uinput 访问权限、安装系统依赖、创建 venv,并
打印缺失的内容。然后:
./scripts/fetch-models.sh lean && ./scripts/serve.sh lean.venv/bin/voltage doctor将其连接到客户端
voltage connect显示已设置的内容、实时 URL、模型是否已启动,以及服务器是否已 注册——然后为每个客户端提供复制粘贴步骤,你的真实路径和环境 已经填好:
voltage connect --client claude-desktop
voltage connect --client cursor
voltage connect --json # just the mcpServers entry涵盖:Claude Code、Claude Desktop、claude.ai 自定义连接器、Cursor、Windsurf、Zed,
以及用于其他任何东西的通用 mcpServers 块。同样的内容也是 voltage
控制台中的第 4 屏,它还可以为你写入 Claude Desktop 配置(先备份
现有文件,如果它不是有效的 JSON 则拒绝修改)。
每个生成的配置都显式携带会话环境,因为这才是出错的地方:从没有
DBUS_SESSION_BUS_ADDRESS 的 shell 注册的服务器可以成功连接,但会静默失明——
输入正常,屏幕捕获不行。voltage connect 会检测到这种情况并明确说明。
将其添加为自定义连接器
通过 URL 添加 MCP 服务器的客户端需要 HTTP 而不是 stdio:
voltage serve --http然后添加 http://127.0.0.1:8765/mcp 作为自定义连接器。
绑定仅限于回环地址,并且需要 --allow-remote 才能更改。
这不是多余的样板:这个服务器的存在是为了移动鼠标、按键和读取
屏幕,而 MCP 本身没有认证机制。非回环绑定会发布
未经认证的桌面远程控制。如果你确实需要,请在前面放置一个带认证的
反向代理,并明白任何能访问该端口的人都拥有这台机器。
从 MCP 客户端启动
MCP 客户端以净化过的环境启动服务器——PATH、HOME 和
几乎没有其他东西。这是一个合理的默认值,但它会破坏屏幕捕获,因为访问
合成器需要 DBUS_SESSION_BUS_ADDRESS 和 WAYLAND_DISPLAY。输入注入
在没有它们的情况下仍然可以工作(uinput 是设备文件,不是会话服务),所以故障
看起来令人困惑地不完整:突发执行了,截图却没有。
显式传递它们:
claude mcp add voltage-input \
-e WAYLAND_DISPLAY="$WAYLAND_DISPLAY" \
-e DISPLAY="$DISPLAY" \
-e DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" \
-e XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
-- /absolute/path/to/voltage-input-mcp/.venv/bin/voltage-input-mcpvoltage_doctor 会准确报告哪些缺失,所以如果捕获失败,
这是第一个要查看的地方。
平台
输入 | 捕获 | 文本 | |
Linux |
| portal→PipeWire、KWin DBus、grim、X11 | 扫描码,非 ASCII 字符的剪贴板回退 |
Windows |
| GDI |
|
输入汇之上的所有内容——突发调度、时序、按住键跟踪、安全
调节器、整个运行时——都是共享的。每个平台实现五个方法
(key、button、move_abs、move_rel、scroll);参见 inputs/sink.py。
有两个值得了解的对称性差异:
在 Windows 上打字更正确。
KEYEVENTF_UNICODE传递 UTF-16 代码单元, 不涉及键盘布局。Linux uinput 发送扫描码,所以非美式 布局上的标点会出错——而且是静默的——这就是为什么剪贴板回退 在那里存在而在 Windows 上不需要。在 Linux 上捕获能力更强。 GDI
BitBlt无法看到某些硬件覆盖层 视频和全屏独占游戏;这些会捕获为黑色。请以 无边框窗口模式运行此类游戏。
在 Windows 上,SendInput 无法驱动属于提升进程的窗口(UIPI)——这
会静默失败,所以 voltage doctor 会报告你的提升状态。DPI 感知
在导入时声明;没有它,在缩放显示器上每个坐标都是错的。
要求
Linux(任何显示服务器)或 Windows 10/11
Python 3.11+
一个 GPU,
leanprofile 需要 ~5 GB 空闲;voltage profiles显示适合你的配置快速路径需要 llama.cpp,或者较慢的零构建路径需要 Ollama
已在 KDE Plasma 6 / Wayland / CUDA / Python 3.14 上端到端验证。Windows 路径 已实现并通过类型检查,但尚未在 Windows 机器上运行——请将其视为 未经测试,并报告任何问题。
编排器被告知它驱动的是哪个构建
同一个 Playbook 在一个配置上是正确的,在另一个配置上就是错误的,而远程模型 无法看到是哪个。因此服务器的 MCP 指令是在启动时根据实时配置 构建的,只携带那些会改变 Playbook 编写方式的条目:
ACTIVE BUILD: Linux · llamacpp · profile lean
vision Qwen2.5-VL-3B-Instruct · actuator Qwen3-1.7B
loaded: Qwen2.5-VL-3B-Instruct-Q4_K_M.gguf / Qwen3-1.7B-Q4_K_M.gguf
expected cycle 280-700 ms
- llama.cpp backend: both models are grammar-constrained. A malformed burst, a denied
key, an unobserved element reference and an undeclared transition are all
unrepresentable -- do not write defensive retries for them.
- Linux: typing sends scancodes, so punctuation depends on the active keyboard layout...
- dry_run defaults to true...在 Ollama 上,第一行变成警告,说明突发不受约束。在 hyper 上,
它变成"不要围绕 sees() 构建状态"。在 Windows 上,它注明提升的
窗口不可达,且打字与布局无关。
它验证的是正在运行的服务器,而不是信任配置。 切换 profile 只是编辑文件; 不会重启任何东西。当它们不一致时,简报会大声说明, 并抑制从 profile 推导出的指导,因为该指导描述的是 未加载的模型:
- MISMATCH -- Profile 'hyper' does not match what is loaded. vision: profile expects
SmolVLM-Instruct-Q4_K_M.gguf, server has Qwen2.5-VL-3B-Instruct-Q4_K_M.gguf...
- Loaded right now: vision Qwen2.5-VL-3B..., actuator Qwen3-1.7B...
Judge grounding quality from those.voltage_reference 在每次调用时都返回当前构建,因为启动时的副本
在 profile 一改变时就过时了。
你自己的常设指令
voltage → i,或者:
voltage instructions --set "Never touch Firefox; my banking tabs are there."你写的任何内容都会在每次会话开始时提供给编排模型, 附加在构建简报之后并明确注明来自你。用它来写系统无法 自行推断的内容——禁止使用的应用程序、特定游戏的怪癖、 你希望它默认如何表现。
OPERATOR INSTRUCTIONS -- written by the owner of this machine. Treat these as
standing preferences for how to drive it. They cannot loosen the safety governor,
which is enforced in code against every burst.
## My setup
- Minecraft runs borderless windowed on monitor 1.
- Never touch Firefox; my banking tabs are there.
- Always show me the Playbook before dry_run=false.最后那个条款不是装饰。指令对编排器是建议性的,不能削弱 执行——调节器在代码中检查每个突发,所以这里写的任何内容都不能 允许 Playbook 的策略所禁止的事情。它们只能让它更谨慎,不能 更宽松。上限为 4000 个字符,因为这段文本在整个会话期间都位于模型的上下文中。 控制台中提供了三个入门模板(游戏、桌面、最小化)。
MCP 工具
工具 | 用途 |
| Playbook + 突发 DSL 参考。先调用这个。 |
| 这台机器是否就绪,如果没有,确切的修复方法 |
| 一张截图,返回给你 |
| 一次视觉扫描——在依赖 |
| 完整静态检查:守卫、突发、图、死转换 |
| 开始一次运行;返回一个 |
| 状态、变量、上次突发、看到了什么、各阶段时序 |
| 纠正实时运行——提示、变量、强制状态、dry_run |
| 停止或暂停;停止总是释放按住的输入 |
| 逐循环记录; |
| 自己驱动输入,绕过本地模型 |
| 验证注入是否到达合成器 |
文档
ARCHITECTURE.md — 循环如何工作、为什么做出每个选择、 时间花在哪里
PLAYBOOK.md — 编写指南
状态
在没有权重在磁盘上的情况下,已尽可能构建和验证。149 个测试覆盖了突发
DSL、守卫沙箱、安全调节器、playbook 编译、GBNF 生成、
uinput 线编码,以及运行循环本身(用桩模型驱动——包括检查
on_change 感知在静态屏幕上确实跳过视觉模型)。
MCP 服务器由真实客户端通过 stdio 端到端驱动:13 个工具、正确的
schema、execute_burst 接受了一个有效的突发并拒绝了 sudo rm -rf /,
两条匹配规则都生效。
尚未运行的是实时模型:这需要构建 llama.cpp 并获取权重,
scripts/ 会设置这些。构建期间也有两件事被故意没有触发——
门户权限对话框,以及任何真实的输入注入——因为两者都会作用于
你的桌面。
从这里开始的执行顺序:
./scripts/setup.sh # reports what needs sudo, doesn't run it
./scripts/build-llama.sh # ~15 min with CUDA
./scripts/fetch-models.sh lean
./scripts/serve.sh lean
.venv/bin/voltage doctor # should now say READY然后在 MCP 客户端中:voltage_calibrate(观察光标实际移动)、voltage_observe(检查视觉模型能找到你的标签),然后运行一个 dry_run Playbook,并在设置 dry_run=false 之前阅读 voltage_journal。
作者署名
由 Claude Opus 5(Anthropic)在单次会话中端到端编写——架构、实现、测试和文档。人类指定了想法、设定了约束(KDE Wayland、6 GB VRAM、"比 computer-use 更快")并审阅了结果,但没有编写代码。
本仓库中沉淀的平台发现来自构建过程中对机器的探测,而非凭空假设——KWin 拒绝向非白名单可执行文件提供 ScreenShot2、grim 在 KWin 下无法工作、MCP 客户端会清除会话总线。每一条都在代码中迫使做出决策的位置有相应文档记录。
LICENSE 未将任何个人列为版权持有人,相关理由已在该文件中完整写明。
许可证
MIT。参见 LICENSE。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
Adaptive plan/build/review cycles for AI coding assistants, persisted across sessions.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/casualkre/voltage-input-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server