MCP Agent Harness
Provides a mountable SSE/ASGI app for FastAPI applications, enabling the harness's MCP tools and endpoints to be exposed alongside FastAPI routes.
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., "@MCP Agent Harnessrun diagnostics and show the trace ID for this call"
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.
MCP Agent Harness
Generic, SRE-hardened Model Context Protocol (MCP) harness for autonomous agents. Acts as an operational firewall preventing LLM context exhaustion, enforcing data boundary blockades, throttling runaway agent retry loops, and guaranteeing zero unhandled panics across SSE streams.
5-Line FastAPI Quickstart
from fastapi import FastAPI
from mcp_agent_harness import AgentHarness
app = FastAPI()
harness = AgentHarness("ops-agent")
@harness.tool(max_chars=1000, rate_limit=(10, 60.0), catch_unhandled=True)
def get_status() -> str: return "System healthy"
app.mount("/mcp", harness.sse_app())Related MCP server: mcp-server-template
Architecture: The MCP SRE Firewall
flowchart TD
Client["Autonomous LLM / MCP Client (OpenClaw)"]
SSE["FastAPI Mount (/mcp/sse)"]
subgraph Harness ["AgentHarness SRE Firewall"]
Trace["1. Telemetry Tracer (init_trace)"]
Rate["2. Sliding Window Rate Limiter"]
Func["3. Tool Execution (Sync/Async)"]
DFGuard["4. DataFrame Blockade (Zero-Import MRO)"]
LogGuard["5. Log Line Capping (cap_log_lines)"]
CtxGuard["6. Context Truncation & XML Strip"]
ErrWrap["7. Deterministic Error Envelope"]
end
Backend["Host Backend Services (DB, Redis, APIs)"]
Client -->|JSON-RPC via SSE| SSE
SSE --> Trace
Trace --> Rate
Rate --> Func
Func <--> Backend
Func --> DFGuard
DFGuard --> LogGuard
LogGuard --> CtxGuard
CtxGuard -->|Clean Bounded Payload| Client
Func -.->|Unhandled Panic / Rate Limit| ErrWrap
DFGuard -.->|TokenStarvationError| ErrWrap
ErrWrap -->|JSON Error Envelope| ClientBenchmark Metrics & SRE Hardening
Metric | Unguarded FastMCP | AgentHarness v0.2.0 | Operational Impact |
Token Consumption (1k rows) | ~85,000 tokens | ~420 tokens | 99.5% prompt token reduction |
Prompt Injection Defense | Raw XML | Sanitized scalar preview | Immune to XML unclosed tag context hijack |
Hallucination Loop Defense | Uncapped infinite retries | Sliding Window Rate Limit | Hard stop on agent runaway retry storms |
Stream Stability | SSE drops on unhandled panic | 100% Stream Uptime | Deterministic JSON error envelope return |
Guard Latency Overhead | None | < 0.15 ms | Sub-millisecond boundary verification |
Dependencies | Requires | Zero Core C-deps | MRO duck-typing for pandas, polars, pyarrow |
Prerequisites
Docker
>= 24.0Docker Compose
>= 2.20GNU Make
>= 4.3(Optional for local development) Python
>= 3.11
Quickstart (Containerized)
No local Python environment or dependency installation required. All lifecycle steps run inside isolated containers:
# 1. Build the hardened container image
make build
# 2. Run the integration test suite
make test
# 3. Spin up the harness and verify live endpoint health
make demo
# 4. Run the security, leak, and Trivy CVE audit gate
make auditAPI & Configuration Reference
AgentHarness
Main server class wrapping FastMCP with SRE boundary guards.
from mcp_agent_harness import AgentHarness
harness = AgentHarness(
name="analytics-mcp",
instructions="Operational analytics tools for agents.",
register_builtins=True,
)Parameter | Type | Default | Description |
|
|
| Identifier for the MCP server instance. |
|
|
| System instructions exposed to MCP clients. |
|
|
| Registers default diagnostic tools ( |
Declarative Tool Decorator (@harness.tool)
Configurable declarative SRE policies applied at the decorator boundary:
@harness.tool(
max_chars=2000,
max_lines=200,
strip_xml=True,
catch_unhandled=True,
rate_limit=(10, 60.0),
)
def query_system_logs(service: str) -> str:
...Parameter | Type | Default | Description |
|
|
| Automatically truncates string outputs exceeding character limit. |
|
|
| Caps string output lines to prevent context terminal flooding. |
|
|
| Strips raw |
|
|
| Catches unexpected exceptions and returns structured JSON error envelopes. |
|
|
|
|
Guardrails in Action
1. Token Starvation Guard (DataFrame Blockade)
The harness blocks raw tabular data from entering LLM context. Returning a raw DataFrame immediately triggers TokenStarvationError, captured into a structured error envelope:
import pandas as pd
from mcp_agent_harness import AgentHarness
harness = AgentHarness()
# ❌ BAD: Leaks raw DataFrame
@harness.tool()
def query_orders() -> pd.DataFrame:
return pd.DataFrame({"order_id": [1, 2], "amount": [99.5, 14.2]})
# Invoking returns a safe error envelope instead of leaking rows:
# {
# "status": "error",
# "error_code": "TokenStarvationError",
# "message": "Raw DataFrames are strictly prohibited in MCP tools. Return scalar metrics or token-compressed strings.",
# "trace_id": "mcp-3a1b4c9e"
# }
# ✅ GOOD: Return compact scalar metrics
@harness.tool()
def query_order_metrics() -> dict:
df = pd.DataFrame({"order_id": [1, 2], "amount": [99.5, 14.2]})
return {
"order_count": len(df),
"total_revenue": float(df["amount"].sum()),
"average_order": float(df["amount"].mean()),
}2. Hallucination Throttling (Rate Limiting)
Throttles runaway LLM retries when an agent enters an infinite retry loop:
@harness.tool(rate_limit=(3, 60.0), catch_unhandled=True)
def trigger_external_mutation(action: str) -> dict:
return {"status": "dispatched", "action": action}
# On the 4th invocation within 60s, execution is stopped before hitting backend:
# {
# "status": "error",
# "error_code": "ToolRateLimitError",
# "message": "Rate limit exceeded: 3 calls per 60.0s limit reached.",
# "trace_id": "mcp-9b2f11c4"
# }Telemetry & Error Envelopes
Every tool invocation automatically initializes an OpenTelemetry-compatible trace_id (mcp-xxxxxxxx).
When catch_unhandled=True is configured, internal tool exceptions are safely converted to structured responses without crashing the SSE connection:
{
"status": "error",
"error_code": "ConnectionResetError",
"message": "Remote database closed connection",
"trace_id": "mcp-e4f912a7"
}This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Hosted MCP runtime where your agent publishes its own tools by tool call and keeps working.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Enable secure connectivity between Sentry issues and debugging data, and LLM clients, using a Model Context Protocol (MCP) server.
Related MCP Servers
- AlicenseBqualityAmaintenanceA lightweight server implementation that exposes Python functions as discoverable tools via HTTP using the Machine-to-Machine Communication Protocol (MCP). Enables remote execution of Python functions through a JSON-RPC interface with async support and type safety.484 PyPIMIT
- AlicenseAqualityCmaintenanceA production-ready starting point for MCP servers, adding per-tool timeouts, concurrency ceilings, error boundaries, secret redaction, correlation IDs, and structured logging so tools are safe and observable for LLM callers.3MIT
- AlicenseNot gradedqualityCmaintenanceEnables turning any Python function into an auto-registered MCP tool and serving them over a FastMCP server with auto-discovery, optional auth, and request context.MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP tool handlers to be declared with a decorator, collected into a registry from a config map, and served over a bearer-token-authenticated Streamable HTTP ASGI app. Tools can also be invoked in-process without running any HTTP server.39 PyPIMIT