ASK KNOX
beta
LESSON 403

Read vs Write Safety — The Permission Model, Destructive-Tool Gating, Idempotency

A destructive tool that fires automatically is a liability, not a feature. Three safety tiers, explicit confirmation gates, and two idempotency patterns that make write tools safe to retry.

9 min read·Building Production MCP Servers

Why Safety Tiers Matter for Agent Loops

When a human uses a REST API, they read the documentation, think about consequences, and click deliberately. When an agent model uses an MCP tool, it may call the tool multiple times in a loop, retry on network failure, and make decisions about tool invocation based on context that may be incomplete or incorrect.

This means MCP tool safety requirements are higher than REST API safety requirements. A REST endpoint that is slightly dangerous is manageable — humans apply judgment. An MCP tool that is slightly dangerous is a liability — agents apply instructions, and instructions can be wrong.

The three-tier safety model is the solution. You classify every tool on your server as read-safe, elevated (writes with limited blast radius), or destructive (irreversible or high blast radius). Destructive tools get explicit confirmation gates. Elevated tools get scope restrictions. Read-safe tools run freely.

The Three-Tier Safety Model

The safety tier classification is not about the caller's identity — it is about the tool's effect on system state. memory_query is always read-safe regardless of who calls it. memory_forget is always destructive regardless of who calls it.

This matters because the scoped access model (from the previous lesson) restricts who can call write tools. But even callers with write access should face confirmation gates on destructive tools. The two protections work together: scope restricts access, gates restrict automation.

For Semantic Memory Layer in production:

  • Claude Code sessions (read-only scope): can only call read-safe tools, not elevated or destructive
  • Agent Gateway (full scope): can call elevated tools freely; destructive tools (memory_forget) require confirmed=true parameter
  • Manual admin calls: all tools available; destructive tools log to a separate audit trail

Idempotency: The Write Safety Foundation

Two idempotency patterns cover almost every write tool:

Content-hash keys for memory_remember: hash the content and namespace into a deterministic ID. The same content in the same namespace always produces the same ID. On retry, the tool finds the existing record and returns without writing — same response shape, zero state change. Callers cannot tell the difference between a first write and a retry.

Soft delete for memory_forget: instead of physically removing the record, mark it as deleted: true in the metadata. The record stays in ChromaDB but is filtered from all search results. A scheduled reindex physically purges deleted records. This makes deletions recoverable for up to the next reindex cycle — typically 24 hours in Knox's setup.

Together, these two patterns make the write surface safe for agent loops. An agent that retries memory_remember three times due to network instability writes exactly one memory. An agent that calls memory_forget with the wrong ID can have the deletion reversed by a human within 24 hours.

The Confirmation Gate Pattern

The confirmation gate for memory_forget is implemented as a two-step interaction:

  1. The agent calls memory_forget(memory_id) without a confirmed flag. The server returns { would_delete: { memory_id, content_preview, namespace } } — showing what would be deleted without deleting it.
  2. The agent reads the preview, verifies it matches the intended target, and calls memory_forget(memory_id, confirmed=true). The server executes the soft delete.

This pattern prevents the most common agent mistake: calling memory_forget with an ID retrieved from a search result that was semantically close but not the intended target. The preview step forces the agent to see the content before deletion — it cannot skip this without explicitly passing confirmed=true after verifying the preview.

Now build the gate yourself: a tool router where a read-only caller can never reach the destructive tool, and even a write-scoped caller must pass confirmed: true before the soft-delete fires.

Read-After-Write Verification

The single most reliable check for write tool correctness is read-after-write: after calling memory_remember, immediately call memory_recall(returned_id) and verify the content matches.

This catches:

  • Writes that return 200 but fail to embed (the DB write succeeded but ChromaDB embedding failed)
  • Writes that land on a different server instance in a split-brain scenario
  • Writes with incorrect namespace routing

In Knox's lessons.md, this pattern appears as: "read-after-write surfaces ownership boundaries — only read-after-write surfaces the boundary between what you think you wrote and what actually persisted." It is the most reliable correctness check for any write surface.

What's Next

The next lesson is the build lesson — constructing a real knowledge-OS MCP server with all 12 tools, namespaces, and the query/remember/recall pattern. The architecture is modeled directly on Semantic Memory Layer.