coerce_request_id() folds non-canonical numeric strings, conflating wire-distinct JSON-RPC ids
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 84/100
Hướng nghiên cứu
Bắt đầu trong src/mcp/shared/dispatcher.py tại coerce_request_id() và đọc test hiện có của nó để hiểu hành vi dự kiến khi chuyển "7" thành 7. Thêm coverage hồi quy cho các chuỗi số không canonical và xác minh rằng các wire id khác nhau vẫn khác nhau trong các response đang chờ, việc hủy và định tuyến progress-token.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Initial Checks
- I confirm that I'm using the newest release of my line (the latest 2.x, or the latest 1.x if I'm still on v1)
- I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue
Release line
2.x (current stable)
Description
On current main, coerce_request_id() in src/mcp/shared/dispatcher.py folds a stringified id to int with a bare int(request_id). That accepts a lot more than a canonical integer string, so ids that are distinct on the JSON-RPC wire collapse onto one correlation key:
coerce_request_id('007') -> 7
coerce_request_id('+7') -> 7
coerce_request_id('1_000') -> 1000
coerce_request_id(' 7 ') -> 7
coerce_request_id('٧') -> 7
This shared key backs _pending (response correlation), _in_flight (cancellation), and progress-token routing. So a peer, or a caller using CallOptions["request_id"], that uses e.g. 10 and "1_0" as two ids has them merged. A notifications/cancelled for one hits the other, and the first can't be cancelled. It's the same cross-wiring class as #3060, but between ids that are genuinely different on the wire.
JSON-RPC 2.0 treats String and Number ids as distinct value types, and the function's own intent (and its test, "7" -> 7) is the canonical "peer stringified an int" case. The forms above aren't that. They're an artifact of Python's int(). The docstring says "matches the TS SDK", but JS Number("1_000") is NaN and Number("0x10") is 16, so today's behavior matches neither.
The narrow fix is to fold only when the string equals str(int(s)), which keeps the intended "7" -> 7 and "-3" -> -3 behavior and leaves every other string a distinct id. I have a patch and a regression test for it (both dispatchers share the function) and I'm happy to open a PR once this is triaged and assigned.
Disclosure: I used an AI coding assistant to help explore the code and draft this. I verified the reproduction and understand the fix myself.
Example Code
from mcp.shared.dispatcher import coerce_request_id
for raw in ("007", "+7", "1_000", " 7 ", "٧"):
print(repr(raw), "->", repr(coerce_request_id(raw)))
# every line prints an int, so all five distinct wire ids share one key
Python & MCP Python SDK
Python 3.11.14, python-sdk main @ 5bc9e07, macOS
- Ngôn ngữ chính
- Python
- Star
- 24.3k
- Fork
- 4k
- Merge trung bình
- 1 ngày 1 giờ
- Pull request đã merge (30 ngày)
- 31
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của modelcontextprotocol/python-sdk
-
Streamable HTTP client logs a WARNING for valid 202 Accepted on session termination (DELETE) Đang mởv1 v2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
modelcontextprotocol/python-sdk#3546 · 4 bình luận ·
-
v1 v2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
modelcontextprotocol/python-sdk#3545 · 1 bình luận ·
-
v1 v2
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 91/100
modelcontextprotocol/python-sdk#3508 · 2 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
modelcontextprotocol/python-sdk#3504 ·
-
v1 v2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
modelcontextprotocol/python-sdk#3492 · 1 bình luận ·
Tất cả issue của modelcontextprotocol/python-sdk
Issue tương tự
-
link-check link-check:sphinx-theme
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
qgis/QGIS-Documentation#11275 ·
-
bug priority:normal ready-for-dev
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
OpenHands/extensions#626 · 1 bình luận ·
-
Change observation tooltip text Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
CSCfi/sd-search-api#39 ·
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100