Skip to main content
Glama
akrym1582

sqldb-mcp-server

by akrym1582

sqldb-mcp-server

A read-only Model Context Protocol (MCP) server that exposes SQL database access to LLMs.

Features

  • Multi-database – supports MSSQL, PostgreSQL, and MySQL

  • Read-only – only SELECT statements are allowed (enforced via AST-level SQL parsing with the correct dialect per DB type)

  • LLM-optimised – results use a compact columnar format (column list + value rows) to reduce token usage

  • Paginationskip / take parameters with automatic cap at 100 rows

  • Total-count aware – every query result includes meta.totalCount so the LLM knows how many rows exist

  • Caching – query / schema results are cached with a configurable TTL

  • File export – stream query results to CSV or JSON files without a row-count limit

  • Markdown evidence export – save SQL and query results as a Markdown report file for test evidence

  • Six MCP tools: query, listTables, describeTable, explainQuery, exportQuery, saveQueryEvidence

Related MCP server: sqlite-mcp-server

Installation

# Install globally
npm install -g @akrym1582/sqldb-mcp-server

# Or run directly with npx (no install needed)
npx @akrym1582/sqldb-mcp-server

From source

git clone https://github.com/akrym1582/sqldb-mcp-server.git
cd sqldb-mcp-server
npm install
npm run build

Quick Start

# 1. Install globally
npm install -g @akrym1582/sqldb-mcp-server

# 2. Configure environment variables (see below)
export DB_TYPE=postgresql
export DB_HOST=localhost
export DB_USER=myuser
export DB_PASSWORD=mypassword
export DB_NAME=mydb

# 3. Run
sqldb-mcp-server

Or use in your MCP client configuration (e.g. Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "sqldb": {
      "command": "npx",
      "args": ["-y", "@akrym1582/sqldb-mcp-server"],
      "env": {
        "DB_TYPE": "postgresql",
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_USER": "myuser",
        "DB_PASSWORD": "mypassword",
        "DB_NAME": "mydb"
      }
    }
  }
}

Environment Variables

Variable

Default

Description

DB_TYPE

mssql

Database type: mssql, postgresql, or mysql

DB_HOST

Database server hostname

DB_PORT

1433 / 5432 / 3306

Database server port (default depends on DB_TYPE)

DB_USER

Database username

DB_PASSWORD

Database password

DB_NAME

Database name

DB_ENCRYPT

true for MSSQL/PostgreSQL, false for MySQL

Enables encrypted DB connections. MSSQL trusts the server certificate. PostgreSQL tries SSL first and falls back to plain if SSL is unavailable. MySQL uses TLS with certificate verification disabled when enabled.

DB_QUERY_TIMEOUT

30000

Query timeout in milliseconds (used by query / explainQuery)

EXPORT_QUERY_TIMEOUT

300000

Export query timeout in milliseconds (used by exportQuery; default 5 min)

CACHE_TTL

60

Cache TTL in seconds

Default ports by DB type

DB_TYPE

Default DB_PORT

mssql

1433

postgresql

5432

mysql

3306

MCP Tools

query

Execute a SELECT SQL statement.

{
  "sql": "SELECT id, name FROM users WHERE active = 1",
  "skip": 0,
  "take": 10
}

Response format (compact / token-efficient):

{
  "meta": { "totalCount": 42, "returnedCount": 10, "skip": 0, "take": 10 },
  "columns": ["id", "name"],
  "rows": [[1, "Alice"], [2, "Bob"], ...]
}

listTables

List all base tables in the database.

[{ "schema": "dbo", "name": "users" }, ...]

describeTable

Describe a table's columns, indexes, foreign keys, check constraints, and size statistics.

{ "table": "dbo.users" }

explainQuery

Return the estimated execution plan for a SELECT query without executing it.

{ "sql": "SELECT * FROM orders WHERE status = 'open'" }

exportQuery

Stream a SELECT query result to a file. Designed for large datasets – there is no row-count limit and results are written directly to disk using Node.js streams.

{
  "sql": "SELECT * FROM large_table",
  "filepath": "/tmp/export.csv",
  "format": "csv",
  "options": { "delimiter": ",", "bom": false }
}

format defaults to "csv" if omitted. "json" is also supported.

CSV options (all optional):

Option

Default

Description

delimiter

","

Column separator

nullValue

""

String to write for NULL / undefined cells

bom

false

Prepend UTF-8 BOM (useful for Excel)

JSON options (all optional):

Option

Default

Description

pretty

false

Indent the output JSON

Response format:

{
  "filepath": "/tmp/export.csv",
  "format": "csv",
  "rowCount": 50000
}

The tool uses a separate, longer-lived connection pool whose requestTimeout is controlled by EXPORT_QUERY_TIMEOUT (default 300 000 ms = 5 min). Increase this value for very large exports.

saveQueryEvidence

Execute a SELECT query and save the SQL plus the returned rows as a Markdown report file for test evidence.

{
  "sql": "SELECT id, name FROM users LIMIT 10",
  "filepath": "/tmp/query-evidence.md"
}

Response format:

{
  "filepath": "/tmp/query-evidence.md",
  "rowCount": 10,
  "previewRows": [
    { "id": 1, "name": "Alice" },
    { "id": 2, "name": "Bob" }
  ]
}

If an error occurs, the tool returns the error message text instead of a success payload.

Development

# Clone the repository
git clone https://github.com/akrym1582/sqldb-mcp-server.git
cd sqldb-mcp-server

# Install dependencies
npm install

# Configure environment
cp .env.example .env
# Edit .env with your DB credentials

# Run in dev mode (no compile step)
npm run dev

# Or build and run
npm run build
npm start

# Run unit tests
npm test

Project Structure

src/
  mcp/
    server.ts           # MCP server entry point
    tools/
      query.ts          # query tool
      listTables.ts     # listTables tool
      describeTable.ts  # describeTable tool
      explainQuery.ts   # explainQuery tool
      exportQuery.ts    # exportQuery tool (streaming file export)
  db/
    index.ts            # DB adapter factory (selects adapter from DB_TYPE)
    types.ts            # DB interfaces (including queryStream)
    adapters/
      mssql.ts          # Microsoft SQL Server implementation
      postgresql.ts     # PostgreSQL implementation (pg + pg-cursor)
      mysql.ts          # MySQL implementation (mysql2)
  utils/
    row-result.ts       # Compact columnar result format
    sanitize.ts         # AST-based SQL read-only validation (dialect-aware)
    pagination.ts       # skip/take normalisation
    cache.ts            # TTL in-memory cache
    export-writer.ts    # Streaming CSV / JSON file writer
  __tests__/            # Unit tests

Available Tools

6 tools
describeTableA

Describe a table: returns columns (name, type, nullability, primary key, identity), indexes, foreign keys, check constraints, and table-level size/row-count statistics.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYesTable name to describe. Optionally prefix with schema: 'schema.table'

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must convey behavioral traits. It details the returned information (columns, indexes, foreign keys, etc.) and implies a read-only operation. Though it does not explicitly state side effects or permissions, the nature of 'describe' suggests no mutation. The transparency is good but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that efficiently lists the key outputs. No superfluous words, and the information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a single required parameter, no output schema, and no annotations, the description fairly completely covers what the tool returns. However, it does not mention any potential limitations (e.g., size constraints, rate limits) or ensure the agent knows the output format. Still, it is sufficient for the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one parameter 'table' with a description; the tool description adds 'Optionally prefix with schema: 'schema.table'' which provides additional context on how to specify table names. Schema coverage is 100%, so the description adds meaningful extra guidance beyond the schema field description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states 'Describe a table: returns columns (name, type, nullability, primary key, identity), indexes, foreign keys, check constraints, and table-level size/row-count statistics.' This clearly identifies the action (describe) and the resource (table), and distinguishes it from sibling tools like query (executing queries) and listTables (listing tables).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit usage guidelines or comparisons to alternatives are provided. The description implies this tool is for retrieving table schema, but it does not state when to use it versus siblings like listTables or query. A 3 is appropriate because the purpose is clear, but the description lacks explicit guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explainQueryA

Return the estimated execution plan for a SELECT SQL query without actually executing it. The response format depends on the database engine (e.g. MSSQL, PostgreSQL, MySQL) and is returned as-is from the database driver.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesSELECT SQL statement whose execution plan should be retrieved

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, description discloses engine-dependent output format and non-execution behavior. Could add that non-SELECT statements may fail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose, no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given single parameter, no output schema, and sibling context, description covers purpose, constraints, and output behavior completely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already has 100% coverage with a clear description. Description reinforces that it must be SELECT and returns plan without execution, adding value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns the estimated execution plan for a SELECT SQL query without execution, distinguishing it from sibling tools like `query` (executes) and `describeTable` (describes structure).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Mentions it's for SELECT queries and does not execute, implying planning context. However, lacks explicit when-not or alternatives like `query` for execution.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exportQueryA

Execute a read-only SELECT SQL query and stream the results to a file. Supports CSV and JSON output formats. Designed for large datasets – results are streamed directly to disk without a row-count limit. CSV options: delimiter (default ','), nullValue (default ''), bom (default false). JSON options: pretty (default false). Timeout is controlled by the EXPORT_QUERY_TIMEOUT environment variable (default: 300 s).

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesSELECT SQL statement whose results should be exported
formatNoOutput format. "csv" (default) or "json"
optionsNoFormat-specific options. CSV: delimiter (default ","), nullValue (default ""), bom (default false). JSON: pretty (default false). Additional keys are accepted for forward compatibility.
filepathYesDestination file path (absolute, or relative to the server working directory)

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behavioral traits: read-only (SELECT only), streaming to file, no row-count limit, timeout controlled by environment variable, and format-specific options with defaults. This is comprehensive for a data export tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences, front-loaded with the primary action. It is efficient but could be slightly more compact; however, no extraneous information is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers input parameters and behavior (streaming, timeout) but lacks details on error handling, file overwrite behavior, or permission requirements. For a tool with no output schema, this is fairly complete given its complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds significant meaning: default values for CSV/JSON options, accepted keys, and timeout env variable. It explains formatting details beyond the schema's basic descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it executes a read-only SELECT query and streams results to a file, supporting CSV and JSON formats. This distinguishes it from sibling tools like query (returns results inline) and saveQueryEvidence (likely saves query evidence rather than results).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description specifies it is designed for large datasets and streams to disk without row-count limit. It implicitly suggests use for exporting large result sets, but does not explicitly mention when not to use or alternatives like query for interactive results.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listTablesA

List all base tables in the database, returning their schema and name.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the burden. It does not explicitly state that the operation is read-only or disclose any behavioral traits like authentication needs or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence of 13 words, highly concise and front-loaded with the action verb 'List'. No filler or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with no parameters, the description is adequate but lacks detail on the output format. It mentions 'schema and name' but could be clearer about what 'schema' entails. With no output schema, more context would help.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description adds no parameter info, which is acceptable given no parameters exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List', the resource 'base tables', and the scope 'all'. It also specifies the return content 'schema and name', distinguishing it from siblings like describeTable which targets a specific table.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives such as describeTable. The description only states what it does without contextualizing when it is appropriate or not.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryA

Execute a read-only SELECT SQL query. Returns results in a compact column/row format to reduce token usage. Results are capped at 100 rows; use skip/take for pagination. The meta.totalCount field shows the total number of matching rows.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesSELECT SQL statement to execute
skipNoNumber of rows to skip (offset)
takeNoMaximum rows to return (max 100)

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully covers behavioral traits: read-only safety, compact column/row format to reduce token usage, 100-row cap, skip/take pagination, and meta.totalCount field. This is comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each earning its place: action+format, rationale, limit+pagination, metadata. No unnecessary words, front-loaded with core information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a SQL query tool with full schema coverage and no output schema, the description explains output format, pagination, limits, and metadata. Missing details on error handling or exact column presentation, but adequate for typical use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema describes all 3 parameters fully. The description adds value by explaining the compact format and pagination pattern, reinforcing the purpose of skip/take. Exceeds the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Execute a read-only SELECT SQL query', providing a specific verb and resource. It distinguishes from sibling tools like describeTable and exportQuery by focusing on executing queries, not describing or exporting.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for read-only queries and mentions pagination with skip/take, but does not explicitly compare to siblings like exportQuery or explainQuery. No when-not or alternative guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saveQueryEvidenceA

Execute a read-only SELECT SQL query and save the SQL plus the results as a Markdown report file. Returns the saved file path, the total number of rows fetched, and the first 10 rows as preview data.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesSELECT SQL statement to execute and document
filepathYesDestination Markdown file path (absolute, or relative to the server working directory)

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full transparency burden. It discloses the read-only nature, output format, and saved artifact, but does not mention file overwrite behavior, permissions, or error handling. This is adequate but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that efficiently conveys purpose, constraints, and output. No redundant or extraneous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations or output schema, the description covers the main functionality, read-only constraint, and return values. It lacks details on side effects like file overwrite, but for a read-only tool it is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters have individual descriptions. The tool description adds 'read-only' context to the sql parameter but largely restates schema info. Minimal added value beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool executes a read-only SELECT SQL query, saves it as a Markdown report, and returns specific outputs (file path, row count, first 10 rows). It distinguishes from siblings like query or exportQuery by specifying the saving behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly limits usage to read-only SELECT queries and mentions the saving aspect. It does not explicitly state when not to use it or provide direct alternatives, but the context of sibling tools and the read-only constraint gives sufficient guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.1
    • First observeddescribeTable
    • First observedexplainQuery
    • First observedexportQuery
    • First observedlistTables
    • First observedquery
    • First observedsaveQueryEvidence

TDQS

A4/5.0

Scored across 6 tools

Disambiguation4/5

Most tools have clearly distinct purposes: listing tables, describing one table, running queries, explaining query plans, exporting results, and saving evidence. However, 'query' and 'saveQueryEvidence' both execute SQL queries, which could cause minor confusion if descriptions are not carefully read.

Naming Consistency4/5

All tool names follow a camelCase pattern with verb+noun, e.g., 'describeTable', 'listTables', 'exportQuery'. The name 'query' is a single word and slightly generic compared to the others, but overall the pattern is consistent.

Tool Count5/5

With 6 tools, the set covers essential operations for a read-only database exploration server: listing, describing, querying, explaining, exporting, and saving evidence. The number is well-scoped without unnecessary bloat.

Completeness4/5

For a read-only database tool, the set is largely complete. It covers table metadata, query execution, plan analysis, and result export. Minor gaps include missing support for views, schemas, or stored procedures, but these are not critical for the core use case.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A read-only MCP server that enables LLMs to safely explore and query any SQLite database via natural language. It exposes tools for listing tables, describing schemas, and executing SELECT/WITH queries with built-in safety guards like write prevention and row limits.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that provides safe, read-only SQL access for AI agents to query databases (PostgreSQL, MySQL, SQLite) with schema awareness and guardrails.
    12
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A configurable, database-agnostic MCP server that enables LLMs to safely interact with SQL databases through read-only operations and schema inspection.
    -