Navigation
Getting Started
Guides
Integrations
Guides
Create a Monitor
How to create HTTP, browser, and MCP monitors using the Web UI, CLI, or natural language.
Create a Monitor
Yorker supports three monitor types:
- HTTP — sends an HTTP request and asserts on the response (status code, body, headers, timing, SSL expiry, OpenAPI conformance).
- Browser — runs a real Chromium session, either against a URL (automatic Core Web Vitals + screenshots) or scripted with Playwright TypeScript.
- MCP — exercises a Model Context Protocol server over Streamable HTTP, validates the advertised tool list, and (optionally) calls tools with expected output.
There are three ways to create monitors: the Web UI, the CLI (monitoring as code), and natural-language generation.
Web UI
To create a monitor through the dashboard:
- Navigate to the dashboard and click Create Monitor.
- Select the monitor type (HTTP, Browser, or MCP).
- For HTTP monitors, fill in the URL, method, headers, authentication, and assertions.
- For browser monitors, choose URL mode (just a URL) or Scripted mode and write a Playwright TypeScript script in the built-in editor.
- For MCP monitors, enter the endpoint and optionally list expected tools and test calls.
- Choose check locations and frequency.
- Click Create.
CLI / Monitoring as Code
To manage monitors as code, define them in yorker.config.yaml and deploy with yorker deploy.
HTTP monitor
project: my-app
monitors:
- name: API Health
type: http
url: https://api.example.com/health
method: GET
frequency: 1m
locations:
- loc_us_east
- loc_eu_central
timeoutMs: 10000
followRedirects: true
headers:
Accept: application/json
labels:
- env:production
- service:api
assertions:
- type: status_code
operator: equals
value: 200
- type: response_time
max: 2000
- type: body_contains
value: '"status":"ok"'
- type: body_json_path
path: $.version
operator: exists
- type: header_value
header: content-type
operator: contains
value: application/json
- type: ssl_expiry
daysBeforeExpiry: 14HTTP authentication
Three auth types are supported. Add an auth block to any HTTP monitor:
# Basic auth
auth:
type: basic
username: "{{secrets.API_USER}}"
password: "{{secrets.API_PASS}}"
# Bearer token
auth:
type: bearer
token: "{{secrets.AUTH_TOKEN}}"
# API key header (defaults to X-API-Key)
auth:
type: api-key
header: X-API-Key
value: "{{secrets.API_KEY}}"Assertion types
| Type | Fields | Description |
|---|---|---|
status_code | operator (equals, not_equals, less_than, greater_than), value | Assert on HTTP status code. Operator defaults to equals. |
response_time | max | Fail if response takes longer than max milliseconds. |
body_contains | value | Fail if response body does not contain the string. |
body_matches | pattern | Fail if response body does not match the regex pattern. |
body_json_path | path, operator (equals, not_equals, contains, exists), value | Assert on a JSONPath expression. Operator defaults to equals. |
header_value | header, operator (equals, contains, exists), value | Assert on a response header. Operator defaults to equals. |
ssl_expiry | daysBeforeExpiry | Fail if SSL certificate expires within the given number of days. Defaults to 14. |
openapi_conformance | specId, operationPath (optional), validateHeaders (optional) | Validate the response against an OpenAPI spec registered in Yorker. See Assertions. |
See the Assertions reference for full details.
Browser monitor — URL mode
The simplest browser monitor: Yorker navigates to the URL, captures Core Web Vitals, takes screenshots, and runs assertions. No script to write.
URL-mode browser monitors are currently created via the Web UI or the REST API. yorker deploy is scripted-only for browser monitors — create URL-mode monitors from the dashboard, or via POST /api/checks with browserConfig.browserMode: "url". See the REST API reference.
Browser monitor — scripted mode
Scripted browser monitors run full Playwright TypeScript scripts. Reference the script file from your config:
monitors:
- name: Checkout Flow
type: browser
script: ./monitors/checkout.ts
frequency: 5m
locations:
- loc_us_east
viewport:
width: 1280
height: 720
screenshotMode: every_step
videoEnabled: falseThe script file (./monitors/checkout.ts) is a Playwright script body, not a full test file. The Yorker runner wraps your script in an async function and injects page and context (both standard Playwright objects) for you to use. That means:
- Do not write
import { test } from "@playwright/test"or any otherimport/requirestatements — the script has no module scope. - Do not wrap the code in
test(...)ordescribe(...)— Yorker doesn't run the Playwright test runner. - Do write the body of your check directly, referencing
page(aPage) andcontext(aBrowserContext) as if they were already in scope. - Do use
// @step: Namecomments to mark steps. Yorker captures a screenshot at each step (whenscreenshotMode: every_step) and surfaces step timing in the filmstrip view.
// @step: Go to shop
await page.goto("https://shop.example.com");
// @step: Add to cart
await page.click("text=Add to Cart");
// @step: Checkout
await page.click("text=Checkout");
await page.waitForSelector(".order-confirmation");Browser configuration options (scripted mode, YAML)
| Field | Default | Description |
|---|---|---|
script | (required) | Path to the Playwright TypeScript script file, relative to the config file. |
viewport | { width: 1280, height: 720 } | Browser viewport dimensions. |
device | (none) | Playwright device name for emulation (e.g., "iPhone 14"). |
screenshotMode | every_step | When to capture screenshots: every_step, failure_only, or disabled. |
videoEnabled | false | Whether to record video of the browser session. |
timeoutMs | 30000 | Maximum script execution time (5000-120000 ms). |
MCP monitor
MCP monitors check the health of a Model Context Protocol server over Streamable HTTP. On each run, Yorker:
- Connects to the
endpointand callstools/list. - Verifies every tool in
expectedToolsis present (if configured). - Runs each
testCallsentry: invokes the tool and checks the result containsexpectedOutputContains(if provided). - Optionally detects schema drift — tools that appeared, disappeared, or changed signatures since the last successful run.
monitors:
- name: Docs MCP Server
type: mcp
endpoint: https://mcp.example.com/sse
frequency: 5m
timeoutMs: 30000
locations:
- loc_us_east
auth:
type: bearer
token: "{{secrets.MCP_TOKEN}}"
expectedTools:
- search_docs
- fetch_page
testCalls:
- toolName: search_docs
arguments:
query: "pricing"
expectedOutputContains: "Plans"
detectSchemaDrift: trueMCP configuration options
| Field | Default | Description |
|---|---|---|
endpoint | (required) | Streamable HTTP endpoint URL of the MCP server. |
timeoutMs | 30000 | Request timeout (5000-120000 ms). |
auth | (none) | Same auth block shape as HTTP monitors (basic, bearer, api-key). |
expectedTools | (none) | Array of tool names that MUST be present. Missing tools fail the check. |
testCalls | (none) | Array of tool invocations to run. Each entry has toolName, optional arguments (plain object), and optional expectedOutputContains. |
detectSchemaDrift | true | Emit schema-drift events when the tool list or tool signatures change. |
Note: MCP monitors cannot be executed locally with
yorker test— deploy them and watch results viayorker results tailor the dashboard.
Labels
Attach labels to any monitor. Labels serve two purposes: filtering and grouping in the dashboard, and emission as OTel resource attributes so you can slice telemetry by label in your observability backend.
monitors:
- name: Payments API
type: http
url: https://api.example.com/payments
labels:
- env:production # key:value label
- service:payments
- critical # boolean label (becomes yorker.label.critical="true")Labels follow the convention [a-zA-Z0-9][a-zA-Z0-9_.:-]*, max 128 characters. Plain labels (no colon) emit as yorker.label.<name>="true". Key-value labels emit as yorker.label.<key>="<value>".
Omitting the labels field leaves labels unmanaged by config — the CLI preserves whatever labels exist on the remote. Setting labels: [] explicitly clears all labels.
Defaults and groups
To avoid repeating configuration across monitors, use defaults and groups.
Defaults apply to all monitors unless overridden:
defaults:
frequency: 5m
locations:
- loc_us_east
- loc_eu_central
http:
timeoutMs: 15000
followRedirects: true
assertions:
- type: status_code
value: 200
browser:
viewport:
width: 1280
height: 720
screenshotMode: every_stepGroups apply shared settings to a subset of monitors:
groups:
- name: API Endpoints
frequency: 1m
locations:
- loc_us_east
- loc_us_west
- loc_eu_central
monitors:
- name: Users API
type: http
url: https://api.example.com/users
- name: Orders API
type: http
url: https://api.example.com/ordersThe cascade order is: defaults -> group -> monitor. Each level overrides the previous.
Per-monitor assertions replace defaults entirely (they do not merge). To clear inherited assertions, set assertions: [] on the monitor.
Frequency format
Frequencies use a shorthand: 30s (seconds), 5m (minutes), 1h (hours). Valid range: 10 seconds to 24 hours.
CLI imperative commands
For quick one-off monitors, use the monitors commands instead of a config file:
Create a monitor
yorker monitors create --name "API Health" --type http --url https://api.example.com/health --frequency 1mList monitors
yorker monitors list
yorker monitors list --type http --status enabledView monitor details
yorker monitors get "API Health"Edit, pause, and resume
yorker monitors edit "API Health" --frequency 30s --add-location loc_eu_central
yorker monitors pause "API Health"
yorker monitors resume "API Health"Delete a monitor
yorker monitors delete "Old Endpoint" --yesSee the CLI reference for the full list of monitor commands and flags.
Natural language
To create a monitor using natural language, use either the Web UI or the API.
Web UI: Click Describe in plain English on the create monitor page and type a description like "Monitor our checkout flow every 2 minutes from US and EU, alert if it takes longer than 3 seconds." Yorker generates a Playwright script you can edit before saving.
API: Send a POST request to /api/checks/generate with a description. The endpoint returns a generated Playwright script you can review, optionally refine, and save as a browser monitor:
curl -X POST https://app.yorkermonitoring.com/api/checks/generate \
-H "Authorization: Bearer $YORKER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"description": "Navigate to https://shop.example.com, add the first product to cart, and verify the cart shows it.",
"targetUrl": "https://shop.example.com"
}'You can also pass previousScript and refinement to iteratively improve an existing script. See the REST API reference.
Generate HTTP checks from an OpenAPI spec
/api/checks/generate also accepts a spec field. Pass an existing spec ID, an OpenAPI URL Yorker should fetch, or the name of a spec already on your team — Yorker creates one HTTP check per operation, skips operations that already have a check, and returns the full list. This is the API equivalent of the spec import flow:
curl -X POST https://app.yorkermonitoring.com/api/checks/generate \
-H "Authorization: Bearer $YORKER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"spec": { "source": "url", "specUrl": "https://api.example.com/openapi.json" },
"locations": ["us-east", "eu-west"],
"frequencySeconds": 300
}'The spec field is a discriminated union: pass {"source": "id", "specId": "spec_..."} to use an existing spec, {"source": "url", "specUrl": "https://..."} to fetch and (if needed) import a new one, or {"source": "name", "specName": "..."} to look up by name. If the spec yields more than 50 new operations the first call returns 409 with requiresConfirmation: true — re-submit with "confirm": true to proceed. See the Generate Checks From OpenAPI Spec reference for the full request/response shape and error codes.