Skip to content

feat: 新增 self-config 自配置 MCP 工具(owner 授权下安全编辑运行配置)#269

Open
lishuceo wants to merge 3 commits into
mainfrom
feat/self-config-tool
Open

feat: 新增 self-config 自配置 MCP 工具(owner 授权下安全编辑运行配置)#269
lishuceo wants to merge 3 commits into
mainfrom
feat/self-config-tool

Conversation

@lishuceo

@lishuceo lishuceo commented Jul 1, 2026

Copy link
Copy Markdown
Owner

背景

用户希望土豆儿(chat bot)能编辑 anycode 自己的配置。现状 /edit(owner-only in-place)已能改热加载配置,但需手打前缀、裸 Write/Bash 无校验、易误伤源码。本 PR 加一个专用的、收敛风险的自配置工具。

方案

新增 manage_config MCP 工具(server self-config),让 anycode 在 owner 授权下安全编辑「自己」的运行配置。工具运行在服务进程内(cwd = 部署目录),命中的是运行实例真实读取的 LIVE 配置,天然绕过隔离 clone 副本问题。

安全边界(四层)

  • owner 门禁:整只工具仅 OWNER_USER_ID 可用;非 owner 在 executor 层根本不创建该 server(fail-closed)
  • 白名单:只能改 agents.json / personas/*.md / knowledge/*.md / .env / ~/.claude.jsonmcpServers 段;防路径穿越、拒 .example 模板、拒非 .md
  • 写前校验:agents.json 走 Zod schema、.env 走 KEY=VALUE 行校验,非法内容不落盘
  • 自动备份:每次写入前备份到 data/config-backups/,可回滚

生效方式

  • agents.json / 人设 / 知识 → 写后 reloadAgentConfig 热加载即时生效,无需重启
  • .env / MCP → 明确提示需重启(仅启动时加载)

Actions

list / read / write / set_mcp / remove_mcpset_mcp 浅合并,保留其它 server 与顶层其它键(不会误删 174KB claude.json 里的历史)。

改动

  • src/config-admin/manager.ts — 纯逻辑:白名单解析 + 校验 + 备份 + 落盘 + MCP 合并
  • src/config-admin/tool.tsmanage_config MCP 工具 + owner 门禁
  • src/agent/config-loader.ts — 导出 getConfigPaths() 定位 LIVE 配置
  • src/claude/executor.ts — owner 门禁创建 server + readonly 放行(否则 readonly 的土豆儿调不了)
  • src/utils/security.tsisOwner 防御性空值处理(config.security 缺失不再抛错)

测试

  • 新增 29 个 manager 单测(白名单/穿越/校验/备份/写入/reload/MCP 合并)+ 2 个 executor owner 门禁用例
  • 全量回归:1755 passed(唯一失败 memory/quality.test.ts既有 flaky,干净基线上同样失败,与本 PR 无关)
  • npm run typecheck 通过

🤖 Generated with Claude Code

lishuceo and others added 3 commits July 1, 2026 16:59
- getConfigPaths() 返回运行实例真实使用的 agents.json/personas/knowledge 路径,
  供自配置工具定位 LIVE 配置文件(而非隔离 clone 里的副本)
- isOwner 改为 config.security?.ownerUserId,security 缺失时按'未配 owner'处理,
  与'空则全员 owner'语义一致,避免调用方在 config 不全时抛错

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
manage_config 工具让 anycode 在 owner 授权下安全编辑自己的运行配置:
- 白名单: agents.json / personas/*.md / knowledge/*.md / .env / ~/.claude.json 的 MCP
- 防路径穿越、拒 .example 模板、拒非 .md
- 写前校验: agents.json 走 Zod schema,.env 走 KEY=VALUE 行校验,非法内容不落盘
- 写前自动备份到 data/config-backups/,可回滚
- agents.json 写后立即 reloadAgentConfig,热加载即时生效;.env/MCP 提示需重启
- set_mcp/remove_mcp 浅合并 mcpServers,保留其它 server 与顶层其它键

工具运行在服务进程内(cwd=部署目录),命中的是运行实例真实读取的 LIVE 配置。
附 29 个单测覆盖白名单/校验/备份/写入/reload/MCP 合并。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 按 sessionKey 解析 userId,仅当 isOwner(userId) 时创建 self-config MCP server
  (非 owner 完全不可见,fail-closed)
- 在 readonly MCP 放行块加入 mcp__self-config__ 分支,否则土豆儿(pm, readonly)
  调不了自配置工具
- 附 executor owner 门禁正/反用例

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished @lishuceo's task in 3m 32s —— View job


Review: self-config 自配置工具 — ⚠️ Approved with considerations

  • Read CLAUDE.md & PR intent
  • Review config-admin/manager.ts
  • Review config-admin/tool.ts
  • Review config-loader.ts
  • Review executor.ts
  • Review security.ts
  • Check tests
  • Post review

整体质量很高:四层安全边界(owner 门禁 / 白名单 / 写前校验 / 自动备份)设计清晰,纯逻辑与 MCP 工具分层干净,路径穿越/.example/非 .md 的拒绝逻辑正确(withinDirbase + '/' 前缀比对稳妥),29+2 个测试覆盖到位。没有发现阻塞性 bug。以下是几点值得考虑的地方,按优先级排列。

🟡 1. OWNER_USER_ID 未配置时,敏感配置读写会对所有人开放(security,~70%)

isOwner() 在 owner 未配置时对所有人返回 truesrc/utils/security.ts:22-24 的向后兼容语义)。executor 的门禁 if (scUserId && isOwner(scUserId))src/claude/executor.ts:813)因此在未设 owner 时会给每个用户创建 self-config server。而该工具可以 read .env(内含 ANTHROPIC_API_KEY / FEISHU_APP_SECRET)并改写 .env / agents.json / ~/.claude.json——这是一条新增的机密外泄/篡改路径。

autoDetectOwner 会把首条消息者设为 owner 从而收敛这个窗口,但它依赖首条消息成功触发、userId 格式校验通过、.env 可写。考虑到这是本仓库权限最高的工具,建议对它单独 fail-closed:owner 未显式配置时不创建 server(而非沿用「人人皆 owner」)。既有的 /edit 虽用同一 isOwner,但需手动前缀调用,风险面小于自动注入的 MCP 工具。

🟡 2. ~/.claude.json 读-改-写与 CLI 子进程存在竞态(correctness,~60%)

setMcpServer / removeMcpServersrc/config-admin/manager.ts:308-347)对 ~/.claude.json 做整份 read → mutate → JSON.stringify(..,2) 写回。但这个文件是正在运行的 Claude Code 子进程持续写入的(history / projects)。tool 调用发生在 query 执行期间,read-modify-write 可能覆盖子进程的并发写入(lost update),反之亦然。effect 已是 restart 所以影响有限,但值得在注释里点明该风险,或至少确认 set_mcp/remove_mcp 只在无活跃 query 时调用。整份 re-stringify 还会规范化 174KB 文件的缩进(非数据丢失,仅 diff 噪音)。

🔵 3. 次要项

  • backupFilemanager.ts:179)用 new Date().toISOString() 做文件名,同毫秒内两次写入会覆盖同名备份。低概率、低危害。
  • set_mcp 传空对象 {} 时,tool.ts if (!args.mcp_config)tool.ts:142)判定为真({} truthy)→ setMcpServer 校验 {} 是合法 object → 写入一个空的 server 配置。建议对必需字段(commandtype/url)做最小校验。

以上均非阻塞。方案本身(改 LIVE 配置绕过隔离副本、agents.json 走 Zod、.env 走行校验)是正确的取舍。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant