Tuesday’s config problems got solved today, with one rule: stop relying on the system PATH.
1. Two Different Commands, Two Different Jobs
uv run mcp dev server.py
This is local development only. It launches the MCP Inspector in a browser so you can call your tools directly and confirm they work.
Do not use it to connect to a client. Claude Desktop launches your server itself — that’s the client’s job, not yours.
2. The Server Fix
If your server starts and immediately exits, the main block isn’t running a transport:
if __name__ == "__main__":
mcp.run(transport="stdio")
Without mcp.run(), the process has nothing to do, so it finishes. Being explicit about transport="stdio" costs nothing and removes any doubt.
3. The Foolproof Method: Absolute Paths
The rule: every executable in your config gets its full absolute path, never a bare command name.
Relying on PATH is, in the words of this session, a game of chance — it depends on how each student’s machine was set up, which is exactly what we can’t control.
Find the real path:
where.exe uv # for Python servers
where.exe npx # for Node servers
Note: where.exe, no space. Plain where in PowerShell is an alias for Where-Object and does something else entirely. On Windows, where.exe npx returns npx.cmd — use that exact path in the JSON.
4. The Claude Desktop Config
{
"mcpServers": {
"my-server": {
"command": "C:\\Users\\you\\.local\\bin\\uv.exe",
"args": [
"run",
"--directory",
"C:\\Users\\you\\projects\\learning-mcp",
"server.py"
]
}
}
}
The rules that make it work:
- Double backslashes everywhere on Windows. A single
\is an escape character in JSON. --directorywith the absolute project path, so the working directory is never in question.- Commas between fields. A missing one, or a trailing one, kills the whole file silently.
- Fully exit Claude Desktop from the system tray and restart. Closing the window isn’t enough.
Verify in Developer settings: the server status should read running.
5. Testing the Tools
We drove the math tools with plain English and watched each one fire.
Use “Allow once”, not “Always allow”, while you’re testing. You want to see exactly which tool the agent picks for each phrase — that’s the feedback loop that teaches you how your descriptions are being read.
6. Ready-Made Servers
You don’t have to write everything. The official reference servers install in one line — but check which runtime each one uses:
| Server | Runtime | Command |
|---|---|---|
| Fetch (web content) | Python | uvx mcp-server-fetch |
| Filesystem | Node | npx -y @modelcontextprotocol/server-filesystem <folder> |
| Memory | Node | npx -y @modelcontextprotocol/server-memory |
| Playwright (browser) | Node | npx @playwright/mcp@latest |
The same absolute-path discipline applies: find the real path to uvx or npx.cmd and put that in command.
7. Why stdio Means One Machine
Because stdio works over pipes to a child process, the agent and the server must run on the same host. That’s fine for local tools and development. Reaching a server on another machine means a different transport — which is where we’re headed.
8. The Same Logic Elsewhere
GitHub Copilot in VS Code uses a different JSON shape, but the principle doesn’t change: absolute paths, explicit arguments, no reliance on environment variables.
9. What You Can Actually Build
Today’s tools were arithmetic, but the limit is whatever you write a tool for. A tool that switches an air conditioner on and off is the same shape as add(a, b) — the model names the tool, your code does the work.
✅ Action Items
- Use
where.exeto find the real path for every executable in your config. - Replace every single backslash with double backslashes in Windows JSON.
- Confirm
mcp.run(transport="stdio")is in your main block. - Add a ready-made server — fetch or filesystem — alongside your own, and watch the agent choose between them.
⏭️ Next up: going beyond local tools.
