mcp-server-mysql

repository·main·Indexed 23 days ago

https://github.com/benborla/mcp-server-mysql

An MCP (Model Context Protocol) server that enables LLMs to interact with MySQL databases (version 5.7+). It supports schema inspection, SQL querying, and optional write operations (INSERT, UPDATE, DELETE). Key features include PII redaction, SSH tunneling, connection pooling, and the ability to run in remote HTTP mode with bearer token authentication.

Tokens
13.5K
Snippets
38
Records
66
Agent score
81%

What's inside mcp-server-mysql

  1. Configure Claude Code MCP Scope

    main

    When adding the MCP server to Claude Code, you can specify the scope to control where the configuration is applied:

    • Local (default): Applies to the current project only.
    • User (-s user): Applies to all your projects.
    • Project (-s project): Shared via a .mcp.json file.

    Security Note: Use local or user scope to keep your database credentials private.

    # Local (default) — current project only
    claude mcp add mcp_server_mysql [options...]
    
    # User — all your projects
    claude mcp add mcp_server_mysql -s user [options...]
    
    # Project — shared via .mcp.json
    claude mcp add mcp_server_mysql -s project [options...]
  2. Understand PII Redaction limitations

    main

    Be aware of the following constraints when using PII redaction:

    • Data Types: Redaction only inspects string values. SSNs or phone numbers stored as BIGINT or INT will not be masked.
    • JSON: Regex-visible PII inside JSON strings is masked, but nested JSON fields (e.g., data->'$.first_name') are not detected via column name heuristics.
    • Formats: International formats (IPv6, non-US E.164 phones, IBANs, EU national IDs) are not currently supported.
    • Bypasses: If PII_ALLOW_REFERENCES is set to true, users can bypass detection using column aliases (e.g., SELECT first_name AS fn).
    • Binary/Dates: Binary/Buffer payloads and Date instances are passed through without inspection.
    • Introspection: SHOW CREATE TABLE and SELECT on information_schema are rejected by default. Use SHOW COLUMNS or the mysql://tables/{name} MCP resource instead.
  3. Enable Multi-Database Mode

    main

    By default, the server connects to a specific database. To enable Multi-Database Mode, omit the MYSQL_DB environment variable. This allows the server to interact with multiple databases on the same host. You can also control write permissions in this mode using MULTI_DB_WRITE_MODE.

    claude mcp add mcp_server_mysql_multi \
      -e MYSQL_HOST="127.0.0.1" \
      -e MYSQL_PORT="3306" \
      -e MYSQL_USER="root" \
      -e MYSQL_PASS="your_password" \
      -e MULTI_DB_WRITE_MODE="false" \
      -- npx @benborla29/mcp-server-mysql
  4. Create SSH tunnel scripts for project database access

    main

    You need two shell scripts in your project root to manage the connection. Each project should use a unique LOCAL_PORT (e.g., 3307, 3308) to avoid conflicts.

    start-tunnel-[project].sh

    This script checks if the port is in use, and if not, creates a background SSH tunnel using ssh -f -N -L.

    stop-tunnel-[project].sh

    This script finds the process ID (PID) listening on the specified LOCAL_PORT and kills it.

    After creating them, make them executable:

    chmod +x start-tunnel-*.sh stop-tunnel-*.sh
    #!/bin/bash
    
    # SSH Tunnel for [PROJECT] project
    LOCAL_PORT=33XX  # Use unique port (3307, 3308, 3309, etc.)
    REMOTE_SERVER="your.server.com"  # Your SSH server
    SSH_PORT=1022  # SSH port (often 1022 or 22)
    SSH_USER="your_ssh_user"  # SSH username
    
    echo "🔗 Starting SSH tunnel for [PROJECT] project..."
    echo "📊 Local port: $LOCAL_PORT"
    echo "🌐 Remote server: $REMOTE_SERVER:$SSH_PORT"
    echo "👤 User: $SSH_USER"
    
    # Check if port is already in use
    if lsof -Pi :$LOCAL_PORT -sTCP:LISTEN -t >/dev/null ; then
        echo "⚠️  Port $LOCAL_PORT already in use - tunnel may already be running"
        exit 0
    fi
    
    # Create the SSH tunnel
    ssh -f -N -L $LOCAL_PORT:localhost:3306 -p $SSH_PORT $SSH_USER@$REMOTE_SERVER
    
    if [ $? -eq 0 ]; then
        sleep 2
        if lsof -Pi :$LOCAL_PORT -sTCP:LISTEN -t >/dev/null ; then
            echo "✅ [PROJECT] SSH tunnel created successfully on port $LOCAL_PORT"
        else
            echo "❌ Tunnel creation failed"
            exit 1
        fi
    else
        echo "❌ Failed to create SSH tunnel"
        exit 1
    fi
  5. Enable Multi-DB Mode

    main

    To enable Multi-DB mode, which allows the server to work with multiple databases simultaneously, leave the MYSQL_DB environment variable empty in your configuration.

    In this mode:

    • The server lists resources from all available databases when schemas are requested.
    • You can query any database the MySQL user has access to.
    • Requirement: You must use fully qualified table names (e.g., database_name.table_name) or use USE database_name; statements to switch contexts.
    • Safety: Multi-DB mode enforces read-only operations by default unless configured otherwise.
    {
      "mcpServers": {
        "mcp_server_mysql": {
          "env": {
            "MYSQL_HOST": "127.0.0.1",
            "MYSQL_PORT": "3306",
            "MYSQL_USER": "root",
            "MYSQL_PASS": "your_password",
            "MYSQL_DB": "", // Empty to enable multi-DB mode
            ...
          }
        }
      }
    }
  6. Set up Remote Mode (HTTP Streamable)

    main

    You can run the MySQL MCP server in remote mode, exposing it via HTTP. This requires a .env file with the following configuration:

    1. IS_REMOTE_MCP=true
    2. REMOTE_SECRET_KEY: A secure string for authentication.
    3. MYSQL_* credentials.
    4. (Optional) PORT: Defaults to 3000.

    Server Startup

    source .env
    npx @benborla29/mcp-server-mysql

    Agent Configuration

    To connect an agent to your remote server, use the streamableHttp type and include the Authorization header with your secret key:

    {
      "mcpServers": {
        "mysql": {
          "url": "http://your-host:3000/mcp",
          "type": "streamableHttp",
          "headers": {
            "Authorization": "Bearer <REMOTE_SECRET_KEY>"
          }
        }
      }
    }
  7. Install @benborla29/mcp-server-mysql for Claude Code

    main

    There are several ways to install the server for Claude Code:

    Option 1: Import from Claude Desktop

    If you have already configured the server in Claude Desktop, run:

    claude mcp add-from-claude-desktop

    Option 2: Manual via NPX (Simplest)

    Use npx to run the server directly without a global installation:

    claude mcp add mcp_server_mysql \
      -e MYSQL_HOST="127.0.0.1" \
      -e MYSQL_PORT="3306" \
      -e MYSQL_USER="root" \
      -e MYSQL_PASS="your_password" \
      -e MYSQL_DB="your_database" \
      -e ALLOW_INSERT_OPERATION="false" \
      -e ALLOW_UPDATE_OPERATION="false" \
      -e ALLOW_DELETE_OPERATION="false" \
      -- npx @benborla29/mcp-server-mysql

    Option 3: Global Install

    Install the package globally first, then add it to Claude Code:

    npm install -g @benborla29/mcp-server-mysql
    # or
    pnpm add -g @benborla29/mcp-server-mysql

    Then run the claude mcp add command using the npx entry point as shown in Option 2.

  8. Configure Claude Code with a Local Repository

    main

    If you are running the server from a local clone of the repository, you must provide the absolute paths to the node binary and the dist/index.js file, along with PATH and NODE_PATH environment variables so the process can find its dependencies.

    To find your paths:

    which node                               # → /path/to/node
    echo "$(which node)/../"                 # → PATH value
    echo "$(which node)/../../lib/node_modules"  # → NODE_PATH value
    claude mcp add mcp_server_mysql \
      -e MYSQL_HOST="127.0.0.1" \
      -e MYSQL_PORT="3306" \
      -e MYSQL_USER="root" \
      -e MYSQL_PASS="your_password" \
      -e MYSQL_DB="your_database" \
      -e ALLOW_INSERT_OPERATION="false" \
      -e ALLOW_UPDATE_OPERATION="false" \
      -e ALLOW_DELETE_OPERATION="false" \
      -e PATH="/path/to/node/bin:/usr/bin:/bin" \
      -e NODE_PATH="/path/to/node/lib/node_modules" \
      -- /path/to/node /full/path/to/mcp-server-mysql/dist/index.js
  9. Set up the test environment for mcp-server-mysql

    main

    To run tests, you must first prepare a dedicated MySQL test database and user, configure the environment variables, and run the setup script.

    1. Prepare MySQL

    Execute the following SQL to create the mcp_test database and a corresponding user with full privileges:

    CREATE DATABASE IF NOT EXISTS mcp_test;
    CREATE USER IF NOT EXISTS 'mcp_test'@'localhost' IDENTIFIED BY 'mcp_test_password';
    GRANT ALL PRIVILEGES ON mcp_test.* TO 'mcp_test'@'localhost';
    FLUSH PRIVILEGES;

    2. Configure Environment

    Create a .env.test file in the project root with the following credentials:

    MYSQL_HOST=127.0.0.1
    MYSQL_PORT=3306
    MYSQL_USER=mcp_test
    MYSQL_PASS=mcp_test_password
    MYSQL_DB=mcp_test

    3. Initialize Setup

    Run the provided setup script to finalize the test database state:

    pnpm run setup:test:db
  10. Install mcp-server-mysql for Claude Desktop or other MCP clients

    main

    For Claude Desktop or other MCP-compatible clients, add the server configuration to your mcpServers JSON configuration file. Use npx to run the package @benborla29/mcp-server-mysql and provide the database connection details in the env object.

    {
      "mcpServers": {
        "mcp_server_mysql": {
          "command": "npx",
          "args": ["-y", "@benborla29/mcp-server-mysql"],
          "env": {
            "MYSQL_HOST": "127.0.0.1",
            "MYSQL_PORT": "3306",
            "MYSQL_USER": "root",
            "MYSQL_PASS": "your_password",
            "MYSQL_DB": "your_database"
          }
        }
      }
    }
  11. Enable PII Redaction

    main

    To enable Personally Identifiable Information (PII) redaction, set the ENABLE_PII_REDACTION environment variable to true. When enabled, the server masks likely PII in read-only query results before returning them to the client.

    Redaction uses a combination of built-in column name detection (e.g., email, ssn, phone, address, api_key) and regex scanning of values (e.g., email addresses, US phone numbers, SSN, IPv4, and Luhn-valid credit card numbers).

    ENABLE_PII_REDACTION=true