feat: migrate HTTP transport to stateless mode, upgrade go-sdk to v1.7.0 - #162
feat: migrate HTTP transport to stateless mode, upgrade go-sdk to v1.7.0#162iavael wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates the MCP HTTP transport from stateful (session/SSE-oriented) behavior to stateless JSON request/response mode, enabled via the go-sdk v1.7.0 StreamableHTTPOptions.Stateless support.
Changes:
- Upgrade
github.com/modelcontextprotocol/go-sdkfrom v1.6.1 to v1.7.0. - Switch the HTTP handler to stateless + JSON responses, and remove the now-inapplicable
--mcp.session-timeoutflag. - Re-enable HTTP server
WriteTimeout(previously disabled for SSE-style streaming).
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| README.md | Updates the Docker example wording to reflect stateless JSON HTTP transport. |
| pkg/mcp/server.go | Configures the go-sdk streamable HTTP handler for stateless application/json request/response behavior. |
| cmd/prometheus-mcp/main.go | Removes session-timeout flag usage, updates handler wiring, and adjusts HTTP server timeout behavior. |
| go.mod | Bumps go-sdk dependency to v1.7.0. |
| go.sum | Updates checksums for the go-sdk version bump. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
cmd/prometheus-mcp/main.go:357
- PR description says the HTTP server WriteTimeout is being "restored to 30s", but the code now sets it to
prometheus.timeout + 5s(default 1m5s). Please align the implementation with the stated behavior (set WriteTimeout back to 30s) or update the PR description to reflect the new timeout semantics.
// request/response cycles. Stateless HTTP transport uses
// application/json responses that complete in a single round
// trip, so standard timeouts apply.
ReadTimeout: 30 * time.Second,
WriteTimeout: *flagPrometheusTimeout + (5 * time.Second),
d86cfd8 to
291d0e1
Compare
Signed-off-by: Iavael <905853+iavael@users.noreply.github.com>
291d0e1 to
9a5640c
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
cmd/prometheus-mcp/main.go:357
initHTTPServersetsWriteTimeoutto*flagPrometheusTimeout(the Prometheus backend client timeout, default 1m), but the PR description says the HTTP server write timeout is being restored to 30s for stateless JSON request/response. Reusing the Prometheus backend timeout here also couples unrelated concerns and makes the actual HTTP server behavior surprising.
WriteTimeout: *flagPrometheusTimeout,
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
cmd/prometheus-mcp/main.go:138
- The
--mcp.keepalive-intervalhelp text still talks about “connected MCP sessions” and “idle connections from dropping”, which is confusing now that HTTP is stateless and stdio isn’t a network connection. Reword this flag description to describe keepalives in terms of the client/transport and dead-peer detection.
flagMcpKeepaliveInterval = kingpin.Flag(
"mcp.keepalive-interval",
"Interval for sending keepalive pings to connected MCP sessions."+
" If the peer fails to respond, the session is closed."+
" Most useful for stdio transport to prevent idle connections from dropping.",
).Default("30s").Duration()
pkg/mcp/server.go:246
NewStreamableHTTPHandlernow depends on go-sdk stateless behavior (Stateless: true+JSONResponse: true), but there’s no test asserting the HTTP handler actually responds with JSON (vs SSE framing) and stays compatible across go-sdk upgrades. Adding a focused httptest-based unit test for the/mcphandler (e.g., responseContent-Type: application/jsonand no session semantics) would help prevent regressions.
handler := mcp.NewStreamableHTTPHandler(
func(r *http.Request) *mcp.Server {
return server
},
&mcp.StreamableHTTPOptions{
Stateless: true,
JSONResponse: true,
Logger: logger,
},
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
pkg/mcp/server.go:207
KeepAlivesupport appears to be removed entirely (the SDKServerOptionsno longer setsKeepAlive). While this makes sense for stateless HTTP, it also disables keepalive pings for thestdiotransport, which is still long-lived/streaming. If the intent was to drop keepalive only for HTTP, consider keepingKeepAliveconfigurable (and applying it at least forstdio), or update the docs/PR description to explicitly call out that keepalive was removed for all transports.
&mcp.ServerOptions{
Instructions: instrx,
Logger: logger.WithGroup("go_sdk_logger"),
Capabilities: caps,
},
|
@copilot is keepalive really necessary for stdio transport? |
|
@tjhop can you, please, give your review? |
Switches the HTTP MCP transport from stateful (SSE, session-tracked) to stateless mode: each request is an independent JSON round-trip with no session ID validation or server-initiated messages.
Changes
go-sdkv1.6.1 → v1.7.0 —Statelessfield onStreamableHTTPOptionswas introduced in v1.7.0NewStreamableHTTPHandler— setsStateless: trueandJSONResponse: true; drops thesessionTimeoutandKeepAliveparameters (inapplicable in stateless mode)--mcp.session-timeoutflag removed — sessions no longer exist; flag would be a no-opWriteTimeoutmatches prometheus timeout — previously forced to0to accommodate never-finishing SSE streams; stateless JSON responses complete within a single round trip--mcp.keepalive-intervalflag removed — network connection is no longer streamable, flag would be a no-op