zhupi-mcp

zhupi-mcp

Agent-side MCP server for the zhupi review loop, enabling AI agents to submit documents, read annotations, and reply via GitHub.

Category
访问服务器

README

English · 中文 <div align="center">

zhupi-mcp

The agent-side of the annotation desk (zhupi), built as an MCP server.<br> The annotation desk (zhupi) is where humans read long documents written by AI, highlight sentences, and leave comments. This repo is the other end of that loop: the set of tools used by the agent to submit a folder, read back comments, and reply to them one by one.

Design Spec · Milestones · Backlog · zhupi core

</div>


Status: Phase 3 is live (seven tools, two of which can write to remote)

Installable, usable. All seven tools are implemented and tested: list_folders / read_comments / lint_folder / audit_folders are read-only, mark_handled only writes to local files, open_folder / reply_comment write to remote. 510 unit tests + e2e acceptance all green, running against real GitHub data.

There are only two holes for remote writes. WRITE_ALLOWED is a literal whitelist, matching route templates exactly. Requests outside the whitelist are intercepted by a runtime hook (read instances still cannot issue any non-GET request):

POST /repos/{owner}/{repo}/pulls                                          create a folder
POST /repos/{owner}/{repo}/pulls/{n}/comments/{id}/replies                reply

Modifying a folder, deleting a folder, or merging a folder are all impossible. mark_handled only writes to ~/.zhupi-mcp/processed.json, without touching GitHub — the stance for R7 is therefore "only these two are allowed for remote", and there are guard rules locking down the whitelists for fs writes and git writes (and the length of the whitelists is pinned down by tests, adding a member must be seen by a human once).

Measured context saved (compared to the old gh api chain): reading a single folder 7.1×, reading all open folders 3.9× (41 KB → 5.8 KB). This is the number one reason for building this thing; the numbers hold up.

The gains on the submit a folder side are another matter: the agent does not touch ~/Developer/review at all (branching, copying files, commit, push are all in a temporary worktree managed by the server, serialized across sessions with file locks), whereas before that entire segment was only written in the prose of SKILL.md — this project measured its own prose omission rate to be 37.5%.

There is another piece that went live early and does not belong to the server: the route guard that rejects bare gh pr create against the folder repo. It lives in the review-loop skill, and was shipped first deliberately — the reason is in "What MCP cannot cure" below.

Installation:

{ "mcpServers": { "menxia": { "command": "node", "args": ["<repo>/dist/index.js"] } } }

Run npm install && npm run build first. Authentication borrows the existing gh on the machine, no need to configure a separate PAT.

Progress and open questions: MILESTONES · OPEN-QUESTIONS

Why build it

The agent side of this loop could already run, living in the ~/.claude/skills/review-loop/ skill: an 8KB prose plus four bash scripts. It just went through a round of hardening on 2026-07-28, prompted by measuring what was actually missed — out of eight submit a folder actions, three missed required markers, and eleven documents lacked translation pairs. The conclusion is that prose reminders cannot cure omission; only gates can, so the rules were moved into the scripts.

That fixed the rules, but left three other things unfixed:

Where it hurts
Cross-harness Claude Code's skill only exists inside Claude Code. Other agent runtimes — Antigravity, Codex, desktop clients — simply cannot submit a folder
Context cost of reading back "Reading comments" is a chain of gh api plus manual model parsing of threads and inline positions, which must be repeated from scratch every time. Structured JSON can compress it into a single call
Untyped inputs Required fields are written in prose. If missed, you only know when the shell script dies halfway through, instead of at the exact point of call

What MCP cannot cure

This must be stated plainly, because it is exactly where assumptions are easiest to make: an MCP server cannot stop an agent from bypassing it. The model can still shell out directly and run gh pr create, skipping all gates. Moving logic from bash to TypeScript swaps the implementation, not the routing.

What blocks the routing is a PreToolUse hook — rejecting bare gh pr create against the folder repo. That is a ten-line config, independent of this repo, and went live first (SPEC §7).

This distinction is the reason this spec exists. If you are also considering the same thing, first figure out exactly which problem you have on hand.

Tools surface

Seven, all live. merge is deliberately excluded — that is clicked by the human in the app ("sealed (squash-merged)"), and there is no reason for the agent side to hold this capability.

Tool What it does What it writes
open_folder The full submit a folder process: copy documents into a temporary worktree, branch, commit, check house style, push, open PR, hardcode return-to-session markers, read back for self-verification Remote (create a folder)
reply_comment Reply to an inline comment, the **回话** prefix is hardcoded Remote (reply)
mark_handled Record "I have handled this conversation comment" Local file
lint_folder Check house style before submit a folder —
audit_folders Scan all open ones, report gaps —
list_folders List all folders, sorted by recent activity, with counts and previews of body to read —
read_comments Read comments into structured JSON, author determination and answered state are pre-calculated by the server —

reply_comment cannot post a conversation comment, this is deliberate: a conversation comment posted by the agent is morphologically identical to the repo owner's in the API (sharing an account), and would turn into un-clearable false todos, measured to over-report by 77%. Folder-level summaries are spoken in the chat.

audit_folders has no --fix: of the two things that can be mechanically patched, one is wrong (patching the return-to-session marker can only patch in the id of the current session, which is fabricating one), and one is unsafe (graduating a draft is not supported by REST, requiring GraphQL, and opening that endpoint equals opening all mutations).

How it works

Loop overview

The repo right in the middle is the entire interface. Neither side calls the other; they each only talk to GitHub. So the annotation desk (zhupi) can be unhooked at any time, and this server can also be swapped back to bash scripts without the human side noticing at all.

Node + TypeScript, stdio transport, installed by absolute path — touching no global npm state. GitHub authentication directly borrows gh auth token, without separately managing a PAT.

Known boundaries

Ugly words up front:

  • Concurrency prevention relies on file locks, not queuing. A stdio-based MCP server is one process per session, not a shared resident service, and cannot serialize across sessions on its own. flock plus a disposable worktree gets the job done, but the mechanism must be stated clearly upfront; don't think of it as a "resident single process".
  • The return-to-session marker is best-effort. It relies on crawling the process tree for detection, and only holds true when the caller is a descendant of the host CLI. If undetected, nothing is buried — silently pointing to the wrong thing is worse than having no button.
  • Risk is concentrated in the lint rewrite. The existing bash checks have accumulated a batch of fixes, and a rewrite is the easiest way to quietly drop them. SPEC §5 records the actual behavior of each rule line by line (there are three places inconsistent with its own documentation), and requires running a differential test before launch to align with the old script line by line.
  • Designed at a personal scale. One reviewer, one folder repo; no plans for multi-tenancy.

Fork to use

The folder repo name and local checkout path are configs, not constants:

ZHUPI_REVIEW_REPO=<owner>/<repo>     default charliezong18/review
ZHUPI_REVIEW_PATH=<path>             default ~/Developer/review

The conventions forced by the tools — bilingual pairs, cross-linked headers, five-paragraph PR bodies — are one person's house style. Just fork it and change them; they are rules in one module, not implicit assumptions scattered everywhere in the code.

License

MIT © Charlie Zong

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选