# Streamable HTTP Transport Implementation in the GitHub MCP Server

> Explore the streamable HTTP transport in GitHub MCP Server for real-time JSON-RPC API over SSE. Get incremental tool responses without stdio pipes.

- Repository: [GitHub/github-mcp-server](https://github.com/github/github-mcp-server)
- Tags: internals
- Published: 2026-02-16

---

**The streamable HTTP transport exposes the GitHub MCP Server's JSON-RPC API over HTTP using Server-Sent Events (SSE), enabling real-time, incremental tool responses without requiring a persistent stdio pipe.**

The `github/github-mcp-server` repository implements a **streamable HTTP transport** that allows the Model Context Protocol (MCP) to operate over standard HTTP connections. This transport mechanism bridges the gap between traditional stdio-based MCP communication and modern web-based architectures, delivering tool outputs incrementally via the `text/event-stream` MIME type.

## What Is the Streamable HTTP Transport?

The **streamable HTTP transport** is an SDK-provided mechanism that wraps a `*mcp.Server` instance with an HTTP handler capable of streaming JSON-RPC messages. Unlike the standard stdio transport that requires a long-running process with piped input/output, this transport allows the GitHub MCP Server to function as a stateless HTTP service while preserving the real-time streaming behavior that MCP clients expect.

The implementation relies on **Server-Sent Events (SSE)**, a standardized HTTP protocol where the server pushes data to the client over a persistent connection using the `text/event-stream` content type.

## Core Implementation Components

### The Streamable HTTP Handler

At the heart of the implementation is the `mcp.NewStreamableHTTPHandler` function from the MCP Go SDK. This factory function creates an `http.Handler` that serializes MCP JSON-RPC messages into an SSE stream.

In [`pkg/http/handler.go`](https://github.com/github/github-mcp-server/blob/main/pkg/http/handler.go), the server initialization code instantiates this handler:

```go
// pkg/http/handler.go – lines 223-230
mcpHandler := mcp.NewStreamableHTTPHandler(
    func(_ *http.Request) *mcp.Server { return ghServer },
    &mcp.StreamableHTTPOptions{
        Stateless: true,               // each request gets a fresh Server instance
    })
mcpHandler.ServeHTTP(w, r)

```

The anonymous function passed as the first argument acts as a server factory, returning the fully initialized `*mcp.Server` instance (`ghServer`) constructed from the GitHub tool inventory.

### Server Configuration and Statelessness

The **`Stateless: true`** configuration option is critical for HTTP operation. When enabled, the transport creates a fresh MCP server instance for each incoming HTTP request. This design aligns with the stateless nature of HTTP while ensuring that each request gets a clean execution context.

The `ghServer` instance is built by `github.NewMCPServer` in [`internal/ghmcp/server.go`](https://github.com/github/github-mcp-server/blob/main/internal/ghmcp/server.go), which configures the appropriate tool inventory, token scopes, and feature flags before the HTTP handler wraps it.

### Server-Sent Events Protocol

The transport uses the **`text/event-stream`** MIME type to deliver messages. This constant is defined in [`pkg/http/headers/headers.go`](https://github.com/github/github-mcp-server/blob/main/pkg/http/headers/headers.go):

```go
// pkg/http/headers/headers.go
ContentTypeEventStream = "text/event-stream"

```

When a client connects, the server responds with HTTP headers indicating an event stream:

```http
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

```

Subsequent JSON-RPC messages are formatted as SSE data frames:

```

data: {"jsonrpc":"2.0","id":1,"result":{...}}
data: {"jsonrpc":"2.0","method":"toolOutput","params":{...}}

```

## Code Walkthrough

### Handler Instantiation

The entry point for HTTP mode is defined in [`cmd/github-mcp-server/main.go`](https://github.com/github/github-mcp-server/blob/main/cmd/github-mcp-server/main.go), where the `http` subcommand starts the server. This delegates to the handler in [`pkg/http/handler.go`](https://github.com/github/github-mcp-server/blob/main/pkg/http/handler.go), which bridges the MCP server to the streamable transport.

### Server Construction

The actual MCP server instance is constructed in [`internal/ghmcp/server.go`](https://github.com/github/github-mcp-server/blob/main/internal/ghmcp/server.go) via `github.NewMCPServer`. This function assembles the tool inventory and configures authentication scopes before returning the `*mcp.Server` that the HTTP handler wraps.

## Practical Usage Example

Clients configure the streamable HTTP transport by specifying the server URL and authentication headers:

```json
{
  "type": "http",
  "url": "http://localhost:8082",
  "headers": {
    "Authorization": "Bearer ghp_...",
    "X-MCP-Toolsets": "default",
    "X-MCP-Readonly": "true"
  }
}

```

When the client sends an MCP request, the server establishes the SSE connection and streams incremental tool outputs as they are produced, maintaining the real-time interaction model that MCP requires while operating over standard HTTP infrastructure.

## Summary

- The **streamable HTTP transport** exposes the GitHub MCP Server over HTTP using Server-Sent Events (SSE) to deliver real-time JSON-RPC messages.
- The implementation uses `mcp.NewStreamableHTTPHandler` from the MCP Go SDK, configured with `Stateless: true` to create a fresh server instance per request.
- The transport relies on the `text/event-stream` content type defined in [`pkg/http/headers/headers.go`](https://github.com/github/github-mcp-server/blob/main/pkg/http/headers/headers.go) to stream incremental tool responses.
- Key source files include [`pkg/http/handler.go`](https://github.com/github/github-mcp-server/blob/main/pkg/http/handler.go) for handler instantiation, [`internal/ghmcp/server.go`](https://github.com/github/github-mcp-server/blob/main/internal/ghmcp/server.go) for server construction, and [`cmd/github-mcp-server/main.go`](https://github.com/github/github-mcp-server/blob/main/cmd/github-mcp-server/main.go) for the HTTP mode entry point.

## Frequently Asked Questions

### How does the streamable HTTP transport differ from the stdio transport?

The **stdio transport** requires a long-running process with piped standard input and output, making it suitable for local integrations. The **streamable HTTP transport** operates over standard HTTP connections using Server-Sent Events, allowing the GitHub MCP Server to function as a stateless web service while still delivering real-time, incremental tool responses.

### What is the purpose of the `Stateless: true` configuration option?

Setting `Stateless: true` in `mcp.StreamableHTTPOptions` instructs the handler to instantiate a fresh `*mcp.Server` for each incoming HTTP request. This design aligns with HTTP's stateless nature and ensures that each client request receives a clean execution context without interference from previous requests.

### Which content type does the streamable HTTP transport use for streaming responses?

The transport uses **`text/event-stream`**, the standard MIME type for Server-Sent Events (SSE). This content type is defined as `ContentTypeEventStream` in [`pkg/http/headers/headers.go`](https://github.com/github/github-mcp-server/blob/main/pkg/http/headers/headers.go) and enables the server to push JSON-RPC messages to clients incrementally over a persistent HTTP connection.