Skip to content
Conduit

mcp server

bi-gateway-mcp

MCP server fronting SQL, Power BI Desktop & Fabric behind one gateway — two-layer SQL safety, adversarially tested.

Riccowil/bi-gateway-mcpcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 23, 2026

BI Gateway MCP Server

Unified MCP server for SQL databases (MSSQL, PostgreSQL), Power BI Desktop, and Fabric Semantic Models — accessed through a single gateway with shared infrastructure.

Quick Start

cd bi-gateway

# Activate venv
.venv\Scripts\activate

# Edit .env with your connection strings (already configured for local MSSQL + PG)

# Run the server
python gateway.py

# Run tests
python -m pytest tests/ -v

Architecture

MCP Host (Claude Desktop / Code)
    | JSON-RPC 2.0 (stdio)
    v
+------------------------------------------+
|          BI Gateway (Python)              |
|                                           |
|  gateway.py      <- MCP server            |
|  models.py       <- shared infra          |
|  safety.py       <- validation/limits     |
|  pbi_desktop.py  <- PBI Desktop bridge    |
|  .env            <- config                |
|                                           |
|  Infrastructure:                          |
|  - Audit Logger (SQLite)                  |
|  - TTL Cache (in-memory)                  |
|  - Circuit Breaker                        |
|  - Rate Limiter                           |
|  - Error Playbooks                        |
|  - Output Formatter + Schema Compression  |
|  - SQL Injection Protection               |
|  - DAX Validation                         |
|  - Query Cost Estimation                  |
+------------------------------------------+
    |              |              |              |
    v              v              v              v
  MSSQL       PostgreSQL    PBI Desktop    Fabric XMLA
  DW2022        17.9        (local SSAS)   (TOM + MSAL)
  DW2017

Tools (27)

SQL Read Tools [R]

ToolPurposeAnnotation
sql_run_queryExecute read-only SQL with paginationreadOnly
sql_list_tablesList tables and viewsreadOnly
sql_describe_tableColumns, types, PKs, indexes, FKsreadOnly
sql_search_schemaKeyword search across table/column namesreadOnly
sql_list_databasesShow all configured connectionsreadOnly
sql_list_proceduresList stored proceduresreadOnly
sql_proc_historyView procedure version historyreadOnly

SQL Write Tools [W]

ToolPurposeAnnotation
sql_executeRun DDL/DML (INSERT, UPDATE, CREATE, etc.)destructive
sql_rollback_lastPreview or undo last write operationdestructive
sql_create_procedureCreate/replace stored procedure (versioned)write
sql_call_procedureExecute stored procedure by namewrite

Power BI Desktop Tools [R]

ToolPurposeAnnotation
pbi_statusCheck if PBI Desktop is runningreadOnly
pbi_run_daxExecute DAX query against open modelreadOnly
pbi_get_schemaGet tables, columns, measures, relationshipsreadOnly

Fabric Semantic Model Tools [R]

ToolPurposeAnnotation
fabric_connectConnect to a Fabric workspace/model via XMLAwrite
fabric_get_schemaTables, columns, measures, relationships, calc groupsreadOnly
fabric_run_daxExecute DAX query against connected Fabric modelreadOnly
fabric_audit_relationshipsScan for missing/orphaned/ambiguous relationshipsreadOnly

Fabric Semantic Model Tools [W]

ToolPurposeAnnotation
fabric_create_relationshipAdd relationship with cardinality/directionwrite
fabric_modify_columnHide/unhide column propertieswrite
fabric_batch_modify_columnsBatch modify multiple columns in one transactionwrite
fabric_create_measureCreate or update a DAX measurewrite
fabric_create_udfCreate a DAX User-Defined Functionwrite
fabric_create_calc_groupCreate calculation group with itemswrite

Cross-Platform Tools [R]

ToolPurposeAnnotation
glossary_lookupResolve business terms to schema objectsreadOnly
cross_platform_compareCompare a metric across SQL and PBIreadOnly

Audit Tools [R]

ToolPurposeAnnotation
get_audit_logQuery the audit trail (filter by tool, limit rows)readOnly

Safety Model

Database-Level (Dual Connection)

UserCan DoCannot Do
mcp_readerSELECTINSERT, UPDATE, DELETE, GRANT
mcp_developerSELECT, INSERT, UPDATE, DELETE, proceduresGRANT, REVOKE, admin ops

Application-Level

CheckBehavior
GRANT/REVOKE/DROP DATABASEAlways blocked (hardcoded, word-boundary match)
DROP/TRUNCATE/DELETE/ALTERRequires confirm=True + readwrite mode
DELETE/UPDATE without WHEREBlocked as high-risk query (needs confirm)
SQL injection patterns15 regex patterns block chaining, UNION, timing attacks, xp_cmdshell, remote-query functions, etc.
Identifier validationAlphanumeric + underscore + brackets only, max 128 chars
Query lengthMax 10,000 chars (configurable)
Rate limiting60 reads/min, 20 writes/min, 30 PBI calls/min (configurable)
Pre-state captureUPDATE/DELETE snapshots affected rows for rollback
DAX validationMust start with EVALUATE/DEFINE; SQL keywords blocked
Readonly modeSQL_{DB}_MODE=readonly disables all write tools for that database

MCP Tool Annotations

All 27 tools have readOnlyHint and destructiveHint annotations per MCP spec, so Claude knows which tools are safe before calling them.

Resources (8)

URIDescription
gateway://statusConnected DBs, cache stats, circuit breaker state, uptime
gateway://safetyRate limit usage, database modes, query limits
gateway://audit/recentLast 20 operations logged
sql://databasesAll configured connections with mode/dialect
glossary://termsBusiness term to schema object mappings
powerbi://desktop/statusPBI Desktop connection status
fabric://statusFabric semantic model connection status

Template resources (auto-register on access):

URIDescription
sql://{database_id}/schemaAuto-compressed schema (cached 5 min)

Prompts (4)

PromptDescription
explore_databaseGuided schema exploration workflow
investigate_metricGlossary-driven metric investigation
compare_databasesCross-database schema comparison
explore_pbi_modelGuided PBI Desktop model exploration

Test Suite

155 tests covering all components:

Test FileCoverage
test_safety.py (59 tests)SQL injection, identifier validation, DAX safety, query classification, rate limiting, cost estimation
test_sqlguard.py (46 tests)AST/token classification, dynamic-SQL unwrap, cross-DB guard, single-SELECT enforcement, error categorization
test_integration.py (47 tests)Live MSSQL read/write, stored procedures, rollback, glossary, PBI Desktop, cross-platform, resources
test_surface.py (3 tests)Surface inventory guard — registered tool/resource/prompt counts

Run: python -m pytest tests/ -v

Configuration (.env)

# Database connections (dual reader/writer with SQL Auth)
SQL_MSSQL_DSN_READ=mssql+pyodbc://mcp_reader:pass@localhost/DBName?driver=...
SQL_MSSQL_DSN_WRITE=mssql+pyodbc://mcp_developer:pass@localhost/DBName?driver=...
SQL_MSSQL_MODE=readwrite          # readonly | readwrite

SQL_PG_DSN_READ=postgresql+psycopg2://user:pass@localhost:5432/db
SQL_PG_MODE=readonly

# Defaults
SQL_DEFAULT_DB=mssql
SQL_MAX_ROWS=1000
SQL_TIMEOUT=30
SQL_WRITE_TIMEOUT=60

# Output formatting
SQL_MAX_DISPLAY_ROWS=50
SQL_MAX_COL_WIDTH=100
MAX_RESULT_CHARS=8000
MAX_QUERY_LENGTH=10000

# Rate limits
RATE_SQL_READ=60    # reads per minute
RATE_SQL_WRITE=20   # writes per minute
RATE_PBI=30         # PBI calls per minute

# Gateway
AUDIT_DB_PATH=~/.mcp-gateway/audit.db
CACHE_DEFAULT_TTL=300
LOG_LEVEL=INFO
GLOSSARY_PATH=~/.mcp-gateway/glossary.yaml

Files

bi-gateway/
├── gateway.py          # MCP server: 27 tools, 8 resources, 4 prompts
├── models.py           # Audit, cache, circuit breaker, formatter, errors
├── safety.py           # SQL injection, DAX validation, rate limiter, cost estimation
├── pbi_desktop.py      # PBI Desktop local SSAS connection via PowerShell + ADOMD.NET
├── fabric_model.py     # Fabric semantic model connection via XMLA/TOM + MSAL auth
├── .env                # Connection strings and config (git-ignored)
├── .env.example        # Template
├── .gitignore
├── pyproject.toml      # Dependencies
├── tests/
│   ├── test_safety.py       # 57 unit tests for safety module
│   └── test_integration.py  # 38 live integration tests
└── .venv/

Related Documents

  • ADR-001-bi-gateway-architecture.md — Architecture Decision Record (10 decisions)
  • RESIDUAL-RISK.md / RED-PASS-2026-06-30.md — accepted risks and the pre-publication adversarial audit
  • ~/.mcp-gateway/glossary.yaml — Business glossary (29 AdventureWorks terms)
↑↓ navigate openesc close