AgentStack
MCP verified MIT Self-run

Mcp Sql Server

mcp-ineersa-mcp-sql-server · by ineersa

MySQL MCP server

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add mcp-ineersa-mcp-sql-server

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Mcp Sql Server? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Database MCP Server

A PHP/Symfony Model Context Protocol (MCP) server for executing read-only SQL queries against multiple databases.

Supports: MySQL, MariaDB, PostgreSQL, SQLite, SQL Server


Table of Contents

  • [Quick Start](#quick-start)
  • [Configuration](#configuration)
  • [Environment Variables](#environment-variables)
  • [Database Configuration File](#database-configuration-file)
  • [MCP Client Setup](#mcp-client-setup)
  • [Available Tools](#available-tools)
  • [PII Detection & Redaction](#pii-detection--redaction)
  • [Enabling PII Protection](#enabling-pii-protection)
  • [Model Setup](#model-setup)
  • [Security](#security)
  • [Development](#development)
  • [License](#license)

Quick Start

Using Docker (Recommended)

The Docker image includes all database drivers. Just 3 steps:

1. Download the example configuration:

curl -L https://raw.githubusercontent.com/ineersa/mcp-sql-server/refs/heads/main/docker-compose.example.yaml -o docker-compose.yaml

2. Create your databases.yaml with your database connections:

doctrine:
    dbal:
        connections:
            mydb:
                url: "mysql://user:password@127.0.0.1:3306/mydb"

3. Configure your MCP client (see [MCP Client Setup](#mcp-client-setup))

That's it! Your MCP client will spawn the server automatically.

Without Docker

Requires PHP 8.4+ with database extensions installed:

git clone https://github.com/ineersa/mcp-sql-server.git
cd mcp-sql-server
composer install --no-dev

Configuration

Environment Variables

| Variable | Default | Description | | ---------------------- | ----------------------- | ---------------------------------------------- | | DATABASE_CONFIG_FILE | required | Path to the database configuration YAML file | | APP_ENV | prod | Application environment | | APP_DEBUG | false | Enable debug mode | | LOG_LEVEL | warning | Log level: debug, info, warning, error | | APP_LOG_DIR | /tmp/database-mcp/log | Directory for log files |

Database Configuration File

Database connections are defined in a YAML file (path set via DATABASE_CONFIG_FILE).

Configuration follows Doctrine DBAL standards with DSN and environment variable support.

Example Configuration
doctrine:
    dbal:
        connections:
            # SQLite with explicit path
            local:
                driver: "pdo_sqlite"
                path: "var/test.sqlite"

            # MySQL with URL/DSN format and PII redaction enabled
            products:
                url: "mysql://user:password@127.0.0.1:3306/mydb?serverVersion=8.0&charset=utf8mb4"

            # PostgreSQL with environment variable
            users:
                url: "%env(POSTGRES_DSN)%"

            # SQL Server with explicit parameters and driver options
            analytics:
                driver: "pdo_sqlsrv"
                host: "127.0.0.1"
                port: 1433
                dbname: "analytics"
                user: "sa"
                password: "MyPassword123"
                serverVersion: "2019"
                options:
                    TrustServerCertificate: "yes"
Supported Databases

| Database | Driver | URL Scheme | | ------------- | ------------ | ------------------------- | | MySQL/MariaDB | pdo_mysql | mysql://, mysql2:// | | PostgreSQL | pdo_pgsql | postgres://, pgsql:// | | SQLite | pdo_sqlite | sqlite:// | | SQL Server | pdo_sqlsrv | sqlsrv://, mssql:// |


MCP Client Setup

Add this to your MCP client's configuration (e.g., mcp.json or Claude Desktop settings).

Docker Compose (Recommended)

{
    "database": {
        "command": "docker",
        "args": [
            "compose",
            "-f",
            "/path/to/docker-compose.yaml",
            "run",
            "--rm",
            "database-mcp"
        ]
    }
}

Opencode

{
    "mcp": {
        "database": {
            "type": "local",
            "command": [
                "docker",
                "compose",
                "-f",
                "/path/to/docker-compose.yaml",
                "run",
                "--rm",
                "database-mcp"
            ],
            "enabled": true
        }
    }
}

Local Installation

{
    "database": {
        "command": "/path/to/bin/database-mcp",
        "args": [],
        "env": {
            "DATABASE_CONFIG_FILE": "/path/to/databases.yaml",
            "LOG_LEVEL": "info",
            "APP_LOG_DIR": "/tmp/database-mcp/log"
        }
    }
}

Testing Your Setup

Verify your configuration works:

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | \
docker compose run --rm database-mcp

You should see a JSON response with server capabilities.

Viewing Logs

# View recent logs
docker compose run --rm logs

# View a specific log entry by line number
docker compose run --rm logs --id=42

# View more entries
docker compose run --rm logs --limit=100

Updating

docker compose pull

Available Tools

Response format (all tools below):

  • TOON text payload: Results are returned as TOON-encoded data in content[].text

query

Executes read-only SQL queries against a specified database connection.

Before querying information_schema/system catalogs for metadata or object definitions, prefer the schema tool with detail: "full" and relevant include flags.

Parameters:

| Parameter | Type | Required | Description | | ------------ | ------ | -------- | --------------------------------------------------------------- | | connection | string | Yes | Name of the database connection to use | | query | string | Yes | SQL query to execute (semicolon-separated for multiple queries) |

Example:

{
    "name": "query",
    "arguments": {
        "connection": "production",
        "query": "SELECT id, name, email FROM users LIMIT 10"
    }
}

schema

Inspects database schema metadata for a specified connection.

Use detail: "full" + includeRoutines: true + includeViews: true as the default for trigger/function/procedure/view definitions. Prefer this over raw catalog queries.

Parameters:

| Parameter | Type | Required | Description | | ----------------- | ------- | -------- | ------------------------------------------------------------------------------------------------ | | connection | string | Yes | Name of the database connection to inspect | | filter | string | No | Optional object-name filter ("" for all) | | detail | string | No | Detail level: summary (default), columns, or full | | matchMode | string | No | Filter matching mode: contains (default), prefix, exact, or glob | | includeViews | boolean | No | Include views in output | | includeRoutines | boolean | No | Include routines/triggers in output |

matchMode: "exact" matches by logical object name across quote and schema variants. For example, these are treated equivalently for exact matching:

  • active_users
  • "active_users"
  • public.active_users
  • "public"."active_users"
  • ` activeusers / [activeusers]`

When detail is full, view/trigger/routine definitions are included in the response.

Object coverage in full detail:

  • Tables: columns, indexes, foreign keys, check constraints, triggers (with trigger definitions)
  • Views: SQL definition (when includeViews is true)
  • Routines: function/procedure definitions (when includeRoutines is true)

For columns and full, use a narrow filter whenever possible. Large payloads are rejected with ToolUsageError.

If matchMode is exact, filter is non-empty, and no object matches, the response includes diagnostics with normalized names and near matches:

  • diagnostics.status (no_exact_match)
  • diagnostics.normalized_filter
  • diagnostics.normalized_names_tried
  • diagnostics.top_near_matches

Example:

{
    "name": "schema",
    "arguments": {
        "connection": "production",
        "filter": "users",
        "detail": "columns",
        "matchMode": "contains",
        "includeViews": false,
        "includeRoutines": false
    }
}

PII Detection & Redaction

This server includes built-in PII (Personally Identifiable Information) detection and redaction using GLiNER models in ONNX format via the native gliner-rs-php extension.

1. Download Models

The server supports any GLiNER model in ONNX format. While any compatible model can be used, we recommend and provide a helper for our tested GLiNER PII ONNX model (~1.8GB).

Using Docker (Recommended):

docker compose run --rm download-models

Using PHP:

php bin/console download-models

This downloads model.onnx and tokenizer.json to your local ./models directory.

2. Enable on Specific Connections

PII redaction is configured per-connection in your databases.yaml. When enabled, query results are automatically scanned and sensitive data is replaced with [REDACTED_type] markers (e.g., [REDACTED_email], [REDACTED_ssn]).

doctrine:
    dbal:
        connections:
            production:
                url: "mysql://..."
                pii_enabled: true # Redact PII in query results
            development:
                url: "mysql://..."
                # pii_enabled defaults to false

3. Optionally Customize PII Settings

You can fine-tune the detection threshold and entity types in your databases.yaml:

pii:
    threshold: 0.6 # Confidence threshold (0.0-1.0)
    # Note: Default is 0.6. For higher recall (especially on dates), you can lower this to e.g. 0.2.

    # Optional: Custom model paths (defaults to models/ in project root)
    # tokenizer_path: "models/tokenizer.json"
    # model_path: "models/model.onnx"

    # Optional: Limit detection to specific entity types for better performance
    labels:
        - email
        - phone_number
        - credit_debit_card
        - ssn

View all 64 supported PII labels

labels:
    # Personal
    # - first_name
    # - last_name
    # - name
    # - date_of_birth
    # - age
    # - gender
    # - sexuality
    # - race_ethnicity
    # - religious_belief
    # - political_view
    # - occupation
    # - employment_status
    # - education_level

    # Contact
    - email
    - phone_number
    # - street_address
    # - city
    # - county
    # - state
    # - country
    # - coordinate
    # - zip_code
    # - po_box

    # Financial
    - credit_debit_card
    # - cvv
    # - bank_routing_number
    # - account_number
    # - iban
    # - swift_bic
    # - pin
    - ssn
    # - tax_id
    # - ein

    # Government
    # - passport_number
    # - driver_license
    # - license_plate
    # - national_id
    # - voter_id

    # Digital/Technical
    # - ipv4
    # - ipv6
    # - mac_address
    # - url
    # - user_name
    # - password
    # - device_identifier
    # - imei
    # - serial_number
    # - api_key
    # - secret_key

    # Healthcare/PHI
    # - medical_record_number
    # - health_plan_beneficiary_number
    # - blood_type
    # - biometric_identifier
    # - health_condition
    # - medication
    # - insurance_policy_number

    # Temporal
    # - date
    # - time
    # - date_time

    # Organization
    # - company_name
    # - employee_id
    # - customer_id
    # - certificate_license_number
    # - vehicle_identifier

Manual Extension Installation (non-Docker):

Install the gliner-rs-php extension:

curl -fsSL -o gliner.tar.gz \
    https://github.com/ineersa/gliner-rs-php/releases/download/0.0.6/gliner-rs-php-0.0.6-linux-x86_64.tar.gz
tar -xzf gliner.tar.gz
cp libgliner_rs_php.so /usr/local/lib/php/extensions/
echo "extension=/usr/local/lib/php/extensions/libgliner_rs_php.so" > /usr/local/etc/php/conf.d/gliner.ini

Security

Read-Only Enforcement

This server enforces read-only mode through multiple layers:

  1. SQL Keyword Validation — Blocks forbidden keywords (INSERT, UPDATE, DELETE, DROP, CREATE, ALTER, TRUNCATE, etc.) before execution
  2. Platform SET Commands — Database-level read-only enforcement:
  • MySQL/MariaDB: SET SESSION transaction_read_only = 1
  • PostgreSQL: SET default_transaction_read_only = on
  • SQLite: PRAGMA query_only = ON
  • SQL Server: ApplicationIntent=ReadOnly
  1. Sandboxed Execution — All queries run in a transaction that is always rolled back

> Best Practice: Always use a database user with read-only permissions for additional security.

SQL Server Note

ApplicationIntent=ReadOnly only works for Always On Availability Groups and Azure SQL Database. For standalone instances, configure a read-only database user.


Development

Setup

git clone https://github.com/ineersa/mcp-sql-server.git
cd mcp-sql-server
composer install

Testing with MCP Inspector

npx @modelcontextprotocol/inspector ./bin/database-mcp

Code Quality

composer cs-fix    # Fix code style
composer phpstan   # Static analysis
composer tests     # Run tests

Building Docker Image

composer docker-build     # Build the image
composer docker-rebuild   # Rebuild without cache

Project Structure

src/
├── Command/        # Symfony console commands
├── Enum/           # PII entity types and groups
├── ReadOnly/       # DBAL middleware for read-only enforcement
├── Service/        # Core services (including PIIAnalyzerService)
└── Tools/          # MCP tool implementations
stubs/              # PHP extension stubs for IDE support
tests/              # PHPUnit test suites
config/             # Symfony configuration

License

MIT License — see [LICENSE](LICENSE) for details.

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.