Skip to main content
Glama
Gowsi31

sql-mcp

by Gowsi31

sql-mcp

sql-mcp

An MCP server for read-only SQL Server access, plus a chat app (Express + React) that lets you ask questions about your databases in plain English.

Two things live in this repo:

  1. An MCP server (src/index.ts) exposing query, list_tables, describe_table, and list_databases tools — usable from Claude Desktop, Claude Code, or any other MCP client.

  2. A standalone chat app (src/server.ts + web/) that drives that same MCP server with an LLM (Gemini, with free OpenRouter models as a fallback), so you can just type a question instead of writing SQL.

See ARCHITECTURE.md for how it's built and why (in particular, why it talks to SQL Server via sqlcmd instead of a normal Node driver).

Prerequisites

  • Node.js 18+ (20+ recommended)

  • sqlcmd on PATH — ships with the ODBC Driver 17 (or later) for SQL Server Client SDK

  • A SQL Server instance reachable from this machine (Shared Memory, Named Pipes, or TCP — sqlcmd handles whichever is available; no manual protocol configuration needed)

Related MCP server: mssql-mcp

Setup

  1. Install dependencies:

    npm install
    cd web && npm install && cd ..
  2. Create a .env file in the project root:

    SQL_SERVER=your-server-name
    SQL_DATABASE=your-database-name
    SQL_USER=sa
    SQL_PASSWORD=your-password
    
    GEMINI_API_KEY=your-gemini-api-key

    GEMINI_API_KEY is required for the chat app (get one from Google AI Studio); the MCP server on its own doesn't need it.

  3. Build:

    npm run build

Running

MCP server (for use with an MCP client like Claude Desktop):

npm start          # runs the compiled dist/index.js
npm run dev         # runs src/index.ts directly via tsx, no build step

Chat app (two terminals):

npm run server       # backend, http://localhost:3001
cd web && npm run dev  # frontend, http://localhost:5173

Quick connection sanity check:

npm run test-connection

MCP tools

Tool

Description

query

Run a read-only SELECT/WITH statement. Writes are rejected.

list_tables

List all tables and views.

describe_table

List a table's columns, types, and nullability.

list_databases

List the configured database aliases (see below).

Every tool takes an optional database argument to target a specific configured database.

Multiple databases

By default there's one database, aliased app, configured via SQL_SERVER/SQL_DATABASE/SQL_USER/SQL_PASSWORD. To add more:

SQL_CONNECTIONS=idp,billing
SQL_IDP_SERVER=...
SQL_IDP_DATABASE=...
SQL_IDP_USER=...
SQL_IDP_PASSWORD=...
SQL_BILLING_SERVER=...
# etc.

Each alias in SQL_CONNECTIONS needs its own SQL_<ALIAS>_SERVER / _DATABASE / _USER / _PASSWORD set. The chat UI's database picker and the list_databases tool pick these up automatically.

Optional: OpenRouter fallback

If GEMINI_API_KEY hits its rate limit, the chat backend can fall back to free models on OpenRouter:

OPENROUTER_API_KEY=your-openrouter-key
# OPENROUTER_MODELS=openai/gpt-oss-20b:free,nvidia/nemotron-3-nano-30b-a3b:free,google/gemma-4-31b-it:free

Leaving OPENROUTER_API_KEY unset disables this fallback entirely — Gemini alone is used.

You can also override which Gemini models are tried, and in what order:

# GEMINI_MODELS=gemini-flash-latest,gemini-flash-lite-latest,gemini-2.5-flash-lite,gemini-pro-latest

Scripts

Script

What it does

npm run build

Compile TypeScript (src/dist/)

npm start

Run the compiled MCP server

npm run dev

Run the MCP server from source (no build)

npm run server

Build, then run the chat backend on port 3001

npm run test-connection

Verify the database connection and print the table list

Security notes

  • The query tool only allows SELECT/WITH statements — no INSERT/UPDATE/DELETE/DROP/etc., enforced in src/db.ts.

  • .env is gitignored. Never commit real credentials or API keys.

Available Tools

4 tools
describe_tableDescribe tableA

List the columns and types for a given table.

ParametersJSON Schema
NameRequiredDescriptionDefault
databaseNoWhich configured database to use (see list_databases). Defaults to the primary database if omitted.
tableNameYesThe table name to describe.

TDQS

A4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It clearly indicates a read-only operation ('List the columns and types'), which implies no destructive side effects. However, it does not explicitly state that it is safe, nor does it mention behavior on errors or missing tables. For a simple describe tool, this is sufficient transparency.

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, front-loaded sentence with zero waste. It conveys purpose directly and efficiently.

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 tool is simple with only two parameters (one required), and the description adequately captures its core behavior. Without an output schema, the description could have detailed the return format, but stating 'columns and types' gives a reasonable hint. It is sufficiently complete for a low-complexity tool.

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 description coverage is 100%, with both 'database' and 'tableName' fully described. The description adds no additional parameter meaning beyond what the schema provides, so the baseline of 3 is appropriate.

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 'List the columns and types for a given table' uses a specific verb and resource, clearly distinguishing this from siblings like list_tables (which lists table names) and query (which runs queries). It fully conveys the tool's purpose.

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 context ('for a given table') but does not explicitly state when to use this tool vs alternatives, nor does it mention that list_tables should be called first to obtain a table name. This is an implied, not explicit, usage guideline.

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

list_databasesList configured databasesA

List the database aliases this server is configured to connect to.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It adds useful context ('configured to connect to') but does not explicitly state side-effect-free behavior or return format. For a simple list operation, this is adequate but not rich.

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, front-loaded sentence that communicates the tool's purpose without any unnecessary words. Every word contributes to the meaning.

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 the tool's simplicity (0 params, no output schema, no annotations), the description is close to complete. It clearly states what is returned (database aliases) and the context. It could potentially clarify the return type, but this is not essential for a list operation.

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 per the rubric the baseline is 4. The description adds no parameter-specific meaning, but this is not necessary since the schema is empty and the operation is parameterless.

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's function with a specific verb ('List') and resource ('database aliases'). It also provides the scope ('configured to connect to'), which distinguishes it from sibling tools that list tables or run queries.

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 the tool is used to see available database connections, but it does not explicitly mention when to use it over alternatives like list_tables. No exclusions or alternative guidance is provided, leaving usage to be inferred from the name and description.

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

list_tablesList tablesB

List all tables and views in the database.

ParametersJSON Schema
NameRequiredDescriptionDefault
databaseNoWhich configured database to use (see list_databases). Defaults to the primary database if omitted.

TDQS

B3.3/5.0
Behavior2/5

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

With no annotations provided, the description carries the full burden of disclosing behavior. It states the tool lists tables and views, but does not explicitly mention read-only nature, lack of side effects, or the return format. This is minimal behavioral information for a tool with no annotation support.

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, focused sentence that leads with the verb and directly states the tool's action. There is no wasted wording or redundancy, making it highly concise and well-structured.

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?

Given the simplicity of the tool (one optional parameter, no output schema), the description is minimally sufficient but lacks explicit details about the return value (e.g., table names only, inclusion of schemas) and how the 'database' parameter affects results. While not incomplete, it does not fully cover the operation without schema/annotation support.

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?

The input schema already fully describes the single optional 'database' parameter (100% coverage), including its meaning and default behavior. The tool description adds no additional parameter semantics beyond what the schema provides, so the baseline score of 3 is appropriate.

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's purpose: to list all tables and views in the database. It uses a specific verb 'List' and a specific resource, distinguishing it from sibling tools like describe_table (which describes a specific table) and query (which runs queries).

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 explicit usage guidance is given. The description does not mention when to use this tool versus alternatives, nor does it provide hints about when it's appropriate (e.g., discovering available tables). The only context is the parameter description referencing list_databases, which is indirect.

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

queryRun SQL queryA

Run a read-only SELECT query against the database and return the results as rows.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesA SELECT (or WITH ... SELECT) statement.
databaseNoWhich configured database to use (see list_databases). Defaults to the primary database if omitted.

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 safety disclosure burden. It does disclose the essential behavior of being read-only, which is critical for an agent considering side effects. However, it does not mention potential limitations (e.g., result size, timeout, error handling) or clarify whether multiple statements are allowed. The description is correct but not richly transparent.

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 front-loads the verb ('Run'), specifies the resource ('database'), and states the output ('rows'). Every word adds value with no redundancy or filler.

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 tool with two well-documented parameters and no output schema, the description adequately covers purpose, read-only behavior, and result format. It lacks mention of potential query limits or error behavior, which would be useful given no output schema and no annotations, but the overall context is sufficiently clear. The nearby sibling tools help orient the agent without needing explicit mention.

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% since both parameters (sql, database) are individually described with sufficient detail. The description adds no new parameter meaning beyond restating that the query is a SELECT, which is already captured in the schema. The constraint 'read-only' is a behavioral qualifier rather than a parameter semantic. Baseline of 3 applies.

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 a specific verb and resource: 'Run a read-only SELECT query against the database.' It specifies the output format ('return the results as rows') and distinguishes itself from sibling tools like list_tables and describe_table by focusing on arbitrary SQL queries.

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 implies the tool is for executing read-only SELECT statements and indicates it returns results. It does not explicitly name alternatives or provide exclusions, but the 'read-only' qualifier clarifies a key usage constraint and the sibling list shows when other tools might be more appropriate. The schema's reference to list_databases for the database parameter adds some guidance.

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

TDQS

A4/5.0
Disambiguation5/5

Each tool has a distinct purpose: list_tables returns the table list, describe_table provides schema for one table, list_databases shows configured connections, and query executes arbitrary SELECT statements. There's no overlap; an agent can easily determine which tool to use for a given task.

Naming Consistency4/5

The first three tools follow a clear verb_noun pattern (list_tables, describe_table, list_databases). The fourth tool, 'query', is a single verb and doesn't fit the pattern cleanly, but it's still intuitive and not confusing.

Tool Count5/5

With only 4 tools, the server is well-scoped for its purpose. Each tool is essential for database exploration and querying, and the count is within the ideal 3-15 range. The small number avoids redundancy and keeps the interface focused.

Completeness5/5

For a read-only SQL query server, the surface is complete: list databases to see connections, list tables, describe a table's schema, and run arbitrary SELECT queries. There are no obvious gaps for the stated purpose, and the read-only constraint is explicit.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    A read-only MCP server that enables users to query Databricks SQL, browse metadata, and monitor Delta Lake tables. It also supports tracking Databricks Jobs, DLT Pipelines, and cluster metrics through natural language interfaces.
    25
    4
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Read-only MCP server for Microsoft SQL Server that retrieves connection details from AWS Secrets Manager, enabling database exploration and querying via natural language.
    12
    11
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Read-only SQL Server MCP server enabling safe database queries, table listing, and schema inspection with built-in security protections.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Security-first, read-only MCP server for Microsoft SQL Server, enabling safe natural-language querying of databases.
    15
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Gowsi31/sql-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server