sqlmesh-mcp
MCP server exposing a SQLMesh project to LLM agents: model metadata, bounded data previews, plan previews, column-level lineage, audits/tests, environment diffs, resources, and reusable prompts.
Not officially affiliated with SQLMesh or Tobiko Data.
Why
SQLMesh's standout feature is column-level lineage, which is exactly the kind of question an agent is good at answering interactively ("where does revenue in finance.daily_summary come from?") that a CLI isn't. As of writing, the only prior MCP server for SQLMesh (sherman94062/sqlmesh-mcp) is a small unmaintained side project — this one aims to be documented, tested, and kept current with SQLMesh's API.
Install
pip install sqlmesh-mcp
Usage
Point it at a SQLMesh project directory:
{
"mcpServers": {
"sqlmesh": {
"command": "sqlmesh-mcp",
"env": { "SQLMESH_PROJECT_PATH": "/path/to/your/sqlmesh/project" }
}
}
}
Example
Calling list_models against examples/demo_project (a stock sqlmesh init duckdb project) returns:
[
{
"name": "sqlmesh_example.full_model",
"kind": "FULL",
"description": null,
"owner": null,
"tags": [],
"columns": { "item_id": "INT", "num_orders": "BIGINT" }
},
{
"name": "sqlmesh_example.incremental_model",
"kind": "INCREMENTAL_BY_TIME_RANGE",
"description": null,
"owner": null,
"tags": [],
"columns": { "id": "INT", "item_id": "INT", "event_date": "DATE" }
},
{
"name": "sqlmesh_example.seed_model",
"kind": "SEED",
"description": null,
"owner": null,
"tags": [],
"columns": { "id": "INT", "item_id": "INT", "event_date": "DATE" }
}
]
From there, lineage("sqlmesh_example.full_model", "num_orders") traces that column back to incremental_model.id — the kind of question this server exists for.
Tools
| Tool | Read-only? | Description |
|---|---|---|
list_models |
Yes | List all models in the project with kind, columns, description |
get_model |
Yes | Full detail for one model |
get_model_dependencies |
Yes | Direct upstream and downstream model dependencies |
fetch_model_data |
Yes | Bounded preview of current model data, capped by SQLMESH_MAX_RESULT_ROWS |
server_info |
Yes | Project, capability, transport, and safety configuration metadata |
start_plan |
Yes | Start a plan preview in the background and return a job ID |
start_run |
No | Start a scheduled model run in the background; requires confirm=true |
get_job_status |
Yes | Inspect a background plan or run job |
cancel_job |
No | Cancel a queued background job |
model_impact |
Yes | Return transitive upstream and downstream model impact |
environment_health |
Yes | Summarize environment existence, snapshots, and project drift |
audit_history |
Yes | Read recent dataveil audit events without cell values |
plan |
Yes | Preview what a plan against an environment would change |
apply_plan |
No | Apply a previously-previewed plan. Requires confirm=true. |
lineage |
Yes | Column-level lineage for a model's column |
run_audit |
Yes | Run a model's audits |
run_test |
Yes | Run a model's unit tests |
diff_environment |
Yes | Diff two environments |
list_environments |
Yes | List every environment that exists in the project's state |
table_diff |
Yes | Compare two tables or environments with structured schema and row differences |
format |
Check only by default | Check or format SQLMesh model and audit files; writing requires confirm=true |
run |
No | Execute scheduled/due model runs for an environment (what a cron trigger would do). Requires confirm=true. |
profile_model |
Yes | Aggregate-only profile of a model's columns (null rates, numeric stats, generalized string format signatures). No raw rows or samples; numeric stats withheld for small or constant columns (see dataveil's Known limits). |
propose_cleansing_plan |
Yes | Profile + a local sensitivity classification per column (PII:EMAIL, PII:SSN, ...) + the operation vocabulary apply_cleansing_plan accepts — the contract an agent reasons over to build a plan. |
apply_cleansing_plan |
No | Validate and apply a data-cleansing plan (mask/drop/impute/... from a closed, pre-tested operation vocabulary — never LLM-generated code). Requires confirm=true. |
register_cleansing_plan |
Yes | Register a plan for later approval instead of applying it directly. Validates it immediately. Only useful when DATAVEIL_REQUIRE_PLAN_APPROVAL=true (see below). |
approve_cleansing_plan |
No* | Mark a registered plan approved by someone. Doesn't touch real data — not read-only (it mutates server-side approval state), not destructive either. |
apply_plan, run, start_run, and apply_cleansing_plan change real data in whatever warehouse the project points at. format changes project files when called with check=false, while approve_cleansing_plan and cancel_job mutate server-side state without changing warehouse data. Destructive tools are marked destructiveHint/non-readOnlyHint in their MCP annotations so clients can warn a user before calling them.
profile_model/propose_cleansing_plan/apply_cleansing_plan are powered by dataveil: profiling, PII classification, and plan execution happen locally against aggregate SQL only (never a sample of raw rows), and a cleansing plan can only reference a small, pre-tested operation vocabulary — never SQL or code an LLM wrote itself. See that project's README for its known limits. Note: apply_cleansing_plan writes directly to a model's physical snapshot table, outside SQLMesh's own state tracking — a FULL-kind model's next scheduled run/plan apply will rematerialize it and silently undo the cleansing.
MCP resources and prompts
The server also publishes MCP resources for clients that support browsing context:
| Resource | Description |
|---|---|
sqlmesh://models |
JSON metadata for every model |
sqlmesh://models/{model_name} |
Rendered SQL and metadata for one model |
sqlmesh://lineage/{model_name}/{column} |
Column-level lineage as JSON |
Reusable prompts are available as explain_model and review_plan. They guide an agent through model analysis and plan review while keeping the final mutation step explicit.
Optional plan-approval gate
By default, apply_cleansing_plan accepts a plan directly (plus confirm=true) — the same posture apply_plan/run already have. Setting DATAVEIL_REQUIRE_PLAN_APPROVAL=true adds a second, independent gate for cleansing plans specifically: apply_cleansing_plan then refuses a plan passed directly and instead requires a plan_id from a plan that was register_cleansing_plan'd and then approve_cleansing_plan'd — by a different call, potentially a different reviewer. confirm=true is still required on top of that approval, not instead of it. A plan is discarded from the registry once applied, so it can't be replayed. Off by default; turn it on once this touches anything with real compliance stakes.
Every call to these three tools is appended to a local JSON-lines audit log (<project>/.dataveil/audit.jsonl by default; override with DATAVEIL_AUDIT_LOG_PATH) — who/what/when, enough to reconstruct what happened without re-running anything, never a literal cell value.
One server process is scoped to a single SQLMesh project, set once via SQLMESH_PROJECT_PATH (the context is cached for the life of the process). Point a client at multiple projects by running multiple server instances, one per SQLMESH_PROJECT_PATH.
Safety and transports
Set SQLMESH_ALLOWED_ENVIRONMENTS=prod,staging to restrict plan, run, diff, and table-diff calls to an environment allowlist. When set, mutation calls must include an explicit environment. SQLMESH_MAX_RESULT_ROWS defaults to 100 and caps both data previews and table-diff samples. SQLMESH_PLAN_TTL_SECONDS defaults to 900, and SQLMESH_PLAN_CACHE_SIZE defaults to 100; cached plans expire and are bound to the configured project path. Set SQLMESH_READ_ONLY=true to disable warehouse, file, and approval-state mutations. Mutating tools still require their individual confirm=true gates.
fetch_model_data masks columns whose names suggest email, phone, SSN, social-security, or address data. Set SQLMESH_PREVIEW_COLUMNS to a comma-separated column allowlist, or pass columns per call. Unmasked values require the explicit SQLMESH_ALLOW_UNMASKED_PREVIEW=true opt-in and every preview is audit logged.
stdio remains the default transport. For a networked MCP client, run Streamable HTTP with:
MCP_TRANSPORT=streamable-http \
SQLMESH_PROJECT_PATH=/path/to/project \
MCP_HOST=127.0.0.1 MCP_PORT=8000 \
sqlmesh-mcp
The endpoint is available at http://127.0.0.1:8000/mcp by default. Set MCP_AUTH_TOKEN to protect HTTP requests with Authorization: Bearer <token>; non-loopback binding is refused unless a token is configured. Use TLS or an authenticated reverse proxy for production deployment.
For named clients and least-privilege access, use MCP_AUTH_TOKENS with a JSON object. Supported scopes are read, mutate, approve, write, and operate:
MCP_AUTH_TOKENS='{"analyst":{"token":"read-secret","scopes":["read"]},"deployer":{"token":"deploy-secret","scopes":["read","mutate","operate"]}}' \
MCP_TRANSPORT=streamable-http sqlmesh-mcp
Each client may also include an expires_at Unix timestamp. MCP_AUTH_TOKEN remains supported as a legacy full-scope token. Authenticated client IDs are included in dataveil audit details.
Approval-gated cleansing plans are persisted at <project>/.dataveil/approvals.json with restrictive file permissions. Override the location with DATAVEIL_APPROVALS_PATH when the project filesystem is not durable.
Testing
See TEST_CASES.md for a plain-English index of every test case and what it covers, including a real bug the protocol-level tests caught that direct function-call tests couldn't (tool errors getting silently replaced with a generic message unless raised as the SDK's own ToolError).
License
MIT
Metadata
Release files for sqlmesh-mcp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| sqlmesh_mcp-0.3.0.tar.gz | 34.4 kB | With provenance | Details for sqlmesh_mcp-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| sqlmesh_mcp-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for sqlmesh_mcp-0.3.0-py3-none-any.whl |
Total release size: 53.2 kB
Release files / sqlmesh_mcp-0.3.0.tar.gz
| Download URL | sqlmesh_mcp-0.3.0.tar.gz |
|---|---|
| Size | 34.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a309d7e98dceff0186704143898c8f4d8d83942a6c6e06f7347ae036eadc379f
|
|
BLAKE2b-256 checksum How to use checksums |
14b81e32537fa640b6d5c8ba0431bd90a7f2a3bf857a8c03cf1af5c1afc8d76a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / sqlmesh_mcp-0.3.0-py3-none-any.whl
| Download URL | sqlmesh_mcp-0.3.0-py3-none-any.whl |
|---|---|
| Size | 18.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
07faa45989693c30a274168dd54b7cb345479bd39f9e692df7ad8cec6e97d907
|
|
BLAKE2b-256 checksum How to use checksums |
8b70a8e7768212f60b2699d7a8da29a30e964a921121553d0c843ea55c7f47c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logSecurity for sqlmesh-mcp 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for sqlmesh_mcp-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.