Skip to main content

Trentina

Trentina is a secure MCP gateway that inspects everything between your AI agents and the outside world — web content, MCP tool responses and tool definitions, Matrix messages, LLM completions, and monitoring alerts — through a three-layer defense pipeline at every ingress, with per-profile enforcement (flag or block) and a full audit trail. Content is never silently modified: what your agent reads is what actually arrived, plus Trentina's verdict. (E2EE Matrix rooms are ciphertext at the gateway and outside what any proxy can defend.) Named after the 1377 quarantine system from Ragusa, where incoming ships had to anchor offshore for thirty days before anyone was allowed into the city. Same idea: keep the commerce flowing without letting something dangerous through.

Capabilities

MCP Gateway

Single chokepoint between your agents and all their MCP backends. One endpoint, one bearer token, one audit log — instead of each agent connecting directly to dozens of MCP servers. Backend tools are namespaced automatically (slack__slack_search_messages, github__list_issues_tool) so there are no collisions.

Authentication

Four ways a client can prove who it is, chosen per profile: a static bearer token, an OAuth identity Trentina issues while proxying login to Google (with dynamic client registration or a provisioned confidential client), or a token minted by an external identity provider that Trentina only verifies — for connectors that will not authenticate against a third-party authorization server.

Per-Agent Profiles

Each consumer — Claude Code, Hermes, OpenClaw, or any MCP client — gets its own profile with independent tool access, defense settings, and authentication. Your human-supervised agent can have full tool access while your autonomous agent gets a locked-down subset, all through the same gateway.

Tool Allowlists & Denylists

Control which tools each agent can even see. Tools not in the allowlist are stripped from tools/list responses before they reach the consumer — they never enter the agent's context window. Supports exact names and glob patterns (delete*, *_gmail_*). Reduces both context cost and attack surface.

Parameter Guards

Per-tool argument validation at the gateway level. Restrict what values an agent can pass, not just which tools it can call. Example: "this agent can send email, but only to user@example.com." The call is rejected before it reaches the backend — no tokens spent, no side effects. Deterministic enforcement that doesn't depend on LLM behavior.

Response Guards

The egress half of parameter guards: the same allow/deny constraint applied to what a backend returns, before the result is reduced, scanned or relayed. Argument-side matching cannot cover a semantic tool — an agent asking a memory server for "my employer's roadmap" sends nothing matchable, and the restricted material arrives in the response. Deny-oriented, blocks the whole response rather than scrubbing it, and audited as policy rather than failure.

Three-Layer Defense Pipeline

Every piece of untrusted content passes through three independent detection layers. Layer 1 deterministically detects structural attacks (hidden markup, invisible Unicode, encoded payloads, exfiltration URLs) and normalizes a copy for Layer 2 to read. Layer 2 runs a Prompt Guard 2 86M classifier on that copy to catch instruction overrides. Layer 3 hands the original content to a quarantined LLM (Gemini Flash Lite) for semantic analysis — no tools, no memory, minimal blast radius. Each layer catches what the others miss.

Tool Description Compression

MCP servers ship verbose tool descriptions that waste context tokens. Trentina uses an LLM to compress every tool description as it passes through the gateway, caching results in SQLite so the model is only called once per unique description. Real-world results: 154 tools compressed from 62K to 17K characters (72% reduction), saving ~11K tokens per session. The compressed descriptions are fully functional — agents use them without issue.

Gateway Audit Log

Every tool call through the gateway is recorded in SQLite with profile, backend, tool name, success/failure, duration, and error message. The quarantine_stats tool exposes this data for monitoring — tool call counts, error rates, per-backend breakdowns. Data-driven evidence for tightening allowlists and identifying problems.

Cumulative Detection Memory

When block refuses a source, Trentina records it in a SQLite blocklist, and later block/flag requests for it are refused before anything is fetched — the system remembers what it's seen before. Blocklist entries include the source URL or content hash, detection timestamp, and risk level.

Content Tools

Five tools — fetch (URL), read (file), dir (directory listing), content (inline text), search (web) — each taking a trentina_mode argument. Every call runs all three layers; the mode decides only what is delivered. block refuses flagged or incompletely judged content. flag delivers the exact bytes with the verdict attached — a security-researcher grant. redact returns an extraction that L3 wrote and a second L3 pass verified, guided by trentina_prompt. The names are OpenRouter's guardrail actions, though redact rewrites through L3 rather than substituting spans; warn and clean, the pre-0.35.0 names, are deprecated aliases. Which modes an agent may choose is policy, not the agent's call: the profile's defense.modes through the gateway, which inserts the same argument into every backend's tools, or TRENTINA_MODE/TRENTINA_MODES standalone.

LLM Key Proxying

Proxy LLM API calls (Gemini, OpenAI, Anthropic) through the gateway so API keys never leave the trusted boundary. Agents send model requests to Trentina, which forwards them with the real credentials. Adding a new provider is a YAML entry, not code. Streaming and non-streaming responses are forwarded transparently.

Matrix Reverse Proxy

Proxy Matrix Client-Server API traffic through the gateway so agents on the internal network can communicate via Matrix without direct internet access. Agents point MATRIX_HOMESERVER at Trentina instead of matrix.org. Long-poll /sync timeouts are tuned automatically.

Cockpit Plugin

Live web dashboard for the defense pipeline, built as a Cockpit plugin with PatternFly 6. Shows layer status, blocklist entries, and pipeline events in real time through the same web console sysadmins already use to manage RHEL systems. Vanilla JavaScript, no React, no build step.

Quick Start

# PyPI
pip install mcp-trentina-crunchtools

# uvx (zero-install)
uvx mcp-trentina-crunchtools

# Container (includes Prompt Guard 2 86M classifier)
podman run quay.io/crunchtools/mcp-trentina

Minimal Configuration

# Required for Layer 3 (Q-Agent) and description compression
export GEMINI_API_KEY=your-key

# Enable gateway mode
export TRENTINA_GATEWAY_ENABLED=true
export TRENTINA_PROFILES_PATH=/path/to/profiles.yaml

# Per-profile bearer tokens
export TRENTINA_PROFILE_MYAGENT_TOKEN=your-token

Claude Code

{
  "mcpServers": {
    "trentina": {
      "type": "streamable-http",
      "url": "http://localhost:8019/gateway/myprofile/mcp",
      "headers": {
        "Authorization": "Bearer your-token"
      }
    }
  }
}

Documentation

Document Description
MCP Gateway Architecture, routing, namespacing
Authentication Static bearer, OAuth proxy, delegated issuers
Per-Agent Profiles Profile schema, multi-agent setup
Tool Filtering Allowlists, denylists, glob patterns
Parameter Guards Per-tool argument validation
Response Guards Per-tool result validation (egress)
Defense Pipeline L1/L2/L3 layers, coverage matrix
Description Compression LLM-powered context reduction
Audit Log Call recording, stats, monitoring
Blocklist Cumulative detection memory
Quarantine Tools Web fetch, read, search, scan
LLM Key Proxying API key isolation via reverse proxy
Matrix Reverse Proxy Agent communication via Matrix
Cockpit Plugin Live defense pipeline dashboard
Internal: Gateway Design Original design document for contributors

Environment Variables

Trentina reads its gateway, profile and backend configuration from a YAML file; these variables control the process itself. Profile tokens (TRENTINA_PROFILE_<NAME>_TOKEN) and provider API keys are covered in Per-Agent Profiles and LLM Key Proxying.

Variable Default Description
TRENTINA_LOG_LEVEL INFO Application log level, sent to stderr. Any standard Python level name.
TRENTINA_GATEWAY_ENABLED unset (disabled) Turns on the MCP gateway (profiles, auth, allowlists, audit). See MCP Gateway.
TRENTINA_PROFILES_PATH /etc/trentina/profiles.yaml Path to the gateway's profile YAML file. See Per-Agent Profiles.
TRENTINA_LEGACY_MCP unset (disabled) Restores the pre-gateway unguarded /mcp endpoint. Bypasses auth, allowlists and audit — migration aid only. See MCP Gateway.
TRENTINA_MODEL_PROVIDER gemini Global LLM provider for L3 Q-Agent and tool-description compression, overridable per-profile. See Per-Agent Profiles.
TRENTINA_PROVIDER_FALLBACK unset (none) Comma-separated provider names to fall back to if TRENTINA_MODEL_PROVIDER is unavailable.
OLLAMA_BASE_URL http://localhost:11434 Base URL for the Ollama provider.
OLLAMA_MODEL qwen2.5:0.5b Model used when the Ollama provider is selected. See LLM Key Proxying.
QUARANTINE_MODEL gemini-2.5-flash-lite Model used for quarantine agent (L3) extraction/detection calls.
QUARANTINE_SEARCH_MODEL gemini-2.5-flash Model used for grounded L0 search.
TRENTINA_REQUIRE_L2 true false lets block/redact deliver with a warning when the L2 model is absent, instead of refusing. Never excuses a partial scan. See Defense Pipeline.
TRENTINA_REQUIRE_L3 true The same for an absent L3 provider. Replaces QUARANTINE_FALLBACK (removed in 0.31.0; setting it now fails startup).
TRENTINA_MODE block Standalone only: the mode an omitted trentina_mode resolves to. flag or block. Under the gateway the profile's defense.enforcement decides.
TRENTINA_MODES the default Standalone only: comma-separated modes a call may choose (block,redact). A default outside the set fails startup. Under the gateway the profile's defense.modes decides.
QUARANTINE_MAX_CONTENT 100000 Max characters of content sent to the quarantine LLM per call. See Token Routing.
CLASSIFIER_THRESHOLD 0.5 Malicious-score threshold above which the L2 classifier flags content.
CLASSIFIER_MODEL_PATH /models/prompt-guard-2-86m Filesystem path to the ONNX classifier model. Set to /models/prompt-guard-2-86m by the container image.
CLASSIFIER_MAX_TOKENS 32768 Max tokens the L2 classifier will scan before truncating.
CLASSIFIER_THREADS 4 ONNX Runtime intra-op thread count for the L2 classifier.
QUARANTINE_DB ~/.local/share/mcp-trentina/trentina.db (container: /data/quarantine.db) Path to the main SQLite database (blocklist, audit log). See Audit Log and Blocklist.
TRENTINA_PERIMETER_DB <QUARANTINE_DB's directory>/perimeter.db Path to the perimeter verdict-cache database, deliberately separate from QUARANTINE_DB.
QUARANTINE_TRUST_CONFIG ~/.config/mcp-env/mcp-trentina-trust.json Path to the trust-level configuration JSON. See Quarantine Tools.
TRENTINA_RATE_LIMIT on Set to off/0/false to disable rate limiting on the unauthenticated OAuth write paths. An escape hatch for an operator locked out during an incident — not a normal setting.
TRENTINA_MAX_REGISTRATION_BYTES 8192 Largest POST /register body accepted, rejected before it is parsed. 0 or negative disables the cap.
TRENTINA_FORWARDED_ALLOW_IPS unset (uvicorn's default of 127.0.0.1) Peer addresses whose X-Forwarded-For is trusted. Set this to your reverse proxy's address, or every caller behind it shares one rate-limit bucket. See Authentication.
TRENTINA_REGISTRATION_TTL_DAYS 90 How long a DCR registration lives once a token exchange has promoted it. Each later exchange re-stamps it.
TRENTINA_OAUTH_CULL_INTERVAL 3600 Seconds between sweeps that unlink expired registrations, transactions and CSRF records from the OAuth store. Floored at 60.

Development

uv sync --all-extras
uv run ruff check src tests
uv run mypy src
uv run pytest -v

The container image is built by the GHA pipeline (container.yml), never locally. The model-export stage needs a gated HuggingFace credential that only CI holds, and building outside the pipeline causes drift. Push the branch and let the pipeline verify the image.

License

AGPL-3.0-or-later

Release files for mcp-trentina-crunchtools 0.35.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-trentina-crunchtools 0.35.0
File Size Uploaded
mcp_trentina_crunchtools-0.35.0.tar.gz 901.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-trentina-crunchtools 0.35.0
File Interpreter ABI Platform
mcp_trentina_crunchtools-0.35.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.2 MB

Release files / mcp_trentina_crunchtools-0.35.0.tar.gz

Download URL mcp_trentina_crunchtools-0.35.0.tar.gz
Size 901.2 kB
Tags Source
SHA-256 checksum
How to use checksums
58a198acc5bb0b20dea7321caf042bb0e919dc30e21781f94e65f9cb4ffcfc58
BLAKE2b-256 checksum
How to use checksums
30f88414cff990048df5aa245f61adc893c92ad70e40e9fde0be6059ef9905df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / mcp_trentina_crunchtools-0.35.0-py3-none-any.whl

Download URL mcp_trentina_crunchtools-0.35.0-py3-none-any.whl
Size 337.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
905016053caaf4557c5998706f9ef042116f45a9478e1f74ee3cebf757f70c77
BLAKE2b-256 checksum
How to use checksums
0cc36b68c13e9548baf2f6c4c45407f8474b518fd5537ea11653f86127fc7535
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.35.0 This release

2 release files

0.20.1

2 release files

0.19.1

2 release files

0.19.0

2 release files

0.12.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.5.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page