Reference

MCP Server Environment Variables

The definitive guide to configuring environment variables for MCP servers across all clients.

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).

Frequently Asked Questions

Related Guides

Ready to explore MCP servers?

Browse 100+ curated MCP servers
Step-by-step setup tutorials
Community-driven reviews and ratings