How to Set Up an MCP Server on Windows
Install and run an MCP server on Windows with Python, Docker Desktop, Claude Desktop, and enterprise registration, plus fixes for common errors.
Quick answer: On Windows, the simplest learning setup is a local Python MCP server. Install Python 3.10 or newer, install mcp[cli], create a server file, and run uv run mcp dev server.py. This opens MCP Inspector so you can call tools interactively. Use Docker Desktop MCP Toolkit when you need repeatable containers, Claude Desktop when you want a desktop host, and Windows on-device agent registration for managed enterprise deployments.
MCP (Model Context Protocol) servers expose tools, resources, and prompts to compatible AI clients. The server can run as a local stdio process, in a Docker container, or through a managed Windows agent registration.
Choose a Windows setup path
| Path | Best for | Isolation | Main requirement |
|---|---|---|---|
| Local Python | Learning and one machine | Your Windows user process | Python 3.10+, mcp[cli], and uv or pip |
| Docker MCP Toolkit | Repeatable, cataloged servers | Container and Toolkit gateway | Docker Desktop with MCP Toolkit enabled |
| Claude Desktop host | Using a local server from Claude | Host-managed subprocess | Claude Desktop configuration |
| Windows on-device agent | Enterprise registration and policy | Contained agent session with approved resources | Package identity, bundle, or manual ODR registration |
Prerequisites
- Windows 10 or 11 with permission to install software.
- Python 3.10 or newer for the official Python SDK (MCP project documentation).
- Node.js if you want MCP Inspector; Inspector is a Node.js application and uses
npx. - For Docker: Docker Desktop with the MCP Toolkit feature available in Settings → Beta features.
- An MCP-compatible client such as Claude Desktop, an Inspector session, or a Windows agent host.
Path A: create a local Python MCP server
1. Install Python and verify PATH
python --version
where python
Use Python 3.10 or newer. If python is not found, reinstall Python and enable the option that adds it to PATH, or use the full path reported by your installation.
2. Install the SDK and CLI
With uv:
uv add "mcp[cli]"
With pip:
py -m pip install "mcp[cli]"
Confirm the commands:
uv --version
py -m pip show mcp
3. Create server.py
This minimal server exposes one tool that adds two numbers. The official SDK examples use the same single-file development pattern.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Windows demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
if __name__ == "__main__":
mcp.run()
Keep protocol traffic on stdout. Send diagnostic messages to stderr so a stdio host does not receive malformed protocol data.
4. Launch MCP Inspector
From the folder containing server.py:
uv run mcp dev server.py
The command starts the development server and opens MCP Inspector. If npx is missing, install Node.js, reopen your terminal, and verify:
node --version
npx --version
In Inspector, connect to the server, list tools, call add with two integers, and confirm the returned value. Inspector is a development check; it does not certify production readiness.
5. Run the server directly
For a host that launches the script itself:
uv run server.py
Do not type arbitrary text into a running stdio process. The client must speak MCP over the process pipes.
Connect the server to Claude Desktop
The SDK CLI can install a server entry for Claude Desktop:
uv run mcp install server.py
The command resolves the script to an absolute path and writes the launch entry to:
%APPDATA%\Claude\claude_desktop_config.json
Fully quit and reopen Claude Desktop after installation or configuration changes. If the server needs secrets, pass them explicitly; Claude Desktop does not automatically inherit variables from the shell where you tested the server.
Pass environment variables explicitly
Using a value:
uv run mcp install server.py -v API_TOKEN=replace_me
Using a dotenv file:
uv run mcp install server.py -f .env
Keep .env out of source control. Use absolute executable paths when the desktop host has a restricted PATH. Find them with:
where uv
where npx
Path B: use Docker Desktop MCP Toolkit
- Install Docker Desktop and enable MCP Toolkit under Settings → Beta features.
- Create a Toolkit profile.
- Add an MCP server from the catalog or configure your own server.
- Connect the profile to your AI client.
- Invoke a tool from the client and confirm its response.
On Windows, Docker documents using a full executable path such as:
C:/Program Files/Docker/Docker/resources/bin/docker.exe
When the host needs them, pass the PROGRAMFILES and PROGRAMDATA environment variables. Set startup_timeout_sec = 60; Docker reports that the gateway typically needs about 15–25 seconds to initialize and that the default 10-second timeout can be too short. See the Docker MCP Toolkit documentation for profile and client configuration details.
Path C: register an MCP server with the Windows on-device agent
Microsoft documents three registration families:
- Package-identity apps: normally MSIX or external-location packaging.
- Directly installed MCP bundles: local bundles without package identity.
- Manual local or remote registration: entries in the Windows on-device agent registry (ODR).
ODR-registered servers run in a contained agent session with restrictions on approved resources. Direct bundles without package identity cannot use the securely contained agent process unless the user explicitly enables the setting that reduces protections for agent connectors. Use package identity or managed registration for enterprise distribution, and review every tool, resource, permission, and secret exposed by the server. Read the current Microsoft Windows MCP guidance before deploying policies.
Test every tool before connecting a host
- Start the server manually and confirm it exits cleanly when the client disconnects.
- List tools and verify names, descriptions, input schemas, and required fields.
- Call each tool with valid input.
- Call each tool with missing, empty, and boundary values.
- Confirm errors are returned as structured tool errors rather than crashes.
- Check that logs go to stderr and do not corrupt stdout protocol messages.
- Repeat the test through the intended host: Inspector, Claude Desktop, Docker client, or Windows agent.
Troubleshooting Windows MCP servers
| Symptom | Likely cause | Fix |
|---|---|---|
uv is not recognized |
Minimal PATH in the host or terminal | Run where uv and configure that absolute path in the host. Reopen the terminal after installation. |
npx is not recognized |
Node.js is missing or not on PATH | Install Node.js, verify npx --version, then restart Inspector. |
| Works manually but not in Claude Desktop | Claude did not inherit shell environment variables | Pass secrets with -v NAME=value or -f .env, use absolute paths, and fully restart Claude Desktop. |
| Docker gateway timeout | Ten-second default is shorter than gateway startup | Use the full Windows docker.exe path, pass PROGRAMFILES and PROGRAMDATA, and set startup_timeout_sec = 60. |
| No tools appear in the Windows agent | Registration or containment mismatch | Check whether the server is package-identity, a bundle, or ODR-registered. Review containment requirements and connector protection settings. |
| Inspector shows protocol errors | Logs or print statements were written to stdout | Move diagnostics to stderr. Keep stdout reserved for MCP protocol messages. |
| Server exits immediately | Wrong working directory, missing dependency, or script exception | Run the exact command in a terminal, inspect the traceback, use absolute paths, and verify dependencies in the same environment the host launches. |
| Tool call hangs | Blocking I/O, unreachable dependency, or no timeout | Add timeouts to network calls, avoid indefinite waits, and log lifecycle events to stderr. |
Performance, reliability, security, and cost
Performance
- Local stdio avoids network setup and is usually the fastest path for one machine.
- Docker adds image and gateway startup time; allow at least the documented 60-second startup timeout.
- Keep tool schemas specific so clients send smaller, valid requests.
- Reuse connections to external services where the SDK and host support it, and set finite timeouts for every network call.
Reliability
- Pin Python dependencies and container image versions for repeatable deployments.
- Return actionable structured errors and make tools safe to retry where possible.
- Test the exact launch command and environment used by the host, not only an interactive shell.
- Use health checks or a simple diagnostic tool for services with external dependencies.
Security
- Expose the smallest set of tools and resources required.
- Keep API keys out of source files and commit history.
- Review filesystem, network, and process permissions before connecting an agent.
- For enterprise use, prefer package identity or managed ODR registration and approved-resource restrictions.
Cost
The MCP protocol and local Python process do not add a per-call fee. Costs can come from the model host, Docker infrastructure, and APIs your tools call. Track those dependencies separately and set usage limits where available.
Or skip the browser setup
If your MCP tools need website screenshots, ScreenshotNeo provides a website screenshot API and an MCP server for Claude, Cursor, and other MCP clients. A single GET request returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status.
See the ScreenshotNeo API documentation for all options and MCP details.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also supports full-page and element capture, device presets, custom CSS and JavaScript, waits, blocking rules, headers, cookies, geolocation, resizing, caching, signed links, asynchronous jobs, bulk capture, usage reporting, and PDFs. Every feature is on every plan. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
FAQ
Can I run an MCP server without Docker?
Yes. A Python stdio server with Python 3.10+ and mcp[cli] is enough for local development and desktop hosts.
Why does Inspector require Node.js?
The MCP Inspector development interface is a Node.js application launched through npx.
Should I use Docker or Python first?
Use Python to understand the protocol and iterate quickly. Use Docker when you need repeatable isolation or a catalog-managed deployment.
Where does Claude Desktop store its configuration?
On Windows, the generated configuration is %APPDATA%\Claude\claude_desktop_config.json.
How should production secrets be supplied?
Provide them through the host’s explicit environment configuration or a protected secret store. Do not hard-code them in the server source.


