Don't expose the database.
Expose the domain.

An open-source framework that turns relational databases into domain-oriented MCP servers. Declarative YAML packs, parameterized SQL, zero boilerplate. Small models beat raw SQL.

pip install mcp-blueprint
Get started Read the paper
PyPI version Python versions License CI
The problem

Your agent is writing SQL. It should be selecting tools.

Exposing a generic execute_sql tool forces the model to discover schemas, infer joins, re-derive business rules, and handle dialect differences on every request. That consumes reasoning capacity, introduces non-determinism, and pushes teams toward expensive frontier models just to compensate for an interface that exposes implementation details instead of business concepts.

🔍

Schema overhead

Enterprise schemas with hundreds of tables consume large portions of the context window before the model even begins reasoning about the user's question.

🎲

Probabilistic execution

Generated queries are synthesized anew each run. Missing joins, SELECT * scans, and Cartesian products can starve connection pools in production.

🔒

Business rules re-derived

Whether an account is "active" or a rental "overdue" depends on multi-column state evaluations. The model must re-derive these rules on every invocation.

Get started

Up and running in two minutes

Install

pip install mcp-blueprint            # Core: PostgreSQL, MySQL, MariaDB, SQLite
pip install mcp-blueprint oracle     # + Oracle
pip install mcp-blueprint clickhouse # + ClickHouse
pip install mcp-blueprint sqlserver  # + SQL Server
pip install mcp-blueprint duckdb     # + DuckDB (embedded, no server)
pip install mcp-blueprint databases  # + Oracle + ClickHouse + SQL Server

Use via MCP — Claude Desktop, OpenCode, Cursor, ...

{
  "mcpServers": {
    "pg-dba": {
      "command": "mcp-blueprint",
      "args": ["--config", "config/pg-dba.toml"]
    }
  }
}

Or create a domain pack in two files

# tools/film_stock.yaml
name: film_stock
description: Per-store stock for a film found by title.
parameters:
  title:
    type: string
    required: true
sql: ../sql/film_stock.sql
-- sql/film_stock.sql
SELECT f.title, s.store_id,
       COUNT(i.inventory_id) AS total_copies
FROM film f
JOIN inventory i ON i.film_id = f.film_id
JOIN store s ON s.store_id = i.store_id
WHERE f.title ILIKE '%%' || %(title)s || '%%'
GROUP BY f.title, s.store_id;
Architecture

How it works

The LLM never writes SQL — it selects from a curated set of domain tools. Every join, filter, and business rule lives server-side in reviewed SQL files.

LLM AgentMCP client
(Claude, OpenCode, Cursor...)
MCP BlueprintEngine layer
transports, pooling, validation
Domain PackYAML tools +
parameterized SQL
DatabasePostgreSQL, MySQL,
Oracle, ...
Invariants

Encapsulated data access

SQL lives in reviewed files, never generated at query time. Schema navigation, joins and filters are server-side guarantees.

Deterministic business rules

Overdue detection, availability checks, standing flags — computed once in SQL, reported by the model. Same input, same output, always.

Declarative tool definition

One YAML file + one SQL file per tool. Versionable, reviewable, testable. Port across engines without touching code.

Domain packs

One YAML + one SQL per tool

Packs are self-contained artifacts: YAML tool definitions, parameterized SQL files, and pack metadata. Add a domain operation as a configuration change, not a code change. Clone an existing pack and adapt it to your schema, or create one from scratch — the engine handles transports, pooling, and validation.

Sakila

The canonical example pack. DVD rental store chatbot: recommend films, inspect stock, review customer accounts.

PostgreSQL

PG DBA

PostgreSQL administration: connections, locks, indexes, vacuum, table bloat, long-running queries.

PostgreSQL

MySQL DBA

MySQL administration: connections, processlist, slow queries, replication status, table sizes.

MySQL MariaDB
Oracle ClickHouse SQL Server MariaDB DuckDB SQLite

Start from the Sakila example pack and adapt it to your domain — or create a new pack from scratch. One YAML + one SQL per tool, no Python code required.

Enterprise-ready

Built for production, not just prototypes

MCP Blueprint ships with the infrastructure that production deployments require: security by default, full audit trails, observability, and multi-engine support.

🛡️

Security by default

All SQL uses bound placeholders — no string interpolation, no injection surface. A SQL guard enforces read-only access and single-statement policy at both load time and runtime. Connections use least-privilege database roles.

📋

Audit trail

Every tool execution emits a structured JSONL record: tool, pack, parameters, duration, row count, status, cache hit, and trace ID. Validation rejections are audited too. Failed calls included.

📊

Prometheus metrics

16 metrics out of the box: tool calls, duration histograms, row counts, cache hit rates, connection pool stats, DB query latency. Optional — lazy-loaded, zero overhead when disabled.

🔄

Connection pooling

Async connection pools per engine: psycopg_pool for PostgreSQL, asyncmy for MySQL, oracledb for Oracle. Configurable min/max sizes, open timeouts, and pool recycling.

🗄️

Eight database engines

PostgreSQL, MySQL, MariaDB, SQLite, Oracle, ClickHouse, SQL Server, DuckDB. Same pack interface, same tool contracts — change the engine in config and your domain tools run unchanged.

📦

Declarative config

YAML-based configuration with environment variable expansion (${VAR:-default}). Separate config files for server, database, logging, and metrics — or a single monolith.

📝

Structured logging

JSON or console output via structlog. Rotating file handlers. Per-request context propagation with trace IDs. Sensitive values (passwords, tokens, DSNs) automatically redacted.

Response caching

TTL-based in-memory cache with per-tool TTL configuration. Cache metrics exposed to Prometheus. Shallow-copy on cache hit prevents mutation. Configurable maxsize (default 256).

🚀

Docker & cloud ready

Multi-stage Dockerfile, Docker Compose stacks, Render.com one-click deployment. Unprivileged container user. Health checks on all adapters. Smoke pack for zero-dependency deployment testing.

Evidence

Model Demotion: small models beat raw SQL

A public reproducibility benchmark compares three server designs across four local models (3B–8B) and seventeen enterprise-style tasks. The verticalized pack dominates every measured dimension. The smallest 3B model gains the most — the empirical signature of Model Demotion.

ApproachMean AccuracyFully-correct cellsZero-score cells
A: Raw SQL (execute_sql)0.66667 / 201 (33%)7 (3%)
B: Verticalized pack (MCP Blueprint)0.939174 / 204 (85%)3 (1%)
C: Generic thin-tool pack0.60563 / 204 (31%)19 (9%)
ModelA: Raw SQLB: VerticalizedC: Generic
llama3.2:3b0.5830.9290.419
qwen2.5:3b0.6840.9020.602
qwen2.5:7b0.6470.9580.631
llama3.1:8b0.7500.9660.769
ApproachTokens / correct answerSeconds / correct answer
A: Raw SQL11,85851.9 s
B: Verticalized3,5825.2 s
C: Generic9,37220.7 s

Tool design, not tool existence, creates value. A generic pack scores below raw SQL (0.605 vs 0.666). Full benchmark: mcp-blueprint-benchmark.

Research

The paper behind the framework

A peer-reviewed arXiv publication formalizes the Domain-Oriented Tooling Pattern and reports the full benchmark methodology, results, and analysis.

From SQL Generation to Tool Selection: A Domain-Oriented Pattern for MCP Servers

Bartolomeo Bogliolo · August 2026

The paper introduces the Domain-Oriented Tooling Pattern (three architectural invariants), formalizes Model Demotion (reducing interface complexity lowers the model tier required), and reports a public reproducibility benchmark: verticalized packs score 0.939 pooled mean accuracy vs 0.666 for raw SQL and 0.605 for generic tool packs, with cost per correct answer improving 2–12x.

Read on arXiv →