This guide explains how to pass dynamic, project-specific values (like project IDs) to MCP servers in Claude Code plugins.
You want to create a plugin with MCP servers (like Apidog) that need project-specific configuration, but:
- Plugin is distributed to multiple users/projects
- Each project has different IDs, tokens, etc.
- Configuration must be dynamic per-project
Plugin (Distributed)
├── MCP Config Template (uses ${ENV_VARS})
└── Setup Command (helps users configure)
User's Project (Specific)
└── .claude/settings.json (contains actual values)
1. Plugin provides MCP config template with placeholders:
// .claude-plugin/plugins/your-plugin/mcp-servers/mcp-config.json
{
"apidog": {
"command": "npx",
"args": [
"-y",
"@apidog/mcp-server",
"--project-id",
"${APIDOG_PROJECT_ID}", // ← Placeholder
"--token",
"${APIDOG_API_TOKEN}" // ← Placeholder
]
}
}2. User runs setup command in their project:
/setup-apidog3. Setup command writes to project's .claude/settings.json:
{
"env": {
"APIDOG_PROJECT_ID": "abc123", // ← Actual value
"APIDOG_API_TOKEN": "secret-token" // ← Actual value
}
}4. Claude Code resolves environment variables at runtime:
${APIDOG_PROJECT_ID} → abc123
${APIDOG_API_TOKEN} → secret-token
5. MCP server starts with correct project-specific values!
Use when: Simple config with 1-3 values
Plugin's mcp-config.json:
{
"apidog": {
"command": "npx",
"args": ["-y", "@apidog/mcp-server"],
"env": {
"APIDOG_PROJECT_ID": "${APIDOG_PROJECT_ID}",
"APIDOG_API_TOKEN": "${APIDOG_API_TOKEN}"
}
}
}User's .claude/settings.json:
{
"env": {
"APIDOG_PROJECT_ID": "my-project-123",
"APIDOG_API_TOKEN": "my-secret-token"
}
}Use when: Complex config with many values
Plugin's mcp-config.json:
{
"apidog": {
"command": "npx",
"args": [
"-y",
"@apidog/mcp-server",
"--config",
"${PROJECT_ROOT}/.apidog/config.json"
]
}
}User creates .apidog/config.json in their project:
{
"projectId": "abc123",
"apiToken": "secret",
"teamId": "team-456",
"endpoints": ["api1", "api2"]
}Use when: Want to provide sensible defaults
{
"apidog": {
"command": "npx",
"args": ["-y", "@apidog/mcp-server"],
"env": {
"APIDOG_BASE_URL": "${APIDOG_BASE_URL:-https://api.apidog.com}",
"APIDOG_TIMEOUT": "${APIDOG_TIMEOUT:-30000}"
}
}
}Syntax: ${VAR:-default_value}
- If
VARis set, use its value - If
VARis not set, usedefault_value
Use when: Want great UX for non-technical users
Create /setup-apidog command that:
- Asks user for credentials (using
AskUserQuestion) - Validates the credentials
- Writes to
.claude/settings.json - Tests MCP server connection
- Provides usage instructions
See: commands/setup-apidog.md for full implementation
${CLAUDE_PLUGIN_ROOT} # Path to plugin installation directory
${PROJECT_ROOT} # Path to current project root
${HOME} # User's home directory
${USER} # Current username{
"env": {
"APIDOG_PROJECT_ID": "your-value",
"CUSTOM_VAR": "any-value",
"API_KEY": "secret-key"
}
}-
Use environment variables for secrets
"env": { "API_TOKEN": "${API_TOKEN}" }
-
Provide setup commands
/setup-apidog # Guides user through setup -
Document required variables
## Required Environment Variables - `APIDOG_PROJECT_ID`: Your project ID from Apidog - `APIDOG_API_TOKEN`: API token from Apidog settings
-
Validate before saving
# Test connection before writing config npx @apidog/mcp-server --project-id ${ID} --token ${TOKEN} --test
-
Mask sensitive data in output
✅ Configured! Project ID: abc***123 Token: sec*******ken
-
Hard-code secrets in plugin
// ❌ BAD { "apidog": { "env": { "APIDOG_PROJECT_ID": "hardcoded-id" // Don't do this! } } }
-
Commit secrets to git
# Add to .gitignore .claude/settings.local.json .apidog/config.json -
Use global settings for project-specific config
# ❌ BAD: Global config affects all projects ~/.config/claude/settings.json # ✅ GOOD: Project-specific config /my-project/.claude/settings.json
-
Skip validation
# Always validate credentials before saving
frontend/
├── mcp-servers/
│ ├── mcp-config.example.json # Template with ${VARS}
│ └── README.md # Setup instructions
├── commands/
│ └── setup-apidog.md # Interactive setup
└── plugin.json
Step 1: Install plugin
/plugin install frontend@mag-claude-pluginsStep 2: Run setup
/setup-apidogClaude prompts:
🔧 Apidog Setup
Enter your Apidog Project ID:
(Found in your project URL: app.apidog.com/project/{ID})
> abc123
Enter your API Token:
(Generate at: Apidog Settings → API Tokens)
> secret-token-here
✅ Testing connection...
✅ Connection successful!
✅ Configuration saved to .claude/settings.json
Available tools:
- apidog_get_project
- apidog_list_apis
- apidog_import_endpoint
Try: "Fetch API documentation from Apidog for the User API"
Step 3: Use MCP tools
User: "Get all endpoints from my Apidog project"
Claude: [Uses apidog_list_apis with correct project ID]
Each project has its own .claude/settings.json:
project-a/
└── .claude/settings.json (APIDOG_PROJECT_ID=project-a-id)
project-b/
└── .claude/settings.json (APIDOG_PROJECT_ID=project-b-id)
# Terminal 1: Project A
cd project-a
export APIDOG_PROJECT_ID="project-a-id"
claude-code
# Terminal 2: Project B
cd project-b
export APIDOG_PROJECT_ID="project-b-id"
claude-codeEnhance setup command to:
- Fetch list of user's Apidog projects (using API token)
- Present selection UI
- Save selected project ID
/setup-apidog
🔍 Fetching your Apidog projects...
Select a project:
1. Project Alpha (ID: abc123)
2. Project Beta (ID: def456)
3. Project Gamma (ID: ghi789)
Which project? [1-3]: 2
✅ Configured for: Project BetaRecommended hierarchy:
-
Project-specific (most secure):
/my-project/.claude/settings.json + Add to .gitignore + Never commit -
User global (for personal projects):
~/.config/claude/settings.json -
Environment variables (for CI/CD):
export APIDOG_PROJECT_ID="..." export APIDOG_API_TOKEN="..."
// .gitignore
.claude/settings.local.json
.claude/settings.json
.apidog/
*.env# Check before committing
git status
git diff .claude/Check 1: Variable is set in .claude/settings.json
cat .claude/settings.json | grep APIDOG_PROJECT_IDCheck 2: Syntax is correct
{
"env": {
"VAR": "${VAR}" // ✅ Correct
"VAR": "$VAR" // ❌ Wrong
}
}Check 1: Run MCP command directly
npx -y @apidog/mcp-server --project-id abc123 --token secretCheck 2: Check Claude Code logs
# Look for MCP server errorsSolution: Reconfigure
/setup-apidog # Run setup again- Plugin Example: frontend-development
- Setup Command Example
- MCP Config Examples
- Claude Code Docs
- MCP Protocol
Author: Jack Rudenko (i@madappgang.com) Company: MadAppGang Plugin: mag-claude-plugins