The governed MCP server: access control and audit for AI data agents
A governed MCP server is a database MCP server with the access control and audit that the raw protocol leaves out: query-time table-level permissions scoped per user, and a per-user record of who asked what. What that means, and why an AI data agent needs it.
MCP is a protocol for handing an AI agent a set of tools. It is not a permission system. A database MCP server can give Claude the ability to run any query the connection can reach, and the protocol has nothing to say about who is asking or whether they should be allowed to.
That gap is easy to miss, because a raw database MCP server demos beautifully. You connect Claude to your warehouse, ask a question in English, and a correct answer comes back in seconds. Nothing about that moment reveals that the agent is querying through a single shared credential, that every person pointed at the same server can reach the same tables, and that no record ties any question to the person who asked it. A governed MCP server is the same connection with those three holes filled.
The short version. A raw database MCP server exposes query tools backed by one shared credential, so anyone connected can reach anything that credential can, with no attribution. A governed MCP server adds an access-control boundary that runs before the warehouse and is scoped to the individual user, a per-user audit trail of question plus SQL plus person, and the shared context and definitions that keep answers consistent. The protocol stays the same. The layer behind it changes.
What the protocol actually does
MCP standardizes how a model discovers and calls tools. A database MCP server implements a few of them: list the tables, describe a schema, run a query. The agent reads what is available and decides what to call. That is the whole contract, and it is a good one. It is why you can swap Claude for ChatGPT and the setup keeps working.
What the contract does not include is any notion of identity or authorization. The server holds a database connection, and whatever that connection can touch, the tools can touch. There is no built-in idea of "this user gets these tables and not those," because MCP was designed to expose capabilities to a model, not to decide which human behind the model is entitled to them. Authorization is left to the implementation, and a bare connector implements none of it.
Where a raw database MCP server stops
Walk through what is actually missing once a second person connects to the same server.
Identity. The database sees one login: the role in the connection string. It cannot distinguish the finance lead from a sales hire from a contractor whose laptop went missing. Every question arrives as the same user, so nothing downstream can make a decision based on who is asking.
Access control. Because there is one credential, everyone reaches every table that credential can. There is no mechanism for marketing to query campaign tables while payroll stays out of reach. You can lean on database grants to carve this up, but then you are maintaining a parallel set of roles and re-applying them on every schema change, and most teams quietly skip it and hope nobody asks the wrong question.
Audit. No log records which person asked what, what SQL ran, or what came back. When a number from the agent lands in a decision and someone later asks how it was produced, there is nothing to trace it to. A shared service account cannot answer "who ran this," because as far as the warehouse is concerned, one account ran everything.
The failure mode here is not that the agent writes broken SQL. It is that it writes perfectly correct SQL against a table the person asking should never have reached, and no one can tell afterward that it happened.
What "governed" adds
A governed MCP server is a database MCP server that carries the missing layer inside the same tool contract. Three things change, and none of them changes how the agent connects.
Access control enforced before the warehouse
The boundary belongs in the layer that hands the agent its tools, not in a prompt asking the model to behave and not in a filter applied after results come back. When a specific user's agent lists tables, it should only ever see the tables that user is permitted to query. A question about a table outside that boundary never becomes SQL, because the tool to reach it was never exposed to that user in the first place.
Scoping this way has a second effect that has nothing to do with security. Every table you keep out of a user's reach is a table the model cannot get confused by. An agent choosing among the twelve tables relevant to a marketing question is more accurate than one choosing among two hundred, so the access boundary doubles as context narrowing.
A per-user audit trail
Every question ties back to a person, the SQL that ran, and the time it ran. The point is not that anyone reads the log daily. The point is that "who asked this, and what did the system actually run" is a question a team eventually has to answer, usually at the least convenient moment, and it can only be answered if attribution was captured when the query happened rather than reconstructed later from nothing.
Shared context and definitions
The third piece is quieter than the other two but it is the one that keeps answers consistent. The governed layer holds what each table means, how a metric like revenue or active user is defined, and the known-good queries worth reusing, and it serves that to every agent that connects. Without it, each person's model re-guesses the schema and two people asking the same question get two different numbers. With it, the definition is written once and every query draws on the same one.
Why the layer has to sit at the MCP boundary
You could imagine bolting permissions onto the agent instead: give Claude a system prompt listing which tables it may touch. That does not hold. A prompt is a request, and a capable model handed a broad credential can be talked around it, or can simply reach for a table the prompt forgot to mention. The boundary only means something if the tool to cross it was never handed over.
Putting governance at the MCP layer also keeps the agent swappable. The team connects whatever model they already use, and the access control and audit apply the same way whether that is Claude today or a stronger model next quarter. The governance is the durable asset. The agent on the other end is a detail. This is the part a proprietary in-app analyst cannot match, because there the model and the boundary are welded together and you take both or neither.
How to tell a governed server from a connector
If a tool bills itself as a governed or secure MCP server, these are the questions that separate a real one from a connector with a nicer landing page.
| Capability | What to look for |
|---|---|
| Identity | Each person is a distinct user, not one shared connection role |
| Access control | Table-level, scoped per user, enforced before the warehouse runs anything |
| Enforcement point | The boundary lives in the tool layer, not in a system prompt |
| Audit | Every query attributable to a person, with the exact SQL that ran |
| Context | Schema meaning and metric definitions served to every agent, kept current |
| Agent | Works with the model your team already uses, not a locked-in bot |
One limit I would want a reader to know before starting: access control at this layer is table-level, not row-level. It decides which tables a user's agent can reach, not which rows inside a table they can see. If your requirement is that two sales reps querying the same orders table each see only their own accounts, that is row-level security, and a table-level boundary does not deliver it. For most teams the meaningful line runs between tables, payroll here, campaigns there, but if yours runs inside a table, this is the wrong tool and you should know that before you start.
One governed MCP layer
Contextflo is a governed MCP server in the sense this page describes. It connects to your warehouse, scopes every query per user through table-level access controls that run before the warehouse, logs who asked what along with the SQL that ran, and serves the same schema descriptions, metric definitions, and saved queries to whatever agent connects over MCP.
To make it concrete: Tilt, a live-auction marketplace for limited-edition goods, runs around 6,000 AI-driven queries a month across a mostly non-technical team with one person owning the data. That volume is only safe because access is scoped per person and every query is attributable, and it stays useful because the definitions and saved queries are shared rather than re-guessed in each chat. The same MCP connection a raw connector would give you, with the three holes filled.
It is free for one user and one data source if you want to see the shape of it before deciding whether the governed part matters for your team.