Unified read-only MCP server for local PostgreSQL, MySQL, and Redis
local-db-mcp
local-db-mcp is a unified read-only MCP server for local PostgreSQL, MySQL, and Redis instances.
It is designed for AI-assisted development workflows where an agent needs safe, structured access to local databases without write privileges and without returning oversized payloads that can overwhelm the client context window.
Features
- One MCP server for PostgreSQL, MySQL, and Redis
- Read-only by design
- Query/result truncation to keep responses bounded
- Target-level enable/disable support
- Safe Redis reads with bounded scans instead of unbounded full dumps
- Streamed SQL row collection with early stop at configured limits
- Designed for local
stdioMCP clients such as Codex Desktop
Implemented tools
health_checklist_targetslist_databaseslist_tablesdescribe_tablesample_rowsrun_read_querylist_redis_keysread_redis_keyredis_key_meta
Requirements
Runtime requirements
- Linux or WSL2
- Access to one or more of:
- PostgreSQL
- MySQL
- Redis
This project uses sqlx with Rustls, so you do not need system PostgreSQL or MySQL client libraries just to run the binary.
Build requirements
- Rust toolchain
- Cargo
Recommended installation:
curl https://sh.rustup.rs -sSf | sh
source "$HOME/.cargo/env"
rustc --version
cargo --version
Project layout
local-db-mcp/
Cargo.toml
README.md
config/
local-db.example.toml
src/
adapters/
guards/
tools/
Configuration
Copy the example config and fill in your own local connection strings:
cp config/local-db.example.toml config/local-db.toml
Example:
[server]
name = "local-db-mcp"
instructions = "Unified read-only MCP server for local PostgreSQL, MySQL, and Redis targets."
default_row_limit = 50
max_row_limit = 200
default_key_limit = 50
max_key_limit = 100
max_value_chars = 4000
query_timeout_secs = 5
[targets.pg_local]
type = "postgres"
dsn = "postgresql://YOUR_USER:YOUR_PASSWORD@127.0.0.1:5432/YOUR_DATABASE"
enabled = true
[targets.mysql_local]
type = "mysql"
dsn = "mysql://YOUR_USER:YOUR_PASSWORD@127.0.0.1:3306/YOUR_DATABASE"
enabled = false
[targets.redis_local]
type = "redis"
dsn = "redis://127.0.0.1:6379/0"
enabled = false
config/local-db.toml is intentionally ignored by git so local credentials do not end up in the repository.
Development build
cargo run -- --config config/local-db.toml
Release build
cargo build --release
The release binary will be written to:
target/release/local-db-mcp
Manual startup
This MCP server is usually launched by the client on demand, but you can start it manually for debugging:
./target/release/local-db-mcp --config config/local-db.toml
If you run it directly in a terminal, it will wait for an MCP client to send initialize. That is expected behavior for a stdio MCP server.
Codex Desktop integration
Add a local_db entry to your Codex config:
[mcp_servers.local_db]
command = "/absolute/path/to/local-db-mcp/target/release/local-db-mcp"
args = ["--config", "/absolute/path/to/local-db-mcp/config/local-db.toml"]
Example on WSL:
[mcp_servers.local_db]
command = "/home/your-user/mcp_servers/local-db-mcp/target/release/local-db-mcp"
args = ["--config", "/home/your-user/mcp_servers/local-db-mcp/config/local-db.toml"]
After updating the config, restart Codex Desktop or reload MCP servers.
Deployment notes
For a local stdio MCP deployment you typically only need:
- the compiled binary
- your private
config/local-db.toml
This binary is dynamically linked against common Linux system libraries, so deploy it to a compatible Linux environment or WSL instance.
Suggested deployment layout:
/home/your-user/mcp_servers/local-db-mcp/
config/local-db.toml
target/release/local-db-mcp
Privacy and repository hygiene
- Do not commit
config/local-db.toml - Do not hardcode real DSNs, passwords, tokens, or secrets in source files
- Keep example configuration placeholders generic
- Review your config before copying screenshots or logs into issues or PRs
Safety model
This server is intentionally read-only.
Current protections include:
- disallowing write-oriented SQL statements
- limiting row counts before collecting full result sets
- limiting Redis key scans and collection reads
- truncating large values before returning them to the client
- allowing targets to be disabled in config
Future improvements
- Environment-variable based DSN loading
- HTTP transport for remote clients
- Audit logging
- Optional write-enabled mode with explicit safeguards
- Additional type handling and richer schema metadata