shiplightaiBLOCK
AI-powered end-to-end testing for Playwright. Write tests as YAML with natural-language steps, with self-healing locators and a visual debugger.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
AI-powered end-to-end testing for Playwright. Write tests as YAML with natural-language steps, run them alongside your existing .test.ts files, and get self-healing locators and a visual debugger.
Documentation: [docs.shiplight.ai](https://docs.shiplight.ai)
What ships from this repository
Quick start
npx shiplightai@latest create ./my-tests cd my-tests npm install npx playwright install chromium npx shiplight test
A test looks like this:
goal: A shopper can add an item to the cart
base_url: https://example.com
statements:
- URL: /products
# Natural language: resolved by a model on the first run
- intent: Click the "Add to cart" button on the first product
# Once resolved, a step carries its locator and replays deterministically
- intent: Open the cart
action: click
locator: "getByRole('link', { name: 'Cart' })"
- VERIFY: The cart shows exactly one itemA statement written as plain intent is resolved by a model at runtime; once resolved it carries a concrete locator, so later runs replay deterministically and only fall back to the model when the page has changed under it.
Self-hosting
Run the CLI and browsers on your own machines or CI runners, with your own AI provider key and the action cache and reports in storage you control: apps/cli/docs/self-hosting.md.
Shiplight Cloud shuts down on October 31, 2026. After that date this is the only way to run Shiplight, and SHIPLIGHT_API_TOKEN stops working.
Working on the code
Requires Node.js >= 22 and p
32099b12f2caOBSERVED · 2026-10-12Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp -- npx -y @shiplightai/[email protected]
Exposed tools (74)
57 read · 12 write · 5 destructive. Blast radius: 5 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
act | write | Execute browser actions using element indices from inspect_page. CRITICAL: Before your first act call, you MUST read resource |
ai_action | read | Use AI to perform a specific action on the page. MCP-only tool. |
ai_assert | read | Assert that a statement is true based on the current screen state |
ai_extract | write | Use AI to extract information from the page and save it to a variable. MCP-only tool. |
ai_step | write | Use AI to execute a complete multi-action step. MCP-only tool. |
ai_wait_until | read | Wait until a specific condition is met on the page (e.g., |
attach_to_browser | read | Connect to a browser for testing. Two modes:\n |
back | read | Press the back button |
browser-session-basics | read | Basic browser session management for UI verification |
clear_execution_history | destructive | Clear the execution history for a session. The execution history tracks past browser operations within a session. Clear it to start fresh or reduce memory usage. |
clear_input | destructive | Clear text from an input field |
clear_logs | destructive | Clear console and network logs for a session |
click | read | Click an interactive element. |
close_all | read | Close all browser sessions |
close_session | read | Close a browser session. Omit session_id entirely to close ALL open sessions. |
close_tab | read | Close a browser tab by index. If no index is specified, closes the current tab. |
constrained | read | field with a refinement |
done | read | Mark the task as complete |
double_click | read | Double-click an interactive element. |
double_click_at | read | Double-click at the given normalized coordinate. |
double_tap | read | Double-tap an element |
enter | read | Press the enter key |
extract_email_code | read | Extract verification code from email inbox |
extract_email_content | read | Extract verification codes, magic links, or custom content from emails received via Mailgun. Polls the Mailgun inbox for matching emails and uses AI to extract the requested content. |
generate_2fa_code | read | Generate a 2FA code from an OTP secret key. The code is saved to the |
generate_html_report | read | Generate a self-contained HTML session report. |
get_browser_console_logs | read | Get console logs from the browser (errors, warnings, etc.) |
get_browser_network_logs | read | Get network request logs from the browser |
get_dropdown_options | read | Get all options from a native dropdown |
get_local_artifact | read | Get a local artifact file (screenshot, DOM snapshot, etc.) from a live browser session. Only accepts local file paths, NOT S3 URIs. For test run artifacts, use get_step_artifacts instead. |
get_page_info | read | Get basic page information (URL and title) without taking a screenshot. Use this as a lightweight way to check what page you |
get_relay_status | read | Get extension relay server status and tab mapping |
get_session_state | read | Get current state of a session (URL, session type) |
go_back | read | Navigate back to the previous page in browser history. |
go_to_url | write | Navigate to a specific URL. Use this to visit web pages. Set new_tab=true to open in a new tab. |
home | read | Press the home button |
hover | read | Hover over an interactive element. |
input | read | Type text into the currently focused input field |
input_text | read | Type text into an input field |
js_code | write | Execute custom JavaScript code in the browser context. Use for advanced interactions not covered by other tools. |
long_press | read | Long press an element |
navigate | read | Navigate to a URL in an existing browser session. Examples: - Navigate to a specific page: url= |
new_session | write | Create a new browser session with optional device emulation. Returns a session_id for subsequent operations. |
opt_out | read | no resolveArgs |
perform_accurate_operation | read | Perform an operation that requires accurate interaction like dragging or interacting with a specific area of an element. Only use this action when neccecary. |
pick_role | read | enum message embeds the received value |
plain_enum | read | no redactor |
press | read | Press a single keyboard key or key combination. Supports combinations like |
press_key | read | Press a system key by key code |
raw_args | read | reports rawArgs |
reload_page | destructive | Reload the current page. WARNING: This will reset any in-progress forms or multi-step flows (like login). Only use when you need to refresh stale data or clear a stuck state. Do NOT use during login, checkout, or form submission flows. |
right_click | read | Right-click an interactive element. |
right_click_at | read | Right-click at the given normalized coordinate. |
save_storage_state | write | Save the browser session |
save_variable | write | Save a value to a named variable for later use in the test. |
scroll | read | Scroll content with precise from/to coordinates (preferred for scrolling lists, feeds, etc.) |
scroll_on_element | read | Scroll on a scrollable element horizontally and vertically. |
scroll_to_element | read | Scroll to find an element |
scroll_to_text | read | Scroll the page until specified text becomes visible. |
select_dropdown_option | read | Select an option from a dropdown/select element by value, label, or index. |
set_date_for_native_date_picker | write | Set a date in a native HTML date picker input (<input type= |
swipe | read | Swipe gesture for switching tabs, dismissing dialogs, or navigating pages (use scroll for scrolling content) |
swipe_points | destructive | Drag/swipe between two specific points (for drag-and-drop, picture-in-picture, etc.) |
switch_tab | read | Switch to a different browser tab by index (0-based). |
tap | read | Tap an element |
unresolvable | read | placeholder has no variable |
update_variables | write | Update session variables for use in subsequent browser operations. Variables are key-value pairs that can be referenced in browser tasks. Mark sensitive values (passwords, tokens) with sensitive_keys to prevent logging. Example: variables: { username: |
upload_file | write | Click on target element (usually contains hints like |
upload_file_to_file_input | write | Upload a file to a file input element. The file path is relative to the test project root. |
verify | read | Verify that a statement is true based on the current page state. Use this to check assertions about the page content, element visibility, or any condition. |
wait | read | Wait for a specified duration |
wait_for_download_complete | read | Wait for an in-progress download to complete. |
wait_for_page_ready | read | Wait for the page to be fully loaded (network idle and DOM ready). Use this when the page is still loading or not ready for interaction. |
with_description | read | description is stripped before resolution |
Trust audit
BLOCKgrade F · trust 47/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (5 observation(s))
- Network
- declared (5 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (25)
const fn = new Function('page', 'agent', `return (async () => { ${code} })();`);const fn = new Function('page', 'expect', 'agent', `return (async () => { return (${code}); })();`);new Function(codeBody);
new Function('return (async () => { ' + code + ' })()');exec(`emulator -avd ${avdName} -no-snapshot-save -no-audio -no-boot-anim`);console.log(`[Gemini] Debug: useVertexAI=${useVertexAI}, apiKey=${apiKey ? 'set' : 'not set'}, modelConfig.apiKey=${modelConfig.apiKey ? 'set' : 'not set'}`);logger.debug(`[collectTokenUsages] No token usages to collect (undefined or empty)`);
logger.debug(`Token usages written to: ${tokenUsagesPath}`);'analytics', 'tracking', 'telemetry', 'beacon', 'metrics',
clear_execution_history, clear_input, clear_logs, reload_page, swipe_points
mock-data.xlsx
.prettierignore
.mcp.json.tpl
CLAUDE.md
return createHash('md5').update(data).digest('base64');const hash = crypto.createHash('md5').update(parsed.search).digest('hex').slice(0, 6);const KEY_PATH = '/home/someone/.ssh/MCP_registry-key.pem';
? path.resolve(currentDir, "../../dist/static")
? path.resolve(currentDir, "../../dist/static-embedded")
import { parseYamlTestFile } from "../../yaml-transpiler";import { createTestContext } from "../../fixture.js";import type { TestContext } from "../../fixture.js";SHIPLIGHT_WEB_URL: 'http://127.0.0.1:1',
return `http://127.0.0.1:${port}${path}`;process.env.SHIPLIGHT_API_URL = `http://127.0.0.1:${upstreamPort}`;Gates applied: no_behavioural_pass.
32099b12f2cafull audit observations/trust-audit/mcp-server/shiplightai__shiplight-cli.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | 32099b12f2ca | BLOCK | F | 47 | first audit |
Questions
What is the shiplightai MCP server?
AI-powered end-to-end testing for Playwright. Write tests as YAML with natural-language steps, with self-healing locators and a visual debugger.
What tools does shiplightai expose?
74 in total: 57 read-only, 12 that write, and 5 that can delete or overwrite (clear_execution_history, clear_input, clear_logs, reload_page, swipe_points). Every one is listed on this page with its risk.
Is shiplightai safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (47/100) and found 5 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 5 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does shiplightai need?
It reads ANTHROPIC_API_KEY, CI_COMMIT_AUTHOR_EMAIL, GEMINI_API_KEY, GOOGLE_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, MCP_REGISTRY_KEY, MCP_REGISTRY_PRIVATE_KEY, MY_KEY, OPENAI_API_KEY and SHIPLIGHT_API_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does shiplightai run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as shiplight-types at 0.1.0.
How current is this page?
The grade is for one exact copy of the source (32099b12f2ca), read on 2026-10-12. The repository is watched and re-audited when it changes.