| title | Docker Deployment |
|---|---|
| author | john-mckillip |
| description | How to run ASP.NET Core MCP servers in Docker containers using Streamable HTTP transport. |
| uid | docker-deployment |
Docker is a practical way to package and run MCP servers consistently across development, CI, and production environments. For HTTP-based MCP servers, use ASP.NET Core hosting with Streamable HTTP.
This guide assumes you already have an ASP.NET Core MCP server configured with ModelContextProtocol.AspNetCore, WithHttpTransport(), and MapMcp().
Tip
For local, process-based integrations where the client launches the server directly, stdio is often simpler. For remote and containerized deployments, Streamable HTTP is the recommended transport.
A minimal HTTP-based MCP server looks like this:
using ModelContextProtocol.Server;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMcpServer()
.WithHttpTransport()
.WithToolsFromAssembly();
var app = builder.Build();
app.MapMcp("/mcp");
app.Run();Use a multi-stage Docker build so SDK tooling stays in the build stage and only runtime dependencies are shipped in the final image.
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
# MCP HTTP endpoint listens on 8080 inside container
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyMcpServer.dll"]Replace MyMcpServer.dll with your server assembly output name.
Build the image:
docker build -t my-mcp-server:latest .Run the container and map host port 3001 to container port 8080:
docker run --rm -p 3001:8080 my-mcp-server:latestWith the baseline route above (app.MapMcp("/mcp")), clients connect to:
- Streamable HTTP:
http://localhost:3001/mcp - Legacy SSE endpoint (if needed):
http://localhost:3001/mcp/sse
Pass configuration through environment variables rather than baking secrets into the image:
docker run --rm -p 3001:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e MYAPP__APIKEY=example \
my-mcp-server:latestASP.NET Core binds MYAPP__APIKEY to MYAPP:APIKEY in configuration.
Important
Do not commit real tokens or credentials into Dockerfiles, compose files, or source code. Use runtime environment variables or an external secret store.
For container orchestrators, add an HTTP health endpoint and use it for readiness/liveness checks. Keep MCP traffic on your mapped MCP route and health probes on a separate route.
If your container is behind a reverse proxy (for example, ingress or load balancers), ensure forwarded headers are handled correctly so auth and origin metadata flow to the MCP server as expected.
See also: