Skip to content

Agent channels

An LLM agent reads emails, calls tools, is shown MCP tool schemas and writes to memory. Those are the channels through which indirect prompt injection, MCP tool poisoning and memory poisoning arrive. The user’s prompt is often perfectly benign.

monsys does not inspect those channels inline and blocks nothing (see the three invariants). It records what the agent was given to read, hashed and redacted, and turns it into two deterministic signals: injection indicators and schema drift. A human judges.

Four typed events on a span of the existing SDK envelope; the exact fields are in the envelope spec.

Event When
tool_call the agent calls a tool (name + arguments)
tool_result a tool returns something the model will read
mcp_schema an MCP server presents a tool description and input schema
memory_write the agent writes to long-term memory

The SDKs have helpers (span.tool_result(...), span.mcpSchema(...), s.MemoryWrite(...)). The hub applies the same redaction as to prompts: PII becomes labelled hash tokens, and the database holds only the sha256 plus metadata.

Everything the model gets to read (tool results, schemas, memory) runs through eleven named regexes. No model, no score: a hit is a label on the event.

Indicator What it looks for
ignore_previous “ignore/disregard previous instructions”
role_override “you are now …”, “new instructions:”
system_prompt_exfil “reveal/print the system prompt”
tool_invocation “call/invoke/run the … tool/function/api”
secrecy “do not tell the user”
hidden_html HTML comment carrying instructions
zero_width invisible Unicode characters
markdown_exfil image link with a query string to an external domain
shell_pipe curl … | sh
prompt_delimiters [INST], <<SYS>>, ### system
base64_blob long base64 run

A hit raises an ai_injection alert in the action inbox (critical for tool_invocation, shell_pipe, markdown_exfil or three or more indicators at once; warning otherwise). The alert names the tool or source and points to the trace. You decide whether the source is trustworthy; monsys changes nothing about the agent.

Tool poisoning is by definition a change to the tool description. monsys keeps a canonical sha256 of description + input schema per (app, server, tool). When it changes:

  1. a row lands in the change log with old and new hash;
  2. an ai_mcp_drift alert appears in the inbox (and as push);
  3. the change counts as configuration drift in the Trust Score (5 points per open change, capped at 30, tenant-wide) until you confirm it.

Confirm in the portal (AI → Agent channels → Confirm as intended) or via POST /api/v1/ai/mcp-schemas/ack. An intended tool update is one click; an unexpected one stays visible.

  • AI → Agent channels: counters per kind (30 days), the schema registry with drift state, events with indicator chips.
  • Action inbox and app: the ai_injection and ai_mcp_drift alerts.
  • Evidence pack: agent_events.jsonl (every event with hash and indicators) and mcp_schemas.json (registry + changes in the period), both with their sha256 in the Ed25519-signed manifest.
  • API: GET /api/v1/ai/agent-channels/summary, GET /api/v1/ai/agent-events?indicators=1, GET /api/v1/ai/mcp-schemas.

The Claude Connector is itself an agent channel. tools/list therefore returns a _meta: the sha256 of the canonical tool catalogue, an Ed25519 signature with the hub key and the entry in the transparency log (kind = mcp.tool_catalog). Whoever keeps the hash can later prove which tool descriptions Claude was shown; a changed catalogue is a new, public log entry.

No firewall, no LLM-as-judge, no blocking in the request path and no training-data scanning. If you want enforcement, wire your own gate to our webhook; monsys delivers the evidence an auditor can verify under AI Act art. 15 and NIS2 art. 21.