mcp-data-tools
Provides tools for querying BigQuery and inspecting Google Cloud Storage objects, with guardrails like allow-lists and cost ceilings.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-data-toolsCheck the null rate in the orders table."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-data-tools
A governed Model Context Protocol (MCP) server for data-platform operations.
Give an LLM agent the ability to query BigQuery, inspect GCS, trigger Airflow DAGs, and run data-quality checks — without giving it the ability to scan an unbounded table, touch a dataset outside its remit, or run anything but a read-only query. Every tool call is dry-run estimated, checked against an explicit allow-list, capped by a cost/row ceiling, and written to an audit trail before it ever reaches a real backend.
Why this exists
Agentic data platforms (NL2SQL assistants, on-call/triage agents, data
copilots) all eventually hit the same problem: an LLM agent that can call
a real query engine is, by construction, an LLM agent that can be
prompt-injected or simply mistaken into running a full-table scan, reading
a dataset it shouldn't, or mutating data it was only supposed to read.
Most MCP servers for data tools wrap the backend SDK directly and call it
done. mcp-data-tools treats the guardrail layer as the actual product:
Allow-listed resources. BigQuery tables, GCS buckets, and Airflow DAGs are matched against explicit glob patterns. Nothing is reachable by default.
Enforced read-only SQL. A lexical check rejects anything that isn't a bare
SELECT/WITH, with comments and string literals stripped first so neither can be used to smuggle a write statement past the check.Two-phase table authorization. A cheap preflight check denies obviously out-of-policy queries before any backend call — so an agent can't even use a dry run to probe the existence/schema of a non-allow-listed table — followed by an authoritative check against the backend's own dry-run result. See
docs/SECURITY.md.Real, enforced cost ceilings.
max_bytes_billedis passed straight through to the backend's execution API, so it holds even if a stale estimate undercounts a table that grew in the meantime.A fail-closed audit trail. Every decision — allowed or denied — is logged. If the audit sink itself is unavailable, the request is denied rather than let through unaudited.
Related MCP server: @us-all/dbt-mcp
Architecture at a glance
flowchart LR
Agent[LLM Agent] -->|MCP / JSON-RPC| Server[mcp-data-tools]
Server --> Guardrails[GuardrailEngine]
Guardrails --> Audit[(Audit Trail)]
Server --> BigQuery[(BigQuery)]
Server --> GCS[(GCS)]
Server --> Airflow[(Airflow)]Full component and sequence diagrams, plus the design decisions and
trade-offs behind them, are in docs/ARCHITECTURE.md.
Tools exposed
Tool | What it does | Guarded by |
| Dry-runs SQL, returns projected bytes/cost/tables — no data returned | Read-only check, table allow-list |
| Executes a read-only SQL query | Read-only check, table allow-list, byte/row ceiling |
| Runs | Same as |
| Fetches metadata for one GCS object | Bucket allow-list |
| Lists objects under a prefix | Bucket allow-list |
| Triggers a new Airflow DAG run | DAG-id allow-list |
| Fetches a DAG run's status | DAG-id allow-list |
Quick start
No cloud credentials required — this runs entirely against in-memory mock adapters, the same ones the test suite uses:
git clone https://github.com/umamahesh-ade/mcp-data-tools.git
cd mcp-data-tools
python -m venv .venv && source .venv/bin/activate
pip install -e .
python examples/quickstart.pyYou should see an allowed query, a data-quality report, a denied query (hitting a table outside the allow-list), and the resulting audit trail — all in a few dozen lines of output.
Installation
pip install -e ".[dev]" # base + testing/linting
pip install -e ".[gcp]" # + google-cloud-bigquery, google-cloud-storage
pip install -e ".[azure]" # + Azure Key Vault secret resolution
pip install -e ".[all]" # everythingRunning the real MCP server
cp configs/full-example.yaml configs/my-config.yaml
# edit configs/my-config.yaml: project ids, allow-list patterns, Airflow URL
cp .env.example .env
# fill in AIRFLOW_TOKEN, GOOGLE_APPLICATION_CREDENTIALS, etc.
mcp-data-tools validate-config --config configs/my-config.yaml
mcp-data-tools serve --config configs/my-config.yamlThe server speaks MCP over stdio, so it's meant to be launched by an MCP
client host (Claude Desktop, an agent framework's MCP client, etc.), not
run standalone as a long-lived network service. See
docs/CONFIGURATION.md for every config field.
Wiring into an MCP client
Most MCP client hosts take a command + args:
{
"mcpServers": {
"data-tools": {
"command": "mcp-data-tools",
"args": ["serve", "--config", "/path/to/configs/my-config.yaml"],
"env": { "AIRFLOW_TOKEN": "..." }
}
}
}Docker
make docker-build
make docker-run # docker compose run --rm mcp-data-toolsTesting
make test # pytest
make test-cov # pytest with coverage (fails under 85%)The suite includes a real MCP-protocol integration test
(tests/integration/test_mcp_server_e2e.py) built on the official mcp
SDK's in-memory client/server harness — it exercises the exact
list_tools/call_tool JSON-RPC path a real agent host uses, not a
hand-rolled fake.
Examples
examples/quickstart.py— guarded query, data-quality check, and a denied query, end to end, no credentials needed.tests/unit/test_tools_data_quality.py— shows the publicmcp_data_tools.testing.ScriptedQueryEnginetest double for unit-testing a newCheckStrategyor tool of your own.
FAQ
Does this replace IAM? No. It's a fast, auditable policy layer in
front of your backends; the service account/role this server runs as
should still be scoped to least privilege. See
docs/SECURITY.md for the full defense-in-depth
argument.
Can it write data? No tool in this package can execute DDL/DML,
delete/write a GCS object, or do anything to Airflow beyond triggering a
run and reading status. guardrails.read_only: false is not currently a
supported configuration surface for SQL tools.
Does it support Databricks/Snowflake instead of BigQuery? Not yet —
the query engine is behind ports.QueryEnginePort, so adding one is a new
adapter, not a rewrite. See "Extensibility" in docs/ARCHITECTURE.md.
Why do dry runs still get preflight-checked if they don't cost anything?
Because a dry run against BigQuery still reveals whether a table exists
and its schema/referenced-table list, which is itself information the
allow-list is meant to gate. See docs/SECURITY.md.
Troubleshooting
Symptom | Likely cause | Fix |
Server starts with zero tools registered | No | Add the relevant section — see |
| A | Export it or add it to |
Every query is denied with "not in the allow-list" |
| Check the exact |
|
|
|
Docker build fails on | No network egress in your build environment | Use |
Performance
Dry runs are always performed before execution (
require_dry_run), so every query pays one extra round-trip to BigQuery — a deliberate trade-off of latency for cost/safety guarantees. Seedocs/ARCHITECTURE.mdfor why this isn't optional.The regex-based preflight check (
core/sql_tables.py) avoids that round-trip entirely for queries that are obviously out of policy.All adapters use a bounded exponential-backoff retry (
core/retry.py) with jitter, so a single transient failure doesn't multiply into a retry storm against the backend.guardrails.max_rows_returnedandmax_bytes_billedbound both the memory footprint of a single tool call and the backend cost, regardless of how a caller phrases the query.
Security
See SECURITY.md for the threat model, the two-phase SQL
authorization design, secret handling, and how to report a vulnerability.
Roadmap
See the [Unreleased] section of CHANGELOG.md:
BigQuery-backed audit sink, a Databricks/Delta Lake query-engine adapter,
and column/row-level masking policy.
Contributing
See CONTRIBUTING.md for the dev setup, the
architecture ground rules new contributions are expected to follow, and
the lint/type/security/test gate every PR must pass.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mahesh-cr-de/mcp-data-tools'
If you have feedback or need assistance with the MCP directory API, please join our Discord server