Skip to main content
Glama
README.md
# VerifierMCP

> An **MCP server** that gives any LLM the power to **check its own work**.
> Instead of trusting a model's arithmetic, regex, JSON or "the code prints X", the model
> can *call a tool and verify it*. Five verification tools over the
> [Model Context Protocol](https://modelcontextprotocol.io): symbolic math, sandboxed code
> execution, JSON-Schema validation, dimensional analysis, and regex testing.

<p align="center">
  <img src="docs/images/playground.png" alt="VerifierMCP playground catching errors live" width="880">
</p>

Built with the official **MCP Python SDK** (FastMCP). Works in **Claude Desktop** and any
MCP client over **stdio**, or remotely over **streamable HTTP** (e.g. behind **Amazon Bedrock
AgentCore Gateway**).

---

## Why it matters

LLMs are confidently wrong about exactly the things that are *mechanically checkable*:
`(x+1)² = x²+1`, a regex that doesn't quite match, JSON that violates its schema, a unit
slip, "this function returns 5050". VerifierMCP turns each of those into a tool call, so an
agent can **replace an assertion with a verified fact**.

## The tools

| Tool | Checks | Engine |
|------|--------|--------|
| `verify_math` | Is an equation an identity? Does a claimed result hold? | SymPy |
| `run_code` | What does this Python snippet *actually* output? | sandboxed subprocess |
| `validate_schema` | Does this JSON conform to its JSON Schema? | jsonschema (Draft 2020-12) |
| `check_units` | Is this quantity/equation dimensionally correct? | Pint |
| `test_regex` | Does this regex match/reject the right cases? | `re` |

Each tool body lives in [`src/verifier_mcp/tools/`](src/verifier_mcp/tools/) as a pure
function, so it is unit-tested without the protocol and reused by the web playground.

---

## Quickstart

```bash
pip install -r requirements.txt

# Run the MCP server over stdio (what Claude Desktop launches)
PYTHONPATH=src python -m verifier_mcp.server

# Or serve it over HTTP (MCP streamable transport on :8000/mcp)
PYTHONPATH=src python -m verifier_mcp.server --http

# See it in action — the visual playground
PYTHONPATH=src uvicorn verifier_mcp.playground:app --port 8080   # http://localhost:8080
```

### Connect to Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "verifier": {
      "command": "python",
      "args": ["-m", "verifier_mcp.server"],
      "env": { "PYTHONPATH": "/absolute/path/to/verifier-mcp/src" }
    }
  }
}
```

Restart Claude Desktop and ask it something like *"Is (x+1)² equal to x²+1? Use the verifier."*
— it will call `verify_math` and come back with the checked answer.

---

## Self-checking agent demo (Groq + MCP)

[`examples/self_checking_agent.py`](examples/self_checking_agent.py) connects a **Groq** LLM to
this server over **real MCP** (via `langchain-mcp-adapters`), instructs it to *verify before
asserting*, and watches it catch its own mistake:

```bash
pip install -r requirements-demo.txt
export GROQ_API_KEY=gsk_...                       # real Groq agent
python examples/self_checking_agent.py

python examples/self_checking_agent.py --offline  # no key: scripted LLM, REAL MCP verification
```

```text
[offline] Question: Is (x+1)^2 equal to x^2 + 1? If not, what is the correct expansion?

  [Assistant] draft answer: "(x+1)^2 = x**2 + 1"
  → verify_math((x+1)**2, claimed_result=x**2 + 1)  [real MCP call]
    MCP result: verified=False  —  expression simplifies to (x + 1)**2, not x**2 + 1
  → verify_math((x+1)**2, claimed_result=x**2 + 2*x + 1)  [real MCP call]
    MCP result: verified=True

  [Assistant] Corrected: (x+1)^2 = x^2 + 2x + 1 — verified, not x^2 + 1.
```

---

## Deploy remotely (Amazon Bedrock AgentCore Gateway)

The HTTP transport (`--http`, container in [`Dockerfile`](Dockerfile)) exposes a standard MCP
endpoint at `/mcp`. Point **AgentCore Gateway** at it to turn these verifiers into tools any
Bedrock agent can call:

```bash
docker build -t verifier-mcp .
docker run -p 8000:8000 verifier-mcp          # MCP over HTTP at http://localhost:8000/mcp
```

---

## The sandbox

`run_code` executes snippets in a fresh `python -I -S` subprocess with **no inherited
environment**, a **temp working dir**, and POSIX **resource limits** (CPU, memory, no forking,
no file writes) plus a wall-clock timeout. That is appropriate for a local dev tool. For
untrusted, multi-tenant use, run the whole server inside a container / gVisor / Firecracker —
the subprocess limits are defense-in-depth, not a complete jail.

---

## Tests

```bash
PYTHONPATH=src pytest -q      # 18 passed — tool logic + MCP protocol registration/dispatch
```

## Tech stack

**Model Context Protocol** (FastMCP) · **SymPy** · **jsonschema** · **Pint** · **FastAPI** ·
**Docker** · **GitHub Actions** · Amazon Bedrock AgentCore Gateway–ready

## License

MIT © Arash Omranpour

TDQS

A3.8/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a clearly distinct validation domain: symbolic math, code execution, JSON Schema, dimensional units, and regex testing. There is no overlap in purpose; an agent can easily select the right tool based on the task type.

Naming Consistency5/5

All names follow a consistent snake_case verb_noun pattern: verify_math, run_code, validate_schema, check_units, test_regex. The verbs are distinct but appropriate to each action, and the naming is highly predictable.

Tool Count5/5

Five tools is a well-scoped size for a verification toolkit, covering a focused set of common checking tasks without redundancy. Each tool earns its place and the set feels neither bloated nor thin.

Completeness4/5

The set covers core verification areas (math, code, schema, units, regex) with no dead ends within those domains. Minor gaps exist, such as XML/YAML schema validation or tolerance-based numeric comparison, but agents can work around them with run_code.

Maintenance

ActivityMaintained
ResponsivenessNo issues