Skip to content

Guide

Read-only database MCP for Claude Code and Codex

MCP / Claude Code / Cursor / PostgreSQL / SQL Server / AI database context

Before connecting Claude Code, Codex or Cursor to a production database via MCP, decide what the agent may touch. Three access levels, one schema-only.

The most common way to give a coding agent access to a database is also the most dangerous one: paste a connection string into an MCP server config and let the agent run SQL. It works on the first try, the agent writes better queries immediately, and the same login that lets it read information_schema lets it run DELETE when it decides a table looks like test data. Stories of agents dropping tables they misjudged now circulate often enough that most teams ask the question before connecting anything to production.

The useful question is narrower than "is MCP safe". It is what the agent actually needs from the database, and the answer is usually less than a SQL connection.

Three levels of database access through MCP

1. A SQL-executing server with a normal login. The agent can run anything the login can run. Prompting it to "only read" is a request, not a control. This level belongs on a local development database and nowhere else.

2. A SQL-executing server with a read-only login. Much better, and the minimum for anything shared. The protection has to come from the database itself: a role with only SELECT grants, or default_transaction_read_only on PostgreSQL, rather than a filter in the MCP server that inspects the SQL text, because text filters miss functions and procedures with side effects. Even fully read-only, the agent still reads rows, so customer data flows into the model context, and a careless join on two large tables still runs against production.

3. A schema-only server. The agent can ask what tables exist, what columns and types they have, which keys and indexes connect them, and what references what. It cannot run a query at all. For writing migrations, ORM models, joins and reports, this is most of what the agent was missing, because the usual failure is not that it cannot see the data. It guesses column names and invents relationships.

What to check before connecting any database MCP server

  • Which login it uses, and whether the database enforces read-only for that login.
  • Whether it can execute arbitrary SQL, or only answers fixed questions.
  • Whether results containing rows leave the network, and where they are logged.
  • Who can see the connection string in the MCP config, which often ends up committed to a repository.
  • Whether tool calls are recorded somewhere a human can review.

The Taavik MCP server is the third kind

Taavik exposes a remote MCP server at https://api.taavik.com/mcp. It does not open a connection to the database and has no tool that runs SQL. Its tools read the schema catalog that the on-premises agent already collected during its scans: list_connections, list_tables and describe_table, which returns columns, primary and foreign keys, indexes, tables that reference the one being described, and relationships the team declared by hand where no foreign key exists. whoami and, on the Pro plan, get_workspace and list_members describe the caller and the workspace.

Sign-in uses the same account as the workspace through an OAuth browser flow, so there is no database password or API key in the config file, and every tool call is recorded.

One detail is worth stating because it is the exception to "schema only". On the Pro and Enterprise plans, the agent also learns the value list of short, low-cardinality columns such as a status or type column, and describe_table can return those values so the agent writes WHERE status = 'shipped' instead of guessing. It never returns rows. The option is on by default for those plans and can be switched off per connection, which also deletes the values already collected.

Connecting it

In Claude Code:

claude mcp add --transport http taavik https://api.taavik.com/mcp

Or commit a .mcp.json at the project root so the whole team gets the same server:

{
  "mcpServers": {
    "taavik": {
      "type": "http",
      "url": "https://api.taavik.com/mcp"
    }
  }
}

In Codex CLI:

codex mcp add taavik --url https://api.taavik.com/mcp
codex mcp login taavik

or the equivalent [mcp_servers.taavik] table with url = "https://api.taavik.com/mcp" in ~/.codex/config.toml.

Cursor reads the same JSON block from .cursor/mcp.json. The first tool call opens a browser window to sign in. For SQL Server specifically, the SQL Server MCP guide compares this with Microsoft's Data API builder.

What a schema-only server cannot do

It cannot answer questions about the data: how many orders shipped last week, which customers churned. For that the agent needs level 2, and the honest setup is a separate read-only login on a replica with its own MCP server, kept apart from the schema context. The free plan includes the schema tools for one connection, which is enough to see how much better the agent's SQL gets when it stops guessing the column names.