feat(percy): Add App Percy BYOS tool, session state, and enhanced tool responses#274
Merged
gaurav-singh-9227 merged 51 commits intobrowserstack:percyfrom Apr 17, 2026
Merged
Conversation
Add Percy MCP tools infrastructure: - Percy API client with JSON:API deserialization, cursor pagination, and Zod response validation (src/lib/percy-api/) - Token resolution supporting PERCY_TOKEN env vars with BrowserStack fetch fallback, error enrichment for 401/403/429 - Markdown formatter for builds, snapshots, comparisons, suggestions - In-memory cache (30s TTL) and exponential backoff polling utility - 7 core tools: list_projects, list_builds, get_build, get_build_items, get_snapshot, get_comparison, approve_build - Registered via addPercyMcpTools in server-factory.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… report tools Build Creation (9 tools): - Web flow: create_build, create_snapshot, upload_resource, finalize_snapshot, finalize_build - App/BYOS flow: create_app_snapshot, create_comparison, upload_tile, finalize_comparison AI Intelligence (4 tools): - get_ai_analysis: per-comparison and build-aggregate AI data - get_build_summary: AI-generated natural language summaries - get_ai_quota: daily regeneration quota status - get_rca: Root Cause Analysis with exponential backoff polling Diagnostics (2 tools): - get_suggestions: rule-engine failure analysis with fix steps - get_network_logs: parsed per-URL base vs head status Composite Workflow (1 tool): - percy_pr_visual_report: single-call PR visual regression report with risk ranking, AI summary, and recommendations Total: 23 tools registered in percy-mcp registrar. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…otal) Composite Workflows (3 tools): - percy_auto_triage: categorize changes into Critical/Review/ Auto-Approvable/Noise with configurable thresholds - percy_debug_failed_build: cross-reference error buckets, suggestions, failed snapshots, and network logs with fix commands - percy_diff_explain: plain English diff explanation at 3 depth levels (summary, detailed, full_rca with DOM/CSS changes) Auth Diagnostic (1 tool): - percy_auth_status: check token configuration, validate scopes, report project/org access All 27 Phase 1 Percy tools now registered: - 7 core query tools (list/get projects, builds, snapshots, comparisons) - 1 approval tool (approve/reject/request_changes/unapprove) - 9 build creation tools (web + app/BYOS flows) - 4 AI intelligence tools (analysis, summary, quota, RCA) - 2 diagnostics tools (suggestions, network logs) - 4 composite workflows (PR report, triage, debug, diff explain) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Export maskToken from auth.ts (used by auth-status.ts) - Fix client.test.ts: re-mock fetch for each assertion to avoid mock exhaustion when calling client.get() multiple times All 176 tests pass, TypeScript compiles clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…bles Clean up 9 unused import/variable lint errors across 5 files: - client.ts: remove unused PercyApiError import - auth-status.ts: remove unused resolvePercyToken import and projects var - auto-triage.ts: remove unused percyCache import - diff-explain.ts: remove unused formatComparison import - pr-visual-report.ts: remove unused formatBuildStatus/formatSnapshot/ formatAiWarning imports and reviewState variable Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 2 Tools (4 new): - percy_trigger_ai_recompute: re-run AI with custom prompts - percy_suggest_prompt: AI-generated prompt suggestions for regions - percy_get_build_logs: download/filter CLI, renderer, jackproxy logs - percy_analyze_logs_realtime: instant diagnostics from raw log data Documentation: - docs/percy-tools.md: comprehensive reference for all 31 tools with parameter tables, example prompts, example outputs, multi-step protocols, common workflows, architecture overview, and troubleshooting guide Total: 31 tools registered (27 Phase 1 + 4 Phase 2). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Management Tools (7 new): - percy_manage_project_settings: view/update 58 project attributes with high-risk change protection (confirm_destructive gate) - percy_manage_browser_targets: list/add/remove Chrome, Firefox, Safari, Edge targets - percy_manage_tokens: list (masked) and rotate project tokens - percy_manage_webhooks: CRUD for webhook configs with event subscription - percy_manage_ignored_regions: CRUD for bounding box, XPath, CSS, fullpage ignored regions - percy_manage_comments: list/create/close comment threads on snapshots - percy_get_usage_stats: org screenshot usage, quota, AI comparison counts Advanced Tools (3 new): - percy_manage_visual_monitoring: create/update/list VM projects with URL lists, cron schedules, auth config - percy_branchline_operations: sync/merge/unmerge branch baselines - percy_manage_variants: list/create/update A/B testing variants All 41 Percy tools now registered across 3 phases. Lint clean, TypeScript clean, 176 tests passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comprehensive 2400-line documentation covering: - All 41 Percy tools organized into 10 categories - Every tool has: parameter table, example prompt, example tool call JSON, and example output - Multi-step protocol guides for Web and App build creation - Quick reference table mapping 41 natural language prompts to tool names - Setup, authentication, and troubleshooting sections Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New tool for creating Percy projects in an organization. Accepts org_id, name, type (web/app/automate/generic), slug, default branch, and auto-approve filter. Returns project ID with next-step guidance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ld to support token-scoped endpoint - percy_create_project now uses api.browserstack.com/api/app_percy/ get_project_token which auto-creates projects and returns tokens. Uses BrowserStack Basic Auth instead of Percy Token auth. - percy_create_build now supports token-scoped /builds endpoint (no project_id needed when PERCY_TOKEN is project-scoped). Requires resources relationship with empty data array. - project_id made optional in create_build Zod schema. Tested: project creation returns web token, build creation returns build ID 48434171 with 4 browser targets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Single command that handles ALL build creation scenarios: 1. URL Snapshots: Give URLs → returns Percy CLI commands to snapshot "percy_create_percy_build(project_name: 'my-app', urls: 'http://localhost:3000')" 2. Screenshot Upload: Give image files → creates build, uploads all, finalizes automatically via Percy API "percy_create_percy_build(project_name: 'my-app', screenshots_dir: './screens/')" 3. Test Command: Give test command → returns percy exec wrapper "percy_create_percy_build(project_name: 'my-app', test_command: 'npx cypress run')" 4. Clone Build: Give source build ID → reads snapshots, provides re-creation instructions "percy_create_percy_build(project_name: 'my-app', clone_build_id: '12345')" Auto-features: - Auto-creates project if it doesn't exist - Auto-detects git branch and SHA - Auto-detects screenshot dimensions from PNG headers - Computes SHA-256 hashes for resources - Handles multi-file screenshot batches Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The BrowserStack API returns success:false when type=web is sent for some projects. Only send the type parameter when explicitly provided by the user. Auto-detection works correctly without it. Tested: percy_create_percy_build now works for project "rahul-mcp" with urls parameter. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…revent auto-execution Fixes: - Use `npx @percy/cli snapshot` instead of `npx percy snapshot` - Widths go in YAML config file, not --widths CLI flag - Generate proper snapshots.yml with per-URL width configuration - Add "Do NOT execute automatically" warning to all instruction outputs so Claude Code presents commands to user instead of running them Tested with multiple URLs — generates correct YAML config. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rmatting Tool Organization: - Reorganized 43 tools into CRUD categories: CREATE (6), READ (17), UPDATE (12), FINALIZE/UPLOAD (5), WORKFLOWS (3) - Updated all tool descriptions to be action-oriented - Removed Phase 1/2/3 markers, replaced with CRUD section comments Formatter Fixes: - Fixed AI analysis to use actual Percy API field names (totalComparisonsWithAi, totalPotentialBugs, totalDiffsReducedCapped) instead of invented names (comparisonsAnalyzed, diffReduction) - Added dual-format support: handles both camelCase (from deserializer) and kebab-case (raw API) field names - Fixed snapshot stats to use actual API fields - Fixed build summary parsing to handle JSON string format Documentation: - Reorganized docs/percy-tools.md into CRUD structure - Added "Quick Start — Two Essential Commands" section - Documented percy_create_percy_build with all 5 modes - Updated tool count to 43 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All config lives inside mcp-server/percy-config/: - config — active credentials (gitignored) - profiles/ — saved org profiles (gitignored) - start.sh — MCP launcher that sources config - switch-org.sh — switch between org profiles Usage: # Edit credentials vi percy-config/config # Switch orgs ./percy-config/switch-org.sh org2 # Check current ./percy-config/switch-org.sh .mcp.json now points to start.sh (no hardcoded tokens). Credentials are gitignored — never committed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Security: - config and profiles/ are gitignored — tokens never committed - Only config.example (with placeholder values) is tracked - switch-org.sh masks token values when displaying config New files: - percy-config/config.example — template with placeholder values - percy-config/setup.sh — interactive first-time setup wizard (prompts for credentials, writes gitignored config file) - percy-config/start.sh — MCP launcher (sources config, starts server) - percy-config/switch-org.sh — org profile switcher with --save flag First-time user experience: cd mcp-server ./percy-config/setup.sh # guided credential entry # restart Claude Code "Use percy_auth_status" # verify setup Multi-org workflow: ./percy-config/switch-org.sh --save org1 # save current ./percy-config/switch-org.sh --save org2 # save another ./percy-config/switch-org.sh org2 # switch # restart Claude Code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Detect token type from prefix (web_, auto_, app_, ss_, vmw_) - Handle CI/write-only tokens (no prefix) without false "Failed" error - Show "No read access (normal for CI tokens)" instead of error - Validate BrowserStack API separately from Percy API - Show capabilities summary: what the current token CAN do - Mask token values in switch-org.sh display Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New tool: percy_clone_build - Clones snapshots from any Percy build to any project - Works across different projects and orgs - Downloads screenshots from source (public GCS URLs) - Re-uploads as tiles to target project - Creates matching comparison tags (device/browser metadata) - Auto-creates target project if it doesn't exist - Auto-detects git branch and SHA - Handles web builds (advises re-snapshotting) vs screenshot builds (full clone) Parameters: - source_build_id: Build to clone FROM - target_project_name: Project to clone INTO - source_token: Token for reading source (if different from PERCY_TOKEN) - branch, commit_sha: Optional overrides (auto-detected) How it works: 1. Reads source build + all snapshot details with comparison data 2. Gets/creates target project token via BrowserStack API 3. Creates new build in target project 4. For each snapshot: downloads head screenshots → creates snapshot → creates comparisons with tiles → uploads tile data → finalizes 5. Finalizes target build Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The client's deserialize() was returning {data, meta} wrapper objects.
All handlers accessed result.state, result.totalSnapshots etc. which
were undefined — the actual data was at result.data.state.
Fix: client.get/post now returns the unwrapped data directly:
- Single object: returns the flattened record (not {data: record})
- Array: returns the array (not {data: [records]})
- Meta attached as non-enumerable __meta property
This was the root cause of:
- percy_clone_build finding 0 snapshots (items were in result.data)
- percy_auth_status showing "unknown" state
- percy_pr_visual_report not finding builds
- All read tools returning incomplete/empty data
Also fixed approve-build handler to match unwrapped response format.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…_token support Critical fixes: - Extract snapshot IDs from build-items' snapshotIds arrays (not from item.id which is the group ID) - Fetch snapshots via raw JSON:API and manually walk the included chain: comparison → head-screenshot → image → url (deserializer doesn't resolve nested relationships) - Add target_token parameter to clone into existing projects without auto-creating via BrowserStack API The BrowserStack get_project_token API can create duplicate projects with same name but different type. target_token bypasses this by using the project's actual token directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two API payload issues causing "param is missing" errors:
1. Comparison creation: attributes must have content (not empty {}).
Fixed to include external-debug-url and dom-info-sha as null.
Removed type: "comparisons" wrapper (not needed).
Tag and tiles data simplified to just attributes.
2. Tile upload: removed type: "tiles" wrapper, just send
data.attributes with base64-content.
Verified end-to-end: build 48446947 created with snapshot,
comparison (201), tile upload (201), finalize (200) — all
successful with proper rendering in Percy.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y_run_tests (46 tools) Two new tools that actually execute Percy CLI locally: percy_snapshot_urls: - Launches @percy/cli to snapshot URLs with a real browser - Creates snapshots.yml config, runs `npx @percy/cli snapshot` - Fire-and-forget: spawns in background, returns build URL immediately - Captures at specified widths (default 375,1280) - Auto-creates project and gets token percy_run_tests: - Wraps any test command with `npx @percy/cli exec --` - Tests call percySnapshot() to capture during execution - Fire-and-forget: returns build URL, tests run in background - Works with Cypress, Playwright, Selenium, etc. Both tools: - Check for @percy/cli availability first - Get/create project token via BrowserStack API - Spawn detached child process (doesn't block MCP server) - Wait up to 8-10 seconds for build URL, then return - Report errors (URL not reachable, CLI not found) Usage: "Snapshot localhost:3000 with Percy" → percy_snapshot_urls(project_name: "my-app", urls: "http://localhost:3000") "Run my cypress tests with Percy" → percy_run_tests(project_name: "my-app", test_command: "npx cypress run") Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete rewrite of docs/percy-tools.md: - Every tool shown as exact copy-paste command - Organized by action: CREATE, READ, UPDATE - Common workflows section with 8 scenarios - Prerequisites table - Token types table - Org switching instructions - No verbose parameter descriptions — just commands and notes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…support Major rework: - New v2 tools using BrowserStack Basic Auth (fixes 403 on reads) - percy_create_build auto-executes Percy CLI (no manual instructions) - Test cases supported for both URLs and screenshot uploads - URL + test case uses percy exec local API (POST localhost:5338) - snapshot_names maps 1:1 with urls or files - test_case: single = all snapshots, comma-separated = per-snapshot New files: - src/lib/percy-api/percy-auth.ts — percyGet/percyPost with Basic Auth - src/tools/percy-mcp/v2/ — 6 handler files + registrar v1 tools disabled in server-factory.ts, v2 active. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove unused import addPercyMcpTools (v1 disabled) - Remove unused stdoutData variable in handleUrlWithTestCases - Remove unused percyPost import in create-project Build clean: lint passes, 176 tests green. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The percy exec + local API approach (POST localhost:5338) didn't work
because percy exec expects SDK DOM snapshots, not URL-based rendering.
New approach: generate a Node.js script that imports @percy/core and
calls percy.snapshot() directly with {url, name, testCase, widths}.
Percy Core handles browser launch, DOM capture, upload, and finalize.
This supports both URL rendering AND test cases in a single flow.
The script runs as a background process with 60s timeout.
Requires @percy/core installed (comes with @percy/cli).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… YAML
Key fix: Percy CLI's snapshots.yml supports testCase and widths
directly. No need for @percy/core script or local API.
YAML format that works:
- name: "App Page"
url: http://localhost:3001/app/projects
testCase: "app-test"
widths:
- 375
- 1280
Changes:
- Use widths (plural, array) instead of additionalSnapshots
- Add testCase directly in YAML per snapshot
- Remove handleUrlWithTestCases function (no longer needed)
- Single code path for all URL snapshots (with or without test cases)
- Output shows test case per snapshot
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, Config, Search, Integrations New tools (15): - percy_figma_build, percy_figma_baseline, percy_figma_link - percy_get_insights, percy_manage_insights_email - percy_get_test_cases, percy_get_test_case_history - percy_discover_urls, percy_get_devices - percy_manage_domains, percy_manage_usage_alerts - percy_preview_comparison, percy_search_builds - percy_list_integrations, percy_migrate_integrations All use BrowserStack Basic Auth via percyGet/percyPost. Total: 20 v2 tools registered. Docs updated with parameter tables and examples for all 20. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ics/{slug}
Org is resolved from BrowserStack Basic Auth credentials, not URL path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
API requires organization_id as query param, not in URL path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New tool that returns AI build summary: potential bugs, visual diffs,
change descriptions with occurrence counts, affected snapshots.
Uses GET /builds/{id}?include=build-summary with BrowserStack Basic Auth.
Handles: AI not enabled, build not finished, summary processing/skipped,
too many comparisons (>50), and raw JSON parsing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…language New unified tool: percy_get_build with detail parameter - overview (default): status, snapshots, AI metrics - ai_summary: AI change descriptions, bugs, diffs - changes: changed snapshots with diff ratios - rca: root cause analysis (needs comparison_id) - logs: failure diagnostics and suggestions - network: network request logs (needs comparison_id) - snapshots: all snapshots with review states One tool replaces: get_ai_summary, get_rca, get_suggestions, get_network_logs, get_build_logs, search_build_items. Also added: - Claude Code skill at ~/.claude/commands/percy.md Maps natural language to correct percy tool calls - Updated docs with all detail options and examples 22 v2 tools total. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove all references to percy-config/setup.sh, switch-org.sh, and shell script approach. Auth is now just BROWSERSTACK_USERNAME + BROWSERSTACK_ACCESS_KEY in .mcp.json env — same as existing BrowserStack MCP tools. No PERCY_TOKEN needed. BrowserStack Basic Auth handles everything. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed: - percy-config/config.example - percy-config/setup.sh - percy-config/start.sh - percy-config/switch-org.sh - .gitignore entries for percy-config Auth now works exactly like existing BrowserStack MCP: - Credentials come from .mcp.json env vars - Client (VS Code, Cursor, Claude) collects credentials via its own UI - No custom setup scripts, no PERCY_TOKEN, no shell wrappers Updated docs with: - Published package setup (npx @browserstack/mcp-server@latest) - Local development testing instructions - MCP Inspector usage Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When REMOTE_MCP=true, the server starts an HTTP server instead of stdio, enabling any MCP client to connect via URL. Usage: BROWSERSTACK_USERNAME=xxx BROWSERSTACK_ACCESS_KEY=yyy \ REMOTE_MCP=true node dist/index.js # Or with custom port: MCP_PORT=8080 REMOTE_MCP=true node dist/index.js Endpoints: POST /mcp — MCP Streamable HTTP endpoint (create/resume sessions) GET /mcp — SSE streaming for active sessions GET /health — Health check GET / — Server info + connection instructions Features: - Stateful sessions with UUID session IDs - CORS headers for browser clients - Per-session server instances - Auto-cleanup on session close - Uses @modelcontextprotocol/sdk StreamableHTTPServerTransport Connecting from clients: VS Code: Add MCP Server → HTTP → http://localhost:3100/mcp Cursor: Add remote server URL Claude Code: /mcp add http://localhost:3100/mcp Default mode (REMOTE_MCP not set) unchanged — uses stdio transport. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…kill New tools: - percy_get_snapshot: full snapshot detail with comparisons table, AI regions, screenshot URLs per browser/width - percy_get_comparison: full comparison with diff ratios, AI change descriptions (title, type, reason, coordinates), image URLs Updated Claude skill (~/.claude/commands/percy.md): - Maps natural language to correct tool + params - Covers build/snapshot/comparison level queries - Documents all data available at each API level 24 v2 tools total. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…I errors New: percy-error-handler.ts with handlePercyToolError() - Catches 401/403/404/422/429/500 errors - Shows what went wrong in plain English - Shows correct parameter table with examples - Shows how to find the right IDs (discovery tools) Applied to 8 most-used tools: - percy_get_build, percy_get_snapshot, percy_get_comparison - percy_get_builds, percy_get_projects - percy_create_build, percy_create_project, percy_clone_build Example: instead of "403 Forbidden" you now get: "Access denied. The ID doesn't belong to your org. Correct usage: percy_get_build with build_id '48436286' Find IDs: Use percy_get_projects → percy_get_builds" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ai-enabled flag can be false even when AI data exists (build was processed before the toggle was turned off). The actual data shows: ai-enabled: false total-potential-bugs: 12 total-ai-visual-diffs: 57 summary-status: ok build-summary: 6 items with titles Fix: check for actual AI data (comparisons-with-ai > 0, bugs > 0, summary-status == ok) instead of the toggle flag. Applied to get-build-detail.ts (overview + ai_summary) and get-ai-summary.ts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rsing Complete rewrite of all 7 detail views based on actual Percy API responses: overview: - Full stats table (snapshots, comparisons, diffs, unreviewed, failed) - AI metrics with real field names (total-potential-bugs, etc.) - Browser list from unique-browsers-across-snapshots - Commit info (SHA, message, author) - Base build reference - Timing (created, finished, processing duration) - AI summary preview (first 3 items) - Failure info with error-buckets table ai_summary: - Doesn't rely on ai-enabled flag (checks actual data) - Full summary items with title, occurrences, affected snapshots/comparisons - Per-snapshot comparison dimensions table changes: - Display name alongside snapshot name - Bug count per snapshot - Comparison count snapshots: - Group count vs total snapshot count - Snapshot IDs shown for drill-down logs: - Failed snapshots list - Error buckets table - Suggestions with fix steps and doc links rca: - Table format with element, XPath, diff type network: - Status summary column added Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ring
New percy_clone_build in v2 with deep clone capability:
For web/DOM builds:
1. Downloads root HTML from /snapshots/{id}/assets/head.html
2. Computes SHA-256 of HTML content
3. Creates target build with resource SHAs in relationships
4. Resources are GLOBAL by SHA — Percy reuses existing CSS/JS/images
5. Only uploads missing resources (usually just the HTML)
6. Creates snapshots with resource manifest
7. Finalizes → Percy RE-RENDERS the DOM against target baseline
8. Gets proper visual regression comparisons
For screenshot builds (fallback):
- Downloads screenshots from public image URLs
- Re-uploads as tiles (same as before)
This replaces the shallow clone that just copied screenshots.
Proper DOM clones mean real visual regression detection in the
target project.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…l resources Previous approach: downloaded root HTML only → CSS/JS/images missing → broken rendering. New approach: URL Replay mode - Extracts snapshot names/URLs from source build - If names are URLs: uses Percy CLI to re-snapshot them → Percy CLI handles full resource discovery (CSS, JS, images, fonts) → All dependencies uploaded with correct SHAs → Percy re-renders with complete styling - If names are not URLs: shows instructions with snapshot list Fallback: Screenshot Copy mode (for app/screenshot builds) - Downloads screenshots and re-uploads as tiles - Same as before but cleaner code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When snapshot names aren't URLs (most builds), the clone was stopping and asking the user to provide URLs. Now it automatically falls through to screenshot copy mode which always works. Logic: URL names → Percy CLI replay. No URLs → screenshot copy. Never stops without creating a build. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Percy API requires relationships field even for screenshot builds. Empty resources array is valid for app/screenshot type snapshots. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-install Percy CLI if missing, use URL Replay for URL-named snapshots - Screenshot copy: add type fields, strict base64, proper tag/tile format - Copy real device/browser names from source (not hardcoded "Clone/Screenshot") - Use existing target project instead of forcing new app-type project - Only create companion app-type project when web project + screenshot copy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace manual tile-based API calls with `percy upload` CLI command. This fixes: - Web projects getting cloned as app type (now uses same project) - Comparison 400 errors (CLI handles API format internally) - Device names showing as "Screenshot [Clone]" - Rate limiting from many sequential API calls Two modes: `percy snapshot` for URL-named snapshots, `percy upload` for named snapshots. Both use Percy CLI and the existing target project. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Download every comparison screenshot per snapshot — each width, device,
and browser combo gets its own file named {snapshot}_{browser}_{width}px.
Previously only downloaded the first comparison per snapshot.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ames Rewrite screenshot clone to use direct tile API instead of percy upload. percy upload creates flat snapshots (one per image), losing the multi-width/multi-browser structure. New approach preserves 100% source parity: - Exact snapshot names from source - All width variants per snapshot (375, 768, 1080, 1170, 1280px etc) - All browser comparisons (Chrome, Firefox, Safari, Edge etc) - Real device/OS info copied from source comparison tags - Rate limiting protection (200ms delay between API calls) - Strict base64 for tile uploads (no padding) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Web projects require DOM resources for snapshots — tile API is rejected
with "param is missing: relationships". Always request app-type token
for screenshot clone path. If target exists as web-type, creates
companion "{name}-screenshots" project as app-type.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…responses Add percy_create_app_build — creates App Percy builds by uploading device screenshots with proper device metadata (OS, orientation, screen size). Supports two modes: built-in sample data (3 devices × 2 screenshots, zero setup) and custom resources directory with device.json + PNGs. Add percy-session — in-memory state that persists active project token, build ID/URL/number, and org info across tool calls so subsequent commands get richer context automatically. Fix percy_auth_status — replace flaky /projects endpoint (500 error) with lightweight BrowserStack user API check. Show org info and getting started guide. Enhance all tool responses — every project command returns and activates the token, every build command returns Build ID, Build #, Build URL, and "Next Steps" with exact follow-up commands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ruturaj-browserstack
approved these changes
Apr 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
percy_create_app_build— New tool for creating App Percy BYOS (Bring Your Own Screenshots) builds via API. Supports sample mode (zero-setup, 3 devices × 2 screenshots auto-generated withsharp) and custom mode (user providesresources/directory withdevice.json+ PNGs). Validates screenshot dimensions against device config, uploads with proper device tags (OS, version, orientation, status/nav bar heights), and finalizes the build.percy-session— In-memory session state that persists active project token, build context (ID, number, URL), and org info across tool calls. Every project command activates the token; every build command stores the build ID/URL for richer follow-up context.percy_auth_status— Replace flaky/projectslist endpoint (was returning 500) with lightweight BrowserStack user API check. Now shows org name/ID, active session state, and a getting-started guide. Removed global PERCY_TOKEN requirement — tokens are now per-project and auto-activated.All Percy MCP v2 Tools (26 total)
Build Creation (4 tools)
percy_create_projectpercy_create_buildpercy_create_app_buildpercy_clone_buildBuild Inspection (5 tools)
percy_get_buildspercy_get_buildpercy_get_snapshotpercy_get_comparisonpercy_search_buildsAI & Intelligence (2 tools)
percy_get_ai_summarypercy_preview_comparisonFigma Integration (3 tools)
percy_figma_buildpercy_figma_baselinepercy_figma_linkInsights & Analytics (2 tools)
percy_get_insightspercy_manage_insights_emailTest Cases (2 tools)
percy_get_test_casespercy_get_test_case_historyDiscovery & Devices (2 tools)
percy_discover_urlspercy_get_devicesConfiguration (3 tools)
percy_manage_domainspercy_manage_usage_alertspercy_list_integrationsProject & Auth (3 tools)
percy_auth_statuspercy_get_projectspercy_migrate_integrationsFiles Changed
src/tools/percy-mcp/v2/create-app-build.tssrc/lib/percy-api/percy-session.tsscripts/generate-app-samples.mjsresources/app-percy-samples/*/device.jsonsrc/tools/percy-mcp/v2/index.tssrc/tools/percy-mcp/v2/auth-status.tssrc/tools/percy-mcp/v2/create-project.tssrc/tools/percy-mcp/v2/create-build.tssrc/tools/percy-mcp/v2/get-builds.tssrc/tools/percy-mcp/v2/get-build-detail.tssrc/tools/percy-mcp/v2/get-projects.tssrc/tools/percy-mcp/v2/clone-build.tssrc/lib/percy-api/percy-error-handler.tspackage.jsongenerate-app-samplesscriptTest plan
npm run buildcompiles cleanlynpx vitest run— 176/176 tests passpercy_auth_status— no 500 error, shows org infopercy_create_project— token stored and shown as activepercy_create_build— returns Build ID, URL, "Next Steps"percy_create_app_build(sample mode) — 6/6 snapshots, zero setuppercy_create_app_build(custom dir) — reads device.json + PNGspercy_create_app_build(dimension mismatch) — rejects bad PNGspercy_get_builds— shows URLs, drill-down commands🤖 Generated with Claude Code