← All articles

Build MCP Server with SSE Transport in .NET

August 4, 2025 · 18 min read

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.

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

Related reading

Related articles