Skip to main content
Glama

dsh-verify

中文 | English

Witness — The browser is the judge. The quality gate for agent-built web apps. Agents say done; the browser proves it. (Witness is the product name; dsh-verify is the package name — same thing.)

ci npm MCP server awesome-dsh-plugin GitHub stars self-acceptance

If Witness catches something for you, ⭐ star the repo — it's how this project stays alive.

You asked an AI to build a web app. It said "done." Does it actually work?

dsh-verify opens a real browser and checks — so you never have to take the agent's word for it.

dsh-verify — Agents say done. The browser proves it.

dsh-verify in action

The quality gate for agent-built web apps. Works with any agent — DeepSeek Harness (dsh), Claude Code, Cursor, Copilot, Codex — and with any CI. You write what a human would check in a browser; a real browser executes it and returns a PASS/FAIL verdict with receipts (screenshots + diff images).

No LLM judges the outcome. The browser is the judge.

Same task, same AI, two builds — only a real browser tells the difference

Same task. Same AI. Two builds. One missing CSS rule — the agent's self-review passed, a real browser caught it.


Why this exists

We ran a 4-agent web team (spec writer → frontend dev → QA → reviewer). Their own review said:

✅ "All requirements met. No issues found."

In a real browser, the dark-mode toggle did nothing — the .dark class was toggled, but the CSS rule was never written. Every agent self-test passed because there was nothing in the page for the agents to run. No one opened a real browser.

That's the gap: agents verify against what they believe they built, not against what a user actually experiences. Unit tests and static checks can't catch a missing CSS rule.

Build

What the agents said

What a real browser says

demo/buggy

"No issues found"

FAIL — background never changes

demo/fixed

one CSS rule added

PASS — theme flips

Same page. Same JS. One missing CSS rule. Two different verdicts.

Related MCP server: Mochi

Why not just ...?

What you might reach for

Its blind spot

What dsh-verify adds

Hand-rolled Playwright scripts

Every agent project re-writes the same boilerplate; nothing is reviewable as a spec

A JSON spec is the whole contract — write once, reuse across agents and CI

LLM judges (promptfoo-style evals)

An LLM says "looks right" — it doesn't run the app or see the pixels

A real browser executes clicks, inputs, styles, and returns screenshot receipts

Agent built-in browser tools

They're the agent's hands — they share the same blind spots as the code they just wrote

dsh-verify is an independent witness, not part of the agent being tested

Screenshot-only visual tools

They catch pixel drift, not "button does nothing"

Behavior checks: click, expect text/class/style change, console errors, network errors

The agent graded its own homework. dsh-verify re-grades it in a real browser.

Use it three ways

Entry point

What it's for

One-liner

MCP server

Your AI agent verifies its own deliverable, mid-session

claude mcp add dsh-verify -- npx -y -p dsh-verify dsh-verify-mcp

CLI

You or your CI verify a build/URL

npx dsh-verify --spec demo/fixed.json

GitHub Action

Every push runs real-browser checks

uses: 263311487-ux/dsh-verify/.github/actions/dsh-verify@main

From any AI agent (MCP)

claude mcp add dsh-verify -- npx -y -p dsh-verify dsh-verify-mcp

Then tell your agent, in plain words:

Verify http://localhost:3000 — click #dark-toggle, then check body background-color changed. Screenshot it.

Tools exposed: verify_spec (run a spec JSON), verify_url (inline checks, no files), generate_and_verify (the AI drafts the checklist, real Chromium executes it), health.

In CI (GitHub Action)

- uses: 263311487-ux/dsh-verify/.github/actions/dsh-verify@main
  with:
    spec: demo/fixed.json       # spec file or glob
    # url: https://staging.example.com   # optional override
    # out: dsh-verify-out               # report output dir (default)

The repo dogfoods it: the dogfood workflow asserts the fixed build passes and the buggy build fails on every push.

On the command line

npm install -g dsh-verify          # or: npx dsh-verify
npx playwright install chromium    # one-time browser download
npx dsh-verify --spec 'specs/*.json'
# [PASS] specs/home.json (5/5)
# [FAIL] specs/cart.json (4/5)
#   ❌ expect_text #total: got "0" want "99"

What's in the box

  • Deterministic judge — a real headless Chromium (or Firefox / WebKit) executes human-style checks: click, fill, text, classes, computed styles, URLs, console errors, network errors, pixels.

  • Receipts, not vibes — every run emits a self-contained HTML report with screenshots and red-highlighted diff images; --json for machines; exit 0/1 for CI.

  • Visual regression — screenshot baselines, pixel-diff with thresholds (expect_screenshot), refresh with --update-baselines.

  • AI-drafted checklistsdsh-verify gen --url ... --prompt "..." learns the page in a real browser, has an LLM draft the checklist, then executes it deterministically. The AI drafts; it never judges.

  • Multi-browserchromium | firefox | webkit per spec or --browser.

  • Zero framework lock-in — a JSON spec is all there is. No config language, no SDK, no vendor.

Example spec

{
  "title": "my app",
  "serve": "dist",
  "browser": "chromium",
  "steps": [
    { "action": "goto", "path": "/index.html" },
    { "action": "click", "selector": "#count-btn", "count": 3 },
    { "action": "expect_text", "selector": "#count-btn", "text": "Clicked: 3" },
    { "action": "capture_style", "selector": "#page", "prop": "backgroundColor", "var": "bg_before" },
    { "action": "click", "selector": "#color-btn" },
    { "action": "expect_class", "selector": "#page", "class": "dark", "present": true },
    { "action": "expect_style_changed", "selector": "#page", "prop": "backgroundColor", "var": "bg_before" },
    { "action": "screenshot", "name": "final-state" }
  ]
}

Top-level fields: title, serve (static dir) or base (target URL), browser, steps. Run many at once with a glob; exit is 0 only if all pass.

The report

A self-contained HTML report — every step with a pass/fail badge, selector, and detail, plus screenshots:

dsh-verify report

Agent Arena — bring your agent

Real-browser benchmark for agent-built web apps: same 3 tasks, same human checks, open entry. Run your model on the board in ~10 minutes:

git clone https://github.com/263311487-ux/dsh-verify && cd dsh-verify
npm install && npx playwright install chromium
export LLM_API_KEY=sk-...          # any OpenAI-compatible model
node arena/run.mjs --agent "gpt-5/single" --task all --repeat 1 --submitter yourname

Your setup appears on the live leaderboard next to DeepSeek v4-flash / v4-pro: agent-arena. Full rules in docs/ARENA.md.

Prove it (run it yourself)

git clone https://github.com/263311487-ux/dsh-verify && cd dsh-verify
npm install && npx playwright install chromium
npm run demo:fixed    # → PASS (11/11)
npm run demo:buggy    # → FAIL (exit 1) — the missing .dark rule, caught
npm test              # engine self-tests

The repo's own CI runs exactly that — engine self-tests, then asserts fixed passes and buggy fails — so the tool verifies itself on every push.

Agent Arena — can agents ship working web apps?

Same task, same prompt, same human checks — different agents, graded by dsh-verify in a real browser. Latest run (2026-08-19): 44/48 runs passed across 2 models × 2 strategies × 3 tasks, 4 runs per cell. Two counterintuitive findings: the pricier v4-pro single-shot scored below the cheaper v4-flash single-shot (10/12 vs 11/12), and a real-browser self-check loop lifted v4-pro to 12/12 — while v4-flash's self-check crashed once when its own verification report came back as corrupt JSON. Every failure is reproducible and invisible to an LLM judge.

Agent Arena

See docs/ARENA.md — methodology, the tasks, and how to run your own agent.

Badge your agent-built app

Built something with an AI agent? Prove it in a real browser and show the world:

[![agent deliverable: browser-verified](https://img.shields.io/badge/agent_deliverable-browser_verified-brightgreen?logo=playwright&logoColor=white)](https://github.com/263311487-ux/dsh-verify)

Add a spec, wire the GitHub Action, and the badge is earned, not claimed. See docs/verified-badge.md.

Roadmap

  • MCP server · AI-drafted checklists · visual regression · multi-browser · GitHub Action · dsh plugin

  • Agent arena — a public benchmark: give the same task to different agent setups, grade them in real browsers, publish the leaderboard

  • Spec recorder (browser extension: click through once → spec generated)

  • Cloud runs + shareable report links + PR comments

  • dsh-doublecheck — delivery quality gate for DeepSeek Harness (/gate): requirements grill + evidence discipline. Complementary pair: /gate keeps the evidence honest, dsh-verify keeps the browser honest.

  • falsify — the scientific thinking protocol for AI agents (hypothesis → falsify → evidence → calibrated conclusion). The pair: falsify catches the wrong conclusion, dsh-verify catches the broken output.

  • Featured in the DeepSeek Harness community — Show Your Plugins: dsh-verify (48-run Agent Arena results in-thread)

License

MIT

Available Tools

4 tools
generate_and_verifyA

AI-drafts an acceptance checklist for a URL (LLM writes it, a real browser executes it), then immediately runs it in real Chromium. Pass requirements as a plain-language description of what a human QA should verify (e.g. "dark-mode toggle changes the background color"). Requires DEEPSEEK_API_KEY or OPENAI_API_KEY in the server environment. Returns the drafted spec path plus the PASS/FAIL verdict, per-step results and report path.

ParametersJSON Schema
NameRequiredDescriptionDefault
outNoOutput dir for spec + report (default: ./dsh-verify-out)
urlYesTarget URL to verify
modelNoLLM model (default: deepseek-v4-flash)
headedNoRun with a visible browser (debug only)
requirementsNoPlain-language QA requirements (optional)

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and uses it well: it reveals that an LLM drafts the spec, that it runs in a real browser (implying actual page interaction), and that API keys are required. It also states the output artifacts. It doesn't mention potential side effects on the target URL, but the 'real browser' clause provides transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each with a distinct role: core action, user input guidance, prerequisite, and return values. No redundancy or extraneous details; the most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description adequately bridges the gap by enumerating the return values: spec path, PASS/FAIL verdict, per-step results, and report path. It also covers prerequisites and usage context, making it complete for the tool's moderate complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes beyond by providing an example for the 'requirements' parameter ('dark-mode toggle changes the background color') and tying the 'out' parameter to both spec and report paths, which adds meaning not fully spelled out in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'AI-drafts an acceptance checklist... then immediately runs it in real Chromium', which specifies the verbs (drafts and runs) and resource (acceptance checklist for a URL). This clearly distinguishes it from siblings like verify_spec and verify_url by highlighting the generation step before verification.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit context for use: pass requirements in plain language as QA criteria, and it notes the prerequisite of DEEPSEEK_API_KEY or OPENAI_API_KEY. However, it does not explicitly state when to use this tool instead of verify_spec or verify_url, so it earns a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

healthA

Check that the dsh-verify MCP server and its Chromium browser are ready to run verifications.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. While it states the purpose, it does not disclose whether the check is read-only, what the result looks like, or what happens if components are not ready. For a health check, this is a notable gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that is concise and free of filler. It communicates the essential purpose without wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 0-parameter tool, the description covers the main purpose but omits the expected response or how to interpret the check result. Since there is no output schema, adding a brief note about the return value would make it more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so schema coverage is complete. No parameter documentation is needed, and the baseline of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool checks the readiness of the dsh-verify MCP server and its Chromium browser. The verb 'check' and the specific resource distinguish it from sibling tools that actually run verifications.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is a pre-flight check before running verifications ('ready to run verifications'), but it does not explicitly state when to use this tool versus the verification siblings, nor does it provide exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_specA

Run a dsh-verify acceptance spec (JSON file, or glob) against a real headless Chromium. The spec may serve a local static dir (spec.serve) or target any URL (spec.base / step.url). Returns PASS/FAIL with per-step results and a self-contained HTML report path. Exit-code semantics: ok=true means every step passed. This is deterministic — no LLM judges the outcome.

ParametersJSON Schema
NameRequiredDescriptionDefault
outNoOutput dir for report.html + screenshots (default: ./dsh-verify-out)
urlNoOptional target URL override (spec.base / step path ignored)
headedNoRun with a visible browser (debug only)
specPathYesPath to the spec JSON file or glob (e.g. specs/*.json)

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It explains that the tool is deterministic ('no LLM judges the outcome'), returns PASS/FAIL with per-step results and an HTML report, and defines exit-code semantics. It does not mention side effects like output directory creation or browser dependency, but these are partially inferable from the schema and tool nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four concise sentences with no fluff or repetition. It front-loads the core action and packs essential nuance about targets, outputs, and determinism into a compact space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has no output schema, but the description explicitly covers return values (PASS/FAIL with per-step results and HTML report) and exit-code semantics. All four parameters are documented in the schema, and the description adds behavior context. There are no significant gaps for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are well-documented in the schema. The description adds modest context by explaining spec structure (spec.serve, spec.base/step.url) and that specPath can be a glob, but it does not materially enhance parameter semantics beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Run a dsh-verify acceptance spec (JSON file, or glob) against a real headless Chromium.' This is a specific verb+resource pairing. It also distinguishes itself from siblings like verify_url by focusing on acceptance specs rather than single URLs, and from generate_and_verify by not mentioning any generation step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful context on when to use the tool, such as the ability to serve a local static dir or target any URL, implying it is for spec-driven verification. However, it does not explicitly state when to use an alternative like verify_url for simple URL checks, so it lacks direct when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_urlA

Verify a live URL against a list of human-style checks, driven by a real headless Chromium. Checks are dsh-verify steps: goto/click/fill/wait/expect_text/expect_class/capture_style/expect_style_changed/expect_url_contains/expect_navigation/expect_console_errors/expect_network_errors/screenshot. If no goto step is given, a goto to the url is prepended. Returns PASS/FAIL with per-step results and a self-contained HTML report path. Deterministic — no LLM judges the outcome.

ParametersJSON Schema
NameRequiredDescriptionDefault
outNoOutput dir for report.html + screenshots (default: ./dsh-verify-out)
urlYesTarget URL to open
checksYesHuman-style checks, e.g. [{action:"click",selector:"#dark-toggle"}, {action:"capture_style",selector:"body",prop:"backgroundColor",var:"bg"}, {action:"expect_style_changed",selector:"body",prop:"backgroundColor",var:"bg"}]
headedNoRun with a visible browser (debug only)

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully discloses key behaviors: it uses a real headless Chromium, lists all supported check steps, automatically prepends goto if missing, returns PASS/FAIL with per-step results and an HTML report, and emphasizes deterministic execution (no LLM judging). This goes far beyond a simple 'verify' statement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences long and extremely information-dense. It front-loads the core purpose and packs the check action list and output semantics into a compact, readable format with no irrelevant details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description clearly explains what the tool returns (PASS/FAIL, per-step results, HTML report path) and how it operates. It could mention potential side effects of click/fill actions or network dependencies, but the given detail is strong for a verification tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema describes all four parameters with 100% coverage, so the baseline is 3. The description adds operational context for the checks parameter (list of actions, prepending goto) and clarifies output behavior, but does not significantly augment the schema beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Verify') and resource ('a live URL') and elaborates on the method with a detailed list of check actions. It clearly distinguishes itself from siblings (health, verify_spec, generate_and_verify) by focusing on human-style browser-based verification of a live URL.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies when to use this tool: when you need to run human-style browser checks against a live URL. It does not explicitly mention alternatives or exclusions, but the context is unambiguous and sufficient for tool selection.

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. Dates show when Glama detected each change.

  1. 4 tool updatesv0.1.0
    • First observedgenerate_and_verify
    • First observedhealth
    • First observedverify_spec
    • First observedverify_url

TDQS

A4/5.0
Disambiguation4/5

The tools are mostly distinct: health checks readiness, verify_spec runs a spec file/glob, verify_url runs ad-hoc checks on a URL, and generate_and_verify combines AI drafting with execution. There is slight overlap between verify_spec and verify_url, but input types clearly differentiate them.

Naming Consistency3/5

Naming is mostly snake_case but inconsistent in style: health is a noun, verify_spec and verify_url follow verb_noun, while generate_and_verify is a compound verb phrase. The pattern is still readable but not uniform.

Tool Count5/5

With 4 tools, the server is well-scoped. Each tool serves a distinct purpose in the verification workflow: readiness check, spec execution, live URL verification, and AI-assisted generation, with no redundancy.

Completeness4/5

The domain of running headless Chromium verifications is well covered: health, spec-based execution, ad-hoc checks, and AI-drafted specs. Minor gaps include no standalone spec generation without execution and no spec management, but these are not critical for the core workflow.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

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/263311487-ux/dsh-verify'

If you have feedback or need assistance with the MCP directory API, please join our Discord server