The Definitive Guide to Securely Configuring MCP Servers
A complete walkthrough on setting up MCP servers for Gemini CLI and VS Code, focusing on security best practices, persistent environment variables, and troubleshooting common issues like 'Access Denied' and authentication loops.
What You'll Learn
- Why you must never hardcode API keys or secrets.
- How to use environment variables to securely manage secrets.
- +3 more
Time & Difficulty
Time: 20 minutes
Level: Beginner
What You'll Need
- A Mac running a modern version of macOS (with Zsh as the default shell).
- Visual Studio Code installed.
- +1 more
Introduction: The Foundation of a Secure Workflow
Using Model-Context Protocol (MCP) servers unlocks incredible power for AI tools like Claude Code, Gemini CLI, VS Code and editor extensions. But with great power comes the great responsibility of managing configurations and secrets securely. This guide provides a definitive, step-by-step workflow for setting up your environment correctly, avoiding common pitfalls, and ensuring your sensitive API keys remain safe.
We will cover the entire process, from securely storing secrets to configuring your tools and troubleshooting the frustrating issues that can stop you in your tracks.
Part 1: The Golden Rule - Never Hardcode Secrets
An API key, Personal Access Token (PAT), or any other secret credential is like a password. If you save it in plain text within a configuration file (settings.json
), anyone who sees that file has full access to your account.
- Bad Practice (Insecure):
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_ThisIsARealSecretKey" }
- Best Practice (Secure):
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}" }
The ${VAR_NAME}
syntax is a placeholder. It tells the application (like Gemini CLI or VS Code) to look for an environment variable with that name and use its value. Our next step is to create these variables securely.
Part 2: Making Environment Variables Permanent on macOS
If you just type export MY_KEY="value"
in your terminal, it only lasts until you close that window. To make variables available in every new terminal session, we must add them to your shell’s startup file. On modern Macs, this is .zshrc
.
Step 1: Install the ‘code’ Command for Your Terminal
This one-time setup lets you open files in VS Code directly from your command line.
- Open the VS Code application.
- Open the Command Palette with
Shift + Command + P
. - Type
shell command
and selectShell Command: Install 'code' command in PATH
. - Enter your Mac password if prompted.
- Restart your terminal completely for the change to take effect.
Step 2: Open and Edit Your .zshrc
File
Now, in your new terminal window, this simple command will work:
code ~/.zshrc
This opens the correct file in VS Code. If the file is new and empty, that’s perfectly fine.
Step 3: Add Your Secrets
Go to the bottom of the .zshrc file and add your export commands. This is the only place where your secret keys will be written down.
# Secrets for MCP Servers (Gemini CLI & VS Code)
export GITHUB_PERSONAL_ACCESS_TOKEN="your_new_github_pat_here"
export GEMINI_API_KEY="your_new_google_api_key_here"
export CLOUDFLARE_API_TOKEN="your_new_cloudflare_api_token_here"
Save the file (Cmd + S).
Step 4: Load and Verify Your Changes
Your new variables won’t be active until you load them.
- Either: Close and reopen your terminal.
- Or (for pros): In your existing terminal, run source ~/.zshrc.
To verify it worked, check one of the variables:
echo $GEMINI_API_KEY
This should print the key you just saved. If it does, your secure environment is ready!
Part 3: Finding and Editing Your Configuration Files
This is a common point of confusion. Gemini CLI and VS Code have separate settings.json files. You must configure both if you want to use both.
How to Edit the Gemini CLI settings.json
Gemini CLI has two settings locations. For “always on” servers, use the global user file.
- Navigate to your home directory in the terminal (this avoids “Access Denied” errors):
cd ~
- Create the directory if it doesn’t exist:
mkdir -p .gemini
- Open the settings file in VS Code:
code ~/.gemini/serttings.json
Now, paste your adapted and secured Gemini CLI configuration into this file. Remember to convert timeouts to milliseconds (e.g., 60 -> 60000) and remove unsupported properties like type or disabled.
How to Edit the VS Code settings.json
This is the configuration for the MCP extension within VS Code.
-
In VS Code, open the Command Palette (Shift + Command + P).
-
Type settings json and select Preferences: Open User Settings (JSON).
-
Find the mcpServers object and ensure it uses the ${VAR_NAME} placeholders for all secrets, just like you did for the Gemini CLI config.
-
Part 4: Troubleshooting Guide
Issue: “Access Denied” when creating ~/.gemini
-
Cause: You are not in your home directory. Your terminal is likely in a system-protected location like /.
- Solution: Always run cd ~ in your terminal before running mkdir .gemini. Do not use sudo.
Issue: zsh: command not found: code
-
Cause: The VS Code shell command isn’t installed in your system’s PATH.
- Solution: Follow the steps in Part 2, Step 1 of this guide.
Issue: An “Authentication Storm” of Browser Windows (e.g., with Cloudflare)
-
Cause: You are running multiple MCP servers from the same provider simultaneously, and none of them can find a valid API token. Each one independently tries to open a browser to get you to log in.
-
Solution:
-
First, ensure the relevant environment variable (e.g., CLOUDFLARE_API_TOKEN) is correctly set in your .zshrc and your terminal has been reloaded.
- If the issue persists, disable all but one of the provider’s servers in your settings. Start the tool, complete the single login prompt, and then re-enable the other servers one by one.
-
Issue: My server isn’t loading and I don’t know why.
-
Check the Path: Is the path to the settings.json file exactly correct? (~/.gemini/settings.json for global Gemini).
-
Validate the JSON: Copy the entire content of your settings.json and paste it into an online JSON validator. A single missing comma will cause it to fail silently.
-
Test the Command: Copy the command and args from your configuration and run them directly in your terminal. If the command fails there, the problem is with the server script itself, not the configuration.
-
Related Guides
A Developer's Guide to MCP Security: Beyond the Basics
Centralize your understanding of MCP security with this comprehensive guide. Learn practical steps for authenticating servers, preventing prompt injection, validating URIs, and managing secrets.
Building Your First MCP Server with Python
A step-by-step tutorial on how to create and run a basic Model Context Protocol (MCP) server using the Python SDK, FastMCP.
Connect Claude to Your Business Files with MCP
Step-by-step guide to setting up Claude AI to read, analyze, and work with your business documents and spreadsheets automatically.
Want More Step-by-Step Guides?
Get weekly implementation guides and practical MCP tutorials delivered to your inbox.
Subscribe for Weekly Guides