mcp-safe-run
Tired of hardcoding secrets like API keys in your MCP client configuration (e.g., mcp.json, claude_desktop_config.json)? mcp-secure-launcher lets you run your existing MCP servers securely without modifying them.
GitHub Stars
11
User Rating
Not Rated
Favorites
0
Views
12
Forks
1
Issues
0
mcp-safe-run
Secure, zero-leak secrets for IDE-integrated MCP servers in under a minute.
mcp-safe-run lets you launch Model Context Protocol (MCP) servers for AI-powered IDEs (like Cursor, Windsurf, or Claude Desktop) using secrets that are never exposed in your shell, process list, or version control. Store secrets persistently in your OS keychain or a hidden file, reference them safely in your IDE config, and launch servers with a single click—no more copy-pasting tokens or risking accidental leaks.
Quick Start
- Install:
npm install -g mcp-safe-run - Create a secrets directory:
mkdir -p ./secrets echo "/secrets/*" >> .gitignore - Add your secret:
echo "ghp_...TOKEN..." > ./secrets/github_token.txt chmod 600 ./secrets/github_token.txt - Configure your IDE: Add the following to your IDE's MCP server settings (e.g.,
mcp_settings.json):{ "mcpServers": { "github": { "command": "mcp-safe-run", "args": [ "--target-env", "{\"GITHUB_TOKEN\": \"file:./secrets/github_token.txt\"}", "--", "npx", "-y", "@modelcontextprotocol/server-github" ], "env": {} } } } - Launch the server from your IDE.
Setup for IDEs (Cursor, Windsurf, Claude Desktop)
To use this project with an IDE that supports Model Context Protocol (like Cursor, Windsurf, or Claude Desktop), add an mcpServers section to your settings (such as mcp_settings.json). This enables the IDE to launch the MCP server with secure environment resolution.
Example configuration:
{
"mcpServers": {
"github": {
"command": "mcp-safe-run",
"args": [
"--target-env",
"{\"GITHUB_TOKEN\": \"keyring:mcp-github:personal-pat\"}",
"--",
"npx",
"-y",
"@modelcontextprotocol/server-github"
],
"env": {}
}
}
}
Setting Up Secrets for IDE Integration
Option 1: Using a Key File (file:)
- Create a hidden directory for your secrets (if it doesn't exist):
mkdir -p ./secrets - Add a
.gitignorerule to keep secrets out of version control:# .gitignore /secrets/* - Create your secret file, e.g.
./secrets/github_token.txt, and paste your token or secret value inside. - Secure the file so only your user can read it:
chmod 600 ./secrets/github_token.txt - In your configuration, use a
file:placeholder, e.g.:{ "GITHUB_TOKEN": "file:./secrets/github_token.txt" }
Option 2: Using the OS Keychain (keyring:) on macOS
- Open the Keychain Access app (Applications > Utilities > Keychain Access).
- Click the
+button to add a new password item. - Set the Keychain Item Name (service) and Account Name (account) to match your placeholder, for example:
- Service:
mcp-github - Account:
personal-pat
- Service:
- Paste your secret/token into the "Password" field and save.
- Alternatively, you can use the
keytarNode.js CLI or API to add secrets programmatically:// Example using keytar in Node.js const keytar = require('keytar'); keytar.setPassword('mcp-github', 'personal-pat', 'ghp_...your_token...'); - In your configuration, use a
keyring:placeholder, e.g.:{ "GITHUB_TOKEN": "keyring:mcp-github:personal-pat" }
Notes:
- The
GITHUB_TOKENwill be securely resolved from your OS keychain using thekeyring:placeholder. - You may need to add the secret to your keychain using a tool like
keytaror your OS's secret manager. - This pattern works for any MCP server; just adjust the command and arguments as needed for your use case.
- In these IDEs,
env:placeholders are generally not supported (the IDE does not pass your shell environment), so preferkeyring:orfile:placeholders.
Installation
npm install -g mcp-safe-run
Note: This CLI uses keytar for OS keychain support. On macOS, install Xcode Command Line Tools. On Linux, install
libsecret-1-devandbuild-essential(or equivalent build tools). On Windows, install Visual Studio Build Tools (npm install --global --production windows-build-tools).
Usage
mcp-safe-run [options] <targetCommand> [targetArgs...]
Options
-V, --versionOutput the current version.-c, --config <path>Path to a custom configuration file (.yaml or .yml).-p, --profile <name>Name of the profile to use from the configuration file.--target-env <jsonString>JSON mapping of target environment variables. Overrides config file profile settings.-v, --verboseEnable verbose logging (outputs diagnostic details).-h, --helpDisplay help information.
Placeholder Syntax
Placeholders can be used within the --target-env JSON string or in the target-env section of a configuration file profile.
env:VAR_NAMEUse the value of environment variableVAR_NAME.file:/path/to/fileRead and trim the contents of the specified file (supports~for home directory).keyring:service:accountRetrieve a secret from the OS keychain using the specifiedserviceandaccount.- Literal values Any other string is passed through unchanged.
Configuration File
For managing multiple configurations, you can use a YAML configuration file (e.g., .mcp-saferun.yaml or .mcp-saferun.yml). This is particularly useful when you need to switch between different sets of environment variables frequently, such as for different deployment environments (dev, staging, production) or distinct operational contexts.
Note on Usage Context: For simpler scenarios, like configuring a single MCP server within an IDE integration (e.g., via mcp.json), using the --target-env flag directly might be more straightforward than managing a separate configuration file. The primary benefit of configuration files comes when managing multiple distinct configurations (profiles) for the same target command.
Search Order:
- Path specified by
-c, --config <path>. .mcp-saferun.yamlor.mcp-saferun.ymlin the current working directory.config.yamlorconfig.ymlinside~/.config/mcp-safe-run/(the directory is created if it doesn't exist).
Format:
# Example .mcp-saferun.yaml
profiles:
# Profile name (used with -p dev)
dev:
target-env:
API_KEY: "env:DEV_API_KEY"
SECRET: "keyring:my-service:dev-user"
DB_URL: "postgresql://localhost/dev_db"
staging:
target-env:
API_KEY: "file:./staging-key.txt"
SECRET: "keyring:my-service:staging-user"
DB_URL: "env:STAGING_DB_URL"
# Global settings can be added here if needed in the future
# global:
# setting: value
Precedence:
- Environment variables provided via
--target-env(highest precedence). - Environment variables defined in the selected profile (
-p <name>) from the configuration file. - Environment variables inherited from the shell where
mcp-safe-runis executed (lowest precedence).
Examples
Using
--target-env(CLI only):export GH_TOKEN_FOR_MCP=ghp_...TOKEN... mcp-safe-run --target-env '{"GITHUB_TOKEN":"env:GH_TOKEN_FOR_MCP", "OTHER_VAR":"literal_value"}' \ npx -y @modelcontextprotocol/server-github --port 8080Using a Config File Profile:
Create
.mcp-saferun.yamlin your project:profiles: github_server: target-env: GITHUB_TOKEN: "keyring:mcp:github" PORT: "8080"Run using the profile:
# Make sure the keychain entry exists: # keytar set mcp github ghp_...TOKEN... mcp-safe-run -p github_server npx -y @modelcontextprotocol/server-github # The target command will receive GITHUB_TOKEN and PORT in its environmentUsing a Specific Config File:
mcp-safe-run -c ~/configs/mcp-servers.yaml -p prod_server node my_server.jsOverriding a Config Profile with
--target-env:Assume
.mcp-saferun.yamlexists with thegithub_serverprofile from example 2.# Temporarily override the PORT defined in the profile mcp-safe-run -p github_server --target-env '{"PORT":"9000"}' \ npx -y @modelcontextprotocol/server-github # GITHUB_TOKEN comes from the profile (keyring), but PORT is set to 9000 by the CLI flag.Verbose Mode:
mcp-safe-run -v -p github_server npx -y @modelcontextprotocol/server-github # Shows config loading, resolved values (if verbose), final environment, etc.
Troubleshooting
Config File Not Found: Check search paths and file names (
.mcp-saferun.yaml/.yml). Ensure correct path with-c. Check permissions.Profile Not Found: Verify the profile name used with
-pexists in the loaded config file.YAML Errors: Ensure the config file is valid YAML. Use an online validator if unsure.
Placeholder Errors: (
env:,file:,keyring:)env:: Check if the environment variable is actually set (echo $VAR_NAME).file:: Check file path (including~expansion), permissions (ls -l), and content (cat).keyring:: Verify the secret exists in the OS keychain (use OS tools orkeytarCLI if installed). Ensurekeytarprerequisites are met.
keytarBuild/Runtime Issues: Check platform notes below and ensure necessary build tools/libraries are installed.Invalid JSON (
--target-env): Ensure proper quoting, especially when used in a shell.Unsupported Placeholder (
env:) in Some Clients (Cursor, Windsurf, Claude Desktop): These environments don't pass shell environment variables tomcp-safe-run, soenv:placeholders won't resolve.file:andkeyring:placeholders still work. For example:mcp-safe-run --target-env '{"API_KEY":"file:./api_key.txt","SECRET":"keyring:my-service:account","DB_URL":"file:./db_url.txt"}' <targetCommand> [args...]
Platform Notes
- macOS: Requires Xcode Command Line Tools.
- Linux: Requires
libsecret-1-devand build tools likebuild-essential. - Windows: Requires Visual Studio Build Tools (can be installed via
npm install --global --production windows-build-tools).
Setup for IDEs (Cursor, Windsurf, Claude Desktop)
To use this project with an IDE that supports Model Context Protocol (like Cursor, Windsurf, or Claude Desktop), add an mcpServers section to your settings (such as mcp_settings.json). This enables the IDE to launch the MCP server with secure environment resolution.
Example configuration:
{
"mcpServers": {
"github": {
"command": "mcp-safe-run",
"args": [
"--target-env",
"{\"GITHUB_TOKEN\": \"keyring:mcp-github:personal-pat\"}",
"--",
"npx",
"-y",
"@modelcontextprotocol/server-github"
],
"env": {}
}
}
}
Setting Up Secrets for IDE Integration
Option 1: Using a Key File (file:)
- Create a hidden directory for your secrets (if it doesn't exist):
mkdir -p ./secrets - Add a
.gitignorerule to keep secrets out of version control:# .gitignore /secrets/* - Create your secret file, e.g.
./secrets/github_token.txt, and paste your token or secret value inside. - Secure the file so only your user can read it:
chmod 600 ./secrets/github_token.txt - In your configuration, use a
file:placeholder, e.g.:{ "GITHUB_TOKEN": "file:./secrets/github_token.txt" }
Option 2: Using the OS Keychain (keyring:) on macOS
- Open the Keychain Access app (Applications > Utilities > Keychain Access).
- Click the
+button to add a new password item. - Set the Keychain Item Name (service) and Account Name (account) to match your placeholder, for example:
- Service:
mcp-github - Account:
personal-pat
- Service:
- Paste your secret/token into the "Password" field and save.
- Alternatively, you can use the
keytarNode.js CLI or API to add secrets programmatically:// Example using keytar in Node.js const keytar = require('keytar'); keytar.setPassword('mcp-github', 'personal-pat', 'ghp_...your_token...'); - In your configuration, use a
keyring:placeholder, e.g.:{ "GITHUB_TOKEN": "keyring:mcp-github:personal-pat" }
Notes:
- The
GITHUB_TOKENwill be securely resolved from your OS keychain using thekeyring:placeholder. - You may need to add the secret to your keychain using a tool like
keytaror your OS's secret manager. - This pattern works for any MCP server; just adjust the command and arguments as needed for your use case.
- In these IDEs,
env:placeholders are generally not supported (the IDE does not pass your shell environment), so preferkeyring:orfile:placeholders.