UltraPopper
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., "@UltraPopperrefute my design for a TTL+LRU cache"
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.
UltraPopper
Adversarial, Karl Popper–style review for Claude Code. UltraPopper front-loads refutation into
software work: before a line of code is written, it forces a change through a conjecture → adversarial refute → refine → survive → implement loop, so the design that ships is the one that survived attack —
not the first one that looked plausible.
Its distinctive value is one move: it surfaces the emergent, interaction-level bugs you would never think to write a test for. In a blind head-to-head against a rigorous test-first methodology building the same cache library, the test-first build wrote more tests (92 vs 78) yet still shipped a real correctness bug (an expired-but-unswept entry counting toward LRU capacity); UltraPopper caught it during refutation — before implementation — because "what breaks when TTL and LRU act on the same structure?" is its native question. You cannot test a bug you never conceived; refutation is the step that conceives it.
UltraPopper ships as two pieces:
a model-free MCP server (
popper) — holds no model, does no inference; every tool returns a prompt/plan for Claude Code and persists artifacts under.popper/;a Claude Code plugin (
ultrapopper) — ausing-ultrapopperentrypoint (auto-loaded via a SessionStart hook) plus per-command skills that drive the server.
Quickstart
Prereqs: Node ≥ 18 and the Claude Code CLI.
# from a checkout of this repo — installs the server + plugin (user scope):
bash scripts/install.sh
# fresh machine (private repo): GH_IBM_TOKEN=github_pat_xxx bash scripts/install.shThen restart Claude Code, cd into any project, and ask it to build something non-trivial — the
refutation loop runs automatically before code is written. Or drive it explicitly:
ultrapopper:understand → :clarify → :hypothesize → :refute → :implement (:solve picks the next step).
Sanity check: npm run verify && npm run smoke.
Related MCP server: codex-fusion-mcp
When to use it
UltraPopper is insurance against the bug you'd never think to write a test for — worth its cost only when a mistake would be expensive and could arise from how pieces interact. It earns a real correctness edge on emergent, interaction-level failures, and little on routine work the model already handles. (A two-task benchmark, same model across arms: on a self-contained rate-limiter it added nothing — every arm was correct; on a TTL×LRU cache it was the only approach that shipped correct code, because the interaction bug is one a plain build "tests around" without ever conceiving.)
Reach for it (light → ultra) when:
You're implementing an idea into a large / unfamiliar codebase — the risk is interaction with code you can't hold in your head (shared state, ordering, invariants). Refutation grounds in the actual code (
understand+ evidence anchors), catching what the model can't conceive on its own.Multiple components interact — caches, concurrency, TTLs, cross-module contracts.
The blast radius is money / prod / security / data, or the change is hard to reverse.
You're extending prior work in a recurring domain — the cross-session knowledgebase feeds last time's failure patterns into this refutation, and sharpens with reuse.
The design space is wide or ambiguous and you want to settle it before writing code.
Skip it (just answer, or just edit) when: a rename / typo / constant tweak / one obvious localized function; a self-contained thing the model clearly knows cold; a reversible, well-specified change; or a question with nothing to build.
The one question: "Could this fail in a way I wouldn't test for — because of how it interacts with something else — and would that failure be expensive?" If yes, refute first (it only works before you code). The plugin triages this automatically (skip / light / ultra); say "just do it" to force a skip.
Why model-free?
The server enforces process, not intelligence. It never calls a model. Every tool is a two-call pattern: call 1 returns a prompt/plan for Claude Code to reason over; call 2 accepts the reasoned artifact and persists it. Claude does all the thinking; the server guarantees the discipline — a locked contract, a firewall, a durable knowledgebase, and a refutation record. This makes the loop deterministic, auditable, and impossible to shortcut.
How it works
UltraPopper is two cooperating pieces: a Claude Code plugin (ultrapopper) and the model-free MCP
server (popper) it drives. Together they run an adversarial review before Claude writes code, so what
ships is a design that survived attack rather than the first one that looked plausible.
When you ask Claude to build something non-trivial, the flow is:
Triage — the plugin sizes up the request and picks a gear: skip (just answer or make the edit), light (one quick refutation pass), or ultra (the full loop) — so the review only runs when it is worth the cost.
Understand — it indexes your codebase once, so the review is grounded in the real code.
Clarify — it restates the task as a locked contract (assumptions, constraints, open questions) and settles anything ambiguous with you first.
Hypothesize — it proposes one or more candidate designs (several independent ones, from different angles, in ultra mode).
Refute — it then attacks those designs with isolated probes that try to break each piece and each interaction, and prunes whatever fails. This is the step that surfaces the emergent, interaction-level bug you would never think to write a test for. It loops (refine → refute) until a design survives.
Implement — finally it writes the code and tests for the design that survived.
The MCP server does no thinking of its own — it holds no model and makes no network calls. It enforces the process (the locked contract, the isolation between proposing and attacking, a durable refutation record, and a knowledgebase that carries lessons across sessions) while Claude does the actual reasoning. Because it is a standard MCP server, the same engine can back any MCP-capable client, not just Claude Code.
The loop
understand → clarify (lock a contract) → hypothesize → refute → [refine ↺] → implementTool | What it does |
| Mechanically index the codebase into |
| Turn a raw statement into a locked problem contract. Refuses to silently abandon an in-progress problem (pass |
| Draft (call 1) then persist (call 2) a split public/private hypothesis. At |
| Return a firewalled fan-out plan of isolated adversarial probes; log verdicts and decide survive / refine / exhaust. |
| Emit a one-shot implementation prompt for the surviving hypothesis / best composite. |
| Report the current phase and the next tool to call (the conductor). |
| Summarize the profile, phase, knowledgebase, and contract stats. |
Light vs. ultra
light— one hypothesis, one refutation fan-out. For a self-contained 1–2 file change.ultra— K diverse Proposers → fragment decomposition → combinatorial viable-path enumeration → per-fragment and interacting-pair and N-way composite refutation → best-composite assembly. For multi-file, architecturally significant work with several viable approaches.
The information firewall (load-bearing)
A hypothesis is split into public (solution, assumptions) and private (reasoningTrace, confidence,
rejectedAlternatives) fields. Two gates in src/firewall.ts are the sole boundary to a Refuter:
toRefuterView(hypothesis)— strips the private fields.toCanonFragmentView(fragment)— exposes only{ key, files, description }(neverproposers).
Nothing else may hand data to a probe. The end-to-end smoke test proves it from both sides: the private reasoning is retained in the private session log yet absent from every public artifact.
Ultra internals
Fragments (
src/fragments.ts) — proposers decompose solutions into toggleable sub-changes with a shared kebab-casekey, plusrequires/conflictsWith. Keys are typographically canonicalized, and a two-callmergePlanlets Claude confirm semantic aliases (model-free — the server proposes candidates by file overlap, it never decides equivalence).Combinatorial engine (
src/bdd.ts) — enumerates conflict-free, requires-closed viable composites with requires-satisfiability forward-pruning, reduced to the maximal frontier.Interacting-pair + N-way composite probes — beyond per-fragment probes, UltraPopper probes co-occurring pairs (capped/ranked by file overlap) and whole composites for emergent fatals that no fragment reveals alone. A grounded fatal pair adds a conflict edge; a fatal composite forbids that combination.
Cross-session knowledgebase (
src/kb.ts) — grounded fatal patterns and resolved-defect findings are promoted to.popper/kb.json; on later problems, patterns on overlapping files are fed to Refuters as ammunition (grounded by file-hash; stale ones trigger re-verification). The loop learns from its own work.File-based intake — large K-proposer payloads are written to
.popper/inbox/and read by the server, never passed as one fragile inline JSON argument.
The three deepenings
Recent work sharpened the core (refutation quality) rather than broadening scope:
Refutation report (
.popper/reports/<id>.json) — a durable, first-class record of what each round probed, pruned, suspected, and left uncovered. The loop's distinctive artifact.Coverage critic — the plan exposes the failure-mode taxonomy as
coverageTargets; the verdict returns thecoverageGap(classes no probe addressed), so blind spots are named, not assumed away.Refuter calibration — a fatal prunes only if the Refuter demonstrated it (
reproduced: true); an unreproduced hunch is recorded as suspected, not acted on, so it can't kill a good fragment.
Scratch auto-cleanup
When a contract's loop finishes — popper_implement completes, popper_refute exhausts, or the
contract is abandoned via popper_clarify { newProblem: true } — its transient scratch is purged
automatically so it can't accumulate and hog disk/context:
.popper/bdd-trees/<id>.json— the viable-path tree; consumed byimplement, never read across contracts..popper/inbox/*.json— proposer staging files, already read into the session log.stray
*.tmp— interrupted atomic-write intermediaries.
Durable artifacts are never touched: reports/ (the SuperPoppers handoff), solutions/,
refutations/ (session logs), kb.json, knowledgebase.json, state.json, config.yaml. The purge is
best-effort (it never fails a run) and defaults on — opt out per repo with cleanup: { purge_scratch: false }
in config.yaml. (Unlike max_patterns, this loses no real data, so it is safe to default on.)
Privacy, cost & control
Privacy — nothing leaves your machine, nothing lands in git. The server is model-free and does no network I/O; it only writes under
.popper/. That dir holds the model's private reasoning traces (session logs) plus the KB/reports/trees, so on first run UltraPopper writes a self-contained.popper/.gitignoreof*— git ignores the whole working dir (including that file), so nothing under.popper/is ever accidentally committed. Delete it orgit add -fto deliberately commit (e.g. to share a KB across a team).Scoped, gitignore-aware scanning.
popper_understandstops at nested git-repo boundaries, caps atMAX_SCAN_FILES, honors the repo's.gitignoreon top ofDEFAULT_IGNORES, and takes apatharg to scope to a single subdirectory — a huge or multi-repo working dir can't pollute the profile.Cost & control. The SessionStart entrypoint triages every request (skip / light / ultra) so the loop runs only when it earns its cost; ultra is token-heavy (K proposers + a probe per fragment and per interacting pair). Say "skip the loop" to bypass for one task, or
claude plugin uninstall ultrapopper@ultrapopperto disable it entirely.
Known limitations
One active popper session per working dir — two concurrent sessions can race on
.popper/state.json..gitignoreawareness covers the common subset (dir-only, anchored,*/**/?, negation); it does not read per-directory nested.gitignorefiles.
The plugin (ultrapopper)
The repo is itself a local plugin marketplace. Installing the plugin registers a SessionStart hook that
auto-loads the using-ultrapopper entrypoint every session, plus per-command skills invoked as
ultrapopper:understand | clarify | hypothesize | refute | implement | solve. A plain "build X" request
then drives the whole loop automatically — refute before code, prove the firewall, then implement.
Install
# from a checkout (server + plugin, user scope):
bash scripts/install.shThis builds the server, registers the popper MCP server (claude mcp add popper -s user), and installs the
plugin (claude plugin marketplace add . && claude plugin install ultrapopper@ultrapopper). Restart Claude
Code so the SessionStart hook loads, then cd into any project and ask it to build something non-trivial.
Quality & testing
The whole project is built and hardened under a strict, ratcheting gate:
npm test # full vitest suite
npm run verify # tsc build + tests + coverage, then RATCHET .baseline.json up on success
npm run verify:check # same gate, read-only (CI / pre-push)
npm run smoke # end-to-end: spawn the built stdio server, drive the whole pipeline, prove the firewallscripts/verify.mjs fails on any regression below the .baseline.json floor (test count + coverage) and
raises the floor on success. .github/workflows/ci.yml runs npm ci → verify:check → smoke on Node 18/20/22.
Current floor: 441 tests, ~92.5% branch coverage, statements/lines ~99%. Every feature and every fixed bug
landed with a test in the same commit; every adversarial-review finding was verified before fixing.
Prove it's an improvement, don't assert it. npm run compare builds the archived baseline in a throwaway
worktree and diffs the same inputs through both versions' (model-free, deterministic) handlers — it doubles
as a cross-version regression gate (non-zero exit if the current version is worse on any probe). Latest run:
6 improved, 0 regressed — see docs/OLD-VS-NEW.md.
SuperPoppers
UltraPopper composes with test-first methodologies rather than replacing them: run the refutation loop to catch what you'd never test for, then hand the refutation report to a TDD executor for broad routine coverage. That pipeline — SuperPoppers — measured best-of-both in the bake-off: as correct as UltraPopper and better-tested than pure TDD.
Layout
src/ # model-free server: handlers, firewall, bdd, kb, fragments, compression, report, …
plugins/ # the ultrapopper Claude Code plugin (skills + SessionStart hook)
scripts/ # install.sh, verify.mjs (ratchet gate), smoke.mjs (e2e)
.claude-plugin/ # marketplace manifest
docs/ # design spec + phase plansLicense
MIT.
Available Tools
8 toolspopper_clarifyA
Turn a raw problem statement into a locked problem contract. First call returns a drafting prompt + relevant files; second call (with contract) validates and locks it.
| Name | Required | Description | Default |
|---|---|---|---|
| contract | No | The drafted contract to persist/lock; omit on the first call. | |
| statement | Yes | The problem statement / feature request / bug report. | |
| newProblem | No | Pass true on the first (draft) call to abandon an in-progress problem and start a fresh contract. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided. The description discloses the two-call behavior and that the first call returns a drafting prompt and relevant files while the second validates and locks the contract. However, it does not mention potential side effects, prerequisites, or what happens if validation fails, leaving gaps in transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that conveys the purpose, the two-step process, and the return value in a compact manner. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's role in a larger problem-solving workflow (indicated by sibling tools), the description adequately explains the tool's function and the required two-call sequence. It does not detail return format or error handling, but the core behavior is sufficiently covered for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All parameters are described in the schema (100% coverage). The description adds value by explaining the two-call context and that the 'contract' parameter should be omitted on the first call. This clarifies the optionality beyond the schema's description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: converting a raw problem statement into a locked problem contract. It specifies a two-step process (draft then lock) and distinguishes itself from sibling tools like popper_understand and popper_implement by focusing on the initial clarification phase.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly outlines the two-call usage pattern: first call without a contract, second call with a contract. It does not explicitly state when not to use the tool or mention alternatives, but the context of sibling tools makes its role clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
popper_hypothesizeA
Draft (call 1) then persist (call 2 with hypothesis) a split public/private hypothesis for the locked contract.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Reasoning depth; ultra is a Phase D capability. | |
| hypotheses | No | UltraPopper: the K drafted split hypotheses (each with fragments); omit for light mode. Prefer hypothesesDir for large payloads. (A JSON string is accepted and parsed.) | |
| hypothesis | No | The drafted hypothesis to persist; omit on the first call. (A JSON string is accepted and parsed.) | |
| hypothesesDir | No | UltraPopper (preferred for large payloads): read every *.json in this dir (each a proposer's hypothesis) instead of passing `hypotheses` inline — avoids giant inline-JSON args. Usually ".popper/inbox". | |
| fragmentAliases | No | UltraPopper: Claude-confirmed canonicalization map { aliasKey: canonicalKey } merging equivalent fragments surfaced in the prior call's mergePlan; omit if none. | |
| hypothesesFiles | No | UltraPopper: explicit list of proposer hypothesis JSON files to read + combine (alternative to hypothesesDir). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It reveals the draft-then-persist pattern but lacks detail on side effects, error handling, or implications of the 'locked contract'. Behavioral traits are partially disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the key concept. It could be slightly improved by breaking into two sentences for clarity, but it effectively conveys the essence without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, nested objects, no output schema) and the complete schema coverage, the description provides sufficient context for the main workflow. It covers the two-call pattern and parameter usage, though it omits error conditions and return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the description adds context beyond the schema, such as preferring `hypothesesDir` for large payloads and omitting `hypothesis` on the first call. This meaningfully supplements the parameter definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses specific verb 'Draft' and 'persist' with resource 'hypothesis for the locked contract'. It clearly distinguishes from siblings like popper_implement or popper_refute by describing a unique two-call process.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description explains the two-call pattern (call 1 without `hypothesis`, call 2 with `hypothesis`) and provides guidance on parameter usage ('omit for light mode', 'prefer hypothesesDir for large payloads'). However, it does not explicitly state when not to use the tool or list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
popper_implementB
Emit a one-shot implementation prompt for the surviving hypothesis and persist a solution record.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Reasoning depth; ultra is a Phase D capability. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It mentions 'persist', indicating a write operation, but provides no details on side effects, idempotency, error conditions, or what the 'solution record' contains. This is insufficient for behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no fluff, but it lacks structure (e.g., no separation of purpose from behavior). It is concise but could benefit from additional detail to improve completeness while maintaining brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema and no annotations, the description should cover key aspects like return values, prerequisites (e.g., a surviving hypothesis), and the nature of 'solution record'. It fails to do so, making it incomplete for reliable agent use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage for the single parameter (depth) including its enum and description. The tool description does not add any extra meaning beyond the schema, so it meets the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool emits a one-shot implementation prompt and persists a solution record. The verb 'emit' and 'persist' are specific, and 'surviving hypothesis' provides context distinguishing it from siblings like popper_hypothesize or popper_refute.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when there is a 'surviving hypothesis', giving some context. However, it lacks explicit guidance on when to use versus alternatives, such as popper_solve or popper_clarify, and does not mention prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
popper_learnA
Record TDD-execution outcomes for the active contract so UltraPopper's KB learns from what actually held up under test. kind: 'held' (a refutation finding confirmed by a failing test), 'false_alarm' (a finding that did NOT reproduce), or 'missed' (a defect the tests found that refutation did not — the sharpest signal). Folded into the KB on the next popper_refute; held/missed need evidenceAnchors to ground.
| Name | Required | Description | Default |
|---|---|---|---|
| outcomes | No | The outcomes to record (a JSON string is accepted and parsed). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses that outcomes affect the KB on future refutation, but does not mention idempotency, error states, or safety implications like data persistence.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: first defines purpose, second defines kinds and critical requirement. No filler or repetition. Ideal conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and a single parameter, the description covers the core usage. It explains kinds and evidenceAnchors. Lacks info on whether outcomes are appended or replaced, and the return value, but is generally sufficient for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, baseline is 3. The description adds value by explaining the meaning of each kind and emphasizing that held/missed require evidenceAnchors, which the schema lists as optional but the description clarifies as necessary for those cases.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's verb and resource: 'Record TDD-execution outcomes for the active contract.' It uniquely distinguishes from siblings like popper_hypothesize and popper_refute by focusing on learning from test results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when outcomes are folded in ('on the next popper_refute') and notes that held/missed need evidenceAnchors, providing implicit usage context. However, it does not explicitly contrast with sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
popper_refuteC
Return a firewalled fan-out plan (call 1); log verdicts + decide survive/refine/exhaust (call 2 with verdicts).
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Reasoning depth; ultra is a Phase D capability. | |
| verdicts | No | Probe verdicts to log; omit on the first call to get the plan. | |
| pairVerdicts | No | UltraPopper: interacting-pair verdicts from the pair-probe round; a fatal pair adds a conflict edge. Omit if no pair probes were dispatched. | |
| resolvedDefects | No | UltraPopper: defects a probe surfaced that you RESOLVED by refining the design (fragment survives). Recorded to the KB (anchored) so the next session gets them as crossSessionKb ammunition — the loop learns from its own work. Include one per fixed defect, with evidenceAnchors on the touched files. | |
| reverifications | No | Answers to the plan's reverifyProbes: for each stale KB pattern, whether the flaw still applies (stillValid); include perAnchor for multi-file patterns so fixed files are dropped. | |
| fragmentVerdicts | No | UltraPopper: per-fragment refutation verdicts. Tag `category` (so fatals promote to the KB and refutation coverage is measured) and set `reproduced` (a fatal prunes only if not explicitly false — an unreproduced hunch is recorded, not acted on). Omit for light mode or the ultra plan call. | |
| compositeVerdicts | No | UltraPopper: composite (N-way) verdicts from the composite-probe round; a fatal composite forbids that exact combination and any superset. Omit if no composite probes were dispatched. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds the two-call protocol and decision outcomes (survive/refine/exhaust) beyond the schema. However, with no annotations, it fails to disclose side effects, permissions, or error conditions. It is moderately transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short (one sentence) and front-loaded, but uses jargon and parenthetical notation that may hinder clarity. It could be more accessible while maintaining brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (7 parameters, nested objects, two-call process), the description is insufficient. It does not explain what the returned plan looks like, how to interpret decision outcomes, or what happens on errors. No output schema exists to compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed parameter descriptions, so the tool-level description adds little extra meaning. The mention of 'verdicts' as the key parameter for the second call is already clear from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool returns a firewalled fan-out plan on first call and logs verdicts with decision on second call. It is specific about verb+resource but uses jargon ('firewalled fan-out plan') that may be unclear to an agent. It does not explicitly differentiate from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives (e.g., popper_understand or popper_hypothesize). The description only outlines the two-call procedure without context on when it's appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
popper_solveB
Report the current phase and which popper_* tool to call next (model-free conductor).
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Reasoning depth; ultra is a Phase D capability. | |
| statement | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description alone must disclose behavior. It mentions being 'model-free conductor' and reporting phases, but omits side effects, state changes, prerequisites, or what the output actually contains. Minimal behavioral detail is insufficient for safe agent invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-formed sentence that efficiently conveys the tool's purpose. Every word earns its place, with zero redundancy or irrelevant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 2 parameters, no output schema, and no annotations, the description is too sparse. It does not explain what 'phase' means, the role of 'statement', or the format of the report. An agent lacks sufficient context to use this tool correctly in a workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 50% schema description coverage, only the 'depth' parameter has a schema description. The tool description adds no semantic clarity: it does not explain 'statement' or how parameters affect behavior. The description fails to compensate for the schema's gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool reports the current phase and suggests the next popper_* tool to call, positioning it as a model-free conductor. This distinct purpose differentiates it from sibling tools that perform specific actions like hypothesize or refute.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool should be used for orchestration—deciding which tool to call next—but does not explicitly state when NOT to use it or provide alternatives among siblings. The conductor role is clear, but exclusion criteria are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
popper_statusC
Report the current .popper/ knowledgebase summary, phase, and contract stats.
| Name | Required | Description | Default |
|---|---|---|---|
| problemId | No | Optional contract id to include detail for. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must fully disclose behavior. It implies a read-only operation but omits details like whether the .popper/ directory must exist, side effects, or authentication requirements. The term 'knowledgebase summary, phase, and contract stats' is vague.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that gets to the point quickly. While concise, it could benefit from slightly more detail without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description should explain what the tool returns. It mentions 'summary, phase, and contract stats' but no format or structure. For a reporting tool, this is insufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes the only parameter 'problemId' adequately. The tool description adds no new meaning beyond what the schema provides, so a baseline score of 3 is appropriate given 100% schema documentation coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reports a status summary, phase, and contract stats. The verb 'Report' and resource references are specific enough to distinguish it from sibling tools like popper_understand or popper_hypothesize.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus its siblings. It does not mention prerequisites, typical use cases, or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
popper_understandA
Mechanically index the codebase into .popper/, then (on a second call with interpretation) persist Claude's semantic architecture/conventions/invariants.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Optional project-relative subdirectory to scan (e.g. "packages/api"). Omit to scan the whole project root. Use it when the working directory holds multiple projects so the profile is grounded in the one repo you care about. | |
| interpretation | No | Semantic interpretation to persist; omit on the first (scan) call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses two behavioral steps (indexing and persisting) and hints at file creation (into .popper/). However, it does not explain side effects such as whether existing .popper/ is overwritten, whether network access is required, or what happens if called multiple times. The reference to 'Claude's semantic architecture' assumes domain knowledge. More detail on destructive potential and prerequisites would improve transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that efficiently conveys the two-step process and parameter role. It is front-loaded with the main action. However, the phrase 'Mechanically index' could be clearer, and the sentence is somewhat dense. Still, it avoids verbosity and is well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (two-step process, nested parameter) and lack of output schema, the description is reasonably complete but has gaps. It does not explain return values or confirmation of success, nor does it mention prerequisites (e.g., must be in a codebase root or have Claude session). Error scenarios are not addressed. The two-call pattern is clearly described, but the overall picture is not fully comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The tool description adds value by explaining the two-call pattern (interpretation only on second call) and reinforcing the path usage. But it does not significantly enhance meaning beyond the schema descriptions. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's two-step purpose: indexing the codebase into .popper/ and then persisting semantic interpretation on a second call. The verb 'index' and 'persist' specify the action, and the resource (codebase, .popper/ directory) is explicit. This distinguishes it from sibling tools like popper_status or popper_implement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear guidance on the two-step calling pattern: omit interpretation on the first scan call and include it on the second. It also explains when to use the path parameter (for subdirectories in multi-project workspaces). However, it does not explicitly state when to use this tool versus alternatives like popper_clarify or popper_hypothesize, though the context of sibling names implies differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
popper_clarify - First observed
popper_hypothesize - First observed
popper_implement - First observed
popper_learn - First observed
popper_refute - First observed
popper_solve - First observed
popper_status - First observed
popper_understand
TDQS
Scored across 8 tools
Each tool targets a distinct phase in the workflow (understand, status, clarify, hypothesize, implement, refute, solve, learn), with no overlapping purposes. The descriptions clearly differentiate their roles.
All tool names follow the consistent pattern 'popper_<verb>', using snake_case throughout. The naming is predictable and systematic.
With 8 tools covering all major phases of the scientific problem-solving workflow, the count is well-scoped. Each tool earns its place without unnecessary bloat or omission.
The tool set provides complete coverage of the intended workflow: from codebase understanding to problem clarification, hypothesis, implementation, refutation, orchestration, and learning. No obvious gaps are present.
Maintenance
Related MCP Connectors
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
MCP server for building and testing AI agents with multi-model experimentation and insights.
Official DevSpeak MCP server — translate technical text into formal specs from any AI IDE or agent
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server that lets Claude Code ask GPT Codex for adversarial planning, code review, debugging, research, and risk triage without leaving your project workflow.96 npm1MIT
- AlicenseNot gradedqualityBmaintenanceMCP server enabling Claude to consult Codex (GPT-5.x) mid-task for second opinions, plan/diff review, brainstorming, and codebase exploration via structured debates and permission-controlled interactions.2MIT
- AlicenseAqualityBmaintenanceAn MCP server that turns Grok CLI into the execution agent for Claude Code, implementing an orchestrated execute-verify-autofix loop for autonomous development tasks.7MIT
- AlicenseNot gradedqualityAmaintenanceA local MCP server that provides adversarial code review by having one frontier agent (Claude Code or Codex) critique code changes using the other agent (Codex or Claude Code) with full repository access, enabling a genuine second opinion on code and plans.14MIT