safe-autonomy

safe-autonomy

Provides MCP tools for AI agents to classify changes into autonomous or human review lanes, and to run shadow simulations over backlogs without shipping anything.

Category
Visit Server

README

safe-autonomy

A fence and a shadow for autonomous coding agents. Decide what an AI is allowed to ship without a human, watch it reason before you trust it, and keep the dangerous stuff in your hands.

The hard problem in AI operations isn't making the agent smarter. It's being disciplined about what it is never allowed to touch. safe-autonomy is that discipline as ~150 lines of pure, dependency-free, unit-tested code you can drop into any agent pipeline.

The idea

Autonomy is only safe where "the AI was wrong" cannot hurt anyone. Additive observability is worst-case noise. A revert goes to a known-good state. The changes that matter most — money, product, user-facing truth, the database — are exactly the ones that stay human. Not from fear, from fallibility: agents make real mistakes, and the value of a human in the loop is catching them.

So this library does two small things:

  1. The fence (classifyChange) — one pure function that routes a proposed change to auto or human. Default is human. auto only when the change touches no sensitive path, is reversible, and is an additive/reversible kind (a monitor, a test, a revert). One sensitive file drags the whole change to human.
  2. Shadow mode (shadowClassify) — run the fence over your real backlog and log exactly how each change would be routed, shipping nothing. You read the shadow log for as long as you want before enabling any autonomy.

Use it

import { classifyChange } from "safe-autonomy/gate";

classifyChange({ files: ["src/lib/metrics.ts"], kind: "add_monitor", reversible: true });
// → { lane: "auto",  reasons: ["additive/reversible \"add_monitor\", no sensitive paths"] }

classifyChange({ files: ["src/api/stripe/webhook.ts"], kind: "add_monitor", reversible: true });
// → { lane: "human", reasons: ["touches human-only path(s): src/api/stripe/webhook.ts"] }

Bring your own denylist and allowlist; the defaults cover money, auth, schema, sending, deletion, webhooks, and secrets:

import { classifyChange, DEFAULT_CONFIG } from "safe-autonomy/gate";

const config = {
  ...DEFAULT_CONFIG,
  humanOnlyPaths: [...DEFAULT_CONFIG.humanOnlyPaths, /\/pricing\//],
};
classifyChange(change, config);

Shadow a whole backlog before you enable anything:

import { shadowClassify, formatShadowLog } from "safe-autonomy/shadow";

const report = shadowClassify(proposals, deriveChange); // deriveChange: your proposal → a ChangeDescriptor
console.log(formatShadowLog(report, (p) => p.title));
// Autonomous shadow — 3 proposal(s): 1 would auto-ship (SHADOW ONLY, nothing shipped), 2 stay human.
//   [AUTO ] watch publish_verify_missing_field — AUTO once enabled → branch, full CI, verify, auto-rollback...
//   [HUMAN] Scanner → connect gate — HUMAN review → no files listed — cannot verify blast radius...

The rollout it's built for

proposal → classifyChange → [human] land as a PR for review
                          → [auto]  implement on a branch
                                    → FULL CI (tsc + lint + tests + build); red = stop
                                    → SHADOW: log the diff + intended action, ship nothing
                                    → (only when enabled) auto-merge + deploy
                                    → verify on REAL metrics + error rate for a watch window
                                    → auto-rollback on regression
                                    → immutable audit log of every step

Ship the fence first (inert). Run it in shadow for as long as you like. Enable it narrowly — one surface, add_monitor / add_test only — with a kill switch, a veto window, and auto-rollback. Widen it an inch at a time, and never widen the allowlist or shrink the denylist without an explicit human decision.

Use it from any agent (MCP)

The same fence is an MCP server, so an agent can ask it before it acts. Two tools: classify_change (route one change) and shadow_run (route a whole backlog, ship nothing).

npm run mcp          # stdio server: npx tsx mcp/server.ts

Point an MCP client at it:

{
  "mcpServers": {
    "safe-autonomy": { "command": "npx", "args": ["tsx", "/path/to/safe-autonomy/mcp/server.ts"] }
  }
}

Then the agent calls, in its own words, "classify this change" and gets back a lane:

// classify_change { "files": ["src/api/stripe/charge.ts"], "kind": "add_monitor", "reversible": true }
// → HUMAN — touches human-only path(s): src/api/stripe/charge.ts

Bring your own denylist/allowlist over the wire (regex source strings, so JSON-safe):

// classify_change { ..., "config": { "humanOnlyPaths": ["/pricing/"], "autoKinds": ["add_test"] } }

Why it's tight (the honest reason)

Verify on real metrics, not just green tests — subtly-wrong changes pass tests. This whole library exists because the AI is fallible, and the point of a boundary is that "the AI was wrong" stays cheap.


Extracted from the autonomous-maintenance system running a production SaaS. Tests: npx vitest run.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured