Augment conceptual docs with Docker-based MCP server deployment guidance (#1423)

Add a Docker deployment guide for ASP.NET Core MCP servers using Streamable HTTP (docs/concepts/deployment/docker.md), a Deployment/Docker entry in the conceptual nav (toc.yml, index.md), and cross-links from the transports and getting-started guides.
This commit is contained in:
John McKillip 2026-07-20 06:50:08 -05:00 • committed by GitHub
commit 71d7eead40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 125 additions and 1 deletions

View file

@ -0,0 +1,112 @@
---
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 deployment for MCP servers
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()`.
<!-- mlc-disable-next-line -->
> [!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.
### Baseline server
A minimal HTTP-based MCP server looks like this:
```csharp
using ModelContextProtocol.Server;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMcpServer()
.WithHttpTransport()
.WithToolsFromAssembly();
var app = builder.Build();
app.MapMcp("/mcp");
app.Run();
```
### Dockerfile
Use a multi-stage Docker build so SDK tooling stays in the build stage and only runtime dependencies are shipped in the final image.
```dockerfile
# 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 and run
Build the image:
```bash
docker build -t my-mcp-server:latest .
```
Run the container and map host port `3001` to container port `8080`:
```bash
docker run --rm -p 3001:8080 my-mcp-server:latest
```
With the baseline route above (`app.MapMcp("/mcp")`), clients connect to the Streamable HTTP endpoint at `http://localhost:3001/mcp`.
Streamable HTTP is the recommended transport for containerized MCP servers. The legacy SSE endpoints (`/mcp/sse` and `/mcp/message`) are not mapped by default, and the option to enable them is obsolete. See [Transports](../transports/transports.md) for details.
### Configuration and secrets
Pass configuration through environment variables rather than baking secrets into the image:
```bash
docker run --rm -p 3001:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e MYAPP__APIKEY=example \
my-mcp-server:latest
```
ASP.NET Core binds `MYAPP__APIKEY` to `MYAPP:APIKEY` in configuration.
<!-- mlc-disable-next-line -->
> [!IMPORTANT]
> Do not commit real tokens or credentials into Dockerfiles, compose files, or source code. Use runtime environment variables or an external secret store.
### Health and readiness
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.
### Reverse proxies and forwarded headers
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:
- [Transports](../transports/transports.md)
- [Getting Started](../getting-started.md)
- [HTTP Context](../httpcontext/httpcontext.md)

View file

@ -172,4 +172,4 @@ var response = await chatClient.GetResponseAsync(
### Next steps
Explore the rest of the conceptual documentation to learn about [tools](tools/tools.md), [prompts](prompts/prompts.md), [resources](resources/resources.md), [transports](transports/transports.md), and more. You can also browse the [samples](https://github.com/modelcontextprotocol/csharp-sdk/tree/main/samples) directory for complete end-to-end examples.
Explore the rest of the conceptual documentation to learn about [tools](tools/tools.md), [prompts](prompts/prompts.md), [resources](resources/resources.md), [transports](transports/transports.md), and [Docker deployment](deployment/docker.md) for HTTP-based servers. You can also browse the [samples](https://github.com/modelcontextprotocol/csharp-sdk/tree/main/samples) directory for complete end-to-end examples.

View file

@ -8,6 +8,12 @@ Welcome to the conceptual documentation for the Model Context Protocol SDK. Here
Install the SDK and build your first MCP client and server.
### Deployment
| Title | Description |
| - | - |
| [Docker deployment](deployment/docker.md) | Learn how to package and run ASP.NET Core MCP servers in Docker containers using Streamable HTTP transport. |
### Base Protocol
| Title | Description |

View file

@ -3,6 +3,10 @@ items:
href: index.md
- name: Getting Started
uid: getting-started
- name: Deployment
items:
- name: Docker
uid: docker-deployment
- name: Base Protocol
items:
- name: Capabilities

View file

@ -261,6 +261,8 @@ app.MapMcp("/mcp");
When using a custom route, Streamable HTTP clients should connect directly to that route (e.g., `https://host/mcp`), while SSE clients (when [legacy SSE is enabled](xref:stateless#legacy-sse-transport)) should connect to `{route}/sse` (e.g., `https://host/mcp/sse`).
For containerized deployments of ASP.NET Core servers, see [Docker deployment](../deployment/docker.md).
### SSE transport (legacy)
The [SSE (Server-Sent Events)] transport is a legacy mechanism that uses unidirectional server-to-client streaming with a separate HTTP endpoint for client-to-server messages. New implementations should prefer Streamable HTTP.