forgejo-mcp/docs/plans/streamable-http-transport.md
Christoph Görn e7283d8d4e feat: ✨ add streamable HTTP transport support (#99)
Add --transport http using MCP spec 2025-03-26 streamable HTTP,
the recommended transport for remote servers and Claude.ai connectors.
Includes --http-port flag, showboat demo, and openspec plan.
2026-03-28 00:07:10 +01:00

95 lines
3.3 KiB
Markdown

# Streamable HTTP Transport Support
**Issue**: [#99](https://codeberg.org/goern/forgejo-mcp/issues/99)
**Branch**: `feature/streamable-http-transport`
## Summary
Add `--transport http` to support the MCP spec `2025-03-26` streamable HTTP transport. This is needed for Claude.ai's custom MCP connector and replaces SSE as the recommended transport.
## Current State
- Two transports: `stdio` and `sse`
- Transport selected via `--transport` / `-t` flag (default: `stdio`)
- SSE uses `--sse-port` (default: `8080`) and `server.NewSSEServer`
- `mcp-go v0.44.0` already ships `server.NewStreamableHTTPServer` with the same `Start(addr)` API pattern
## Implementation
The change is straightforward since mcp-go already provides the server-side support.
### 1. `cmd/cmd.go` — Add `--http-port` flag, update help text
```go
var (
transport string
// ...
ssePort int
httpPort int // NEW
)
```
Register the flag:
```go
fs.IntVar(
&httpPort,
"http-port",
8080,
"Port for streamable HTTP transport mode",
)
```
Update transport help text from `"stdio or sse"` to `"stdio, sse, or http"`.
Pass `httpPort` to `flagPkg.HTTPPort`.
### 2. `pkg/flag/flag.go` — Add `HTTPPort` variable
```go
var HTTPPort int
```
### 3. `operation/operation.go` — Add `http` case to transport switch
```go
case "http":
httpServer := server.NewStreamableHTTPServer(mcpServer)
log.Info("Starting MCP streamable HTTP server",
log.IntField("port", flag.HTTPPort),
)
if err := httpServer.Start(fmt.Sprintf(":%d", flag.HTTPPort)); err != nil {
log.Error("Failed to start streamable HTTP server",
log.IntField("port", flag.HTTPPort),
log.ErrorField(err),
)
return fmt.Errorf("failed to start streamable HTTP server: %w", err)
}
log.Info("MCP streamable HTTP server shutdown")
```
Update the default error case from `"stdio, sse"` to `"stdio, sse, http"`.
### 4. Update `README.md`
Document the new `--transport http` option and `--http-port` flag.
## Design Decisions
- **Flag name `http` not `streamable-http`**: Short, consistent with `stdio`/`sse`. The MCP spec name is verbose for a CLI flag.
- **Separate `--http-port` from `--sse-port`**: Avoids confusion if users switch transports — each transport has its own port flag. Could share a `--port` flag instead, but keeping them separate is clearer and backward-compatible.
- **No SSE deprecation yet**: SSE still works. A future PR can add a deprecation warning once streamable HTTP is proven stable.
- **No TLS/auth options in this PR**: `mcp-go` supports `WithTLSCert` and other options, but those are separate concerns. Ship the basic transport first, add TLS in a follow-up if needed.
## Open Questions
1. **Should `--sse-port` and `--http-port` share a single `--port` flag?** Simpler, but a breaking change for SSE users relying on `--sse-port`.
2. **Should SSE emit a deprecation warning?** The MCP spec has SSE on a deprecation path, but it's still widely used.
## Test Plan
- [ ] `forgejo-mcp --transport http --http-port 9090 --url ... --token ...` starts and accepts connections
- [ ] MCP client can discover tools via streamable HTTP
- [ ] Claude.ai custom connector can connect to the server
- [ ] `--transport stdio` and `--transport sse` still work as before
- [ ] `--transport invalid` still errors with updated valid options list