mcp-db-read-only
Read-only database querying for AI assistants across MySQL, PostgreSQL, SQLite, SQL Server, ClickHouse, MongoDB, Redis, and Elasticsearch/OpenSearch.
Inspect current connection and list/switch named connection profiles mid-session.
Connect to new databases at runtime with a connection URL.
Explore schemas: list databases, tables/collections/indices/keys, describe structures, indexes, foreign keys.
Fetch sample data from tables, collections, indices, or Redis keys.
Execute read-only SQL (SELECT, WITH, SHOW, DESCRIBE, EXPLAIN) on SQL engines.
Query MongoDB with find, aggregate (no $out/$merge), count documents, distinct values.
Search Elasticsearch/OpenSearch indices with Query DSL.
Run read-only Redis commands like GET, HGETALL, LRANGE, ZRANGE, SCAN, TTL, INFO.
Writes are refused twice: by server validation and database read-only mode; optional logging/viewer available.
Provides read-only SQL access to ClickHouse databases, including schema browsing and running SELECT queries.
Provides read-only search access to Elasticsearch indices, including browsing indices and running Query DSL searches.
Provides read-only SQL access to MariaDB databases, including listing tables, describing schemas, and running read-only queries.
Provides read-only access to MongoDB collections with tools for finding documents, aggregating, counting documents, and retrieving distinct values.
Provides read-only SQL access to MySQL databases, including listing tables, describing schemas, and running read-only queries.
Provides read-only search access to OpenSearch indices, including browsing indices and running Query DSL searches.
Provides read-only SQL access to PostgreSQL databases, including schema browsing and running read-only queries.
Provides read-only access to Redis keys and values, including browsing keys by pattern and running read-only Redis commands.
Provides read-only SQL access to SQLite databases, including table browsing and running read-only queries.
Click on "Deploy 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., "@mcp-db-read-onlyshow me the first 10 rows of the orders table"
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.
mcp-db-read-only
Let your AI assistant look at your databases without being able to change them.
Point it at MySQL, PostgreSQL, SQLite, SQL Server, ClickHouse, MongoDB, Redis or Elasticsearch, then just ask questions in plain words: "how many users signed up this week?", "what's in the orders table?", "which Redis keys hold sessions?". It can read anything you give it access to, and it cannot write, update or delete anything.
Every popular database, one server. Switch between them in the middle of a conversation.
Read-only, twice over. Every query is checked before it is sent, and the database itself is also told to refuse writes.
No restart to switch. Change database, server or engine by asking.
Optional logging, with a live page in your browser that shows every query as it happens.
flowchart LR
Y["You"] -->|"ask in plain words"| AI["Your AI assistant"]
AI -->|"tool call"| S["mcp-db-read-only"]
S -->|"read-only query"| DB[("Your databases")]
DB -->|"rows, documents, keys"| SWorks with Claude Desktop, Claude Code, and any other MCP client.
Quick start
1. Have Node.js 22.13 or newer (node --version), or Docker.
2. Add the server to your client. For Claude Desktop, edit claude_desktop_config.json (Settings, Developer, Edit Config). For Claude Code, create .mcp.json in your project:
{
"mcpServers": {
"databases": {
"command": "npx",
"args": ["-y", "@shibbirweb/mcp-db-read-only"],
"env": {
"DB_URL": "postgres://readonly:secret@localhost:5432/myapp"
}
}
}
}Replace the DB_URL with your own database. The examples below show one for every kind.
3. Restart the client once, and ask away:
"What tables are in my database?" "Show me the 5 newest orders." "How many customers are in each country?"
That's it. You never need to restart again to change database; just ask the assistant to switch.
Related MCP server: safe-sql-mcp
Examples for each database
Each database has a URL format, then a real example to copy and change. Put the finished URL in DB_URL.
Replace each [PLACEHOLDER] with your own value:
Placeholder | What to put there |
| The database user name |
| That user's password |
| The server's address, e.g. |
| The server's port. Optional: leave out |
| The database name. Optional for most: leave it out and ask the assistant to list them |
No password? Leave out :[PASSWORD]. No user either? Leave out [USER]:[PASSWORD]@ entirely.
MySQL and MariaDB
Format (usual port 3306):
mysql://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]
mariadb://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]Example:
mysql://readonly:secret@localhost:3306/shop"List the tables in shop." · "Describe the orders table." · "What were last month's top 10 products by revenue?"
PostgreSQL
Format (usual port 5432). Add ?sslmode=require to use TLS:
postgres://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]Example:
postgres://readonly:secret@localhost:5432/myapp"Which tables are in the reporting schema?" · "Show the foreign keys on invoices." · "Count signups per day this week."
SQLite
Format (three slashes, then the full path to the file):
sqlite:///[PATH_TO_FILE]Example:
sqlite:///Users/me/data/app.dbThe file is opened read-only.
"What tables does this file have?" · "Show 10 rows from notes."
SQL Server (and Azure SQL)
Format (usual port 1433). Add ?trustServerCertificate=true for a local server with a self-signed certificate:
mssql://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]Example:
mssql://readonly:secret@localhost:1433/Sales?trustServerCertificate=true"List the tables in Sales." · "Show the top 5 customers by order total." (SQL Server uses
TOP 5, notLIMIT; the assistant knows.)
ClickHouse
Format (usual port 8123, or 8443 with clickhouse+https):
clickhouse://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]
clickhouse+https://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]Example:
clickhouse://reader:secret@localhost:8123/analytics"How many events per hour did we have yesterday?" · "What is the sorting key of the events table?"
MongoDB
Format (usual port 27017). Use mongodb+srv for MongoDB Atlas, with no port:
mongodb://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]?authSource=admin
mongodb+srv://[USER]:[PASSWORD]@[CLUSTER_HOST]/[DATABASE]Example:
mongodb://reader:secret@localhost:27017/myapp?authSource=admin"What collections are in myapp?" · "What fields do documents in users have?" · "Find the 5 most recent orders over 100." · "Count users by country."
Redis (and Valkey, KeyDB)
Format (usual port 6379). [DB_NUMBER] is the database number, 0 if left out; rediss means TLS:
redis://[USER]:[PASSWORD]@[HOST]:[PORT]/[DB_NUMBER]
rediss://[USER]:[PASSWORD]@[HOST]:[PORT]/[DB_NUMBER]Example:
redis://localhost:6379/0"Which keys start with session:?" · "What's inside user:42?" · "How long until cache:home expires?"
Elasticsearch and OpenSearch
Format (usual port 9200, no database). Add +https for TLS, or ?api_key=[API_KEY] instead of a user and password:
elasticsearch://[USER]:[PASSWORD]@[HOST]:[PORT]
opensearch://[USER]:[PASSWORD]@[HOST]:[PORT]Example:
elasticsearch+https://elastic:secret@search.example.com:9200"What indices do we have?" · "Find error logs from the last hour." · "How many documents are in logs-2026.09?"
Detailed notes for every database, including how to create a read-only account, are in the Databases guide.
Using several databases
Give each one a name with DB_PROFILES, and switch by asking ("switch to legacy", "use the cache"):
"env": {
"DB_PROFILES": "{\"app\": \"postgres://readonly@localhost/app\", \"legacy\": \"mysql://readonly@localhost/shop\", \"cache\": \"redis://localhost:6379/0\"}",
"DB_DEFAULT_PROFILE": "app"
}You can also connect to a database you didn't list, mid-conversation: "connect to postgres://readonly@10.0.0.5/reports".
Password with special characters (@, /, #)? Give it separately instead of inside the URL: DB_PASSWORD next to DB_URL, or {"url": "...", "password": "..."} inside DB_PROFILES.
Running with Docker
Nothing to install but Docker:
{
"mcpServers": {
"databases": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--add-host", "host.docker.internal:host-gateway",
"-e", "DB_URL=postgres://readonly:secret@host.docker.internal:5432/myapp",
"shibbirweb/mcp-db-read-only"
]
}
}
}Inside Docker, use host.docker.internal instead of localhost to reach a database on your own computer. For SQLite, mount the folder: add "-v", "/Users/me/data:/data:ro" and use sqlite:///data/app.db.
Watching what the assistant does
Turn on logging to keep a record of every query the assistant runs, and see them live in your browser.
flowchart LR
S["mcp-db-read-only<br/>(in your AI client)"] -->|"one file per call"| F[("Log folder<br/>DB_LOG_DIR")]
F --> V["viewer command<br/>(in a terminal)"]
V -->|"live"| B["Your browser"]1. Save logs to a folder by adding this to the server's env:
"DB_LOG_DIR": "/Users/me/Library/Logs/mcp-db-read-only"Each query is saved as its own file, one folder per day. Nothing is ever deleted automatically.
2. Open the viewer in a terminal, whenever you want to watch:
npx -y @shibbirweb/mcp-db-read-only viewer --dir /Users/me/Library/Logs/mcp-db-read-only --port 4800Then open http://127.0.0.1:4800/. You'll see every call: what was asked, the exact query sent, how long it took, and the result. It updates live, shows 20 per page (10, 20, 30 or 50 to choose from), and lets you filter and copy anything. Press Ctrl+C to close it.
The viewer has no password. Anyone who can reach that port on your network can read the log while it runs.
Passwords are never written to the logs. More in the Logging guide.
Is it really read-only?
Yes, in two independent ways, so a mistake in one is caught by the other:
flowchart LR
Q["The assistant<br/>writes a query"] --> C{"1. Checked by<br/>this server:<br/>only a read?"}
C -->|"no"| R1["Refused,<br/>with the reason"]
C -->|"yes"| D["2. Sent to the database<br/>in read-only mode"]
D -->|"a read"| A["The answer"]
D -->|"a write that<br/>slipped through"| R2["Refused by<br/>the database"]Before anything is sent, every query is checked. Only reads are allowed:
SELECTand friends for SQL, read commands for Redis, searches for Elasticsearch, and no$outor$mergefor MongoDB.The database is told to refuse writes too, wherever it supports that: read-only sessions on MySQL, read-only transactions on PostgreSQL, a read-only file on SQLite, and so on.
The best protection is still a read-only database account. Then nothing can write through it, whatever happens. The Databases guide shows how to create one for each database.
Keep in mind that the assistant can read whatever the account can see, and what it reads becomes part of your conversation with the AI provider. Only connect accounts that can see data you are happy to share. See PRIVACY.md.
Settings
All optional. Set them in the server's env.
Setting | What it does |
| The database to connect to at startup |
| The password for |
| Several named databases, as JSON, to switch between |
| Which of those to start with |
| Stop a query after this long (default 30000, that is 30 seconds) |
| Give up connecting after this long (default 10000) |
| Save every call as a file in this folder |
| Write every call to the client's log instead |
| Write every call to one file instead |
|
|
| Run the viewer inside the server itself (the separate |
Coming from mcp-mysql-read-only? Its MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE and MYSQL_PROFILES settings still work as they are.
Full details: Configuration guide.
Troubleshooting
"Can't connect" from Docker to a database on my computer. Use host.docker.internal instead of localhost, and keep the --add-host line from the Docker example.
The server won't start with npx. Check node --version is 22.13 or newer.
SQL Server says the certificate isn't trusted. Add ?trustServerCertificate=true to the URL for a local or development server.
"No database selected". Your URL has no database name. Add one (.../myapp), or ask the assistant to list the databases and pick one.
My password has @ or # in it. Use DB_PASSWORD, or the {"url": ..., "password": ...} form in DB_PROFILES.
The viewer says the port is in use. Something else is using it. Close that, or pick another port with --port 4801.
More answers in the Troubleshooting guide.
Learn more
Wiki: user guides for every feature, plus developer documentation
CHANGELOG.md: what changed in each version
PRIVACY.md: what the server sends where (nothing, except to your databases)
Contributing: pull requests to
masterare welcome../scripts/test-in-docker.shruns the full test suite against every database in throwaway containers; see Testing. If you change this README, change README.dockerhub.md to match.
License
MIT © Md. Shibbir Ahmed
Available Tools
18 toolsaggregateRun Aggregation PipelineARead-onlyIdempotent
Run a read-only MongoDB aggregation pipeline on a collection ($out and $merge are not allowed)
| Name | Required | Description | Default |
|---|---|---|---|
| database | No | Optional database to read from for this call only, without changing the active connection | |
| pipeline | Yes | Pipeline stages as Extended JSON, e.g. [{"$match": {"status": "active"}}, {"$group": {"_id": "$type", "n": {"$sum": 1}}}] | |
| collection | Yes | Collection name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds value by explicitly forbidding $out and $merge, which are the two aggregation stages that would violate the read-only contract. This is meaningful behavioral context beyond the annotations. It doesn't mention performance implications or result size limits, but the core safety-relevant behavior is well covered.
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 core purpose ('read-only MongoDB aggregation pipeline') and immediately states the critical constraint. Every word earns its place; no filler or repetition of schema details.
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 read-only tool with full schema coverage and strong annotations, the description is nearly complete. The main gap is that it doesn't mention what the return value looks like (e.g., array of documents) or any limits on result size, but since there's no output schema and the tool is read-only, these are minor omissions. The $out/$merge exclusion is the most important contextual detail and it's present.
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 the read-only constraint and the $out/$merge exclusion, which helps the agent understand what pipeline stages are acceptable, but it doesn't add parameter-level detail beyond what the schema provides. Baseline 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 ('Run'), a specific resource ('a read-only MongoDB aggregation pipeline on a collection'), and explicitly excludes $out and $merge stages. This clearly distinguishes it from sibling tools like find_documents, run_query, and count_documents.
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 indicates this is for aggregation pipelines, and the read-only constraint plus the $out/$merge exclusion gives implicit guidance on when not to use it. However, it doesn't explicitly name alternative tools for non-aggregation operations or for write operations, so it falls just short of full explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connectConnect to DatabaseAIdempotent
Connect to a database at runtime with a connection URL (mysql, mariadb, postgres, sqlite, mssql, clickhouse, mongodb, redis, elasticsearch, opensearch). Not persisted to disk, but kept for the rest of the session under an alias
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Connection URL, e.g. postgres://user@host:5432/db, mongodb://user@host/db, redis://host:6379/0, sqlite:///path/to/file.db. Use host.docker.internal for a database on this machine when running in Docker | |
| alias | No | Name to remember this connection under for use_connection later | |
| password | No | Password, if not in the URL. Avoids percent-encoding special characters |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, so the description correctly reflects these (no contradiction). The description adds value by specifying that the connection is session-scoped and not persisted to disk, which is a key behavioral trait beyond the annotations.
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 sentences, front-loading the core purpose and scoping, and then adding a practical note about the alias. Every word earns its place; no fluff.
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?
Given the tool's moderate complexity (3 params, all schema-described, no output schema), the description covers the purpose, usage, and key behavioral nuances. The agent has enough information to invoke it correctly without additional context.
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 100%, so the schema already documents all parameters. The description adds context about using the alias with use_connection later, and the password parameter avoids percent-encoding issues, which is not in the schema but is helpful.
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?
States a specific verb ('connect') and a resource ('database'), with a list of supported database types and how the connection is scoped (session-only, under an alias). This clearly distinguishes it from later operations and covers the full scope.
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 sets context: it's a runtime connection that is not persisted, and can be used later via an alias. It doesn't explicitly mention when to prefer this over sibling tools, but given that the siblings are separate actions, a 4 is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
count_documentsCount DocumentsARead-onlyIdempotent
Count documents in a MongoDB collection that match a filter
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No | Query filter as MongoDB Extended JSON, e.g. {"status": "active", "_id": {"$oid": "..."}} | |
| database | No | Optional database to read from for this call only, without changing the active connection | |
| collection | Yes | Collection name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds the filtering behavior, but it does not mention what the call returns, that an omitted filter counts the whole collection, or any cost/performance caveats. No contradiction with annotations.
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, front-loaded sentence with no filler. Every word contributes to the meaning: what is counted, where, and under what condition.
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 read-only counting operation, the schema covers all parameters and annotations cover side effects. The main gap is that the description does not explicitly state that the result is a numeric count or what happens when filter is omitted, but with no output schema and an obvious count return this is a minor omission.
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%, with each parameter (filter, database, collection) already documented, including a MongoDB Extended JSON example for filter. The description adds no semantic information about parameters that is not already in the schema, so the baseline of 3 applies.
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 uses a specific verb ('Count'), names the exact resource (documents in a MongoDB collection), and adds a filtering condition. This distinguishes it from siblings like find_documents or aggregate, which retrieve or process documents rather than return a count.
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 implies the use case: use this tool when only the number of matching documents is needed. However, it does not explicitly tell the agent when to prefer count_documents over find_documents or aggregate, and it mentions no exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
current_connectionShow Current ConnectionARead-onlyIdempotent
Show which database server, engine and database the read-only tools are currently pointed at
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, idempotent, and non-destructive, so the safety profile is covered. The description adds the useful context that the returned state governs the read-only tools, but it does not disclose output shape, failure behavior, or any other operational traits.
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 and clearly states the scope of the returned information. There is no filler or redundancy.
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 parameterless, read-only introspection tool with rich annotations and no output schema, the description fully tells an agent what to expect: server, engine, and database of the current connection. Nothing else is required to 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?
The tool has zero parameters, so the schema leaves nothing undocumented and the description needs no parameter-level detail. Baseline 4 is appropriate for a parameterless tool.
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 uses a specific verb ('Show') with a clear resource: the database server, engine, and database that the read-only tools are currently pointed at. This distinguishes it from sibling tools like list_connections (which lists connections), use_connection, and list_databases, so an agent knows exactly what state it will read.
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 phrase 'currently pointed at' implies this is for inspecting active session context, but it never states when to prefer it over list_connections, list_databases, or use_connection. There is no explicit when-to-use or exclusionary guidance, so the usage context is only inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_tableDescribe TableARead-onlyIdempotent
Show the structure of a table: columns on SQL engines, inferred fields for a MongoDB collection, the mapping of an Elasticsearch index, or the type and TTL of a Redis key
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name (schema.table where the engine has schemas), collection, Redis key, or index | |
| database | No | Optional database to read from for this call only, without changing the active connection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose a read-only, idempotent, non-destructive operation, and the description adds engine-specific behavioral detail: columns for SQL, inferred fields for MongoDB, mapping for Elasticsearch, and type/TTL for Redis. This goes beyond the structured fields without contradicting them.
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 front-loaded sentence with no filler. The colon-separated list packs four engine-specific behaviors into one compact, readable statement, and every clause 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?
With no output schema, the description must explain return values, and it does so for each supported engine. Combined with the schema's parameter descriptions and the safety annotations, it is nearly complete, though it does not state prerequisites such as having an active connection or how errors for missing objects are surfaced.
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 description does not need to add much. It reinforces that the `table` parameter can name a table, collection, index, or key, but it does not add new syntax or format details 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 uses the verb 'Show' with a specific resource, 'the structure of a table', and enumerates what that means across SQL, MongoDB, Elasticsearch, and Redis. This is not a tautology and clearly identifies a metadata/introspection operation, though it does not explicitly name sibling tools to distinguish itself.
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 no explicit guidance on when to choose this tool over siblings like get_table_sample, get_table_indexes, or list_tables. While the purpose implies schema introspection, there are no when/when-not statements or named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
distinct_valuesList Distinct ValuesBRead-onlyIdempotent
List the distinct values of a field in a MongoDB collection, optionally within a filter
| Name | Required | Description | Default |
|---|---|---|---|
| field | Yes | Field path, e.g. status or address.city | |
| filter | No | Query filter as MongoDB Extended JSON, e.g. {"status": "active", "_id": {"$oid": "..."}} | |
| database | No | Optional database to read from for this call only, without changing the active connection | |
| collection | Yes | Collection name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds no additional behavioral context such as limits, ordering, missing-field behavior, or return shape, and it does not contradict the annotations.
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 front-loaded sentence with minimal waste. It is concise, though 'optionally within a filter' is slightly awkward and the description adds little beyond the title and schema details.
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 read-only operation, the required collection and field plus optional filter and database are documented, and annotations cover safety. The main gap is the lack of output format or edge-case behavior, especially since there is no output 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 description coverage is 100%, so all parameters including field path format and Extended JSON filter syntax are already documented. The description mainly restates field and filter concepts and adds no new parameter-level meaning beyond what the schema provides.
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 uses a specific verb ('List') and a precise object: distinct values of a field in a MongoDB collection, optionally filtered. It is clear and easily distinguished from siblings like find_documents or count_documents, though it does not explicitly name those alternatives.
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?
There is no guidance about when to use this tool versus find_documents, aggregate, count_documents, or search. The only hint is the semantic meaning of 'distinct values,' which implies a use case but provides no exclusions, prerequisites, or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_documentsFind DocumentsBRead-onlyIdempotent
Find documents in a MongoDB collection with a filter, optional projection and sort
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Documents to skip, for paging | |
| sort | No | Sort order, e.g. {"createdAt": -1} | |
| limit | No | Maximum documents to return (1-100, default 20) | |
| filter | No | Query filter as MongoDB Extended JSON, e.g. {"status": "active", "_id": {"$oid": "..."}} | |
| database | No | Optional database to read from for this call only, without changing the active connection | |
| collection | Yes | Collection name | |
| projection | No | Fields to include or exclude, e.g. {"name": 1, "_id": 0} |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is clear and the description does not contradict it. The description adds no behavioral context beyond the schema's filter/projection/sort fields, such as defaults, paging behavior, or output shape, but with strong annotations that gap is acceptable.
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?
One compact sentence front-loads the verb and target resource, then lists the major options. There is no filler or repetition, and the size is appropriate for the tool's simplicity.
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?
With seven parameters fully documented in the schema, the description only needs to orient the agent, and it names the three core query features. It does not state the return shape explicitly, but the absence of an output schema is mitigated by the action literally being 'find documents.'
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% and each parameter already has a clear description and example (filter as Extended JSON, sort/projection syntax, limit/skip paging). The tool description only restates filter/projection/sort without adding new parameter semantics, so it lands 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?
States a specific action ('Find documents') on a MongoDB collection and names the main query capabilities (filter, projection, sort), so the core purpose is unambiguous. It does not explicitly contrast with sibling aggregation/counting/search tools, but the verb and resource are specific enough to identify the intended operation.
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 says what the tool does but gives no guidance about when to choose find_documents over aggregate, count_documents, distinct_values, or search. There are no use-case conditions, exclusions, or alternative routing, so an agent must infer appropriateness from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_foreign_keysGet Foreign KeysARead-onlyIdempotent
Show foreign key relationships for a table on MySQL, PostgreSQL, SQLite or SQL Server
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name | |
| database | No | Optional database to read from for this call only, without changing the active connection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the cross-database scope and indicates the output is relationship information, but does not mention return shape, ordering, or behavior for missing tables—acceptable 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence that states the action, target, and scope without wasted words. It is efficiently structured and easy to parse.
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 read-only tool with strong annotations and a fully documented schema, the description is largely sufficient. It could be slightly more complete by noting that a connection must be active or that a database must be selected when not using the optional parameter, but these are minor omissions.
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 both 'table' and 'database' parameters fully. The description adds no meaning beyond the schema, leaving the baseline of 3 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 ('Show'), a clear resource ('foreign key relationships for a table'), and distinguishes itself from siblings like describe_table or get_table_indexes by naming the exact relationship type. It also scopes supported databases, fully clarifying what the tool does.
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 implies this is the right tool when an agent needs foreign key relationships for a table across four major databases. It does not explicitly name alternatives or exclusion criteria, but the sibling context and the focused wording provide sufficient usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_indexesGet Table IndexesARead-onlyIdempotent
Show indexes on a table or MongoDB collection, or the sorting key and skipping indices of a ClickHouse table
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table or collection name | |
| database | No | Optional database to read from for this call only, without changing the active connection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds valuable behavioral nuance by disclosing that ClickHouse tables return sorting key and skipping indices rather than conventional indexes. This is context beyond the structured metadata.
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 entire description is one sentence that states the core behavior first, then adds the ClickHouse variation. There is no redundant phrasing 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 read-only introspection tool with rich annotations, the description provides enough information to call it correctly: it names the required resource and the subtle ClickHouse behavior. It does not describe the exact return shape, but no output schema is promised and the operation is low-risk.
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%, with both 'table' and 'database' already documented in the input schema. The description does not add parameter-level detail, so the baseline of 3 applies.
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 uses a specific verb ('Show') and resource ('indexes on a table or MongoDB collection'), and further clarifies the ClickHouse-specific behavior ('sorting key and skipping indices'). This clearly differentiates it from related introspection tools like get_foreign_keys or describe_table.
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 implies when to use it: when you need index information for a table, collection, or ClickHouse table. It does not explicitly name alternatives or exclusions, but the operation and resource scope are clear enough for an agent to select it without confusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_sampleGet Table SampleARead-onlyIdempotent
Get sample rows from a table, documents from a collection, hits from an index, or the first entries of a Redis key
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of rows to return (1-50, default 5) | |
| table | Yes | Table, collection, index, or Redis key | |
| database | No | Optional database to read from for this call only, without changing the active connection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description has less burden. It adds useful scope context by covering four resource types and notes Redis returns 'first entries,' but it does not clarify whether table samples are random or deterministic or describe the return shape.
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, front-loaded sentence with no filler. It efficiently communicates the core action and all supported resource types in a scannable way.
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 read-only sampler with strong annotations and fully documented parameters, the basics are covered. However, with no output schema and no usage guidance, the description leaves the agent to infer return format and when sampling is preferable to search/find_documents.
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 only restates the table parameter's permitted resource types and adds nothing meaningful about limit or database behavior beyond what the schema provides.
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 action ('Get sample rows') and enumerates the exact resource types it applies to: tables, collections, indexes, and Redis keys. The 'sample' qualifier distinguishes it from siblings like run_query, find_documents, and search, even without naming them.
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 phrase 'sample rows' implies a lightweight data-peeking use case, but there is no explicit statement of when to use this tool instead of alternatives like find_documents, search, or redis_command. Usage context is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_connectionsList Connection ProfilesARead-onlyIdempotent
List the connection profiles available to switch to, with each one's engine, including any added during this session
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive behavior. The description adds genuinely useful dynamic context: 'including any added during this session,' which is not captured by annotations. No contradiction exists.
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, tightly worded sentence that front-loads the action and resource, then adds the relevant session-created detail. No filler or repetition.
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 zero-parameter, read-only list tool with no output schema, the description covers what is listed (connection profiles), the distinguishing field (engine), and an important edge case (session-added profiles). No missing information needed to call 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?
The tool has zero parameters, so the baseline is 4. The description adds no parameter-specific meaning because there are none to describe, and the schema already indicates an empty parameter set.
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 uses a specific verb ('List') and resource ('connection profiles'), and clarifies scope ('available to switch to') and content ('with each one's engine'). This clearly distinguishes it from siblings like list_databases and current_connection.
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 phrase 'available to switch to' provides clear context that this tool is meant for viewing profiles before using use_connection or connect. It does not explicitly name alternatives or exclusion criteria, but the purpose is unambiguous enough that an agent would not confuse it with list_databases or run_query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_databasesList DatabasesARead-onlyIdempotent
List databases on the currently connected server (schemas on MySQL, numbered databases on Redis)
| Name | Required | Description | Default |
|---|---|---|---|
| include_system | No | Include system databases such as information_schema, pg templates, or MongoDB admin and local |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the description doesn't need to repeat those. It adds useful behavioral context by noting state dependence on the current connection and platform-specific naming conventions, which helps an agent interpret results correctly.
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 front-loaded sentence with a parenthetical qualifier that adds important nuance without clutter. Every word earns its place, and there is no redundant restatement of the title or annotations.
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 read-only list tool with one optional, fully documented parameter and rich safety annotations, the description is complete. It identifies the target, the connection context, and the cross-engine behavior; the return shape is implicit from the verb 'List' and the tool type.
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%, and the include_system parameter already has a thorough description in the schema. The tool description doesn't discuss the parameter, but that's acceptable because the schema carries the semantic weight; baseline 3 applies.
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 uses a specific verb ('List') and resource ('databases on the currently connected server'), and adds important cross-engine clarification ('schemas on MySQL, numbered databases on Redis'). This clearly distinguishes it from sibling tools like list_connections and list_tables.
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 phrase 'currently connected server' gives clear context: this is meant to be used after establishing a connection to inspect available databases. It doesn't explicitly name alternatives or exclusions, but the target resource is distinct enough from sibling tools that an agent can select it correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesList TablesARead-onlyIdempotent
List the tables in the active database: collections on MongoDB, keys on Redis, indices on Elasticsearch
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | No | Optional glob filter, * for any characters and ? for one, e.g. user* or logs-2026-* | |
| database | No | Optional database to read from for this call only, without changing the active connection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, open-world, and non-destructive behavior, so the safety profile is covered. The description adds valuable context by explaining that 'tables' maps to different entities depending on the backend (collections, keys, indices) and that listing happens in the active database, which helps an agent form correct expectations across stores.
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 front-loaded sentence conveys the action, resource, and backend-specific terminology with no filler. Every part of the description contributes meaning.
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, read-only, zero-required-parameter listing tool, the description together with the schema and annotations covers purpose, scope, and per-call overrides. It does not explicitly describe the output shape or behavior when no active database exists, but the phrase 'list the tables' plus the absence of an output schema makes the expected result reasonably inferable.
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%, and the schema already explains pattern as a glob filter and database as a per-call override. The description adds no parameter-level details, so it does not need to compensate; 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.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'List the tables in the active database,' then clarifies the cross-store meaning of 'table' as collections (MongoDB), keys (Redis), and indices (Elasticsearch). This makes the tool's purpose unmistakable and distinguishes it from list_databases or list_connections without requiring agents to open those tools.
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 the scope ('active database') and implies an exploratory listing use case, but it does not state when to prefer this tool over siblings such as describe_table, get_table_indexes, or list_databases, nor when not to use it. The usage context is implied by the name rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
redis_commandRun Read-Only Redis CommandARead-onlyIdempotent
Run one read-only Redis command such as GET, HGETALL, LRANGE, ZRANGE, SCAN, TTL or INFO. Write commands and KEYS are refused
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments, e.g. ["user:42"] | |
| command | Yes | Command name, e.g. HGETALL | |
| database | No | Optional database to read from for this call only, without changing the active connection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, and the description reinforces this while adding a useful guardrail: write commands and KEYS are refused. It does not discuss return/error behavior in detail, but for a read-only command runner the safety-relevant behavior is disclosed.
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 tight sentences: the core action is front-loaded, followed by concrete examples and a crisp exclusion. There is no filler, redundancy, or unnecessary restatement.
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 generic Redis command runner, the allowed-command examples and refusal rule give enough context to select and invoke it correctly, and the schema covers all parameters. It would be slightly stronger with a note about raw return shape or command errors, but the definition is still sufficient without it.
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 command, args, and database are already documented structurally. The description's command examples help set expectations, but it adds little parameter-level meaning beyond what the schema already provides.
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 a specific action and resource: 'Run one read-only Redis command', and lists representative commands like GET, HGETALL, LRANGE, and SCAN. It is immediately distinct from the sibling SQL/query tools, and the refusal of write commands and KEYS further pins down its scope.
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 clearly states when to use the tool: for read-only Redis commands. It also explicitly gives a when-not signal by refusing write commands and KEYS. It does not name alternative tools for those cases, so it falls just short of full 5-level guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_queryRun Read-Only SQL QueryARead-onlyIdempotent
Execute a read-only SQL query (SELECT, WITH, and the engine's SHOW, DESCRIBE or EXPLAIN) on a MySQL, MariaDB, PostgreSQL, SQLite, SQL Server or ClickHouse connection
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | SQL query to execute, in the active engine's dialect | |
| database | No | Optional database to read from for this call only, without changing the active connection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive behavior. The description adds value beyond annotations by specifying exactly which SQL statement types are allowed and which DB engines are supported, giving the agent a concrete behavioral contract for what the tool accepts. No contradictions found.
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?
One tightly packed sentence with no wasted words. The primary action and scope are front-loaded, followed by allowed statements and engine list. Every phrase 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?
With only two parameters, high schema coverage, and annotations covering the safety profile, the description is largely complete. It explains what statements are executed and on which engines. Minor omissions like result format, row limits, or single-statement constraints would be useful but are not critical for a read-only query tool, especially with no output schema defined.
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?
Input schema provides 100% coverage with descriptions for both 'query' and 'database', so the description needs no param-level detail. It adds general context about statement types and engines, which is useful but not required beyond the schema. Baseline 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?
States a specific verb ('Execute'), a resource ('read-only SQL query'), enumerates allowed statement types (SELECT, WITH, SHOW, DESCRIBE, EXPLAIN), and lists supported engines. This clearly distinguishes it from sibling data-exploration tools, none of which execute 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 makes the tool's scope explicit (read-only SQL across listed engines), which implies when to use it: when arbitrary SQL querying is needed over a managed connection. It does not explicitly name alternatives or exclusions, but the read-only constraint and statement list effectively rule out write operations and non-SQL tools like redis_command.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchSearch IndexARead-onlyIdempotent
Search an Elasticsearch or OpenSearch index with a Query DSL body. Use size 0 with track_total_hits true to count, and aggs for aggregations
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Search body, e.g. {"query": {"match": {"title": "error"}}, "size": 10, "sort": [{"@timestamp": "desc"}]} | |
| index | Yes | Index name, pattern such as logs-*, or comma-separated list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the description doesn't need to repeat those. It adds useful context about how to perform count and aggregation operations via the body parameter, which is beyond the schema. However, it doesn't disclose potential errors (e.g., invalid DSL) or pagination behavior, but with annotations covering safety, a 3 is appropriate.
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, front-loaded with the purpose, then concise usage tips. Every word earns its place; no fluff.
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?
Given the tool's complexity (query DSL), the schema fully documents parameters, and annotations cover safety. The description adds critical usage patterns for counting and aggregation that an agent might not infer. Output schema is absent, but return format is likely clear from Elasticsearch conventions. It's nearly complete, missing only error-handling notes.
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 100%, and both parameters have descriptions in the schema. The description adds usage tips for the body parameter (size 0, track_total_hits, aggs), which is valuable but not directly explaining the parameters' semantics beyond what the schema says. So baseline 3 is correct, with a slight addition of context.
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?
Description states the verb 'Search' and the resource 'Elasticsearch or OpenSearch index' clearly, with a focus on Query DSL body. It distinguishes from sibling tools by being the generic search tool, though it doesn't explicitly name alternatives for filtering or aggregations (though it mentions aggs). It's clear but could be more specific about what makes it unique among siblings.
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?
Provides clear guidance on when to use size 0 with track_total_hits for counting and aggs for aggregations, which are specific use cases. However, it doesn't explicitly say when not to use this tool versus siblings like find_documents or aggregate, but the 'use aggs for aggregations' implies that for aggregation-specific tasks you might use aggregate instead, so it's implicit but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
use_connectionSwitch Connection ProfileAIdempotent
Switch to a named connection profile, on any engine. Takes effect immediately, no restart needed
| Name | Required | Description | Default |
|---|---|---|---|
| profile | Yes | Profile name from list_connections | |
| database | No | Optional database to use instead of the profile's own database |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as non-read-only, idempotent, and non-destructive. The description adds useful behavioral context beyond those: the switch takes effect immediately and requires no restart. This is meaningful operational information not present in the schema or annotations.
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 extremely compact and front-loaded: it states the action, then the scope, then the key behavioral caveat. Every word earns its place and there is no redundant 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 state-switch with one required parameter, the combination of description, schema, and annotations is complete: the source of valid profile names is given, the optional database behavior is documented, and the immediate effect is stated. No output schema exists, so return-value expectations are not a gap.
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%, and both parameters are already clearly documented: profile is a name from list_connections, and database is an optional override. The free-text description adds no additional parameter-level detail, so the baseline 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 uses a specific action-object pair ('Switch to a named connection profile') and adds engine-agnostic scope with 'on any engine.' This clearly distinguishes it from sibling tools like use_database, connect, and the list/current connection tools.
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 gives clear context for when the tool is relevant—switching an existing profile—and the 'no restart needed' note gives one practical selection criterion. However, it never explicitly mentions alternatives or says when not to use it, so the guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
use_databaseSwitch DatabaseAIdempotent
Switch the active database on the current server. Takes effect immediately, no restart needed
| Name | Required | Description | Default |
|---|---|---|---|
| database | Yes | Database name to switch to, or the database number on Redis |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as non-read-only, non-destructive, and idempotent. The description adds meaningful behavioral context—'Takes effect immediately, no restart needed'—telling the agent the operation has immediate runtime impact without a server restart. It also clarifies the scope to the current server. No contradiction with annotations.
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 short sentences with zero waste: the first states the core action and scope, the second adds a relevant behavioral note. The information is front-loaded and every sentence 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?
For a single-parameter utility with annotations covering idempotence and non-destructiveness, the description plus schema give an agent enough to call it correctly. It could mention error behavior or that the switch affects subsequent operations, but 'active database' is sufficiently clear. The minor gap keeps it at 4.
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?
The input schema provides 100% coverage of the single parameter, including the Redis variant ('or the database number on Redis'). The tool description adds no additional parameter-level detail, so the schema carries the semantic weight; the baseline 3 applies.
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 precise action: 'Switch the active database on the current server.' It clearly identifies the verb and resource, and 'on the current server' distinguishes it from connection-level operations like use_connection. However, it doesn't explicitly name or contrast with any sibling tool, so it falls just short of a 5.
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 implied usage context: it targets a database on the current server, which hints at when to use this versus use_connection or connect. It offers no explicit when-to-use/when-not-to-use guidance or named alternatives, but the 'current server' scoping and 'takes effect immediately' provide some directional context.
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.
18 tool updates
v0.1.0- First observed
aggregate - First observed
connect - First observed
count_documents - First observed
current_connection - First observed
describe_table - First observed
distinct_values - First observed
find_documents - First observed
get_foreign_keys - First observed
get_table_indexes - First observed
get_table_sample - First observed
list_connections - First observed
list_databases - First observed
list_tables - First observed
redis_command - First observed
run_query - First observed
search - First observed
use_connection - First observed
use_database
TDQS
Scored across 18 tools
Most tools target clearly distinct resources and actions, and engine-specific operations (run_query, find_documents, search, redis_command) are easy to tell apart. The only mild ambiguity is among context-switching tools like use_database, use_connection, and connect, though their descriptions clarify the differences.
Many tools follow a list_/get_/use_ verb_noun pattern, but standalone verbs like connect, aggregate, and search, plus noun-only names like distinct_values and redis_command, break the convention. The names are still readable and all snake_case, but the style is not uniform.
At 18 tools, this is slightly over the typical sweet spot, but the broad multi-engine scope (SQL, MongoDB, Elasticsearch, Redis) justifies the count. Each tool covers a distinct operation or engine, and none feel redundant.
The toolset covers the read-only database workflow end-to-end: connection selection, database/table discovery, schema inspection, sample data, and engine-specific query/aggregation/search/read operations. There are no obvious missing capabilities for a read-only toolset.
Maintenance
Related MCP Connectors
- dataOAuthco.thinair
PostgreSQL, MySQL, and SQL Server in one session. 26 read-only MCP tools for AI agents.
Query 40 databases from Claude, ChatGPT, or Cursor — on any device. Read-only, encrypted, audited.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides AI assistants with read-only access to inspect database schemas, preview data, and run safe queries across PostgreSQL, MySQL, MongoDB, and SQL Server. It enables AI tools to understand database structures and relationships automatically to generate more accurate code.7 npm7MIT
- FlicenseNot gradedqualityDmaintenanceEnables read-only SQL database access for AI assistants, allowing schema exploration and safe query execution without risk of data modification.-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to query SQL databases safely with read-only access, allowing schema discovery and SELECT queries while blocking writes and DDL operations.-
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to safely query and explore SQL Server and PostgreSQL databases with read-only access, supporting schema discovery, relationship exploration, and query execution.15 npm3MIT