db-mcp
An MCP database gateway that lets you inspect databases, run safe read-only queries, and execute write statements only after an explicit, human-approved preview with a one-time token.
List available database connections (
list_connections).List tables and views in a connection (
list_tables).Describe table columns, keys, foreign keys, and indexes (
describe_table).Execute read-only SQL queries directly (
query), with results capped byDB_MAX_ROWS.Preview mutations and get a short-lived, single-use confirmation token (
preview_mutation).Execute approved mutations only when the exact SQL, connection, and token match (
execute_mutation).Manage credentials through an OS-level vault, including registering connections and importing them from allowed file paths.
Works with PostgreSQL and SQLite out of the box; Oracle, MySQL, SQL Server, and Snowflake are available with extra drivers.
Provides read-only and gated write access to MySQL databases, allowing agents to list tables, describe schemas, and execute read queries, with write operations requiring user approval via tokens.
Provides read-only and gated write access to PostgreSQL databases, allowing agents to list tables, describe schemas, and execute read queries, with write operations requiring user approval via tokens.
Provides read-only and gated write access to Snowflake databases, allowing agents to list tables, describe schemas, and execute read queries, with write operations requiring user approval via tokens.
Provides read-only and gated write access to SQLite databases, allowing agents to list tables, describe schemas, and execute read queries, with write operations requiring user approval via tokens.
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., "@db-mcpshow me the schema 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.
An MCP database gateway for LLM agents: read freely, preview writes, approve explicitly.
securedblink gives an LLM a controlled, auditable way to inspect and query databases through the Model Context Protocol. Read-only work runs immediately; every mutating statement must be previewed, bound to a single-use token, and explicitly approved before it touches the database. Credentials live in your OS credential manager — never in chat history, logs, or tool responses.
Table of Contents
Related MCP server: db-mcp
About
securedblink is a local MCP server that sits between your agent and your databases. You declare connections as DB_<NAME> environment variables — the suffix becomes the connection name exposed to the agent. The server classifies every statement: SELECT, EXPLAIN, SHOW/DESCRIBE, and safe WITH run through query; everything else (INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE…) is forced through the gated path.
Stack: Python 3.12+, SQLAlchemy 2.0, MCP 1.x, structlog, keyring. PostgreSQL and SQLite work out of the box; other dialects load via optional drivers.
Who it's for: engineers who want to let an agent explore schemas and run reads autonomously, but keep every write visible and reversible — ideal for analytics databases, staging environments, and local development.
How it works
Read lane — free. query executes immediately and returns rows capped by DB_MAX_ROWS (default 500).
Write lane — gated. The flow is deliberately visible:
1. Agent → preview_mutation(connection, sql) → securedblink returns plan + one-time token
2. Agent shows preview and asks for confirmation
3. Human approves in the MCP client
4. Agent → execute_mutation(connection, sql, token) → securedblink validates token
5. securedblink executes, consumes the token, returns the resultThe token binds the exact SQL string and connection name (SHA-256), expires after 5 minutes, and is single-use. A mismatched connection, altered SQL, expired token, or replay is rejected — even if the agent tries.
Vault lane — isolated. Aliases registered with securedblink register or register-from-path are stored in the OS credential manager (macOS Keychain, Linux Secret Service, Windows Credential Manager). The agent sees only the alias; values are redacted from logs and tool output.
Getting started
1. Install the command
Pick one distribution. The binary is the primary entry point for terminals and MCP clients.
macOS / Linux — standalone binary (recommended):
curl -fsSL https://raw.githubusercontent.com/paulushcgcj/securedblink/main/install.sh | bashWindows (PowerShell):
irm https://raw.githubusercontent.com/paulushcgcj/securedblink/main/install.ps1 | iexPyPI / uv — all platforms (use when you need extra drivers):
uv tool install securedblink
# optional drivers
uv tool install 'securedblink[oracle]'
uv tool install 'securedblink[mysql]'
uv tool install 'securedblink[mssql]'Standalone installers bundle PostgreSQL support only. Install via PyPI/
uv toolwhen you need Oracle, MySQL, or MSSQL drivers.
2. Connect a database
Set one or more DB_<NAME> variables. The suffix becomes the MCP connection name.
export DB_LOCAL=sqlite:///./local.db
export DB_ANALYTICS=postgresql://user:password@db.example.com:5432/analytics
export DB_MAX_ROWS=500 # optional; defaults to 500Prefer the credential vault for secrets (see below) rather than exporting passwords in plain text. Never commit real credentials.
3. Run it
securedblinkAn MCP client can now discover local and analytics, list tables, describe schemas, and run reads. Writes will surface a preview and wait for your explicit approval.
Configure an MCP client
The binary must be on the MCP client's PATH. If it isn't, replace securedblink with its absolute path (e.g. /usr/local/bin/securedblink).
Add to ~/.config/opencode/opencode.jsonc or .opencode.json in a project:
{
"mcp": {
"securedblink": {
"type": "local",
"command": ["securedblink"],
"environment": {
"DB_ANALYTICS": "postgresql://user:password@host:5432/analytics",
"DB_LOCAL": "sqlite:///./local.db",
"DB_MAX_ROWS": "500"
}
}
}
}Add to .vscode/mcp.json or ~/.vscode/mcp.json:
{
"servers": {
"securedblink": {
"type": "stdio",
"command": "securedblink",
"env": {
"DB_ANALYTICS": "postgresql://user:password@host:5432/analytics",
"DB_LOCAL": "sqlite:///./local.db",
"DB_MAX_ROWS": "500"
}
}
}
}Keep connection values in your MCP client's environment block or in the vault. Do not commit real credentials to config files.
What it protects
Operation | Behavior |
| Runs immediately through |
| Requires |
Approval token | Binds the exact SQL and connection; 5-minute expiry; single-use |
Credentials | Vault values stay in the system credential manager and never appear in tool responses or logs |
Supported databases
Any SQLAlchemy-compatible dialect works once its driver is installed. PostgreSQL and SQLite need no extra setup.
Database | URL example | Install |
PostgreSQL |
| Included |
SQLite |
| Built in |
Oracle |
|
|
MySQL |
|
|
SQL Server |
|
|
Snowflake |
| Install |
Tools
Tool | Purpose |
| List environment and vault connections |
| List tables and views |
| Show columns, keys, foreign keys, and indexes |
| Execute read-only SQL |
| Preview a write and issue an approval token |
| Execute an approved write |
| Store a connection in the credential vault |
| Import a connection from |
| List vault aliases and metadata |
| Remove a vault alias |
Credential vault
The vault stores credentials in the platform's secure store so the agent can use an alias without ever receiving the username or password.
Register from the terminal:
securedblink register \
--alias analytics \
--jdbc-url "postgresql://host:5432/analytics" \
--username user \
--password password \
--driver org.postgresql.Driver
securedblink listImport from a file — allow-list the directory first:
export SECUREDBLINK_ALLOWED_ROOTS="/path/to/configs"
securedblink register-from-path \
--alias analytics \
--file-path /path/to/configs/analytics.envSupported formats: .env, .properties, and Spring Boot-style .yml/.yaml. Paths outside SECUREDBLINK_ALLOWED_ROOTS are rejected; values are redacted from logs and errors.
Configuration
Variable | Default | Description |
| — | SQLAlchemy URL for a named connection |
|
| Maximum rows returned by |
| — | Colon-separated roots allowed for vault file imports |
Source checkout
Use run.sh for development — it syncs the project, reads .env, detects drivers from DB_* URLs, and installs missing drivers before starting:
DB_LOCAL=sqlite:///./local.db ./run.shThe installed binary does no setup preparation; configure its environment and optional drivers explicitly.
Development
Requirements: Python 3.12+ and uv.
uv sync
uv run pytest -q
uv run ruff check .
uv run mypy --strict securedblinkSee CONTRIBUTING.md for the full workflow and release process.
Security
Please report vulnerabilities according to SECURITY.md. Never place real database credentials in issues, pull requests, or committed config files.
License
Distributed under GPL-3.0.
Available Tools
6 toolsdescribe_tableA
Describe columns, primary key, foreign keys, and indexes for a table.
| Name | Required | Description | Default |
|---|---|---|---|
| connection_name | Yes | ||
| table_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It implies a read-only operation via the verb 'describe', but does not explicitly state non-destructiveness or any side effects. For a simple metadata tool, this is adequate but not thorough.
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, well-structured sentence that efficiently communicates the tool's purpose without redundancy. It is front-loaded with the verb and lists specific objects (columns, PK, FKs, indexes).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has two simple parameters and an output schema, so the description need not explain return values. However, it lacks context about prerequisites (e.g., connection must be valid) and error conditions. It is minimally sufficient for correct invocation but could be more complete.
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 0%, and the description does not elaborate on the meaning, format, or allowed values of 'connection_name' or 'table_name'. While parameter names are self-explanatory, the description fails to add value beyond the schema, which is required given the low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: describe columns, primary key, foreign keys, and indexes of a table. It distinguishes from siblings like list_tables (which only lists table names) and query (for data retrieval).
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 usage for obtaining table metadata but does not explicitly state when to use it over siblings or any prerequisites (e.g., connection must exist). No exclusions or alternative guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_mutationC
Execute a confirmed write or destructive SQL statement.
| Name | Required | Description | Default |
|---|---|---|---|
| connection_name | Yes | ||
| sql | Yes | ||
| confirmation_token | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description should disclose safety and effects. Only mentions 'confirmed write or destructive', but lacks detail on success/failure conditions, rollback, or data loss risks.
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?
Single sentence is concise but at the cost of omitted critical information. Not well-structured for quick comprehension of tool behavior.
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?
Despite having 3 required parameters and a destructive action, the description fails to cover prerequisites, return values, or error handling. Output schema existence does not compensate for missing behavioral 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 0%, so description must explain parameters. It does not describe 'connection_name', 'sql', or 'confirmation_token', leaving agents to infer meaning.
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 clearly states it executes a confirmed write or destructive SQL statement, distinguishing it from sibling tools like 'query' (reads) and 'preview_mutation' (preview).
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?
No guidance on when to use this tool versus alternatives like 'preview_mutation' or 'query'. Missing explicit instructions for confirmation flow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_connectionsA
List all database connections available via DB_ environment variables.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It clarifies the source (environment variables) but does not disclose read-only nature, authentication requirements, or return format. Adequate but minimal.
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?
Single sentence, front-loaded with key action and resource, no wasted words.
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 no-parameter tool with an output schema, the description is sufficiently complete: states what it lists and the source of connections.
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?
No parameters exist, and schema coverage is 100%. The description does not need to add parameter info; baseline score of 4 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 specific verb 'list' and resource 'database connections', and specifies they come from 'DB_<NAME> environment variables', clearly distinguishing from sibling tools like describe_table or query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage for enumerating available connections, but no explicit guidance on when to use vs alternatives like query or list_tables. Context suggests it's a prerequisite for other operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesC
List all tables and views in the specified database connection.
| Name | Required | Description | Default |
|---|---|---|---|
| connection_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavioral traits. It only states the tool lists tables/views without mentioning permissions, side effects, or pagination. This is insufficient for safe usage.
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 one sentence and concise, but it is too minimal for a tool with one required parameter. It lacks necessary detail while being short.
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?
Despite having an output schema (not shown), the description does not cover input semantics or usage context. It is incomplete for a simple tool, missing information about connection_name and error conditions.
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 has 0% description coverage for its single parameter 'connection_name'. The description does not explain what a connection name is, how to obtain it, or any constraints, adding no value 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 clearly states the verb 'list' and the resource 'tables and views in the specified database connection', which distinguishes it from sibling tools like describe_table (describes a single table) or query (queries data).
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 provides no guidance on when to use this tool versus alternatives such as describe_table or query. No when-to-use or when-not-to-use information is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_mutationB
Preview a write or destructive SQL statement and get a one-time confirmation token.
| Name | Required | Description | Default |
|---|---|---|---|
| connection_name | Yes | ||
| sql | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description bears full responsibility for behavioral disclosure. It indicates a preview action and token return but does not detail side effects, error behavior, or required permissions. The description is clear but lacks depth.
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 sentence that front-loads the action. Every word is necessary, and there is no 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?
Given the presence of an output schema, the description does not need to detail return values, but it fails to explain the token's purpose or that this is a safety step before mutation. The description is adequate but could be more complete.
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 0%, and the description provides no information about the parameters connection_name and sql beyond their names. The agent must infer their meaning, which is insufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: preview a write/destructive SQL statement and obtain a one-time confirmation token. It uses specific verbs and resource, distinguishing it from sibling tools like execute_mutation.
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 usage for previewing before executing, but it does not explicitly state when to use this tool versus alternatives like execute_mutation. No exclusion criteria or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
queryB
Execute a read-only SQL query on the specified connection.
| Name | Required | Description | Default |
|---|---|---|---|
| connection_name | Yes | ||
| sql | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It only discloses the read-only nature but fails to mention execution behavior, error handling, limits, or whether it supports multiple statements. This is insufficient for a query tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that conveys the core purpose without redundancy. It is concise but could benefit from additional details without being verbose.
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 presence of an output schema, return values need not be explained. However, the description omits critical context such as how connection_name is resolved, whether sql can be parameterized, and how the tool fits with siblings like list_connections. This leaves gaps for an agent.
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 0%, so description must compensate. It adds minimal context by referencing 'specified connection' and 'SQL query', but does not describe parameter syntax, allowed values, or any constraints (e.g., SQL dialect, query size limits).
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 explicitly states 'Execute a read-only SQL query' with a specific verb and resource, and distinguishes from sibling 'execute_mutation' which is for writes. The addition of 'read-only' clarifies the 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 implies this tool is for read queries (SELECT) and not for mutations, contrasting with sibling 'execute_mutation'. However, it does not explicitly state when not to use it or mention alternatives like 'preview_mutation' for previewing mutations.
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.
6 tool updates
v0.1.0- First observed
describe_table - First observed
execute_mutation - First observed
list_connections - First observed
list_tables - First observed
preview_mutation - First observed
query
TDQS
Scored across 6 tools
Each tool has a clearly distinct purpose: describing tables, executing mutations, listing connections, listing tables, previewing mutations, and read-only queries. No overlap or ambiguity.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., describe_table, execute_mutation, list_tables). Even 'query' fits the pattern as a simple verb.
With 6 tools, the set is well-scoped for a database MCP server. Each tool covers a distinct and necessary operation without redundancy.
The set covers basic read/write operations and metadata exploration but lacks DDL tools (create/alter tables) and transaction control. This may be intentional, but it leaves notable gaps for a comprehensive database interface.
Maintenance
Related MCP Connectors
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
AI agents propose database changes as reviewable requests — no direct write access.
Preventive human-approval write-gate for AI agents: writes commit only after a human approves.
AI agents need permission before production SQL writes. Pilot $100 · Gateway $299. Lint≠authorize.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables LLM clients to query SQL databases via natural language with read-only, AST-validated, and capped queries, ensuring safety guarantees.2MIT
- FlicenseNot gradedqualityCmaintenanceProvides read-only database access for AI agents across multiple databases (Postgres, MySQL, MongoDB, Elasticsearch) with enforced read-only guarantees and separate tools for prod and non-prod environments.-
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to safely work with SQLite databases by enforcing read/write separation, dry-run writes with confirmation, automatic backups, and an audit trail.MIT
- AlicenseNot gradedqualityCmaintenanceEnables LLM clients to safely inspect database schemas and run only approved read-only queries and stored procedures, with auditing.MIT