Skip to content

KablamoOSS/heimdall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Heimdall

The all-seeing watchman of the bridge between AI and Data.

Heimdall is a Universal Multi-Database MCP (Model Context Protocol) Server written in Go. It sits between AI models and your databases, enforcing granular permissions, data masking, and query safety — so models can query data without unrestricted access.

Quick Start

# Build
go build -o heimdall ./cmd/heimdall

# Run
./heimdall -config heimdall.yaml

# Verify database connectivity
./heimdall -config heimdall.yaml -verify

Usage with Claude Desktop

Add Heimdall to your Claude Desktop MCP configuration (claude_desktop_config.json):

{
    "mcpServers": {
        "heimdall": {
            "command": "/path/to/heimdall",
            "args": ["-config", "/path/to/heimdall.yaml"]
        }
    }
}

Heimdall communicates over stdio using JSON-RPC. Claude Desktop will see dynamically generated tools for each configured database (e.g., inspect_finance_db, read_finance_db, task_finance_db).

Configuration

Heimdall is configured via a YAML file. See examples/heimdall.yaml for a fully commented example.

Minimal Config

version: "1.0"

databases:
  - id: my_db
    type: sqlite
    dsn: "file:./data.db"

Full Config Reference

version: "1.0"

server:
  port: 3000              # Currently unused (stdio transport)
  log_level: "info"        # debug, info, warn, error — logs go to stderr

defaults:
  read_timeout: "30s"      # Default query timeout per database
  max_rows: 1000           # Default row limit injected into SELECT queries

databases:
  - id: "finance_db"                     # Unique identifier (alphanumeric + underscore)
    type: "postgres"                     # postgres, mysql, mssql, oracle, sqlite
    dsn: "postgres://user:pass@host:5432/db"
    allowed_operations:                  # Default: [SELECT]
      - SELECT
      - INSERT
    allow_list:                          # Restrict to specific tables (empty = all)
      - transactions
      - accounts
    masking:
      salt: "your-secret-salt"           # For deterministic hashing
      rules:
        - table: users
          column: email
          action: redact                 # Replaces with [REDACTED]
        - table: transactions
          column: account_id
          action: hash                   # Salted SHA-256 hash
    resources:                           # Custom MCP resource endpoints
      - name: daily_summary
        description: "Daily transaction summary"
        sql: "SELECT date, SUM(amount) FROM transactions GROUP BY date"
    read_timeout: "5s"                   # Overrides defaults.read_timeout
    max_rows: 200                        # Overrides defaults.max_rows

Environment Variable Expansion

DSN strings support environment variable expansion:

dsn: "postgres://${DB_USER}:${DB_PASS}@${DB_HOST}:5432/mydb"

Supported Databases

Database Driver Read-Only Session
PostgreSQL / CockroachDB github.com/jackc/pgx/v5 SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY
MySQL / MariaDB github.com/go-sql-driver/mysql SET SESSION TRANSACTION READ ONLY
SQL Server github.com/microsoft/go-mssqldb Not supported (AST enforcement only)
Oracle github.com/sijms/go-ora/v2 Not supported (AST enforcement only)
SQLite modernc.org/sqlite PRAGMA query_only = ON

All drivers are pure Go — no CGO required. The binary cross-compiles for Mac, Windows, and Linux.

Security Model

Heimdall enforces a multi-layered security pipeline (SafeGuard) on every query:

  1. AST Parsing — SQL is parsed into an AST (vitess-based parser) to identify statement type. No keyword matching.
  2. Operation Enforcement — Statement type checked against the per-database allowed_operations whitelist.
  3. Table Allow-List — If configured, only queries targeting listed tables are permitted.
  4. Multi-Statement Rejection — Semicolon-separated queries are blocked.
  5. Read-Only Session — When only SELECT is allowed, the database connection is set to read-only mode (where supported) as defense-in-depth.
  6. Auto-Limit Injection — Row limits injected using dialect-specific syntax (LIMIT, TOP, FETCH FIRST). Existing limits above max_rows are replaced.
  7. Context Timeout — Every query is wrapped in a context with a configurable deadline.
  8. Data Masking — Sensitive columns are redacted ([REDACTED]) or hashed (salted SHA-256) before results reach the AI model.

Generated Tools

For each configured database, Heimdall dynamically generates MCP tools:

Tool Purpose Registered When
inspect_<id> Schema introspection (tables, columns, types) Always
read_<id> Execute SELECT queries SELECT in allowed_operations
task_<id> Execute mutations (INSERT/UPDATE/DELETE) Any non-SELECT operation allowed

The inspect tool implements token economy protection — if the database has more than 50 tables, it returns only table names with a hint to filter, avoiding context window bloat.

MCP Resources

Each database also exposes MCP resource endpoints:

  • <id>://schema — Full schema as JSON
  • <id>://<resource_name> — Results of custom queries defined in config resources

Verify Mode

The -verify flag pings all configured databases and reports health:

./heimdall -config heimdall.yaml -verify

Output goes to stderr as JSON followed by a human-readable summary. Exit code 0 if all databases are healthy, 1 if any failed.

Development

Prerequisites

  • Go 1.21+
  • Docker (for integration tests)

Running Tests

# Unit tests
go test ./...

# Static analysis
go vet ./...

# All integration tests (requires Docker for Testcontainers)
go test -tags integration ./integration/...

# Single-dialect integration tests
go test -tags integration -run TestPostgres ./integration/...
go test -tags integration -run TestMySQL ./integration/...
go test -tags integration -run TestMSSQL ./integration/...
go test -tags integration -run TestOracle ./integration/...
go test -tags integration -run TestSQLite ./integration/...

# Full MCP protocol integration test
go test -tags integration -run TestMCP ./integration/...

Integration tests use testcontainers-go to spin up real database instances. Oracle tests may take longer due to container startup time.

Project Structure

cmd/heimdall/          Entry point and CLI
internal/
  config/              YAML config loading and validation
  database/            Dialect registry, driver abstraction, connection manager
  safeguard/           SQL analyzer, enforcer, limiter, timeout
  execution/           Query execution pipeline
  masking/             Data masking (redact/hash)
  mcp/                 MCP server wrapper
  tools/               Dynamic tool registration
  resources/           MCP resource endpoints
  verify/              Health check for --verify
integration/           Testcontainers-based integration tests
testdata/              Test configuration files
examples/              Example configuration

CLI Flags

Flag Description
-config <path> Path to YAML config file (required)
-verify Ping all databases and report health, then exit
-version Print version and exit

License

See LICENSE for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors