NUAAwqy opened a new pull request, #6947:
URL: https://github.com/apache/rocketmq-dashboard/pull/6947

   ### What this PR does
   
   The rmqctl stdio-MCP bridge re-encodes JSON-RPC messages through mcp-go SDK 
types. The SDK decodes numeric ids (mcp.RequestId and notification params) 
through float64, so integers beyond 2^53 are silently rounded:
   
   - a request id like `9007199254740993` is sent as `9007199254740992` (int64 
max becomes `9223372036854776000`),
   - the id returned to the stdio client is the rounded one,
   - a response carrying the rounded neighbour of the request id is accepted as 
matching,
   - `notifications/cancelled` forwards `params.requestId` rounded.
   
   Reproduced on `rocketmq-studio` at `a92c231` with the production 
`MCPClientSession` against a local httptest peer; no live Studio/Broker 
required.
   
   Fixes #6904
   
   ### How it is fixed
   
   Bridge-side, no SDK change:
   
   - `decodeMCPMessage` keeps the exact textual token for numeric request ids 
(`json.Number` re-marshals verbatim) and for a numeric `params.requestId` in 
notifications.
   - `mcpStatusRoundTripper` compares the raw id token of the outgoing JSON-RPC 
request against the response frame before the SDK decodes it: JSON bodies 
eagerly, POST SSE streams as the response frame is consumed (non-response SSE 
events keep streaming unblocked). Numeric tokens are compared by value (`1` 
matches `1.0`), a numeric and a string token never match, and a mismatch fails 
the exchange.
   - `sendRequest` returns the exact outgoing identity in the response payload 
once the raw tokens matched.
   
   ### Tests
   
   New `rmqctl/internal/studio/mcp_id_precision_test.go`: the four defect 
scenarios from the issue (the adjacent-id one over both the JSON and the SSE 
response channel) plus six passing controls.
   
   RED against the unmodified code:
   
   ```
   --- FAIL: TestLargeNumericRequestIDIsPreserved (0.00s)
   --- FAIL: TestInt64MaxRequestIDIsPreserved (0.00s)
   --- FAIL: TestAdjacentResponseIDIsRejected (0.00s)
   --- FAIL: TestLargeCancellationRequestIDIsPreserved (0.00s)
   --- FAIL: TestAdjacentResponseIDIsRejectedOverSSE (0.00s)
   --- PASS: TestSmallNumericRequestIDIsPreserved (0.00s)
   --- PASS: TestStringRequestIDIsPreserved (0.00s)
   --- PASS: TestStringResponseIDForNumericRequestIsRejected (0.00s)
   --- PASS: TestNumericResponseIDForStringRequestIsRejected (0.00s)
   --- PASS: TestSmallCancellationRequestIDIsPreserved (0.00s)
   --- PASS: TestStringCancellationRequestIDIsPreserved (0.00s)
   FAIL
   FAIL github.com/apache/rocketmq-dashboard/rmqctl/internal/studio     0.035s
   FAIL
       mcp_id_precision_test.go:134: wire request id was changed, body = 
{"jsonrpc":"2.0","id":9007199254740992,"method":"tools/list","params":{}}
       mcp_id_precision_test.go:134: returned response id was changed, payload 
= {"jsonrpc":"2.0","id":9007199254740992,"result":{"tools":[]}}
       mcp_id_precision_test.go:144: wire request id was changed, body = 
{"jsonrpc":"2.0","id":9223372036854776000,"method":"tools/list","params":{}}
       mcp_id_precision_test.go:144: returned response id was changed, payload 
= {"jsonrpc":"2.0","id":9223372036854776000,"result":{"tools":[]}}
       mcp_id_precision_test.go:157: adjacent response id was accepted: ok:true 
err:<nil>
       mcp_id_precision_test.go:174: cancellation requestId was changed, body = 
{"jsonrpc":"2.0","method":"notifications/cancelled","params":{"_meta":{},"requestId":9007199254740992}}
       mcp_id_precision_test.go:189: adjacent SSE response id was accepted: 
ok:true err:<nil>
   ```
   
   GREEN with the fix:
   
   ```
   --- PASS: TestLargeNumericRequestIDIsPreserved (0.00s)
   --- PASS: TestInt64MaxRequestIDIsPreserved (0.00s)
   --- PASS: TestAdjacentResponseIDIsRejected (0.00s)
   --- PASS: TestLargeCancellationRequestIDIsPreserved (0.00s)
   --- PASS: TestAdjacentResponseIDIsRejectedOverSSE (0.00s)
   --- PASS: TestSmallNumericRequestIDIsPreserved (0.00s)
   --- PASS: TestStringRequestIDIsPreserved (0.00s)
   --- PASS: TestStringResponseIDForNumericRequestIsRejected (0.00s)
   --- PASS: TestNumericResponseIDForStringRequestIsRejected (0.00s)
   --- PASS: TestSmallCancellationRequestIDIsPreserved (0.00s)
   --- PASS: TestStringCancellationRequestIDIsPreserved (0.00s)
   PASS
   ok   github.com/apache/rocketmq-dashboard/rmqctl/internal/studio     0.034s
   ```
   
   Full-module `go test ./... -count=1`, `go test -race ./internal/studio/ 
./cmd/`, `go vet ./...` and `gofmt -l` are clean, including the existing stdio 
saturation tests.
   
   AI assistance used for discovery; changes were verified by running the test 
suite locally.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to