SQLScope
Provides database querying for MariaDB using the MySQL-compatible driver, allowing agents to discover tables, inspect schemas, sample rows, run SQL queries, and view execution plans.
Provides database querying for MySQL, allowing agents to discover tables, inspect schemas, sample rows, run SQL queries, and view execution plans.
Provides database querying for SQLite, allowing agents to discover tables, inspect schemas, sample rows, run SQL queries, and view execution plans.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SQLScopeWhat tables are in the default database, and how many rows does each have?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 runSET 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 withtruncated: trueinstead 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: mcp-knowledgebase
Tools
Tool | Arguments | Description |
|
| Tables + views in the default schema, with column counts |
|
| Columns (type, nullability, default, PK), indexes, foreign keys, CREATE DDL, row count |
|
| First N rows (default 10) to see real values |
|
| Run SQL: SELECT returns rows (capped), DML returns affected counts; multi-statement scripts where the driver allows |
|
| 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 --readonlyDocker
docker build -t sqlscope .
docker run -i --rm \
-e SQLSCOPE_DSN='sqlite:////data/app.db' \
-v "$PWD/data:/data" \
sqlscopeConnections — 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 mysqlAppend ?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=roOther driver-specific params after ? are passed through (e.g. charset=utf8mb4 for mysql2).
Declaring connections:
Where | Form | Notes |
CLI |
| connection named |
CLI |
| named, e.g. |
env |
| single connection ( |
env |
| JSON map for several |
Server options
Option | Env | Default | Notes |
|
| off | Engine-enforced read-only on every connection (per-DSN |
|
| 1000 | Row cap; per-query override via the |
|
| stdio | |
|
| 127.0.0.1 | HTTP mode |
|
| 3000 | HTTP mode |
|
| 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 scanDesign 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 torun(). MySQL: the presence of field packets on the result discriminates rows from OkPacket. Multi-statement scripts (SQLite only) are routed toexec()by a scanner that respects quotes and comments — newernode:sqlitesilently 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: trueon 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
multipleStatementsoff.sample_rowshas no ORDER BY — it returns whatever the engine yields first.Row counts in
describe_tableare 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 s3cretRoadmap: PostgreSQL driver, per-connection readonly overrides, write-statement confirmation flow, query timeouts.
License
MIT — see LICENSE.
Available Tools
5 toolsdescribe_tableDescribe tableA
Describe one table: columns (name, type, nullability, default, primary key), indexes, foreign keys, the CREATE statement, and the row count.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name (optionally schema-qualified, e.g. "mydb.users") | |
| connection | No | Named connection to use. Omit when only one connection is configured (or it is named "default"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It transparently lists the result contents and implies a read-only operation, but it does not mention potential caveats such as row-count cost on large tables, required permissions, or error behavior for missing tables.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-organized sentence that front-loads the core action and then lists the returned metadata without any filler. Every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is fairly simple and the parameter schema is complete, but with no annotations and no output schema the description would benefit from a little more context, such as usage intent or caveats. It is adequate but not fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (table and connection) are already fully documented in the input schema. The description adds only the 'one table' scope and does not provide additional parameter nuance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Describe one table', then enumerates the exact metadata returned (columns, indexes, foreign keys, CREATE statement, row count). This clearly separates it from siblings like list_tables, sample_rows, query, and explain_query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: use this tool when you need schema-level details about a single table rather than listing tables, sampling rows, or running queries. However, there is no explicit guidance about when to choose this over alternatives or any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | Statement to plan (does not get executed) | |
| params | No | Bound parameters: array for positional placeholders (?), object for named ones (:name) where the driver supports them. | |
| connection | No | Named connection to use. Omit when only one connection is configured (or it is named "default"). |
TDQS
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 explicitly states that the statement is not executed and that write statements are safe, and it also describes what the plan reveals. This is strong behavioral transparency for a relatively simple tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no filler. The core purpose is front-loaded, and 'Safe on write statements' adds an important behavioral note without extra verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool, the description covers purpose, safety, non-execution behavior, and even the nature of the output (index usage, scan order, estimated rows). Combined with a fully documented parameter schema, an agent has enough context to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already fully documents the sql, params, and connection parameters. The description adds no parameter-level meaning beyond the schema, which is acceptable but not extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Show the execution plan'), a clear resource ('a statement'), and explicitly distinguishes it from execution by saying 'without running it'. This makes it easy to separate from the sibling query tool, which actually runs statements.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly communicates when to use this tool: when you need index usage, scan order, or estimated rows without executing the statement. It also notes it is safe on write statements, which is useful context, though it does not explicitly name alternative tools or list when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| connection | No | Named connection to use. Omit when only one connection is configured (or it is named "default"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It transparently discloses the scope ('default schema'), the return content ('tables and views... with column counts'), and implies a read-only operation. It does not mention potential permission requirements or pagination, but for a listing tool this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no redundancy. The action and scope are front-loaded in the first sentence, and the usage guidance is a single clear instruction in the second.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a low-complexity tool with one optional parameter and no output schema. The description covers what the tool lists, the scope of that listing, the result detail (column counts), and when to call it. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the connection parameter is already fully documented in the schema. The description adds no parameter-specific meaning beyond 'use this first,' so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('all tables and views in the connection's default schema') with an additional detail ('with column counts'). It clearly distinguishes itself from siblings like describe_table (which targets a single table) and query (which executes arbitrary SQL).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit instruction, 'Use this first to discover what to query,' which tells the agent when this tool is appropriate. However, it does not explicitly mention when not to use it or name alternatives, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | SQL statement or script to run | |
| params | No | Bound parameters: array for positional placeholders (?), object for named ones (:name) where the driver supports them. | |
| maxRows | No | Row cap for this query only (server default: 1000) | |
| connection | No | Named connection to use. Omit when only one connection is configured (or it is named "default"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden. It does this well by explaining return shapes per statement type, the maxRows cap/default, multi-statement script support, and parameter binding conventions. It stops short of discussing side effects or permissions, but the core runtime behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense, well-structured sentences with no filler. The purpose is front-loaded, behavior is grouped logically, and every sentence contributes information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a general SQL execution tool with no output schema and no annotations, the description covers the essential decision factors: return modes, row limits, binding syntax, and multi-statement support. It leaves some room for connection-selection details, but those are documented in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, giving the baseline of 3. The description adds useful semantics beyond the schema by connecting sql statement categories to their return behavior and clarifying maxRows as a per-query cap with a default of 1000.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Run a SQL statement', giving a clear verb and resource, then distinguishes this general-purpose execution tool from the specialized siblings list_tables, describe_table, sample_rows, and explain_query by covering the statement types it handles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly conveys that this is the tool for arbitrary SQL execution and enumerates which statement categories it supports. It does not name sibling alternates explicitly, but the practical context is strong enough for an agent to choose it over the specialized table-introspection siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of rows to return (default 10) | |
| table | Yes | Table name (optionally schema-qualified) | |
| connection | No | Named connection to use. Omit when only one connection is configured (or it is named "default"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It correctly states the action and default, but it omits an important caveat: 'first N rows' has no guaranteed order without an ORDER BY clause. It also does not mention whether this is a simple LIMIT query or the potential performance implications on large tables.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the action, includes the default, and closes with practical use-case guidance. Every word earns its place, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple preview tool, the description covers the essence: what it does, the default behavior, and the intended use case. It could be improved by noting that rows are unsorted unless specified and that this is effectively a SELECT * FROM table LIMIT n, but the existing text is sufficient for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters. The description adds no parameter-specific meaning beyond restating the default limit already present in the schema, which keeps it at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Fetch the first N rows of a table') with a concrete resource and a default limit. It also explains the purpose ('to see real values... before writing queries'), which distinguishes it from siblings like describe_table or explain_query without needing to open the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit context for when to use the tool: 'useful for understanding data shape before writing queries.' It does not explicitly name alternatives or exclusions, but the use case is clear enough relative to the sibling tools.
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.
5 tool updates
v0.1.1- First observed
describe_table - First observed
explain_query - First observed
list_tables - First observed
query - First observed
sample_rows
TDQS
Scored across 5 tools
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.
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.
Five tools is well-scoped for a SQL database interaction server. Each tool serves a distinct and necessary purpose without unnecessary bloat.
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
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
An agent-native database over MCP: shared, validated, structured records in every AI chat.
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Let AI agents query data and act across all your business apps via MCP.
MCP-first toolbox for agents: KV storage, auth, queue, and utility tools. Free in early access.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to query and manage MySQL databases through a structured MCP interface, supporting SQL execution, table inspection, and database operations.913MIT
- FlicenseAqualityDmaintenanceEnables AI agents to explore MySQL database schemas and execute read-only queries through a safe, MCP interface.6-
- AlicenseBqualityCmaintenanceEnables AI agents to interact with over 50 SQL and NoSQL databases through MCP tools for querying, schema inspection, and table management.51MIT
- FlicenseAqualityCmaintenanceEnables AI agents to safely inspect and query a SQLite database through read-only MCP tools for listing tables, describing schemas, and running paginated SELECT queries.3-