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 ### 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. 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 ### Base Protocol
| Title | Description | | Title | Description |

View file

@ -3,6 +3,10 @@ items:
href: index.md href: index.md
- name: Getting Started - name: Getting Started
uid: getting-started uid: getting-started
- name: Deployment
items:
- name: Docker
uid: docker-deployment
- name: Base Protocol - name: Base Protocol
items: items:
- name: Capabilities - 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`). 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) ### 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. 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.