MCP with Docker: stdio, environment and bind mounts
Run MCP servers with Docker: keep stdio connected, pass environment variables and mount selected directories. Includes troubleshooting and a test plan.
A container can package an MCP server runtime and its dependencies. The client connection, credentials and paths still have to match. Start with one read operation whose expected result you already know. Record where the client runs and which Docker engine it reaches. That distinction prevents you from looking for a directory on your laptop when the container actually starts on another computer. Keep the first test small enough to repeat after each configuration change.
Decide the startup method and transport first
Docker packages the process; it is not the MCP transport. A container may connect through stdio or expose an HTTP service. Docker documents -i for keeping standard input open. The -t option creates a pseudo-terminal; use the startup form documented by the server for a protocol process. A detached container is not automatically attached to the client’s input and output streams.
Read the package identity and original repository for your chosen entry. Use the configuration builder as a starting point when the registry contains a container launch template. The transport comparison helps distinguish an executable command from an endpoint. GitHub also has a dedicated setup guide.
Pass variables through both process boundaries
The client starts Docker and Docker starts the server. A value in the client environment is therefore not automatically present in the container. -e NAME passes an existing value from the Docker invocation environment. Docker options go before the image name; arguments after it belong to the container command. Use the variable names documented by the server and check that values reach the intended process without printing the values themselves.
A common failure is a successful terminal test followed by a missing-variable error in the desktop client. Compare the two startup environments first. Do not simultaneously replace the token and server version: you would lose the ability to identify which change fixed the problem. Keep credentials out of public checking forms and logs. The configuration checker cannot inspect the environment inside your running container.
Distinguish host paths from container paths
A bind mount connects a path on the Docker daemon host to a destination inside the container. The server uses that destination path. Bind mounts are writable by default; a file-reading test can use the documented readonly option. With a remote Docker engine, the source path belongs to the engine host. A directory existing only on your client computer is not transferred by declaring a mount.
| Observation | Boundary | Check |
|---|---|---|
| Docker unavailable | Client to engine | Engine and selected context |
| Missing variable | Docker to container | Forwarding and startup environment |
| File not found | Host to container | Source, destination and server path |
| Connection closes immediately | Process to MCP client | Startup form, exit code and logs |
| HTTP unavailable | Container to network | Service binding and port mapping |
For a file test, create a dedicated directory and a text file with known contents. Check both a successful read inside the allowed directory and an expected refusal outside it. The Filesystem guide explains additional server-side directory boundaries. A mount and a server allowlist are different controls; record both so someone else can reproduce your setup.
Finish with a small acceptance test
Record the image version, startup arguments and engine. Choose a version deliberately; a mutable tag is not a permanent version identifier.
Inspect startup without mixing unrelated diagnostics into protocol output. Read exit status and error messages together.
Have the client initialize the connection and display the tool inventory. Select the prepared read operation.
Compare the returned value with your expectation. Repeat after changes to mounts, variables or image versions.
- Does stdio need a published port?
- The protocol uses process streams. Additional ports may be required by other documented server features.
- Is every container read-only?
- No. Check mounts, process permissions and offered operations separately.
- What does --rm do?
- Docker removes the container after it exits. This does not undo files already written to a mounted host directory.
- Does a running container prove MCP works?
- No. Initialization, tool discovery and the chosen operation also need to produce the expected results.
Official documentation checked on 1 October 2026. The test plans are editorial suggestions.
- Docker: running containers
Show retrieval command
curl -s https://docs.docker.com/engine/containers/run/ - Docker: bind mounts
Show retrieval command
curl -s https://docs.docker.com/engine/storage/bind-mounts/ - Docker: container run reference
Show retrieval command
curl -s https://docs.docker.com/reference/cli/docker/container/run/