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

README
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
  1. Install:
    npm install -g mcp-safe-run
    
  2. Create a secrets directory:
    mkdir -p ./secrets
    echo "/secrets/*" >> .gitignore
    
  3. Add your secret:
    echo "ghp_...TOKEN..." > ./secrets/github_token.txt
    chmod 600 ./secrets/github_token.txt
    
  4. 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": {}
        }
      }
    }
    
  5. 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:)
  1. Create a hidden directory for your secrets (if it doesn't exist):
    mkdir -p ./secrets
    
  2. Add a .gitignore rule to keep secrets out of version control:
    # .gitignore
    /secrets/*
    
  3. Create your secret file, e.g. ./secrets/github_token.txt, and paste your token or secret value inside.
  4. Secure the file so only your user can read it:
    chmod 600 ./secrets/github_token.txt
    
  5. 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
  1. Open the Keychain Access app (Applications > Utilities > Keychain Access).
  2. Click the + button to add a new password item.
  3. Set the Keychain Item Name (service) and Account Name (account) to match your placeholder, for example:
    • Service: mcp-github
    • Account: personal-pat
  4. Paste your secret/token into the "Password" field and save.
  5. Alternatively, you can use the keytar Node.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...');
    
  6. In your configuration, use a keyring: placeholder, e.g.:
    { "GITHUB_TOKEN": "keyring:mcp-github:personal-pat" }
    
Notes:
  • The GITHUB_TOKEN will be securely resolved from your OS keychain using the keyring: placeholder.
  • You may need to add the secret to your keychain using a tool like keytar or 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 prefer keyring: or file: 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-dev and build-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, --version Output 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, --verbose Enable verbose logging (outputs diagnostic details).
  • -h, --help Display 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_NAME Use the value of environment variable VAR_NAME.
  • file:/path/to/file Read and trim the contents of the specified file (supports ~ for home directory).
  • keyring:service:account Retrieve a secret from the OS keychain using the specified service and account.
  • 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:

  1. Path specified by -c, --config <path>.
  2. .mcp-saferun.yaml or .mcp-saferun.yml in the current working directory.
  3. config.yaml or config.yml inside ~/.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:

  1. Environment variables provided via --target-env (highest precedence).
  2. Environment variables defined in the selected profile (-p <name>) from the configuration file.
  3. Environment variables inherited from the shell where mcp-safe-run is executed (lowest precedence).
Examples
  1. 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 8080
    
  2. Using a Config File Profile:

    Create .mcp-saferun.yaml in 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 environment
    
  3. Using a Specific Config File:

    mcp-safe-run -c ~/configs/mcp-servers.yaml -p prod_server node my_server.js
    
  4. Overriding a Config Profile with --target-env:

    Assume .mcp-saferun.yaml exists with the github_server profile 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.
    
  5. 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 -p exists 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 or keytar CLI if installed). Ensure keytar prerequisites are met.
  • keytar Build/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 to mcp-safe-run, so env: placeholders won't resolve. file: and keyring: 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-dev and build tools like build-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:)
  1. Create a hidden directory for your secrets (if it doesn't exist):
    mkdir -p ./secrets
    
  2. Add a .gitignore rule to keep secrets out of version control:
    # .gitignore
    /secrets/*
    
  3. Create your secret file, e.g. ./secrets/github_token.txt, and paste your token or secret value inside.
  4. Secure the file so only your user can read it:
    chmod 600 ./secrets/github_token.txt
    
  5. 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
  1. Open the Keychain Access app (Applications > Utilities > Keychain Access).
  2. Click the + button to add a new password item.
  3. Set the Keychain Item Name (service) and Account Name (account) to match your placeholder, for example:
    • Service: mcp-github
    • Account: personal-pat
  4. Paste your secret/token into the "Password" field and save.
  5. Alternatively, you can use the keytar Node.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...');
    
  6. In your configuration, use a keyring: placeholder, e.g.:
    { "GITHUB_TOKEN": "keyring:mcp-github:personal-pat" }
    
Notes:
  • The GITHUB_TOKEN will be securely resolved from your OS keychain using the keyring: placeholder.
  • You may need to add the secret to your keychain using a tool like keytar or 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 prefer keyring: or file: placeholders.