mcpField
W
wyd

wyd

本地服务
wyd.sh开发工具47 周前更新

关于 wyd

wyd 是面向 macOS 和 Linux 编码 Agent 用户的本地运行时溯源工具。它将开发进程关联到 Agent 会话和项目,解释遗留进程,并可监督有时限的命令运行。

主要功能

  1. 01追踪进程所属的 Agent 会话和项目
  2. 02根据证据解释进程归属
  3. 03查看会话与受管理的运行
  4. 04监督命令并限制时长、保留日志
  5. 05通过 MCP 提供只读运行时查询

适用场景

  1. 01查明哪个 Agent 会话启动了进程
  2. 02识别遗留的浏览器或开发服务器
  3. 03为测试设置超时并保留输出

MCP 相关

wyd 通过 stdio 提供 MCP 服务。客户端可查询会话、进程归属、运行、输出和容量;启动或取消运行需使用 `--allow-run`。

配置

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

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
cargowyd0.10.0

工具

还没有获取到工具列表

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

详细介绍

wyd

wyd? — 你在做什么?

查看你的编码 Agent 留下了哪些仍在运行的程序。

编码 Agent 会启动 MCP 服务、无头浏览器、开发服务器、工作进程和数据库。

ps 会告诉你正在运行什么。wyd 会告诉你为什么——哪个会话启动了它、它属于哪个项目,以及它是否是遗留进程。

OpenCode
└─ chrome-devtools-mcp
   └─ Chromium ×8       1.2 GB

Agent exited 47m ago
⚠ leftover

本地运行,支持 macOS 和 Linux。无需账户、网络或遥测。

https://wyd.sh

curl -fsSL https://wyd.sh/install.sh | sh
# or
brew install oxyplay/tap/wyd
# or
cargo install wyd
wyd
wyd upgrade   # brew or cargo, matching the install
wyd --demo    # deterministic synthetic dataset — screenshots/demos, no host scan

每个带标签的发行版本都会将 crate 发布到 crates.io,并自动更新 oxyplay/homebrew-tap 中的 Formula/wyd.rb,因此 wyd upgrade 始终保持最新,无需手动操作。如果 公式更新有所延迟,wyd upgrade 仍会打印提示。

二进制文件:GitHub 发布版本。从克隆仓库安装:cargo install --path .

wyd TUI(wyd --demo)——5 个 Agent 会话、MCP 服务、开发服务器、数据库和 Docker

系统守护进程会隐藏。桌面版 Chrome 会隐藏。由 Agent 启动的 Chromium 不会隐藏。

为什么选择 wyd

ps / 活动监视器Docker Desktopwyd
所有进程是仅容器仅开发运行时
启动者否compose 标签Agent → MCP → 浏览器
所属项目否有时当前工作目录 / git 根目录
是否为遗留进程?否由你猜评分并说明原因
安全终止只能祈祷stop/rmPID + 启动时间,按 y 确认
卷—很容易误删未使用 ≠ 垃圾;需要按 D

专为整天运行编码 Agent、之后又会问 那个会话留下了什么? 的人打造。

运行时归属

除了实时视图,wyd 还会追踪编码 Agent 运行时会话——某个会话启动了哪些 资源,并以 boot_id + pid + start_time 为键,因此即使进程被重新托管或 Wyd 重启,来源信息也能保留下来。即使确切的进程祖先关系已不可用,确定性解析器 也会通过可解释的评分将资源归属于某个会话。

  • TUI 中的 Sessions 视图(顶层):Agent · 项目 · 状态 · 时长 · ID,并带有详情面板。
  • wyd why <pid>——哪个会话拥有某个进程,以及相关证据。如果没有 Agent 会话拥有它,则会指出系统来源(systemd 单元、launchd、cron、tmux、ssh、snap、flatpak 或交互式 shell),并显示祖先链。退出码:0 表示明确归属,1 表示遗留或未归属,2 表示未运行,5 表示内部错误。
  • wyd --json sessions——以 JSON 格式显示已记录的会话。
  • wyd serve——通过 Unix 套接字(wyd.sock,模式 0600,单实例)运行本地守护进程。它会保持来源信息为最新,并响应只读查询;供应商可以通过 session_start / session_end 注册会话(其 ID 会作为别名映射到 Wyd 会话)。
  • wyd mcp——通过 stdio 运行 Model Context Protocol 服务,让编码 Agent 查询 wyd 的会话、PID 的归属者以及由它管理的运行任务(--allow-run 会启用主机执行)。

MCP

wyd 也支持通过 stdio 使用 Model Context Protocol,因此编码 Agent 可以询问机器有哪些程序是它自己或其他 Agent 留下的。

wyd mcp                 # read-only
wyd mcp --allow-run     # also allows starting and cancelling runs

启动本地 MCP 服务。始终提供读取工具: list_sessions(已记录的 Agent 会话)、explain(按 PID 查询进程所属会话)、 list_runs、get_run、read_run_output 和 get_capacity。--allow-run 只会为当前连接添加 start_run 和 cancel_run;未启用时,这些调用会被拒绝,并提示使用 --allow-run 重启。 无需网络或账户——答案来自本地来源信息存储。

已在 MCP Registry 注册:

  • MCP Registry 名称:mcp-name: io.github.oxyplay/wyd

受管理的运行任务

wyd run 会在本地监督器下启动命令,让 Agent 获得截止时间、由 wyd 管理的进程组, 以及有大小限制的日志,而不是卡住的 shell。

wyd run --timeout 120s -- npm test

该命令使用 argv,而不是 shell — &&、管道和 glob 都需要显式使用 sh -c。--timeout 默认为 10m,--grace(从软停止到强制停止的宽限时间)默认为 3s,且 --cwd 必须是绝对路径。--json 会输出结构化结果,而不是捕获的输出;在 24 小时内重复使用同一个 --request-id 会复用该次运行,而不会启动第二次运行;同一个 ID 搭配不同命令则会被拒绝。

所有运行共享同一份准入预算,因此同一台机器上的多个 Agent 不会同时全部启动。 wyd run 接受每次运行的资源请求:

wyd run --memory 512 --enforce monitored --queue-timeout 60s -- npm test
标志含义
--memory <MiB>从运行预算中预留的内存;搭配 --enforce monitored 时,也作为停止阈值。
--enforce none|monitored|hard默认值为 none。monitored 会在观测到的用量超过 --memory 时停止运行;hard 是内核限制,如果后端无法提供,则会在启动进程前拒绝请求 — 绝不会静默降级。
--queue-timeout <dur>请求等待可用槽位的最长时间;仅对本次运行覆盖 queue_timeout_secs。与 --timeout 相互独立,后者只在进程启动时开始计时。排队请求等待超时后会以 timed_out 结束,并附带队列超时详情;等待时间不会计入执行超时时间。
--cpu <millicores>CPU 请求。仅供参考:目前没有后端会强制执行此项。
--processes <n>进程数请求。仅供参考:目前没有后端会强制执行此项。

因监控内存阈值而停止的运行会以 outcome=resource_limit 结束, 并以 137 退出,同时附带指出观测数值的 limit_event。

预留量是预算,不是实测内存。 reserved_memory_bytes 是已准入运行预留量的总和,并非它们的实际用量。 实测用量会单独报告为 observed_memory_bytes;在 macOS 上,该值是每 200 毫秒采样一次的运行进程组内 RSS 总和。 共享页面可能被重复计数,短暂的峰值也可能被漏掉,因此这只是观测值,不是保证值。

macOS 不提供硬内存限制:aggregate_memory_limit 为 monitored,并且在创建运行之前就会拒绝 --enforce hard,而不是将其降级。在 Linux 上,硬限制来自委派的 cgroup v2 子树(memory.max、memory.swap.max、cpu.max、pids.max),因此只要存在可用值, aggregate_memory_limit、cpu_quota 和 process_limit 就会报告 available。没有委派时,它们会报告 unavailable,且 hard 请求会被拒绝 — wyd 不会请求 root 权限,也不会改写你的 systemd 单元。将监督程序放入带有 Delegate=yes 的单元,或将 WYD_CGROUP_ROOT 指向委派子树中你拥有的目录,然后 重启监督程序(其能力在启动时固定)。由于 cgroup 成员身份会由所有后代进程继承,即使通过 setsid 脱离进程组的子进程仍处于该运行的 cgroup 中,并会随其一起终止。所有运行也处于同一个聚合 cgroup 下,其 memory.max 即为运行预算,因此 预算是对总量的内核限制,而不只是准入规则; wyd capacity --set memory_budget_mb=… 会更新该限制。可在 [runs] 中设置 cpu_budget_millicores 和/或 pids_budget,以同样方式限制所有运行的 CPU 总量和进程数(wyd capacity 会报告这些值,运行时更改也会更新内核限制)。

之后可检查或停止它:

wyd runs                  # recent runs: state, outcome, cleanup, duration
wyd runs --json           # full RunView records
wyd logs <id> --follow    # retained stdout (--stream stderr for the other)
wyd cancel <id>           # idempotent

wyd capacity 会显示准入限制和当前用量;--json 会附加能力状态(monitored、available 或 unavailable):

wyd capacity                                              # slots, queue, reservations
wyd capacity --json                                       # the full Capacity record, incl. capabilities
wyd capacity --set max_parallel=2 --set queue_timeout_secs=30

--set 可重复使用,接受任意 [runs] 键对应的 key=value:

KeyDefaultMeaning
max_parallel4同时获准运行的任务数。
max_parallel_per_project2每个项目根目录同时获准运行的任务数。
max_queued32队列长度;超出此长度的请求会被拒绝,而不会一直挂起。
queue_timeout_secs600请求等待可用名额的最长时间。
memory_budget_mb8192正在运行的任务可预留的总内存。
default_run_memory_mb512未指定内存量的任务所预留的内存。
starvation_after_secs60被跳过这么久的请求将优先获得下一个名额。

更改限制后,新限制仅适用于之后的准入;不会因此终止正在运行的任务。 如果新上限低于已准入的任务数,系统会报告临时超限状态 over_parallel_limit,而不会将其隐藏。相同的键也位于 ~/.config/wyd/config.toml 的 [runs] 下。

TUI 以只读方式显示相同的任务:在 Overview 窗格中选择 Runs, 按 enter 打开任务详情。Runs 窗格还会显示已配置的限制 (实时计数在此处标记为不可用,因为 TUI 读取的是存储,而不是 supervisor 套接字),对于排队中的任务,还会显示其位置、等待时间和原因。 Web 仪表板提供相同的视图,并额外显示实时容量面板;两者都不能 更改限制或启动命令。

supervisor 拥有任务,而不是启动任务的客户端:如果 CLI 或 MCP 连接断开,任务仍会运行至截止时间,之后仍可查看其结果和日志。读取操作持久且无需守护进程——wyd runs、 wyd logs 和 MCP list_runs/get_run/read_run_output 会读取存储 和保留的日志文件,因此即使没有运行中的 supervisor 也能正常工作。wyd capacity 和 Web 仪表板的容量面板在没有运行中的 supervisor 时,会报告已配置的 [runs] 限制和空队列,而不会启动 supervisor;MCP get_capacity 工具会向 supervisor 发送请求,并按需启动它, 与 start_run 一样。启动或取消任务需要 supervisor;它会按需启动,并在空闲五分钟后退出;下次运行 wyd run 或 wyd mcp --allow-run 会重新启动它。向 supervisor 发送 SIGTERM/SIGINT 时,它会先停止正在运行的任务(最多等待 10s),而不是将其遗弃。

退出代码:命令退出时使用其自身的代码;收到信号时使用 128+signal;超时时使用 124;取消时使用 130;无法启动命令时使用 125;资源限制导致命令停止时使用 137。具体原因始终记录在 JSON 中(outcome、exit_code、signal、cleanup、detail、 limit_event)。

每个流的输出上限为 10 MiB,所有保留任务的总输出上限为 250 MiB——保留开头部分,并报告截断情况 (JSON 中的 stdout_truncated/stderr_truncated,以及 wyd logs 输出中 stderr 上的标记)。达到上限后,管道仍会持续排空,因此输出量大的测试不会卡住 supervisor。已完成的任务及其日志保留 7 天。

这不是什么

托管运行仅是在 macOS 和 Linux 上运行的本地进程,仅此而已:

  • 清理仅涵盖运行自身的进程组。若命令脱离该进程组运行 — setsid、双重 fork、外部守护进程 — 不会默默声称已涵盖:cleanup 会报告 incomplete 或 unknown,而不是 complete。
  • TMPDIR、TMP 和 TEMP 指向运行专属目录。这只是 便利功能,不是沙箱:命令仍可写入你有权限访问的任何位置。
  • 不隔离文件系统、网络或机密,也不控制软件包安装。请在容器或虚拟机中运行 不受信任的代码,而不是在这里运行。
  • 受监控的内存限制是一项策略,而非保证:两次间隔 200 ms 的采样之间出现的短暂峰值会被漏掉,共享页面也可能被重复计数。硬性 内存、CPU 和进程数限制取决于后端:macOS 仅进行监控;Linux 会在有可用的委派式 cgroup v2 子树时通过它强制执行限制 — 否则该功能会报告 unavailable,并会拒绝 hard 请求,而不是用近似方式替代。macOS 上的硬性限制需要 Linux 执行后端(容器/虚拟机);在此功能实现之前,请在容器中运行 受资源限制的命令。关于此项功能以及真正的暂停/恢复测试,计划中的下一步见 docs/managed-runs-plan.md → «后续计划»。
  • 预留额度是预算,并非测得的 RAM:reserved_memory_bytes 表示允许运行使用的内存,observed_memory_bytes 表示观察到某次运行使用的内存。

MCP 配置:wyd mcp 为只读模式。wyd mcp --allow-run 会为该连接启用 start_run 和 cancel_run;start_run 被描述为主机执行,wyd 绝不会将其放在沙箱中运行。

WebMCP

试用托管演示:https://demo.wyd.sh

wyd 提供十一种 WebMCP 工具,让浏览器 Agent 能够在与人类所见相同的界面中调查遗留项:list_sessions、get_session、 list_leftovers、explain_process、focus_resource、propose_cleanup,以及托管运行读取工具 list_runs、get_run、read_run_output、get_capacity 和仅用于提议的 propose_cancel_run。工具调用不会终止任何进程 — 清理须由人类确认,取消运行也会经过相同的确认提议流程。网页可以读取限制和队列状态,但无法更改限制或启动命令。

wyd web         # local runtime (loopback)
wyd web --demo  # synthetic dataset, no host data
快速测试

将以下内容粘贴到 演示 中的浏览器 Agent(或本地 wyd web):

Find an ended OpenCode session, show me what it left running, explain Chromium PID 4102, and prepare a cleanup proposal. Do not execute cleanup.

WebMCP 支持是在 OpenAI WebMCP Challenge 期间,基于现有的 wyd CLI/TUI 运行时检查器添加的。

参见 docs/webmcp.md。

按键

按键操作
← → / h l概览 / 列表
↑ ↓ / j k移动(滚动详情弹窗)
Tab聚焦概览 / 列表
backspace返回(清除筛选 / 项目 / 区域,绝不退出)
enter打开详情弹窗;在项目上按下时,将该项目固定
space标记多个项目
x / K终止 / 强制结束(按 y 确认)
s停止正在运行的 Docker 容器(运行中的容器优先排列)
c清理 Docker(按 y;卷需要按 D)
P清理未使用的匿名卷(确认;保留命名数据)
o以 HTTP 方式打开选中的监听器(o try HTTP — 这是明确的假设;监听器显示为套接字,而非 URL)
p项目
/筛选
r刷新
?帮助
esc关闭弹窗,然后清除筛选 / 项目,最后退出
q退出

终止操作只向项目自身的 PID 发送信号(按 PID + 启动时间重新检查)。命名卷绝不会被视为垃圾 — 只有未附加的匿名卷(P)才会列为可清理对象,并且需要确认。底部提示行会根据上下文变化:它会显示适用于当前所选行的操作。

脚本

与 TUI 中的快照相同——适用于 Agent 完成任务后:

wyd --json leftovers
wyd --plain mcp
wyd --json project myapp
wyd --json sessions      # recorded agent sessions
wyd why <pid>            # which session owns a process, and the evidence
wyd why <pid> --tree     # full ancestry tree: path + children, target marked
wyd ports                # listening ports: process on each + what started it
wyd ports --json         # same, machine-readable
wyd serve                # local daemon: Unix-socket API + keeps provenance fresh
wyd mcp                  # MCP server over stdio (for coding agents)
wyd prune --dry-run      # list anonymous volumes that would be deleted
wyd prune                # confirm, then delete them

筛选项:leftovers、mcp、agents、docker、project、sessions(仅 JSON)。

wyd why <pid> 在进程由活跃会话正常管理时退出码为 0;进程为残留进程或没有记录的所有者时退出码为 1(此时会显示系统来源);pid 未运行时退出码为 2;发生内部错误时退出码为 5——因此,wyd why <pid> && … 或 case $? 可用于脚本和 CI。

wyd why <pid> --tree 会打印完整的祖先树,而非文字说明:从 pid 1(或最高的可见祖先)到目标进程(以 ◀ 标记)的路径,以及目标进程的子进程(最多显示 10 个,超出时会显示 … (+N more) 行)。这只是结构视图——无需来源信息。

wyd ports 会列出每个监听套接字的 address:port、对应进程及其启动来源——如果来源信息已知,则显示所属的 Agent 会话(session opencode (active));否则显示系统来源(systemd (postgresql.service)、launchd、cron 等)。--json 会为每个条目返回 {address, port, pid, process, owner_agent, owner_session, owner_state, source},并省略不适用的字段。

{
  "runtime": [{ "type": "mcp", "name": "chrome-devtools-mcp", "pid": 94148, "status": "leftover", "reasons": ["owning agent missing"] }],
  "docker": [{ "type": "dangling-image", "name": "abcdef012345", "status": "dangling", "size_bytes": 1400000000 }]
}

字段名称在主版本升级前保持稳定。空的 ports / reasons / children / project 会被省略。

配置

~/.config/wyd/config.toml——文件不存在也没关系。

[leftovers]
server_age_hours = 8

[runs]
max_parallel = 4
max_parallel_per_project = 2
max_queued = 32
queue_timeout_secs = 600
memory_budget_mb = 8192
default_run_memory_mb = 512
starvation_after_secs = 60

[persistent]
commands = ["postgres", "redis-server"]

[projects]
roots = ["~/Work"]

[keys]
quit = "q"
kill = "x"
force_kill = "K"
clean = "c"
stop = "s"
prune = "P"
help = "?"
refresh = "r"

[[signature]]
category = "agent"
names = ["myagent"]
contains = ["my-company-agent"]
display = "myagent"

许可证

Apache-2.0。Copyright 2026 Maksym Nevinchanyy。

评论

支持 Markdown

第一次接触 MCP?

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

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