{"id":"4325446b-9f2d-4869-9beb-c933e3cf7c16","slug":"sqlsense","kind":"mcp","name":"sqlsense","summary":"Safe, audited SQL for AI agents via MCP.","owner":"raj8github","repoUrl":"https://github.com/raj8github/sqlsense","license":"MIT","licenseTier":"permissive","trust":"community","stars":3,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-03-02T03:55:31.000Z","addedAt":"2026-10-21T08:26:04.423Z","logoUrl":"https://avatars.githubusercontent.com/u/9230581?u=1d5c6f72461d83196b88cba40326ade4aa1150a1&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["databases"],"tags":["ai","ai-agents","claude","database","guardrails","llm","python","sql"],"runtime":"python","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-21T14:23:03.246Z","sample":false,"url":"https://conduits.dev/tools/sqlsense","language":"Python","transports":["stdio"],"install":{"pypi":"sqlsense"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# 🛡️ SQLSense\n\n**Safe, audited SQL for AI agents via MCP.**\n\nAI agents are talking to your database. SQLSense makes sure they don't destroy it.\n\n```\npip install sqlsense\nsqlsense serve --dsn \"postgresql://user:pass@localhost/mydb\"\n```\n\n[![PyPI version](https://img.shields.io/pypi/v/sqlsense.svg)](https://pypi.org/project/sqlsense/)\n[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![Downloads](https://img.shields.io/pypi/dm/sqlsense.svg)](https://pypi.org/project/sqlsense/)\n\n---\n\n## The problem\n\nYou're giving an AI agent access to your database. It generates SQL, executes it. What could go wrong?\n\n```sql\n-- Agent confidently generates this\nDELETE FROM users;\n\n-- Or this\nSELECT password, ssn, credit_card FROM customers;\n\n-- Or this  \nDROP TABLE orders;\n```\n\nNo existing MCP database tool blocks these. SQLSense does.\n\n---\n\n## What SQLSense does\n\nSQLSense is an **MCP server** that wraps your database connection with:\n\n- 🚫 **Guardrails** — blocks dangerous queries before they reach your database  \n- 🔒 **Readonly mode** — SELECT-only by default, writes opt-in  \n- 📋 **Audit log** — every query an agent runs, logged to JSONL  \n- 🔢 **Auto-LIMIT** — automatically caps SELECT queries to prevent full-table scans  \n- 🙈 **Column blocking** — blocklist sensitive columns (`password`, `ssn`, `api_key`...)  \n- 💉 **Injection guard** — multi-statement queries blocked at parse time  \n- 🗄️ **Multi-database** — SQLite, PostgreSQL, MySQL, SQL Server, Snowflake, DuckDB, BigQuery\n\n---\n\n## Quickstart\n\n### Install\n\n```bash\npip install sqlsense\n\n# With your database driver\npip install \"sqlsense[postgres]\"    # PostgreSQL\npip install \"sqlsense[mysql]\"       # MySQL / MariaDB (AWS RDS, Azure MySQL)\npip install \"sqlsense[sqlserver]\"   # SQL Server\npip install \"sqlsense[snowflake]\"  # Snowflake\npip install \"sqlsense[duckdb]\"     # DuckDB (local analytics, Python-native)\npip install \"sqlsense[bigquery]\"   # Google BigQuery (auth via ADC)\npip install \"sqlsense[all]\"        # Everything\n```\n\n#### SQL Server — extra step required\n\n`pyodbc` (installed by `sqlsense[sqlserver]`) needs the **Microsoft ODBC Driver 17** installed at the OS level. `pip` cannot do this part.\n\n**macOS:**\n```bash\nbrew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release\nbrew update\nHOMEBREW_ACCEPT_EULA=Y brew install msodbcsql17\n```\n\n**Ubuntu / Debian:**\n```bash\ncurl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -\ncurl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list \\\n  | sudo tee /etc/apt/sources.list.d/mssql-release.list\nsudo apt-get update\nsudo ACCEPT_EULA=Y apt-get install -y msodbcsql17\n```\n\n**Windows:** Download from [Microsoft's ODBC Driver page](https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server) and run the installer.\n\n### Start the MCP server\n\n```bash\n# PostgreSQL (readonly by default)\nsqlsense serve --dsn \"postgresql://user:pass@localhost/mydb\"\n\n# SQL Server (common in enterprise/fintech)\nsqlsense serve --dsn \"mssql://user:pass@server:1433/mydb\"\n\n# MySQL / MariaDB (AWS RDS, Aurora, Azure Database for MySQL)\nsqlsense serve --dsn \"mysql://user:pass@host:3306/mydb\"\n\n# Snowflake\nsqlsense serve --dsn \"snowflake://user:pass@account/warehouse/database\"\n\n# BigQuery (auth via GOOGLE_APPLICATION_CREDENTIALS or ADC)\nsqlsense serve --dsn \"bigquery://my_project/my_dataset\"\n\n# SQLite (great for local dev)\nsqlsense serve --dsn \"sqlite:///./myapp.db\"\n\n# DuckDB (local analytics, dbt-style workflows)\nsqlsense serve --dsn \"duckdb:///./analytics.duckdb\"\n# or in-memory: duckdb://:memory:\n```\n\n### Connect to Claude Desktop\n\nAdd to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"sqlsense\": {\n      \"command\": \"sqlsense\",\n      \"args\": [\"serve\", \"--dsn\", \"postgresql://user:pass@localhost/mydb\"]\n    }\n  }\n}\n```\n\nClaude now has safe, audited database access. Ask it:\n> *\"Show me the top 10 customers by order value this month\"*\n\nSQLSense intercepts every query, checks it against guardrails, logs it, and either executes it safely or blocks it with a clear reason.\n\n### Connect to Claude Code\n\n```bash\n# In your project\nclaude mcp add sqlsense -- sqlsense serve --dsn \"postgresql://...\"\n```\n\n---\n\n## Credentials — never hardcode them\n\nNever put database credentials directly in your MCP config or shell history. Use one of these patterns instead.\n\n### Option 1 — Wrapper script (recommended)\n\nCreate a script that pulls credentials from your secret store at runtime:\n\n```bash\n# ~/scripts/sqlsense-mydb.sh\n#!/bin/bash\nsqlsense serve \\\n  --dsn \"postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:5432/${DB_NAME}\" \\\n  --max-rows 1000 \\\n  --audit-log ~/.sqlsense/audit.jsonl\n```\n\n```bash\nchmod +x ~/scripts/sqlsense-mydb.sh\n```\n\nThen your Claude Desktop config stays clean — no credentials anywhere:\n\n```json\n{\n  \"mcpServers\": {\n    \"mydb\": {\n      \"command\": \"/Users/you/scripts/sqlsense-mydb.sh\"\n    }\n  }\n}\n```\n\n### Option 2 — macOS Keychain\n\n```bash\n# Store once\nsecurity add-generic-password -a sqlsense -s db-password -w \"your_password\"\n\n# Retrieve in your wrapper script\nDB_PASS=$(security find-generic-password -a sqlsense -s db-password -w)\n```\n\n### Option 3 — Environment variables via `env` block\n\nClaude Desktop supports an `env` block in the config — credentials stay out of `args`:\n\n```json\n{\n  \"mcpServers\": {\n    \"mydb\": {\n      \"command\": \"sqlsense\",\n      \"args\": [\"serve\", \"--dsn\", \"postgresql://$(DB_USER):$(DB_PASS)@$(DB_HOST)/$(DB_NAME)\"],\n      \"env\": {\n        \"DB_USER\": \"myuser\",\n        \"DB_PASS\": \"mypassword\",\n        \"DB_HOST\": \"localhost\",\n        \"DB_NAME\": \"mydb\"\n      }\n    }\n  }\n}\n```\n\n### Option 4 — `.env` file with a loader\n\n```bash\n# .env (never commit this)\nDB_USER=myuser\nDB_PASS=mypassword\nDB_HOST=localhost\nDB_NAME=mydb\n```\n\n```bash\n# wrapper script\n#!/bin/bash\nset -a && source ~/.sqlsense/.env && set +a\nsqlsense serve --dsn \"postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_NAME}\"\n```\n\n---\n\n## Guardrails in action\n\n```bash\n# Test any query before running it\n$ sqlsense check \"DELETE FROM users\"\n🚫 BLOCKED  (risk: HIGH)\nReason: DELETE is blocked. Set allow_delete=True to enable.\n\n$ sqlsense check \"SELECT * FROM orders\"\n✅ ALLOWED  (risk: MEDIUM)\nWarnings:\n  • SELECT * detected — prefer explicit column names.\n  • No WHERE clause — query may scan the full table.\n  • LIMIT 1000 automatically added to protect against full-table scans.\n\n$ sqlsense check \"SELECT id FROM users WHERE id = 1\"\n✅ ALLOWED  (risk: LOW)\nHash: a3f9c2d1b8e4\n```\n\n---\n\n## Configuration\n\nAll guardrails are configurable. Defaults are deliberately conservative.\n\n```bash\n# Allow writes (careful!)\nsqlsense serve --dsn \"...\" --allow-writes\n\n# Increase row limit\nsqlsense serve --dsn \"...\" --max-rows 5000\n\n# Block specific tables\nsqlsense serve --dsn \"...\" \\\n  --block-table audit_log \\\n  --block-table internal_config\n\n# Disable auto-LIMIT (not recommended)\nsqlsense serve --dsn \"...\" --no-auto-limit\n```\n\nOr configure programmatically:\n\n```python\nfrom sqlsense import SQLSenseMCPServer\nfrom sqlsense.guardrails import GuardrailConfig\n\nconfig = GuardrailConfig(\n    max_rows=2000,\n    readonly_mode=True,           # default: True\n    auto_add_limit=True,          # default: True\n    blocked_tables=[\"secrets\"],\n    blocked_columns=[\"password\", \"token\", \"ssn\", \"credit_card\"],\n    require_where_on_writes=True, # default: True\n)\n\nserver = SQLSenseMCPServer(dsn=\"postgresql://...\", config=config)\nserver.run()\n```\n\n---\n\n## Audit log\n\nEvery query an agent runs is written to a JSONL file:\n\n```bash\n# View recent queries\nsqlsense audit --tail 20\n\n# Output\nTIME                   ALLOWED  RISK    ROWS   MS     SQL\n────────────────────────────────────────────────────────────────────────────────────────────\n2025-02-26T14:22:01Z   ✅       low     42     12.3   SELECT id, name FROM customers WHE...\n2025-02-26T14:22:15Z   🚫       high    —      —      DELETE FROM users\n2025-02-26T14:22:31Z   ✅       medium  1000   891.2  SELECT * FROM orders\n\n# JSON output for piping to your observability stack\nsqlsense audit --tail 100 --json | jq '.[] | select(.allowed == false)'\n```\n\nEach entry is a self-contained JSON object — trivially parseable by Splunk, Datadog, CloudWatch, or `grep`.\n\n---\n\n## MCP Tools\n\nSQLSense exposes 4 tools to the AI agent:\n\n| Tool | Description |\n|------|-------------|\n| `sql_query` | Execute SQL (with guardrails + auto-LIMIT) |\n| `get_schema` | Get table/column definitions for context |\n| `explain_query` | Check what a query will do before running |\n| `get_audit_log` | Retrieve recent query history |\n\nThe agent calls `get_schema` first to understand the database, then `explain_query` to validate before executing — SQLSense nudges agents toward safer patterns.\n\n---\n\n## Supported databases\n\n| Database | Status | Install |\n|----------|--------|---------|\n| SQLite | ✅ Built-in | `pip install sqlsense` |\n| PostgreSQL | ✅ Stable | `pip install \"sqlsense[postgres]\"` |\n| MySQL / MariaDB | ✅ Stable | `pip install \"sqlsense[mysql]\"` |\n| SQL Server | ✅ Stable | `pip install \"sqlsense[sqlserver]\"` |\n| Snowflake | ✅ Stable | `pip install \"sqlsense[snowflake]\"` |\n| DuckDB | ✅ Stable | `pip install \"sqlsense[duckdb]\"` |\n| BigQuery | ✅ Stable | `pip install \"sqlsense[bigquery]\"` |\n\n---\n\n## Use with other AI frameworks\n\nSQLSense is an MCP server, so it works with anything that speaks MCP:\n\n- ✅ Claude Desktop\n- ✅ Claude Code  \n- ✅ Any MCP-compatible agent framework\n- ✅ Custom agents (via stdio JSON-RPC)\n\n---\n\n## Python API\n\nUse SQLSense as a library if you don't need the MCP layer:\n\n```python\nfrom sqlsense.guardrails import GuardrailsEngine, GuardrailConfig\nfrom sqlsense.connectors import create_connector\nfrom sqlsense.audit import AuditLogger\n\n# Guardrails only\nengine = GuardrailsEngine(GuardrailConfig())\nresult = engine.check(\"SELECT * FROM users\")\nif not result.allowed:\n    raise PermissionError(result.reason)\n\n# Full stack\ndb = create_connector(\"postgresql://user:pass@localhost/mydb\")\nlogger = AuditLogger(\"./audit.jsonl\")\n\nguard = engine.check(sql)\nif guard.allowed:\n    safe_sql = guard.rewritten_sql or sql\n    query_result = db.execute(safe_sql)\n    logger.record(sql, guard, rows_returned=query_result.row_count)\n```\n\n---\n\n## Roadmap\n\n- [ ] HTTP/SSE transport (in addition to stdio)\n- [ ] MySQL connector\n- [ ] BigQuery connector  \n- [ ] DuckDB connector\n- [ ] Web dashboard for audit log\n- [ ] Query cost estimation (EXPLAIN integration)\n- [ ] Rate limiting per agent/session\n- [ ] Row-level security policies\n- [ ] Slack/webhook alerts on blocked queries\n- [ ] Docker image\n\n---\n\n## Contributing\n\nContributions very welcome. The most useful things right now:\n\n1. **New database connectors** — MySQL, BigQuery, DuckDB (see `sqlsense/connectors.py`)\n2. **Guardrail improvements** — edge cases, dialect-specific rules\n3. **HTTP transport** — SSE server for remote deployments\n4. **Tests** — more edge cases in `tests/test_sqlsense.py`\n\n```bash\ngit clone https://github.com/raj8github/sqlsense\ncd sqlsense\npip install -e \".[dev]\"\npytest tests/ -v\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n\n---\n\n## Why this exists\n\nAI agents with database access are powerful. They're also one bad prompt away from `DELETE FROM production_users` without a WHERE clause.\n\nThe current ecosystem of MCP database tools (sqlite-mcp, postgres-mcp, etc.) gives agents raw access with no guardrails, no audit trail, and no circuit breakers. SQLSense fills that gap — built with patterns from production fintech environments where database safety isn't optional.\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE)"}