Report the page your browser sees and get next steps
exploration.observeChanges dataCreates, updates or deletes something in your workspace.What it does
The core of the exploration loop. After every single browser action, send what the page looks like now (page: url, title, html and/or accessibility snapshot) and what you just did (performed). Then do exactly ONE of the returned nextActions in your browser and call observe again; repeat until coverage.done is true, then call exploration.finish. Returns: step (verified, urlChanged, domChanged, note) — a verified step is one the server could confirm from the page: you landed on the expected URL, or the page visibly changed after a click/submit/navigate/back, or new content appeared after a hover (fill, select, scroll and press are accepted as-is; a reported error is never verified). elements and forms with a stable locator for each element — a way to find it again that survives page reloads, preferring data-testid, then id, then role + accessible name, with stability 0–1 and ready Playwright code in locator.code. suggestedAssertions (checks that hold on this page), assertionResults (for expect), revealed (elements that appeared since the last observe). coverage — how much of the app you have seen: pagesVisited, pagesKnownUnvisited, unvisited (up to 20 URLs), stepsUsed, errors, budget, done, reason. nextActions — up to 8, ranked: unvisited links first, then form fills with sample values and submits, then menus to hover, then other buttons; each has actionId, kind, target, value, why. A "hover" action means hover it, then observe again so the menu that opens can be read. Only the user who started the session can observe it, and only while it is active.
Ask your agent
You don’t call exploration.observe yourself. Say something like this to Claude Code, Cursor or another MCP-connected agent:
- “Keep exploring the app and tell me what pages you find”
- “Log what this page looks like after I clicked Sign in”
- “Check that submitting the contact form shows a success message”
Inputs
| Name | Type | Description |
|---|---|---|
sessionIdrequired | string | The sessionId returned by exploration.start. |
pagerequired | object | What your browser shows right now. Shape: { "url": "https://app.example.com/login", "title": "Sign in", "html": "<html>…</html>" } (html and/or snapshot; html gives the richest analysis). |
performedoptional | object | The one action you just did in the browser, e.g. { "actionId": "a300", "kind": "click", "target": "role=link[name=\"Pricing\"]" }. Copy actionId, kind, target and value from the nextAction you followed; add error if it failed. Omit only on the very first observe after start (after opening the start URL). |
expectoptional | object[] | Up to 50 checks to judge against this page, typically right after a submit, e.g. [{ "type": "url-contains", "expected": "/dashboard" }, { "type": "element-visible", "selector": ".alert-success", "expected": true }]. Each comes back in assertionResults with passed and actual; failures are noted on the step. |
The MCP call
What the agent’s MCP client sends (placeholders in angle brackets):
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "exploration.observe",
"arguments": {
"sessionId": "<sessionId>",
"page": {
"url": "https://example.com"
}
}
}
}Connect your agent
npx -y @testmaze/mcp init tmt_xxx claude mcp add tm --scope project -- npx -y @testmaze/mcp
Create the token in your Test Maze workspace under Settings → MCP. Setup for Cursor, Cline, Gemini CLI and Codex CLI is shown there too.
More exploratory testing tools
- Start exploring a web app
exploration.start - Finish an exploration session
exploration.finish - Draft test cases from an exploration
exploration.to_cases - List exploration sessions
exploration.list - Show an exploration session in full
exploration.get