prompt-protection
Überblick
Beschreibung vom Entwickler (englisches Original)
Scan prompts, tool definitions and model output for injection, and guard agent tool calls.
Die drei Säulen von PopNx MCP
Diese drei werden nie zu einer Punktzahl zusammengefasst: Meinungen, Messungen und Beliebtheit sind verschiedene Dinge.
- Stimmen der NutzeriNoch keine BewertungenBewertungen starten in einem späteren Schritt zusammen mit Benutzerkonten
- Unsere Basischecksi1 von 1 bestandenAnhand öffentlicher Informationen geprüft; Code noch nicht gescannt
- NutzungiAm Anfang↓ 1365/Wo. · ★ –
Was du damit machen kannst
Für diesen Server haben wir noch keine Zusammenfassung in einfacher Sprache geschrieben. Unten stehen die Fakten, die wir aus der Registry gelesen haben.
- Verbindung: Läuft auf deinem Computer
- Transport: stdio
- Kategorie: Suche & KI-Gedächtnis
Installation
Wähle die KI-App, die du nutzt, und kopiere die Einstellungen.
Bevor du installierst
- Basischecks: 1 von 1 bestanden
- Läuft auf deinem Computer mit den Rechten deines Benutzerkontos (Dateien, Netzwerk, Apps).
- Die Registry nennt keinen Schlüssel zum Eintragen.
Du brauchst
- npmNode.js installiert (für den Befehl npx)
Welche App nutzt du?
Wähle oben deine App. Wir merken sie uns, damit der Button beim nächsten Mal „In … installieren“ anzeigt.
Öffne Claude Desktop → Settings → Developer → Edit Config und füge dies in claude_desktop_config.json ein
{
"mcpServers": {
"prompt-protection": {
"command": "npx",
"args": [
"-y",
"prompt-protection"
]
}
}
}Führe das in deinem Terminal aus
claude mcp add prompt-protection -- npx -y prompt-protectionOder kopier die Einstellungen selbst
In .cursor/mcp.json in deinem Projekt oder in ~/.cursor/mcp.json einfügen
{
"mcpServers": {
"prompt-protection": {
"command": "npx",
"args": [
"-y",
"prompt-protection"
]
}
}
}Dein Browser fragt, ob er die App öffnen darf, dann zeigt die App die Einstellungen und bittet dich um Bestätigung. Schlüsselwerte bleiben leer, damit du sie selbst einträgst.
Oder kopier die Einstellungen selbst
In .vscode/mcp.json in deinem Projekt einfügen
{
"servers": {
"prompt-protection": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"prompt-protection"
]
}
}
}Dein Browser fragt, ob er die App öffnen darf, dann zeigt die App die Einstellungen und bittet dich um Bestätigung. Schlüsselwerte bleiben leer, damit du sie selbst einträgst.
Dieser Server läuft auf deinem Computer, und ChatGPT kann sich nur mit Servern im Internet verbinden. Wähle eine andere App.
Deine Auswahl bleibt in einem Cookie auf diesem Gerät; kein Konto nötig.
Diese Einstellungen werden aus dem Registry-Eintrag des Entwicklers erzeugt. Wenn in der README etwas anderes steht, folge der README.
Was er kann
Läuft auf deinem Computer; die Tool-Liste erscheint nach der Installation in deiner KI-App.
Basischecksi
Wir prüfen Informationen, die jeder sehen kann; den Code haben wir nicht gelesen. Checks, die nicht zutreffen, werden nicht mitgezählt. · Geprüft am 8. Nov. 2026
- ✓ Bestanden
Entwickler passt zum Repo
Der Registry-Name wurde mit dem GitHub-Konto mughalhere bestätigt, dem das Repo gehört
- … Noch nicht geprüft
Wird noch gepflegt
Dieses Repo haben wir noch nicht von GitHub gelesen
- … Noch nicht geprüft
Hat eine Lizenz
Dieses Repo haben wir noch nicht von GitHub gelesen
- – Nicht zutreffend
Endpunkt antwortet
Dieser Server läuft auf deinem Computer; es gibt keinen Endpunkt im Internet
- – Nicht zutreffend
Anmeldung mit OAuth
Läuft auf deinem Computer und nutzt stattdessen lokale Einstellungen
- … Noch nicht geprüft
Keine versteckten Anweisungen in Tool-Beschreibungen
Läuft auf deinem Computer; Tool-Listen können wir nur von Endpunkten im Internet lesen
Im Vergleich mit anderen in Suche & KI-Gedächtnisi
- Mehr Sterne als 0 % der anderen 5718 Server in dieser Kategorie
- Neuer in der Registry veröffentlicht als 92 % der anderen 5718 Server in dieser Kategorie
- Basischecks gleich gut wie oder besser als bei 100 % der anderen 5718 Server in dieser Kategorie
Verglichen mit allen aktiven Servern dieser Kategorie in der Registry. Sterne zählen nur, wenn dem Herausgeber das Repo gehört.
Häufige Fragen
Ist prompt-protection sicher?
Er hat 1 von 1 zutreffenden Basischecks bestanden. Den Code haben wir nicht gelesen. Bevor du einen Schlüssel oder Token hinzufügst, sieh nach, welche Zugriffe der Server verlangt, und nutze einen Schlüssel, der nur die Berechtigungen hat, die du brauchst.
Welche Schlüssel oder Codes braucht er?
Die Registry nennt keinen erforderlichen Schlüssel, manche Server bitten dich aber bei der ersten Nutzung, dich anzumelden.
Läuft er auf meinem Computer oder in der Cloud?
Er läuft auf deinem Computer. Deine KI-App startet ihn bei Bedarf, und die Daten laufen nicht über die Server des Entwicklers (außer der Server ruft selbst einen Onlinedienst auf).
Wird er noch gepflegt?
Das GitHub-Repo wurde zuletzt – geändert, und die neueste Version (4.4.0) kam vor 3 Tagen in die Registry.
Welche Apps können ihn nutzen?
Apps, die MCP unterstützen, etwa Claude Desktop, Claude Code, Cursor und VS Code. Außerdem brauchst du Node.js auf deinem Computer.
Was kann ich stattdessen nutzen?
In derselben Kategorie: Context7, Codebase Memory, Exa
Alternativen
Server derselben Kategorie von anderen Entwicklern, sortiert nach Sternen.
So liest du eine Karte:↓ Downloads pro Wochei★ GitHub-SterneiDrei Säulen: Bewertungen · Checks · NutzungiAktualisiert = neueste Version in der Registry veröffentlichti
Codebase Memory
Codebase knowledge graph for AI agents — 162 languages, sub-ms queries, 99% fewer tokens.
Exa
Connect AI agents to Exa for web search, content fetching, and multi-step research.
README vom Entwickler
README öffnen
Unverändert aus dem Repo des Entwicklers übernommen. PopNx MCP hat den Inhalt weder geprüft noch empfiehlt es ihn. HTML, Bilder und Skripte wurden entfernt. Links führen von dieser Website weg.
prompt-protection
A provenance-tracked tool-call guard for JavaScript agents. Tool results are tainted, destinations the user named are trusted, and every tool call the model proposes is checked before it runs: untrusted data does not reach a network, email, exec, file or payment sink. Fail-closed, in-process, zero runtime dependencies. Text detection, spotlighting and canaries ship as components, with their benchmark numbers published whether they flatter the library or not.
Listed in the Agent Threat Rules ADOPTERS registry (Tier 2, adapter), the official MCP registry as io.github.mughalhere/prompt-protection, MCPrush, and the XERJ Corpus Hub.
[Live Demo →](https://mughalhere.github.io/prompt-protection/)
What it is, and what it isn't
Prompt injection stopped being a text-classification problem the moment models started calling tools. The damage in an agent is a consequence, not a sentence: a URL lifted from an email ends up in an outbound request, an attendee address from a calendar entry becomes the recipient of send_email, a payload in a README lands in exec. Version 3 tracks where data came from and refuses to let untrusted data reach a dangerous sink. That is the capability model from Google DeepMind's CaMeL paper (arXiv 2503.18813), ported to a JavaScript tool-calling loop without the custom interpreter.
It is a policy layer inside your process. It is not an isolation boundary. It cannot see a flow that passes through the model's hidden state, a paraphrase that shares no identifiers with its source, or a source you never registered. The Limitations section lists what it misses, with the dataset rows that show it.
60-second agent quickstart
import { generateText } from 'ai';
import { createGuard } from 'prompt-protection/guard';
const guard = createGuard({ sinks: { http_post: 'network', send_email: 'email', run_shell: 'exec' }, // or rely on name heuristics });
guard.analyzeUserTurn(userMessage); // destinations the user names become trusted
const result = await generateText({ model, tools: guard.wrapTools(tools), // check → execute → taint result toolApproval: guard.vercelToolApproval(), // block → denied, confirm → user-approval prompt: userMessage, });
Or drive it by hand:
guard.taint('read_email', emailBody); // label a tool result as untrusted
const decision = guard.checkToolCall({ toolName: 'http_post', args: { url } }); // { action: 'block', policy: 'untrusted-to-exfil-sink', reasons: ['untrusted-to-exfil-sink'], flows: [{ kind: 'identifier', path: 'args.url', … }] }
Taint survives three places it used to leak (4.1):
// Memory: persist the entry next to the value, read it back next session with its lineage.
const { store, entry } = guard.taintMemoryWrite('summarise', summary, { key: 'notes/today' }); if (store) await db.put(entry.key, { value: summary, entry }); // … later, in a new guard: guard.memoryRead([savedEntry]); // a blocked lineage into an exfil/exec sink → 'lineage-untrusted'
// Sub-agents: the child guard inherits sources, labels and trusted identifiers; depth increments. const child = guard.fork(); // or createGuard({ inherit: guard.handoff() }) across a boundary
// Approvals: what the human saw is what runs. const card = await guard.approvalCard(call); // rendered fields, tainted marks, card.digest guard.confirm(card.id, card.digest, 'alice'); // UI echoes the digest back guard.checkToolCall(call); // identical args → allow ('approved'); changed args → block ('approval-mismatch')
Every decision carries reasons: DecisionReason[] (stable codes, docs/CONFORMANCE.md) and depth.
Static structure (4.2): pin what the agent may call, and bound how often.
const lock = await guard.pin(tools); // digests name, description, schema, annotations; persist it
// … next process: guard.lock(savedLock); await guard.verify(tools) guard.wrapTools(tools); // a redefined description now blocks with 'tool-drift' guard.checkToolCall({ toolName: 'new_tool', args }); // unlisted under a lock → 'tool-unpinned'
createGuard({ budgets: { maxCallsPerTurn: 20, maxRepeatIdentical: 3, maxDepth: 2 } }); // the 4th identical call, or the 21st this turn → 'budget-exceeded'
import { createBoundary } from 'prompt-protection/spotlight'; const boundary = createBoundary({ mode: 'datamark' }); createGuard({ spotlight: boundary }); // one marker, one system-prompt sentence: boundary.instruction
Under a lock, readOnlyHint: true makes a tool a non-sink and an unannotated tool the name heuristics cannot place resolves to unknown (treated as exfil and exec) unless you set annotationsDefault: 'heuristic' or name its sink in sinks.
Operability (4.3): pick a preset, observe before you enforce, and read the reason chain.
createGuard({ preset: 'strict' }); // 'balanced' (default) · 'strict' · 'permissive'; explicit options win
createGuard({ mode: 'observe' }); // action is always 'allow'; decision.observedAction is the verdict import { explain } from 'prompt-protection/guard'; explain(decision); // { summary, chain: [{ code, policy, because, flows }] }
One call per framework:
import { protect } from 'prompt-protection/adapters/vercel-guardrail'; // ai ≥ 6
const { tools, toolApproval, prepareStep, onToolExecutionEnd, stopWhen } = protect(guard, myTools); new WorkflowAgent({ tools, toolApproval, prepareStep, onToolExecutionEnd, stopWhen }); // WorkflowAgent has no default step limit
import { protect } from 'prompt-protection/adapters/openai-agents'; // @openai/agents ≥ 0.18 const { inputGuardrails, wrapTool } = protect(guard); new Agent({ inputGuardrails, tools: [wrapTool(sendEmail)] }); // tool guardrails + needsApproval bound per tool
import { protect, interruptWhen } from 'prompt-protection/adapters/langchain'; // langchain ≥ 1 createAgent({ middleware: [await protect(guard), humanInTheLoopMiddleware({ interruptOn: { stripe_transfer: { allowedDecisions: ['approve', 'reject'], when: interruptWhen(guard) } } })] });
Output side: analyzeOutput(text, { renderAllowlist: ['ourcompany.com', '*.cdn.ourcompany.com'], conversation }) blocks markdown/HTML that would render or link an unlisted host, a data: URI, or a query parameter carrying high-entropy or conversation-derived data (off unless the allowlist is set). redact(text) and analyzeOutput(text, { redact: 'all' }) replace secrets and PII (gitleaks / Presidio shapes, checksums validated in code).
Trust across boundaries (4.4, preview): a label is only worth what signs it.
import { seal, generateKey } from 'prompt-protection/envelope';
const key = await generateKey('HS256', 'k1'); // or 'EdDSA' (Ed25519, Node ≥ 20.19.3) const env = await seal(toolResult, key, { label: 'tool', ttlMs: 60_000, from: 'fetcher' }); // … in the receiving process: const { opened, error } = await guard.taintEnvelope(env, key); // forged / expired / replayed → a blocked source const child = await guard.sealHandoff(key); // sealed TaintHandoff for a sub-agent elsewhere await other.absorbSealed(child, key); // bad seal → 'handoff-untrusted' on any flow const entry = await guard.sealMemoryEntry(write.entry); // memoryReadSealed() reads unsigned entries as blocked
Architecture
tool result ──taint──▶ provenance label ──▶ shingles + identifiers (URL, host, email, path, token)
│ model proposes tool call ──▶ sink class ──▶ flow detection (exact / identifier / content) ──▶ policies ──▶ allow · flag · confirm · block ▲ ▲ explicit map or name heuristics plan() allow-list · user-trusted destinations
The default policies run in this order. plan-violation blocks any tool outside the plan() allow-list. injection-source-flow blocks when a source that itself scored as injection flows anywhere. untrusted-to-exfil-sink blocks untrusted data reaching network, email or messaging tools, and untrusted-to-exec does the same for exec and file writes. untrusted-to-payment asks for confirmation. injection-then-sink flags a sink call made in the same turn as an injection-scored source even when no flow was detected, because paraphrase is exactly the case the flow detectors miss. args-injection flags when the arguments themselves read as injection. Each of these is one of the patterns in *Design Patterns for Securing LLM Agents* (arXiv 2506.08837): Action-Selector via plan(), Plan-Then-Execute, Context-Minimisation via spotlighting.
Spotlighting (prompt-protection/spotlight, arXiv 2403.14720) marks untrusted spans by delimiting, datamarking or base64-encoding them, and gives you the system-prompt sentence that tells the model what the marker means. With wrapTools({ spotlight: 'datamark' }) the model sees marked text while the guard taints the original, and arguments are unmarked before flow detection so a copied span still matches.
Canaries (prompt-protection/canary) put a token in the system prompt and look for it in the output in exact, normalized, spaced, base64, hex, reversed and partial forms. There is also a shingle-similarity check between the output and the system prompt. Plain verbatim canaries were shown to fail against paraphrase (arXiv 2506.19109). Similarity closes part of that gap. Not all of it.
Text detection is a component, not the product: 106 input rules, 21 output rules and 9 tool-poisoning rules score text that has to be scored, and the Benchmark section says how well. An embedded 33 KB int8 n-gram classifier lives on prompt-protection/ml (preview tier, off by default, for reasons the benchmark explains). prompt-protection/lite is the rules-only entry at 20 KB gzipped.
Benchmark
npm run bench runs the shipped build against every set below and writes bench/results.json. The same run is a CI gate. Recall and false-positive rate are shown as regex / ml / hybrid; the shipped default is regex.
| Set | Licence | N (attack/benign) | Recall | False-positive rate |
|---|---|---|---|---|
| NotInject, over-defence benchmark (arXiv 2410.22770) | MIT | 339 (0/339) | n/a | 2.9% / 7.7% / 10.6% |
| datasets/benign-hard + datasets/attacks, ours, written to evade proximity matching | CC-BY-4.0 | 285 (130/155) | 14.6% / 19.2% / 30.8
Nur der Anfang wird gezeigt; den Rest findest du im Repo