makecindy / makecindy/cindy

Auto 档对 MCP 工具完全绕过 AI 审阅,只走 server 级静态白名单

Open
#1,576 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
2.7k
Forks
395
Avg merge
21h 48m
Merged PRs (30d)
776

Description

## 现象

Auto 权限档对 MCP 工具**完全不生效**。所有 `mcp__*` 工具被排除在 AI 审阅之外,只走一张静态策略表,结果两头都不理想:

- 表内可信 server(`cindy_browser`、`cindy_scheduler`、`cindy_orca`…)整体静默执行,AI 完全不过目
- 表外(第三方 server、插件宿主 `cindy` 的 `ghost_call`、`cindy_ssh`)恒定逐次弹窗,用户选了 Auto 也照弹

## 代码位置

`packages/maker-core/src/agents/claude-code/index.ts:1613`:

```ts
if (mutablePermissionMode === 'auto' && !toolName.startsWith('mcp__')) {
// ... reviewAutoAction
} else {
if (mcpApprovalPolicy === 'auto-approve' && !turnPolicyForcePrompt) return allow;
forcePrompt = forcePrompt || mcpApprovalPolicy === 'prompt-each-time';
}
```

策略表:`apps/desktop/src/main/maker-host/mcp-tool-approval-policy.ts:96`

```ts
if (toolName && READ_ONLY_MCP_TOOLS.has(`${serverName}::${toolName}`)) return 'auto-approve';
if (serverName === 'cindy_contacts') return canAutoApproveContactsMcpTool(...) ? 'auto-approve' : 'prompt-each-time';
if (TRUSTED_MCP_SERVERS.has(serverName)) return 'auto-approve';
return 'prompt';
```

## 为什么值得改

这张表的粒度是 **server 级 + 少量工具级白名单**,判据是"这个 server 是否已 review 过",不看**本次调用的实际参数和用户意图**。而 Auto 档的整个设计前提恰恰是"按当前意图逐个动作判定"。

具体后果:

- `cindy_browser::call_tool` 整体可信 → 一次浏览器调研里访问任意站点、提交任意表单都不过目
- `cindy_ssh::call_tool` 在远端跑任意命令 → 永远弹窗,Auto 档形同虚设
- `cindy::ghost_call` 转发到第三方插件沙箱 → 同上

Bash 侧已经有确定性规则 + 灰区送审的完整分层(`packages/maker-core/src/agents/shared/auto-review.ts`),MCP 侧却停留在二值白名单。

## 建议改法(保持独立)

不动现有静态表的语义,只在它**判为 `prompt` / `prompt-each-time`** 时增加一层灰区送审:

1. 把 MCP 调用映射成 `ReviewableAction`(`kind: 'other'` + server/tool/参数摘要,或对 `cindy_ssh` 之类映射成 `exec`)
2. 送 `resolveAutoReviewDecision`,`allow` 则放行,`block` 静默拒,`ask` 才弹窗
3. `auto-approve` 的表项保持原样,零行为变化

这样 Auto 档对 MCP 从"要么全静默要么全弹"变成和内建工具同一套语义,且对已可信 server 无回归。

## 独立性

只碰 `claude-code/index.ts` 与 `codex/index.ts` 的 MCP 分支 + 一个 action 映射函数,不依赖其他 auto-review issue。

注:与「无 UI 场景 MCP 一律 deny」是**两个**问题,那条单独提。本 issue 只讨论有 UI 时 Auto 档的审阅粒度。

## 验证

- Auto 档下调 `cindy_ssh::call_tool` 跑一条只读命令,确认不再弹窗
- Auto 档下调同一工具跑破坏性命令,确认 block 或 ask
- 确认 `cindy_browser::list_tools` 等只读白名单行为不变

Contributor guide

Open the contributing guide

Research direction

Start with the MCP branches in packages/maker-core/src/agents/claude-code/index.ts and codex/index.ts, then read packages/maker-core/src/agents/shared/auto-review.ts and the policy in apps/desktop/src/main/maker-host/mcp-tool-approval-policy.ts. Map only prompt and prompt-each-time decisions into the existing review flow while preserving auto-approve behavior. Verify read-only cindy_ssh calls no longer prompt, destructive calls block or ask, and cindy_browser::list_tools remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authorization, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.