How Environment Variables Work in MCP
MCP servers often need environment variables for API keys, database connections, and configuration. Unlike regular terminal commands, MCP servers are spawned by your client application, which means they don't inherit your shell's environment variables by default.
The MCP configuration supports an "env" field that passes environment variables directly to the server process. This is the primary way to configure secrets and API keys for your MCP servers.
The env Field in MCP Config
Every MCP client that supports stdio transport accepts an "env" field in the server configuration:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}
The env field is a simple key-value object. Values must be strings. The variables are passed only to that specific server process - they don't affect other servers or the client itself.
Per-Client Configuration
Claude Desktop
Claude Desktop supports the "env" field in claude_desktop_config.json:
{
"mcpServers": {
"github": {
"command": "/usr/local/bin/npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx",
"GITHUB_API_URL": "https://api.github.com"
}
},
"postgres": {
"command": "/usr/local/bin/npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb"
}
}
}
}
Claude Desktop merges the env field with a minimal set of system environment variables (like PATH). Your server receives both.
Cursor
Cursor uses the same env format in .cursor/mcp.json:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}
Cursor inherits more of the system environment than Claude Desktop. If an env var is already set in your system, you may not need to add it to the config. However, explicitly setting it in the config ensures reliability.
VS Code
VS Code MCP configuration depends on the extension being used. For GitHub Copilot's MCP support, the config is in VS Code settings:
// .vscode/settings.json
{
"mcp": {
"servers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}
}
CLI Clients
CLI-based MCP clients (like Claude Code) typically inherit your shell's full environment. You can still use the env field to override or add variables specifically for a server.
Common Environment Variables
Here are the most commonly used environment variables for popular MCP servers:
API Keys
{
"env": {
"GITHUB_TOKEN": "ghp_xxxx", // GitHub server
"ANTHROPIC_API_KEY": "sk-ant-xxxx", // Anthropic API
"OPENAI_API_KEY": "sk-xxxx", // OpenAI-based servers
"SLACK_BOT_TOKEN": "xoxb-xxxx", // Slack server
"GOOGLE_API_KEY": "AIza-xxxx", // Google services
"BRAVE_API_KEY": "BSA-xxxx" // Brave Search server
}
}
Database Connections
{
"env": {
"DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb",
"REDIS_URL": "redis://localhost:6379",
"MONGODB_URI": "mongodb://localhost:27017/mydb",
"SQLITE_PATH": "/path/to/database.db"
}
}
Server Configuration
{
"env": {
"MCP_LOG_LEVEL": "debug",
"MCP_PORT": "3001",
"NODE_ENV": "production",
"PYTHONDONTWRITEBYTECODE": "1"
}
}
Secrets Management Best Practices
Storing API keys directly in MCP config files is convenient but has security risks. Here are better approaches:
1. Reference System Environment Variables
Some clients support referencing system environment variables. Set them in your shell profile:
# ~/.zshrc or ~/.bashrc
export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx"
export ANTHROPIC_API_KEY="sk-ant-xxxxxxxxxxxx"
Then in CLI clients, you don't need the env field at all. For GUI clients like Claude Desktop, you still need the env field because they don't source your shell profile.
2. Use a Secrets Manager
For team environments, use a secrets manager and inject values at startup:
# Using 1Password CLI
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "op://vault/github/token"
}
}
}
}
Note: Not all clients support secret manager references directly. You may need a wrapper script.
3. Wrapper Script Approach
Create a wrapper script that loads secrets and then runs the server:
#!/bin/bash
# mcp-github-wrapper.sh
export GITHUB_TOKEN=$(cat ~/.secrets/github-token)
exec npx -y @modelcontextprotocol/server-github "$@"
{
"mcpServers": {
"github": {
"command": "/path/to/mcp-github-wrapper.sh"
}
}
}
4. Keep Config Out of Version Control
Add your MCP config files to .gitignore:
# .gitignore
claude_desktop_config.json
.cursor/mcp.json
For security best practices, see our MCP Server Security Guide.
Loading .env Files
MCP servers don't automatically load .env files. If your server needs values from a .env file, you have several options:
Node.js Servers
// In your server code, load dotenv at the top
import 'dotenv/config'
// Or use the --require flag
{
"command": "node",
"args": ["--require", "dotenv/config", "server.js"]
}
Python Servers
# In your server code
from dotenv import load_dotenv
load_dotenv()
# Or use the python-dotenv CLI
{
"command": "python3",
"args": ["-m", "dotenv", "run", "python3", "server.py"]
}
Debugging Environment Variable Issues
If your server isn't receiving the right environment variables:
1. Log the Environment
Add temporary logging to your server to see what variables it receives:
// Node.js
console.error('ENV:', JSON.stringify(process.env, null, 2));
# Python
import os, sys
print(dict(os.environ), file=sys.stderr)
Check the client's MCP logs for the stderr output.
2. Verify the Config
Common mistakes in the env field:
// WRONG - using numbers instead of strings
"env": { "PORT": 3000 }
// CORRECT - all values must be strings
"env": { "PORT": "3000" }
// WRONG - nested objects
"env": { "CONFIG": { "key": "value" } }
// CORRECT - flat key-value pairs only
"env": { "CONFIG_KEY": "value" }
3. PATH Issues
If your server needs specific binaries on the PATH, include PATH in the env field:
{
"env": {
"PATH": "/usr/local/bin:/usr/bin:/bin:/home/user/.local/bin",
"GITHUB_TOKEN": "ghp_xxxx"
}
}
Be careful: setting PATH in env replaces the inherited PATH on most clients. Include all directories you need.
Environment Variables for the GitHub MCP Server
The official GitHub MCP server is one of the most popular servers and requires specific env vars:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_xxxx",
"GITHUB_API_URL": "https://api.github.com"
}
}
}
}
Generate a GitHub Personal Access Token at github.com/settings/tokens with the scopes your workflow needs (typically repo, read:org).