DEV Community

Bora Kilicoglu
Bora Kilicoglu

Posted on

AI-Safe MCP Server for SQL

Giving an AI direct database access is one of those ideas that sounds useful immediately and dangerous a few seconds later.

You want the model to inspect schema, understand relationships, run queries, and help with analysis. But you also do not want it to mutate data, run unrestricted SQL, or pull back massive result sets because a prompt was vague.

That was the motivation behind ajan-sql.

It is a small MCP server for SQL that gives AI clients schema-aware, read-only SQL access with a guard layer in front of query execution.

What ajan-sql does

ajan-sql runs as an MCP server over stdio and connects to SQL through DATABASE_URL.

It currently exposes these tools:

  • list_tables
  • describe_table
  • list_relationships
  • run_readonly_query
  • explain_query
  • sample_rows

It also exposes schema resources:

  • schema://snapshot
  • schema://table/{name}

The goal is simple: give LLMs useful database visibility without handing them unsafe SQL execution.

Why I built it

A lot of AI + database demos jump from “the model can write SQL” straight to “let it query production-ish data.”

That gap matters.

In practice, if you want this to be usable, you need a few things:

  • schema discovery
  • safe defaults
  • hard query restrictions
  • predictable outputs for clients

I wanted something that felt closer to:

sql + schema awareness + an AI-safe guard layer

But packaged in a way that works naturally with MCP clients.

The safety model

The core rule is that query execution must stay read-only and constrained.

ajan-sql enforces:

  • SELECT only
  • rejection of INSERT
  • rejection of UPDATE
  • rejection of DELETE
  • rejection of DROP
  • rejection of ALTER
  • rejection of TRUNCATE
  • rejection of multi-statement SQL
  • rejection of SQL comments
  • default LIMIT 100
  • max query timeout of 5 seconds
  • max result size checks

That means the model can inspect and analyze, but it cannot mutate the database through this server.

Tooling that is actually useful

The schema tools are what make the server practical instead of just being a thin SQL wrapper.

list_tables

Returns visible tables and includes extra metadata such as:

  • schema
  • table name
  • table comment
  • estimated row count

describe_table

Returns:

  • columns
  • data types
  • nullability
  • default values
  • primary key metadata
  • unique metadata
  • foreign key references
  • index metadata

list_relationships

Returns foreign key relationships across the schema.

run_readonly_query

Executes guarded SELECT queries and returns:

  • normalized SQL
  • row count
  • duration
  • column metadata
  • rows

explain_query

Runs EXPLAIN (FORMAT JSON) and returns:

  • query timing
  • raw plan
  • a lightweight summary of the root plan node

sample_rows

Returns a limited sample from a table and can optionally target selected columns.

Structured outputs matter

One thing I wanted from the beginning was output that works well for both humans and clients.

So the tools now return both:

  • content for a short human-readable summary
  • structuredContent for machine-friendly consumption

That makes the server easier to use from MCP-compatible clients that want stable structured payloads instead of parsing JSON from plain text.

Example setup

Install it globally:

npm install -g ajan-sql
Enter fullscreen mode Exit fullscreen mode

Top comments (0)