red-castle
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@red-castle please quarantine old-report.pdf for human review"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AI agents may ask to delete things. Only a human decides.
Red Castle is a guarded deletion pipeline for AI agents. An agent never deletes anything itself: it asks the castle, the object is hidden in quarantine, and a human approves or restores it from the terminal. The castle runs silently in the background and only speaks up, with a desktop notification, when a human is needed.
AI Agent
│ "I want to delete X" (cannot delete it themselves)
▼
[The Gateway] receives deletion requests via API or MCP tools
▼
[The Judge] calculates its own risk score and compares it with the agent's
▼
[The Quarantine] the object is hidden but still exists
▼
[The Throne Room] a human approves, restores, or freezes the agent (in the terminal)
▼
[The Executioner] the only role in the world authorized to permanently delete
▼
[The Chronicle] tamper-evident log of every decision
Around the wall:
[The Moat] guardrails
[The Watchtower] monitoring and desktop notifications
[The Traps] canariesPure Python standard library. No dependencies, except boto3 if you use the S3 backend.
Quick start
git clone https://github.com/babayaga370/red-castle.gitcd red-castlepip install .Or skip the install and use python -m redcastle in place of redcastle below.
redcastle demoThe demo walks through the whole flow in a throw-away castle: quarantine, approval, restore, a sprung trap, a frozen agent and the Chronicle. Nothing on your machine is touched.
To set up a real castle, go to the folder that should hold it and run:
redcastle initinit greets you with the castle and a short guide. It creates redcastle.toml (the
configuration), realm/ (the folder agents can see and ask to delete from) and
.redcastle/ (database, keys, quarantine and log; keep it private).
redcastle agent add clauderedcastle startredcastle notify testThat's it: the castle runs silently in the background, and agents reach it at
http://127.0.0.1:8750/api/v1. When something needs you, a notification pops up, and you
answer it with:
redcastle throne reviewRunning redcastle without a command shows the welcome screen and the most useful commands.
Every command accepts --root <folder> (or REDCASTLE_HOME) when the castle lives elsewhere.
Related MCP server: Shotstack MCP Server
Running silently
Command | |
| Start the castle detached from the terminal, with no window ( |
| Is it running? How many cases await you? Any alerts in the last day? Is the Chronicle intact? |
| Ask the castle to close its gates; forced after 15 seconds if it does not answer. |
| Run in the foreground of this terminal (Ctrl+C to stop). |
The castle does not start at login by itself. To make it, schedule
pythonw -m redcastle --root <folder> serve --quiet with Windows Task Scheduler (or launchd / systemd).
Notifications
The Watchtower stays quiet unless a human is needed:
An object is waiting in quarantine. The notification names the agent and the object, shows the Judge's and the agent's risk scores, and says if the agent underestimated the risk.
Alerts (urgent): an agent reached for a canary, an agent was frozen, a canary vanished behind the castle's back, the Chronicle or the quarantine was tampered with, or the Executioner refused to act.
Reminders when cases have waited longer than
remind_interval_minutes.
Everything that happens within batch_seconds is gathered into one notification, so a busy
agent cannot flood your screen. Rejected requests (bad keys, missing objects …) stay quiet.
Windows uses native toast notifications through Windows PowerShell (they show
"Windows PowerShell" as the sender), macOS uses osascript and Linux notify-send. Without
any of these, notifications go to the log; REDCASTLE_NOTIFY=off forces that, for CI for
example.
[notify]
enabled = true
on_quarantine = true # notify when an object awaits your judgement
min_severity = "warning" # "warning" or "critical"
batch_seconds = 3
remind_interval_minutes = 60 # 0 = neverNothing shows up? Check the system's notification settings and Focus Assist / Do Not Disturb.
The Throne Room, in your terminal
redcastle throne reviewThe review goes through the quarantine one case at a time. For each case it shows the object, the agent, its reason, both risk scores and the Judge's reasoning:
[1/2] Case rc-6c9b6e01fd01 [quarantined] 4m ago
object: config/prod.env (31 bytes)
agent: claude
reason: Looks unused
risk: agent 5, Judge 70 (high) <-- agent UNDERESTIMATED the risk
+10 permanent deletion is never risk-free
+35 path matches sensitive pattern '*.env'
+20 path matches sensitive pattern '*prod*'
+5 terse justification
[a]pprove (delete forever) [r]estore [s]kip [f]reeze claude [q]uit >Approving asks you to type yes. Every decision is recorded under your name (your
username, or --by).
Command | |
| Cases waiting in quarantine ( |
| One case, the Judge's reasoning and its Chronicle entries |
| Approve; the Executioner deletes the object permanently |
| Decline and put the object back |
| Freeze an agent (and optionally restore all it asked for) |
| Let it submit requests again |
| Watch every decision as it happens |
| Verify the hash chain |
| Recent alerts / check canaries, quarantine and Chronicle now |
| Plant a canary |
| Carry out approved cases that are still pending |
The Throne Room exists only in the terminal. There is no web interface and no admin API, so nobody can approve a deletion over the network.
For agents: HTTP API
Every call needs Authorization: Bearer <agent token>.
Method | Path | |
GET |
| Visible objects (quarantined ones are hidden) |
POST |
|
|
GET |
| Your own requests ( |
GET |
| Status of one of your requests |
curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"object_key":"logs/app-2025.log","reason":"Last year log, already archived","risk_score":10}' http://127.0.0.1:8750/api/v1/deletion-requestsFor agents: MCP
redcastle mcp is an MCP server over stdio with the tools list_objects,
request_deletion, get_deletion_request and list_my_deletion_requests. No tool can
delete, approve or restore anything.
Point it at the running castle with --gateway. The agent's process then holds nothing but
its own token and cannot reach the database or the keys. For Claude Code, in .mcp.json:
{
"mcpServers": {
"red-castle": {
"command": "redcastle",
"args": ["mcp", "--gateway", "http://127.0.0.1:8750"],
"env": { "REDCASTLE_AGENT_TOKEN": "rc_agent_..." }
}
}
}Without --gateway the castle is opened in-process (needs --root and access to .redcastle/).
How it works
Life of a request
received ──► rejected (Moat: frozen agent, invalid key, protected object, rate limit …)
──► trapped (a canary: the agent is frozen and only ever sees "rejected")
──► failed (storage error; nothing was deleted)
──► quarantined ──► approved ──► executed
└─► restoredThe roles in the code
Role | File | What it does |
Gateway | Authenticates the agent and walks the request through the castle. Has no delete function. | |
Judge | Its own 0–100 risk score with explained factors; flags agents that under- or overestimate. | |
Quarantine | Moves the object out of sight and records its checksum. | |
Throne Room | Approve (seals the decision with an HMAC), restore, freeze or unfreeze agents. | |
Executioner | Holds the only storage handle with | |
Chronicle | Hash-chained, HMAC-signed log; SQLite triggers refuse UPDATE and DELETE. | |
Moat | Frozen agents, key validation, protected patterns, required reason and score, rate limits. | |
Watchtower | Alerts, automatic freezes, patrols, reminders, desktop notifications, webhook. | |
Traps | Canaries. Asking to delete one freezes the agent on the spot. |
Storage backends: local folder and S3. Background mode: daemon.py.
The Judge
The Judge starts at 10 points and adds or subtracts for:
sensitive paths (
*.env,*secret*,*backup*,*.db,*prod*…) and low-value ones (*.tmp,*.log,__pycache__…)size (≥ 1 / 10 / 100 MB), and whether the object changed in the last hour or day
the agent's behaviour: bursts of requests, earlier underestimates
a terse reason
If the Judge's score is at least discrepancy_threshold (25) above the agent's own, the
request is flagged as underestimated. The notification says so, and three of those
within an hour freeze the agent. Patterns and weights live in redcastle.toml.
Around the wall
Moat: see
[moat]inredcastle.toml. The castle's own files (.redcastle/,redcastle.toml) are never reachable, even if the realm is the castle's own folder.Watchtower: freezes an agent on a sprung trap, after 5 Moat rejections within 10 minutes, or after 3 underestimates within an hour. The running castle patrols every minute: the Chronicle must verify, every canary must be in place and unchanged, and every quarantined object must match its checksum. Each new problem raises an urgent notification. An optional
webhook_urlreceives alerts as JSON.Traps:
redcastle traps plant "backups/db-dump-prod.sql"writes a decoy with fake credentials, or turns an existing object into a canary.
S3
[storage]
backend = "s3"
bucket = "my-bucket"
prefix = "data/" # what agents can see
quarantine_prefix = ".redcastle-quarantine/"
profile = "redcastle" # the castle's AWS profile
executioner_profile = "redcastle-executioner"Quarantine copies the object to quarantine_prefix and removes the original. With
bucket versioning enabled, that removal is only a delete marker, so nothing is lost.
Suggested IAM roles:
Agent: no S3 permissions at all, or read-only with an explicit
Denyons3:DeleteObject*.Castle (
profile):s3:ListBucket,s3:GetObject,s3:PutObject,s3:DeleteObject, and an explicitDenyons3:DeleteObjectVersion.Executioner (
executioner_profile):s3:DeleteObject,s3:DeleteObjectVersion,s3:ListBucketVersions,s3:GetObject.
The only irreversible call in the whole system is then made with the Executioner's keys.
Security model and limits
The Chronicle is tamper-evident, not tamper-proof. Someone holding both the database and
secrets.jsoncan rewrite history. Publish the head fromredcastle chronicle verify(sequence number and hash) somewhere else now and then to detect truncation too.Run the castle as a different OS user than the agent. An agent with file access to
.redcastle/could runthrone approveitself. With the local backend, an agent with a shell can also delete files inrealm/directly; the Traps and the patrols detect and report that, but cannot prevent it. Real isolation needs separate users or containers, or S3 with IAM.Agent tokens are stored only as SHA-256 hashes. Text written by agents (such as object keys) is XML-escaped before it reaches a notification.
The HTTP server listens on
127.0.0.1by default and has no TLS. Put a TLS-terminating reverse proxy in front of it before exposing it to a network.
Development
python -m unittest discover -s tests -t .CI runs the tests on Windows and Linux with Python 3.11–3.14. macOS is supported
(notifications use osascript) but not tested in CI.
License
Available Tools
4 toolsget_deletion_requestGet deletion requestARead-only
Show the current status of one of your deletion requests.
Inputs: request_id (required).
list_my_deletion_requestsList my deletion requestsCRead-only
List your deletion requests, newest first.
Inputs: status.
list_objectsList objectsBRead-only
List the objects you can see. Objects waiting in quarantine are hidden.
Inputs: prefix.
request_deletionRequest deletionA
Ask Red Castle to delete one object. Nothing is deleted right away: the object is hidden in quarantine until a human approves (permanent deletion) or restores it. Use get_deletion_request to follow up.
Inputs: reason (required), object_key (required), risk_score (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: requesting deletion, listing visible objects, checking one request, and listing all of the user's requests. The single-request vs list-request distinction is explicitly clarified by the descriptions.
All tool names use snake_case with a predictable verb-object pattern: request_deletion, list_objects, get_deletion_request, list_my_deletion_requests. The slight inclusion of 'my' is readable and consistent with the possessive scope.
Four tools is well-scoped for a deletion-request workflow. Each tool earns its place by covering requesting, browsing targets, checking status, and listing requests.
The core deletion-request lifecycle is covered: create a request, inspect status, list requests, and view visible objects. A cancellation or withdrawal operation for pending requests is a minor gap, but human approval/restore is intentionally outside the agent surface.
Related MCP Connectors
Amazon Ads, Seller Central, Vendor Central and AMC data for AI agents. Read-only by default.
The system of record for AI agent authority: playbooks, routed policy questions, reusable rules.
Read-only finance and operations controls for AI agents with evidence and safe next actions.
Deterministic allow/require_approval/deny verdicts for agent actions, before they happen.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables MCP-capable AI clients to read a local AI ticket triage queue and human decision log through four read-only tools for checking queue status, listing pending review items, viewing recent decisions, and searching decisions. It does not allow approving, rejecting, or sending anything.4MIT
- AlicenseAqualityBmaintenanceEnables AI agents to inspect and manage video renders, templates, generation models, hosted assets, and ingest sources while using isolated private account profiles. It requires explicit approval for mutation operations and supports both MCP and CLI access.2332 npmAGPL 3.0
- AlicenseNot gradedqualityBmaintenanceEmpowers AI agents to keep lists of records—adding, showing, noting on, attaching to, and moving items through states—while the binder itself stays outside the agent's reach. Human approval gates, per-list read/change access, and archive-only deletion keep agents from approving, seeing ungranted lists, or deleting anything.6,730 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to manage App Store Connect releases—versions, builds, TestFlight groups, metadata, pricing, reviews, and submission—while staying read-only by default and requiring human approval before any public or destructive action.2MIT