dánwòdánwò

Coding agents

MCP tools

Every tool, resource and prompt danwo's MCP server gives a coding agent, and what each is for.

danwo's MCP server is what your agent calls to work with your project. Start it with npx @danwo/cli mcp; Set up your agent registers it for you. This page lists everything it offers.

Run and explain tests

The tools an agent uses most. They work on the project's tests as danwo test would:

ToolWhat it does
list_testsLists the tests by file, with skip/only, and whether each has an invariant.
run_testsRuns all tests, or some by file, grep or name, and reports each failure's step, error and record.
run_matrixRuns the fault matrix on one test: a clean run, then a run per fault, judged.
show_runExplains a recorded run: the error, the steps, console errors, provider calls and webhooks.
read_screenshotReturns a screenshot from a flight record: the screen at failure, or after a step.
scaffold_testWrites a new *.danwo.ts file: the page it opens, its steps, and an invariant stub.
inspect_pageOpens one page of your app through the project's environment and returns its accessibility tree and its calls.

Pass format: "md" to show_run to get the same failure page danwo show --format md prints.

Drive the app step by step

A session is your app opened in danwo's browser, with its emulators and proxy, for the agent to explore before it writes a test. Every action answers with the page as it is now:

ToolWhat it does
open_session, close_sessionStarts the app, emulators and browser (or a device), or stops them.
navigateGoes to a path or URL, or back, forward, reload.
click, hover, fill, press, select, checkActs on an element, by a ref from the last snapshot or by a locator.
fill_secretFills a field with a configured secret by name. The value never appears anywhere.
uploadPuts files into a file input, or the file picker a button opens. Up to 10 MB a call.
dragDrags an element (target) and drops it on another (to), such as a card onto a column.
tabs, switch_tab, close_tabLists the open tabs, moves actions to another, or closes one.
dialogAnswers the alert, confirm or prompt the page has open: OK or Cancel, with text for a prompt.
snapshot, screenshotThe page as an accessibility tree with refs, or as an image with secrets masked.
check_locatorChecks a locator matches exactly one element, and returns the line to paste.
start_recording, stop_recordingRecords the session's screenshots, and video when no secret was filled.

Find an element inside another

A target is a ref from the last snapshot, or a locator as a test writes it. When one locator matches several elements, chain it inside the part of the page that holds the one you want:

target · fragment
getByRole("region", { name: "Cart" }).getByRole("button", { name: "Remove" })

A chain can also narrow what it found:

LinkWhat it keeps
.getBy…(…)Matches inside each element so far.
.filter({ hasText: … })The elements that contain this text.
.first(), .last()The first or last element.
.nth(n)The element at index n, from 0.

check_locator takes chains too. When a chain matches nothing, it names the first link after which nothing matched, so you know which part to fix.

Click with keys held, twice or with the right button

click takes three options beyond its target:

OptionWhat it doesDefault
modifiersKeys held during the click: Shift, Alt, Meta, Control.none
buttonright opens a context menu; middle is the wheel button."left"
doubletrue double-clicks, such as to edit a cell or select a word.false

ControlOrMeta is Meta on macOS and Control elsewhere. Use it to add an item to a selection or open a link in a new tab, so the same step works on every machine.

Follow a new tab

When the app opens a tab, such as a popup or a link to a new window, actions go to it straight away. The answer says so:

clicked screen.getByRole("link", { name: "Open receipt" })
tab: 2 of 2 (actions now go to it)
url: http://localhost:3000/receipt/42

tabs lists every open tab by number. switch_tab moves back to one, and close_tab closes one, or the active tab without a number. When the active tab closes, the newest one left takes over.

Answer a dialog

A dialog is the box alert, confirm or prompt opens. It blocks the page until someone answers it, so danwo holds it open and the answer tells your agent:

a confirm dialog is open: "Empty the basket?"
the page waits for an answer: dialog with accept: true (OK) or false (Cancel)

Call dialog with accept: true for OK or false for Cancel.

Add text to type into a prompt; without it, the prompt keeps its default. The click that opened the dialog then finishes, and the answer shows what changed. Until then, every other page tool says the dialog is open.

Upload a file

upload takes a list of files. Give each one in whichever form you have it:

FormWhat it is
{ path }A file in your project, relative to the project folder.
{ file }A file your config offers tests by name, under files.
{ name, text }A file the agent writes on the spot, such as a small CSV.
{ name, base64 }Any other bytes, such as an image.
upload · arguments
{
  "session": "s1",
  "target": "getByLabel(\"Receipt\")",
  "files": [{ "path": "fixtures/receipt.pdf" }, { "name": "notes.csv", "text": "item,qty\noats,2" }]
}

A test uploads by name only, so a recording never holds a path. Add the file under files in danwo.config.ts, then call setInputFiles("receipt"). An empty list clears the input.

Drive a mobile app

A device session drives your app on the Android emulator or iOS Simulator your config's environment sets up, in place of a browser. Open one with device: true:

open_session · arguments
{ "device": true }

The app starts afresh, and the answer is its screen. It reads like a page's tree, with a line that says what is in front:

session s1 is open.
device: iOS Simulator
in front: the app com.danwo.shopmobile

- heading "Danwo Shop" [ref=e2]
- text "Credits: 0" [testId=credits] [ref=e3]
- button "Buy 500 credits" [testId=buy] [ref=e4]

The same tools work, the way a person uses a phone:

ToolOn a device
clickTaps the element.
fill, fill_secretTypes into a field, replacing what it holds.
checkTaps a switch or checkbox, unless it already shows that state.
pressTaps the target, then presses the key. iOS has Enter only.
navigateOpens a path by the app's link scheme, a full URL, or goes back.
backGoes back: Android's Back button, or the screen's back control.
scrollScrolls the screen, or one list, up, down, left or right.
swipeSwipes a finger across the screen or an element, for duration_ms.
long_pressPresses and holds an element.
dismiss_keyboardPuts the on-screen keyboard away.
tap_atTaps a point, in screenshot pixels, for what the tree can't show.
screenshotThe screen, with password and secret fields painted over.
snapshot, check_locatorThe screen's tree, and locators checked against it.

Locators take the same chains as on a page. Tools only a browser has, such as hover or drag, answer with an error that says so. When the app opens a browser, such as a checkout page, the answer's in front line names it and its URL.

Before each action, danwo reads the screen again. If the element a ref names has moved or gone, nothing is tapped: the answer says so and shows the screen as it is now, with fresh refs.

Look behind the app

These show what the app did at its providers during a session. They're how an agent finds the right invariant:

ToolWhat it does
exchangesThe calls the app and browser made through danwo's proxy since the last look.
deliver_webhooksDelivers the webhooks the emulators have queued, then lists the deliveries.
emulator_stateWhat each emulated service holds now: Stripe objects, sent mail, Slack messages, S3 objects.
inject_faultArms one fault, named as the matrix names it, to fire on the next matching call or delivery.
clear_faultsDisarms the faults that haven't fired yet.

Resources and the prompt

The server also offers resources your agent can read, and one prompt:

NameWhat it is
danwo://configWhere tests live, how the app runs, the model, and your secrets' names.
danwo://runs/latestThe newest run, with its failures explained.
danwo://specEvery API, option, fault label and error code, generated from danwo's code.
danwo://guide/<topic>A task guide, such as first-test, matrix or debugging.
write-danwo-testA prompt: inspect the app, scaffold a test, run it and fix it until it passes.

Secrets stay hidden from the agent everywhere: answers, screenshots, recordings and records are all redacted. A video can't mask a typed secret, so start_recording refuses video once one is filled.

Next

On this page

Run it on every pull request

A GitHub check and one comment per pull request, with the flight records attached.

Set up CI