deskpet-guard
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@deskpet-guardAny suspicious exfiltration events from agents right now?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
deskpet-guard 🐾
Agent 行为守护桌宠 —— 跨 agent 监控可疑外传行为(加密打包直传对象存储 / 敏感密钥被触达 / DNS 外泄线索), 发现即告警,在明确确认后才终止目标 agent 进程;事件写入只追加的
guard-events.jsonl, 并通过 DSH host 工具 与 MCP(stdio) 供其它 agent 查询。A desktop-pet-shaped guardian for AI agent exfiltration: read-only probing, rule-based judgement, append-only event log, two-step human-confirmed process termination (one target per confirmation), exposed to other agents via DSH host tools and an MCP stdio server.
形态 | DSH 插件(host 工具 + 面板/桌宠)· 独立 CLI · MCP server |
平台 | Windows(探针基于 |
依赖 | 运行时零依赖(只用 Node 内置),不用装构建工具链就能跑 |
许可 | BSD-3-Clause |
测试 | 全离线套件,不联网、不杀进程、不需要 DSH |

目录
Related MCP server: ChatGPT Gateway MCP Nyan
它是什么 / 它不是什么
是:一个只读侦察 + 分级告警 + 一步确认后处置的小守护。它回答的问题是 "本机现在有没有 agent 正在做可疑外传动作",并把答案做成可被其它 agent 查询的公共事件源。
不是:防火墙。用户态无法阻断另一个进程的 TLS 出网 —— 能阻断的三条路 (杀进程 / 防火墙与 WFP / 内核级文件拦截)分别是"会打断用户会话""要管理员且改系统""不现实"。 详见 SECURITY.md。
一句话:它是案发现场的公告板,外加一支需要人点头的手。
缘起:为什么做这个
对某桌面 AI 客户端(ZCode v3.11.2)做过一次完整只读取证,结论是它确实存在"工作区打包加密后直传阿里云 OSS"的通道:
证据层 | 内容 | 位置 |
打包产物 | 3 个 |
|
上传意图 | 明文 | 同目录 |
上传实现 |
| 客户端 |
凭证来源 | 服务端接口 | 同上 |
加密方式 |
|
|
未证实的部分(必须保留在结论里,别当既成事实):本机 3 个包**全部滞留在 pending\**,
failureCount 12/222/20,DNS 缓存中 0 条 OSS 桶域名,采样时该客户端出网连接 0。
即"能力确证 + 已打包 + 上传未成功(本机证据)",不是"已确认泄露"。
关键设计推论:与其做"某客户端专杀",不如做通用 agent 行为守护 —— ① 这类行为不是某一家独有;② 用户要求"其它 agent 也能搜到并使用";③ profile 化画像表可覆盖任意 agent。
免责:本项目与上述厂商无任何关联,不含任何厂商代码,全部证据来自本机只读观察,用于防御目的。
快速开始
方式一:装进 DSH(插件形态,推荐)
标准安装(推荐,等同插件市场的"一键装"):本包带 cordis.patch.yml(dsh.bundle.patch),
所以既能从仓库装,也能在支持的市场里一键装:
# 仓库直装(pnpm 会把本包装进 web profile,并按 cordis.patch.yml 插入 loader entry)
dsh plugin --profile web add github:cny1230/deskpet-guard
# 按包名装(npm 发布后;包名就是 deskpet-guard,不带 scope)
dsh plugin --profile web add deskpet-guard
# MCP 客户端:npx deskpet-guard注入器安装(开发/热重载用,免重启):
git clone https://github.com/cny1230/deskpet-guard.git D:/deskpet-guard
# 在 DSH 会话里:
# dev_inject_plugin {"dir":"D:/deskpet-guard"} # 注入
# dev_uninject_plugin {"match":"deskpet-guard"} # 卸载⚠️ 两条路径选一条:同时用会让插件被加载两次(工具重名、面板重复)。 从注入器切到标准安装前,先
dev_uninject_plugin。
装好后你会得到:
5 个 host 工具:
guard_status/guard_events/guard_scan/guard_prepare_kill/guard_confirm_kill右下角常驻桌宠(
shell.overlay)+ 会话侧栏详情面板(conversation.view)本地 HTTP API:
GET /deskpet-guard/api/status|events、POST /deskpet-guard/api/scan|prepare-kill|confirm-killMCP server:
npx deskpet-guard(npm 发布后)或node <repo>/bin/deskpet-guard-mcp.js
配置(apply(ctx, config) 的 config):
{
"dataDir": "D:/guard-data", // 默认 $DSH_HOME/super-injector/deskpet-guard
"intervalMs": 15000, // 采样周期,最小 5000
"killMode": "audit", // "execute"(默认) | "audit" —— audit = 只要预警,拒绝任何终止
"profiles": [ /* 追加/覆盖 agent 画像,见下 */ ]
}方式二:CLI(不装 DSH 也能用)
node lib/index.js # 人读的一次采样
node lib/index.js --json # 结构化输出(含候选处置目标)
node lib/index.js --status # 最近一次落盘状态
node lib/index.js --events 20 # 最近 20 条事件
node lib/index.js --endpoint # host API 端点(面板/MCP 用)方式三:MCP(给别的 agent 用)
node bin/deskpet-guard-mcp.js # stdio MCP server
node lib/mcp.js --list # 看看工具清单与数据目录客户端配置片段与降级语义见 docs/MCP.md。
规则集
规则 | 触发条件 | 级别 | 建议 |
| 探针不可用 | medium/high | 告警(防止"假安全") |
| agent 进程连向 OSS/S3/COS | critical | 建议终止(两步确认) |
| 10 分钟内出现打包产物 | high | 告警 |
| 5 分钟内成簇刷包 ≥3 | high | 告警 |
| 密钥/凭据文件最近被写 | medium | 告警 |
| DNS 缓存残留对象存储域名 | info | 线索(非外传证据) |
| agent 存活 + 当前外发连接数 | info | 状态显示 |
moodOf() 把 findings 归一为桌宠表情:watching(安静)/ alert(中高)/ panic(critical)。
防误报口径:egressHostPatterns 只放"对象存储/文件托管"类域名。
反例:*.log.aliyuncs.com 是阿里云日志服务,实测出现在本机 DNS 缓存里,
但不能据此判定"工作区被上传" —— test/rules.test.mjs 有专门用例锁死这条。
面板与桌宠
面板挂在两个 DSH client slot 上(都是宿主白名单内的合法 slot):
slot | 形态 | 内容 |
| 右下角常驻桌宠 | 表情( |
| 会话侧栏详情面板 | 统计芯片、探针降级警示(R0)、候选处置目标(两步确认,一次一个)、最近 20 条事件流 |

数据面是本地 HTTP API(
lib/api.js),3 秒轮询,两个 slot 共用一条轮询; 处置流程的状态挂在闭包上 —— 轮询重画不会冲掉进行中的两步确认(有回归用例锁)所有系统字符串(进程名/路径/域名)都用
textContent写入 —— 不用innerHTML, 否则一个精心命名的进程就能在面板里注入标记(有测试盯着这条)面板是手写 bundle(
lib/client.js,DSHModuleLoader约定),不需要打包器 —— 见 架构上面两张图来自
tools/panel-preview.html(离线预览 harness:加载的是真实交付物lib/client.js,但宿主 slots 服务与fetch是 stub、数据为预览样例)。 用任意浏览器打开即可肉眼验收面板,不必装 DSH:start "tools/panel-preview.html?mode=panic&step=2" # step=2 会把两步确认展开 start "tools/panel-preview.html?mode=alert"
给其它 agent 用(MCP)
guard_status / guard_events / guard_scan(只读)+ guard_prepare_kill / guard_confirm_kill(变更)。
MCP 进程与 host 是两个进程,所以:
优先走 host 的本地 HTTP API(token 在 host 里签发/核销,单一事实源)
host 不可达时 只读工具降级本地(读落盘快照 / 本进程采样)
host 不可达时 终止类工具明确拒绝 —— 绝不本地签一个 host 不认的 token
细节与给 agent 的系统提示模板:docs/MCP.md。
扩展到一个新 agent
只改 lib/profiles.js(TS 镜像 src/guard/profiles.ts 同步),不用碰规则引擎:
{
id: 'my-agent',
label: 'MyAgent',
processPattern: 'myagent(\\.exe)?$', // 进程名/路径正则
dataRoots: ['{home}\\AppData\\MyAgent'], // 该 agent 的数据根
bundlePatterns: ['\\.bundle$'], // 打包产物文件名正则
indexFiles: [], // 工作区映射文件
secretFiles: ['{home}\\AppData\\MyAgent'], // 密钥/凭据文件或目录
egressHostPatterns: ['upload\\.myagent\\.example\\.com'], // 外发目标
uploadPathPatterns: [],
}运行时追加也可以(不改代码):apply(ctx, { profiles: [ {...} ] })。
test/rules.test.mjs 里有一条用例专门证明"加一条画像即可生效、无需改规则代码"。
架构与实现
lib/profiles.js agent 画像表(跨 agent 扩展点:新增 agent 只加一条定义)
lib/rules.js 规则引擎(纯函数,可离线单测)
lib/probe.js 只读探针(Windows: PowerShell Get-* / Test-Path)
lib/events.js 事件流(唯一写盘点:只追加、只写自己的数据目录)
lib/api.js 本地 HTTP API(纯函数分发,可离线单测;三重闸门)
lib/toolkit.js 工具定义适配层(defineTool 等价形状,零依赖)
lib/index.js 核心库 + CLI + DSH 插件入口(apply)
lib/client.js 面板/桌宠 bundle(手写,DSH ModuleLoader 约定,无需构建)
lib/mcp.js MCP stdio server(JSON-RPC 2.0,桥接 HTTP API)
bin/…-mcp.js MCP 可执行入口
src/guard/*.ts TS 权威源码(类型),与 lib/*.js 由 consistency 测试锁死一致
tools/…preview.html 离线预览 harness(浏览器里肉眼验收面板,无需 DSH)
test/*.mjs 8 个离线套件;test/dom-shim.mjs 是跑面板用的极简 DOM为什么有"手写运行时 + 无构建面板"
开发环境里没有 DSH 源码检出(只有 pnpm 打包版),tsc 与 tsdown 都装不上。
于是核心逻辑做成零依赖纯 JS(lib/*.js),并把面板也写成手写 bundle:
tsdown.config.ts 与占位用的 src/client/index.ts 已删除 —— 它们存在的唯一效果就是
"跑一次 npm run build:client 把真正的面板覆盖回一行文字"(和上面那个坑同一类)。
src/guard/*.ts 保留为带类型的权威源码,两侧用 test/consistency.test.mjs 锁死语义一致。
若日后接入构建工具链:把 lib/client.js 迁回 src/client/index.ts 并重建 tsdown 配置,
同时把 test/client-bundle.test.mjs 的产物检查指向新输出。
⚠️ 一个真实踩过的坑(保留在仓库里当路标)
dev_scaffold_plugin 生成的模板落在 src/index.ts,而 tsconfig 是
rootDir: src / outDir: lib —— 一旦跑 tsc,它会把 lib/index.js(真正的守护实现)
覆盖成一个只会读 self-heal.log 的 LLM 自省循环,整套探针/规则/终止链路当场消失。
现在有三道防线:
模板挪到
src/daemon/index.ts(并改名,不再是宿主入口)tsconfig的产物目录改为build/scripts/build.sh里有硬守卫:outDir=lib或src/index.ts存在即拒绝构建
test/ 里的 client-bundle.test.mjs 也会检查 package.json 的入口/类型/bin 指针不悬空
(第一版就犯过"exports["./client"] 指向一个不存在的 lib/client.js")。
桌宠:怎么开、怎么关
桌宠是独立桌面窗口(Windows / PowerShell + WinForms,零依赖),每个客户端各一只。 它不在客户端 UI 里渲染——因为 ZCode / Claude Code 这类 agent 的插件 API 只提供 skills / commands / agents / hooks / MCP,没有"往界面插悬浮组件"的能力。
自动拉起:
场景 | 机制 |
DSH | 宿主插件在第一次 tick 时拉起,看护对象 = 宿主自己 → 宿主退出它自己关 |
ZCode | 插件 |
任何 MCP 客户端 | 它的 MCP server 启动时顺带拉起( |
手动开/关(随时可用,不必等客户端):
node bin/deskpet-guard-pet.js --client dsh # 开:DSH 桌宠(自动看护 DSH 宿主)
node bin/deskpet-guard-pet.js --client zcode # 开:ZCode 桌宠(按进程名看护 ZCode)
node bin/deskpet-guard-pet.js --status # 只看文字状态,不开窗
node bin/deskpet-guard-pet.js --list # 现在有哪几只、看护谁
node bin/deskpet-guard-pet.js --stop all # 一次全关(含没有锁文件的孤儿)Windows 上也可以双击仓库根目录的 start-pet.cmd(默认起 DSH 桌宠,可带参数,如
start-pet.cmd --client zcode)。
手动关掉之后:不会自己弹回来(关闭是你的明确意图,宿主不会跟你抢)。
想再开就上面任意一条命令 / 双击 start-pet.cmd;ZCode 侧重启 ZCode 也会重新拉起。
⚠️
start-pet.cmd必须保持纯 ASCII:批处理按控制台代码页读取,GBK 双字节字符的 尾字节可能撞上&/|,cmd 会把后半行当命令执行(踩过,报错很迷惑)。测试里有守卫。
测试
npm test # 9 个套件 / 126 例(= node test/all.mjs;离线:不联网、不杀进程、不需要 DSH、不需要 Windows)
npm run check # 交付 JS 的语法自检(本仓库没有编译步骤兜底)
node test/panel-ui.test.mjs # 只跑面板行为(DOM shim 里挂真面板)
node test/mcp-stdio.test.mjs # 只跑 MCP 传输层(单请求单响应 / close 不吞响应)套件 | 关注点 |
| 规则判定 / 防误报(SLS 日志域名反例)/ 画像扩展性 |
| 处置链路安全:无确认不可能误杀、token 一次性、一次确认只杀一个 |
|
|
| HTTP API 与鉴权边界:预检拒绝、跨源拒绝、secret 路径、body 边界 |
| 假 ctx 跑 |
| JSON-RPC 往返 + 工具名/HTTP 路径跨文件一致 + host 不可达的降级语义 |
| 传输层:单请求单响应(防双 server 抢 stdin)、close 不吞最后一个响应、stdout 纯净 |
| 面板产物约定、slot 白名单与注入器自检正则、API 路径与 host 一致、不用 |
| 在 DOM shim 里跑真面板:渲染、两步确认(第一步不执行)、轮询不冲掉确认区、取消、API 不可达、dispose 停轮询 |
已知限制(读这里再决定要不要用)
沙箱内探针会被拒:受限沙箱禁止程序打开命名管道,抓 PowerShell 输出会失败, 三个系统探针(进程 / TCP / DNS)全挂 →
R0上报降级。文件类探针不受影响 (就是它在沙箱里扫出了那 3 个.tar.gz.enc)。要看进程/连接侧,请在你自己的终端里跑。不是防火墙(见上)。
只在 Windows 上有完整探针;其它平台会明确上报
unsupported。画像表偏薄:zcode / cursor / claude-desktop 三条,只有 zcode 有实证画像。
文件名匹配是启发式:打包产物靠文件名/扩展名识别,改名可绕过。
没有基线学习:新装的 agent 一律按陌生进程处理,误报会随安装量上升。
killMode:'execute'会真的杀进程(需两步人工确认 + 一次一个)。生产环境建议先用audit跑一段时间。
安全
探针只读;不写被监控 agent 的任何目录;不碰防火墙 / hosts / 注册表 / 证书存储;host 侧不出网
事件流只追加
变更端点三重闸门(自定义头 + 同源 + JSON,或 0600 secret);预检一律 403,永不发 CORS 头
终止必须两步确认、token 一次性、一次一个目标
完整模型与已知弱点:SECURITY.md。漏洞请走私密渠道(Security advisory),不要开 public issue。
状态 / Roadmap
只读探针 + 规则引擎 + 只增事件流 + CLI
DSH host 工具(5 个)+ 本地 HTTP API + 面板/桌宠
MCP stdio 暴露层
基线/白名单学习(降低误报)
更多 agent 画像与实证
系统托盘通知 / 声音
macOS / Linux 探针
发布状态(能不能在插件市场里搜到)
渠道 | 状态 | 说明 |
GitHub 仓库 | ✅ 已发布 | https://github.com/cny1230/deskpet-guard(public,CI 绿) |
| ✅ 可用 | 本包带 |
GitHub topic | ✅ 已打 | 已被 GitHub 搜索索引; |
npm 包 | ✅ 已发布 |
|
dsh.so 收录 | ✅ 已提交两次 | 用它自己的提交页跑完 checker 后点 |
下一步(可选,非阻塞):
未来版本发布建议改用 Trusted publishing (OIDC): 由 GitHub Actions 用 OIDC 发布、不存凭据 —— 因为 npm 已宣布 2027-01 起 bypass-2FA token 不能再直连发布; 本仓库已有 CI,加一个
release.yml+ 在 npm 上把 trusted publisher 指到cny1230/deskpet-guard即可;dsh.so 的 artifact 页要等它自己的重建周期(条目已在其后台)。
用法汇总:GitHub 直装(dsh plugin --profile web add github:cny1230/deskpet-guard)、
npm 装(dsh plugin --profile web add deskpet-guard)、MCP(npx deskpet-guard)。
逐步操作与自检清单见 docs/PUBLISHING.md。
许可
This server cannot be deployed
Maintenance
Related MCP Connectors
Guarded MCP server for agent-readable business truth, provenance, readiness, and discovery.
Hosted MCP memory and agent control plane for durable conversations, jobs, and operations.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Run and manage H Company's Computer-Use Agents from any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to securely create, manage, and monitor local processes such as dev servers, docker-compose, and test watchers, including restarting, checking status, and retrieving logs via MCP, HTTP, or WebSocket messaging.9 npm1MIT
- AlicenseNot gradedqualityBmaintenanceEnables agent clients to safely connect to tools and execution resources through MCP with authorization, approvals, audit, chat-context isolation, SSH/Docker access, and long-running command session tracking.MIT

openrhyme-mcpofficial
AlicenseAqualityBmaintenanceEnables any MCP-compatible agent to query a local OpenRhyme activity timeline, search history, and issue control commands over stdio while keeping all data on-machine.5MIT- AlicenseNot gradedqualityCmaintenanceEnables one coding agent to inspect, configure, debug, and repair another agent over stdio MCP, with redacted reads and confirm-gated writes and restarts.MIT