Skip to main content
Glama
SQLScope

SQLScope

by unfallenwill

SQLScope

SQLScope is a database query tool exposed as an MCP server, built for AI agents that need to look into real data: discover tables, understand schemas, sample rows, and run SQL — through five focused tools.

First release supports SQLite (zero-dependency node:sqlite) and MySQL / MariaDB (mysql2). The driver layer is small and typed, so PostgreSQL and friends slot in without touching the tool surface.

Architecture

MCP client ──stdio / streamable HTTP──> SQLScope MCP server (this process)
                          │  connection table (opened at startup)
                          ├── sqlite connection  (node:sqlite)
                          ├── mysql connection   (mysql2/promise)
                          └── ...
  • Connections are operator-declared, never agent-created. Databases are configured at startup via standard DSN URIs; the agent can only query what the operator exposed.

  • Read-only mode is engine-enforced. SQLite connections open with SQLITE_OPEN_READONLY; MySQL sessions run SET SESSION TRANSACTION READ ONLY. In both cases mutations fail inside the database engine — not by SQL-text pattern matching, which triggers, PRAGMAs, and CTE-hidden writes would defeat.

  • Row caps protect the context window. Row results are capped (--max-rows, default 1000, per-query override up to 100k) and flagged with truncated: true instead of silently flooding the model.

  • No guessing SQL grammar. Statement routing uses engine metadata (SQLite result-column metadata at prepare time; MySQL field packets), and multi-statement scripts are detected by a real scanner so nothing is silently dropped.

Related MCP server: Data Nexus MCP

Tools

Tool

Arguments

Description

list_tables

connection?

Tables + views in the default schema, with column counts

describe_table

table, connection?

Columns (type, nullability, default, PK), indexes, foreign keys, CREATE DDL, row count

sample_rows

table, limit?, connection?

First N rows (default 10) to see real values

query

sql, params?, connection?, maxRows?

Run SQL: SELECT returns rows (capped), DML returns affected counts; multi-statement scripts where the driver allows

explain_query

sql, params?, connection?

Execution plan (EXPLAIN) without executing; safe on write statements

Clients see them namespaced, e.g. sqlscope.list_tables. Errors come back as tool errors with the engine's message (connection failures, syntax errors, read-only violations), so agents can react instead of parsing stack traces.

Usage

Local

npm install
npm run build
node dist/index.js --db sqlite:///app.db
node dist/index.js --db 'mysql://user:pass@127.0.0.1:3306/shop'

Register with Claude Code:

claude mcp add sqlscope -- node /path/to/sqlscope/dist/index.js --db sqlite:///app.db --readonly

Docker

docker build -t sqlscope .
docker run -i --rm \
  -e SQLSCOPE_DSN='sqlite:////data/app.db' \
  -v "$PWD/data:/data" \
  sqlscope

Connections — one standard DSN format

Every connection is a standard RFC 3986 URI. Schemes follow each database's own conventions (SQLAlchemy/DATABASE_URL for SQLite, MySQL Shell/mysql2 for MySQL; a future PG driver will use libpq's postgresql://):

sqlite:///app.db               SQLite, relative path
sqlite:////var/data/app.db     SQLite, absolute path (four slashes)
sqlite:///:memory:             SQLite, in-memory
mysql://user:pass@host:3306/db MySQL / MariaDB
mariadb://user@host/db         alias for mysql

Append ?mode=ro (the SQLite URI spec's read-only parameter, honored by every driver) to force a single connection read-only:

sqlite:////data/app.db?mode=ro
mysql://user@host/db?mode=ro

Other driver-specific params after ? are passed through (e.g. charset=utf8mb4 for mysql2).

Declaring connections:

Where

Form

Notes

CLI

--db <dsn>

connection named default; repeatable

CLI

--db <name>=<dsn>

named, e.g. --db analytics=mysql://u@h/db

env

SQLSCOPE_DSN='<dsn>'

single connection (default)

env

SQLSCOPE_CONNECTIONS='{"oltp":"mysql://u:p@h/db","cache":"sqlite:///a.db"}'

JSON map for several

Server options

Option

Env

Default

Notes

--readonly

SQLSCOPE_READONLY=1

off

Engine-enforced read-only on every connection (per-DSN ?mode=ro ORs in)

--max-rows <n>

SQLSCOPE_MAX_ROWS

1000

Row cap; per-query override via the query tool

--transport <stdio|http>

MCP_TRANSPORT

stdio

--host <address>

MCP_HOST

127.0.0.1

HTTP mode

--port <number>

MCP_PORT / PORT

3000

HTTP mode

--token <secret>

MCP_TOKEN

none

Bearer auth for HTTP; use whenever reachable beyond loopback

With more than one connection (and none named default), tools require the connection argument; the error message lists what is configured.

Example session

list_tables {}                                                  # → users(3 cols), orders(5), ...
describe_table { "table": "users" }                             # columns, pk, indexes, DDL
sample_rows   { "table": "users", "limit": 3 }                  # real values
query         { "sql": "SELECT count(*) AS n FROM users WHERE team_id = ?", "params": [7] }
explain_query { "sql": "SELECT * FROM users WHERE email = 'a@b.c'" }   # index used? no table scan

Design notes

  • Why startup-declared connections? The agent never holds credentials or chooses targets; the operator pins exactly what is visible. This also makes SQLScope safe to run read-write against a staging database without giving the agent a footgun.

  • Statement routing. SQLite: StatementSync.columns() exposes result columns at prepare time — row-returning statements are detected without executing or regex-matching; write statements route to run(). MySQL: the presence of field packets on the result discriminates rows from OkPacket. Multi-statement scripts (SQLite only) are routed to exec() by a scanner that respects quotes and comments — newer node:sqlite silently executes only the first statement of a multi-statement string, which we refuse to do.

  • JSON-safe results. BIGINTs become numbers (strings when > 2^53), BLOBs become hex, DATETIMEs stay strings (dateStrings: true on mysql2) so agents always receive plain JSON.

  • Read-only is not a regex. See Architecture. MySQL's read-only session blocks even temporary-table writes — that is the point.

Limitations

  • MySQL runs one connection per configured name; concurrent tool calls are queued by mysql2 (fine for agent workloads, not for analytics fan-out).

  • Multi-statement scripts are SQLite-only; MySQL keeps multipleStatements off.

  • sample_rows has no ORDER BY — it returns whatever the engine yields first.

  • Row counts in describe_table are exact for SQLite (COUNT(*)) and omitted for MySQL (InnoDB estimates would lie).

Development

npm run build
node scripts/smoke.mjs                    # stdio smoke, all 5 tools, readonly mode (19 assertions)

# MySQL integration (spins up nothing itself — point it at a disposable server):
docker run -d --rm --name sqlscope-mysql -e MYSQL_ROOT_PASSWORD=t -e MYSQL_DATABASE=t -p 127.0.0.1:33061:3306 mysql:8
TEST_MYSQL_URL='mysql://root:t@127.0.0.1:33061/t' node scripts/smoke-mysql.mjs

# HTTP transport check
node dist/index.js --db sqlite:///:memory: --transport http --port 3000 --token s3cret

Roadmap: PostgreSQL driver, per-connection readonly overrides, write-statement confirmation flow, query timeouts.

License

MIT — see LICENSE.

Available Tools

5 tools
describe_tableDescribe tableA

Describe one table: columns (name, type, nullability, default, primary key), indexes, foreign keys, the CREATE statement, and the row count.

Inputs: table (required), connection.

explain_queryExplain query planA

Show the execution plan for a statement (EXPLAIN / EXPLAIN QUERY PLAN) without running it — index usage, scan order, estimated rows. Safe on write statements.

Inputs: sql (required), params, connection.

list_tablesList tablesA

List all tables and views in the connection's default schema, with column counts. Use this first to discover what to query.

Inputs: connection.

queryRun SQLA

Run a SQL statement. SELECT/SHOW/EXPLAIN return rows (capped by maxRows, default 1000); INSERT/UPDATE/DELETE return affected-row counts; multi-statement scripts are supported where the driver allows them. Params bind with ? (array) or :name (object) where supported.

Inputs: sql (required), params, maxRows, connection.

sample_rowsSample rowsA

Fetch the first N rows of a table (default 10) to see real values — useful for understanding data shape before writing queries.

Inputs: table (required), limit, connection.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 5 tools

    Disambiguation5/5

    Each tool has a clearly distinct role: discovering tables, inspecting schema, previewing data, executing queries, and showing query plans. There is no meaningful overlap between the five tools.

    Naming Consistency4/5

    Most tools follow a clear verb_noun pattern such as list_tables, describe_table, sample_rows, and explain_query. The single exception is query, which is concise but does not follow the same pattern as the others.

    Tool Count5/5

    Five tools is well-scoped for a SQL database interaction server. Each tool serves a distinct and necessary purpose without unnecessary bloat.

    Completeness5/5

    The tool set covers the full core workflow of database exploration and querying: discover tables, inspect structure, preview data, run arbitrary queries, and analyze execution plans. Write operations are handled through the general query tool, so no major lifecycle gaps exist.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      Enables AI agents to interact with over 50 SQL and NoSQL databases through MCP tools for querying, schema inspection, and table management.
      5
      1
      MIT
    • F
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to analyze databases through MCP, including listing all tables and inspecting table structures.
      -