幂等性演示工具

一个展示MCP工具调用中幂等性的Python演示项目,包含非幂等和幂等服务器实现。

  • by MarlzRana
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 MarlzRana/mcp-idempotency

使用说明

MCP Idempotency演示(流式HTTP、Python)

此仓库包含一个最小的演示,说明MCP工具调用中的幂等性,使用 python,the MCP Python SDK,以及 流式HTTP 运输。

注: 首选方法是引入一个新的顶级属性 idempotencyKey 到CallToolRequest。这使得幂等性明确且是必需的,而不仅仅是一段可选或可忽略的元数据。通过制造 idempotencyKey 作为一级属性,客户端和服务器都清楚幂等性是协议的核心部分,可以减少歧义和意外遗漏的风险。但是,此演示在 _meta 现场(_meta.io.modelcontextprotocol/idempotency-key)以避免破坏当前的MCP规范。两种形式见下文。

组件

  • server_non_idempotent.py:带工具的MCP服务器:
    • make_payment(IBAN, BIC, amountMinorUnits, currency) – 不 幂等性;重试时,它会再次收费。
    • get_balance() –退货 { "balanceMinorUnits": <int> }.
    • get_transactions() –退货 { "transactions": [...] }.
  • server_idempotent.py:工具相同,但 make_payment 用途 _meta.io.modelcontextprotocol/idempotency-key 是 幂等性。使用相同密钥重试 不 申请付款 再一次。
  • client.py:一个客户:
    1. 呼叫 get_balance.
    2. 呼叫 make_payment 一次(服务器速度较慢,因此HTTP客户端超时)。
    3. 重试 make_payment 同样的论点。
    4. 呼叫 get_balance 和 get_transactions 再次打印结果。

客户端对非幂等服务器运行此序列一次,对 幂等服务器,因此您可以直接比较结果。

创建venv

uv venv

安装依赖项

uv install -r requirements.txt

运行服务器(流式HTTP)

在一个终端中:

uv run server_non_idempotent.py

在另一个终端中:

uv run server_idempotent.py

两台服务器都公开了MCP 流式HTTP 接受JSON POST请求的端点。此演示使用保留密钥方法实现兼容性:

{
  "tool": "make_payment",
  "params": {
    "IBAN": "...",
    "BIC": "...",
    "minorUnits": 2500,
    "currency": "EUR"
  },
  "_meta": {
    "io.modelcontextprotocol/idempotency-key": "73c2eaf4-8cc4-4ba4-908f-7017f0aa2f4f"
  }
}

首选(未来)方法:

{
  "tool": "make_payment",
  "params": {
    "IBAN": "...",
    "BIC": "...",
    "minorUnits": 2500,
    "currency": "EUR"
  },
  "idempotencyKey": "73c2eaf4-8cc4-4ba4-908f-7017f0aa2f4f"
}

运行演示客户端

两台服务器都在运行时:

uv run client.py

您应该注意:

  • 非幂等服务器
    • 第一 make_payment 调用:客户端记录超时,但服务器已经应用了付款。
    • 第二 make_payment 调用:服务器应用支付 再次 (无幂等性),因此 get_balance 显示两个借记和 get_transactions 包含两个匹配的付款。
  • 临时服务器
    • 第一 make_payment 调用:客户端超时,但服务器应用一次支付并存储 这 _meta.io.modelcontextprotocol/idempotency-key.
    • 第二 make_payment 用同样的电话 _meta.io.modelcontextprotocol/idempotency-key:服务器 不 再次申请付款,因此 get_balance 仅显示一笔借记 get_transactions 只有一笔付款。

这提供了一个具体的、端到端的说明,说明为什么幂等性对于安全重试支付等工具很有价值。虽然此演示在中使用了保留密钥 _meta 为了兼容性,建议的方法是 idempotencyKey MCP规范中的一级属性。