Skip to main content
Glama

MCP-Guard

A data-loss-prevention proxy for Model Context Protocol traffic. It sits between an AI agent and an MCP server, inspects every tool call in both directions, and replaces sensitive values with stable placeholders before the model ever sees them.

Live

MCP-Guard Live Dashboard

┌─ automatic feed (off by default, Start/Stop in the console)
├─ manual upload (paste or drop a file in the console)
└─ data source connectors (live PostgreSQL / MongoDB / HTTP API)
        │
        ▼
   MCP-Guard
        │
        ├─ regex pass        structural shapes, checksum-validated
        ├─ AI pass           names, addresses, free-text identifiers — via OpenRouter
        ├─ masking engine    [REDACTED_SSN_1]
        └─ audit log ──▶ MongoDB (or in-memory) ──▶ console (copy / download / export)

Preview

https://github.com/user-attachments/assets/1b5a0a75-2593-4875-b230-97f1f82959e6

What's in this build

  • Everything AI runs through OpenRouter. Detection's second pass and the final "analyze this dataset" step both use the same OPENROUTER_API_KEY. No separate Anthropic account needed. openrouter/free works out of the box for both.

  • An automatic traffic feed, controlled from the console — never on by default. Press Start and the guard calls a rotation of the upstream server's demo tools on a timer (45s by default). Press Stop and it stops. The server itself never starts this on its own.

  • A manual test panel. Paste text or drop a .txt/.json/.csv file and it's scanned immediately.

  • Live database and API connectors. Point the guard at a real PostgreSQL database, a MongoDB collection, or any external HTTP API, from the console — fetch, redact, and see the result in one action. Nothing is preconfigured in .env; every connection detail is entered per-request and used once, never stored or logged.

  • Export on every result. Every scan — manual, automatic, or from a connector — can be copied to the clipboard or downloaded as .txt/.json. The whole audit log exports as JSON or CSV from the events panel.

  • No Docker. Runs with npm run dev / npm start, nothing else required.

Related MCP server: Agent Guardrail MCP

Running it

npm install
cp .env.example .env      # add OPENROUTER_API_KEY if you want the AI pass and analysis
npm test
npm run dev
cd dashboard
npm install
npm run dev                # http://localhost:5173

The backend runs with zero keys: no OPENROUTER_API_KEY means regex-only detection and /analyze returns 400; no MONGODB_URI means the audit log lives in memory and resets on restart. GET /health reports the actual state of each.

Using the console

Open http://localhost:5173. Four things happen there:

  1. Automatic traffic — pick an interval, press Start. Each tick calls one upstream demo tool and logs the result. Press Stop any time.

  2. Test your own data — paste text or choose a file, press Scan. The redacted result and every finding show immediately, with Copy and Download buttons.

  3. Connect a data source — switch between API, PostgreSQL, and MongoDB, fill in the connection details, press "Fetch & scan." The guard connects, pulls the data, redacts it, and shows the same result card as the upload panel. Connection details are used for that one request only — never logged, never stored. Use read-only credentials when pointing this at anything real.

  4. Redaction events — every scan from all three paths lands here, filterable by source, direction, and PII type. Click a row for the full finding list, a copy of the redacted text, and a download button. "Export" in the panel header downloads the whole visible log as JSON or CSV, or copies it to the clipboard.

API

Method

Path

Purpose

GET

/health

subsystem status

GET

/mcp/tools

tool catalogue from the upstream server

POST

/mcp/call

guarded tool call — { name, arguments }

GET

/mcp/demo/:tool?count=5

same call from a browser

POST

/scan

scan pasted/uploaded text — the console's upload panel

POST

/sources/http

fetch an external API and scan the response — { url, method?, headers?, body? }

POST

/sources/postgres

run a read-only query and scan the rows — { connectionString, query, limit? }

POST

/sources/mongo

run a find() and scan the documents — { uri, database, collection, filter?, limit? }

POST

/analyze

pull from MCP, redact, then ask an OpenRouter model about it

GET

/scheduler/status

is the automatic feed running, and its stats

POST

/scheduler/start

{ intervalMs? } — starts the automatic feed

POST

/scheduler/stop

stops it

GET

/audit/events?limit=&direction=&type=&origin=

audit events, newest first, each including the full redacted text

GET

/audit/summary

totals by type, direction and origin

origin on an event is one of scheduler (automatic feed), manual (paste/upload panel), source (a database or API connector), or api (a direct /mcp/call from an agent or script).

curl -s localhost:5000/mcp/tools | jq
curl -s -X POST localhost:5000/scheduler/start -d '{"intervalMs":30000}' -H 'content-type: application/json'
curl -s -X POST localhost:5000/scan -d '{"text":"SSN 123-45-6789"}' -H 'content-type: application/json'
curl -s -X POST localhost:5000/sources/http -d '{"url":"https://api.example.com/customers"}' -H 'content-type: application/json'
curl -s -X POST localhost:5000/sources/postgres -d '{"connectionString":"postgres://user:pass@host/db","query":"select * from customers limit 20"}' -H 'content-type: application/json'
curl -s -X POST localhost:5000/sources/mongo -d '{"uri":"mongodb://host","database":"app","collection":"customers"}' -H 'content-type: application/json'

Data source safety notes

  • PostgreSQL — only a single SELECT statement is accepted; anything containing INSERT, UPDATE, DELETE, DROP, ALTER, or a second statement after a ; is rejected before it reaches the database. A LIMIT is appended automatically if missing (default 20 rows, capped at 200). This is a safety net, not a substitute for connecting with a database user that only has SELECT privileges — use one.

  • MongoDB — only find() with an optional JSON filter is supported, capped at 200 documents. No writes, no aggregation pipeline execution.

  • HTTP — only http:// and https:// URLs are accepted; the response body is capped at SOURCE_MAX_CHARS (20,000 by default) before scanning.

  • None of the three ever write the connection string, URI, or headers to the audit log — only a sanitised label (the URL's host, or database.collection) is stored alongside the scan result.

Layout

src/
  config.ts             environment parsing
  logger.ts              structured JSON logging
  openrouter.ts           shared OpenRouter chat-completion client
  scheduler.ts             the automatic feed — off until start() is called
  service.ts             guarded call orchestration and audit recording
  server.ts               express app factory
  index.ts                process entry, graceful shutdown
  detection/
    patterns.ts         rule table, precedence, Luhn
    regex.ts              structural pass
    llm.ts                 OpenRouter-backed second pass
    mask.ts                overlap resolution and placeholder assignment
  dataSources/
    http.ts                generic external API connector
    postgres.ts             read-only PostgreSQL connector
    mongo.ts                 MongoDB find() connector
  mcp/client.ts          JSON-RPC over Streamable HTTP
  storage/                 AuditStore interface, Mongo and in-memory backends
  routes/                  health, mcp, scan, sources, audit, analyze, scheduler
  middleware/errors.ts     typed HTTP errors, async wrapper
tests/                     vitest — detection, HTTP contract, scheduler, data sources
dashboard/                 React + TypeScript console

Configuration

Variable

Default

Effect when unset

MCP_SERVER_URL

dlptest public server

—

OPENROUTER_API_KEY

—

AI pass skipped; /analyze returns 400

OPENROUTER_MODEL

openrouter/free

—

LLM_MAX_CHARS

6000

—

LLM_TIMEOUT_MS

30000

—

ANALYSIS_MODEL

same as OPENROUTER_MODEL

—

ANALYSIS_TIMEOUT_MS

30000

—

MONGODB_URI

—

in-memory audit log

SOURCE_TIMEOUT_MS

15000

—

SOURCE_MAX_CHARS

20000

—

SOURCE_DEFAULT_LIMIT

20

—

SOURCE_MAX_LIMIT

200

—

PORT

5000

—

CORS_ORIGIN

*

—

openrouter/free is OpenRouter's own router — it picks a free underlying model per request. It has no dollar cost but is still rate-limited (roughly 20 requests/minute on the free tier), which is why the automatic feed defaults to a 45-second interval and why it's off until you start it.

Note that MONGODB_URI above configures the guard's own audit log storage. The live MongoDB connector in "Connect a data source" is separate and unrelated — its connection URI is entered per-request in the dashboard, not in .env, even if it happens to point at the same cluster.

Deployment

npm run build
npm start

Any host that runs npm ci && npm run build then npm start works — Render, Railway, Fly.io, a plain VPS. The dashboard is a static Vite build (npm run build in dashboard/) with VITE_GUARD_URL pointed at the deployed guard.

Roadmap

  • Replace the OpenRouter call in detection/llm.ts with a local Ollama model so payloads never leave the host during the AI pass.

  • Per-type policy — redact, block, allow — evaluated before masking.

  • Server-sent events in place of console polling once event volume justifies it.

  • Saved connection profiles for the data-source panel (still never persisting credentials server-side — a browser-local, opt-in convenience only).

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides a pre-flight/post-flight firewall for LLM calls with comprehensive detection, classification, policy enforcement, reversible redaction, output safety, and immutable audit logging.
    1
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enforces deterministic security policies on Model Context Protocol traffic between agents and remote MCP servers, including request validation, signed human approval, response-side credential blocking, prompt-injection flagging, and privacy-minimized auditing.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables secure interoperability between LLM agents and MCP tool servers by sanitizing requests and responses, masking sensitive tokens, detecting PII, and performing server reputation scans.
    MIT