GitHunt
NO

noblepayne/mcp-injector

HTTP shim for injecting MCP tools into OpenAI-compatible chat completions

mcp-injector

Resilient LLM gateway shim with virtual models, provider fallbacks, and secure MCP tool injection

mcp-injector sits between an agent (like OpenClaw) and LLM gateways. It provides automatic failover, error translation, and a secure governance framework for MCP tool execution.

Key Features

  • Virtual model chains - Define fallback providers with cooldowns.
  • Transparent Loop Preservation - Accumulates all internal turns (reasoning, tool calls, results) and synchronizes them with clients via signed footers.
  • Session Re-hydration - Automatically restores conversation context from durable storage when a session-id is provided.
  • Governance Framework - Declarative tool access policies (Permissive/Strict).
  • PII Scanning & Restoration - Automatic redaction of sensitive data in prompts. Trusted tools can receive original PII values for secure processing.
  • Signed Audit Trail - Tamper-proof NDJSON logs with ULID and HMAC chaining.
  • Provider-Level Observability - Granular tracking of tokens, requests, and rate-limits per provider.
  • Multi-transport MCP - Support for HTTP and STDIO (local process) MCP servers.
  • Error translation - Converts cryptic provider errors into actionable messages.

Governance & Security

mcp-injector includes a robust governance layer configured via the :governance key in mcp-servers.edn (copy from mcp-servers.example.edn).

Governance Modes

  • :permissive (Default): All tools are allowed unless explicitly denied.
  • :strict: All tools are denied unless explicitly allowed in the policy.

Privileged Tools

Certain high-risk tools (like clojure-eval) are marked as Privileged. These tools are always blocked by default, even in permissive mode, unless explicitly listed in an :allow rule.

Example Policy

:governance
{:mode :permissive
 :policy
 {:mode :permissive  ; Fallback mode for this policy (overrides global)
  :allow ["mcp__stripe__*"]
  :deny ["mcp__danger-server__*"]
  :rules [{:model "gpt-4o-mini" :deny ["clojure-eval"]}]
  :sampling {:trusted-servers ["stripe" "postgres"]}}
 :audit
 {:enabled true :path "logs/audit.log.ndjson"}
  :pii
  {:enabled true :mode :replace :proximity-check-enabled true}}

PII Hardening & False Positive Reduction

The PII scanner uses a multi-layered approach to minimize false positives while catching real secrets:

  1. Whitelisting: Local file paths (Windows/POSIX), URLs, IP addresses, and UUIDs are automatically ignored.
  2. Character Diversity: Tokens must contain at least 4 character classes (lower, upper, digit, special) OR 3 classes with at least 20 characters. This prevents descriptive strings like mcp__stripe__retrieve_customer from being flagged.
  3. Proximity Check: By default, general high-entropy strings are only redacted if they follow assignment-like keywords (e.g., api_key:, token =). Explicit regex patterns (AWS, Anthropic, etc.) bypass this check for maximum safety.

PII Restoration (Smart Vault)

For tools that need access to original PII data (e.g., a Stripe integration that must see real email addresses), configure trust levels:

:servers
{:stripe
 {:url "http://localhost:3001/mcp"
  :trust :restore  ; :none (default), :read, or :restore
  :tools [{:name "retrieve_customer" :trust :restore}]}}
  • :none (default): Tool receives redacted tokens like [EMAIL_ADDRESS_a35e2662]
  • :restore: Tool receives original values (e.g., wes@example.com)

The vault uses deterministic SHA-256 hashing with a per-request salt, ensuring tokens are consistent within a request but not leakable across requests.

⚠️ Security Notice: clojure-eval Escape Hatch

The clojure-eval tool is a privileged escape hatch that allows the LLM to execute arbitrary Clojure code on the host JVM. This is Remote Code Execution (RCE) by design.

  • Default State: Disabled. You must explicitly allow clojure-eval in your policy's :allow list.
  • Risk: If enabled, a compromised, hallucinating, or prompt-injected LLM gains full system access—including files, environment variables, network, and process control.
  • Mitigation: Only enable clojure-eval for highly trusted models in isolated environments. Treat it as root-level access.
  • Startup Warning: When enabled, mcp-injector logs a CRITICAL audit event at startup.

Observability & Tracing

Action Receipts — When tools run during a request, mcp-injector prepends a clean markdown receipt to the response content:

Action Receipt: trace_id=abc123 | 2 tools (165ms total)
- stripe.get_customer: 45ms
- postgres.query: ERROR: timeout
---

Receipts are:

  • Prepended (not appended) — better for Telegram/Slack UX
  • PII-masked — sensitive values replaced with tokens
  • Controllable via config/env var

Response Headers — Every response includes W3C trace headers for distributed tracing:

X-Injector-Traceparent: 00-<trace-id>-<parent-id>-00

Configure observability:

{:receipt-mode :on}    ;; :on, :off, or :errors-only
{:receipt-style :emoji} ;; :emoji (future) or :ascii
{:footer-mode :off}    ;; :off (default) or :legacy

Or via environment variables:

MCP_INJECTOR_RECEIPT_MODE=on|off|errors-only
MCP_INJECTOR_RECEIPT_STYLE=emoji|ascii
MCP_INJECTOR_FOOTER_MODE=off|legacy

Per-request override: extra_body: {:receipt false} suppresses the receipt for that request.

Quick Start

Prerequisites

Installation

nix develop
bb test
bb run

Configuration

Copy the example config and customize:

cp mcp-servers.example.edn mcp-servers.edn

Environment Variables

Variable Description Default
INJECTOR_AUDIT_SECRET 32-byte secret for signing audit log entries. (auto-generated)
MCP_INJECTOR_AUDIT_LOG_PATH Path for NDJSON audit log. logs/audit.log.ndjson
MCP_INJECTOR_PORT Server port. 8080
MCP_INJECTOR_LLM_URL LLM gateway endpoint. http://localhost:11434
MCP_INJECTOR_MAX_ITERATIONS Agent loop iteration limit. 10
MCP_INJECTOR_LOG_LEVEL Log verbosity. debug
MCP_INJECTOR_TIMEOUT_MS LLM request timeout. 1800000
MCP_INJECTOR_RECEIPT_MODE When to show action receipts: on, off, or errors-only. on
MCP_INJECTOR_RECEIPT_STYLE Receipt style: emoji or ascii. emoji
MCP_INJECTOR_FOOTER_MODE Legacy HTML footer: off or legacy. off

Edit mcp-servers.edn:

{:servers
  {:stripe
   {:url "http://localhost:3001/mcp"
    :tools ["retrieve_customer" "list_charges"]}}
 
 :llm-gateway
 {:url "http://localhost:8080"
  :virtual-models
  {:brain
   {:chain ["provider1/model1" "provider2/model2"]
    :cooldown-minutes 5}}}}

Control API

  • GET /api/v1/status: Health and version.
  • GET /api/v1/mcp/tools: List discovered tools.
  • GET /api/v1/stats: Usage statistics broken down by model and provider.
  • GET /api/v1/audit/verify: Cryptographically verify the audit log integrity.
  • POST /api/v1/mcp/reset: Clear caches and restart processes.

NixOS Deployment

services.mcp-injector = {
  enable = true;
  mcpServers = { ... };
  governance = {
    mode = "permissive";
    policy = {
      allow = [ "mcp__stripe__*" ];
    };
  };
};

Status: Production-ready | Tests: 72 passing | Built with: Babashka + http-kit + Cheshire