MCP server with an indirect prompt injection guard. Tracks provenance of external content and blocks side-effectful actions whose arguments trace back to untrusted sources.
Server demonstrates solid domain-specific design with clear security-focused tool naming and descriptions. All 7 tools have descriptions (10 - 200 chars, within baseline range). Input schemas are present and typed for all tools. However, parameter descriptions are minimal or absent in several tools (fetch, shell, send_email, write_file lack detailed format/constraint guidance), and output schemas are not formally documented. Error handling is present but generic. The server's educational/demonstration nature (stubs that don't execute) is well-communicated, but production-grade validation and recovery guidance are limited.
Fetch external content. The content is UNTRUSTED and is tainted on arrival. Use `demo://poisoned` or `demo://clean` to try it with no network.
Show the current taint state — how many tokens are tracked, from where.
Clear the taint store and audit log. Use between unrelated tasks.
Show what the guard did this session: what it tainted, what it blocked, why.
Send an email. Blocked if any argument traces back to untrusted content. NOTE: this is a demonstration stub — it records the attempt and never sends. Replace `_deliver()` with a real transport to use it for real.
Run a shell command. Blocked if it traces back to untrusted content. NOTE: demonstration stub — records the attempt and NEVER executes. Wiring a real shell behind an injectable channel is exactly the thing this repo is about; if you do it, sandbox it.
Output schemas not formally documented. Tools return strings (security_log, guard_status, reset_session) or success messages (send_email, write_file, shell) but no structured schema is declared. LLMs cannot plan downstream composition or extract typed fields.
Parameter descriptions lack format/constraint guidance. 'target' in fetch says 'an http(s) URL, or demo://<name>' but does not specify URL length limits, timeout behavior, or valid demo names. 'cmd' in shell lacks examples of valid commands or restrictions.
Error responses are generic strings ('ERROR: {e}', 'BLOCKED BY INJECTION GUARD') without actionable recovery guidance. Per pattern:recovery-guide, errors should tell the LLM what to do next. E.g., 'fetch failed: invalid URL. Ensure target is http(s) or demo://<name>. Available demos: poisoned, clean.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 56 | 2026-07-28+ | v2 |
Write a file. Blocked if any argument traces back to untrusted content. NOTE: demonstration stub — records the attempt, writes nothing.
No dry-run or confirmation step for destructive operations (send_email, write_file, shell). Per pattern:confirmation-request, irreversible operations should support confirmation. Even though these are stubs, the pattern should be modeled for production use.
Tool composition assumes single-session state (module-level GUARD, AUDIT). Per pattern:tool-chain, tools should be stateless or keyed by session. Real deployment would need per-session isolation (e.g., via MCP session ID in request metadata).