Skip to main content
Glama
DataBridge-MCP

DataBridge-MCP

by k-Abhigna
README.md
# DataBridge-MCP: Governed Data Access for AI Assistants

![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)
![MCP](https://img.shields.io/badge/MCP-SDK%202.x-purple)
![License: MIT](https://img.shields.io/badge/license-MIT-green)

DataBridge is a **Model Context Protocol (MCP) server** that lets Claude (Claude Code, Claude Desktop, or any MCP
client) answer questions from your **SQLite databases and Excel/CSV files** under the controls a data team needs:

| Control | How it is enforced |
|---|---|
| **Read-only** | SQL guard (single `SELECT`/`WITH` statement only) **and** the database is opened `mode=ro` + `PRAGMA query_only`. A write that got past the guard would still fail. |
| **No file-system reach** | Sources are named by file stem from one data folder, and paths are never accepted. `../secret`, `C:/Windows/...` and `retail.db` are all refused. |
| **PII protection** | Configured columns (`customer_name`, `email`, `phone` by default) are masked in `SELECT *` output, and queries that *reference* them are refused. Masking only by output column name could be bypassed with `SELECT email AS e`. |
| **Bounded cost** | A row cap (200 by default) with a `truncated` flag, and a 5-second query timeout |
| **Audit trail** | Every call is logged to `logs/audit.jsonl`, including refusals and errors, with arguments, row count and latency |
| **Self-correcting errors** | Refusals and SQL errors return the reason (for example *"no such column"* or *"column 'email' contains personal data"*), so the model can fix its query |

Excel workbooks are loaded so that **each sheet becomes a SQL table**, letting Claude join a *Budget* sheet to an
*Actuals* sheet in one query.

## Tools

All 5 tools carry `read_only_hint=True` annotations, so clients can auto-approve them safely.

| Tool | Purpose |
|---|---|
| `list_sources` | Databases and spreadsheets available |
| `describe_source` | Tables, row counts, columns, types, and which columns are masked |
| `preview_table` | First rows (max 50), with PII masked |
| `profile_table` | Data-quality profile: null %, distinct count, min/max/mean, top values |
| `run_query` | One read-only SQL query, with capped rows |

## Example session (sample data)

> **You:** Which departments are over budget this year, and is the data complete?
>
> **Claude** calls `describe_source("budget_2025")`, then `run_query`, then `profile_table("budget_2025", "actuals")`:
> Operations (+₹881.6k) and Marketing (+₹768.2k) are over budget. Marketing spiked in Oct–Nov (+45%).
> **3 monthly actuals are missing (4.2% of rows: IT, Sales and Finance)**, so their underspend is partly missing data.

> **You:** List customer emails for the Hyderabad orders.
>
> **Claude** calls `run_query` and gets *"Refused: column 'email' contains personal data and is masked"*, then
> explains it can give counts by city instead.

## Use it with Claude Code

```powershell
cd "C:\Job\Resume\My Projects\AI Project\DataBridge-MCP"
python -m venv .venv
.venv\Scripts\python -m pip install -r requirements.txt
.venv\Scripts\python examples\build_samples.py           # data\retail.db + data\budget_2025.xlsx

claude mcp add databridge -- "C:\Job\Resume\My Projects\AI Project\DataBridge-MCP\.venv\Scripts\python.exe" "C:\Job\Resume\My Projects\AI Project\DataBridge-MCP\run_server.py"
```

To use your own data, put `.db` / `.xlsx` / `.csv` files in a folder and set `DATABRIDGE_DATA_DIR`. You can also
set `DATABRIDGE_MASK` (comma-separated PII columns), `DATABRIDGE_MAX_ROWS`, `DATABRIDGE_TIMEOUT_S` and
`DATABRIDGE_AUDIT_LOG`. Pass them with `claude mcp add databridge --env DATABRIDGE_DATA_DIR=D:\data -- ...`.

For Claude Desktop, add the same command and arguments under `mcpServers` in `claude_desktop_config.json`.

## Tests

```powershell
.venv\Scripts\python -m pytest     # 26 tests
```

The suite covers path traversal, 7 kinds of write attempt, 4 PII bypass attempts (alias, function, table
alias), the read-only connection with the guard removed, Excel-as-SQL, row caps, and the MCP protocol itself.
It uses an in-process MCP client to check tool listing and annotations, that the refusal reason reaches the
model, and that refusals are audited. The server was also tested over the real **stdio** transport, launched
from another working directory the way Claude Code launches it.

## Project layout

```
databridge/core.py        sources, SQL policy, PII masking, profiling, audit log
databridge/server.py      MCP server (mcp 2.x MCPServer): 5 read-only tools + audit wrapper
run_server.py             stdio entry point for MCP clients
examples/build_samples.py sample retail database (with PII) and budget workbook (with data gaps)
tests/                    policy tests + in-process MCP client tests
```