The agent never writes SQL: queries compile from a semantic layer you control, PII refused first.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
[!IMPORTANT] This repository has moved into the Governed Agent Stack monorepo.
Active development is now at
packages/sql-steward/. This repo is archived and read-only. Its full commit history is preserved here; new work, issues and releases happen in the monorepo.
Part of the Governed Agent Stack: free, on-prem building blocks for an AI agent you can point at a real database and audit.
A governed SQL gateway for AI agents, exposed over the Model Context Protocol. The agent never gets a connection string and never writes SQL. It calls typed tools; sql-steward compiles every query from a semantic layer you control, refuses blocked PII before the query runs, and returns rows. Same tools across SQL Server, Postgres and SQLite.
Most SQL MCP servers hand the model a run_sql tool and try to catch the bad queries on the way out. sql-steward removes the tool. There is no path from a prompt to raw SQL at your database, because the only thing the agent can do is name an entity or a metric and pick from allow-lists you wrote.
See it defend a database live. The governed vs ungoverned demo runs the same request through a naive run_sql agent, which leaks customer PII and empties a table, and through sql-steward, which refuses it at compile time.
run_sql, query, or execute tool. The compiler can only ever build a SELECT, so a write isn't blocked, it's unrepresentable.audit-verify to prove nothing was rewritten.This YAML is the entire contract between the agent and your database. Review it like code.
Ask for a join that isn't defined and you get unreachable_entity, not an invented relationship. Ask to group a metric by a dimension that isn't listed and you get dimension_not_allowed. Misspell a metric or field and the error lists what does exist, with the closest spellings, so an agent corrects itself in one turn instead of making a second discovery call.
| Tool | Purpose |
|---|---|
list_entities() | What can be read, plus the available metrics |
describe_entity(entity) | Fields, types and PII tags (blocked ones flagged) |
list_metrics() | Metrics and the dimensions/filters each allows |
get_records(entity, fields, filters, order_by, limit) | Read rows from one entity |
get_metric(metric, dimensions, filters, limit) | Compute a pre-approved aggregate |
semantic_search(entity, query, k, filters) | pgvector nearest-neighbour search over an entity's embedding column |
audit_verify() | Verify the tamper-evident audit chain |
Filters are {field, op, value}; operators are =, !=, <, <=, >, >=, like, in, not in, is null, is not null. Values are always bound parameters, never inlined.
The semantic layer YAML lives wherever you point SQL_STEWARD_LAYER. Claude Desktop (claude_desktop_config.json):
SQL_STEWARD_DB_URL is a SQLAlchemy URL, so the same server reads SQL Server (mssql+pyodbc://...), Postgres (postgresql+psycopg://...) or SQLite (sqlite:///path.db). Install the matching driver with the extras: pip install "sql-steward[postgres]" or "[mssql]".
The semantic layer is the primary control. These are extra layers, all opt-in, and no-ops if the library isn't installed:
Give an entity a search block pointing at a pgvector column and the agent gets a semantic_search tool, governed exactly like everything else (PII refused, results masked, calls audited):
The query text is embedded locally (set SQL_STEWARD_EMBED_URL to a local Ollama endpoint, so nothing leaves the building), and matched with pgvector's <=> operator. PostgreSQL only. The embedding column is never returned.
sql-steward audit-verify checks it.sql-steward governs the path from the model to your database. It assumes the process that calls its tools is trusted. That boundary is the difference between deploying it safely and exposing it, so it is worth stating plainly.
What it enforces, whatever the model asks. Every call runs the same gate: read-only by construction, blocked PII refused before retrieval, an optional role check via query-warden, results masked by pii-veil, and a hash-chained audit of the call. A jailbroken model still cannot write, cannot read a blocked column, and cannot reach an entity the layer does not define. These hold by construction, not by trusting the model to behave.
What it does not do. sql-steward is an enforcement plane, not a front door.
SQL_STEWARD_ROLE is configuration, not a verified identity; sql-steward trusts that the role it is handed is the correct one.SQL_STEWARD_DB_URL and the audit key AGENT_BLACKBOX_KEY are read from the environment; supply them from a secret store, not a checked-in file.Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/sql-steward)<a href="https://allmcps.com/mcp/sql-steward"><img src="https://allmcps.com/api/badge/sql-steward?style=directory" alt="Sql Steward on AllMCPs" /></a>