Skip to main content

MCP Playbooks

Paste-ready prompts for common workflows in Claude Desktop. Each playbook is a single message — copy it, fill in the bracketed values, send. Claude chains the MCP tools itself; you don't compose the calls.

These are tested against the live demo project (User Management Platform, id=2) and the User Service application. Substitute your own project/environment/application names as needed — MCP resolves both names and ids.

1. Crawl an application's UI

Discover pages and interactive elements on a target. Output is a structured inventory the LLM can consume to compose UI tests, not a saved test.

HtmlUnit (default — fast, server-rendered apps)

Crawl the Portn_Web_Store_UI target in project 20, development
environment. Use depth 2, max 50 URLs. Show me the page → element
inventory grouped by page title.

Playwright (slower — for SPAs / React / heavy JS)

Crawl the same target with engine=PLAYWRIGHT.
crawl_by_target(target="Portn_Web_Store_UI", project=20,
environment="development", engine="PLAYWRIGHT", max_depth=2, max_urls=50)

Choose Playwright if the app uses Next.js / React / Vue / Angular or renders content asynchronously. Choose HtmlUnit for server-rendered pages and Java apps — it's ~10x faster.

The scan-detail page in the UI labels the run Playwright Crawler or HtmlUnit Crawler so you can confirm which engine ran.

2. Generate a CRUD scenario from Swagger

The fastest path: hand Claude the swagger URL, let it parse and compose the lifecycle.

Create an API scenario from the swagger of the User Service API
application in the User Management Platform project, development
environment. Full CRUD lifecycle: list → create (extract userId) →
read → update → verify update → delete → verify 404.

Use {{baseUrl}} for the host and {{username}}/{{password}} for the
env-bound credentials so it stays portable. Tag it:
mcp-demo, user-service, crud, claude-authored.

Claude calls parse_swagger to read the spec, then create_scenario_from_swagger or create_scenario_from_yaml. The save endpoint runs validation first (see save-time validation below) so a typo in {{userId}} fails before persistence.

Prefer the digest for authoring (release#298). parse_swagger(mode="digest", level="minimal"|"standard") returns a compact, author-focused API digest (~12–25× fewer tokens than the raw dump): endpoints + required body fields + success codes + idPath + a pre-computed flows.crud lifecycle; standard adds field types (reqTypes) and response keys (res) for assertions. Server-set fields (id/createdAt/…) and fault/health endpoints are dropped. Author the CRUD scenario straight from flows.crud — no need to hold the raw spec in context.

parse_swagger(url="...", mode="digest", level="standard", app_tag="user-service")

3. Author a portable scenario by hand

When the swagger isn't available or you want a hand-tuned shape, write the YAML directly. The variable-resolution rules are documented under Variable Resolution.

Save this scenario in project 2, environment 1, then run it:

create_scenario_from_yaml(project=2, environment=1, yaml_text="""
name: "User Service — Bearer CRUD (portable)"
baseUrl: "{{baseUrl}}"
appTag: "user-service-api"
tags: [mcp-demo, user-service, crud, env-bound]

auth:
type: BEARER
loginEndpoint: /auth/login
tokenPath: $.accessToken
username: "{{username}}"
password: "{{password}}"

steps:
- name: Create user
method: POST
path: /api/users
body:
username: testuser_crud
email: crud@proofarc.ai
password: Test123!
role: USER
expect: [201]
extract:
userId: $.id

- name: Read created user
method: GET
path: /api/users/{{userId}}
expect: [200]
assert:
- path: $.username
equals: testuser_crud

- name: Delete user
method: DELETE
path: /api/users/{{userId}}
expect: [200]
""")

Then execute_scenario(scenario=<new id>, environment=1, wait=true,
summarize=true) and tell me which steps passed.

{{baseUrl}}, {{username}}, {{password}}, {{token}} are built-in env-bound — the platform seeds them from the env target + credential vault before step 1. {{userId}} is extracted from step 1's response and reused in step 2 + 3.

4. Save-time validation fails loudly

The save endpoint refuses any scenario referencing a {{name}} with no source — typos, forward refs, copy-paste residue. Try it:

Try to save this scenario — I expect it to fail:

create_scenario_from_yaml(project=2, environment=1, yaml_text="""
name: r159 negative test
baseUrl: "{{baseUrl}}"
steps:
- name: Create
method: POST
path: /api/users
body:
username: "{{notSeeded}}"
expect: [201]
""")

Expected: 400 with errors naming notSeeded and listing the known sources (baseUrl, username, password, token, apiKey, target) so the typo is obvious.

5. Diagnose an execution that failed mid-chain

The last execution of scenario {id} failed. Pull the full step results
and tell me which step failed, what the request URL/body looked like,
and what the response was. If it's a variable-resolution error, also
show variablesSnapshot.

get_execution_status(execution_id=<id>, kind="api_scenario")

If you see an Unresolved template variable {{X}} error, the runtime survivor check caught a placeholder that reached substitution with no value. The error message lists Available variables — compare against the YAML to spot the broken upstream (failed extract, missing hook output, wrong credential tag).

6. Run by tag across environments

When you have many scenarios sharing a tag (e.g. smoke-v1.0) and want to fan them out at once:

Run all scenarios tagged `smoke-v1.0` in project 2 against the staging
environment.

run_by_tag(tags=["smoke-v1.0"], project=2, environment="staging",
kinds=["api"], dry_run=false)

Use dry_run=true first to see what would execute without spending the runs.

7. Performance test from an existing scenario

Convert scenario {id} into a performance test with 20 virtual users
for 60 seconds against staging. Use p95 = 500ms threshold.

create_performance_scenario(name="User Service load — staging",
project=2, environment="staging", base_url="{{baseUrl}}",
test_type="LOAD", p95_threshold_ms=500, application="User Service API")

Then run_performance_scenario(scenario=<id>, environment="staging",
tags=["perf-baseline"]).

8. Mobile test from a real device

Inspect the SauceLabs demo app (mobileAppId=1) on the connected
emulator with crawl_mode=true, depth=3. After it finishes, show me
the discovered elements grouped by screen, then propose a login test
YAML using accessibility selectors.

9. Instantiate a stored playbook template (fill-in-the-blank)

A playbook is a stored, vetted recipe (find_playbooksget_playbook). Beyond its guided beats, a playbook can also carry a blank artifact template — a scenario YAML skeleton with two kinds of placeholder:

  • ${key}author-time blanks, filled once when you instantiate (e.g. ${appTag}user-service).
  • {{var}}runtime vars, left untouched and resolved at execute time (e.g. {{baseUrl}}). The two are kept strictly separate.

Available templates (live)

find_playbooks returns these stored templates. The category is the stable contract; the id is what instantiate_playbook takes — but ids shift as templates are added, so resolve the id via find_playbooks rather than hardcoding it:

idCategoryName
1CONTRACT_ANCHORContract Anchor — Swagger → contract scenario
10CONTRACT_ANCHORContract Anchor — Create → Update → Verify → Delete
4UI_FLOWUI Flow — crawl → compose → run on both engines
5PERF_FROM_APIPerformance from API — contract scenario → load test with SLOs
8DATA_DRIVENData-Driven User Creation — valid + invalid input cases
9DATA_DRIVENData-Driven User Creation — 20-case input validation matrix

The contract test is CONTRACT_ANCHOR (id 1)not id 9. Id 9 is DATA_DRIVEN. (These are the instantiable templates; the conceptual flows on AI Playbooks → overview are a higher-level narrative, not the same thing.)

Fill the blanks and create a runnable scenario in one call:

Find the contract-test playbook, then instantiate it for the User Service API.

find_playbooks(intent="contract test for an API") # note the id
instantiate_playbook(playbook=<id>, project="User Management Platform",
environment="development",
values={"flowName": "User CRUD", "appTag": "user-service",
"credentialTag": "default", "collectionPath": "/api/users",
"createBody": "{\"username\":\"t\",\"email\":\"t@x.io\"}"},
run_immediately=true)

Supply every ${...} blank, not just the ones a prompt mentions. A CONTRACT_ANCHOR template, for example, needs credentialTag, collectionPath, and createBody in values (plus appTag/flowName). Anything missing without a default returns a MISSING_VALUES failure naming the field — call get_playbook(<id>) to see them all.

The platform fills every ${...} from values (overlaid on the playbook's parameter defaults), leaves {{...}} for run time, validates, and creates the scenario through the normal path — so the appTag guard and type-aware app binding apply. Pass dry_run=true to preview the filled YAML without creating.

Missing a blank? If a ${key} has no value and no default, instantiate fails fast and names it (same style as the appTag guard): "Missing required template values for: appTag (API target tag) …". Call get_playbook(<id>) to read each blank's prompt, then supply it in values.

Authoring the template itself (admin): create_playbook(..., template="<YAML skeleton>"); get_playbook returns it as artifactTemplate. Filled artifacts are never stored — only the blank template.

Best-practice cheat sheet

WantUseDon't use
Portable scenario across environments{{baseUrl}}, {{username}}, {{password}} + appTagHardcoded https://staging.example.com
Chain a value from one step to the nextextract: { userId: $.id } then {{userId}}Recompute / duplicate the value
Run the same scenario in dev + staging + prodSame scenario, vary environment= on executeThree near-identical scenarios
Catch a typo before savevalidate_scenario_yaml (now also runs automatically on save)Save and debug at run time
See what variables are in scope at failure timeget_execution_status(...).variablesSnapshotGuess from the YAML
Get a clickable UI link to a runscanUrl from execute_scenario / get_execution_status (release#297)Quote the integer executionId and hunt for it in the UI