跳转至

MCP Elicitation 专题

重要性:⭐⭐⭐⭐(MCP 协议扩展——server 主动问用户信息) 真实位置src/Tool.ts + src/QueryEngine.ts + src/types/hooks.ts + src/utils/hooks.ts 角色:MCP 错误码 -32042 → server 请求用户信息 → client 处理 URL 关联topics/deep-dive-mcp-client.mdtopics/deep-dive-mcp-auth.md


1. Elicitation 是什么

MCP Elicitation = server 主动向 client 请求额外信息 - server 工具调用时返回错误 -32042 - 错误中包含 URL(要用户在浏览器打开) - client 处理这个 URL(打开浏览器 / 等待 / 回调) - 类似 OAuth 流程

Claude Code 的实现 —— Tool.handleElicitation + QueryEngine.handleElicitation


2. 错误码 -32042

MCP 错误码:
-32700  Parse error
-32600  Invalid Request
-32601  Method not found
-32602  Invalid params
-32603  Internal error
-32042  Elicitation  ← 这

-32042 = server 要求 elicitation(auth、user info 等)。


3. 5 个相关文件

src/
├── Tool.ts                ← Tool.handleElicitation 接口
├── QueryEngine.ts         ← QueryEngine.handleElicitation 集成
├── main.tsx               ← 初始化 elicitation 上下文
├── types/hooks.ts         ← ElicitationHookInput / ElicitationResult types
└── utils/hooks.ts         ← 触发 Elicitation hook

5 个文件 —— 跨层集成。


4. 3 大核心类型

4.1 ElicitRequestURLParams

type ElicitRequestURLParams = {
  // server 提供的参数
  url: string
  // ... 其它 params
}

server 返回 —— URL 让用户在浏览器打开。

4.2 ElicitResult

type ElicitResult = {
  // 用户完成 elicitation 后的结果
  // 通常是 token / code
}

client 返回 —— 用户完成的凭证。

4.3 ElicitationHookInput / ElicitationResult

// types/hooks.ts
{
  hookEventName: z.literal('Elicitation'),
  // ...
}

{
  hookEventName: z.literal('ElicitationResult'),
  // ...
}

Hook 输入/输出 —— 触发 Elicitation hook。


5. 完整流程

MCP server 工具调用
返回错误 -32042
client 解析错误
Tool.handleElicitation(params)
打开浏览器 / 等待 callback
用户完成(OAuth 等)
ElicitResult
retry 工具调用

8 步流程


6. Tool.handleElicitation

// Tool.ts
interface Tool {
  handleElicitation?: (
    params: ElicitRequestURLParams,
  ) => Promise<ElicitResult>
}

Tool 接口 —— 工具可实现 handleElicitation

默认实现: - print/SDK 模式:structuredIO.handleElicitation(推测) - 交互模式:UI 弹窗(推测)

6.1 注释

/**
 * Optional handler for URL elicitations triggered by tool call errors (-32042).
 * In print/SDK mode, this delegates to structuredIO.handleElicitation.
 */

注释 —— 解释用途和模式。


7. QueryEngine.handleElicitation

// QueryEngine.ts
class QueryEngine {
  config: {
    handleElicitation?: ToolUseContext['handleElicitation']
  }
}

QueryEngine 持有 handleElicitation 引用。

7.1 3 处使用

// 3 处
handleElicitation: this.config.handleElicitation,  // 构造
handleElicitation: this.config.handleElicitation,  // 构造 (推测)
handleElicitation,  // 调用

3 处集成 —— 透传到工具。


8. main.tsx 初始化

// main.tsx
elicitation: {
  // ... 配置
}

初始化 —— 把 elicitation 注入到 tool context。

位置推测:在 ToolUseContext 配置中。


9. Hook 触发

9.1 Elicitation Hook

// types/hooks.ts
{
  hookEventName: 'Elicitation',
  // ...
}

Hook 事件 —— 用户配置可拦截。

9.2 ElicitationResult Hook

// types/hooks.ts
{
  hookEventName: 'ElicitationResult',
  // ...
}

结果 hook —— 用户完成 elicitation 触发。

9.3 用法

{
  "hooks": {
    "Elicitation": [
      {
        "hooks": [
          { "type": "command", "command": "log-elicitation.sh" }
        ]
      }
    ]
  }
}

配置 —— 用户可拦截。


10. ElicitResult 处理

// 推测
async function handleElicitation(params) {
  // 1. 打开 URL
  await openExternal(params.url)

  // 2. 等待 callback
  const result = await waitForCallback()

  // 3. 触发 ElicitationResult hook
  await runHook('ElicitationResult', { result })

  // 4. 返回 result
  return result
}

4 步 —— URL → 等待 → hook → 返回。


11. 与 OAuth 的对比

维度 OAuth Elicitation
触发 MCP server 启动 MCP 工具调用
错误码 401 -32042
流程 browser → callback → token browser → callback → result
handler ClaudeAuthProvider Tool.handleElicitation
持久化 token 存 disk result 在内存

类似但不同 —— 两者都用 URL + browser,但触发场景不同。


12. 推测的实现细节

12.1 URL 格式

https://example.com/elicit?param1=...&param2=...

MCP 标准 —— 类似 OAuth authorize URL。

12.2 Callback 机制

// 推测:类似 OAuth callback
const callbackPromise = new Promise((resolve) => {
  // 监听 callback server
})

本地 server —— 接收 redirect。

12.3 错误重试

// 推测:拿到 result 后 retry 工具调用
const result = await handleElicitation(params)
return retryToolCall(result)

自动 retry


13. 关键设计模式

13.1 Optional handler

handleElicitation?: (...) => Promise<ElicitResult>

可选 —— 不是所有 tool 都有。

13.2 错误码驱动

-32042 触发 —— 标准化。

13.3 Hook 集成

用户可拦截 —— Elicitation / ElicitationResult。

13.4 URL 回调模式

browser → callback —— OAuth 模式复用。

13.5 上下文透传

QueryEngine.config.handleElicitation —— 透传到工具。


14. 安全考虑

14.1 URL 来源

MCP server 提供 —— 信任 server。

14.2 Callback 来源

仅本地 server —— 避免伪造。

14.3 Result 验证

server 验证 —— 不应 client 验。

14.4 用户确认

推测:总是弹窗 让用户确认。


15. 错误处理

15.1 错误 -32042 解析

// 推测
if (error.code === -32042) {
  const params = parseElicitParams(error)
  return handleElicitation(params)
}

特定错误码 触发。

15.2 超时

// 推测:30s 默认
const result = await Promise.race([
  handleElicitation(params),
  timeout(30000)
])

30s timeout —— 类似 OAuth。

15.3 用户取消

// 推测:返回 ElicitResult { cancelled: true }

取消支持


16. 关键洞察

16.1 Elicitation = OAuth 类似

URL + browser + callback —— 复用 OAuth 模式。

16.2 错误码 -32042 触发

MCP 协议级 —— 标准化。

16.3 Tool 接口可选

不是所有 tool 都实现。

16.4 Hook 集成

用户可拦截 Elicitation / ElicitationResult。

16.5 上下文透传

QueryEngine → Tool context。

16.6 OAuth 模式复用

URL + browser 模式同。

16.7 安全考虑

URL 信任 server,callback 仅本地。

16.8 错误处理完善

超时 / 取消 / 重试。


17. 阅读建议

  1. Tool.ts handleElicitation 接口 —— 入口
  2. QueryEngine.ts 3 处使用 —— 集成
  3. types/hooks.ts Elicitation types —— 协议
  4. main.tsx elicitation 配置 —— 初始化

18. 与其他专题的关系

文件 关系
deep-dive-mcp-client.md MCP 客户端
deep-dive-mcp-auth.md MCP OAuth(不同)
authentication.md 鉴权(OAuth 类似)