Skip to main content
Glama
negrip

SQL Query Tools MCP Server

by negrip
README.md
# SQL Query Tools β€” MCP Server

MCP (Model Context Protocol) server for connecting to SQL Server in readonly mode.
Allows any MCP client (Claude Desktop, GEAI, Cursor, etc.) to explore the schema and run SELECT queries against a SQL Server database.

> πŸ“– [VersiΓ³n en espaΓ±ol](README.es.md)

---

## Installation

### 1. Install dependencies

Open a terminal inside the project folder and run:

```bash
npm install
```

### 2. Configure the connection

The `.env` file is already included with the variables ready. Fill it in with your server details:

```env
# Connection
SQL_SERVER=my_server
SQL_DATABASE=MyDatabase
SQL_USER=my_user
SQL_PASSWORD=my_password
SQL_INSTANCE=              # leave empty if not using a named instance
SQL_ENCRYPT=false          # set to true for Azure SQL or cloud servers
SQL_TRUST_SERVER_CERT=true

# Security / filters
ALLOWED_TABLES=            # leave empty to expose all tables (supports wildcards: dbo.prefix_*)
MAX_ROWS=200               # maximum rows returned per query

# Performance
SQL_QUERY_TIMEOUT=30000    # query timeout in milliseconds (default: 30s)
SCHEMA_CACHE_TTL_MINUTES=5 # how long to cache schema results in memory (default: 5 min)

# Audit log
AUDIT_LOG=false            # set to true to enable audit logging
AUDIT_LOG_DIR=./logs       # folder where daily log files are written
```

> If `SQL_ENCRYPT` is `true` (cloud servers), make sure to also set `SQL_TRUST_SERVER_CERT=true`.

### 3. Verify the connection

```bash
npm run test-connection
```

You should see `βœ… Connection successful!` along with the SQL Server version and available tables.

### 4. Verify the MCP server starts

```bash
node mcp-server.js
```

You should see `βœ… MCP server connected and ready`. Close it with `Ctrl+C` β€” the MCP client starts it automatically when needed.

---

## Connect from your MCP client

### Claude Desktop

1. Open the Claude Desktop configuration file:
   - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
   - Mac: `~/Library/Application Support/Claude/claude_desktop_config.json`

2. Add the `sql-query-tools` block inside `mcpServers` (replace the path):

```json
{
  "mcpServers": {
    "sql-query-tools": {
      "command": "node",
      "args": ["ABSOLUTE_PATH/SQLQueryTools/mcp-server.js"]
    }
  }
}
```

3. Restart Claude Desktop from the system tray (right-click β†’ Quit, then reopen).

4. Verify the tools icon (πŸ”§) appears in the chat β€” clicking it should show the `db_*` tools.

### GEAI or other clients

Point the client to the `mcp-sql-config.json` file included in this folder, or configure it manually with the absolute path to `mcp-server.js`. Credentials are read from `.env` automatically.

### Cursor

1. Open Settings β†’ MCP.
2. Add the same JSON block from above.
3. Restart Cursor.

---

## Available tools

| Tool | Description |
|------|-------------|
| `db_test_connection` | Tests the connection and returns server version and current datetime |
| `db_describe_schema` | Lists all tables and views with their column count (result is cached) |
| `db_describe_table` | Returns column details (name, type, nullable) for a specific table or view |
| `db_sample_data` | Returns 5 sample rows from a table β€” useful for the agent to understand the data |
| `db_run_readonly` | Executes a SELECT query (auto-injects TOP if no row limit is present) |
| `db_list_databases` | Returns info about the currently connected database |

---

## Configuration reference

### Security β€” `ALLOWED_TABLES`

Controls which tables and views are accessible. Leave empty to expose everything.

```env
ALLOWED_TABLES=dbo.Orders,dbo.Customers,dbo.Invoice_*
```

Wildcards are supported at the end of the name (`dbo.prefix_*`). The filter applies to `db_describe_schema`, `db_describe_table`, and `db_run_readonly`.

### Row limit β€” `MAX_ROWS`

Maximum number of rows returned by any `SELECT` query. The server automatically injects `TOP N` if the query doesn't include a limit.

```env
MAX_ROWS=200
```

### Query timeout β€” `SQL_QUERY_TIMEOUT`

If a query takes longer than this value (in milliseconds), it is automatically cancelled. Prevents slow or heavy queries from blocking the server.

```env
SQL_QUERY_TIMEOUT=30000   # 30 seconds
```

### Schema cache β€” `SCHEMA_CACHE_TTL_MINUTES`

`db_describe_schema` results are cached in memory to avoid repeated database roundtrips. After the TTL expires, the next call refreshes the cache.

```env
SCHEMA_CACHE_TTL_MINUTES=5   # cache lasts 5 minutes
```

Set to `0` to disable caching (always queries the database).

### Audit log β€” `AUDIT_LOG`

When enabled, every tool call is recorded in a daily log file inside `AUDIT_LOG_DIR`. Each entry includes the timestamp, tool name, query or table, result, and execution time.

```env
AUDIT_LOG=true
AUDIT_LOG_DIR=./logs
```

Log format:
```
[2026-03-27T14:32:11Z] db_run_readonly | SELECT TOP 10 * FROM dbo.Orders | rows:10 | 45ms
[2026-03-27T14:32:20Z] db_run_readonly | SELECT * FROM dbo.Users | BLOCKED: table not allowed | 0ms
```

A new file is created each day: `logs/audit-YYYY-MM-DD.log`. Blocked queries are also logged.

---

## Usage

Once the MCP is active, you can ask questions in natural language about your database. The agent will use the tools automatically to explore the schema and respond.

---

## Test scripts

```bash
npm run test-connection            # verify connectivity and list available tables
npm run test-schema                # list all tables and views with column counts
node tests/test-table.js dbo.Employees   # describe columns of a specific table
```

---

## Security

- Only `SELECT` queries are allowed. Blocked keywords: `DROP`, `DELETE`, `UPDATE`, `INSERT`, `ALTER`, `TRUNCATE`, `CREATE`, `EXEC`, `EXECUTE`, `WAITFOR`, `XP_`, `SP_`.
- SQL comments (`--` and `/* */`) are stripped before validation.
- Tabs and newlines are normalized to prevent whitespace bypass attempts.
- Multiple statements (`;`) are not allowed.
- `SELECT TOP N` is automatically injected if no row limit is present.
- `ALLOWED_TABLES` acts as a table whitelist (supports `*` wildcards), enforced in `db_describe_schema`, `db_describe_table` and `db_run_readonly`.

### Tested attack vectors

| Category | Examples | Result |
|----------|----------|--------|
| Direct writes | `DROP`, `DELETE`, `UPDATE`, `INSERT` | βœ… Blocked |
| Multiple statements | `SELECT 1; DROP TABLE t` | βœ… Blocked |
| System procedures | `xp_cmdshell`, `EXEC sp_help` | βœ… Blocked |
| DoS | `WAITFOR DELAY '0:0:5'` | βœ… Blocked |
| Whitespace bypass | tabs and newlines between keywords | βœ… Blocked |
| Comment bypass | `/* */` and `--` before keywords | βœ… Blocked |
| Valid queries | `SELECT`, `SELECT TOP`, `COUNT`, `WHERE` | βœ… Allowed |

---

## Project structure

```
SQLQueryTools/
β”œβ”€β”€ mcp-server.js          # Main MCP server
β”œβ”€β”€ mcp-sql-config.json    # Reference MCP config for the client
β”œβ”€β”€ .env                   # Environment variables (do not version)
β”œβ”€β”€ env.example            # Environment variables template
β”œβ”€β”€ package.json
β”œβ”€β”€ package-lock.json
β”œβ”€β”€ README.md              # English documentation
β”œβ”€β”€ README.es.md           # Spanish documentation
└── tests/
    β”œβ”€β”€ test-connection.js
    β”œβ”€β”€ test-schema.js
    β”œβ”€β”€ test-table.js      # Usage: node tests/test-table.js dbo.Employees
    └── test-examples.js
```

---

## Troubleshooting

**Connection error:**
- Check that `SQL_SERVER`, `SQL_USER` and `SQL_PASSWORD` in `.env` are correct.
- For cloud servers, try setting `SQL_ENCRYPT=true`.
- If using a named instance, set `SQL_INSTANCE` (e.g. `SQLEXPRESS`).
- Confirm that port 1433 is accessible from your network.

**No tables shown in `db_describe_schema`:**
- Check `ALLOWED_TABLES` in `.env`. If empty, all tables are shown; if set, verify the names/prefixes match.

**MCP not appearing in Claude:**
- Verify the path in the config points correctly to `mcp-server.js`.
- Restart Claude Desktop after any config change.
- Check logs: Claude Desktop β†’ Help β†’ Open Logs Folder.

---

## Author

**--Pablon--** β€” [github.com/negrip](https://github.com/negrip)

TDQS

A4.2/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: connection testing, schema overview, database info, table details, data sampling, and read-only query execution. The descriptions clarify any potential overlap between schema and table descriptions.

Naming Consistency5/5

All tool names follow a consistent db_ prefix with snake_case verbs/nouns, such as test_connection, describe_schema, list_databases, describe_table, sample_data, and run_readonly. The naming pattern is uniform and predictable.

Tool Count5/5

With 6 tools, the set is well-scoped for a SQL query server. Each tool covers a necessary step in the query workflow without redundancy or unnecessary additions.

Completeness4/5

The toolset covers the core read-only query workflow: connect, understand schema, sample data, and execute queries. Minor gaps like lack of multiple database listing or more advanced metadata are acceptable for the stated purpose.

Maintenance

ActivityInactive
ResponsivenessNo issues