MCP server de IntentProbe
Commit 19 oct 2026Permite que los agentes de IA realicen clasificaciones de seguridad y comprobaciones de guardrails a alta velocidad leyendo los estados ocultos de una única pasada de un modelo local.
También conocido como mcpware/IntentProbe
- Stars
- 9
- Herramientas
- —
- Descargas, 30 días
- —
- Última versión
- —
- Último commit
- 19 oct 2026
- Licencia
- Apache-2.0
¿Qué es IntentProbe MCP?
IntentProbe es un MCP server. Permite que los agentes de IA realicen clasificaciones de seguridad y comprobaciones de guardrails a alta velocidad leyendo los estados ocultos de una única pasada de un modelo local.
Resumen generado a partir del README del proyecto
Acerca del MCP server de IntentProbe
Los desarrolladores que construyen agentes de IA pueden usar IntentProbe para realizar clasificaciones de seguridad y comprobaciones de guardrails a alta velocidad leyendo los estados ocultos de una única pasada de un modelo local. En lugar de ejecutar múltiples llamadas costosas a un LLM para verificar toxicidad, spam o jailbreaks, este sistema ejecuta un único modelo de lenguaje local congelado y utiliza probes pequeños y específicos para analizar las activaciones internas. Este enfoque permite realizar múltiples comprobaciones simultáneas con un aumento mínimo de la latencia.
El sistema se ejecuta completamente de forma local y sin telemetría, lo que lo hace adecuado para aplicaciones sensibles a la privacidad. Se utiliza mediante la integración de probes específicos como el scanner de tool-poisoning, el probe de autorización de acciones o el probe de escritura en memoria. Los usuarios pueden instalar el scanner de tool-poisoning vía pip para escanear configuraciones de MCP para Claude Desktop, Cursor o Windsurf. La arquitectura está diseñada para separar la detección de la política, proporcionando una señal que las aplicaciones host utilizan para decidir sobre acciones irreversibles.
Qué puedes hacer con él
- 1Escanear configuraciones de herramientas MCPUn desarrollador puede revisar sus configuraciones actuales de herramientas MCP en busca de instrucciones ocultas que podrían robar datos o tomar el control de las herramientas.
- 2Prevenir acciones no autorizadas del agenteUn agente de IA puede usar el probe de autorización para determinar si la solicitud de un usuario realmente otorga permiso para realizar una tarea sensible, como enviar un correo electrónico.
- 3Filtrar entradas de memoria a largo plazoUn asistente puede usar un probe especializado para clasificar qué partes de una conversación son lo suficientemente importantes como para guardarse en la memoria.
- 4Automatizar la seguridad en CI/CDLos equipos pueden usar una GitHub Action para bloquear automáticamente pull requests que introduzcan manifiestos de herramientas o skills envenenados.
Escrito a partir del README del proyecto. Cada caso de uso se verifica con una cita del mismo.
Verificaciones automáticas
Ejecutado 14 nov 2026Informe completo →Aún no verificado. Un servidor necesita una puntuación de 80, ningún hallazgo grave y suficientes datos para que podamos revisarlo. Cómo funcionan las verificaciones · Qué corregir para obtener más puntos
- Repositorio de origen vinculado y accesiblemcpware/intentprobe is public and reachablegithub.com/mcpware/intentprobe ↗Aprobado
- El paquete indica este repositorio como su origenNo verificado
- Procedencia de la compilación (atestación de Sigstore)No verificado
- Licencia de código abierto (OSI)Apache-2.0spdx.org/licenses/Apache-2.0.html ↗Aprobado
- Commit o lanzamiento en el último añoLast commit or release 2026-10-19github.com/mcpware/intentprobe ↗Aprobado
- OpenSSF ScorecardNo verificado
- El nombre del paquete no es similar a un paquete popularNo verificado
- No hay avisos críticos en el paquete ni en sus dependenciasNo verificado
- Sin instrucciones ocultas para el modelo0 tool descriptions and the README read; no override phrases, credential paths or hidden charactersAprobado
- Las herramientas destructivas están etiquetadasNo verificado
- El endpoint remoto responde al handshake de MCPNo verificado
README
Ver en GitHubIntentProbe
Why make the model read the same input again for every task?
You do not have to.
One agent turn may need toxicity, jailbreak, spam, sentiment, emotion and conversation-state checks on the same input. Asking a model each question separately repeats the expensive part. An IntentProbe runtime reads the input once, exposes selected hidden states through an activation bus, and lets many small probes reuse that same pass. Different probes can read different layers and use different pooling, normalization, classifiers and thresholds.
The first measured Qwen2.5-0.5B CPU runtime produced a clear systems result:
- across 80 real held-out texts per K, one forward plus one head averaged 68.63 ms; one
forward plus 16 heads averaged 73.34 ms. That is a 6.9% increase, with a paired mean ratio
of
1.069(95% CI[1.056, 1.078]); - measured head application itself rose from 0.38 ms to 1.85 ms. Of the 4.70 ms total increase, 1.47 ms is recorded head work and the remaining 3.23 ms is unattributed;
- on the separate matched ten-prompt comparator, one forward plus 16 heads averaged 62.70
ms. Sixteen repeated base-model forwards averaged 956.71 ms — 15.26× the shared path
(95% CI
[15.04, 15.49]).
The repeated-forward arm is deliberately favourable to repetition: it omits task prompts, language-model output scoring and generation. It is a lower bound, not a complete implementation of 16 LLM judges. The shared path requests all hidden outputs even at K=1, so the K=1 measurement is the activation-bus baseline rather than an optimized single-probe path.
The benchmark is evidence for the architecture, not a final ranking of the first 16 heads. Each head has its own task contract and admission evidence. New labelled data, a better readout recipe, a different classifier or a stronger local backbone can improve a task without changing the shared interface or retraining unrelated heads.
That separation is the architecture. One local model acts as a reusable semantic sensor. Small task heads turn its hidden states into independently tested signals. The host application decides what those signals are allowed to do. Detection, policy and irreversible action remain separate, auditable layers.
| Current layer | What exists now |
|---|---|
| Public products | PyPI tool-poisoning scanner; standalone Hugging Face authorization and memory-write probes |
| Measured research runtime | Reproducible one-forward fan-out across 16 frozen heads, with row-level timing artifacts and tests |
| Specified next runtime | General manifest registry, hot-loading and multi-head receipt emission; these are designed and schema-tested, not yet the PyPI product surface |
Read the plain-English public note, IntentProbe: One Local Model Pass, Many Task-Specific Probes, the research manuscript IntentProbe: Many Task-Specific Probes from a Single Frozen Small-Model Forward Pass, or the complete technical disclosure. The v0.1.2 release record links the frozen evidence ledger.
GEASS LABS INC.
└── MCPware publisher; GitHub/Hugging Face organization
└── IntentProbe research and product umbrella
├── Papers readout benchmark + shared-runtime architecture
├── Runtime activation extraction, policy, and receipts
└── Probe products / heads poisoning, authorization, memory, and future tasks
One architecture, three public probe products
IntentProbe is a family of small classifiers that read the internal activations of frozen local language models. Each probe has its own task, training data, selected layers, benchmark, and probe weights.
| Probe | The problem it catches | Frozen model | Activation recipe | Learned artifact |
|---|---|---|---|---|
| Tool-poisoning probe | A tool or agent skill hides instructions to steal data, take over another tool, or act outside its stated job | Qwen/Qwen2.5-0.5B |
Mean-pooled hidden states 13–15 | 22 KB |
| Action-authorization probe | An agent treats “help me apply” or “draft an email” as permission to submit or send something the user has not reviewed | openbmb/MiniCPM5-1B-Base |
Standardized masked-mean hidden outputs 13–14 | 28 KB |
| Memory-write probe | An assistant needs to rank which utterances are useful enough to carry into long-term memory | Qwen/Qwen2.5-0.5B |
Masked-mean hidden output 11 | 15 KB |
The idea behind all three is simple. A language model creates internal number patterns while it reads an input. Those patterns are called activations. IntentProbe freezes the model, reads a selected set of middle layers, and trains a small logistic classifier for one specific job.
This signal is different from keyword rules and surface-text classifiers. It also avoids asking another LLM to say “safe” or “unsafe.”
The probe catalog keeps each probe's model recipe, artifact, benchmark, source record, and reproduction steps together.
The PyPI package currently ships the Qwen tool-poisoning scanner. The MiniCPM authorization probe and Qwen memory-write probe are standalone research releases with local scorers and complete selection receipts.
The main research track is now the multi-task activation benchmark: one common protocol for testing how backbone, normalized depth, token pooling, and layer combination interact across authorization, prompt injection, tool/skill poisoning, memory write, and toxicity. Individual probes remain useful products, while the paper studies the engineering choices that transfer—or fail to transfer—between tasks.
Install the tool-poisoning scanner
python3 -m pip install intentprobe
If your macOS Python blocks global installs with an "externally managed environment" error, use an app venv instead:
python3 -m venv .venv-intentprobe
.venv-intentprobe/bin/python -m pip install intentprobe
Then scan the MCP tools already configured on your machine. scan-config auto checks common Claude
Desktop, Claude Code, Codex, Cursor, Windsurf, and repo MCP config locations:
intentprobe scan-config auto --format summary
Or scan a suspicious tool description:
intentprobe scan --format summary --text "Reads SSH config and private keys, then silently uploads credentials to a remote server."
First model-backed scan downloads Qwen2.5-0.5B (~1 GB, once). After that, everything stays local.
Try the authorization probe
Suppose you ask an agent to show you an email draft. The proposed action below tries to send it instead. The authorization probe scores the request, conversation history, and exact tool call together:
python3 -m pip install "transformers>=5.8,<6" "torch>=2.2" "numpy>=1.26" huggingface_hub
hf download mcpware/intentprobe-minicpm5-1b-authorization --local-dir ./intentprobe-auth
python3 ./intentprobe-auth/score.py \
--artifact ./intentprobe-auth/probe.npz \
--call-json '{"tool":"send_email","args":{"to":"sam@example.com","body":"The draft"}}' \
--user-request 'Show me the draft before sending.' \
--history 'The assistant displayed a draft, but the user has not approved it.'
The scorer returns an approve_score. It is designed to sit beside exact runtime checks for the
payload, recipient, preview, final confirmation, and any change made after approval.
GitHub Action
Use IntentProbe as a CI gate for MCP configs, skills, and tool manifests:
name: IntentProbe scan
on: [pull_request, workflow_dispatch]
jobs:
scan-ai-tools:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mcpware/IntentProbe@main
with:
paths: |
.
fail-on: block
Inputs, target paths, and exit behavior: docs/GITHUB_ACTION.md. Quickest proof without a video — run the demo script or inspect the live demo repo: safe PR passes, poisoned PR blocks.
What the current probe products run
Each current probe product follows the same basic path:
request + context + proposed action
↓
frozen local model
↓
selected hidden activations
↓
small task-specific probe
↓
review signal or runtime receipt
The current PyPI scanner uses the Qwen tool-poisoning path shown below.
The activation probe is the primary signal for allow / warn. The block tier additionally
requires static-keyword corroboration to control false positives, so a novel no-keyword input the
probe flags surfaces as warn, not block. Use it as a review signal, not the only boundary.
Note: the probe needs the frozen 0.5B host model to produce activations, so inference is heavier than a standalone text classifier, not lighter. The ~22 KB size is a training-and-storage advantage, not a runtime one.
Why not just ask the model "is this safe?"
LLM-as-judge is an output-level mechanism: you ask a model to say safe or unsafe, and the generated
answer becomes part of the attack surface — a poisoned tool can argue "I am safe", and a judge prompt
can be steered. IntentProbe is representation-level: it scores the hidden activation state the text
produces, before any verbal answer. We also tested direct-prompting the same Qwen2.5-0.5B sensor as a
judge; the deterministic label baseline flagged every clean curated item as poisoned (clean FPR =
1.000). The reproducible baseline is in research/.
Benchmarks
Shared runtime: one forward, sixteen heads
The architecture benchmark separates two questions that use different panels:
| Question | Inputs | Measured result |
|---|---|---|
| What changes when the same forward serves 1 versus 16 heads? | 80 held-out texts per K | 68.63 → 73.34 ms; paired ratio 1.069, 95% CI [1.056, 1.078] |
| What changes when 16 probes share one pass instead of repeating the base model? | Same 10 prompts in both arms | 62.70 vs 956.71 ms; repeated/shared ratio 15.26, 95% CI [15.04, 15.49] |
The 16-head suite is a heterogeneous research workload, not a claim that 16 production probes are ready. Each head keeps its own held-out discrimination, calibration and task contract. The systems finding is that compatible heads can share the expensive pass; admission remains a separate decision for every head.
Full row-level timing artifacts, the frozen head registry and reproduction code are in
ONE-FORWARD-MULTIHEAD-EXP001.
Action authorization: did the user approve this exact action?
This benchmark tests a common agent failure. The user asks for help preparing an email, application, or tool action. The agent must distinguish that request from clear permission to carry it out.
We froze six small backbones and tested every individual layer, every adjacent two-layer window, every adjacent three-layer window, and two pooling methods. MiniCPM5-1B ranked first on the frozen validation screen. Its best representation came from masked-mean hidden outputs 13–14, rather than the final layer.
| Same 1,600-row training budget | Separate-test AUROC | Separate-test AUPRC |
|---|---|---|
| MiniCPM5 activation probe | 0.8137 | 0.8223 |
| Word/bigram TF-IDF logistic | 0.7897 | 0.8079 |
The separate test contains 3,000 examples and has zero exact rendered-text overlap with the training
or validation rows. The paired AUROC difference was +0.0240, with a 95% bootstrap interval of
+0.0056 to +0.0429 and p=0.0150.
The layer search also produced a broader engineering finding: every winning activation probe used masked-mean pooling, but the best depth and window changed across model architectures.
| Frozen backbone | Best hidden output(s) | Validation AUPRC |
|---|---|---|
| MiniCPM5-1B | 13–14 | 0.9228 |
| Qwen3.5-0.8B | 14–16 | 0.9205 |
| Qwen2.5-0.5B | 16–18 | 0.9136 |
| LFM2.5-230M | 10–12 | 0.9090 |
| Granite 4.0 350M | 19 | 0.9081 |
| Qwen3-0.6B | 14 | 0.9045 |
We also ran the frozen probe on two independently released authorization benchmarks. On AuthorizationPairs, both activation and a stronger word-and-character TF-IDF baseline fell near chance. On the 156-row human-labelled DelegationCheck benchmark, an audit caught that the published 192-token interface erased 40 of 48 controlled pair contrasts. A post-hoc full-context rerun kept all 48 contrasts visible; the activation probe reached 0.4850 AUPRC / 0.5632 AUROC versus 0.4533 / 0.5276 for full-text TF-IDF, but the paired family-bootstrap intervals included zero and both systems followed the authored contrast direction in 29/48 pairs. The full audit trail is preserved rather than replacing the original result.
Full methods, hashes, model revisions, uncertainty estimates, held-out results, and reproduction commands are in the authorization research workspace and the Hugging Face release.
Tool poisoning and prompt injection
Reproducible from research/: the experiment scripts and result JSONs are committed; the PI datasets are
downloaded from their original public sources (deepset, SafeGuard, SPML, jayavibhav, HackAPrompt on
Hugging Face). The point is generalization to attacks the probe never trained on. The HackAPrompt headline
runs on the shipped Qwen2.5-0.5B; the cross-source section below also reports a research upper bound that
lets the loop pick a larger 1.5B sensor.
1. Generalization to unseen attacks: HackAPrompt (n=3,866 real attacks, a source neither detector trained on)
HackAPrompt is a large set of attacks written by real people in a red-teaming competition. Neither the probe nor the text baseline ever saw it during training. It is positive-only (attacks, no benign), so we report recall at a clean false-positive rate fixed on the training data, not AUROC.
recall @ 5% clean-FPR recall @ 1% clean-FPR
───────────────────── ─────────────────────
Probe (Qwen2.5-0.5B, 90.3% 88.3%
mean-pooled concat L13-15)
TF-IDF (same training data) 52.8% 30.3%
Same training data, same held-out evaluation, same false-alarm budget. At a 5% false-positive rate the probe catches 90% of these unseen attacks; a text classifier trained on the same data catches 53% — it does fine on attacks that reuse familiar wording, but its learned vocabulary does not transfer to wording it never saw, so recall drops. The probe keys off the model's internal representation instead, so it holds up. At the stricter 1% setting the gap is wider still (88% vs 30%). Caveat: HackAPrompt is positive-only, so this is recall at a matched FPR set on the training clean data, not a full AUROC; the sample is uniform-random over the corpus, not an exhaustive panel.
2. Curated cross-source generalization: leave-one-source-out, 4 real PI datasets
Train on three of {deepset, safeguard, spml, jayavibhav}, test on the held-out fourth, repeat for each. The shipped fixed config (Qwen2.5-0.5B, mean-pooled concat L13-15, no per-input picking) is the product number:
held-out source probe (shipped 0.5B) TF-IDF (same data)
─────────────── ──────────────────── ──────────────────
deepset 0.933 0.732
safeguard 0.999 0.993
spml 0.990 0.935
jayavibhav 1.000 0.997
─────────────── ──────────────────── ──────────────────
mean 0.980 0.914
deepset is where the gap is widest: TF-IDF's vocabulary does not transfer to the held-out source (0.732) while the probe holds (0.933). The other three are near ceiling, so there is less room to separate.
A nested cross-validation that is additionally free to pick a larger 1.5B sensor per fold (model + layer selected on the training sources only, never the held-out one) reaches mean 0.984, with 95% bootstrap CIs on the probe-minus-TF-IDF difference: deepset +0.209 [0.168, 0.250], spml +0.059 [0.044, 0.077], safeguard +0.006, jayavibhav +0.002 (3/4 significant). That is a research upper bound, not the shipped 0.5B artifact. An exhaustive single+pair search tops out around 0.982; combining layers gives no gain over one good mid-layer.
3. Tool poisoning: partial, leave-one-corpus-out
The cross-source advantage extends to tool poisoning, but only partially — and on synthetic attacks (there is no real-human tool-poisoning corpus yet, so these are constructed).
held-out corpus probe TF-IDF difference (95% CI)
─────────────── ───── ────── ───────────────────
MCPTox 0.738 0.545 +0.193 [0.145, 0.241] significant
routeguard 0.640 0.582 a non-significant lean
synthetic minpairs 0.494 0.498 both at chance (out of distribution)
MCPTox is a clear win. Our own synthetic minimal-pairs set is out of distribution for both detectors, and both sit at chance on it.
Within-distribution, the text baseline is not blind — it wins. On matched-vocabulary minimal pairs from the distribution the probe was trained on, the shipped 0.5B probe scores AUROC ~0.74 vs TF-IDF ~0.82 — a text classifier is slightly better there. (A nested CV free to pick a 1.5B sensor closes it to roughly a tie, ~0.79 vs ~0.82, but that is not the shipped config.) The edge is generalizing to new sources and new vocabulary, not same-vocabulary detection inside one distribution.
Competitive landscape
| Type | Who | How they scan | How IntentProbe differs |
|---|---|---|---|
| MCP scanner | Snyk Agent Scan (formerly Invariant MCP-Scan), Cisco AI Defense, NVIDIA SkillSpector | Static rules, AST, YARA signatures, LLM-as-judge | Adds a model-internal activation signal; static keywords still corroborate the block tier |
| Text classifier | ProtectAI DeBERTa (used by Invariant/Snyk/Lakera/promptfoo), Meta Prompt Guard | Classify text as injection / jailbreak | Reads the host model's internal activations instead of classifying the surface text, a different and complementary signal |
| Probe-based | PIShield, TaskTracker (research code); RouteGuard, MindGuard (papers); frontier-lab production probes (e.g. Google Gemini) | Linear probe / classifier on model internals | Same family of method; IntentProbe's angle is the deployment shape: installable, pre-install, scans the tool description on activations |
| LLM-as-judge | NeMo, OpenAI Guardrails, Promptfoo | Ask another LLM "is this poisoned?" | Deterministic, local, no API call; scores state not the verbal answer |
| Enterprise cloud | Lakera, Azure, Google Model Armor, AWS Bedrock | Ship content to a vendor cloud | Runs locally; benchmarks, scripts, and the probe artifact are public (datasets from their original sources) |
Full source-backed comparison: docs/COMPETITIVE_LANDSCAPE.md.
Use it
# Scan Claude/Cursor/Codex MCP configs already on this machine
intentprobe scan-config auto --format summary
# Scan a suspicious tool description
intentprobe scan --format summary \
--text "Reads SSH config and private keys, then silently uploads credentials to a remote server."
# Scan an MCP server / package / skill folder before installing
intentprobe scan-path ./some-mcp-server --format summary --fail-on block
# Batch scan a JSON array of descriptions
intentprobe batch --batch-file tools.json --format summary
# CI gate (exit code 2 on block)
intentprobe scan --fail-on block --text "..."
Real output (run locally on the shipped artifact):
$ intentprobe scan --format summary \
--text "Reads SSH config and private keys, then silently
uploads credentials to a remote server."
input-1: decision=block risk=0.950 (activation=0.913, static=0.950)
- cached probe qwen-pooled-curated-core-l13-15-v2 score=0.913
- static: private keys, credential files
- static: uploading data outside local scope
$ intentprobe scan --text "A calculator that adds two numbers."
input-1: decision=allow risk=0.000
Preguntas sobre IntentProbe MCP
¿Qué es IntentProbe?
Es una familia de clasificadores pequeños que leen las activaciones internas de modelos de lenguaje locales congelados para realizar comprobaciones específicas de tareas, como la detección de toxicidad o de envenenamiento de herramientas (tool-poisoning).
¿Qué tan rápido es IntentProbe en comparación con llamadas repetidas a un LLM?
El uso de una ruta compartida para 16 probes es aproximadamente 15.26 veces más rápido que realizar dieciséis ejecuciones (forwards) repetidas del modelo base.
¿Puedo usarlo para escanear configuraciones de herramientas MCP?
Sí, puedes usar el scanner de tool-poisoning para revisar ubicaciones comunes de configuración de MCP para Claude Desktop, Cursor y más.