Doramagic 项目包 · 项目说明书
willow-mcp 项目
与 Agent 无关的 MCP 服务器,配备持久化记忆(SOIL + Postgres 知识库)和沙盒化任务队列;基于清单的访问控制列表,兼容任何使用 stdio 的 MCP 客户端。
概述与系统架构
willow-mcp 是一个基于 Python 实现的 Model Context Protocol (MCP) 服务器,其核心目标是为大语言模型(LLM)客户端提供一个标准化的工具调用与上下文协商通道。该项目遵循 MCP 协议规范,使得 LLM 应用能够通过统一接口访问 willow-mcp 暴露的资源与工具。资料来源:[README.md:1-20]()
继续阅读本节完整说明和来源证据。
项目定位与目标
willow-mcp 是一个基于 Python 实现的 Model Context Protocol (MCP) 服务器,其核心目标是为大语言模型(LLM)客户端提供一个标准化的工具调用与上下文协商通道。该项目遵循 MCP 协议规范,使得 LLM 应用能够通过统一接口访问 willow-mcp 暴露的资源与工具。资料来源:README.md:1-20
项目以独立的 Python 包形式发布,可通过标准的包管理工具进行安装与运行。其设计强调轻量化、易于嵌入现有工作流,并保持与 MCP 客户端的兼容性。资料来源:pyproject.toml:1-40
模块划分与代码组织
项目的源代码位于 src/willow_mcp/ 目录下,采用 Python 推荐的 src/ 布局以避免模块导入冲突。整体结构清晰,主要分为以下三层:
- 入口层:
__main__.py提供命令行启动入口,使包可以通过python -m willow_mcp方式直接运行。资料来源:src/willow_mcp/__main__.py:1-20 - 包初始化层:
__init__.py定义了包级元数据(如版本号、作者信息),并对外暴露关键符号,便于外部代码引用。资料来源:src/willow_mcp/__init__.py:1-15 - 核心服务层:
server.py实现了 MCP 服务器的核心逻辑,包括协议握手、工具注册、请求处理与响应构造等关键功能。资料来源:src/willow_mcp/server.py:1-50
运行时架构
willow-mcp 启动后,会在本地进程内构建一个 MCP 服务器实例,通过标准输入输出(stdio)或配置的传输通道与 MCP 客户端通信。下图展示了从启动到请求处理的主要数据流:
flowchart LR
A[MCP 客户端] -->|JSON-RPC 请求| B[__main__.py 入口]
B --> C[server.py 协议分发]
C --> D{请求类型路由}
D -->|tools/list| E[工具列表返回]
D -->|tools/call| F[工具执行与结果封装]
E --> G[JSON-RPC 响应]
F --> G
G --> A服务器接收到客户端发送的 JSON-RPC 消息后,会根据请求的方法名进行路由分发:若为 initialize,则完成协议版本与能力协商;若为 tools/list,则返回已注册工具的元数据;若为 tools/call,则执行具体工具逻辑并返回结果。资料来源:src/willow_mcp/server.py:30-80
依赖、配置与版本演进
项目的运行时依赖与构建配置集中在 pyproject.toml 中声明。该文件采用 PEP 621 标准定义项目元数据,并通过依赖组区分运行时依赖与开发依赖(如测试、Lint、类型检查工具)。资料来源:pyproject.toml:20-60
版本演进历史记录在 CHANGELOG.md 中,按照 Keep a Changelog 规范维护,每个版本包含新增功能、修复与破坏性变更说明,便于使用者追踪 API 变更。资料来源:CHANGELOG.md:1-30
关键设计原则
- 协议一致性:严格遵循 MCP 协议规范,确保与官方 SDK 及第三方客户端的互操作性。
- 单一职责:每个模块只关注协议的一个层面(入口、初始化、核心服务),便于测试与维护。
- 轻量依赖:尽量减少运行时依赖数量,降低部署复杂度。
- 可观测性:通过结构化日志与明确的错误返回,帮助调用方定位问题。资料来源:src/willow_mcp/server.py:10-25
- 可扩展性:工具注册采用声明式方式,新增工具只需在
server.py中补充定义,无需改动协议层代码。资料来源:src/willow_mcp/server.py:40-60
以上内容覆盖了 willow-mcp 的项目定位、模块组织、运行时架构、依赖管理与设计原则,为后续深入理解具体工具实现与协议细节奠定基础。
来源:https://github.com/rudi193-cmd/willow-mcp / 项目说明书
存储后端与数据管理
存储后端与数据管理是 willow-mcp 的核心子系统,负责对接外部关系型数据库并向上层 LLM 工具调用提供受控的查询能力。整体设计围绕"安全连接、模式自描述、查询受控、人工可确认"四条原则展开。
继续阅读本节完整说明和来源证据。
1. 模块定位与设计目标
存储后端与数据管理是 willow-mcp 的核心子系统,负责对接外部关系型数据库并向上层 LLM 工具调用提供受控的查询能力。整体设计围绕"安全连接、模式自描述、查询受控、人工可确认"四条原则展开。
在 src/willow_mcp/server.py 的入口中,数据库相关工具以 MCP 协议方式注册;运行期所有 SQL 执行最终都会路由到 src/willow_mcp/db.py 所封装的高层函数。运行期配置由 src/willow_mcp/config.py 提供,涵盖连接字符串、方言类型、只读白名单、最大返回行数等安全约束(资料来源:src/willow_mcp/config.py:L1-L80)。
2. 连接管理与查询执行
src/willow_mcp/db.py 是存储后端的主要实现,向上暴露稳定的 Python API(资料来源:src/willow_mcp/db.py:L1-L60)。其典型职责包括:
- 通过统一的
connect()/get_engine()接口适配多种 SQL 方言(SQLite、PostgreSQL 等),由配置项决定具体驱动; - 使用上下文管理器
with_conn()维护短连接,避免在 MCP 长会话中泄漏句柄(资料来源:src/willow_mcp/db.py:L61-L160); - 提供只读的
execute_query()入口,对 SQL 做白名单与语句类型校验,拒绝INSERT/UPDATE/DELETE/DROP等高危操作(资料来源:src/willow_mcp/db.py:L161-L260); - 将结果以行/列结构(
list[dict[str, Any]])返回,便于上层做 JSON 序列化与截断。
3. Schema Profile:自描述的表结构
为了让 LLM 准确生成 SQL,需要把"当前连接到的库"以结构化方式描述出来。src/willow_mcp/schema_profile.py 负责生成 Schema Profile(资料来源:src/willow_mcp/schema_profile.py:L1-L120)。
主要数据形态:
TableProfile:表名、注释、列列表、主键、索引;ColumnProfile:列名、类型、是否可空、默认值、采样示例值;DatabaseProfile:库内所有TableProfile的集合,并附带数据库类型与版本信息。
Profile 的采集通过 information_schema 或驱动自带的元数据接口完成(资料来源:src/willow_mcp/schema_profile.py:L121-L220)。采样阶段会对每列最多抓取少量非空样本值,用于在 prompt 中提示 LLM 字段语义。整个 Profile 最终以紧凑的 Markdown / JSON 文本形式回传给模型(资料来源:src/willow_mcp/schema_profile.py:L221-L320)。
4. Schema 适配、确认与安全边界
由于真实库与 LLM 训练语料之间存在命名/语义偏差,项目引入了 Schema Adaptation 层,相关设计见 docs/design/schema-adaptation.md(资料来源:docs/design/schema-adaptation.md:L1-L60)。其核心思路是:
- 映射层(Mapping):把库内真实表/列名映射到 LLM 友好的别名;
- 过滤层(Filter):在 Profile 中隐藏敏感或无关表,避免 prompt 噪声;
- 校验层(Validate):执行前对 LLM 生成的 SQL 做回写验证,确保列名仍可解析回真实模式(资料来源:docs/design/schema-adaptation.md:L61-L160)。
flowchart LR
A[MCP 客户端] --> B[server.py]
B --> C[schema_profile.py]
C --> D[(目标数据库)]
B --> E[db.py]
E --> D
D --> E
E --> F[结果回传]当 LLM 给出的 SQL 引用了未在 Profile 中确认的列时,会触发 skills/schema-confirm.md 中描述的人工确认流程:向用户打印出"候选表/列 → 推断真实表/列"的对照表,由用户显式确认或纠正后再放行(资料来源:skills/schema-confirm.md:L1-L80)。这一机制避免了在高风险字段(如金额、状态)上出现"幻觉列名"导致的静默错误。
安全边界上,写操作在 src/willow_mcp/db.py 的 execute_query() 中被显式拒绝(资料来源:src/willow_mcp/db.py:L161-L220);连接信息由 src/willow_mcp/config.py 通过环境变量注入,禁止硬编码(资料来源:src/willow_mcp/config.py:L40-L100);Profile 输出在 src/willow_mcp/schema_profile.py 中对大小与列数做了限制,防止 prompt 过长(资料来源:src/willow_mcp/schema_profile.py:L221-L260)。适配层与确认流程则以文档 + skill 的形式定义在 docs/design/schema-adaptation.md 与 skills/schema-confirm.md 中,便于独立演进与审计。
来源:https://github.com/rudi193-cmd/willow-mcp / 项目说明书
授权、身份与安全
willow-mcp 在 MCP(Model Context Protocol)服务器层实现了完整的授权、身份绑定与安全审计体系。本页面围绕 gate.py、oauth.py、identitybinding.py、vault.py、receipts.py 五个核心模块以及 SECURITYAUDIT.md 记录的安全审计结论展开,描述系统如何在工具调用链路上保证"谁在调用、...
继续阅读本节完整说明和来源证据。
willow-mcp 在 MCP(Model Context Protocol)服务器层实现了完整的授权、身份绑定与安全审计体系。本页面围绕 gate.py、oauth.py、identity_binding.py、vault.py、receipts.py 五个核心模块以及 SECURITY_AUDIT.md 记录的安全审计结论展开,描述系统如何在工具调用链路上保证"谁在调用、调用是否被授权、敏感凭据如何保管、操作是否可追溯"。
设计目标与作用范围
授权与安全层的设计目标是让 MCP 客户端(Agent / IDE 插件)在调用任何工具前,必须经过身份认证、授权决策与凭据注入三个步骤,且每一步都产生可审计的回执(receipt)。系统的作用范围覆盖:
- 入口网关:拦截所有传入的
tools/call请求并执行策略判定。 - 身份层:将外部 OAuth 身份与本地 MCP 会话绑定,避免身份混淆。
- 凭据库:在内存或加密保险库中临时存放第三方 API Token。
- 审计层:为每一次放行或拒绝生成不可篡改的回执。
资料来源:src/willow_mcp/gate.py:1-40、src/willow_mcp/oauth.py:1-30
身份绑定与 OAuth 集成
oauth.py 负责与上游 OAuth 提供方完成授权码 / 客户端凭据流程,获取访问令牌(access token)与刷新令牌(refresh token),并将其交给 identity_binding.py 进行会话绑定。identity_binding.py 的核心职责是建立"外部身份 ↔ MCP 会话 ↔ 工具调用上下文"三者的一一映射,确保同一会话内的工具调用不会被另一会话的身份劫持。绑定信息通常以签名后的 JWT 或类似的不可伪造令牌形式传递给下游模块,避免在请求头中明文传递用户标识。
flowchart LR
Client[Agent / IDE] -->|Authorization Code| OAuth[oauth.py]
OAuth -->|access_token| Bind[identity_binding.py]
Bind -->|signed identity| Gate[gate.py]
Gate -->|policy check| Vault[vault.py]
Vault -->|injected secret| Tool[Tool Implementation]
Gate -->|allow/deny| Receipts[receipts.py]
Receipts -->|audit log| Audit[SECURITY_AUDIT.md]资料来源:src/willow_mcp/oauth.py:30-120、src/willow_mcp/identity_binding.py:20-90
入口网关与访问控制
gate.py 是整个安全链路的执行中枢。它在 MCP 请求进入业务工具之前完成三件事:校验 identity_binding 产生的身份令牌、读取调用者所请求的 tool_name 与参数、根据预置策略(allowlist、scopes、配额)判定是否放行。gate.py 的判定结果分为三类:allow、deny、require_step_up(需要二次认证,例如刷新凭据或重新同意 scope)。被拒绝或需要升级的请求不会触达 vault.py,从结构上避免敏感凭据被未授权调用读取。
资料来源:src/willow_mcp/gate.py:40-160
凭据保险库与可审计回执
vault.py 作为秘密管理组件,只接受来自 gate.py 放行后的请求,按需返回对应工具所需的第三方 API Key、数据库连接串等敏感信息,并在调用结束后立即从内存中清除。receipts.py 则为每一次授权决策生成结构化回执,包含调用者身份哈希、工具名、时间戳、决策结果与策略版本号,便于事后审计与合规追溯。SECURITY_AUDIT.md 汇总了威胁模型、已修复漏洞与残余风险,是评估整体安全态势的一手资料。
资料来源:src/willow_mcp/vault.py:25-110、src/willow_mcp/receipts.py:15-80、SECURITY_AUDIT.md:1-60
资料来源:src/willow_mcp/gate.py:1-40、src/willow_mcp/oauth.py:1-30
任务执行、钩子与运维
本条目覆盖 willow-mcp 项目中负责 任务执行接入、Agent 工具调用钩子 与 运行时服务运维 的核心组件,对应仓库的 src/willowmcp/、hooks/、scripts/、deploy/ 四个目录。这一组代码共同保证 MCP 工具既能被外部 Agent 安全调用,又能在 systemd 或容器环境中以守护进程方式托管。
继续阅读本节完整说明和来源证据。
模块拓扑
graph LR Agent[外部 Agent / Claude Code] -->|stdio JSON-RPC| Hook[hooks/pre_tool_use.py] Hook -->|白名单/脱敏| Server[willow-serve 启动的进程] Server -->|safe_integration 封装| Tools[MCP 工具集合] Toggle[mcp_entry_toggle.py] -.->|改写| Cfg[客户端 mcp.json / settings.json] Template[service.template] -.->|渲染| Unit[systemd unit] Dockerfile -.->|构建| Image[运行镜像] Unit --> Server Image --> Container[容器内运行 Server]
任务执行接入:safe_integration 与 pre_tool_use
safe_integration.py 是 MCP 工具的运行时封装层,统一处理异常、入参与审计:捕获工具内部异常并以可解析 JSON 返回,避免单次失败拖崩整个会话;依据 schema 对入参做键名、长度与可疑字符串过滤;并在每次调用时记录工具名、参数哈希与时间戳。资料来源:src/willow_mcp/safe_integration.py:1-40,资料来源:src/willow_mcp/safe_integration.py:42-90,资料来源:src/willow_mcp/safe_integration.py:92-130。
hooks/pre_tool_use.py 是面向客户端的 PreToolUse 钩子,在每次工具调用前被触发,负责 白名单 / 黑名单判定、路径收敛 和 零延迟返回。--allow 与 --deny 通过 argv 解析加载并据此放行或拒绝;涉及文件系统的工具调用会被强制收敛到工程根目录下,阻止越权读取;钩子以 exit 0 表示放行,非零状态码 + stderr 表示拒绝原因,避免长时间占用调用栈。资料来源:hooks/pre_tool_use.py:10-55,资料来源:hooks/pre_tool_use.py:57-90,资料来源:hooks/pre_tool_use.py:92-110。
两层组合形成" 调用前过滤 + 调用中兜底"的双闸门模式,是 willow-mcp 防止外部 Agent 越权调用的核心机制。
服务运维:systemd 单元与容器化
scripts/willow-serve 是守护进程入口脚本,以 exec 把 stdio 透传给真正的 MCP 服务器进程,支持前台模式与 --daemon 后台模式,便于被 systemd 直接接管。资料来源:scripts/willow-serve:5-40。
deploy/willow-mcp-serve.service.template 是 systemd unit 模板,包含 User=、WorkingDirectory=、ExecStart= 三个占位符,部署阶段被渲染脚本替换。模板默认启用 Restart=on-failure 与 Environment=PYTHONUNBUFFERED=1,确保 Python 输出不被内核缓冲、可被 journalctl 完整捕获。资料来源:deploy/willow-mcp-serve.service.template:6-22。
Dockerfile 采用多阶段构建:构建阶段安装 pyproject.toml 中声明的依赖,运行阶段将已安装的包复制到 python:slim 基础镜像,并将 willow-serve 设为 ENTRYPOINT,由 CLI 参数决定启用哪些工具子集。资料来源:Dockerfile:1-15,资料来源:Dockerfile:18-35。
三者分别覆盖开发机直跑、服务节点 systemd 与生产集群容器镜像这三种典型部署形态。
客户端入口切换:mcp_entry_toggle
scripts/mcp_entry_toggle.py 是面向客户端的切换 CLI,用于在 ~/.config/claude*/settings.json 与项目级 .mcp.json 之间改写 willow-mcp 条目的 command/args,把入口在本地脚本路径与 Docker 镜像路径之间互换,从而让同一台机器上的不同 Agent 复用同一份协议栈。其切换流程为:①读取目标 JSON 文件;②把原文件备份到 .bak;③改写 mcpServers.<name> 的 command、args;④写回磁盘并重新解析校验,任一步骤出错都会回滚到备份。资料来源:scripts/mcp_entry_toggle.py:20-70,资料来源:scripts/mcp_entry_toggle.py:72-130。
小结:safe_integration.py 与 pre_tool_use.py 共同提供执行期安全;willow-serve + systemd 模板 + Dockerfile 提供三种运维形态;mcp_entry_toggle.py 让协议栈可以在不同 Agent 客户端之间以最小代价切换。整体形成一个 接入 — 防护 — 部署 — 切换 的完整闭环。
来源:https://github.com/rudi193-cmd/willow-mcp / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
风险会影响是否适合普通用户安装。
Pitfall Log / 踩坑日志
项目:rudi193-cmd/willow-mcp
摘要:发现 8 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。
1. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 证据:capability.host_targets | https://github.com/rudi193-cmd/willow-mcp | host_targets=mcp_host, claude_code, claude, cursor
2. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://github.com/rudi193-cmd/willow-mcp | README/documentation is current enough for a first validation pass.
3. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://github.com/rudi193-cmd/willow-mcp | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://github.com/rudi193-cmd/willow-mcp | no_demo; severity=medium
5. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://github.com/rudi193-cmd/willow-mcp | no_demo; severity=medium
6. 安全/权限坑 · 来源证据:knowledge mapping confirmed on name-match: content column is metadata JSON, title/summary never surface
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:knowledge mapping confirmed on name-match: content column is metadata JSON, title/summary never surface
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 证据:community_evidence:github | https://github.com/rudi193-cmd/willow-mcp/issues/20 | 来源类型 github_issue 暴露的待验证使用条件。
7. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://github.com/rudi193-cmd/willow-mcp | issue_or_pr_quality=unknown
8. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://github.com/rudi193-cmd/willow-mcp | release_recency=unknown
来源:Doramagic 发现、验证与编译记录