Menu

AI

MCP Server in Docker Not Connecting: How to Fix It (Claude, Cursor, VS Code)

Fix an MCP server that runs in Docker but never connects. Covers the -i flag, detached mode, env vars, Docker MCP Toolkit gateway timeouts and where to read logs.

By: Irina ShvayaNovember 2, 2026

MCP Server in Docker Not Connecting: How to Fix It (Claude, Cursor, VS Code)

This fix is part of MCP troubleshooting, within The MCP Guide. Still stuck? Request a free MCP readiness review.

An MCP server in Docker usually fails to connect because the container cannot talk over stdin and stdout. The client launches docker run as a stdio process, so the container must keep standard input open (-i) and must run in the foreground. The fastest fix is to make your args read run -i --rm ... <image>, remove any -d flag, then restart the client and read its MCP log.

Checked against: VS Code's MCP troubleshooting table, the docker run reference, Docker's MCP Toolkit get-started guide and GitHub's MCP server README on 2 November 2026. eSEOspace did not run these steps; follow the vendor page if it differs.

Key Takeaways

  • A Dockerized stdio server needs -i so the container keeps stdin open for the client's messages.
  • Never use detached mode (-d). VS Code's docs say the client needs the stdio connection, so the container must stay in the foreground.
  • -e NAME with no value copies NAME from the docker process environment, which is the env block of your MCP config.
  • Docker Desktop must be running before the client starts, or the docker command has nothing to talk to.
  • Docker says its MCP Toolkit gateway takes about 15 to 25 seconds to start, so short client timeouts can kill it.

What this error means

Most local MCP servers use the stdio transport. The client starts a process and exchanges newline-delimited JSON-RPC messages over that process's stdin and stdout. When the process is docker, Docker sits in the middle and has to pass those streams through to the container.

Three things break that chain. The container may close stdin at once because -i is missing. It may detach and return control to the client, which then sees the process exit. Or it may start, but crash because a required variable never reached it.

The symptom looks different per client. Claude Desktop shows the server as failed. VS Code reports that the server exited. Claude Code lists it as failed in /mcp. The cause is usually the same.

Quick fix

  1. Start Docker Desktop (or the Docker daemon on Linux) and wait until it reports it is running.
  2. Run the image by hand in a terminal: docker run -i --rm <image>. If Docker cannot pull or start it, fix that first.
  3. Open your MCP config and check the args array. It should start with "run", "-i", "--rm".
  4. Delete -d or --detach if present. Also remove -t, since the docker run reference describes -t as allocating a pseudo-TTY, which a JSON stream does not need.
  5. Pass each secret as "-e", "NAME" in args and put the value in the config's env block.
  6. Fully quit and reopen the client, then read the MCP log for that server.

GitHub's official README uses this exact shape for its Docker image:

"github": {
  "command": "docker",
  "args": [
    "run", "-i", "--rm",
    "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
    "ghcr.io/github/github-mcp-server"
  ],
  "env": {
    "GITHUB_PERSONAL_ACCESS_TOKEN": "your-token"
  }
}

The -e GITHUB_PERSONAL_ACCESS_TOKEN line has no value on purpose. The docker run reference shows that --env VAR1 with no value uses the variable already exported in the calling environment. The client sets it from env, and Docker copies it in. If you write the token inside args instead, it can end up in logs and process lists. Our secret leakage guide explains why that matters.

Fix by client / OS

Claude Desktop

Edit claude_desktop_config.json under mcpServers. The file lives at ~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows and ~/.config/Claude/ on Linux, per the MCP local server guide. Quit Claude Desktop fully after each change. If you use Docker's MCP Toolkit, its guide says to select Connect next to Claude Desktop on the Clients tab, then restart Claude Desktop.

Cursor

Put the same block in .cursor/mcp.json (project) or ~/.cursor/mcp.json (global). Cursor's MCP docs list "docker" as a valid command, as long as it is on your system path or written as a full path.

Claude Code

Use the -- separator so Claude Code does not read Docker's flags as its own:

claude mcp add github --env GITHUB_PERSONAL_ACCESS_TOKEN=your-token -- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server

Claude Code's MCP docs say everything after -- is passed to the server command untouched, and --env goes after the server name and before --. Check the result with claude mcp list.

VS Code

In .vscode/mcp.json servers sit under servers, not mcpServers. The VS Code configuration reference warns: "When using Docker with stdio servers, don't use the detach option (-d)." In a remote or dev container window, the command runs in the remote environment, so Docker must be reachable there too.

Docker MCP Toolkit gateway

If you connect through the Toolkit, the client runs docker mcp gateway run --profile <profile>. Docker's get-started guide says the gateway "takes approximately 15-25 seconds to start," and recommends a 60-second startup timeout in one client whose default is 10 seconds. In Claude Code, the docs say you can raise the startup timeout with MCP_TIMEOUT, for example MCP_TIMEOUT=60000 claude. Docker's guide also shows a Windows client config that uses the full path C:/Program Files/Docker/Docker/resources/bin/docker.exe. Our Docker MCP Toolkit setup guide covers profiles in more depth.

Where to find the logs

  • Claude Desktop: mcp.log and mcp-server-SERVERNAME.log in ~/Library/Logs/Claude (macOS), %APPDATA%\Claude\logs (Windows) or ~/.config/Claude/logs (Linux).
  • Cursor: Output panel (Cmd+Shift+U or Ctrl+Shift+U), then MCP Logs.
  • VS Code: run MCP: List Servers, pick the server and choose Show Output.
  • Claude Code: /mcp in a session, or claude mcp list in a terminal.
  • Docker itself: docker ps -a shows containers that started and exited. With --rm they vanish, so remove --rm briefly while you debug.

If it still fails

  • Image pull errors. Run docker pull <image> by hand. A login or rate limit problem shows up there.
  • Wrong platform. An image built for one CPU architecture may not start on another. Docker prints a warning when you run it by hand.
  • Server logs to stdout. If the server inside the container prints banners to stdout, the client reads them as broken JSON. Log to stderr only.
  • Ports for OAuth. GitHub's README publishes a callback port with -p 127.0.0.1:8085:8085 for its local OAuth flow. Without the port, sign-in cannot finish.
  • It works by hand but not in the client. Compare the client's env with your shell. See env variables not passed.

Look up any JSON-RPC code you see in the log with the MCP error code lookup, or rebuild the block with the MCP config generator.

Next step

Once the container connects, decide what it should be allowed to touch. Containers help with isolation, but only if you limit mounts and network. Our guide to sandboxing local MCP servers covers that. If you want a team to review your setup, eSEOspace offers an MCP readiness audit.

More in the MCP Guide

Free tools: MCP Error Code Lookup · MCP Config Generator

Latest research: State of MCP: October 2026

Frequently asked questions

Why does my MCP container need -i?

The client sends every request on stdin. The docker run reference defines -i as "Keep STDIN open even if not attached." Without it, the server sees an empty input stream and the client gets no replies.

Can I run the container with -d and connect over HTTP instead?

Yes, if the server supports a remote transport such as Streamable HTTP. Then you publish a port and give the client a URL instead of a command. For a stdio server, detached mode will not work.

Do I need Docker Desktop for the MCP Toolkit?

Yes. Docker's guide says you enable it in Docker Desktop under Beta features with Enable Docker MCP Toolkit. Its pages describe the interface in Docker Desktop 4.62 and later.

Why does the server connect in one client and not another?

Each client reads a different file and some use different keys (servers in VS Code, mcpServers elsewhere). Timeouts and the PATH used to find docker also differ. Check the logs of the failing client first.

You Might Also like to Read

Get a FREE Website Audit

Enter your website and get a 20–30 page SEO, GEO, AEO & CRO audit within 24 hours. Completely free.

Don't have a site yet? Get in touch →

Ready to speak with a marketing expert?
Give us a call! (916) 866-7893

Websites Launched
1407
Websites Launched
Marketing Experts
29
Marketing Experts
Hours of Dedicated Work
204533
Hours of Dedicated Work
Irina S.Benjamin G.Jeanette M.David G.