> ## Documentation Index
> Fetch the complete documentation index at: https://mcp.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SEP-1303: 输入验证错误作为工具执行错误

> 输入验证错误作为工具执行错误

<div className="flex items-center gap-2 mb-4">
  <Badge color="green" shape="pill">
    最终版
  </Badge>

  <Badge color="gray" shape="pill">
    标准轨道
  </Badge>
</div>

| 字段       | 值                                                                               |
| -------- | ------------------------------------------------------------------------------- |
| **SEP**  | 1303                                                                            |
| **标题**   | 输入验证错误作为工具执行错误                                                                  |
| **状态**   | 最终版                                                                             |
| **类型**   | 标准轨道                                                                            |
| **创建日期** | 2025-08-05                                                                      |
| **作者**   | [@fredericbarthelet](https://github.com/fredericbarthelet)                      |
| **赞助人**  | 无                                                                               |
| **PR**   | [#1303](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1303) |

***

## 摘要

本 SEP 提议将工具输入验证错误视为工具执行错误，而不是协议错误。这一变更将使语言模型能够在其上下文窗口中接收验证错误反馈，允许它们自我纠正并成功完成任务而无需人工干预，显著提高任务完成率。

## 动机

语言模型可以从工具输入验证错误消息中学习，并相应地重试带有修正参数的 tools/call，但前提是它们在其上下文窗口中接收到错误反馈。协议错误由 MCP 客户端在应用层捕获。只有工具执行错误才会作为 JSON-RPC 响应转发回模型。根据当前规范，模型无法看到这些错误消息，因此无法自我纠正，导致重复失败和糟糕的用户体验。

### 问题陈述

考虑一个使用以下 `zod` 验证架构验证出发日期的航班预订工具：

```typescript theme={null}
departureDate: z.string()
  .regex(/^\d{2}\/\d{2}\/\d{4}$/, "date must be in dd/mm/yyyy format")
  .superRefine((dateStr, ctx) => {
    const date = parseDateFr(dateStr);
    if (date.getTime() < Date.now()) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message:
          "Dates must be in the future. Current date is " +
          formatDateFr(new Date()),
      });
    }
    return true;
  })
  .describe("Departure date in dd/mm/yyyy format");
```

工具预期的输入 JSON 架构只能描述正则语句。实际的日期在过去的时间编程检查无法在此处表示为 JSON 架构。
即使模型提供了语法正确且通过 JSON 架构验证的日期，也无法保证它在未来。当验证错误被引发并作为协议错误返回时：

1. 模型没有收到解释日期为何被拒绝的错误消息
2. 模型多次重复同样的错误（例如，当用户只指定日和月或相对日期时，Cursor 通常一致地发送 2024 年的日期，并重复相同的 tools/call 请求 3 次，而没有获得任何关于工具调用为何失败的信息）
3. 尽管模型在获得适当反馈的情况下能够自我纠正，但任务仍然失败
4. 用户感到沮丧并且必须手动干预

### 本提案的好处

1. **更高的任务完成率**：模型无需人工干预即可自我纠正验证错误
2. **更好的用户体验**：减少失败并加快任务完成
3. **利用模型能力**：现代大语言模型擅长理解和响应错误消息
4. **减少 API 调用**：随着模型在第一个错误上自我纠正，重试尝试减少

## 规范

### 当前行为

[工具错误规范](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#error-handling) 目前提供了模糊的指导：

* “无效参数”应被视为协议错误
* “无效输入数据”应被视为工具执行错误

这种模糊性导致不一致的实现，其中有价值的错误反馈丢失。

### 提议的变更

通过以下变更澄清规范：

1. 从 **协议错误** 中移除“无效参数”类别。
2. **工具执行错误** 应用于所有工具参数验证失败（将 `无效参数` 和 `无效输入数据` 合并到新的 `输入验证错误` 类别下）

### 规范文本变更

更新错误处理部分以包括：

```
## 错误处理

工具使用两种错误报告机制：

1. **协议错误**：用于以下问题的标准 JSON-RPC 错误：

   - 未知工具
   - 服务器错误

2. **工具执行错误**：在工具结果中报告，带有 `isError: true`：
   - API 失败
   - 输入验证错误
   - 业务逻辑错误
```

## 实现

### 之前（协议错误）

```typescript theme={null}
// 模型提交过去的日期
request: {
  ...
  method: "tools/call",
  params: {
    name: "book_flight",
    arguments: {
      departureDate: "12/12/2024"  // 过去的日期
    }
  }
}

// 服务器返回协议错误
response: {
  ...
  error: {
    code: -32602,
    message: "Invalid params"
  }
}

// 模型盲目地用另一个过去的日期重试
// 此循环重复直到失败
```

### 之后（工具执行错误）

```typescript theme={null}
// 模型提交过去的日期
request: {
  ...
  method: "tools/call",
  params: {
    name: "book_flight",
    arguments: {
      departureDate: "12/12/2024"  // 过去的日期
    }
  }
}

// 服务器返回工具执行错误（对模型可见）
response: {
  ...
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Dates must be in the future. Current date is 08/08/2025"
      }
    ],
    "isError": true
  }
}

// 模型理解错误并自我纠正
request: {
  method: "tools/call",
  params: {
    name: "book_flight",
    arguments: {
      departureDate: "12/12/2025"  // 未来的日期
    }
  }
}
```

## 向后兼容性

此变更是向后兼容的，因为它：

* 不改变协议结构
* 仅澄清现有的模糊行为
* 维持所有现有的错误类型和格式
* 在不破坏现有实现的情况下改进行为

实施澄清行为的服务器将提供更好的模型自我恢复，同时继续与所有现有客户端一起工作。

## 参考资料

* [MCP 工具错误处理规范](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#error-handling)
* [更好的 MCP tools/call 错误响应：帮助你的 AI 优雅地恢复](https://dev.to/alpic/better-mcp-toolscall-error-responses-help-your-ai-recover-gracefully-15c7)
* 相关问题：[https://github.com/modelcontextprotocol/typescript-sdk/pull/824](https://github.com/modelcontextprotocol/typescript-sdk/pull/824)
