Skip to main content

AI

Build MCP Server with SSE Transport in .NET

August 4, 2025 · 18 min read

Hero image for Build MCP Server with SSE Transport in .NET

Server-Sent Events (SSE) is a standard HTTP transport for MCP servers—unidirectional streams from server to client. This guide builds an MCP server with legacy SSE in .NET and connects it to Claude Desktop.

Note: Legacy SSE (protocol 2024-11-05) is maintained for compatibility. New remote deployments should prefer Streamable HTTP—see Build MCP Server with Streamable HTTP and the MCP protocol overview. This article focuses on legacy SSE because some clients and bridges (including mcp-remote) still target /sse.

Key Takeaways

  • SSE MCP uses POST plus an EventSource stream—dual endpoints to maintain.
  • Treat SSE MCP as legacy; choose Streamable HTTP for new remote servers.
  • Disable buffering and configure proxy timeouts so SSE streams stay alive.
  • Test SSE through production reverse proxies—not only localhost.
  • Docker deployment works—watch health checks that drop long-lived connections.

Prerequisites

Understanding Server-Sent Events (SSE)

Server-Sent Events (SSE) is a web standard that allows a server to push data to a client over a single HTTP connection. Unlike WebSockets, SSE provides unidirectional communication from server to client, making it well suited for streaming updates over HTTP.

For a full treatment of event framing, EventSource clients, C# and Node.js server examples, and production tuning, see Server-Sent Events (SSE) and EventSource.

Key benefits of SSE for MCP

  • Simplicity: Built on standard HTTP, no special protocols needed
  • Automatic reconnection: Clients can reconnect on connection loss
  • Event-driven: Fits MCP's message-based architecture
  • Firewall friendly: Works through most corporate firewalls
  • Low overhead: Minimal protocol overhead compared to WebSockets

How MCP uses SSE

Legacy MCP over HTTP splits traffic across two endpoints:

Endpoint Role
GET /sse Long-lived SSE stream (server → client)
POST /message JSON-RPC requests (client → server)

MCP JSON-RPC responses travel as standard SSE frames on Content-Type: text/event-stream:

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

For the full field reference (data, event, id, retry, comment heartbeats), see Server-Sent Events (SSE) and EventSource.

Complete example: Echo MCP server

Create the project

dotnet new web -n SseMcpServer
cd SseMcpServer
dotnet package add ModelContextProtocol.AspNetCore

Pin the port so Claude config stays predictable. In Properties/launchSettings.json:

"applicationUrl": "http://localhost:5130"

Define tools

Create Tools/EchoTools.cs:

using System.ComponentModel;
using ModelContextProtocol.Server;

[McpServerToolType]
public sealed class EchoTools
{
    [McpServerTool, Description("Echoes the input back to the client.")]
    public static string Echo(string message) => message;
}

Configure Program.cs

Legacy SSE is disabled by default in the MCP C# SDK. Enable it explicitly:

var builder = WebApplication.CreateBuilder(args);
builder.Services
    .AddMcpServer()
    .WithHttpTransport(options =>
    {
        options.Stateless = false;
        options.EnableLegacySse = true;
    })
    .WithTools<Tools>();

var app = builder.Build();

app.MapMcp();
app.Run();

Run and smoke test

Start the server:

dotnet run

Test with Claude Desktop

Claude Desktop connects to legacy SSE MCP servers through mcp-remote: a stdio bridge that forwards to your HTTP URL (GET /sse and POST /message).

Prerequisites

  • Claude Desktop installed
  • Node.js 18+ (for npx mcp-remote)
  • The .NET MCP server running locally on port 5130

Configure Claude Desktop

Edit claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "sse-echo": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:5130/sse"
      ]
    }
  }
}

Step-by-step

  1. Start the server: dotnet run (leave the terminal open)
  2. Add the config above to claude_desktop_config.json
  3. Fully quit Claude Desktop and relaunch (config is read at startup)
  4. Open Claude and check the MCP/tools indicator (hammer icon)—sse-echo should show as connected
  5. Send a test prompt, for example: "Use the echo tool to repeat the phrase hello mcp"
  6. Confirm Claude calls Echo and returns the echoed text

Verify and troubleshoot

  • Claude logs: Help → View Logs (or Developer settings)—look for connection errors
  • Server terminal: should log incoming HTTP requests when Claude connects
  • Wrong port: align launchSettings.json with the URL in claude_desktop_config.json
  • Server not running: start the server before restarting Claude
  • Stale config: quit Claude completely (not just close the window), then relaunch
  • Firewall: ensure localhost traffic on port 5130 is allowed
  • SSE disconnects behind a proxy: disable response buffering and send periodic comment heartbeats—see Server-Sent Events (SSE) and EventSource

For local development without HTTP, stdio transport is simpler—see Building MCP Server Using .NET.

Conclusion

An MCP server over legacy SSE fits existing clients and bridges that target /sse. The .NET MCP SDK handles concurrent connections well; for new remote deployments, use Build MCP Server with Streamable HTTP when your clients support it.

Next steps

  • Implement custom tools for your use case
  • Add authentication and authorization
  • Set up monitoring and logging
  • Deploy to your preferred cloud platform

FAQ

How do I build an MCP server with SSE transport in .NET?

Configure the MCP .NET SDK for SSE transport: an HTTP endpoint accepts POSTed JSON-RPC messages and a separate GET stream delivers server events back to the client. ASP.NET Core can implement both routes with correct cache and connection headers. Prefer Streamable HTTP for new builds unless you must support legacy SSE clients.

Why is MCP SSE considered legacy?

The MCP specification moved toward Streamable HTTP as the standard remote transport, simplifying proxies, auth, and connection management. SSE MCP required dual endpoints and behaved poorly behind some load balancers. Maintain SSE only for existing integrations; greenfield work should use Streamable HTTP.

What ASP.NET Core settings matter for SSE MCP endpoints?

Disable response buffering for the event stream, set Cache-Control: no-cache, and keep connections alive through reverse proxies with appropriate timeout configuration. Proxies that buffer entire responses break real-time delivery. Test through the same nginx or Cloudflare path production uses.

Should I deploy SSE MCP in Docker?

Docker works for SSE MCP the same as any ASP.NET Core app—ensure health checks do not kill long-lived SSE connections and configure proxy timeouts externally. For new deployments, containerized Streamable HTTP is simpler to operate and monitor.

From AI licenses to measurable impact

Licenses are table stakes. Tell me where adoption stalls - we turn fragmented AI usage into measured gains and an operating model that scales.

Get Your AI Adoption Score

3 minutes · Instant result · No sales call required