reflect-mcp
Provides integration with OpenAI's API, allowing the use of GPT models as an alternative provider for the generator and critic in the extraction and verification pipeline.
Click on "Install 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., "@reflect-mcpextract invoice fields from: 'Bill from Acme for $200 on 2024-01-01'"
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.
reflect-mcp
An MCP server for LLM tasks that verify themselves: Generator → second-model Critic → human-in-the-loop gate. Never a silent wrong answer.
1. TL;DR
reflect-mcp is a small multi-agent pipeline that checks its own work before surfacing it, exposed as an MCP server so it plugs into Claude Desktop, Cursor, or any MCP client. A Generator extracts a typed object from messy text; a second-model Critic scores every field and the whole extraction; a confidence-thresholded gate either returns the result or, if it isn't confident enough, returns a needs_review payload naming the exact fields a human should confirm.
┌───────────┐ ┌──────────────┐ ┌────────┐ ┌──────────────┐
messy text ──▶ │ Generator │ ───▶ │ heuristics + │ ───▶ │ Gate │ ───▶ │ ok / │
│ (model A) │ │ Critic (B) │ │ (HITL) │ │ needs_review│
└───────────┘ └──────────────┘ └────────┘ └──────────────┘
typed JSON per-field + overall threshold flagged fields
confidence decision + rationaleRelated MCP server: Kluster.ai Verify MCP
2. Why — the trust problem
LLMs are confidently wrong. The failure mode that actually hurts in production isn't a model that says "I don't know" — it's a model that returns a clean, plausible, wrong value with no signal that anything is off. reflect-mcp makes verification a first-class step: a different model critiques the output, deterministic structural checks run alongside it, and anything below a confidence threshold is escalated instead of emitted.
The pattern is well established: naive extraction pipelines look great in a demo and then quietly degrade on real inputs, and adding a multi-model verification + human-review gate is a proven way to claw accuracy back. The point reflect-mcp makes concrete: the verification discipline is the product, not the extraction call.
3. Demo
Messy input → typed JSON with per-field confidence → one low-confidence field flagged for review:
// input
"Hi team, bill from Globex Ltd. Ref GLX/2026/778, dated 2026-02-28.
540.00 before tax, tax 43.20, amount due 683.20. Pay in GBP."
// output (the model hallucinated the total; the critic + arithmetic check caught it)
{
"status": "needs_review",
"data": { "vendor_name": "Globex Ltd", "invoice_number": "GLX/2026/778",
"invoice_date": "2026-02-28", "subtotal": 540.0, "tax": 43.2,
"total": 683.2, "currency": "GBP" },
"field_confidence": { "total": 0.12, "subtotal": 0.95, "tax": 0.95, "...": 0.95 },
"overall_confidence": 0.70,
"flagged_fields": [
{ "field": "total", "value": 683.2, "confidence": 0.12,
"reason": "683.20 does not reconcile with 540.00 + 43.20; not found in source" }
],
"notes": "1 field(s) below the 70% confidence threshold require human review before use."
}(A ~20s GIF of this in Claude Desktop goes here in the published repo.)
4. Use it in Claude Desktop
Install and point Claude Desktop at the server. Add this to your claude_desktop_config.json
(macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"reflect-mcp": {
"command": "/ABSOLUTE/PATH/reflect-mcp/.venv/bin/python",
"args": ["-m", "reflect_mcp.server"],
"env": {
"REFLECT_PROVIDER": "anthropic",
"ANTHROPIC_API_KEY": "sk-ant-...",
"REFLECT_GENERATOR_MODEL": "claude-3-5-sonnet-latest",
"REFLECT_CRITIC_MODEL": "claude-3-5-haiku-latest"
}
}
}
}Then restart Claude Desktop and ask it to "extract the invoice fields from this text …" — it will call the extract tool.
Tool exposed
Tool | Args | Returns |
|
|
|
When status == "needs_review", do not use data blindly — confirm the fields in flagged_fields first.
5. Architecture
Three roles, one shared trace id, clean layering (resolver-free by design — the pipeline has no infra dependency):
Generator (
generator.py) — one LLM call → validatedInvoiceData(Pydantic). Absent fields come backnull; the model is instructed never to invent a value.Critic (
critic.py) — a different model (REFLECT_CRITIC_MODEL) is shown the source and the candidate extraction and must ground each field, returning per-field + overall confidence. A different model matters: self-critique with the same model tends to rubber-stamp its own errors.Deterministic heuristics (
heuristics.py) — a free, non-LLM signal: grounding (is a committed value actually present in the source?), arithmetic reconciliation (subtotal + tax == total), and ISO-date validation. These cap the Critic — a structurally impossible value can't be waved through on the Critic's word alone.Gate (
gate.py) — combines the two signals multiplicatively (combined = critic_confidence × heuristic_factor), flags any non-null field belowfield_threshold, and escalates the whole result if any field is flagged or overall confidence is belowoverall_threshold.
The extract tool (server.py) is the only module that imports the mcp SDK, and providers.py is the only module that imports a provider SDK — so the core pipeline and the entire test suite have zero hard dependency on either.
6. Evaluation
A tiny golden-file eval treats LLM quality as measurable, not vibes. eval/golden/dataset.jsonl holds labeled messy-text → expected-fields examples; eval/run_eval.py runs the full pipeline over them and reports field accuracy, exact-match accuracy, needs-review rate, and exactly where it fails.
make eval # OFFLINE: deterministic, uses recorded model outputs (no API keys)
make eval-live # LIVE: runs against REFLECT_PROVIDER (needs credentials)Offline run (recorded fixtures, one example carries an injected hallucination to prove the harness catches misses):
============================================================
reflect-mcp eval | mode: OFFLINE (replay fixtures)
============================================================
examples : 5
field accuracy : 97.1% (34/35)
exact-match acc : 80.0% (4/5)
needs-review rate : 20.0% (1/5)
------------------------------------------------------------
field-level failures (where it breaks):
[inv-004] total: expected 583.2 but got 683.2
============================================================
PASS: field accuracy 97.1% >= required 90.0%make eval exits non-zero below --min-accuracy (default 0.90), so it works as an offline eval-CI gate with no secrets.
7. Testing
Deterministic tests around a stochastic core. The single LLM boundary (LLMClient) is mocked with a ScriptedLLMClient that returns canned JSON and raises if it's ever asked for more than expected — so pytest runs fully offline, with no API keys, and can't leak a real call.
make install # .venv + package + dev/server deps
make test # deterministic offline suite
make cov # with coverageThe flagship test is tests/test_critic_catches_error.py: the Generator is fed a deliberately wrong value (vendor_name = "Invoice" — a word that does appear in the source, so the deterministic grounding check can't catch it), and the test asserts the second-model Critic catches it and the gate routes to needs_review. It also flips only the Critic's verdict and shows the decision flip to ok — proving the verification step is doing real work, not the plumbing.
8. Design decisions
Second-model Critic (multi-model reflection), not self-critique. The Critic defaults to a different, cheaper model than the Generator (
sonnetgenerates,haikucritiques). Cross-model disagreement is a real signal; same-model self-review is mostly agreement theater.Provider switching via env var.
REFLECT_PROVIDERselectsanthropic|openai|bedrock, so a reviewer runs it against whatever key they have. The Bedrock (Claude) path is there for AWS users; the public-API paths (Anthropic/OpenAI) let anyone try it without AWS. Provider SDKs are optional extras (pip install 'reflect-mcp[anthropic]') and imported lazily.Confidence is multiplicative.
critic_confidence × heuristic_factor— evidence can only lower confidence. A structurally impossible value (bad arithmetic, ungrounded amount) is capped regardless of how sure the Critic sounded.Nulls are honest. A field absent from the source returns
nulland is never flagged — abstention is correct behavior, not a low-confidence guess.Prompt versioning + injection awareness. Prompts live in versioned files (
src/reflect_mcp/prompts/). Both instruct the model to treat document content as data, not commands — the source text is untrusted input, a basic prompt-injection guard.Observability. Every stage emits a structured JSON log line carrying a shared
trace_id, so one extraction is greppable end to end.
9. What I'd productionize next
Batching + caching of Generator/Critic calls; per-request cost/latency budgets.
A real human-review queue (persist
needs_reviewpayloads, route to a reviewer UI, feed corrections back as new golden examples).Offline eval in CI on every PR (the
make evalgate is already CI-shaped) plus periodic live eval to catch model drift.Confidence calibration — replace hand-set thresholds with thresholds tuned on the labeled set to hit a target precision.
Streaming + partial results, and a richer schema library (invoices, receipts, resumes, log lines) behind the same verify-then-gate loop.
Repository layout
reflect-mcp/
├── src/reflect_mcp/
│ ├── schema.py # Pydantic extraction + verdict/decision models
│ ├── providers.py # provider switching (Anthropic/OpenAI/Bedrock), lazy SDKs
│ ├── scripted.py # ScriptedLLMClient — the mock at the LLM boundary
│ ├── generator.py # Generator stage
│ ├── critic.py # second-model Critic stage
│ ├── heuristics.py # deterministic structural checks
│ ├── gate.py # confidence gate / HITL decision
│ ├── pipeline.py # orchestration (generate → heuristics → critique → decide)
│ ├── logging_config.py # structured JSON-line logging
│ ├── parsing.py # robust JSON extraction + prompt loader
│ ├── prompts/ # versioned generator.txt / critic.txt
│ └── server.py # FastMCP server exposing the `extract` tool
├── eval/
│ ├── golden/dataset.jsonl # labeled golden examples
│ ├── fixtures/replay.json # recorded model outputs for offline eval
│ └── run_eval.py # eval harness
├── tests/ # deterministic, fully offline
├── Makefile # install / test / cov / eval targets
├── pyproject.toml
└── LICENSELicense
MIT — see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jeffma8888/reflect-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server