You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by "LuoYushi7 (via GitHub)" <gi...@apache.org> on 2026/09/21 11:49:20 UTC
[I] [studio] Design: let the rmqctl stdio MCP proxy forward server-initiated requests and client responses [rocketmq-dashboard]
LuoYushi7 opened a new issue, #4758:
URL: https://github.com/apache/rocketmq-dashboard/issues/4758
### Summary
`rmqctl mcp-stdio` bridges a newline-delimited stdio MCP client to a Studio
MCP session over Streamable HTTP. It can only forward client-to-server
requests and server-to-client notifications today. Two frame shapes have no
path through the proxy, so a stdio MCP client and the Studio server cannot
complete any exchange that is not a plain client→server request.
Raised from #4638. Posting the design first, per the contribution guide's
"discuss before coding" rule for this track.
### Current state
* `stdioProxy.handleEvent` (`rmqctl/cmd/mcp_stdio.go`) sends **every** stdin
line to `session.SendMessage` and prints whatever comes back on stdout.
* `studio.decodeMCPMessage` (`rmqctl/internal/studio/mcp_message.go`) accepts
only frames that carry a `method`. A JSON-RPC **response** carries `id` plus
`result`/`error` and no `method`, so it fails with
`invalid MCP JSON-RPC message: missing method`, which the proxy surfaces to
the caller as `-32603 Internal error`.
* The session exposes `SetNotificationHandler` (`mcp_http.go`) but no handler
for a **server-initiated request**, and no way to post a client response
back to the server.
Net effect: a server request (`sampling/createMessage`, `roots/list`) is
answered by the transport with `-32601 method not found` instead of reaching
the stdio client, and a client response never reaches the server, so the
server-side call waits for its timeout.
### Proposed design
**1. Classify stdin frames before forwarding.**
Extend the existing decode step to a three-way classification instead of
accepting only frames with a `method`:
| Frame | Shape | Action |
|---|---|---|
| request | `method` + `id` | `SendMessage` → stdout (today's behaviour) |
| notification | `method`, no `id` | `SendMessage` → no stdout (today's behaviour) |
| response | `id` + `result`/`error`, no `method` | `SendResponse` → no stdout |
Only the response case is new. Classifying in one place keeps stdin order and
the existing concurrency limits intact.
**2. Add a response path to the session.**
Add `SendResponse(ctx, payload) error` to `MCPClientSession`, and to the
`mcpSession` interface the proxy depends on (with the test fake extended to
match). It posts the frame to the same Streamable HTTP endpoint as a request,
but expects no JSON-RPC reply — the same shape as `SendNotification`, so it can
reuse `sendWithReconnect` for session-terminated recovery.
**3. Add a server-request handler that forwards to stdout.**
Register a handler on the transport alongside the existing notification
handler. On a server request the proxy writes the frame to stdout so the stdio
client can answer it. The answer comes back on stdin and is routed by (1) and
(2). Requests need to be tracked by id so a response can be matched, and an
in-flight server request must not be counted against `maxConcurrentCalls`,
which bounds client-originated calls only.
### Open questions
1. **Should a server request be forwarded while the initialize handshake is
still in flight?** The proxy deliberately preserves stdin order until
`initialized` is sent. Server requests can only arrive after that point in
practice, but I would rather state the ordering rule than assume it.
2. **What should happen to a response whose id matches no tracked request?**
Dropping it silently is cheap but hides a client bug; reporting it on stderr
is observable but noisy. I lean towards a bounded stderr diagnostic.
3. **Is adding `SendResponse` to the session the right layer**, or should the
transport expose it? The session already owns reconnect and timeout
behaviour, so putting it there keeps that policy in one place.
4. **Do we need a bound on tracked server requests?** A server that opens
requests and never reads the answers would otherwise grow the map.
### Tests I would add
* A response frame from stdin reaches the session response path instead of
being sent as a request, and does not print to stdout.
* A server-initiated request is forwarded to stdout verbatim.
* A client answer to a forwarded request reaches the server response path
matched by id.
* Existing behaviour is unchanged: request/notification forwarding, the
initialize-order gate, and `maxConcurrentCalls`.
Happy to adjust the shape before I write any code — in particular on
questions 2 and 4, which change observable behaviour.
--
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: commits-unsubscribe@rocketmq.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] [studio] Design: let the rmqctl stdio MCP proxy forward server-initiated requests and client responses [rocketmq-dashboard]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on issue #4758:
URL: https://github.com/apache/rocketmq-dashboard/issues/4758#issuecomment-5881207864
This issue has been automatically closed because there has been no activity for 7 days. If you believe this issue is still relevant, please reopen it with updated information.
--
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: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] [studio] Design: let the rmqctl stdio MCP proxy forward server-initiated requests and client responses [rocketmq-dashboard]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] closed issue #4758: [studio] Design: let the rmqctl stdio MCP proxy forward server-initiated requests and client responses
URL: https://github.com/apache/rocketmq-dashboard/issues/4758
--
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: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] [studio] Design: let the rmqctl stdio MCP proxy forward server-initiated requests and client responses [rocketmq-dashboard]
Posted by "RockteMQ-AI (via GitHub)" <gi...@apache.org>.
RockteMQ-AI commented on issue #4758:
URL: https://github.com/apache/rocketmq-dashboard/issues/4758#issuecomment-5760185953
**Issue Evaluation**
Category: `enhancement` | Status: **Evaluated**
**Feasibility:** Feasible
**Scope:** `rmqctl/cmd/mcp_stdio.go`, `rmqctl/internal/studio/mcp_message.go`, `rmqctl/internal/studio/session.go`
**Compatibility:** No breaking changes — additive frame handling
The design proposal is well-structured and correctly identifies the gap: the current stdio MCP proxy only handles client→server requests and server→client notifications, but cannot forward server→client requests or client→server notifications.
**Key observations:**
1. The two missing frame shapes (server-initiated requests, client-initiated notifications) are legitimate MCP protocol flows that should be supported for full protocol compliance.
2. The proposed approach of extending `decodeMCPMessage` to distinguish frame types and routing them appropriately is sound.
3. The bidirectional forwarding model (stdin→server, server→stdout) needs careful handling of concurrent request/response pairing to avoid interleaving issues.
**Recommendation:** The design is ready for implementation. Consider adding integration tests that exercise both new frame shapes through the stdio proxy.
---
*Automated evaluation by github-manager*
--
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: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] [studio] Design: let the rmqctl stdio MCP proxy forward server-initiated requests and client responses [rocketmq-dashboard]
Posted by "Frun1na (via GitHub)" <gi...@apache.org>.
Frun1na commented on issue #4758:
URL: https://github.com/apache/rocketmq-dashboard/issues/4758#issuecomment-5760934832
PR #4637 (opened from #4638 before this write-up) already implements this full loop, so the design discussion has a working reference — it is green on `go test ./... -race`, vet, gofmt and catalog-verify, and would love a review.
How it maps to the three points:
1. **Classify stdin frames before forwarding** — `decodeMCPMessage` (`rmqctl/internal/studio/mcp_message.go`) does exactly the three-way split: `method`+`id` → request, `method` without `id` → notification, `id` + `result`/`error` without `method` → response. The response case no longer fails with `missing method`.
2. **Response path back to the server** — #4637 takes a slightly different route than a dedicated `SendResponse` POST: when a server-initiated request is forwarded to the stdio client, the session registers it in `pendingRequests` by request id (`deliverResponse`, `mcp_message.go:331`), and the stdio client's answer is routed into that pending entry as a `JSONRPCResponse`. The mcp-go transport then carries it on the HTTP call it already owns for the in-flight server request, so its reconnect/error handling is reused instead of duplicated. A standalone `SendResponse` would work too; the pending-entry form just avoids a second write path racing the original call.
3. **Server-request handler → stdout** — `transport.SetRequestHandler(session.forwardRequest)` (`mcp_http.go:120`) writes the frame to stdout so the stdio client can answer it.
Ordering and the existing concurrency limits are preserved, as in the proposal. If you would rather see the explicit `SendResponse` shape (or spot anything the pending-entry approach handles worse — e.g. a server request that outlives the stdio client), say so and I will adjust #4637 accordingly.
--
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: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org