Agent Escalation Harness

Agent Escalation Harness

An MCP server that lets an AI coding agent pause on human-only tasks, request structured input via a form, and resume with the answer, all locally without cloud dependencies.

Category
Visit Server

README

Agent Escalation Harness

Pause on a wall, ask a human, resume. A local, self-contained harness that lets an AI coding agent stop when it hits something only a human can do, request the one thing as a typed form, get the answer back as structured data, and continue - no cloud accounts, no external services.

Three small pieces share one SQLite database: a FastAPI backend, an MCP server any agent can call, and a browser inbox where a human clears the wall. It runs entirely on your machine.

The wall problem

Coding agents stall on the handful of steps they cannot do alone: provisioning a Supabase project, minting a Stripe key, registering a domain. This harness turns that dead stop into a structured escalation: the agent files a typed request, a human fills a generated form, and the agent resumes with the values dropped straight into .env - all on your machine, no cloud accounts, no external services.

Architecture

                       one shared SQLite DB (requests table)
                                     |
        +----------------------------+----------------------------+
        |                            |                            |
  MCP server (stdio)          FastAPI backend               Inbox (browser)
  mcp_server.py               harness/app.py                served at /
  - request_human   --POST--> POST /requests                - polls /api/requests
  - check_request   <-poll--  GET  /requests/{id}            - schema-driven form
                              POST /requests/{id}/resolve <--- "Send to agent"
                              GET  /api/stats  (by category)
        ^                            ^
        |                            |
   real Claude Code            demo/demo_agent.py
   session                     (self-running demo, no Claude needed)
  • Backend + inbox - one FastAPI process. Owns the SQLite table and serves the inbox page.
  • MCP server - FastMCP over stdio. Exposes request_human and check_request to any agent.
  • Demo agent - drives the whole loop over plain HTTP so you can demo it live without wiring up Claude Code.

Quickstart

# 1. install
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# 2. start the backend + inbox (terminal 1)
./run.sh
# -> serving on http://127.0.0.1:8000

# 3. open the inbox
open http://127.0.0.1:8000

# 4. run the demo agent (terminal 2)
source .venv/bin/activate
python demo/demo_agent.py

The demo agent narrates building a todo app, hits three walls in sequence (provisioning, then an API key, then a domain), and blocks on each. Fill the form in the inbox, click Send to agent, and watch that terminal resume with the values it "received" and the .env lines it would write. Every wall is logged and counted at /api/stats.

Run the tests

pytest

Wire up a real Claude Code agent

Register the MCP server so a live Claude Code session can escalate through the same backend. Start the backend first (./run.sh), then add this to your Claude Code MCP config (~/.claude.json, or .mcp.json in a project):

{
  "mcpServers": {
    "escalation-harness": {
      "command": "/absolute/path/to/harness/.venv/bin/python",
      "args": ["/absolute/path/to/harness/mcp_server.py"],
      "env": {
        "HARNESS_URL": "http://127.0.0.1:8000"
      }
    }
  }
}

The agent now has two tools:

  • request_human(title, instructions, context, response_schema, category, timeout_seconds=300) - files a request and blocks (long-poll) until a human resolves it or the timeout hits. On resolve it returns the human's values; on timeout it returns {status: "pending", request_id} so the agent can keep working and check back.
  • check_request(request_id) - non-blocking status/response lookup for a pending request.

Optional: set NTFY_TOPIC in the backend's env to also get a phone push via ntfy.sh when a wall is raised. A failed push never breaks request creation.

Data model

A request is the core abstraction. The response_schema both generates the inbox form and validates what the human submits.

{
  "id": "req_a1b2",
  "title": "Create Supabase project",
  "context": "Building auth for the todo app. Needs Postgres + keys.",
  "instructions": "1. New project at supabase.com  2. Paste the values below",
  "response_schema": [
    {"name": "SUPABASE_URL",         "type": "string", "secret": false, "required": true},
    {"name": "SUPABASE_ANON_KEY",    "type": "string", "secret": false, "required": true},
    {"name": "SUPABASE_SERVICE_KEY", "type": "secret", "secret": true,  "required": true}
  ],
  "category": "provisioning",
  "status": "pending",
  "response": null,
  "created_at": "2026-07-21T04:06:00Z",
  "resolved_at": null
}

Secret fields render as password inputs. category tags every wall so /api/stats can aggregate them.

Design decisions

  • Polling, not a blocking backend call. The agent long-polls GET /requests/{id} and the backend resolve is a fast, stateless write. Nothing is held open server-side, so a slow human or a dropped connection can't wedge a request, the timeout path is trivial (return pending, keep working), and the exact same endpoint feeds the browser inbox. A blocking call would couple request lifetime to a single held HTTP connection and make the "give up and check back later" story much harder.
  • Schema-driven forms. The request declares the fields it needs; the inbox renders inputs from that schema and the backend validates against it. One source of truth means the form can never drift from what the agent expects, secret-masking is declarative (secret: true), and adding a new kind of wall needs zero UI code.
  • Category as instrumentation. Every wall is tagged with a category, and /api/stats aggregates by it. Over time that answers "which wall do I hit most" - the questions that tell you what to actually automate away next. The stats view is the point, not decoration.

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