Auto-Installation for MCP Servers
Complete guide for automatically installing MCP servers in both Claude Code and Claude Desktop with safe credential management.
Overview
Auto-Installation for MCP Servers
Complete guide for automatically installing MCP servers in both Claude Code and Claude Desktop with safe credential management.
Overview
When you build an MCP server, you want it instantly available in both:
- Claude Code - For development and coding workflows
- Claude Desktop - For conversational usage
This guide provides scripts and patterns for zero-friction installation.
The Problem
Manual MCP installation requires:
- Adding to Claude Code via CLI (
claude mcp add) - Editing Claude Desktop config JSON manually
- Copying credentials to multiple places
- Restarting both applications
- Testing that everything works
This is tedious and error-prone.
The Solution
A manual configuration approach with secure patterns:
- Store credentials in
~/.mcp_secretswithchmod 600 - Use variable expansion (
${VAR}) in all configs - Install in Claude Code (user scope)
- Manually update Claude Desktop config with variable references
- Never write hardcoded secrets to configuration files
Why not automated? Auto-installation scripts that write actual credential values to configs are insecure. The recommended pattern uses variable expansion everywhere.
Secure Installation Guide
Step 1: Set Up Secrets
Create ~/.mcp_secrets:
# ~/.mcp_secrets
Secure it:
chmod 600 ~/.mcp_secrets
Load in shell profile (~/.zshrc or ~/.bashrc):
# Load MCP secrets
if [ -f ~/.mcp_secrets ]; then
source ~/.mcp_secrets
fi
Reload:
source ~/.zshrc # or ~/.bashrc
Step 2: Install in Claude Code
# Source secrets
source ~/.mcp_secrets
# Install with actual values (Claude Code stores them securely)
claude mcp add --transport stdio meta-ads \\
--scope user \\
--env META_ACCESS_TOKEN=${META_ACCESS_TOKEN} \\
--env META_AD_ACCOUNT_ID=${META_AD_ACCOUNT_ID} \\
-- uv --directory ~/Developer/mcp/meta-ads-mcp run python -m src.server
Note: When using claude mcp add, you pass actual values. Claude Code stores them securely in ~/.claude/.claude.json and references them correctly.
Step 3: Configure Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"meta-ads": {
"command": "/Users/username/.local/bin/uv",
"args": ["--directory", "/Users/username/Developer/mcp/meta-ads-mcp", "run", "python", "-m", "src.server"],
"cwd": "/Users/username/Developer/mcp/meta-ads-mcp",
"env": {
"META_ACCESS_TOKEN": "${META_ACCESS_TOKEN}",
"META_AD_ACCOUNT_ID": "${META_AD_ACCOUNT_ID}"
}
}
}
}
CRITICAL: Use variable expansion (${VAR}), never hardcode values.
Step 4: Verify Installation
# Check Claude Code
claude mcp list
# Test environment variables
echo $META_ACCESS_TOKEN # Should show value
Restart Claude Desktop and test.
Complete Examples
Example 1: Stripe MCP Server
1. Add to ~/.mcp_secrets:
2. Install in Claude Code:
source ~/.mcp_secrets
claude mcp add --transport stdio stripe \\
--scope user \\
--env STRIPE_API_KEY=${STRIPE_API_KEY} \\
-- uv --directory ~/Developer/mcp/stripe-mcp run python -m src.server
3. Configure Claude Desktop:
{
"mcpServers": {
"stripe": {
"command": "/Users/username/.local/bin/uv",
"args": ["--directory", "/Users/username/Developer/mcp/stripe-mcp", "run", "python", "-m", "src.server"],
"cwd": "/Users/username/Developer/mcp/stripe-mcp",
"env": {
"STRIPE_API_KEY": "${STRIPE_API_KEY}"
}
}
}
}
Example 2: Multi-Profile Server (GoHighLevel)
1. Add to ~/.mcp_secrets:
2. Install in Claude Code:
source ~/.mcp_secrets
claude mcp add --transport stdio ghl \\
--scope user \\
--env GHL_MAIN_API_TOKEN=${GHL_MAIN_API_TOKEN} \\
--env GHL_MAIN_LOCATION_ID=${GHL_MAIN_LOCATION_ID} \\
--env GHL_CLIENT_API_TOKEN=${GHL_CLIENT_API_TOKEN} \\
--env GHL_CLIENT_LOCATION_ID=${GHL_CLIENT_LOCATION_ID} \\
-- uv --directory ~/Developer/mcp/ghl-mcp run python -m src.server
3. Configure Claude Desktop:
{
"mcpServers": {
"ghl": {
"command": "/Users/username/.local/bin/uv",
"args": ["--directory", "/Users/username/Developer/mcp/ghl-mcp", "run", "python", "-m", "src.server"],
"cwd": "/Users/username/Developer/mcp/ghl-mcp",
"env": {
"GHL_MAIN_API_TOKEN": "${GHL_MAIN_API_TOKEN}",
"GHL_MAIN_LOCATION_ID": "${GHL_MAIN_LOCATION_ID}",
"GHL_CLIENT_API_TOKEN": "${GHL_CLIENT_API_TOKEN}",
"GHL_CLIENT_LOCATION_ID": "${GHL_CLIENT_LOCATION_ID}"
}
}
}
}
Credential Management Best Practices
Use ~/.mcp_secrets
Store all MCP server credentials in ~/.mcp_secrets:
# ~/.mcp_secrets
# Meta Ads
# Stripe
# GoHighLevel
# Zoom
Secure it:
chmod 600 ~/.mcp_secrets
Load in shell profile:
# Add to ~/.zshrc or ~/.bashrc
if [ -f ~/.mcp_secrets ]; then
source ~/.mcp_secrets
fi
Security Checklist
-
~/.mcp_secretshaschmod 600permissions - All configs use
${VAR}variable expansion -
.envfiles are in.gitignore - Pre-commit hook installed to catch secrets
- Never commit actual credential values
- Rotate credentials if accidentally exposed
Verification
Check Claude Code Installation
# List all installed servers
claude mcp list
# Get specific server details
claude mcp get meta-ads
# Remove if needed
claude mcp remove meta-ads
Check Claude Desktop Configuration
# View all servers
cat ~/Library/Application\\ Support/Claude/claude_desktop_config.json | jq '.mcpServers'
# Check specific server
cat ~/Library/Application\\ Support/Claude/claude_desktop_config.json | jq '.mcpServers["meta-ads"]'
# Verify cwd property is set
cat ~/Library/Application\\ Support/Claude/claude_desktop_config.json | jq '.mcpServers["meta-ads"].cwd'
# Verify env uses variable expansion
cat ~/Library/Application\\ Support/Claude/claude_desktop_config.json | jq '.mcpServers["meta-ads"].env'
Ensure configs show ${VAR} syntax, not actual values.
Test in Conversation
Claude Code:
- Open any project
- Ask: "List available MCP servers"
- Ask: "What Meta Ads operations are available?"
Claude Desktop:
- Restart the app
- Ask: "List available MCP servers"
- Ask: "What Meta Ads operations are available?"
Workflow Integration
When creating MCP servers, include installation in your development process:
Final Installation Steps
- Add credentials to
~/.mcp_secrets - Install in Claude Code using
claude mcp addwith actual values - Configure Claude Desktop with variable expansion (
${VAR}) - Verify with security checklist
- Test in both environments
This ensures secure, consistent installation across all clients.
Troubleshooting
"Command not found: claude"
- Install Claude Code CLI: Open Claude Code → run
/install-cli
"jq: command not found"
brew install jq # macOS
"Server not appearing in Claude Code"
# Check installation
claude mcp list
# Try removing and reinstalling
claude mcp remove <server-name>
~/.claude/scripts/install-mcp.sh ...
"Server not appearing in Claude Desktop"
- Verify JSON syntax:
jq '.' ~/Library/Application\\ Support/Claude/claude_desktop_config.json - Check backup file if config is corrupted
- Restart Claude Desktop
"Environment variable not found"
- Check
~/.claude/.envexists - Verify variable names match exactly
- Ensure no extra spaces:
KEY=valuenotKEY = value
TypeScript/Node Servers
Installation Pattern
Claude Code:
claude mcp add --transport stdio my-ts-server \\
--scope user \\
--env API_KEY=${API_KEY} \\
-- node ~/Developer/mcp/my-ts-server/dist/index.js
Claude Desktop:
{
"mcpServers": {
"my-ts-server": {
"command": "/usr/local/bin/node",
"args": ["/Users/username/Developer/mcp/my-ts-server/dist/index.js"],
"cwd": "/Users/username/Developer/mcp/my-ts-server",
"env": {
"API_KEY": "${API_KEY}"
}
}
}
}
Note: TypeScript servers have natural isolation through node_modules/.
Advanced: HTTP/SSE Servers
For remote servers:
# HTTP server
claude mcp add --transport http my-server https://api.example.com/mcp
# SSE server with headers
claude mcp add --transport sse my-server \\
--header "Authorization: Bearer $API_TOKEN" \\
https://mcp.example.com/sse
Security Best Practices Summary
Critical Security Rules
- Never hardcode credentials - Always use
${VAR}variable expansion - Secure credential files -
chmod 600 ~/.mcp_secrets - Use
.gitignore- Never commit.env,.env.local,*.key,secrets.json - Variable expansion everywhere - Claude Desktop configs must use
${VAR} - Token rotation - Update
~/.mcp_secrets, restart clients - Pre-commit hooks - Install to catch accidental commits
- Always include
cwd- Set working directory in all configs - Absolute paths - Command, args, cwd must all be absolute
- User scope for secrets - Keep credentials out of project configs
- Validate before deploy - Run security checklist
What Good Looks Like
✅ Secure Configuration:
{
"command": "/Users/username/.local/bin/uv",
"args": ["--directory", "/Users/username/Developer/mcp/my-server", "run", "python", "-m", "src.server"],
"cwd": "/Users/username/Developer/mcp/my-server",
"env": {
"API_KEY": "${API_KEY}",
"DB_URL": "${DB_URL:-postgres://localhost/mydb}"
}
}
❌ Insecure Configuration:
{
"command": "uv",
"args": ["--directory", "./my-server", "run", "python", "-m", "src.server"],
"env": {
"API_KEY": "sk_live_abc123"
}
}
Issues: Relative command path, relative directory, hardcoded secret, no cwd property.