Skip to main content
Glama
AishwaryaDV

safe-db-mcp

by AishwaryaDV

safe-db-mcp

An MCP server that lets an AI client query SQLite databases safely — every query validated, forced read-only, row-capped, time-limited, and logged — plus an eval harness that measures how accurately a model answers benchmark questions through the server.

Work in progress. This README is expanded to the full standard (demo GIF, live link, results tables, failure write-ups) in the final phase. For now:

Quick start

make setup     # create the virtualenv, install the package, download Chinook
make run       # start the MCP server over stdio
make test      # run the test suite
make lint      # ruff lint + format check

Related MCP server: sqlite-mcp

Use it in Claude Desktop

Add the server to Claude Desktop's config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS). Use absolute paths, since the client launches the server from its own working directory:

{
  "mcpServers": {
    "safe-db-mcp": {
      "command": "/ABSOLUTE/PATH/TO/safe-db-mcp/.venv/bin/safedb-mcp",
      "args": ["--config", "/ABSOLUTE/PATH/TO/safe-db-mcp/config.yaml"]
    }
  }
}

Set the Chinook path in config.yaml to an absolute path too, then restart Claude Desktop. It will list the four tools; ask questions in plain English and it writes the SQL for you.

Five questions to try against Chinook:

  1. How many tracks are in the database?

  2. Who are the top 5 artists by number of albums?

  3. Which 5 countries have the most customers?

  4. What are the 5 longest tracks, with their album titles?

  5. What is the total revenue by billing country (top 5)?

A dangerous request (e.g. "delete the Album table") is refused by the server, not the model.

Licence

MIT. See LICENSE. Bundled data (Chinook, Spider) is downloaded locally and never committed; see DATA_SOURCES.md.

Available Tools

4 tools
describe_schemaA

Return the tables, columns, keys, and a few sample rows for a database. Call this before writing SQL so you use real table and column names. Pass a table to inspect just one, or sample_rows=0 to omit the samples.

NameRequiredDescriptionDefault
tableNo
databaseYes
sample_rowsNo

Output Schema

NameRequiredDescription
tablesYes
databaseYes

TDQS

A3.8/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 burden; it discloses that sample rows are returned and that sample_rows=0 suppresses them, which is genuine behavioral context for a read operation. It does not state permission requirements, cost or size of output on wide schemas, or what happens when a requested table does not exist.

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?

Three short sentences, front-loaded with purpose, then usage, then parameter shortcuts. Every clause adds information; nothing repeats the name or wastes space.

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?

An output schema exists, so the description need not explain return values, and it still summarizes them usefully. Combined with its handling of two of three parameters, only the undocumented `database` argument and missing error behavior keep it from being fully 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 description coverage is 0%, so the description must compensate. It adds real meaning for `table` (inspect a single table) and `sample_rows` (0 omits samples), but `database` — the only required parameter — gets no explanation of accepted forms or how to discover valid values, leaving a meaningful gap.

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

Purpose4/5

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

Opens with a concrete verb and enumerates exactly what comes back: tables, columns, keys, and sample rows. It is clearly a schema-inspection tool, distinct from list_databases and run_query, though it never names those siblings explicitly.

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?

'Call this before writing SQL so you use real table and column names' gives a clear trigger condition, and the same sentence tells you how to narrow scope with the table argument. It does not say when to prefer list_databases instead, but that tool's role is implied.

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

explain_queryA

Return SQLite's query plan for a SELECT without executing it. Use it to check how a query will run or to debug a slow one. The same validation as run_query applies.

NameRequiredDescriptionDefault
sqlYes
databaseYes

Output Schema

NameRequiredDescription
okYes
hintNo
planNo
messageNo
error_typeNo

TDQS

A3.8/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 behavioral burden. It usefully discloses that the query is not executed and that run_query-style validation applies, but it does not state permission requirements, whether the query must be a SELECT (beyond implication), or any other error/behavioral details.

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?

Three short sentences, front-loaded with the core behavior ('Return SQLite's query plan...') and followed by usage context. Every sentence adds useful information with no filler.

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?

An output schema exists, so return values need not be explained. However, with no annotations and 0% parameter description coverage, the description leaves important gaps about the 'database' parameter and validation/error behavior, even though the non-execution safety property is covered.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate for both parameters. It implies that 'sql' is a SELECT statement, but it says nothing about the 'database' parameter or the format/meaning of either argument beyond that implication.

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?

States a specific verb and resource: returns SQLite's query plan for a SELECT. It also distinguishes itself from the likely sibling run_query by specifying 'without executing it', so an agent can tell exactly what this tool does differently.

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?

Explicitly says to use it to check how a query will run or debug a slow one, which gives clear context. It also signals that the same validation as run_query applies, though it does not explicitly name run_query as the executing alternative or state when not to use this tool.

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

list_databasesA

List the databases available to query, with a short description and table count for each. Call this first to discover what you can query.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
databasesYes

TDQS

A4.3/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 burden. It discloses the return contents and the intended call-ordering behavior, but says nothing about side effects, scope limits, or cost of the call — for a zero-parameter read-only listing the residual risk is low, hence a middle score rather than a low one.

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, zero filler. Scope is front-loaded and the usage instruction follows immediately.

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?

For a no-argument discovery tool with an output schema, this is complete: what it returns, and that it should be the first call in a session. Nothing an agent needs before invoking it is missing.

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 takes zero parameters, so there is no parameter semantics to document and no risk of under-specification. Baseline 4 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?

Specific verb + resource ('List the databases') plus a precise statement of the payload ('short description and table count for each'). This clearly separates it from describe_schema and run_query, which operate on a schema or execute SQL rather than enumerate databases.

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?

'Call this first to discover what you can query' gives explicit, actionable ordering guidance that an agent can follow without inference. It stops short of a 5 because it never names the alternatives (describe_schema, run_query) or states when-not to use this tool.

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

run_queryA

Run a single read-only SELECT against a database and get the rows back. The query is rejected if it is not one read-only statement, and results are capped and may be truncated. Call describe_schema first to get exact table and column names.

NameRequiredDescriptionDefault
sqlYes
databaseYes
max_rowsNo

Output Schema

NameRequiredDescription
okYes
hintNo
rowsNo
columnsNo
messageNo
row_countNo
truncatedNo
elapsed_msNo
error_typeNo

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations, the description carries the full disclosure burden and does well: it states the read-only enforcement, that multi-statement or non-SELECT queries are rejected, and that results are capped and may be truncated. It omits permission/auth requirements and what the rejection or error shape looks like.

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?

Three tight sentences, front-loaded with the core action, then the constraint, then the prerequisite. No filler, and the truncation caveat is placed before the agent commits to the call.

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?

An output schema exists, so return-value explanation is not required, and the truncation/cap warning covers the main risk. However, for a 3-parameter tool with zero schema coverage and no annotations, the meaning of 'database' and 'max_rows' is a real gap an agent must guess at.

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

Parameters2/5

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

Schema description coverage is 0% across three parameters, so the description must compensate and largely does not. It implies the sql parameter must be a single read-only SELECT, but leaves 'database' (which database name, sourced from list_databases?) and 'max_rows' (its interaction with the cap) completely undefined.

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

Purpose4/5

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

The opening sentence gives a specific verb, resource, and execution mode: a single read-only SELECT returning rows. It is clearly distinct from explain_query (plan only) and describe_schema (metadata only), though the sibling distinction is implied rather than stated.

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?

It gives a concrete prerequisite: call describe_schema first for exact table and column names, and it constrains use to one read-only statement. It stops short of naming when to prefer explain_query or list_databases instead.

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. 4 tool updatesv0.1.0
    • First observeddescribe_schema
    • First observedexplain_query
    • First observedlist_databases
    • First observedrun_query

TDQS

A4.2/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct role: discovery, schema inspection, query execution, and query-plan explanation. The boundaries between describe_schema and explain_query are especially clear because one describes table structure while the other reports SQLite's execution plan.

Naming Consistency5/5

All four tools follow a consistent snake_case verb_noun pattern: list_databases, describe_schema, run_query, explain_query. There are no mixed conventions or vague names.

Tool Count5/5

Four tools is well-scoped for a read-only database exploration server. Each tool earns its place by covering a distinct step in the workflow without adding redundant operations.

Completeness5/5

The surface fully covers the intended read-only workflow: discover databases, inspect schemas, run SELECT queries, and explain query plans. Write operations are intentionally absent, consistent with the safe-db-mcp purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that provides safe, read-only access to SQLite databases through MCP. This server is built with the FastMCP framework, which enables LLMs to explore and query SQLite databases with built-in safety features and query validation.
    108
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that enables AI agents to interact with SQLite databases by querying schemas, executing SQL, and inspecting table metadata. It supports safe database access through configurable read-only modes, query timeouts, and dry-run execution plans.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Read-only MCP server for querying PostgreSQL, MySQL, and SQLite from AI agents — multi-database, safe by default.
    4
    38 npm
    1
    ISC
  • A
    license
    Not graded
    quality
    D
    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