Skip to content

Commit 292ebb6

Browse files
authored
feat(server): add transport-agnostic Handle entry point (#851)
* feat(server): add transport-agnostic Handle entry point Introduces a small abstraction layer over net/http so StreamableHTTPServer can be driven from frameworks like fasthttp/fiber without going through the buffering net/http<->fasthttp adaptor. Two new exported types: - HTTPRequest: framework-neutral view of an MCP HTTP request (Method, URL, Header, Body, Context). - HTTPResponseWriter: minimum surface needed to write a streamable MCP HTTP response, including a CanStream() capability check that lets non-streaming transports gracefully skip SSE upgrades. New entry point: func (s *StreamableHTTPServer) Handle(w HTTPResponseWriter, r *HTTPRequest) ServeHTTP is refactored into a thin wrapper around Handle that builds a default httpResponseWriterAdapter (which satisfies HTTPResponseWriter and forwards Flush to http.Flusher when present) and an HTTPRequest preserving the original *http.Request for legacy options like WithHTTPContextFunc and SessionIdManagerResolver. Backwards-compatibility: - All existing public APIs (NewStreamableHTTPServer, ServeHTTP, Start, Shutdown, every option, every session interface) are unchanged. - WithHTTPContextFunc is honored from both ServeHTTP and Handle. Under Handle it receives a synthetic *http.Request derived from the HTTPRequest so existing options keep working. - SessionIdManagerResolver still takes *http.Request; Handle constructs a synthetic request only when a custom resolver is configured. - When the configured response writer cannot stream (CanStream==false), GET is rejected with 405 Method Not Allowed (same as today for non-flushable writers) and POST stays in buffered application/json mode, matching the new explicit contract. Closes the integration gap reported in #611 while leaving the existing adaptor.HTTPHandler workaround fully functional. * docs(server): document Handle entry point for non-net/http frameworks - README: add subsection under Transports introducing Handle, HTTPRequest, and HTTPResponseWriter with a link to the full HTTP transport guide. - www/docs/pages/transports/http.mdx: add an Embedding in Non-net/http Frameworks section with a ServeHTTP-vs-Handle comparison table, the full API surface, the CanStream() streaming-capability contract, a concrete fasthttp adapter snippet, and behavior notes covering CORS, protected-resource-metadata, WithHTTPContextFunc, and BC guarantees.
1 parent 0678053 commit 292ebb6

5 files changed

Lines changed: 804 additions & 64 deletions

File tree

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,30 @@ Key examples include:
657657

658658
MCP-Go supports stdio, SSE and streamable-HTTP transport layers. For SSE transport, you can use `SetConnectionLostHandler()` to detect and handle disconnections for implementing reconnection logic.
659659

660+
### Embedding StreamableHTTP in non-net/http frameworks
661+
662+
`StreamableHTTPServer` is an `http.Handler`, so it can be mounted in any
663+
router that speaks `net/http`. To embed it in a framework that does **not**
664+
go through `net/http` (e.g. [fasthttp](https://github.com/valyala/fasthttp)
665+
or [fiber](https://gofiber.io/)) without buffering the response through an
666+
adaptor, use the transport-agnostic `Handle` entry point:
667+
668+
```go
669+
func (s *StreamableHTTPServer) Handle(w HTTPResponseWriter, r *HTTPRequest)
670+
```
671+
672+
`HTTPRequest` is a plain struct (`Method`, `URL`, `Header`, `Body`,
673+
`Context`) and `HTTPResponseWriter` is a small interface (`Header`,
674+
`WriteHeader`, `Write`, `Flush`, `CanStream`). Implementations whose
675+
underlying transport cannot stream MUST return `false` from `CanStream`;
676+
the server will then reject GET (SSE listening) with `405 Method Not
677+
Allowed` and keep POST responses as buffered `application/json` instead of
678+
upgrading to `text/event-stream`.
679+
680+
See the [HTTP transport docs](https://mcp-go.dev/transports/http#embedding-in-non-nethttp-frameworks)
681+
for a full fasthttp/fiber adapter example. `ServeHTTP` is unchanged and
682+
remains the conventional `net/http` entry point.
683+
660684
### OAuth Protected Resource Metadata
661685

662686
Servers that require OAuth can advertise their authorization requirements

0 commit comments

Comments
 (0)