mcp-dbserver
Provides read-only access to MongoDB Atlas collections, including listing collections, retrieving documents, scanning documents, counting documents, and running vector search against Atlas Vector Search.
Provides read-only access to PostgreSQL databases via a fixed set of allowlisted queries, including listing available queries, executing them, and running pgvector-powered semantic search over the demo document dataset.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-dbserversemantic search the demo data for content similar to 'database security'"
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-dbserver
A self-built MCP server that gives an AI agent — Claude Code, Claude Desktop, or any MCP-compatible client — read-only, security-scoped access to three database engines at once: PostgreSQL (with pgvector), DynamoDB, and MongoDB Atlas (with Atlas Vector Search). It's a personal project extending 17+ years of multi-cloud database architecture work into the AI/agentic tooling space: the goal isn't "an agent can query a database," it's demonstrating the same least-privilege, defense-in-depth discipline a production reference architecture would demand, applied to a caller that's an LLM instead of a service.
No employer data, schemas, or business logic (current or former) appears anywhere in this repo — only public or synthetic data, generated specifically for this project.
Architecture
flowchart LR
Client["MCP client<br/>(Claude Code / Claude Desktop)"]
subgraph Server["mcp-dbserver (stdio)"]
direction TB
Tools["Fixed tool surface<br/>(no generic 'run query' tool)"]
Guard["guardrails.py + allowlist.py<br/>read-only + row-limit re-check"]
Tools --> Guard
end
Client -- "MCP tool calls" --> Tools
Guard --> PG[("PostgreSQL + pgvector<br/>RDS, IAM or password auth")]
Guard --> DDB[("DynamoDB<br/>fixed table-target registry")]
Guard --> Mongo[("MongoDB Atlas + Vector Search<br/>fixed collection-target registry")]Every arrow into a database is a named, allowlisted operation — never raw SQL, a raw MongoDB filter, or a raw DynamoDB key condition. See ARCHITECTURE.md for the full design.
Related MCP server: Secure RDS Read-Only MCP Server
Security model
This is the part of the project meant to differentiate it from a typical "point an agent at a database" demo. Full detail (including two things found by actually testing the guardrails, not just designing them) lives in ARCHITECTURE.md — summary:
Read-only, full stop. No write, update, or delete tool exists for any engine in v1. A write-capable version, if it ever exists, is a separate project with its own threat model.
A documented boundary, found by testing it. The "no write tool" guardrail constrains what an agent can do through the MCP protocol. It cannot constrain a code-capable client (like Claude Code, as opposed to a chat-only client like Claude Desktop) that has independent access to the same credentials. In testing, Claude Code correctly found no delete tool — then wrote its own
psycopgscript and attempted the delete directly, bypassing the MCP server entirely. It failed only because the configured database role lacked write privilege. That makes the database-/IAM-level read-only role the real last line of defense against a code-capable client, not the absence of a write method in this code — documented explicitly rather than left implicit.No raw queries from the agent. Every operation is a named, allowlisted shape with typed parameters — a fixed SQL template (Postgres), a fixed table/collection target registry plus a typed key (DynamoDB/MongoDB) — never a filter document, key-condition expression, or SQL string built from agent input. An earlier draft of the vector search tool took a table/column name as a direct argument and was caught and fixed (a real SQL injection surface via f-string interpolation) before the server was ever wired up to a live client.
Defense in depth at execution time. Even an allowlisted Postgres query is re-validated by
guardrails.pybefore running (rejects anything that isn'tSELECT/WITH, rejects stacked statements, enforces a row-limit ceiling regardless of what's requested), and every connection setsdefault_transaction_read_only = onat the database level.Credentials: environment variables only, never logged, never hardcoded. RDS IAM database authentication is supported and preferred over a stored Postgres password (a fresh ~15-minute token per connection via
rds:GenerateDBAuthToken, no long-lived DB secret at all).
Supported engines & tools
Engine | Tools |
PostgreSQL + pgvector |
|
DynamoDB |
|
MongoDB Atlas + Vector Search |
|
Full per-tool descriptions and the reasoning behind each one are in
ARCHITECTURE.md. semantic_search_documents
and semantic_search_mongodb run against the same demo dataset and the
same local embedding model, specifically so pgvector and Atlas Vector
Search results can be compared directly.
Setup
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env # fill in your own, personal, non-work credentialsRun the test suite (no live database required — guardrail/allowlist logic is unit tested against fakes for all three engines):
pytestRun the MCP server (stdio transport, for local use with Claude Code / Claude Desktop):
mcp-dbserverTools are only registered for engines whose required environment
variables are set — e.g. with only POSTGRES_DSN set, only the Postgres
tools appear. See .env.example for every variable, per engine.
Postgres demo dataset
data/demo_documents.jsonl is a small, synthetic set of ~30 short
software/infra explainer snippets (written for this project). Load it
and generate embeddings locally (fastembed's ONNX runtime — offline, no
external API key, no torch/torchvision dependency):
python scripts/load_demo_dataset.py
python scripts/smoke_test_postgres.py # connectivity + read-only guardrail
python scripts/verify_demo_dataset.py # row count + semantic search sanity checkDynamoDB
Tables aren't configured via environment variables — accessible tables
come from a fixed registry in engines/dynamodb.py (_TABLE_TARGETS).
Set AWS_REGION (and standard AWS credentials via env vars/profile/
instance role, scoped to dynamodb:GetItem/Scan/DescribeTable on the
registered table ARN(s)) to enable the *_dynamodb_* tools.
MongoDB Atlas demo dataset
Mirrors the Postgres setup exactly — same dataset, same embedding model —
so results are directly comparable. Set MONGODB_URI/MONGODB_DATABASE
(Atlas user with the built-in read role, not readWrite), then:
python scripts/load_demo_dataset_mongodb.py # upserts data + creates the Atlas Vector Search index
python scripts/verify_demo_dataset_mongodb.py # index builds asynchronously; re-run if search comes back emptyProject layout
src/mcp_dbserver/
guardrails.py # read-only + row-limit enforcement, engine-agnostic
allowlist.py # named, parameterized Postgres query registry
config.py # env-var credential loading, per engine
engines/
postgres.py # allowlisted queries + pgvector semantic search
dynamodb.py # fixed table-target registry, get/scan/count
mongodb.py # fixed collection-target registry, get/list/count/$vectorSearch
server.py # MCP entrypoint, registers tools per configured engine
tests/ # guardrail/allowlist/engine unit tests, all three engines (no live DB needed)
scripts/ # demo dataset loaders/verifiers, Postgres smoke testWhat I'd do differently at production scale
Being explicit about what v1 deliberately doesn't solve signals more than pretending it's production-complete:
Client ↔ server authentication. v1 runs over stdio, launched directly by the client as a subprocess — the OS process boundary is the trust boundary, which is fine for local, single-user use and not fine for anything else. A networked deployment (HTTP/SSE, reachable by more than one client) needs per-client API keys scoped per-engine, and TLS termination in front of the server, before it's anything but a demo.
Observability. No query logging or metrics yet. At minimum, before any networked deployment: which named query/operation was called, when, and whether it succeeded — deliberately never parameter values or row contents, to avoid quietly building a second copy of the data in logs.
Rate limiting. Not implemented; only matters once the server is reachable by more than a single local stdio client, but it's a gap worth naming rather than discovering under load.
MySQL. Explicitly out of scope for v1. Would follow the same allowlist + guardrail pattern as Postgres if added — no new design needed, just the fourth engine's worth of plumbing.
The DynamoDB/MongoDB filter-shape question got simpler than planned, not more complex. The original design considered a typed schema per allowlisted filter for DynamoDB/MongoDB. What shipped instead is smaller: a fixed target registry plus a fixed, small set of named operations per engine, with no generic
find(filter)orquery(key_condition)tool at all. Worth calling out because the instinct to build a validation DSL was the more "impressive-sounding" option, and the simpler one turned out to close the same gap more reliably — there's no permissive shape for$whereor an arbitrary key condition to hide in, because there's no field for one.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to securely query VAST Data databases for schema, metadata, and sample data via read-only SQL and MCP resources.MIT
- AlicenseNot gradedqualityBmaintenanceProvides read-only access to PostgreSQL databases via MCP, enforcing least-privilege roles, row-level security, masked views, and SQL AST guardrails to prevent data leakage and unauthorized operations, enabling AI agents to safely query sensitive production data.MIT
- FlicenseNot gradedqualityCmaintenanceEnables read-only access to company data across PostgreSQL, MongoDB Atlas, and flat files through MCP tools, allowing AI assistants to query and retrieve information via natural language.

MCP DB Gatewayofficial
AlicenseNot gradedqualityBmaintenanceProvides governed, read-only PostgreSQL access for AI agents via MCP. Enforces schema/table allowlists, query limits, and audit events.MIT
Related MCP Connectors
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Connect MCP clients to 2,000+ AI models without managing provider API keys.
A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/stanisraja/mcp_model'
If you have feedback or need assistance with the MCP directory API, please join our Discord server