# MCP Configuration Reference Complete schema and technical reference for MCP server configuration in Claude Code plugins. ## Configuration Schema ### Stdio Server Configuration ```typescript { command: string // Required: Executable path or command name args?: string[] // Optional: Command-line arguments env?: Record // Optional: Environment variables } ``` **Field Details:** - **`command`**: The executable to run. Can be: - System command: `"node"`, `"python"`, `"npx"` - Absolute path: `"/usr/local/bin/my-server"` - Plugin-relative: `"${CLAUDE_PLUGIN_ROOT}/servers/my-server"` - **`args`**: Array of arguments passed to the command - Order matters - Supports variable expansion: `["--config", "${CONFIG_PATH}"]` - **`env`**: Environment variables for the process - Inherits user's environment by default - Additional vars override/extend inherited ones - Supports variable expansion: `{"KEY": "${USER_KEY}"}` **Example:** ```json { "my-server": { "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/dist/server.js", "--port", "8080"], "env": { "NODE_ENV": "production", "LOG_LEVEL": "${LOG_LEVEL:-info}" } } } ``` ### HTTP Server Configuration ```typescript { type: "http" // Required: Transport type url: string // Required: HTTP(S) endpoint URL headers?: Record // Optional: HTTP headers } ``` **Field Details:** - **`type`**: Must be `"http"` for HTTP transport - **`url`**: The MCP endpoint URL - Must be valid HTTP(S) URL - Supports variable expansion: `"${API_BASE_URL}/mcp"` - Should end in `/mcp` by convention - **`headers`**: HTTP headers sent with requests - Common uses: Authentication, API keys, custom metadata - Supports variable expansion: `{"Authorization": "Bearer ${TOKEN}"}` **Example:** ```json { "api-server": { "type": "http", "url": "https://api.example.com/mcp", "headers": { "Authorization": "Bearer ${API_TOKEN}", "X-Client-Version": "1.0.0", "Accept": "application/json" } } } ``` ### SSE Server Configuration (Deprecated) ```typescript { type: "sse" // Required: Transport type url: string // Required: SSE endpoint URL headers?: Record // Optional: HTTP headers } ``` **Note**: SSE transport is deprecated. Use HTTP transport instead when available. **Field Details:** - **`type`**: Must be `"sse"` for Server-Sent Events transport - **`url`**: The SSE endpoint URL - **`headers`**: HTTP headers (same as HTTP transport) **Example:** ```json { "legacy-server": { "type": "sse", "url": "https://api.example.com/sse", "headers": { "X-API-Key": "${API_KEY}" } } } ``` ## Environment Variable Expansion ### Syntax | Pattern | Behavior | Example | |---------|----------|---------| | `${VAR}` | Required variable (error if not set) | `${API_KEY}` | | `${VAR:-default}` | Optional with fallback value | `${PORT:-8080}` | | `${CLAUDE_PLUGIN_ROOT}` | Plugin directory path (special) | `${CLAUDE_PLUGIN_ROOT}/bin` | ### Expansion Locations Environment variables can be expanded in: - **Stdio servers**: - `command` field - `args` array elements - `env` object values - **HTTP/SSE servers**: - `url` field - `headers` object values ### Special Variables #### `${CLAUDE_PLUGIN_ROOT}` - **Type**: Plugin-specific - **Value**: Absolute path to plugin directory - **Use case**: Reference bundled servers, configs, assets - **Example**: `"${CLAUDE_PLUGIN_ROOT}/servers/db-server"` #### User Environment Variables All variables from user's shell environment are available: ```json { "env": { "PATH": "${PATH}", // User's PATH "HOME": "${HOME}", // User's home directory "DATABASE_URL": "${DATABASE_URL}" // Custom user variable } } ``` ### Expansion Examples **Basic expansion:** ```json { "url": "${API_BASE_URL}/mcp" } ``` With `API_BASE_URL=https://api.example.com`, becomes: ``` https://api.example.com/mcp ``` **Default values:** ```json { "env": { "LOG_LEVEL": "${LOG_LEVEL:-info}", "PORT": "${PORT:-3000}" } } ``` Without environment variables set, becomes: ```json { "env": { "LOG_LEVEL": "info", "PORT": "3000" } } ``` **Plugin-relative paths:** ```json { "command": "${CLAUDE_PLUGIN_ROOT}/bin/server", "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"] } ``` With plugin at `/home/user/.claude/plugins/my-plugin`, becomes: ``` command: /home/user/.claude/plugins/my-plugin/bin/server args: ["--config", "/home/user/.claude/plugins/my-plugin/config.json"] ``` ## Configuration Files ### .mcp.json (Recommended) **Location**: Plugin root directory **Structure**: ```json { "mcpServers": { "server-name-1": { /* config */ }, "server-name-2": { /* config */ } } } ``` **Advantages**: - Separates concerns (MCP config separate from plugin metadata) - Easier to maintain complex configurations - Can be shared/reused across plugins - Better for multiple MCP servers **Example**: ```json { "mcpServers": { "database": { "command": "npx", "args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}"] }, "api": { "type": "http", "url": "${API_BASE_URL}/mcp" } } } ``` ### plugin.json (Inline) **Location**: `.claude-plugin/plugin.json` **Structure**: ```json { "name": "my-plugin", "version": "1.0.0", "mcpServers": { "server-name": { /* config */ } } } ``` **Advantages**: - Single file for simple plugins - All configuration in one place - No additional files needed **Example**: ```json { "name": "simple-plugin", "version": "1.0.0", "description": "A simple plugin with one MCP server", "mcpServers": { "api": { "type": "http", "url": "https://api.example.com/mcp" } } } ``` **Choosing Between .mcp.json and inline:** - Use `.mcp.json` for 2+ servers or complex configs - Use inline for single simple server - Both methods are functionally identical ## Server Lifecycle ### 1. Plugin Enable - Plugin is enabled via `/plugin enable` - MCP servers are registered with Claude Code - No servers start yet ### 2. Claude Code Start - Claude Code reads enabled plugins - MCP servers start automatically - Stdio servers: Process spawned - HTTP/SSE servers: Connection established ### 3. Server Ready - Server responds to initialization - Tools/resources/prompts registered - Available via `/mcp` command ### 4. Plugin Update - Configuration changes detected - **Requires Claude Code restart** to apply - Old servers stop, new ones start on restart ### 5. Plugin Disable - Plugin disabled via `/plugin disable` - MCP servers stop automatically - Resources cleaned up ## Platform-Specific Considerations ### Windows **npx Wrapper Required:** ```json { "command": "cmd", "args": ["/c", "npx", "-y", "package-name"] } ``` **Path Separators:** - Windows: Use forward slashes `/` in JSON - Variable expansion handles platform differences - Example: `"${CLAUDE_PLUGIN_ROOT}/bin/server"` works on all platforms **Environment Variables:** ```json { "env": { "USERPROFILE": "${USERPROFILE}", // Windows home directory "APPDATA": "${APPDATA}" // Windows app data } } ``` ### macOS/Linux **Standard Commands:** ```json { "command": "npx", "args": ["-y", "package-name"] } ``` **Executable Permissions:** - Bundled executables must have execute permissions - Set in version control: `git update-index --chmod=+x server.sh` - Or in plugin distribution: `chmod +x ${CLAUDE_PLUGIN_ROOT}/bin/*` ## Validation and Errors ### Common Validation Errors **Invalid JSON:** ``` Error: Failed to parse .mcp.json ``` **Solution**: Validate JSON syntax with `jq` or JSON validator **Missing Required Fields:** ``` Error: Missing required field 'command' in stdio server config Error: Missing required field 'url' in http server config ``` **Solution**: Add required fields per schema above **Invalid Variable Expansion:** ``` Error: Environment variable 'API_KEY' is required but not set ``` **Solution**: Set required environment variable or provide default value **Invalid URL:** ``` Error: Invalid URL in http server config ``` **Solution**: Ensure URL is valid HTTP(S) format ### Runtime Errors **Server Won't Start:** - Check command path exists and is executable - Verify all required environment variables are set - Check server logs for startup errors **Connection Failed (HTTP/SSE):** - Verify URL is accessible - Check network/firewall settings - Confirm authentication headers are correct **Server Not Found:** - Ensure plugin is enabled - Restart Claude Code after config changes - Check `/mcp` output for registered servers ## Performance Considerations ### Stdio Servers **Process Overhead:** - Each stdio server is a separate process - Consider resource usage for multiple servers - Use HTTP servers for remote services **Startup Time:** - Servers start on Claude Code launch - Slow-starting servers delay tool availability - Consider lazy initialization for heavy servers ### HTTP/SSE Servers **Network Latency:** - Remote servers add network latency - Use connection pooling where possible - Consider caching for read-heavy operations **Rate Limiting:** - Respect API rate limits - Implement backoff strategies - Cache responses when appropriate ## Security Best Practices ### Credential Management ✅ **Do:** - Store credentials in environment variables - Use `${VAR}` expansion in configs - Document required variables in README - Use secure storage for sensitive values ❌ **Don't:** - Hardcode credentials in JSON - Commit credentials to version control - Share credentials in plugin distributions - Log credential values ### Network Security **HTTPS Only:** ```json { "type": "http", "url": "https://api.example.com/mcp" // ✅ HTTPS } ``` **Avoid HTTP:** ```json { "type": "http", "url": "http://api.example.com/mcp" // ❌ Insecure } ``` **Certificate Validation:** - HTTPS certificates are validated by default - Don't disable certificate validation - Use valid, trusted certificates ### Process Security **Least Privilege:** - Stdio servers run with user's permissions - Don't require elevated privileges - Validate all inputs from MCP protocol **Sandboxing:** - Stdio servers are not sandboxed - Be cautious with user input - Validate/sanitize all data ## Debugging ### Enable Debug Logging Set environment variables before starting Claude Code: ```bash export DEBUG=mcp:* export MCP_LOG_LEVEL=debug claude ``` ### Check Server Status Within Claude Code: ``` /mcp ``` Shows: - Registered servers - Connection status - Available tools/resources ### Test Server Manually **Stdio Server:** ```bash # Test command directly node ${CLAUDE_PLUGIN_ROOT}/servers/my-server.js # With environment API_KEY=test node servers/my-server.js ``` **HTTP Server:** ```bash # Test endpoint curl -H "Authorization: Bearer ${API_TOKEN}" \ https://api.example.com/mcp ``` ### Common Debug Scenarios **Server Not Appearing:** 1. Check plugin is enabled: `/plugin list` 2. Verify config syntax: `cat .mcp.json | jq .` 3. Restart Claude Code 4. Check for error messages on startup **Server Starts But No Tools:** 1. Check server logs for initialization errors 2. Verify server implements MCP protocol correctly 3. Test server manually outside Claude Code 4. Check server responds to `tools/list` request **Environment Variables Not Expanding:** 1. Verify syntax: `${VAR}` not `$VAR` 2. Check variable is set: `echo $VAR` 3. Restart Claude Code after setting variables 4. Check for typos in variable names ## See Also - [Main MCP Configuration Guide](skill.md) - [Real-World Examples](examples.md) - [MCP Protocol Specification](https://modelcontextprotocol.io/) - [Claude Code Plugin Documentation](https://docs.claude.com/en/docs/claude-code/plugins)