@browserstack/mcp-server 1.2.15-beta.2 → 1.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server-factory.js +0 -4
- package/dist/tools/percy-sdk.js +20 -11
- package/dist/tools/testmanagement-utils/get-testplan.d.ts +16 -0
- package/dist/tools/testmanagement-utils/get-testplan.js +99 -0
- package/dist/tools/testmanagement-utils/list-folders.d.ts +16 -0
- package/dist/tools/testmanagement-utils/list-folders.js +77 -0
- package/dist/tools/testmanagement-utils/list-testcases.js +1 -1
- package/dist/tools/testmanagement-utils/list-testplans.d.ts +15 -0
- package/dist/tools/testmanagement-utils/list-testplans.js +75 -0
- package/dist/tools/testmanagement-utils/update-testcase.d.ts +16 -0
- package/dist/tools/testmanagement-utils/update-testcase.js +133 -10
- package/dist/tools/testmanagement.d.ts +15 -0
- package/dist/tools/testmanagement.js +73 -2
- package/package.json +2 -3
- package/dist/lib/percy-api/auth.d.ts +0 -41
- package/dist/lib/percy-api/auth.js +0 -96
- package/dist/lib/percy-api/cache.d.ts +0 -28
- package/dist/lib/percy-api/cache.js +0 -48
- package/dist/lib/percy-api/client.d.ts +0 -69
- package/dist/lib/percy-api/client.js +0 -275
- package/dist/lib/percy-api/errors.d.ts +0 -15
- package/dist/lib/percy-api/errors.js +0 -52
- package/dist/lib/percy-api/formatter.d.ts +0 -16
- package/dist/lib/percy-api/formatter.js +0 -344
- package/dist/lib/percy-api/percy-auth.d.ts +0 -43
- package/dist/lib/percy-api/percy-auth.js +0 -137
- package/dist/lib/percy-api/percy-error-handler.d.ts +0 -24
- package/dist/lib/percy-api/percy-error-handler.js +0 -302
- package/dist/lib/percy-api/percy-session.d.ts +0 -42
- package/dist/lib/percy-api/percy-session.js +0 -87
- package/dist/lib/percy-api/polling.d.ts +0 -26
- package/dist/lib/percy-api/polling.js +0 -42
- package/dist/lib/percy-api/types.d.ts +0 -56
- package/dist/lib/percy-api/types.js +0 -76
- package/dist/tools/percy-mcp/advanced/branchline-operations.d.ts +0 -16
- package/dist/tools/percy-mcp/advanced/branchline-operations.js +0 -81
- package/dist/tools/percy-mcp/advanced/manage-variants.d.ts +0 -16
- package/dist/tools/percy-mcp/advanced/manage-variants.js +0 -155
- package/dist/tools/percy-mcp/advanced/manage-visual-monitoring.d.ts +0 -16
- package/dist/tools/percy-mcp/advanced/manage-visual-monitoring.js +0 -171
- package/dist/tools/percy-mcp/auth/auth-status.d.ts +0 -3
- package/dist/tools/percy-mcp/auth/auth-status.js +0 -131
- package/dist/tools/percy-mcp/core/approve-build.d.ts +0 -14
- package/dist/tools/percy-mcp/core/approve-build.js +0 -97
- package/dist/tools/percy-mcp/core/get-build-items.d.ts +0 -13
- package/dist/tools/percy-mcp/core/get-build-items.js +0 -65
- package/dist/tools/percy-mcp/core/get-build.d.ts +0 -10
- package/dist/tools/percy-mcp/core/get-build.js +0 -16
- package/dist/tools/percy-mcp/core/get-comparison.d.ts +0 -11
- package/dist/tools/percy-mcp/core/get-comparison.js +0 -59
- package/dist/tools/percy-mcp/core/get-snapshot.d.ts +0 -10
- package/dist/tools/percy-mcp/core/get-snapshot.js +0 -40
- package/dist/tools/percy-mcp/core/list-builds.d.ts +0 -14
- package/dist/tools/percy-mcp/core/list-builds.js +0 -45
- package/dist/tools/percy-mcp/core/list-projects.d.ts +0 -12
- package/dist/tools/percy-mcp/core/list-projects.js +0 -51
- package/dist/tools/percy-mcp/creation/create-app-snapshot.d.ts +0 -12
- package/dist/tools/percy-mcp/creation/create-app-snapshot.js +0 -29
- package/dist/tools/percy-mcp/creation/create-build.d.ts +0 -19
- package/dist/tools/percy-mcp/creation/create-build.js +0 -68
- package/dist/tools/percy-mcp/creation/create-comparison.d.ts +0 -18
- package/dist/tools/percy-mcp/creation/create-comparison.js +0 -90
- package/dist/tools/percy-mcp/creation/create-snapshot.d.ts +0 -17
- package/dist/tools/percy-mcp/creation/create-snapshot.js +0 -99
- package/dist/tools/percy-mcp/creation/finalize-build.d.ts +0 -12
- package/dist/tools/percy-mcp/creation/finalize-build.js +0 -33
- package/dist/tools/percy-mcp/creation/finalize-comparison.d.ts +0 -10
- package/dist/tools/percy-mcp/creation/finalize-comparison.js +0 -16
- package/dist/tools/percy-mcp/creation/finalize-snapshot.d.ts +0 -12
- package/dist/tools/percy-mcp/creation/finalize-snapshot.js +0 -33
- package/dist/tools/percy-mcp/creation/upload-resource.d.ts +0 -15
- package/dist/tools/percy-mcp/creation/upload-resource.js +0 -43
- package/dist/tools/percy-mcp/creation/upload-tile.d.ts +0 -11
- package/dist/tools/percy-mcp/creation/upload-tile.js +0 -53
- package/dist/tools/percy-mcp/diagnostics/analyze-logs-realtime.d.ts +0 -13
- package/dist/tools/percy-mcp/diagnostics/analyze-logs-realtime.js +0 -65
- package/dist/tools/percy-mcp/diagnostics/get-build-logs.d.ts +0 -17
- package/dist/tools/percy-mcp/diagnostics/get-build-logs.js +0 -74
- package/dist/tools/percy-mcp/diagnostics/get-network-logs.d.ts +0 -5
- package/dist/tools/percy-mcp/diagnostics/get-network-logs.js +0 -21
- package/dist/tools/percy-mcp/diagnostics/get-suggestions.d.ts +0 -7
- package/dist/tools/percy-mcp/diagnostics/get-suggestions.js +0 -24
- package/dist/tools/percy-mcp/index.d.ts +0 -36
- package/dist/tools/percy-mcp/index.js +0 -1137
- package/dist/tools/percy-mcp/intelligence/get-ai-analysis.d.ts +0 -15
- package/dist/tools/percy-mcp/intelligence/get-ai-analysis.js +0 -166
- package/dist/tools/percy-mcp/intelligence/get-ai-quota.d.ts +0 -9
- package/dist/tools/percy-mcp/intelligence/get-ai-quota.js +0 -73
- package/dist/tools/percy-mcp/intelligence/get-build-summary.d.ts +0 -11
- package/dist/tools/percy-mcp/intelligence/get-build-summary.js +0 -78
- package/dist/tools/percy-mcp/intelligence/get-rca.d.ts +0 -6
- package/dist/tools/percy-mcp/intelligence/get-rca.js +0 -153
- package/dist/tools/percy-mcp/intelligence/suggest-prompt.d.ts +0 -15
- package/dist/tools/percy-mcp/intelligence/suggest-prompt.js +0 -86
- package/dist/tools/percy-mcp/intelligence/trigger-ai-recompute.d.ts +0 -16
- package/dist/tools/percy-mcp/intelligence/trigger-ai-recompute.js +0 -64
- package/dist/tools/percy-mcp/management/create-project.d.ts +0 -14
- package/dist/tools/percy-mcp/management/create-project.js +0 -52
- package/dist/tools/percy-mcp/management/get-usage-stats.d.ts +0 -12
- package/dist/tools/percy-mcp/management/get-usage-stats.js +0 -61
- package/dist/tools/percy-mcp/management/manage-browser-targets.d.ts +0 -12
- package/dist/tools/percy-mcp/management/manage-browser-targets.js +0 -136
- package/dist/tools/percy-mcp/management/manage-comments.d.ts +0 -14
- package/dist/tools/percy-mcp/management/manage-comments.js +0 -147
- package/dist/tools/percy-mcp/management/manage-ignored-regions.d.ts +0 -18
- package/dist/tools/percy-mcp/management/manage-ignored-regions.js +0 -182
- package/dist/tools/percy-mcp/management/manage-project-settings.d.ts +0 -16
- package/dist/tools/percy-mcp/management/manage-project-settings.js +0 -97
- package/dist/tools/percy-mcp/management/manage-tokens.d.ts +0 -14
- package/dist/tools/percy-mcp/management/manage-tokens.js +0 -90
- package/dist/tools/percy-mcp/management/manage-webhooks.d.ts +0 -15
- package/dist/tools/percy-mcp/management/manage-webhooks.js +0 -180
- package/dist/tools/percy-mcp/v2/auth-status.d.ts +0 -3
- package/dist/tools/percy-mcp/v2/auth-status.js +0 -80
- package/dist/tools/percy-mcp/v2/clone-build.d.ts +0 -24
- package/dist/tools/percy-mcp/v2/clone-build.js +0 -539
- package/dist/tools/percy-mcp/v2/create-app-build.d.ts +0 -28
- package/dist/tools/percy-mcp/v2/create-app-build.js +0 -442
- package/dist/tools/percy-mcp/v2/create-build.d.ts +0 -16
- package/dist/tools/percy-mcp/v2/create-build.js +0 -601
- package/dist/tools/percy-mcp/v2/create-project.d.ts +0 -8
- package/dist/tools/percy-mcp/v2/create-project.js +0 -33
- package/dist/tools/percy-mcp/v2/discover-urls.d.ts +0 -7
- package/dist/tools/percy-mcp/v2/discover-urls.js +0 -38
- package/dist/tools/percy-mcp/v2/figma-baseline.d.ts +0 -7
- package/dist/tools/percy-mcp/v2/figma-baseline.js +0 -18
- package/dist/tools/percy-mcp/v2/figma-build.d.ts +0 -7
- package/dist/tools/percy-mcp/v2/figma-build.js +0 -39
- package/dist/tools/percy-mcp/v2/figma-link.d.ts +0 -6
- package/dist/tools/percy-mcp/v2/figma-link.js +0 -27
- package/dist/tools/percy-mcp/v2/get-ai-summary.d.ts +0 -5
- package/dist/tools/percy-mcp/v2/get-ai-summary.js +0 -109
- package/dist/tools/percy-mcp/v2/get-build-detail.d.ts +0 -22
- package/dist/tools/percy-mcp/v2/get-build-detail.js +0 -567
- package/dist/tools/percy-mcp/v2/get-builds.d.ts +0 -8
- package/dist/tools/percy-mcp/v2/get-builds.js +0 -63
- package/dist/tools/percy-mcp/v2/get-comparison.d.ts +0 -5
- package/dist/tools/percy-mcp/v2/get-comparison.js +0 -94
- package/dist/tools/percy-mcp/v2/get-devices.d.ts +0 -5
- package/dist/tools/percy-mcp/v2/get-devices.js +0 -33
- package/dist/tools/percy-mcp/v2/get-insights.d.ts +0 -7
- package/dist/tools/percy-mcp/v2/get-insights.js +0 -52
- package/dist/tools/percy-mcp/v2/get-projects.d.ts +0 -6
- package/dist/tools/percy-mcp/v2/get-projects.js +0 -41
- package/dist/tools/percy-mcp/v2/get-snapshot.d.ts +0 -5
- package/dist/tools/percy-mcp/v2/get-snapshot.js +0 -96
- package/dist/tools/percy-mcp/v2/get-test-case-history.d.ts +0 -5
- package/dist/tools/percy-mcp/v2/get-test-case-history.js +0 -20
- package/dist/tools/percy-mcp/v2/get-test-cases.d.ts +0 -6
- package/dist/tools/percy-mcp/v2/get-test-cases.js +0 -36
- package/dist/tools/percy-mcp/v2/index.d.ts +0 -35
- package/dist/tools/percy-mcp/v2/index.js +0 -544
- package/dist/tools/percy-mcp/v2/list-integrations.d.ts +0 -5
- package/dist/tools/percy-mcp/v2/list-integrations.js +0 -41
- package/dist/tools/percy-mcp/v2/manage-domains.d.ts +0 -8
- package/dist/tools/percy-mcp/v2/manage-domains.js +0 -33
- package/dist/tools/percy-mcp/v2/manage-insights-email.d.ts +0 -8
- package/dist/tools/percy-mcp/v2/manage-insights-email.js +0 -49
- package/dist/tools/percy-mcp/v2/manage-usage-alerts.d.ts +0 -10
- package/dist/tools/percy-mcp/v2/manage-usage-alerts.js +0 -43
- package/dist/tools/percy-mcp/v2/migrate-integrations.d.ts +0 -6
- package/dist/tools/percy-mcp/v2/migrate-integrations.js +0 -20
- package/dist/tools/percy-mcp/v2/preview-comparison.d.ts +0 -5
- package/dist/tools/percy-mcp/v2/preview-comparison.js +0 -17
- package/dist/tools/percy-mcp/v2/search-build-items.d.ts +0 -12
- package/dist/tools/percy-mcp/v2/search-build-items.js +0 -45
- package/dist/tools/percy-mcp/workflows/auto-triage.d.ts +0 -7
- package/dist/tools/percy-mcp/workflows/auto-triage.js +0 -82
- package/dist/tools/percy-mcp/workflows/clone-build.d.ts +0 -22
- package/dist/tools/percy-mcp/workflows/clone-build.js +0 -414
- package/dist/tools/percy-mcp/workflows/create-percy-build.d.ts +0 -32
- package/dist/tools/percy-mcp/workflows/create-percy-build.js +0 -434
- package/dist/tools/percy-mcp/workflows/debug-failed-build.d.ts +0 -5
- package/dist/tools/percy-mcp/workflows/debug-failed-build.js +0 -122
- package/dist/tools/percy-mcp/workflows/diff-explain.d.ts +0 -6
- package/dist/tools/percy-mcp/workflows/diff-explain.js +0 -147
- package/dist/tools/percy-mcp/workflows/pr-visual-report.d.ts +0 -8
- package/dist/tools/percy-mcp/workflows/pr-visual-report.js +0 -184
- package/dist/tools/percy-mcp/workflows/run-tests.d.ts +0 -17
- package/dist/tools/percy-mcp/workflows/run-tests.js +0 -107
- package/dist/tools/percy-mcp/workflows/snapshot-urls.d.ts +0 -18
- package/dist/tools/percy-mcp/workflows/snapshot-urls.js +0 -197
|
@@ -1,1137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Percy MCP tools — CRUD-organized tools for Percy visual testing.
|
|
3
|
-
*
|
|
4
|
-
* Registers 41 tools organized by CRUD action:
|
|
5
|
-
*
|
|
6
|
-
* === CREATE (6) ===
|
|
7
|
-
* percy_create_project, percy_create_percy_build, percy_create_build,
|
|
8
|
-
* percy_create_snapshot, percy_create_app_snapshot, percy_create_comparison
|
|
9
|
-
*
|
|
10
|
-
* === READ (17) ===
|
|
11
|
-
* percy_list_projects, percy_list_builds, percy_get_build,
|
|
12
|
-
* percy_get_build_items, percy_get_snapshot, percy_get_comparison,
|
|
13
|
-
* percy_get_ai_analysis, percy_get_build_summary, percy_get_ai_quota,
|
|
14
|
-
* percy_get_rca, percy_get_suggestions, percy_get_network_logs,
|
|
15
|
-
* percy_get_build_logs, percy_get_usage_stats, percy_auth_status
|
|
16
|
-
*
|
|
17
|
-
* === UPDATE (12) ===
|
|
18
|
-
* percy_approve_build, percy_manage_project_settings,
|
|
19
|
-
* percy_manage_browser_targets, percy_manage_tokens,
|
|
20
|
-
* percy_manage_webhooks, percy_manage_ignored_regions,
|
|
21
|
-
* percy_manage_comments, percy_manage_variants,
|
|
22
|
-
* percy_manage_visual_monitoring, percy_trigger_ai_recompute,
|
|
23
|
-
* percy_suggest_prompt, percy_branchline_operations
|
|
24
|
-
*
|
|
25
|
-
* === FINALIZE / UPLOAD (6) ===
|
|
26
|
-
* percy_finalize_build, percy_finalize_snapshot, percy_finalize_comparison,
|
|
27
|
-
* percy_upload_resource, percy_upload_tile, percy_analyze_logs_realtime
|
|
28
|
-
*
|
|
29
|
-
* === WORKFLOWS (4) ===
|
|
30
|
-
* percy_pr_visual_report, percy_auto_triage,
|
|
31
|
-
* percy_debug_failed_build, percy_diff_explain
|
|
32
|
-
*/
|
|
33
|
-
import { handleMCPError } from "../../lib/utils.js";
|
|
34
|
-
import { trackMCP } from "../../index.js";
|
|
35
|
-
import { z } from "zod";
|
|
36
|
-
import { percyListProjects } from "./core/list-projects.js";
|
|
37
|
-
import { percyListBuilds } from "./core/list-builds.js";
|
|
38
|
-
import { percyGetBuild } from "./core/get-build.js";
|
|
39
|
-
import { percyGetBuildItems } from "./core/get-build-items.js";
|
|
40
|
-
import { percyGetSnapshot } from "./core/get-snapshot.js";
|
|
41
|
-
import { percyGetComparison } from "./core/get-comparison.js";
|
|
42
|
-
import { percyCreateBuild } from "./creation/create-build.js";
|
|
43
|
-
import { percyCreateSnapshot } from "./creation/create-snapshot.js";
|
|
44
|
-
import { percyUploadResource } from "./creation/upload-resource.js";
|
|
45
|
-
import { percyFinalizeSnapshot } from "./creation/finalize-snapshot.js";
|
|
46
|
-
import { percyFinalizeBuild } from "./creation/finalize-build.js";
|
|
47
|
-
import { percyCreateAppSnapshot } from "./creation/create-app-snapshot.js";
|
|
48
|
-
import { percyCreateComparison } from "./creation/create-comparison.js";
|
|
49
|
-
import { percyUploadTile } from "./creation/upload-tile.js";
|
|
50
|
-
import { percyFinalizeComparison } from "./creation/finalize-comparison.js";
|
|
51
|
-
import { percyApproveBuild } from "./core/approve-build.js";
|
|
52
|
-
import { percyGetAiAnalysis } from "./intelligence/get-ai-analysis.js";
|
|
53
|
-
import { percyGetBuildSummary } from "./intelligence/get-build-summary.js";
|
|
54
|
-
import { percyGetAiQuota } from "./intelligence/get-ai-quota.js";
|
|
55
|
-
import { percyGetRca } from "./intelligence/get-rca.js";
|
|
56
|
-
import { percyTriggerAiRecompute } from "./intelligence/trigger-ai-recompute.js";
|
|
57
|
-
import { percySuggestPrompt } from "./intelligence/suggest-prompt.js";
|
|
58
|
-
import { percyGetSuggestions } from "./diagnostics/get-suggestions.js";
|
|
59
|
-
import { percyGetNetworkLogs } from "./diagnostics/get-network-logs.js";
|
|
60
|
-
import { percyGetBuildLogs } from "./diagnostics/get-build-logs.js";
|
|
61
|
-
import { percyAnalyzeLogsRealtime } from "./diagnostics/analyze-logs-realtime.js";
|
|
62
|
-
import { percyPrVisualReport } from "./workflows/pr-visual-report.js";
|
|
63
|
-
import { percyCreatePercyBuild } from "./workflows/create-percy-build.js";
|
|
64
|
-
import { percyCloneBuild } from "./workflows/clone-build.js";
|
|
65
|
-
import { percyAutoTriage } from "./workflows/auto-triage.js";
|
|
66
|
-
import { percyDebugFailedBuild } from "./workflows/debug-failed-build.js";
|
|
67
|
-
import { percyDiffExplain } from "./workflows/diff-explain.js";
|
|
68
|
-
import { percySnapshotUrls } from "./workflows/snapshot-urls.js";
|
|
69
|
-
import { percyRunTests } from "./workflows/run-tests.js";
|
|
70
|
-
import { percyAuthStatus } from "./auth/auth-status.js";
|
|
71
|
-
import { percyCreateProject } from "./management/create-project.js";
|
|
72
|
-
import { percyManageProjectSettings } from "./management/manage-project-settings.js";
|
|
73
|
-
import { percyManageBrowserTargets } from "./management/manage-browser-targets.js";
|
|
74
|
-
import { percyManageTokens } from "./management/manage-tokens.js";
|
|
75
|
-
import { percyManageWebhooks } from "./management/manage-webhooks.js";
|
|
76
|
-
import { percyManageIgnoredRegions } from "./management/manage-ignored-regions.js";
|
|
77
|
-
import { percyManageComments } from "./management/manage-comments.js";
|
|
78
|
-
import { percyGetUsageStats } from "./management/get-usage-stats.js";
|
|
79
|
-
import { percyManageVisualMonitoring } from "./advanced/manage-visual-monitoring.js";
|
|
80
|
-
import { percyBranchlineOperations } from "./advanced/branchline-operations.js";
|
|
81
|
-
import { percyManageVariants } from "./advanced/manage-variants.js";
|
|
82
|
-
export function registerPercyMcpTools(server, config) {
|
|
83
|
-
const tools = {};
|
|
84
|
-
// =========================================================================
|
|
85
|
-
// === CREATE ===
|
|
86
|
-
// =========================================================================
|
|
87
|
-
// -------------------------------------------------------------------------
|
|
88
|
-
// percy_create_project
|
|
89
|
-
// -------------------------------------------------------------------------
|
|
90
|
-
tools.percy_create_project = server.tool("percy_create_project", "Create a new Percy project. Auto-creates if doesn't exist, returns project token.", {
|
|
91
|
-
name: z.string().describe("Project name (e.g. 'my-web-app')"),
|
|
92
|
-
type: z
|
|
93
|
-
.enum(["web", "automate"])
|
|
94
|
-
.optional()
|
|
95
|
-
.describe("Project type: 'web' for Percy Web, 'automate' for Percy Automate (default: auto-detect)"),
|
|
96
|
-
}, async (args) => {
|
|
97
|
-
try {
|
|
98
|
-
trackMCP("percy_create_project", server.server.getClientVersion(), config);
|
|
99
|
-
return await percyCreateProject(args, config);
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
return handleMCPError("percy_create_project", server, config, error);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
// -------------------------------------------------------------------------
|
|
106
|
-
// percy_create_percy_build
|
|
107
|
-
// -------------------------------------------------------------------------
|
|
108
|
-
tools.percy_create_percy_build = server.tool("percy_create_percy_build", "Create a complete Percy build with snapshots. Supports URL scanning, screenshot upload, test wrapping, or build cloning. The primary build creation tool.", {
|
|
109
|
-
project_name: z
|
|
110
|
-
.string()
|
|
111
|
-
.describe("Percy project name (auto-creates if doesn't exist)"),
|
|
112
|
-
urls: z
|
|
113
|
-
.string()
|
|
114
|
-
.optional()
|
|
115
|
-
.describe("Comma-separated URLs to snapshot, e.g. 'http://localhost:3000,http://localhost:3000/about'"),
|
|
116
|
-
screenshots_dir: z
|
|
117
|
-
.string()
|
|
118
|
-
.optional()
|
|
119
|
-
.describe("Directory path containing PNG/JPG screenshots to upload"),
|
|
120
|
-
screenshot_files: z
|
|
121
|
-
.string()
|
|
122
|
-
.optional()
|
|
123
|
-
.describe("Comma-separated file paths to PNG/JPG screenshots"),
|
|
124
|
-
test_command: z
|
|
125
|
-
.string()
|
|
126
|
-
.optional()
|
|
127
|
-
.describe("Test command to wrap with Percy, e.g. 'npx cypress run' or 'npm test'"),
|
|
128
|
-
clone_build_id: z
|
|
129
|
-
.string()
|
|
130
|
-
.optional()
|
|
131
|
-
.describe("Build ID to clone snapshots from"),
|
|
132
|
-
branch: z
|
|
133
|
-
.string()
|
|
134
|
-
.optional()
|
|
135
|
-
.describe("Git branch (auto-detected from git if not provided)"),
|
|
136
|
-
commit_sha: z
|
|
137
|
-
.string()
|
|
138
|
-
.optional()
|
|
139
|
-
.describe("Git commit SHA (auto-detected from git if not provided)"),
|
|
140
|
-
widths: z
|
|
141
|
-
.string()
|
|
142
|
-
.optional()
|
|
143
|
-
.describe("Comma-separated viewport widths, e.g. '375,768,1280' (default: 375,1280)"),
|
|
144
|
-
snapshot_names: z
|
|
145
|
-
.string()
|
|
146
|
-
.optional()
|
|
147
|
-
.describe("Comma-separated snapshot names (for screenshots — defaults to filename)"),
|
|
148
|
-
test_case: z
|
|
149
|
-
.string()
|
|
150
|
-
.optional()
|
|
151
|
-
.describe("Test case name to associate snapshots with"),
|
|
152
|
-
type: z
|
|
153
|
-
.enum(["web", "app", "automate"])
|
|
154
|
-
.optional()
|
|
155
|
-
.describe("Project type (default: web)"),
|
|
156
|
-
}, async (args) => {
|
|
157
|
-
try {
|
|
158
|
-
trackMCP("percy_create_percy_build", server.server.getClientVersion(), config);
|
|
159
|
-
return await percyCreatePercyBuild(args, config);
|
|
160
|
-
}
|
|
161
|
-
catch (error) {
|
|
162
|
-
return handleMCPError("percy_create_percy_build", server, config, error);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
// -------------------------------------------------------------------------
|
|
166
|
-
// percy_create_build
|
|
167
|
-
// -------------------------------------------------------------------------
|
|
168
|
-
tools.percy_create_build = server.tool("percy_create_build", "Create an empty Percy build (low-level). Use percy_create_percy_build for full automation.", {
|
|
169
|
-
project_id: z
|
|
170
|
-
.string()
|
|
171
|
-
.optional()
|
|
172
|
-
.describe("Percy project ID (optional if PERCY_TOKEN is project-scoped)"),
|
|
173
|
-
branch: z.string().describe("Git branch name"),
|
|
174
|
-
commit_sha: z.string().describe("Git commit SHA"),
|
|
175
|
-
commit_message: z.string().optional().describe("Git commit message"),
|
|
176
|
-
pull_request_number: z
|
|
177
|
-
.string()
|
|
178
|
-
.optional()
|
|
179
|
-
.describe("Pull request number"),
|
|
180
|
-
type: z
|
|
181
|
-
.string()
|
|
182
|
-
.optional()
|
|
183
|
-
.describe("Project type: web, app, automate, generic"),
|
|
184
|
-
}, async (args) => {
|
|
185
|
-
try {
|
|
186
|
-
trackMCP("percy_create_build", server.server.getClientVersion(), config);
|
|
187
|
-
return await percyCreateBuild(args, config);
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
return handleMCPError("percy_create_build", server, config, error);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
// -------------------------------------------------------------------------
|
|
194
|
-
// percy_create_snapshot
|
|
195
|
-
// -------------------------------------------------------------------------
|
|
196
|
-
tools.percy_create_snapshot = server.tool("percy_create_snapshot", "Create a snapshot in a Percy build with DOM resources (low-level web flow).", {
|
|
197
|
-
build_id: z.string().describe("Percy build ID"),
|
|
198
|
-
name: z.string().describe("Snapshot name"),
|
|
199
|
-
widths: z
|
|
200
|
-
.string()
|
|
201
|
-
.optional()
|
|
202
|
-
.describe("Comma-separated viewport widths, e.g. '375,768,1280'"),
|
|
203
|
-
enable_javascript: z.boolean().optional(),
|
|
204
|
-
resources: z
|
|
205
|
-
.string()
|
|
206
|
-
.optional()
|
|
207
|
-
.describe('JSON array of resources: [{"id":"sha","resource-url":"url","is-root":true}]'),
|
|
208
|
-
}, async (args) => {
|
|
209
|
-
try {
|
|
210
|
-
trackMCP("percy_create_snapshot", server.server.getClientVersion(), config);
|
|
211
|
-
return await percyCreateSnapshot(args, config);
|
|
212
|
-
}
|
|
213
|
-
catch (error) {
|
|
214
|
-
return handleMCPError("percy_create_snapshot", server, config, error);
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
// -------------------------------------------------------------------------
|
|
218
|
-
// percy_create_app_snapshot
|
|
219
|
-
// -------------------------------------------------------------------------
|
|
220
|
-
tools.percy_create_app_snapshot = server.tool("percy_create_app_snapshot", "Create a snapshot for App Percy / screenshot builds (low-level app flow).", {
|
|
221
|
-
build_id: z.string().describe("Percy build ID"),
|
|
222
|
-
name: z.string().describe("Snapshot name"),
|
|
223
|
-
test_case: z.string().optional().describe("Test case name"),
|
|
224
|
-
}, async (args) => {
|
|
225
|
-
try {
|
|
226
|
-
trackMCP("percy_create_app_snapshot", server.server.getClientVersion(), config);
|
|
227
|
-
return await percyCreateAppSnapshot(args, config);
|
|
228
|
-
}
|
|
229
|
-
catch (error) {
|
|
230
|
-
return handleMCPError("percy_create_app_snapshot", server, config, error);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
// -------------------------------------------------------------------------
|
|
234
|
-
// percy_create_comparison
|
|
235
|
-
// -------------------------------------------------------------------------
|
|
236
|
-
tools.percy_create_comparison = server.tool("percy_create_comparison", "Create a comparison with device tag and tiles for screenshot builds (low-level).", {
|
|
237
|
-
snapshot_id: z.string().describe("Percy snapshot ID"),
|
|
238
|
-
tag_name: z.string().describe("Device/browser name, e.g. 'iPhone 13'"),
|
|
239
|
-
tag_width: z.number().describe("Tag width in pixels"),
|
|
240
|
-
tag_height: z.number().describe("Tag height in pixels"),
|
|
241
|
-
tag_os_name: z.string().optional().describe("OS name, e.g. 'iOS'"),
|
|
242
|
-
tag_os_version: z.string().optional().describe("OS version, e.g. '16.0'"),
|
|
243
|
-
tag_browser_name: z
|
|
244
|
-
.string()
|
|
245
|
-
.optional()
|
|
246
|
-
.describe("Browser name, e.g. 'Safari'"),
|
|
247
|
-
tag_orientation: z.string().optional().describe("portrait or landscape"),
|
|
248
|
-
tiles: z
|
|
249
|
-
.string()
|
|
250
|
-
.describe("JSON array of tiles: [{sha, status-bar-height?, nav-bar-height?}]"),
|
|
251
|
-
}, async (args) => {
|
|
252
|
-
try {
|
|
253
|
-
trackMCP("percy_create_comparison", server.server.getClientVersion(), config);
|
|
254
|
-
return await percyCreateComparison(args, config);
|
|
255
|
-
}
|
|
256
|
-
catch (error) {
|
|
257
|
-
return handleMCPError("percy_create_comparison", server, config, error);
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
// -------------------------------------------------------------------------
|
|
261
|
-
// percy_clone_build — Cross-project build cloning
|
|
262
|
-
// -------------------------------------------------------------------------
|
|
263
|
-
tools.percy_clone_build = server.tool("percy_clone_build", "Clone snapshots from one Percy build to another project. Downloads screenshots from source and re-uploads to target. Works across different projects and orgs. Handles the entire flow: read source → create target build → clone each snapshot with comparisons → finalize.", {
|
|
264
|
-
source_build_id: z
|
|
265
|
-
.string()
|
|
266
|
-
.describe("Build ID to clone FROM (the source)"),
|
|
267
|
-
target_project_name: z
|
|
268
|
-
.string()
|
|
269
|
-
.describe("Project name to clone INTO. Use the EXACT project name from Percy dashboard. If project doesn't exist, a new one is created."),
|
|
270
|
-
target_token: z
|
|
271
|
-
.string()
|
|
272
|
-
.optional()
|
|
273
|
-
.describe("Percy token for the TARGET project. Use this to clone into an existing project without creating a new one. Get it from project settings."),
|
|
274
|
-
source_token: z
|
|
275
|
-
.string()
|
|
276
|
-
.optional()
|
|
277
|
-
.describe("Percy token for reading the source build (if different from PERCY_TOKEN). Must be a full-access web_* or auto_* token."),
|
|
278
|
-
branch: z
|
|
279
|
-
.string()
|
|
280
|
-
.optional()
|
|
281
|
-
.describe("Branch for the new build (auto-detected from git)"),
|
|
282
|
-
commit_sha: z
|
|
283
|
-
.string()
|
|
284
|
-
.optional()
|
|
285
|
-
.describe("Commit SHA for the new build (auto-detected from git)"),
|
|
286
|
-
}, async (args) => {
|
|
287
|
-
try {
|
|
288
|
-
trackMCP("percy_clone_build", server.server.getClientVersion(), config);
|
|
289
|
-
return await percyCloneBuild(args, config);
|
|
290
|
-
}
|
|
291
|
-
catch (error) {
|
|
292
|
-
return handleMCPError("percy_clone_build", server, config, error);
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
// =========================================================================
|
|
296
|
-
// === READ ===
|
|
297
|
-
// =========================================================================
|
|
298
|
-
// -------------------------------------------------------------------------
|
|
299
|
-
// percy_list_projects
|
|
300
|
-
// -------------------------------------------------------------------------
|
|
301
|
-
tools.percy_list_projects = server.tool("percy_list_projects", "List all Percy projects in your organization.", {
|
|
302
|
-
org_id: z
|
|
303
|
-
.string()
|
|
304
|
-
.optional()
|
|
305
|
-
.describe("Percy organization ID. If not provided, uses token scope."),
|
|
306
|
-
search: z
|
|
307
|
-
.string()
|
|
308
|
-
.optional()
|
|
309
|
-
.describe("Filter projects by name (substring match)"),
|
|
310
|
-
limit: z.number().optional().describe("Max results (default 10, max 50)"),
|
|
311
|
-
}, async (args) => {
|
|
312
|
-
try {
|
|
313
|
-
trackMCP("percy_list_projects", server.server.getClientVersion(), config);
|
|
314
|
-
return await percyListProjects(args, config);
|
|
315
|
-
}
|
|
316
|
-
catch (error) {
|
|
317
|
-
return handleMCPError("percy_list_projects", server, config, error);
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
// -------------------------------------------------------------------------
|
|
321
|
-
// percy_list_builds
|
|
322
|
-
// -------------------------------------------------------------------------
|
|
323
|
-
tools.percy_list_builds = server.tool("percy_list_builds", "List Percy builds with filters (branch, state, SHA, tags).", {
|
|
324
|
-
project_id: z
|
|
325
|
-
.string()
|
|
326
|
-
.optional()
|
|
327
|
-
.describe("Percy project ID. If not provided, uses PERCY_TOKEN scope."),
|
|
328
|
-
branch: z.string().optional().describe("Filter by branch name"),
|
|
329
|
-
state: z
|
|
330
|
-
.string()
|
|
331
|
-
.optional()
|
|
332
|
-
.describe("Filter by state: pending, processing, finished, failed"),
|
|
333
|
-
sha: z.string().optional().describe("Filter by commit SHA"),
|
|
334
|
-
limit: z.number().optional().describe("Max results (default 10, max 30)"),
|
|
335
|
-
}, async (args) => {
|
|
336
|
-
try {
|
|
337
|
-
trackMCP("percy_list_builds", server.server.getClientVersion(), config);
|
|
338
|
-
return await percyListBuilds(args, config);
|
|
339
|
-
}
|
|
340
|
-
catch (error) {
|
|
341
|
-
return handleMCPError("percy_list_builds", server, config, error);
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
// -------------------------------------------------------------------------
|
|
345
|
-
// percy_get_build
|
|
346
|
-
// -------------------------------------------------------------------------
|
|
347
|
-
tools.percy_get_build = server.tool("percy_get_build", "Get full Percy build details: state, snapshots, AI metrics, summary.", {
|
|
348
|
-
build_id: z.string().describe("Percy build ID"),
|
|
349
|
-
}, async (args) => {
|
|
350
|
-
try {
|
|
351
|
-
trackMCP("percy_get_build", server.server.getClientVersion(), config);
|
|
352
|
-
return await percyGetBuild(args, config);
|
|
353
|
-
}
|
|
354
|
-
catch (error) {
|
|
355
|
-
return handleMCPError("percy_get_build", server, config, error);
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
// -------------------------------------------------------------------------
|
|
359
|
-
// percy_get_build_items
|
|
360
|
-
// -------------------------------------------------------------------------
|
|
361
|
-
tools.percy_get_build_items = server.tool("percy_get_build_items", "List snapshots in a build by category: changed, new, removed, unchanged, failed.", {
|
|
362
|
-
build_id: z.string().describe("Percy build ID"),
|
|
363
|
-
category: z
|
|
364
|
-
.string()
|
|
365
|
-
.optional()
|
|
366
|
-
.describe("Filter category: changed, new, removed, unchanged, failed"),
|
|
367
|
-
sort_by: z
|
|
368
|
-
.string()
|
|
369
|
-
.optional()
|
|
370
|
-
.describe("Sort field (e.g. diff-ratio, name)"),
|
|
371
|
-
limit: z
|
|
372
|
-
.number()
|
|
373
|
-
.optional()
|
|
374
|
-
.describe("Max results (default 20, max 100)"),
|
|
375
|
-
}, async (args) => {
|
|
376
|
-
try {
|
|
377
|
-
trackMCP("percy_get_build_items", server.server.getClientVersion(), config);
|
|
378
|
-
return await percyGetBuildItems(args, config);
|
|
379
|
-
}
|
|
380
|
-
catch (error) {
|
|
381
|
-
return handleMCPError("percy_get_build_items", server, config, error);
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
// -------------------------------------------------------------------------
|
|
385
|
-
// percy_get_snapshot
|
|
386
|
-
// -------------------------------------------------------------------------
|
|
387
|
-
tools.percy_get_snapshot = server.tool("percy_get_snapshot", "Get snapshot with all comparisons, screenshots, and diff data.", {
|
|
388
|
-
snapshot_id: z.string().describe("Percy snapshot ID"),
|
|
389
|
-
}, async (args) => {
|
|
390
|
-
try {
|
|
391
|
-
trackMCP("percy_get_snapshot", server.server.getClientVersion(), config);
|
|
392
|
-
return await percyGetSnapshot(args, config);
|
|
393
|
-
}
|
|
394
|
-
catch (error) {
|
|
395
|
-
return handleMCPError("percy_get_snapshot", server, config, error);
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
// -------------------------------------------------------------------------
|
|
399
|
-
// percy_get_comparison
|
|
400
|
-
// -------------------------------------------------------------------------
|
|
401
|
-
tools.percy_get_comparison = server.tool("percy_get_comparison", "Get comparison details: diff ratio, AI analysis, screenshot URLs.", {
|
|
402
|
-
comparison_id: z.string().describe("Percy comparison ID"),
|
|
403
|
-
include_images: z
|
|
404
|
-
.boolean()
|
|
405
|
-
.optional()
|
|
406
|
-
.describe("Include screenshot image URLs in response (default false)"),
|
|
407
|
-
}, async (args) => {
|
|
408
|
-
try {
|
|
409
|
-
trackMCP("percy_get_comparison", server.server.getClientVersion(), config);
|
|
410
|
-
return await percyGetComparison(args, config);
|
|
411
|
-
}
|
|
412
|
-
catch (error) {
|
|
413
|
-
return handleMCPError("percy_get_comparison", server, config, error);
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
// -------------------------------------------------------------------------
|
|
417
|
-
// percy_get_ai_analysis
|
|
418
|
-
// -------------------------------------------------------------------------
|
|
419
|
-
tools.percy_get_ai_analysis = server.tool("percy_get_ai_analysis", "Get AI visual diff analysis: change types, bug classifications, diff reduction.", {
|
|
420
|
-
comparison_id: z
|
|
421
|
-
.string()
|
|
422
|
-
.optional()
|
|
423
|
-
.describe("Get AI analysis for a single comparison"),
|
|
424
|
-
build_id: z
|
|
425
|
-
.string()
|
|
426
|
-
.optional()
|
|
427
|
-
.describe("Get aggregated AI analysis for an entire build"),
|
|
428
|
-
}, async (args) => {
|
|
429
|
-
try {
|
|
430
|
-
trackMCP("percy_get_ai_analysis", server.server.getClientVersion(), config);
|
|
431
|
-
return await percyGetAiAnalysis(args, config);
|
|
432
|
-
}
|
|
433
|
-
catch (error) {
|
|
434
|
-
return handleMCPError("percy_get_ai_analysis", server, config, error);
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
// -------------------------------------------------------------------------
|
|
438
|
-
// percy_get_build_summary
|
|
439
|
-
// -------------------------------------------------------------------------
|
|
440
|
-
tools.percy_get_build_summary = server.tool("percy_get_build_summary", "Get AI-generated natural language summary of all visual changes.", {
|
|
441
|
-
build_id: z.string().describe("Percy build ID"),
|
|
442
|
-
}, async (args) => {
|
|
443
|
-
try {
|
|
444
|
-
trackMCP("percy_get_build_summary", server.server.getClientVersion(), config);
|
|
445
|
-
return await percyGetBuildSummary(args, config);
|
|
446
|
-
}
|
|
447
|
-
catch (error) {
|
|
448
|
-
return handleMCPError("percy_get_build_summary", server, config, error);
|
|
449
|
-
}
|
|
450
|
-
});
|
|
451
|
-
// -------------------------------------------------------------------------
|
|
452
|
-
// percy_get_ai_quota
|
|
453
|
-
// -------------------------------------------------------------------------
|
|
454
|
-
tools.percy_get_ai_quota = server.tool("percy_get_ai_quota", "Check AI regeneration quota: daily usage and limits.", {}, async () => {
|
|
455
|
-
try {
|
|
456
|
-
trackMCP("percy_get_ai_quota", server.server.getClientVersion(), config);
|
|
457
|
-
return await percyGetAiQuota({}, config);
|
|
458
|
-
}
|
|
459
|
-
catch (error) {
|
|
460
|
-
return handleMCPError("percy_get_ai_quota", server, config, error);
|
|
461
|
-
}
|
|
462
|
-
});
|
|
463
|
-
// -------------------------------------------------------------------------
|
|
464
|
-
// percy_get_rca
|
|
465
|
-
// -------------------------------------------------------------------------
|
|
466
|
-
tools.percy_get_rca = server.tool("percy_get_rca", "Get Root Cause Analysis: maps visual diffs to DOM/CSS changes.", {
|
|
467
|
-
comparison_id: z.string().describe("Percy comparison ID"),
|
|
468
|
-
trigger_if_missing: z
|
|
469
|
-
.boolean()
|
|
470
|
-
.optional()
|
|
471
|
-
.describe("Auto-trigger RCA if not yet run (default true)"),
|
|
472
|
-
}, async (args) => {
|
|
473
|
-
try {
|
|
474
|
-
trackMCP("percy_get_rca", server.server.getClientVersion(), config);
|
|
475
|
-
return await percyGetRca(args, config);
|
|
476
|
-
}
|
|
477
|
-
catch (error) {
|
|
478
|
-
return handleMCPError("percy_get_rca", server, config, error);
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
// -------------------------------------------------------------------------
|
|
482
|
-
// percy_get_suggestions
|
|
483
|
-
// -------------------------------------------------------------------------
|
|
484
|
-
tools.percy_get_suggestions = server.tool("percy_get_suggestions", "Get build failure diagnostics: categorized issues with fix steps.", {
|
|
485
|
-
build_id: z.string().describe("Percy build ID"),
|
|
486
|
-
reference_type: z
|
|
487
|
-
.string()
|
|
488
|
-
.optional()
|
|
489
|
-
.describe("Filter: build, snapshot, or comparison"),
|
|
490
|
-
reference_id: z
|
|
491
|
-
.string()
|
|
492
|
-
.optional()
|
|
493
|
-
.describe("Specific snapshot or comparison ID"),
|
|
494
|
-
}, async (args) => {
|
|
495
|
-
try {
|
|
496
|
-
trackMCP("percy_get_suggestions", server.server.getClientVersion(), config);
|
|
497
|
-
return await percyGetSuggestions(args, config);
|
|
498
|
-
}
|
|
499
|
-
catch (error) {
|
|
500
|
-
return handleMCPError("percy_get_suggestions", server, config, error);
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
// -------------------------------------------------------------------------
|
|
504
|
-
// percy_get_network_logs
|
|
505
|
-
// -------------------------------------------------------------------------
|
|
506
|
-
tools.percy_get_network_logs = server.tool("percy_get_network_logs", "Get network request logs: per-URL status comparison (base vs head).", {
|
|
507
|
-
comparison_id: z.string().describe("Percy comparison ID"),
|
|
508
|
-
}, async (args) => {
|
|
509
|
-
try {
|
|
510
|
-
trackMCP("percy_get_network_logs", server.server.getClientVersion(), config);
|
|
511
|
-
return await percyGetNetworkLogs(args, config);
|
|
512
|
-
}
|
|
513
|
-
catch (error) {
|
|
514
|
-
return handleMCPError("percy_get_network_logs", server, config, error);
|
|
515
|
-
}
|
|
516
|
-
});
|
|
517
|
-
// -------------------------------------------------------------------------
|
|
518
|
-
// percy_get_build_logs
|
|
519
|
-
// -------------------------------------------------------------------------
|
|
520
|
-
tools.percy_get_build_logs = server.tool("percy_get_build_logs", "Get raw build logs (CLI, renderer, proxy) with level filtering.", {
|
|
521
|
-
build_id: z.string().describe("Percy build ID"),
|
|
522
|
-
service: z
|
|
523
|
-
.string()
|
|
524
|
-
.optional()
|
|
525
|
-
.describe("Filter by service: cli, renderer, jackproxy"),
|
|
526
|
-
reference_type: z
|
|
527
|
-
.string()
|
|
528
|
-
.optional()
|
|
529
|
-
.describe("Reference scope: build, snapshot, comparison"),
|
|
530
|
-
reference_id: z
|
|
531
|
-
.string()
|
|
532
|
-
.optional()
|
|
533
|
-
.describe("Specific snapshot or comparison ID"),
|
|
534
|
-
level: z
|
|
535
|
-
.string()
|
|
536
|
-
.optional()
|
|
537
|
-
.describe("Filter by log level: error, warn, info, debug"),
|
|
538
|
-
}, async (args) => {
|
|
539
|
-
try {
|
|
540
|
-
trackMCP("percy_get_build_logs", server.server.getClientVersion(), config);
|
|
541
|
-
return await percyGetBuildLogs(args, config);
|
|
542
|
-
}
|
|
543
|
-
catch (error) {
|
|
544
|
-
return handleMCPError("percy_get_build_logs", server, config, error);
|
|
545
|
-
}
|
|
546
|
-
});
|
|
547
|
-
// -------------------------------------------------------------------------
|
|
548
|
-
// percy_get_usage_stats
|
|
549
|
-
// -------------------------------------------------------------------------
|
|
550
|
-
tools.percy_get_usage_stats = server.tool("percy_get_usage_stats", "Get organization usage: screenshot counts, quotas, AI comparisons.", {
|
|
551
|
-
org_id: z.string().describe("Percy organization ID"),
|
|
552
|
-
product: z
|
|
553
|
-
.string()
|
|
554
|
-
.optional()
|
|
555
|
-
.describe("Filter by product type (e.g., 'percy', 'app_percy')"),
|
|
556
|
-
}, async (args) => {
|
|
557
|
-
try {
|
|
558
|
-
trackMCP("percy_get_usage_stats", server.server.getClientVersion(), config);
|
|
559
|
-
return await percyGetUsageStats(args, config);
|
|
560
|
-
}
|
|
561
|
-
catch (error) {
|
|
562
|
-
return handleMCPError("percy_get_usage_stats", server, config, error);
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
// -------------------------------------------------------------------------
|
|
566
|
-
// percy_auth_status
|
|
567
|
-
// -------------------------------------------------------------------------
|
|
568
|
-
tools.percy_auth_status = server.tool("percy_auth_status", "Check Percy auth: which tokens are set, validated, and their scope.", {}, async () => {
|
|
569
|
-
try {
|
|
570
|
-
trackMCP("percy_auth_status", server.server.getClientVersion(), config);
|
|
571
|
-
return await percyAuthStatus({}, config);
|
|
572
|
-
}
|
|
573
|
-
catch (error) {
|
|
574
|
-
return handleMCPError("percy_auth_status", server, config, error);
|
|
575
|
-
}
|
|
576
|
-
});
|
|
577
|
-
// =========================================================================
|
|
578
|
-
// === UPDATE ===
|
|
579
|
-
// =========================================================================
|
|
580
|
-
// -------------------------------------------------------------------------
|
|
581
|
-
// percy_approve_build
|
|
582
|
-
// -------------------------------------------------------------------------
|
|
583
|
-
tools.percy_approve_build = server.tool("percy_approve_build", "Approve, reject, or request changes on a Percy build.", {
|
|
584
|
-
build_id: z.string().describe("Percy build ID to review"),
|
|
585
|
-
action: z
|
|
586
|
-
.enum(["approve", "request_changes", "unapprove", "reject"])
|
|
587
|
-
.describe("Review action"),
|
|
588
|
-
snapshot_ids: z
|
|
589
|
-
.string()
|
|
590
|
-
.optional()
|
|
591
|
-
.describe("Comma-separated snapshot IDs (required for request_changes)"),
|
|
592
|
-
reason: z
|
|
593
|
-
.string()
|
|
594
|
-
.optional()
|
|
595
|
-
.describe("Optional reason for the review action"),
|
|
596
|
-
}, async (args) => {
|
|
597
|
-
try {
|
|
598
|
-
trackMCP("percy_approve_build", server.server.getClientVersion(), config);
|
|
599
|
-
return await percyApproveBuild(args, config);
|
|
600
|
-
}
|
|
601
|
-
catch (error) {
|
|
602
|
-
return handleMCPError("percy_approve_build", server, config, error);
|
|
603
|
-
}
|
|
604
|
-
});
|
|
605
|
-
// -------------------------------------------------------------------------
|
|
606
|
-
// percy_manage_project_settings
|
|
607
|
-
// -------------------------------------------------------------------------
|
|
608
|
-
tools.percy_manage_project_settings = server.tool("percy_manage_project_settings", "Update Percy project settings: diff sensitivity, auto-approve, IntelliIgnore.", {
|
|
609
|
-
project_id: z.string().describe("Percy project ID"),
|
|
610
|
-
settings: z
|
|
611
|
-
.string()
|
|
612
|
-
.optional()
|
|
613
|
-
.describe('JSON string of attributes to update, e.g. \'{"diff-sensitivity":0.1,"auto-approve-branch-filter":"main"}\''),
|
|
614
|
-
confirm_destructive: z
|
|
615
|
-
.boolean()
|
|
616
|
-
.optional()
|
|
617
|
-
.describe("Set to true to confirm high-risk changes (auto-approve/approval-required branch filters)"),
|
|
618
|
-
}, async (args) => {
|
|
619
|
-
try {
|
|
620
|
-
trackMCP("percy_manage_project_settings", server.server.getClientVersion(), config);
|
|
621
|
-
return await percyManageProjectSettings(args, config);
|
|
622
|
-
}
|
|
623
|
-
catch (error) {
|
|
624
|
-
return handleMCPError("percy_manage_project_settings", server, config, error);
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
|
-
// -------------------------------------------------------------------------
|
|
628
|
-
// percy_manage_browser_targets
|
|
629
|
-
// -------------------------------------------------------------------------
|
|
630
|
-
tools.percy_manage_browser_targets = server.tool("percy_manage_browser_targets", "Add or remove browser targets (Chrome, Firefox, Safari, Edge).", {
|
|
631
|
-
project_id: z.string().describe("Percy project ID"),
|
|
632
|
-
action: z
|
|
633
|
-
.enum(["list", "add", "remove"])
|
|
634
|
-
.optional()
|
|
635
|
-
.describe("Action to perform (default: list)"),
|
|
636
|
-
browser_family: z
|
|
637
|
-
.string()
|
|
638
|
-
.optional()
|
|
639
|
-
.describe("Browser family ID to add or project-browser-target ID to remove"),
|
|
640
|
-
}, async (args) => {
|
|
641
|
-
try {
|
|
642
|
-
trackMCP("percy_manage_browser_targets", server.server.getClientVersion(), config);
|
|
643
|
-
return await percyManageBrowserTargets(args, config);
|
|
644
|
-
}
|
|
645
|
-
catch (error) {
|
|
646
|
-
return handleMCPError("percy_manage_browser_targets", server, config, error);
|
|
647
|
-
}
|
|
648
|
-
});
|
|
649
|
-
// -------------------------------------------------------------------------
|
|
650
|
-
// percy_manage_tokens
|
|
651
|
-
// -------------------------------------------------------------------------
|
|
652
|
-
tools.percy_manage_tokens = server.tool("percy_manage_tokens", "View (masked) or rotate Percy project tokens.", {
|
|
653
|
-
project_id: z.string().describe("Percy project ID"),
|
|
654
|
-
action: z
|
|
655
|
-
.enum(["list", "rotate"])
|
|
656
|
-
.optional()
|
|
657
|
-
.describe("Action to perform (default: list)"),
|
|
658
|
-
role: z
|
|
659
|
-
.string()
|
|
660
|
-
.optional()
|
|
661
|
-
.describe("Token role for rotation (e.g., 'write', 'read')"),
|
|
662
|
-
}, async (args) => {
|
|
663
|
-
try {
|
|
664
|
-
trackMCP("percy_manage_tokens", server.server.getClientVersion(), config);
|
|
665
|
-
return await percyManageTokens(args, config);
|
|
666
|
-
}
|
|
667
|
-
catch (error) {
|
|
668
|
-
return handleMCPError("percy_manage_tokens", server, config, error);
|
|
669
|
-
}
|
|
670
|
-
});
|
|
671
|
-
// -------------------------------------------------------------------------
|
|
672
|
-
// percy_manage_webhooks
|
|
673
|
-
// -------------------------------------------------------------------------
|
|
674
|
-
tools.percy_manage_webhooks = server.tool("percy_manage_webhooks", "Create, update, or delete webhooks for build events.", {
|
|
675
|
-
project_id: z.string().describe("Percy project ID"),
|
|
676
|
-
action: z
|
|
677
|
-
.enum(["list", "create", "update", "delete"])
|
|
678
|
-
.optional()
|
|
679
|
-
.describe("Action to perform (default: list)"),
|
|
680
|
-
webhook_id: z
|
|
681
|
-
.string()
|
|
682
|
-
.optional()
|
|
683
|
-
.describe("Webhook ID (required for update/delete)"),
|
|
684
|
-
url: z.string().optional().describe("Webhook URL (required for create)"),
|
|
685
|
-
events: z
|
|
686
|
-
.string()
|
|
687
|
-
.optional()
|
|
688
|
-
.describe("Comma-separated event types, e.g. 'build:finished,build:failed'"),
|
|
689
|
-
description: z
|
|
690
|
-
.string()
|
|
691
|
-
.optional()
|
|
692
|
-
.describe("Human-readable webhook description"),
|
|
693
|
-
}, async (args) => {
|
|
694
|
-
try {
|
|
695
|
-
trackMCP("percy_manage_webhooks", server.server.getClientVersion(), config);
|
|
696
|
-
return await percyManageWebhooks(args, config);
|
|
697
|
-
}
|
|
698
|
-
catch (error) {
|
|
699
|
-
return handleMCPError("percy_manage_webhooks", server, config, error);
|
|
700
|
-
}
|
|
701
|
-
});
|
|
702
|
-
// -------------------------------------------------------------------------
|
|
703
|
-
// percy_manage_ignored_regions
|
|
704
|
-
// -------------------------------------------------------------------------
|
|
705
|
-
tools.percy_manage_ignored_regions = server.tool("percy_manage_ignored_regions", "Create, save, or delete ignored regions on comparisons.", {
|
|
706
|
-
comparison_id: z
|
|
707
|
-
.string()
|
|
708
|
-
.optional()
|
|
709
|
-
.describe("Percy comparison ID (required for list/create)"),
|
|
710
|
-
action: z
|
|
711
|
-
.enum(["list", "create", "save", "delete"])
|
|
712
|
-
.optional()
|
|
713
|
-
.describe("Action to perform (default: list)"),
|
|
714
|
-
region_id: z
|
|
715
|
-
.string()
|
|
716
|
-
.optional()
|
|
717
|
-
.describe("Region revision ID (required for delete)"),
|
|
718
|
-
type: z
|
|
719
|
-
.string()
|
|
720
|
-
.optional()
|
|
721
|
-
.describe("Region type: raw, xpath, css, full_page"),
|
|
722
|
-
coordinates: z
|
|
723
|
-
.string()
|
|
724
|
-
.optional()
|
|
725
|
-
.describe('JSON bounding box for raw type: {"x":0,"y":0,"width":100,"height":100}'),
|
|
726
|
-
selector: z.string().optional().describe("XPath or CSS selector string"),
|
|
727
|
-
}, async (args) => {
|
|
728
|
-
try {
|
|
729
|
-
trackMCP("percy_manage_ignored_regions", server.server.getClientVersion(), config);
|
|
730
|
-
return await percyManageIgnoredRegions(args, config);
|
|
731
|
-
}
|
|
732
|
-
catch (error) {
|
|
733
|
-
return handleMCPError("percy_manage_ignored_regions", server, config, error);
|
|
734
|
-
}
|
|
735
|
-
});
|
|
736
|
-
// -------------------------------------------------------------------------
|
|
737
|
-
// percy_manage_comments
|
|
738
|
-
// -------------------------------------------------------------------------
|
|
739
|
-
tools.percy_manage_comments = server.tool("percy_manage_comments", "Create or close comment threads on snapshots.", {
|
|
740
|
-
build_id: z
|
|
741
|
-
.string()
|
|
742
|
-
.optional()
|
|
743
|
-
.describe("Percy build ID (required for list)"),
|
|
744
|
-
snapshot_id: z
|
|
745
|
-
.string()
|
|
746
|
-
.optional()
|
|
747
|
-
.describe("Percy snapshot ID (required for create)"),
|
|
748
|
-
action: z
|
|
749
|
-
.enum(["list", "create", "close"])
|
|
750
|
-
.optional()
|
|
751
|
-
.describe("Action to perform (default: list)"),
|
|
752
|
-
thread_id: z
|
|
753
|
-
.string()
|
|
754
|
-
.optional()
|
|
755
|
-
.describe("Comment thread ID (required for close)"),
|
|
756
|
-
body: z
|
|
757
|
-
.string()
|
|
758
|
-
.optional()
|
|
759
|
-
.describe("Comment body text (required for create)"),
|
|
760
|
-
}, async (args) => {
|
|
761
|
-
try {
|
|
762
|
-
trackMCP("percy_manage_comments", server.server.getClientVersion(), config);
|
|
763
|
-
return await percyManageComments(args, config);
|
|
764
|
-
}
|
|
765
|
-
catch (error) {
|
|
766
|
-
return handleMCPError("percy_manage_comments", server, config, error);
|
|
767
|
-
}
|
|
768
|
-
});
|
|
769
|
-
// -------------------------------------------------------------------------
|
|
770
|
-
// percy_manage_variants
|
|
771
|
-
// -------------------------------------------------------------------------
|
|
772
|
-
tools.percy_manage_variants = server.tool("percy_manage_variants", "Create or update A/B testing variants.", {
|
|
773
|
-
comparison_id: z
|
|
774
|
-
.string()
|
|
775
|
-
.optional()
|
|
776
|
-
.describe("Percy comparison ID (required for list)"),
|
|
777
|
-
snapshot_id: z
|
|
778
|
-
.string()
|
|
779
|
-
.optional()
|
|
780
|
-
.describe("Percy snapshot ID (required for create)"),
|
|
781
|
-
action: z
|
|
782
|
-
.enum(["list", "create", "update"])
|
|
783
|
-
.optional()
|
|
784
|
-
.describe("Action to perform (default: list)"),
|
|
785
|
-
variant_id: z
|
|
786
|
-
.string()
|
|
787
|
-
.optional()
|
|
788
|
-
.describe("Variant ID (required for update)"),
|
|
789
|
-
name: z
|
|
790
|
-
.string()
|
|
791
|
-
.optional()
|
|
792
|
-
.describe("Variant name (required for create)"),
|
|
793
|
-
state: z.string().optional().describe("Variant state (for update)"),
|
|
794
|
-
}, async (args) => {
|
|
795
|
-
try {
|
|
796
|
-
trackMCP("percy_manage_variants", server.server.getClientVersion(), config);
|
|
797
|
-
return await percyManageVariants(args, config);
|
|
798
|
-
}
|
|
799
|
-
catch (error) {
|
|
800
|
-
return handleMCPError("percy_manage_variants", server, config, error);
|
|
801
|
-
}
|
|
802
|
-
});
|
|
803
|
-
// -------------------------------------------------------------------------
|
|
804
|
-
// percy_manage_visual_monitoring
|
|
805
|
-
// -------------------------------------------------------------------------
|
|
806
|
-
tools.percy_manage_visual_monitoring = server.tool("percy_manage_visual_monitoring", "Create or update Visual Monitoring projects.", {
|
|
807
|
-
org_id: z
|
|
808
|
-
.string()
|
|
809
|
-
.optional()
|
|
810
|
-
.describe("Percy organization ID (required for list/create)"),
|
|
811
|
-
project_id: z
|
|
812
|
-
.string()
|
|
813
|
-
.optional()
|
|
814
|
-
.describe("Visual Monitoring project ID (required for update)"),
|
|
815
|
-
action: z
|
|
816
|
-
.enum(["list", "create", "update"])
|
|
817
|
-
.optional()
|
|
818
|
-
.describe("Action to perform (default: list)"),
|
|
819
|
-
urls: z
|
|
820
|
-
.string()
|
|
821
|
-
.optional()
|
|
822
|
-
.describe("Comma-separated URLs to monitor, e.g. 'https://example.com,https://example.com/about'"),
|
|
823
|
-
cron: z
|
|
824
|
-
.string()
|
|
825
|
-
.optional()
|
|
826
|
-
.describe("Cron expression for monitoring schedule, e.g. '0 */6 * * *'"),
|
|
827
|
-
schedule: z
|
|
828
|
-
.boolean()
|
|
829
|
-
.optional()
|
|
830
|
-
.describe("Enable or disable the monitoring schedule"),
|
|
831
|
-
}, async (args) => {
|
|
832
|
-
try {
|
|
833
|
-
trackMCP("percy_manage_visual_monitoring", server.server.getClientVersion(), config);
|
|
834
|
-
return await percyManageVisualMonitoring(args, config);
|
|
835
|
-
}
|
|
836
|
-
catch (error) {
|
|
837
|
-
return handleMCPError("percy_manage_visual_monitoring", server, config, error);
|
|
838
|
-
}
|
|
839
|
-
});
|
|
840
|
-
// -------------------------------------------------------------------------
|
|
841
|
-
// percy_trigger_ai_recompute
|
|
842
|
-
// -------------------------------------------------------------------------
|
|
843
|
-
tools.percy_trigger_ai_recompute = server.tool("percy_trigger_ai_recompute", "Re-run AI analysis with a custom prompt.", {
|
|
844
|
-
build_id: z
|
|
845
|
-
.string()
|
|
846
|
-
.optional()
|
|
847
|
-
.describe("Percy build ID (for bulk recompute)"),
|
|
848
|
-
comparison_id: z
|
|
849
|
-
.string()
|
|
850
|
-
.optional()
|
|
851
|
-
.describe("Single comparison ID to recompute"),
|
|
852
|
-
prompt: z
|
|
853
|
-
.string()
|
|
854
|
-
.optional()
|
|
855
|
-
.describe("Custom prompt for AI (max 400 chars), e.g. 'Ignore font rendering differences'"),
|
|
856
|
-
mode: z
|
|
857
|
-
.enum(["ignore", "unignore"])
|
|
858
|
-
.optional()
|
|
859
|
-
.describe("ignore = hide matching diffs, unignore = show matching diffs"),
|
|
860
|
-
}, async (args) => {
|
|
861
|
-
try {
|
|
862
|
-
trackMCP("percy_trigger_ai_recompute", server.server.getClientVersion(), config);
|
|
863
|
-
return await percyTriggerAiRecompute(args, config);
|
|
864
|
-
}
|
|
865
|
-
catch (error) {
|
|
866
|
-
return handleMCPError("percy_trigger_ai_recompute", server, config, error);
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
// -------------------------------------------------------------------------
|
|
870
|
-
// percy_suggest_prompt
|
|
871
|
-
// -------------------------------------------------------------------------
|
|
872
|
-
tools.percy_suggest_prompt = server.tool("percy_suggest_prompt", "Get AI-suggested prompt for specific diff regions.", {
|
|
873
|
-
comparison_id: z.string().describe("Percy comparison ID"),
|
|
874
|
-
region_ids: z.string().describe("Comma-separated region IDs to analyze"),
|
|
875
|
-
ignore_change: z
|
|
876
|
-
.boolean()
|
|
877
|
-
.optional()
|
|
878
|
-
.describe("true = suggest ignore prompt, false = suggest show prompt (default true)"),
|
|
879
|
-
}, async (args) => {
|
|
880
|
-
try {
|
|
881
|
-
trackMCP("percy_suggest_prompt", server.server.getClientVersion(), config);
|
|
882
|
-
return await percySuggestPrompt(args, config);
|
|
883
|
-
}
|
|
884
|
-
catch (error) {
|
|
885
|
-
return handleMCPError("percy_suggest_prompt", server, config, error);
|
|
886
|
-
}
|
|
887
|
-
});
|
|
888
|
-
// -------------------------------------------------------------------------
|
|
889
|
-
// percy_branchline_operations
|
|
890
|
-
// -------------------------------------------------------------------------
|
|
891
|
-
tools.percy_branchline_operations = server.tool("percy_branchline_operations", "Sync, merge, or unmerge branch baselines.", {
|
|
892
|
-
action: z
|
|
893
|
-
.enum(["sync", "merge", "unmerge"])
|
|
894
|
-
.describe("Branchline operation to perform"),
|
|
895
|
-
project_id: z.string().optional().describe("Percy project ID"),
|
|
896
|
-
build_id: z.string().optional().describe("Percy build ID"),
|
|
897
|
-
target_branch_filter: z
|
|
898
|
-
.string()
|
|
899
|
-
.optional()
|
|
900
|
-
.describe("Target branch pattern for sync (e.g., 'main', 'release/*')"),
|
|
901
|
-
snapshot_ids: z
|
|
902
|
-
.string()
|
|
903
|
-
.optional()
|
|
904
|
-
.describe("Comma-separated snapshot IDs to include"),
|
|
905
|
-
}, async (args) => {
|
|
906
|
-
try {
|
|
907
|
-
trackMCP("percy_branchline_operations", server.server.getClientVersion(), config);
|
|
908
|
-
return await percyBranchlineOperations(args, config);
|
|
909
|
-
}
|
|
910
|
-
catch (error) {
|
|
911
|
-
return handleMCPError("percy_branchline_operations", server, config, error);
|
|
912
|
-
}
|
|
913
|
-
});
|
|
914
|
-
// =========================================================================
|
|
915
|
-
// === FINALIZE / UPLOAD ===
|
|
916
|
-
// =========================================================================
|
|
917
|
-
// -------------------------------------------------------------------------
|
|
918
|
-
// percy_finalize_build
|
|
919
|
-
// -------------------------------------------------------------------------
|
|
920
|
-
tools.percy_finalize_build = server.tool("percy_finalize_build", "Finalize a Percy build (triggers processing).", {
|
|
921
|
-
build_id: z.string().describe("Percy build ID"),
|
|
922
|
-
}, async (args) => {
|
|
923
|
-
try {
|
|
924
|
-
trackMCP("percy_finalize_build", server.server.getClientVersion(), config);
|
|
925
|
-
return await percyFinalizeBuild(args, config);
|
|
926
|
-
}
|
|
927
|
-
catch (error) {
|
|
928
|
-
return handleMCPError("percy_finalize_build", server, config, error);
|
|
929
|
-
}
|
|
930
|
-
});
|
|
931
|
-
// -------------------------------------------------------------------------
|
|
932
|
-
// percy_finalize_snapshot
|
|
933
|
-
// -------------------------------------------------------------------------
|
|
934
|
-
tools.percy_finalize_snapshot = server.tool("percy_finalize_snapshot", "Finalize a snapshot (triggers rendering).", {
|
|
935
|
-
snapshot_id: z.string().describe("Percy snapshot ID"),
|
|
936
|
-
}, async (args) => {
|
|
937
|
-
try {
|
|
938
|
-
trackMCP("percy_finalize_snapshot", server.server.getClientVersion(), config);
|
|
939
|
-
return await percyFinalizeSnapshot(args, config);
|
|
940
|
-
}
|
|
941
|
-
catch (error) {
|
|
942
|
-
return handleMCPError("percy_finalize_snapshot", server, config, error);
|
|
943
|
-
}
|
|
944
|
-
});
|
|
945
|
-
// -------------------------------------------------------------------------
|
|
946
|
-
// percy_finalize_comparison
|
|
947
|
-
// -------------------------------------------------------------------------
|
|
948
|
-
tools.percy_finalize_comparison = server.tool("percy_finalize_comparison", "Finalize a comparison (triggers diff processing).", {
|
|
949
|
-
comparison_id: z.string().describe("Percy comparison ID"),
|
|
950
|
-
}, async (args) => {
|
|
951
|
-
try {
|
|
952
|
-
trackMCP("percy_finalize_comparison", server.server.getClientVersion(), config);
|
|
953
|
-
return await percyFinalizeComparison(args, config);
|
|
954
|
-
}
|
|
955
|
-
catch (error) {
|
|
956
|
-
return handleMCPError("percy_finalize_comparison", server, config, error);
|
|
957
|
-
}
|
|
958
|
-
});
|
|
959
|
-
// -------------------------------------------------------------------------
|
|
960
|
-
// percy_upload_resource
|
|
961
|
-
// -------------------------------------------------------------------------
|
|
962
|
-
tools.percy_upload_resource = server.tool("percy_upload_resource", "Upload a resource to a Percy build (CSS, JS, HTML, images).", {
|
|
963
|
-
build_id: z.string().describe("Percy build ID"),
|
|
964
|
-
sha: z.string().describe("SHA-256 hash of the resource content"),
|
|
965
|
-
base64_content: z.string().describe("Base64-encoded resource content"),
|
|
966
|
-
}, async (args) => {
|
|
967
|
-
try {
|
|
968
|
-
trackMCP("percy_upload_resource", server.server.getClientVersion(), config);
|
|
969
|
-
return await percyUploadResource(args, config);
|
|
970
|
-
}
|
|
971
|
-
catch (error) {
|
|
972
|
-
return handleMCPError("percy_upload_resource", server, config, error);
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
// -------------------------------------------------------------------------
|
|
976
|
-
// percy_upload_tile
|
|
977
|
-
// -------------------------------------------------------------------------
|
|
978
|
-
tools.percy_upload_tile = server.tool("percy_upload_tile", "Upload a screenshot tile to a comparison (PNG/JPEG).", {
|
|
979
|
-
comparison_id: z.string().describe("Percy comparison ID"),
|
|
980
|
-
base64_content: z
|
|
981
|
-
.string()
|
|
982
|
-
.describe("Base64-encoded PNG or JPEG screenshot"),
|
|
983
|
-
}, async (args) => {
|
|
984
|
-
try {
|
|
985
|
-
trackMCP("percy_upload_tile", server.server.getClientVersion(), config);
|
|
986
|
-
return await percyUploadTile(args, config);
|
|
987
|
-
}
|
|
988
|
-
catch (error) {
|
|
989
|
-
return handleMCPError("percy_upload_tile", server, config, error);
|
|
990
|
-
}
|
|
991
|
-
});
|
|
992
|
-
// -------------------------------------------------------------------------
|
|
993
|
-
// percy_analyze_logs_realtime
|
|
994
|
-
// -------------------------------------------------------------------------
|
|
995
|
-
tools.percy_analyze_logs_realtime = server.tool("percy_analyze_logs_realtime", "Analyze raw logs in real-time without a stored build.", {
|
|
996
|
-
logs: z
|
|
997
|
-
.string()
|
|
998
|
-
.describe('JSON array of log entries: [{"message":"...","level":"error","meta":{}}]'),
|
|
999
|
-
}, async (args) => {
|
|
1000
|
-
try {
|
|
1001
|
-
trackMCP("percy_analyze_logs_realtime", server.server.getClientVersion(), config);
|
|
1002
|
-
return await percyAnalyzeLogsRealtime(args, config);
|
|
1003
|
-
}
|
|
1004
|
-
catch (error) {
|
|
1005
|
-
return handleMCPError("percy_analyze_logs_realtime", server, config, error);
|
|
1006
|
-
}
|
|
1007
|
-
});
|
|
1008
|
-
// =========================================================================
|
|
1009
|
-
// === WORKFLOWS (Composite — highest value) ===
|
|
1010
|
-
// =========================================================================
|
|
1011
|
-
// -------------------------------------------------------------------------
|
|
1012
|
-
// percy_pr_visual_report
|
|
1013
|
-
// -------------------------------------------------------------------------
|
|
1014
|
-
tools.percy_pr_visual_report = server.tool("percy_pr_visual_report", "Get a complete PR visual regression report: risk-ranked changes with AI analysis and recommendations. THE tool for checking PR status.", {
|
|
1015
|
-
project_id: z
|
|
1016
|
-
.string()
|
|
1017
|
-
.optional()
|
|
1018
|
-
.describe("Percy project ID (optional if PERCY_TOKEN is project-scoped)"),
|
|
1019
|
-
branch: z
|
|
1020
|
-
.string()
|
|
1021
|
-
.optional()
|
|
1022
|
-
.describe("Git branch name to find the build"),
|
|
1023
|
-
sha: z.string().optional().describe("Git commit SHA to find the build"),
|
|
1024
|
-
build_id: z
|
|
1025
|
-
.string()
|
|
1026
|
-
.optional()
|
|
1027
|
-
.describe("Direct Percy build ID (skips search)"),
|
|
1028
|
-
}, async (args) => {
|
|
1029
|
-
try {
|
|
1030
|
-
trackMCP("percy_pr_visual_report", server.server.getClientVersion(), config);
|
|
1031
|
-
return await percyPrVisualReport(args, config);
|
|
1032
|
-
}
|
|
1033
|
-
catch (error) {
|
|
1034
|
-
return handleMCPError("percy_pr_visual_report", server, config, error);
|
|
1035
|
-
}
|
|
1036
|
-
});
|
|
1037
|
-
// -------------------------------------------------------------------------
|
|
1038
|
-
// percy_auto_triage
|
|
1039
|
-
// -------------------------------------------------------------------------
|
|
1040
|
-
tools.percy_auto_triage = server.tool("percy_auto_triage", "Auto-categorize all visual changes: Critical, Review Required, Auto-Approvable, Noise.", {
|
|
1041
|
-
build_id: z.string().describe("Percy build ID"),
|
|
1042
|
-
noise_threshold: z
|
|
1043
|
-
.number()
|
|
1044
|
-
.optional()
|
|
1045
|
-
.describe("Diff ratio below this is noise (default 0.005 = 0.5%)"),
|
|
1046
|
-
review_threshold: z
|
|
1047
|
-
.number()
|
|
1048
|
-
.optional()
|
|
1049
|
-
.describe("Diff ratio above this needs review (default 0.15 = 15%)"),
|
|
1050
|
-
}, async (args) => {
|
|
1051
|
-
try {
|
|
1052
|
-
trackMCP("percy_auto_triage", server.server.getClientVersion(), config);
|
|
1053
|
-
return await percyAutoTriage(args, config);
|
|
1054
|
-
}
|
|
1055
|
-
catch (error) {
|
|
1056
|
-
return handleMCPError("percy_auto_triage", server, config, error);
|
|
1057
|
-
}
|
|
1058
|
-
});
|
|
1059
|
-
// -------------------------------------------------------------------------
|
|
1060
|
-
// percy_debug_failed_build
|
|
1061
|
-
// -------------------------------------------------------------------------
|
|
1062
|
-
tools.percy_debug_failed_build = server.tool("percy_debug_failed_build", "Diagnose a failed build: cross-references logs, suggestions, and network issues with fix commands.", {
|
|
1063
|
-
build_id: z.string().describe("Percy build ID"),
|
|
1064
|
-
}, async (args) => {
|
|
1065
|
-
try {
|
|
1066
|
-
trackMCP("percy_debug_failed_build", server.server.getClientVersion(), config);
|
|
1067
|
-
return await percyDebugFailedBuild(args, config);
|
|
1068
|
-
}
|
|
1069
|
-
catch (error) {
|
|
1070
|
-
return handleMCPError("percy_debug_failed_build", server, config, error);
|
|
1071
|
-
}
|
|
1072
|
-
});
|
|
1073
|
-
// -------------------------------------------------------------------------
|
|
1074
|
-
// percy_diff_explain
|
|
1075
|
-
// -------------------------------------------------------------------------
|
|
1076
|
-
tools.percy_diff_explain = server.tool("percy_diff_explain", "Explain visual changes in plain English at 3 depth levels (summary/detailed/full_rca).", {
|
|
1077
|
-
comparison_id: z.string().describe("Percy comparison ID"),
|
|
1078
|
-
depth: z
|
|
1079
|
-
.enum(["summary", "detailed", "full_rca"])
|
|
1080
|
-
.optional()
|
|
1081
|
-
.describe("Analysis depth (default: detailed)"),
|
|
1082
|
-
}, async (args) => {
|
|
1083
|
-
try {
|
|
1084
|
-
trackMCP("percy_diff_explain", server.server.getClientVersion(), config);
|
|
1085
|
-
return await percyDiffExplain(args, config);
|
|
1086
|
-
}
|
|
1087
|
-
catch (error) {
|
|
1088
|
-
return handleMCPError("percy_diff_explain", server, config, error);
|
|
1089
|
-
}
|
|
1090
|
-
});
|
|
1091
|
-
// -------------------------------------------------------------------------
|
|
1092
|
-
// percy_snapshot_urls — Actually render URLs locally via Percy CLI
|
|
1093
|
-
// -------------------------------------------------------------------------
|
|
1094
|
-
tools.percy_snapshot_urls = server.tool("percy_snapshot_urls", "Snapshot URLs locally using Percy CLI. Launches a browser, captures screenshots at specified widths, and uploads to Percy. Runs in background — returns build URL immediately. Requires @percy/cli installed.", {
|
|
1095
|
-
project_name: z
|
|
1096
|
-
.string()
|
|
1097
|
-
.describe("Percy project name (auto-creates if doesn't exist)"),
|
|
1098
|
-
urls: z
|
|
1099
|
-
.string()
|
|
1100
|
-
.describe("Comma-separated URLs to snapshot, e.g. 'http://localhost:3000,http://localhost:3000/about'"),
|
|
1101
|
-
widths: z
|
|
1102
|
-
.string()
|
|
1103
|
-
.optional()
|
|
1104
|
-
.describe("Comma-separated widths (default: 375,1280)"),
|
|
1105
|
-
type: z.string().optional().describe("Project type: web or automate"),
|
|
1106
|
-
}, async (args) => {
|
|
1107
|
-
try {
|
|
1108
|
-
trackMCP("percy_snapshot_urls", server.server.getClientVersion(), config);
|
|
1109
|
-
return await percySnapshotUrls(args, config);
|
|
1110
|
-
}
|
|
1111
|
-
catch (error) {
|
|
1112
|
-
return handleMCPError("percy_snapshot_urls", server, config, error);
|
|
1113
|
-
}
|
|
1114
|
-
});
|
|
1115
|
-
// -------------------------------------------------------------------------
|
|
1116
|
-
// percy_run_tests — Run tests with Percy visual testing
|
|
1117
|
-
// -------------------------------------------------------------------------
|
|
1118
|
-
tools.percy_run_tests = server.tool("percy_run_tests", "Run a test command with Percy visual testing. Wraps your test command with percy exec to capture snapshots during test execution. Runs in background — returns build URL immediately. Requires @percy/cli installed.", {
|
|
1119
|
-
project_name: z
|
|
1120
|
-
.string()
|
|
1121
|
-
.describe("Percy project name (auto-creates if doesn't exist)"),
|
|
1122
|
-
test_command: z
|
|
1123
|
-
.string()
|
|
1124
|
-
.describe("Test command to run, e.g. 'npx cypress run' or 'npm test'"),
|
|
1125
|
-
type: z.string().optional().describe("Project type: web or automate"),
|
|
1126
|
-
}, async (args) => {
|
|
1127
|
-
try {
|
|
1128
|
-
trackMCP("percy_run_tests", server.server.getClientVersion(), config);
|
|
1129
|
-
return await percyRunTests(args, config);
|
|
1130
|
-
}
|
|
1131
|
-
catch (error) {
|
|
1132
|
-
return handleMCPError("percy_run_tests", server, config, error);
|
|
1133
|
-
}
|
|
1134
|
-
});
|
|
1135
|
-
return tools;
|
|
1136
|
-
}
|
|
1137
|
-
export default registerPercyMcpTools;
|