Skip to main content
Glama
Maha-Strategies

maha-mcp-bridge

Official
README.md
# maha-mcp-bridge

Zero-trust local MCP bridge for the [Maha Provenance Standard](https://www.mahastrategies.com/mps) API. Your source data stays on your machine; only sanitized context ever reaches the API.

## Install

```sh
npm install -g @mahastrategies/maha-mcp-bridge
```

## Quick start

```sh
maha login    # paste your mhaic_ credential (input hidden), verified live
maha status   # token validity + remaining audit credits
maha logout   # remove the stored credential
```

Credentials are verified against the live backend before being stored in a user-only file (`0600`), like the AWS and gcloud CLIs. Set `MAHA_MPS_CREDENTIAL` instead for CI and containers — it always takes precedence and nothing is written to disk.

`MAHA_MPS_API_URL` overrides the backend origin (https required, localhost exempt) for staging and local development.

## The MCP bridge

```sh
maha serve   # stdio MCP server; requires `maha login` first
```

`maha serve` refuses to start without a valid credential — an unauthenticated host exposes no tools. Register it with any MCP client, e.g. Claude Code:

```json
{ "mcpServers": { "maha": { "command": "maha", "args": ["serve"] } } }
```

### Tools

| Tool | What it does |
|---|---|
| `get_schema_definition` | Tables and columns of a configured local database, redacted. |
| `query_internal_db` | One read-only SQL statement; rows capped, cells truncated, results redacted locally. |
| `mps_audit_passage` | Redacts a passage locally, then submits the sanitized text for an MPS claim-level audit. |
| `mps_local_audit_summary` | Aggregate counts from the local hash-chained ledger. No payloads. |

### Two-tier PII redaction

Before any row or schema reaches the agent it passes through two redaction tiers, and both are counted separately in the ledger:

1. **Regex tier** (always on, fast): emails, SSNs, payment cards, phones, access/bearer tokens, secret-named fields, plus any custom patterns.
2. **Contextual tier** (local ONNX model via [`@huggingface/transformers`](https://github.com/huggingface/transformers.js)): a Named Entity Recognition model (`Xenova/bert-base-NER`) catches free-text PII the regexes miss — `PER` (people), `LOC` (locations), `ORG` (organizations), `MISC`. It runs **entirely on your machine** on the native `onnxruntime-node` backend; the model downloads once to `~/.cache/maha-mcp-bridge/` and never phones home afterward.

The model loads lazily so it never blocks the MCP handshake, and if it can't load (offline, disk, etc.) the bridge degrades to regex-only rather than failing. Disable it with `"pii": { "contextual": { "enabled": false } }` or `MAHA_MPS_DISABLE_NER=1`. Redaction is best-effort, not a guarantee that every entity is caught.

> **The contextual (NER) tier works out of the box.** `onnxruntime-node` ships prebuilt native binaries for macOS, Linux, and Windows (x64 and arm64) inside the npm package, so a plain `npm install -g` runs the full `regex + NER` pipeline with no extra flags. (Recent npm prints an `npm warn allow-scripts` about the package's `postinstall`; on the supported platforms that script isn't needed — the binary is already bundled.)
>
> You never have to guess which tiers are live: **`maha status` reports the active redaction tier** — `Redaction  regex + NER`, `regex-only (NER unavailable)`, or `regex-only (NER disabled)` — and `maha serve` prints the same on startup. If your platform has no prebuilt binary, NER is skipped and the bridge degrades to regex-only (safely, not fatally). Only then do you need to rebuild the backend from source:
>
> ```sh
> npm install -g --allow-scripts=onnxruntime-node @mahastrategies/maha-mcp-bridge
> ```

### Read-only, enforced twice

A statement gate rejects anything that isn't a single `SELECT`/`WITH`/`SHOW`/`EXPLAIN`/`DESCRIBE`, and every query then runs inside a server-side `READ ONLY` transaction that is always rolled back — so a data-modifying CTE that slips past the gate still dies in the database engine.

### Configuration

`~/.config/maha-mcp-bridge/config.json`:

```json
{
  "databases": [
    { "name": "appdb", "kind": "postgres", "urlEnv": "APPDB_URL" },
    { "name": "legacy", "kind": "mysql", "urlEnv": "LEGACY_DB_URL" }
  ],
  "pii": { "customPatterns": [{ "name": "employee_id", "source": "EMP-\\d{6}" }] }
}
```

Connection URLs come from environment variables (`urlEnv`); inline `url` values are rejected if they embed a password. Use a database role with read-only grants as a third layer.

Every tool invocation is recorded in a local, hash-chained SQLite ledger (`0600`) holding only hashes and redaction counts — never passage text, SQL, or rows.

## Configuration (contextual model)

```json
{
  "pii": {
    "contextual": { "enabled": true, "model": "Xenova/bert-base-NER", "minScore": 0.5 }
  }
}
```

## Mount a book

Mount a purchased book as a local MCP server so your agent can navigate it by section instead of scrolling a wall of text:

```sh
maha book mount the-imagined-life   # uses your MHAIC token (~/.maha/config.json or MHAIC_TOKEN)
```

On first use it prompts for your `mhaic_` token (input hidden), verifies it, and stores it `0600`. Register the mounted book with any MCP client:

```json
{ "mcpServers": { "maha-book-the-imagined-life": { "command": "maha", "args": ["book", "mount", "the-imagined-life"] } } }
```

`maha book mount` prints this exact snippet on a successful mount. The book is fetched once (entitlement-checked) and served from memory — the tools are:

| Tool | What it does |
|---|---|
| `list_chapters` | The book's outline: sections and per-section chunk counts. |
| `read_section` | One section's text, by heading (partial match allowed) or numeric index. |
| `search_concepts` | Ranked plain-text search across the book's chunks. |

The full text of each book is free to read on the web; this structured, agent-queryable form is the paid endpoint. If your token isn't entitled, `maha book mount` prints the purchase URL instead of starting.

## Security notes

- The contextual model runs locally; database rows are never sent anywhere for inference.
- `npm audit` is clean (0 vulnerabilities). Inference uses the maintained [`@huggingface/transformers`](https://github.com/huggingface/transformers.js) on the native `onnxruntime-node` backend — no `onnxruntime-web`/`protobufjs`. `adm-zip` (pulled by `onnxruntime-node` to unpack its native binary) is pinned to a patched `^0.6.0` via a package override.

## Why open source

Security teams should be able to audit exactly what leaves the building. The bridge is MIT-licensed; the cloud control plane (billing, idempotent credit ledger, audit engine) is the paid service behind it.