@sitelensapi/mcp
v0.1.27
Published
SiteLens MCP + CLI: real-browser verification and page intelligence for developers and AI agents—Local Chromium, flows, registry sync, optional Cloud/API; no Docker required
Downloads
3,653
Maintainers
Readme
SiteLens
SiteLens is real-browser verification and page intelligence for developers and AI agents.
Run structured QA and agent verification flows from .sitelens/flows, capture screenshots and artifacts, sync prompts and templates from the registry, and optionally use Page Intelligence and Cloud/API runs. Use SiteLens Local on your machine via this MCP package, Desktop, or QA Studio as needed.
This package (@sitelensapi/mcp) is the portable npm distribution: an MCP server for Cursor and other MCP hosts, plus a CLI for setup, registry sync, and diagnostics. Local runs use bundled Chromium on your machine—no Docker required.
Links: sitelensapi.com · MCP docs · QA Studio · Dashboard / MCP setup · npm @sitelensapi/mcp
Install
# One-shot bootstrap (recommended first run)
npx --yes @sitelensapi/mcp sitelens-mcp setup
# Or install globally
npm install -g @sitelensapi/mcpRequires Node.js 20+.
Quick start
1. Wire Cursor (local QA — no API key)
Add to ~/.cursor/mcp.json or your project .cursor/mcp.json:
{
"mcpServers": {
"sitelens": {
"command": "npx",
"args": ["-y", "@sitelensapi/mcp"],
"env": {
"SITELENS_MODE": "local",
"SITELENS_DEFAULT_URL": "http://127.0.0.1:3000"
}
}
}
}For local/dev HTTPS targets with self-signed or private CA certificates (e.g. https://app.local), also allow the host and bypass Playwright TLS checks:
{
"mcpServers": {
"sitelens": {
"command": "npx",
"args": ["-y", "@sitelensapi/mcp"],
"env": {
"SITELENS_LOCAL_ALLOWED_HOSTS": "app.local",
"SITELENS_LOCAL_IGNORE_HTTPS_ERRORS": "true"
}
}
}
}Restart Cursor after changing MCP env. Your normal browser may trust the cert; SiteLens local QA uses Playwright, which needs this flag for local/dev targets only.
Optional: on corporate machines where Chrome or Edge already trusts local certs, you may use the system browser instead of bundled Chromium:
{
"mcpServers": {
"sitelens": {
"command": "npx",
"args": ["-y", "@sitelensapi/mcp"],
"env": {
"SITELENS_LOCAL_ALLOWED_HOSTS": "app.local",
"SITELENS_LOCAL_IGNORE_HTTPS_ERRORS": "true",
"SITELENS_BROWSER_CHANNEL": "chrome"
}
}
}
}SITELENS_BROWSER_CHANNEL accepts chrome, msedge, or chromium (bundled default). When unset, SiteLens uses bundled Chromium. If you explicitly set chrome or msedge and that browser is missing, SiteLens reports a clear error — it does not silently fall back.
Restart Cursor, then ask: "Use SiteLens setup."
That runs the sitelens_setup MCP tool (bundled Chromium, writable dirs, API key presence only — never the key value).
2. Run local QA on your dev server
Ask Cursor:
"Run SiteLens local QA on http://localhost:3000 (desktop + mobile)."
That invokes sitelens_qa_run (alias sitelens_run_local_qa). Local QA does not require a SiteLens account or API key.
3. Check readiness from the terminal
npx --yes @sitelensapi/mcp sitelens-mcp -- --self-test
npx --yes @sitelensapi/mcp sitelens doctor
npx --yes @sitelensapi/mcp sitelens doctor --cursor4. Scaffold and run a project flow from the terminal
Create a starter flow JSON in your project (edit steps and URL afterward):
npx --yes @sitelensapi/mcp sitelens flow init homepage-smoke
# or: npx --yes @sitelensapi/mcp sitelens flow init --flow-id homepage-smoke --template smokeThen run it:
npx --yes @sitelensapi/mcp sitelens flow run \
--flow-id homepage-smoke \
--url http://127.0.0.1:3000/Same engine as MCP sitelens_run_local_flow — useful for CI and shell scripts without Cursor.
Current status
Verified against package implementation and tests (May 2026). See MCP docs — project flows for flow schema and step reference.
Supported now
| Capability | How to use |
|------------|------------|
| Ad-hoc local QA | MCP sitelens_qa_run / sitelens_run_local_qa (≤ 8 steps, no API key) |
| Project flows | JSON in .sitelens/flows/*.json + CLI sitelens flow run or MCP sitelens_run_local_flow (≤ 200 steps) |
| Flow discovery | sitelens doctor, --self-test, MCP sitelens_setup list flows dir |
| Local run artifacts | summary.json, report.md, screenshots/ under $TMPDIR/sitelens-mcp-local-qa |
| Local run history / compare | MCP sitelens_list_local_runs, sitelens_compare_local_runs |
| Saved auth profiles | ~/.sitelens/ + sitelens_auth_* tools |
| Local MCP resources | sitelens-local://runs/{localRunId}/… |
| CLI bootstrap / diagnostics | sitelens-mcp setup, --self-test, sitelens doctor |
| CLI flow scaffold | sitelens flow init --flow-id <id> [--template smoke] |
| CLI project flow runner | sitelens flow run --flow-id <id> --url <url> |
| Scenario Runner | JSON in .sitelens/scenarios/*.json + CLI sitelens run scenario or MCP sitelens_run_local_scenario (chained flows, shared session) |
| Remote content registry | sitelens registry sync — prompts, example flows, QA presets, scenario templates (optional) from sitelensapi.com/registry (no npm bump) |
| Cloud QA (optional) | SITELENS_API_KEY + sitelens_run_qa, sitelens_run_flow (cloud UUID flows) |
Consumer-repo verification: release smoke (pnpm run pack:smoke) installs a publish-shaped tarball in a temp project with .sitelens/flows/smoke-flow.json, runs --self-test and sitelens doctor, and confirms flow discovery. Unit tests cover flow load, MCP registration, and GET /flows/local.
Experimental
| Capability | Notes |
|------------|-------|
| Strict pixel screenshot diff | MCP sitelens_compare_local_runs with includeScreenshotDiff: true — RGBA equality, not perceptual |
| Local flow templates in ad-hoc QA | template presets on sitelens_qa_run (homepage-qa, basic-smoke, etc.) |
Internal only (not npm consumer surface)
| Capability | Notes |
|------------|-------|
| HTTP runtime sidecar | start:http-runtime — GET /flows/local, POST /flows/local/run, POST /runs/local for SiteLens Desktop |
| Desktop capture packs | Desktop runs project flows via HTTP when a capture step references a flowId — not the primary npm onboarding path |
| SITELENS_MCP_LOCAL_RUN_PLACEHOLDER | Dev/test flag — skips browser execution |
Planned / roadmap
| Capability | Notes |
|------------|-------|
| sitelens_local_doctor MCP tool | Targeted local connectivity diagnostics (hostname, allowlist, HTTPS ignore, browser channel, DNS/navigation) |
| Desktop “Run flow” UI | Desktop Project flows page runs .sitelens/flows from the app |
| QA Studio ↔ .sitelens/flows sync | Studio stores cloud UUID flows; repo JSON is separate |
| Cloud sync of local artifacts | Local bundles stay on disk (supportsCloudUpload: false) |
| Desktop visual compare viewer | MCP compare works; Desktop UI roadmap |
| Advanced cloud history in Desktop | In progress |
Project flows
Project flows are JSON files stored in .sitelens/flows/*.json in your project — not hand-written browser test files (*.spec.ts), not QA Studio cloud records, and not files inside the npm package install path.
Intended convention
your-app-repo/
.sitelens/
flows/
homepage-smoke.json ← flowId "homepage-smoke"
login-check.json ← flowId "login-check"
scenarios/
login-then-smoke-scenario.json ← scenarioId (see Scenario Runner)Auth and browser profiles (when using profile or authProfile) are stored under ~/.sitelens/ on your machine — not in the repo:
~/.sitelens/
auth/ ← Playwright storage-state JSON per profile name
profiles/ ← persistent browser profile dirs (cookies, localStorage)| Directory | Purpose |
|-----------|---------|
| .sitelens/flows/ | Single QA flows — one page or workflow step sequence each |
| .sitelens/scenarios/ | Chained orchestration — runs multiple flows in order with one shared browser session |
| ~/.sitelens/auth/ | Saved login state (storage-state auth mode) |
| ~/.sitelens/profiles/ | Persistent browser profiles (persistent-profile auth mode; default for scenarios) |
| Rule | Detail |
|------|--------|
| Location | <workspace>/.sitelens/flows/{flowId}.json |
| flowId | Lowercase slug: [a-z0-9][a-z0-9-]{0,63} (must match "id" inside the file) |
| Workspace | Resolved from SITELENS_WORKSPACE_DIR → CURSOR_PROJECT_DIR → VSCODE_CWD → process.cwd() |
| Schema | version: 1, required id, name, url, steps[] — validated by @sitelensapi/qa-smoke |
| Steps | Same vocabulary as SiteLens cloud saved flows (click, assert*, network waits, expectEither, etc.) |
| Step limits | File-backed: up to 200 steps. Ad-hoc sitelens_qa_run: 8 steps max |
Commit .sitelens/flows/ to git in your app repo so agents and CI can run the same smoke paths.
Starter flows (flow init)
Scaffold a valid flow file without hand-writing the full schema (via the sitelens bin from @sitelensapi/mcp):
npx --yes @sitelensapi/mcp sitelens flow init --flow-id homepage-smoke
npx --yes @sitelensapi/mcp sitelens flow init homepage-smoke --template smoke
npx --yes @sitelensapi/mcp sitelens flow init --flow-id screenshot-pack --template screenshotsAfter npm install -g @sitelensapi/mcp, you can use sitelens flow init … directly.
| Template | What you get |
|----------|----------------|
| smoke (default) | readySelector: body, document screenshot, minimal assertSelector, final-state screenshot step |
| screenshot | Explicit waitForSelector on body, assertions, final-state screenshot step, exportArtifacts |
| text-check | assertText placeholder plus final-state screenshot step — edit the expected string after init |
| login | Login form fill, before-submit / after-submit / after-login screenshot checkpoints |
| form-submit | Generic form fill/submit with before-submit / after-submit / final-state checkpoints |
Default URL in generated files is http://localhost:3000/ — change it in JSON or override at run time with --url. Existing files are not overwritten unless you pass --force.
Example flow file
{
"version": 1,
"id": "homepage-smoke",
"name": "Homepage Smoke",
"url": "http://127.0.0.1:3000/",
"viewports": ["desktop", "mobile"],
"screenshot": true,
"readySelector": "body",
"steps": [
{ "type": "assertSelector", "selector": "body", "state": "visible" },
{ "type": "assertText", "text": "Welcome" },
{ "type": "screenshot", "label": "final-state" }
]
}Use screenshot steps for labeled checkpoints during a flow (saved under the run artifact screenshots/ directory and returned in actionLog[].screenshot):
{ "type": "screenshot", "label": "after-login" }Common labels for investigations: before-submit, after-submit, after-login, final-state.
Legacy flow JSON may also use { "action": "screenshot", "label": "after-login" } — it normalizes to the same step.
Scaffold flows with checkpoints:
sitelens flow init login-smoke --template login
sitelens flow init checkout --template form-submit
sitelens flow init homepage-smoke --template smokeAgent guidance: evidence collection
When debugging UI, auth, or workflow issues with MCP or CLI:
- Call
sitelens_statusto confirm workspace and flow discovery. - Run flows/scenarios with
exportArtifacts: true(default for repo flows). - Add
{ "type": "screenshot", "label": "…" }steps at key moments — before/after submit, after login, final state. - Read
summary.actionLog[].screenshot.pathandsummary.screenshotPathsin the tool response; open PNGs under{artifactDir}/screenshots/. - For ad-hoc checks (≤8 steps), pass screenshot steps in
sitelens_qa_runactions/scenarioarrays.
Cursor prompt example: "Run sitelens_run_local_flow for auth-login-setup with export artifacts enabled. List every labeled screenshot path from actionLog."
Step reference: Project flows & local templates.
selectOption (native <select>)
Use selectOption when working with native HTML <select> dropdowns — especially when options are visually hidden or hard to click in headless mode. Playwright selects through the native element directly.
{
"type": "selectOption",
"selector": "select[name='status']",
"value": "active"
}Provide exactly one of value, label, or index. selector is required. Custom JavaScript dropdowns should still use click / press steps.
Tier 1 interactions
Target with exactly one of selector, testId, label, or role+name:
check/uncheck— checkbox state vialocator.check()/uncheck()setChecked—{ "checked": true \| false }vialocator.setChecked()clear— clear text inputs vialocator.clear()(file inputs blocked)hover— reveal menus/tooltips vialocator.hover()doubleClick—locator.dblclick()with the sameallowSubmitguard asclick
{ "type": "hover", "selector": "[data-testid='account-menu']" }
{ "type": "setChecked", "testId": "terms", "checked": true }Tier 2 interactions
uploadFile—locator.setInputFiles()on nativeinput[type=file]; requiresfiles(one or more paths)dragTo—locator.dragTo()withsourceandtargetendpoint objects (each uses one target ref style)focus/blur—locator.focus(); blur focuses first thenlocator.blur()scrollIntoView—locator.scrollIntoViewIfNeeded()
{ "type": "uploadFile", "label": "Attach CSV", "files": ["/tmp/report.csv"] }
{
"type": "dragTo",
"source": { "testId": "draggable-item" },
"target": { "testId": "drop-zone" }
}Browser storage
Safe localStorage / sessionStorage manipulation for authenticated or spoofed workflows — no arbitrary JavaScript. Mutations apply to the active page (no reload). Run results include actionLog[].storage with storage, operation, keysAffected, and pageUrl for each mutation step.
| Step | Behavior |
|------|----------|
| storage.set | Set a string value (setItem) |
| storage.remove | Remove one key or many keys |
| storage.clear | Clear all items in local or session storage |
| storage.assert | Assert key exists / exists: false or exact value |
{ "type": "storage.remove", "storage": "session", "key": "environmentConfig" }
{ "type": "storage.set", "storage": "local", "key": "featureFlag", "value": "enabled" }
{ "type": "storage.assert", "storage": "session", "key": "environmentConfig", "exists": false }Example smoke flow: .sitelens/flows/storage-smoke.json.
Project flows vs QA Studio vs cloud flows
These are three different storage/run paths that share step types:
| | Project flows (this package) | QA Studio / API |
|--|---------------------------|-----------------|
| Storage | .sitelens/flows/my-smoke.json in your repo | Postgres via sitelens-api |
| ID | String slug (my-smoke) | UUID |
| Run tool | CLI sitelens flow run or MCP sitelens_run_local_flow | MCP sitelens_run_flow or Studio UI |
| API key | Not required | Required |
| Browser | Your machine (bundled Chromium) | SiteLens cloud hosts |
| History | Local disk (sitelens_list_local_runs) | Cloud (sitelens_list_runs) |
QA Studio does not read or write .sitelens/flows/*.json today. Export/import between Studio and repo JSON is not implemented.
Run a project flow (CLI or MCP)
Project flows can run from the terminal or Cursor MCP — same load → execute path (loadLocalFlowDocument → localFlowToToolInput → executeLocalRunQa).
CLI (shell / CI)
npx --yes @sitelensapi/mcp sitelens flow run --flow-id homepage-smoke --url http://127.0.0.1:3000/
npx --yes @sitelensapi/mcp sitelens flow run --flow-id login-flow --url http://localhost:3000 --viewport desktop --json--flow-id→.sitelens/flows/{flowId}.jsonin your workspace.--urlis required (overrides or supplements the file’surl).- Optional:
--viewport,--output,--json,--auth-profile,--auth-mode,--browser. - Prerequisites: dev server on
url,sitelens-mcp setupcompleted, cwd (orSITELENS_WORKSPACE_DIR) pointing at the repo with.sitelens/flows/.
MCP (Cursor / IDE agents)
Tool: sitelens_run_local_flow (registered when local tools are enabled — always, including SITELENS_MODE=local)
{
"flowId": "homepage-smoke",
"url": "http://127.0.0.1:3000/"
}- Same flags as CLI where applicable:
authProfile,authMode,viewports,browser,exportArtifacts. - Cursor prompt: "Run sitelens_run_local_flow with flowId auth-login-setup and url http://127.0.0.1:3000/login — list labeled screenshot paths from actionLog (before-submit, after-login, final-state)."
Flow discovery (CLI — list only)
These commands list flows; they do not run them:
npx --yes @sitelensapi/mcp sitelens doctor
npx --yes @sitelensapi/mcp sitelens-mcp -- --self-testBoth report the resolved workspace, flows directory, and discovered flow ids when present.
To run a flow from the terminal, use npx --yes @sitelensapi/mcp sitelens flow run (see above).
Screenshot & artifact output
When exportArtifacts is true (default for flow runs):
$SITELENS_LOCAL_ARTIFACT_DIR/runs/<localRunId>/
summary.json # status, paths, localRunId, screenshotPaths, actionLog
report.md # human-readable report
raw.json # per-viewport capture (redacted)
screenshot-inventory.json # PNG metadata (size, WxH)
screenshots/ # PNG files — end-of-run and labeled checkpoint stepsLabeled checkpoint steps ({ "type": "screenshot", "label": "after-login" }) save {label}-{viewport}-step{N}.png during the flow. Each successful step adds actionLog[].screenshot with path, url, and label.
- Default base:
$TMPDIR/sitelens-mcp-local-qa(override withSITELENS_LOCAL_ARTIFACT_DIR). - Tool response includes
summary.artifactDir,summary.reportPath, andsitelens-local://resource URIs. - Not uploaded to SiteLens cloud. Optional pixel diff only via
sitelens_compare_local_runs.
SiteLens Desktop (architecture note)
Desktop bundles the MCP HTTP runtime (start:http-runtime) as a sidecar. That runtime exposes:
GET /flows/local— catalog.sitelens/flows/*.jsonPOST /flows/local/run— execute a flow (used by Desktop capture packs)
Desktop Project flows lists .sitelens/flows/*.json and runs them in-app. When Desktop detects supportsRepoLocalScenarios in MCP capabilities, it can surface Run Scenario using localScenarioRunner metadata (path pattern, param syntax, CLI command). npm consumers can use CLI or Cursor MCP without Desktop.
Scenario Runner
Flows and scenarios solve different problems:
| | Flow | Scenario |
|--|------|----------|
| What it is | A single QA flow targeting one page or workflow step sequence | Setup and orchestration of one or more flows using a shared browser session/profile |
| Storage | .sitelens/flows/{flowId}.json | .sitelens/scenarios/{scenarioId}.json |
| Browser session | New session per run | One session for all chained flows (cookies, localStorage, sessionStorage carry over) |
| Run | sitelens flow run / sitelens_run_local_flow | sitelens run scenario / sitelens_run_local_scenario |
| Params | Override url at run time | {{paramName}} interpolation + scenario/runtime params |
Supported use cases
- Login flows — authenticate once, then run smoke tests in the same session
- Session initialization — establish browser state before downstream flows
- Role elevation — dev or staging session setup that grants elevated permissions for admin flows
- Feature flag activation — toggle flags in an admin flow, verify in the app flow
- Test data selection — pick a record or fixture, then run workflow verification
- Environment setup — configure staging/local context before smoke validation
- Multi-step application workflows — paths spanning several pages with shared state
- Admin workflow verification — validate admin panels and privileged actions after setup
- End-to-end smoke validation — chained setup + assertion flows in one run
Scenarios stay inside the SiteLens flow step vocabulary (click, assert*, network waits, etc.) — they chain existing flow JSON files; they are not arbitrary Playwright scripts.
Example scenario JSON
{
"version": 1,
"id": "role-elevation-scenario",
"name": "Role Elevation Scenario",
"profile": "qa-user",
"params": {
"baseUrl": "http://localhost:3000",
"userId": "12345"
},
"flows": [
{ "flow": "session-setup" },
{ "flow": "admin-workflow-smoke" }
]
}Each flows[] entry references a flow id (.sitelens/flows/{id}.json) or a path to a flow file. Optional with overrides flow fields or supplies param values for that step.
Parameter interpolation
Use {{paramName}} placeholders in flow URL fields and string step fields (selectors, assert text, fill values, etc.).
Per-flow URL override with interpolation:
{
"flow": "session-setup",
"with": {
"url": "{{baseUrl}}/dev/elevate-session?user={{userId}}"
}
}Example flow with interpolated fields:
{
"id": "session-setup",
"name": "Session Setup",
"url": "{{baseUrl}}/dev/elevate-session?user={{userId}}",
"steps": [
{ "type": "waitForSelector", "selector": "[data-testid='session-updated']" },
{ "type": "assertText", "text": "session updated" },
{ "type": "assertUrlContains", "text": "/dev/elevate-session" }
]
}Precedence (later values win):
scenario.params— defaults in the scenario file- Runtime params — CLI
--param key=valueor MCPparamsobject - Per-flow
with— overrides and extra values for that flow entry
Validation (before browser launch):
- Missing
{{param}}placeholders → clear error listing required param names - Interpolated flow JSON → validated against the same schema as
.sitelens/flows(invalid URLs or steps fail before execution)
Run a scenario (CLI)
npx --yes @sitelensapi/mcp sitelens run scenario role-elevation-scenario \
--profile qa-user \
--param baseUrl=http://localhost:3000 \
--param userId=12345| Flag | Description |
|------|-------------|
| --profile <name> | Auth profile for persistent browser session (overrides scenario.profile) |
| --param key=value | Runtime param (repeatable); merges over scenario.params |
| --viewport desktop\|mobile | Repeat for both viewports |
| --output <dir> | Artifact base directory (SITELENS_LOCAL_ARTIFACT_DIR) |
| --json | Machine-readable combined scenario result |
| --auth-mode | none | storage-state | persistent-profile (default for scenarios: persistent-profile) |
| --browser | chromium | chrome | msedge | firefox | webkit |
| --no-screenshot | Disable screenshots for all flows in the scenario |
| --no-artifacts | Disable artifact bundle export |
Help: sitelens run scenario --help
Each flow in the scenario gets its own artifact folder under the configured artifact base; the combined JSON output lists per-flow statuses, errors, labeled screenshot paths (actionLog[].screenshot), and artifactDir values.
Run a scenario (MCP)
Tool: sitelens_run_local_scenario
Input schema:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| scenarioId | string | yes | Scenario id (.sitelens/scenarios/{id}.json) or path to scenario JSON |
| params | object (string values) | no | Runtime params merged over scenario.params |
| profile | string | no | Auth profile override |
| authMode | enum | no | none | storage-state | persistent-profile |
| viewports | string[] | no | desktop, mobile |
| browser | enum | no | Browser channel |
| screenshot | boolean | no | Enable/disable screenshots |
| exportArtifacts | boolean | no | Enable/disable artifact bundles |
Example request:
{
"scenarioId": "role-elevation-scenario",
"profile": "qa-user",
"params": {
"baseUrl": "http://localhost:3000",
"userId": "12345"
}
}Example response (summary fields):
{
"scenarioId": "role-elevation-scenario",
"scenarioName": "Role Elevation Scenario",
"status": "passed",
"profile": "qa-user",
"sharedSession": true,
"startedAt": "2026-06-01T12:00:00.000Z",
"finishedAt": "2026-06-01T12:01:30.000Z",
"flowResults": [
{
"flowRef": "session-setup",
"flowId": "session-setup",
"flowName": "Session Setup",
"index": 0,
"status": "passed",
"testedUrl": "http://localhost:3000/dev/elevate-session?user=12345",
"localRunId": "local_abc123",
"artifactDir": "/tmp/sitelens-mcp-local-qa/runs/local_abc123",
"screenshotPaths": ["/tmp/.../screenshots/local-qa-....png"],
"reportPath": "/tmp/.../report.md"
},
{
"flowRef": "admin-workflow-smoke",
"flowId": "admin-workflow-smoke",
"flowName": "Admin Workflow Smoke Test",
"index": 1,
"status": "passed",
"testedUrl": "http://localhost:3000/admin/dashboard",
"localRunId": "local_def456",
"screenshotPaths": [],
"artifactDir": "/tmp/sitelens-mcp-local-qa/runs/local_def456"
}
],
"infrastructure": "local",
"billingNotice": "Local SiteLens MCP runs are free."
}If a flow fails, flowResults includes error on the failed entry and later flows are skipped. CLI human output and JSON include workspace paths, auth diagnostics (profile name, auth paths, whether saved state exists), and full artifact paths (artifactDir, summary.json, screenshots).
Working across multiple repositories
Each git repo can have its own SiteLens workspace. Flows and scenarios are repo-local; auth profiles are machine-local under ~/.sitelens/.
Recommended repo layout:
your-app-repo/
.sitelens/
flows/ ← flow JSON files
scenarios/ ← scenario JSON files
config.json ← optional: browser channel, default profile nameRun artifacts (screenshots, summary.json, report.md) are written under the configured artifact base — default $TMPDIR/sitelens-mcp-local-qa/runs/<localRunId>/, or set SITELENS_LOCAL_ARTIFACT_DIR / CLI --output.
Workspace resolution order (first match wins):
SITELENS_WORKSPACE_DIR— explicit override (best for CI or monorepo subprojects)CURSOR_PROJECT_DIR— Cursor’s open project rootVSCODE_CWD— VS Code / integrated terminal cwd hintprocess.cwd()— shell working directory when you run the CLI
Per-run workspaceDir is not a CLI flag today; use SITELENS_WORKSPACE_DIR or cd into the repo. Scenario paths can also be passed as explicit file paths (relative to workspace or absolute).
There is no automatic walk for a nearest ancestor .sitelens/ directory. If you run from a subdirectory, set SITELENS_WORKSPACE_DIR to the repo root or pass a path to the scenario file.
Use distinct profile names per app (--profile my-app-qa) so cookies from one repo do not leak into another when reusing ~/.sitelens/profiles/.
Interactive login and saved profiles
Scenarios default to persistent-profile auth — one Chromium user-data directory per profile name under ~/.sitelens/profiles/<name>/.
| Step | Command / tool |
|------|----------------|
| Interactive login | sitelens auth start --profile qa-user → log in → sitelens auth save |
| Check saved state | sitelens auth status --profile qa-user or MCP sitelens_auth_status |
| Run with profile | sitelens run scenario … --profile qa-user |
At scenario start, CLI and MCP results include auth diagnostics (no secrets):
- Profile name and resolved paths (
~/.sitelens/auth/<profile>.json,~/.sitelens/profiles/<profile>/) - Whether each path exists on disk before the run
- Auth mode (
persistent-profile,storage-state,none) - Whether a shared session is reused across chained flows
For login flows inside a scenario, prefer DOM and URL assertions over a single network URL check — see Troubleshooting login redirects.
Running scenarios
| Surface | Command / tool |
|---------|----------------|
| CLI | sitelens run scenario <scenario-id> [--profile …] [--param key=value …] |
| MCP | sitelens_run_local_scenario with scenarioId, optional profile, params |
| Help | sitelens run scenario --help |
Use --json for CI: combined status, per-flow artifactDir, summary.json paths, and auth block. Exit code 1 when scenario status is failed.
List scenario ids: ls .sitelens/scenarios/ or copy examples from docs/examples/scenarios/.
Troubleshooting login redirects
If a flow lands on /login instead of the expected page:
- Read auth diagnostics in the scenario result — confirm profile name, paths, and
foundvsmissing. - Run
sitelens auth status --profile <name>— re-save if storage state or profile dir is empty. - Inspect the failed flow artifact — open
summary.jsonand screenshots under the printedartifactDir. - Harden login flows — combine multiple success signals instead of relying on one API response URL:
{
"type": "expectEither",
"label": "login success",
"oneOf": [
{ "type": "assertSelector", "selector": "[data-testid='user-menu']", "state": "visible" },
{ "type": "assertText", "text": "Welcome" },
{ "type": "assertUrlContains", "text": "/dashboard" }
]
}After submit, use assertNotExists on the login form to catch silent failures. Avoid only waitForResponse on a login API path — pair it with assertText, waitForSelector, or assertUrlContains.
Scenario runs surface login-related interpretationNotes from the underlying QA runner when a redirect is detected.
Capabilities (Desktop discovery)
When the MCP HTTP runtime is enabled, GET /capabilities includes:
| Field | Meaning |
|-------|---------|
| supportsRepoLocalScenarios | true when sitelens_run_local_scenario is registered |
| supportsScenarioParamInterpolation | true — {{paramName}} supported in flows |
| localScenarioRunner | { tool, scenarioPathPattern, paramSyntax, cliCommand } for Desktop UI |
Desktop should call /capabilities (or read MCP tool list) and, when supportsRepoLocalScenarios is true, offer Run Scenario with runtime param inputs matching localScenarioRunner.paramSyntax ({{paramName}}).
Complete examples
Copyable bundles live in docs/examples/:
- Login → smoke test —
login-then-smoke-scenario.json+auth-login-setup,homepage-smokeflows - Session setup → admin smoke —
role-elevation-scenario.json+session-setup,admin-workflow-smokeflows - Multi-flow workflow verification —
workflow-verification-scenario.json— test data selection → feature toggle → admin panel verify
See docs/scenario-runner-release-notes.md for release notes and a pre-release verification checklist.
Migrating from helper scripts
Shell wrappers that call multiple flow runs in sequence:
./run-workflow.sh userId=12345
./run-smoke.sh userId=12345become one scenario file plus a single command:
sitelens run scenario role-elevation-scenario \
--param userId=12345Scenarios replace custom orchestration scripts in many cases while keeping flows as reusable, reviewable JSON. You still author flows for individual pages; scenarios wire them together with shared session and params.
SiteLens ecosystem
| Surface | What it is | Local flows? |
|---------|------------|--------------|
| @sitelensapi/mcp (this package) | MCP server + CLI for Cursor/IDEs and shell/CI | Yes — .sitelens/flows + CLI + MCP tools |
| SiteLens API | Hosted cloud QA, run history, artifacts | Cloud UUID flows via sitelens_run_flow |
| QA Studio | Visual flow builder (web) | Cloud-stored flows — not the same as .sitelens/flows JSON |
| SiteLens Desktop | Native app + local engine | Project flows page — list and run .sitelens/flows/*.json |
| Dashboard / MCP onboarding | API keys, setup copy-paste | — |
Website: https://www.sitelensapi.com
MCP docs: https://www.sitelensapi.com/mcp/docs
npm: @sitelensapi/mcp · @sitelensapi/qa-smoke (shared step schema; usually a dependency)
Setup guides
- Use SiteLens MCP globally in Cursor
- WSL / Linux setup
- Login once and reuse auth
- Authenticated localhost QA
- Project flows & local templates
- Clear saved sessions
CLI commands
| Command | Purpose |
|---------|---------|
| sitelens-mcp | Start stdio MCP server (normal Cursor wiring) |
| sitelens-mcp setup | Install bundled Chromium + verify dirs |
| sitelens-mcp -- --self-test | Readiness probe (workspace, flows dir, browser) |
| sitelens doctor | Portable diagnostics (lists .sitelens/flows ids) |
| sitelens doctor --cursor | Cursor-focused hints + example mcp.json |
| sitelens flow init | Scaffold .sitelens/flows/{flowId}.json (--flow-id or positional id; --template) |
| sitelens flow run | Run .sitelens/flows/{flowId}.json (--flow-id, --url) |
| sitelens run scenario | Run .sitelens/scenarios/{scenarioId}.json (chained flows, shared session) |
Example:
npx --yes @sitelensapi/mcp sitelens flow run \
--flow-id homepage-smoke \
--url https://example.com
npx --yes @sitelensapi/mcp sitelens run scenario login-then-smoke-scenario \
--profile qa-user \
--param baseUrl=http://localhost:3000Cursor wiring: use npx -y @sitelensapi/mcp as the command — do not pass setup, doctor, flow run, or --self-test as MCP server args.
SiteLens Desktop uses a separate HTTP runtime process (start:http-runtime) — do not set SITELENS_MCP_HTTP=1 in Cursor unless you intentionally want a loopback health server.
MCP tools
Local (registered when SITELENS_MODE=local or always without cloud key)
| Tool | Description |
|------|-------------|
| sitelens_setup | First-run bootstrap |
| sitelens_billing_status | Local-free vs cloud-paid boundary |
| sitelens_auth_start / _save / _status / _clear | Login-once auth under ~/.sitelens/ |
| sitelens_qa_run | Ad-hoc local QA (preferred name) |
| sitelens_run_local_qa | Same as sitelens_qa_run (legacy alias) |
| sitelens_run_local_flow | Run .sitelens/flows/{flowId}.json |
| sitelens_run_local_scenario | Run .sitelens/scenarios/{scenarioId}.json (chained flows, shared session, {{param}} interpolation) |
| sitelens_list_local_runs | Scan local artifact dirs |
| sitelens_compare_local_runs | Diff two local run bundles |
Cloud (requires SITELENS_API_KEY + SITELENS_MODE=all or cloud)
| Tool | HTTP |
|------|------|
| sitelens_analyze_page | POST /analyze/page |
| sitelens_run_qa | POST /analyze/qa |
| sitelens_list_runs | GET /qa/runs |
| sitelens_get_run | GET /qa/runs/:runId |
| sitelens_run_flow | POST /qa/flows/:flowId/run |
Cloud run resources: sitelens://runs/{runId} (Markdown digest via MCP resources/read).
Cursor MCP config (cloud + local)
When you need cloud tools, add your API key:
{
"mcpServers": {
"sitelens": {
"command": "npx",
"args": ["--yes", "@sitelensapi/mcp", "sitelens-mcp"],
"env": {
"SITELENS_API_BASE_URL": "https://api.sitelensapi.com",
"SITELENS_API_KEY": "sitelens_sk_…",
"SITELENS_MODE": "all"
}
}
}
}Local-only tools work without an API key — omit the key or use SITELENS_MODE=local.
Page Intelligence: Use MCP tool sitelens_analyze_page (cloud API) to plan flows from page structure. See Page Intelligence overview and monorepo doc docs/sitelens-mcp-page-intelligence.md for the analyze → flow → verify workflow.
Environment variables
| Variable | Description |
|----------|-------------|
| SITELENS_MODE | local (default for Cursor) · all · cloud |
| SITELENS_API_KEY | Required for cloud tools only |
| SITELENS_API_BASE_URL | API origin (default http://127.0.0.1:3000; production https://api.sitelensapi.com) |
| SITELENS_WORKSPACE_DIR | Override workspace root for .sitelens/flows and .sitelens/scenarios (see Working across multiple repositories) |
| SITELENS_LOCAL_ARTIFACT_DIR | Base for runs/<localRunId>/ bundles |
| SITELENS_LOCAL_BROWSER_CHANNEL | Omit → bundled Chromium; or chrome / msedge / firefox / webkit |
| SITELENS_BROWSER_CHANNEL | Optional local MCP alias when SITELENS_LOCAL_BROWSER_CHANNEL unset — chrome, msedge, or chromium (bundled default). Explicit chrome/msedge never silently falls back to bundled Chromium |
| SITELENS_LOCAL_BROWSER_ARGS | Advanced/dev-only: comma-separated Chromium launch flags (e.g. --ignore-certificate-errors) for local MCP runs |
| SITELENS_LOCAL_ALLOWED_HOSTS | Extra hostnames for local QA (staging domains) |
| SITELENS_LOCAL_IGNORE_HTTPS_ERRORS | Local/dev only: true, 1, or yes — Playwright ignores HTTPS certificate errors (self-signed / private CA) |
| SITELENS_DEFAULT_URL | Default target for cloud sitelens_run_qa |
Never commit real API keys.
Example Cursor prompts
- "Use SiteLens setup."
- "Run SiteLens local QA on http://localhost:3000."
- "Run sitelens_run_local_flow with flowId homepage-smoke and url http://127.0.0.1:3000/."
- "Run sitelens_run_local_scenario for login-then-smoke-scenario with baseUrl http://127.0.0.1:3000/."
- "List my last 10 SiteLens local QA runs."
- "Compare these two local runs and include screenshot diff."
- "Open the SiteLens local report resource for the last run."
With cloud API key configured:
- "Use sitelens_analyze_page on https://www.sitelensapi.com/ and list primaryActions and workflowStages."
- "Use SiteLens to QA https://staging.example.com and call out blockers."
- "List my latest SiteLens QA runs."
- "Run saved flow
<cloud-flow-uuid>against https://staging.example.com."
Remote registry (prompts, flows, templates)
Ship updated Cursor prompts, example flows, and local QA template presets without publishing a new @sitelensapi/mcp version.
npx --yes @sitelensapi/mcp sitelens registry sync
npx --yes @sitelensapi/mcp sitelens registry list --type prompts
npx --yes @sitelensapi/mcp sitelens registry show prompts teach-cursor
npx --yes @sitelensapi/mcp sitelens registry materialize flow homepage-smokeCache: ~/.sitelens/registry/ (override with SITELENS_REGISTRY_DIR). Catalog URL: SITELENS_REGISTRY_URL (default https://www.sitelensapi.com/registry/v1/).
Operators publish catalog JSON to https://www.sitelensapi.com/registry/v1/ (manifest + prompts/, flows/, scenarios/, qa-templates/). Scenario templates use the same flow-entry shape as local scenarios; remote sync is optional — local .sitelens/scenarios/ works without registry sync.
Monorepo development
cd packages/sitelens-mcp
pnpm install
pnpm run build
pnpm run setup
pnpm run doctor
pnpm run start # stdio MCP server
pnpm run test
pnpm run pack:smoke # release tarball smokeRebuild after src/ changes — MCP clients run compiled dist/.
Requirements & privacy
- Node.js 20+
- Local QA: bundled browser runtime (via
sitelens-mcp setup); no Docker - macOS: approve Cursor + browser automation in Privacy & Security when prompted
- Local artifacts stay on disk — not uploaded to SiteLens cloud by default
SITELENS_API_KEYis required only for cloud HTTP tools andsitelens://runs/…resources
Troubleshooting: browser runtime (last resort)
Normal path: sitelens-mcp setup (or sitelens doctor) — installs dirs, probes the bundled Chromium, and reports what failed.
Only if setup cannot finish (offline CDN, strict proxies, corrupted cache) and you are developing this package from a git checkout:
cd packages/sitelens-mcp && pnpm exec playwright install chromiumThen rerun sitelens-mcp setup. Do not use the command above for routine installs — it bypasses SiteLens setup checks.
License
See repository root for license terms.
