Key Takeaways
- Learn why MCP servers must use file-relative .env paths.
- Claude Desktop's config lacks cwd, so relative paths break.
- Fix:
os.path.join(os.path.dirname(os.path.abspath(__file__)), '.env').
The Problem: MCP Servers and Unpredictable Working Directories

When you build an MCP server and configure it in Claude Desktop or another client, you typically specify command and args — but rarely cwd. The client launches your server as a subprocess, and that subprocess inherits the client's working directory, not the directory where your script lives.
This is a silent trap. If your server loads a .env file with a relative path like ".env", you're assuming the process's current working directory is the repo root. Nothing in your code enforces that, and nothing in the client config guarantees it.
The Fix: Resolve .env Relative to file
The robust solution is to anchor your .env path to the server script's own location. In Python, that looks like this:
import os
def load_env(path):
try:
f = open(path, encoding="utf-8")
except FileNotFoundError:
return
for line in f:
line = line.strip()
if "=" in line and not line.startswith("#"):
k, v = line.split("=", 1)
os.environ.setdefault(k, v.strip().strip('"').strip("'"))
here = os.path.dirname(os.path.abspath(__file__))
load_env(os.path.join(here, ".env"))
Note the key line: here = os.path.dirname(os.path.abspath(__file__)). This works regardless of where the client launches the process from.
Why This Matters for Claude Code Users
You likely use Claude Code to build and manage MCP servers. If you're developing a custom MCP server that reads API keys from .env, you've probably tested it by running python server.py from your repo root. It worked — so you shipped it. But Claude Desktop (or any MCP client) might launch it from ~ or /Applications or anywhere else. The moment that happens, your server silently fails to load credentials.
The failure is especially insidious: the server starts fine, but every tool that needs an API key returns an auth error. You debug for hours before noticing the env vars are missing.
Try It Now: Audit Your MCP Servers

- Find all your MCP server scripts — look for Python (or Node) files that read
.envorprocess.env. - Check their
.envloading code — does it use a relative path like".env"? If so, fix it. - For Node.js, use
path.join(__dirname, '.env')instead of'.env'. - Test from a different directory:
cd /tmp && python /path/to/your/server.py— does it still load env? If not, you've found the bug.
The Deeper Lesson: Don't Trust Implicit Assumptions
This bug is a symptom of a broader principle: never let your code rely on the environment's current working directory. MCP servers are especially vulnerable because they're launched by external clients you don't control.
Beyond .env, audit your server for other relative path usage — file logging, SQLite databases, temp directories. All of them should be anchored to __file__ or explicitly configured.
Conclusion
One line of code — os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env") — saves you from a whole class of "works on my machine" failures. Apply it to every MCP server you build, and you'll never lose a session to a missing API key again.
Source: dev.to








