@canonry/canonry 7.25.0 → 7.43.2
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/README.md +3 -2
- package/assets/agent-workspace/skills/canonry/references/aeo-analysis.md +24 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +219 -6
- package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +14 -2
- package/assets/assets/{AuditHistoryPanel-B-9DLSmD.js → AuditHistoryPanel-C5oZsvsR.js} +1 -1
- package/assets/assets/{BacklinksPage-DPssWU5-.js → BacklinksPage-CF5sGSTQ.js} +1 -1
- package/assets/assets/{HistoryPage-BAPUoHjI.js → HistoryPage-DumL6cl5.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-aTs5l1OV.js → MeasurementPropertyPage-DCegOp_w.js} +3 -3
- package/assets/assets/ProjectPage-CWDk48Y6.js +8 -0
- package/assets/assets/RunsPage-Bb1VMWYu.js +1 -0
- package/assets/assets/{SettingsPage-Oo861eRm.js → SettingsPage-CHGh169l.js} +1 -1
- package/assets/assets/{SiteHealthSection-BMdk3Och.js → SiteHealthSection-bGzH9m9-.js} +3 -3
- package/assets/assets/{TrafficPage-Ciot_0lN.js → TrafficPage-cfnEZ2Mu.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-D7tWadfJ.js → TrafficSourceDetailPage-BQS0MAXE.js} +1 -1
- package/assets/assets/{extract-error-message-Bb4azvlK.js → extract-error-message-IWhACkO_.js} +1 -1
- package/assets/assets/index-BDY3-V1S.js +86 -0
- package/assets/assets/{react-sigma_core.esm.min-C-Y9Z74U.js → react-sigma_core.esm.min-BQt189AI.js} +1 -1
- package/assets/assets/{v2-overview-adapter-D2S25ivE.js → v2-overview-adapter-ZC3VuoTT.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-PKQF7BV2.js → chunk-65BHDVYO.js} +5650 -4002
- package/dist/{chunk-NOA7KJDB.js → chunk-BPFRGC7K.js} +3 -3
- package/dist/{chunk-I3546GTK.js → chunk-BWR5MNL5.js} +2 -2
- package/dist/chunk-C2I7M3B2.js +22948 -0
- package/dist/{chunk-PFEQWGJN.js → chunk-E43JM3QV.js} +11444 -10397
- package/dist/chunk-HGMYEDAQ.js +79 -0
- package/dist/{chunk-BMBHREYM.js → chunk-KOIOZ7QW.js} +195 -20
- package/dist/{chunk-6AOIFHC6.js → chunk-LYKDNJXR.js} +163 -107
- package/dist/chunk-WRUKKEGR.js +562 -0
- package/dist/chunk-WU2BRWXY.js +546 -0
- package/dist/{chunk-NX257AKC.js → chunk-WXX3NL4C.js} +108 -41
- package/dist/cli-catalog-J3O6W726.js +15 -0
- package/dist/cli-commands-QST2CPDG.js +15 -0
- package/dist/cli.js +136 -22502
- package/dist/{demo-server-RUZWYXSW.js → demo-server-KA7DWTY6.js} +5 -4
- package/dist/index.js +7 -6
- package/dist/{intelligence-service-TYSVXO3S.js → intelligence-service-LHZZTJPH.js} +2 -2
- package/dist/mcp.js +30 -15
- package/package.json +6 -6
- package/assets/assets/ProjectPage-sVY1ETmt.js +0 -8
- package/assets/assets/RunsPage-D0q7ifK3.js +0 -1
- package/assets/assets/index-ClA5Nf2V.js +0 -86
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CliError,
|
|
3
|
+
EXIT_SYSTEM_ERROR
|
|
4
|
+
} from "./chunk-HGMYEDAQ.js";
|
|
1
5
|
import {
|
|
2
6
|
AGENT_MEMORY_KEY_MAX_LENGTH,
|
|
3
7
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
@@ -7,6 +11,7 @@ import {
|
|
|
7
11
|
GOOGLE_MARKETING_STORED_SNAPSHOT_PAGE_MAX,
|
|
8
12
|
LATEST_RUN_ID,
|
|
9
13
|
MEASUREMENT_DEFAULT_QUERY_CLASS,
|
|
14
|
+
OperationAccesses,
|
|
10
15
|
PROVIDER_ACCOUNT_FAILURE_STREAK,
|
|
11
16
|
PROVIDER_ACCOUNT_RETRY_HOURS,
|
|
12
17
|
RESEARCH_RUN_SCOPE,
|
|
@@ -27,6 +32,7 @@ import {
|
|
|
27
32
|
adsUnresolvedOperationListQuerySchema,
|
|
28
33
|
agentConversationCreateSchema,
|
|
29
34
|
apiKeyDtoSchema,
|
|
35
|
+
auditHistoryQuerySchema,
|
|
30
36
|
backlinkSourceSchema,
|
|
31
37
|
calendarDateSchema,
|
|
32
38
|
canonicalizeGtmAccountId,
|
|
@@ -35,7 +41,9 @@ import {
|
|
|
35
41
|
competitorAliasesRequestSchema,
|
|
36
42
|
competitorAppendRequestSchema,
|
|
37
43
|
competitorBatchRequestSchema,
|
|
44
|
+
competitorChangePreviewRequestSchema,
|
|
38
45
|
competitorLandscapeQuerySchema,
|
|
46
|
+
competitorSuggestionsQuerySchema,
|
|
39
47
|
contentTargetDismissRequestSchema,
|
|
40
48
|
describeError,
|
|
41
49
|
discoveryBucketSchema,
|
|
@@ -44,14 +52,17 @@ import {
|
|
|
44
52
|
discoveryRunRequestSchema,
|
|
45
53
|
feedbackAcceptedDtoSchema,
|
|
46
54
|
feedbackSubmissionSchema,
|
|
55
|
+
gaAcquisitionQuerySchema,
|
|
47
56
|
gaMeasurementAnalysisWindowSchema,
|
|
48
57
|
gaMeasurementHostScopeSchema,
|
|
49
58
|
gaSearchLandingWindowSchema,
|
|
50
59
|
googleAdsMetricsWindowSchema,
|
|
51
60
|
gscPerformanceOrderBySchema,
|
|
61
|
+
instanceStatusDtoSchema,
|
|
52
62
|
keywordBatchRequestSchema,
|
|
53
63
|
keywordGenerateRequestSchema,
|
|
54
64
|
logQuerySchema,
|
|
65
|
+
maxOperationAccess,
|
|
55
66
|
measurementChangesQuerySchema,
|
|
56
67
|
measurementDataQualityQuerySchema,
|
|
57
68
|
measurementDiscoveryRequestSchema,
|
|
@@ -94,9 +105,11 @@ import {
|
|
|
94
105
|
measurementQuestionResultQuerySchema,
|
|
95
106
|
notificationCreateRequestSchema,
|
|
96
107
|
notificationEventSchema,
|
|
108
|
+
operationAccess,
|
|
97
109
|
operationalLogListReadSchema,
|
|
98
110
|
organicEvidencePeriodSchema,
|
|
99
111
|
projectConfigSchema,
|
|
112
|
+
projectPatchRequestSchema,
|
|
100
113
|
projectUpsertRequestSchema,
|
|
101
114
|
providerQuotaPolicySchema,
|
|
102
115
|
providerReloadRequestSchema,
|
|
@@ -109,6 +122,7 @@ import {
|
|
|
109
122
|
queryTrackingPreviewRequestSchema,
|
|
110
123
|
referralAssessmentQuerySchema,
|
|
111
124
|
reportMonthSchema,
|
|
125
|
+
reportedQueryClasses,
|
|
112
126
|
researchBatchCreateSchema,
|
|
113
127
|
researchRunCreateSchema,
|
|
114
128
|
resultsClearRequestSchema,
|
|
@@ -141,77 +155,11 @@ import {
|
|
|
141
155
|
trafficConnectVercelRequestSchema,
|
|
142
156
|
trafficConnectWordpressRequestSchema,
|
|
143
157
|
trafficEventKindSchema,
|
|
158
|
+
trafficSamplesQuerySchema,
|
|
144
159
|
trafficSeriesGranularitySchema,
|
|
145
160
|
visibilityCompareSelectionSchema,
|
|
146
161
|
visibilityReportRequestSchema
|
|
147
|
-
} from "./chunk-
|
|
148
|
-
|
|
149
|
-
// src/support-links.ts
|
|
150
|
-
var CANONRY_DISCORD_URL = "https://discord.gg/jnJ2H2z5Xh";
|
|
151
|
-
var CANONRY_ISSUES_URL = "https://github.com/Canonry/canonry/issues";
|
|
152
|
-
|
|
153
|
-
// src/cli-error.ts
|
|
154
|
-
function isMachineFormat(format) {
|
|
155
|
-
return format === "json" || format === "jsonl";
|
|
156
|
-
}
|
|
157
|
-
var EXIT_USER_ERROR = 1;
|
|
158
|
-
var EXIT_SYSTEM_ERROR = 2;
|
|
159
|
-
var CliError = class extends Error {
|
|
160
|
-
code;
|
|
161
|
-
displayMessage;
|
|
162
|
-
details;
|
|
163
|
-
exitCode;
|
|
164
|
-
constructor(options) {
|
|
165
|
-
super(options.message);
|
|
166
|
-
this.name = "CliError";
|
|
167
|
-
this.code = options.code;
|
|
168
|
-
this.displayMessage = options.displayMessage;
|
|
169
|
-
this.details = options.details;
|
|
170
|
-
this.exitCode = options.exitCode ?? EXIT_USER_ERROR;
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
function usageError(displayMessage, options) {
|
|
174
|
-
const firstLine = displayMessage.split("\n", 1)[0] ?? "Error: invalid command usage";
|
|
175
|
-
return new CliError({
|
|
176
|
-
code: "CLI_USAGE_ERROR",
|
|
177
|
-
message: options?.message ?? firstLine.replace(/^Error:\s*/, ""),
|
|
178
|
-
displayMessage,
|
|
179
|
-
details: options?.details
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
function isEndpointMissing(err) {
|
|
183
|
-
if (!(err instanceof CliError)) return false;
|
|
184
|
-
const status = err.details?.httpStatus;
|
|
185
|
-
return status === 404 || status === 405;
|
|
186
|
-
}
|
|
187
|
-
function systemError(message, options) {
|
|
188
|
-
return new CliError({
|
|
189
|
-
code: "CLI_SYSTEM_ERROR",
|
|
190
|
-
message,
|
|
191
|
-
displayMessage: options?.displayMessage,
|
|
192
|
-
details: options?.details,
|
|
193
|
-
exitCode: EXIT_SYSTEM_ERROR
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
function printCliError(err, format) {
|
|
197
|
-
if (isMachineFormat(format)) {
|
|
198
|
-
const envelope = err instanceof CliError ? { error: { code: err.code, message: err.message, ...err.details ? { details: err.details } : {} } } : { error: { code: "CLI_ERROR", message: err instanceof Error ? err.message : "An unexpected error occurred" } };
|
|
199
|
-
console.error(JSON.stringify(envelope, null, format === "jsonl" ? 0 : 2));
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (err instanceof CliError && err.displayMessage) {
|
|
203
|
-
console.error(err.displayMessage);
|
|
204
|
-
} else if (err instanceof Error) {
|
|
205
|
-
console.error(`Error: ${err.message}`);
|
|
206
|
-
} else {
|
|
207
|
-
console.error("An unexpected error occurred");
|
|
208
|
-
}
|
|
209
|
-
const unexpected = !(err instanceof CliError) || err.exitCode === EXIT_SYSTEM_ERROR;
|
|
210
|
-
if (unexpected && process.stderr.isTTY) {
|
|
211
|
-
console.error(`
|
|
212
|
-
Need help? Run 'canonry support' or ask in the Canonry Discord: ${CANONRY_DISCORD_URL}`);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
162
|
+
} from "./chunk-E43JM3QV.js";
|
|
215
163
|
|
|
216
164
|
// src/package-version.ts
|
|
217
165
|
import { createRequire } from "module";
|
|
@@ -388,6 +336,13 @@ var writeAnnotations = (opts) => ({
|
|
|
388
336
|
destructiveHint: Boolean(opts.destructiveHint),
|
|
389
337
|
...opts.openWorldHint ? { openWorldHint: opts.openWorldHint } : {}
|
|
390
338
|
});
|
|
339
|
+
function toolOperationAccess(tool) {
|
|
340
|
+
const derived = maxOperationAccess(tool.openApiOperations.map((operation) => {
|
|
341
|
+
const separator = operation.indexOf(" ");
|
|
342
|
+
return separator < 0 ? OperationAccesses.stored : operationAccess(operation.slice(0, separator), operation.slice(separator + 1));
|
|
343
|
+
}));
|
|
344
|
+
return tool.access === "write" ? OperationAccesses.write : derived;
|
|
345
|
+
}
|
|
391
346
|
function defineTool(tool) {
|
|
392
347
|
return {
|
|
393
348
|
...tool,
|
|
@@ -541,6 +496,7 @@ var measurementDraftActionOpenApiOperations = [
|
|
|
541
496
|
"POST /api/v1/projects/{name}/measurement-plan/draft/actions/discard"
|
|
542
497
|
];
|
|
543
498
|
var runsListInputSchema = z3.object({
|
|
499
|
+
since: z3.string().optional().describe("Inclusive ISO 8601 lower bound on creation time. Omit to read all dates."),
|
|
544
500
|
project: projectNameSchema,
|
|
545
501
|
limit: z3.number().int().positive().max(500).optional(),
|
|
546
502
|
kind: runListFilterQuerySchema.shape.kind.describe('Restrict to a single run kind (e.g. "answer-visibility"). Unknown values are rejected.'),
|
|
@@ -562,12 +518,9 @@ var timelineInputSchema = z3.object({
|
|
|
562
518
|
limit: z3.number().int().positive().max(100).optional().describe("Restrict history to the most recent N project runs.")
|
|
563
519
|
});
|
|
564
520
|
var historyFilterShape = {
|
|
521
|
+
...auditHistoryQuerySchema.shape,
|
|
565
522
|
limit: z3.number().int().positive().max(500).optional(),
|
|
566
|
-
offset: z3.number().int().nonnegative().optional()
|
|
567
|
-
since: z3.string().optional().describe("ISO 8601 lower bound."),
|
|
568
|
-
action: z3.string().optional().describe("Exact audit action filter."),
|
|
569
|
-
actor: z3.string().optional().describe("Exact actor filter."),
|
|
570
|
-
entityType: z3.string().optional().describe("Exact entity type filter.")
|
|
523
|
+
offset: z3.number().int().nonnegative().optional()
|
|
571
524
|
};
|
|
572
525
|
var projectHistoryInputSchema = z3.object({ project: projectNameSchema, ...historyFilterShape });
|
|
573
526
|
var globalHistoryInputSchema = z3.object(historyFilterShape);
|
|
@@ -938,6 +891,12 @@ var competitorsAddInputSchema = z3.object({
|
|
|
938
891
|
project: projectNameSchema,
|
|
939
892
|
request: competitorAppendRequestSchema
|
|
940
893
|
});
|
|
894
|
+
var competitorChangePreviewInputSchema = z3.discriminatedUnion("change", [
|
|
895
|
+
competitorChangePreviewRequestSchema.options[0].extend({ project: projectNameSchema }),
|
|
896
|
+
competitorChangePreviewRequestSchema.options[1].extend({ project: projectNameSchema }),
|
|
897
|
+
competitorChangePreviewRequestSchema.options[2].extend({ project: projectNameSchema }),
|
|
898
|
+
competitorChangePreviewRequestSchema.options[3].extend({ project: projectNameSchema })
|
|
899
|
+
]);
|
|
941
900
|
var competitorDomainInputSchema = z3.string().trim().min(1).describe("Tracked competitor domain (any spelling; it resolves to the stored registrable domain).");
|
|
942
901
|
var competitorAliasesInputSchema = competitorAliasesRequestSchema.safeExtend({
|
|
943
902
|
project: projectNameSchema,
|
|
@@ -952,6 +911,9 @@ var competitorLandscapeInputSchema = competitorLandscapeQuerySchema.safeExtend({
|
|
|
952
911
|
project: projectNameSchema,
|
|
953
912
|
runId: z3.string().trim().min(1).optional().describe(latestSweepRunIdDescription)
|
|
954
913
|
}).strict();
|
|
914
|
+
var competitorSuggestionsInputSchema = competitorSuggestionsQuerySchema.safeExtend({
|
|
915
|
+
project: projectNameSchema
|
|
916
|
+
}).strict();
|
|
955
917
|
function latestSweepUnlessPooled(query) {
|
|
956
918
|
if (query.runId !== void 0 || query.window !== void 0) return query;
|
|
957
919
|
if (query.queryClass !== "branded" && query.queryClass !== "non-brand") return query;
|
|
@@ -961,6 +923,10 @@ var projectUpsertInputSchema = z3.object({
|
|
|
961
923
|
project: projectNameSchema,
|
|
962
924
|
request: projectUpsertRequestSchema
|
|
963
925
|
});
|
|
926
|
+
var projectPatchInputSchema = z3.object({
|
|
927
|
+
project: projectNameSchema,
|
|
928
|
+
request: projectPatchRequestSchema
|
|
929
|
+
});
|
|
964
930
|
var applyConfigInputSchema = z3.object({
|
|
965
931
|
config: projectConfigSchema
|
|
966
932
|
});
|
|
@@ -983,6 +949,10 @@ var doctorInputSchema = z3.object({
|
|
|
983
949
|
project: projectNameSchema.optional().describe("Project name to scope project-level checks. Omit to run global checks (provider keys, config, etc.)."),
|
|
984
950
|
checks: z3.array(z3.string().min(1)).optional().describe('Optional check IDs or wildcard prefixes (e.g. "google.auth.*", "config.providers"). Empty/omitted runs all matching checks for the chosen scope.')
|
|
985
951
|
});
|
|
952
|
+
var statusInputSchema = z3.object({
|
|
953
|
+
project: projectNameSchema.optional().describe("Optional project name. Omit to read every visible project."),
|
|
954
|
+
problems: z3.boolean().optional().describe("Return only failing, stale, or never-synced projects and integrations.")
|
|
955
|
+
});
|
|
986
956
|
var contentTargetsInputSchema = z3.object({
|
|
987
957
|
project: projectNameSchema,
|
|
988
958
|
limit: z3.number().int().positive().max(500).optional().describe("Max rows. Defaults to all. Use a small number (3-10) when summarizing for the user."),
|
|
@@ -1285,7 +1255,7 @@ var sentimentPreviewInputSchema = sentimentBackfillSelectionSchema.safeExtend({
|
|
|
1285
1255
|
if (input.from && input.to && Date.parse(input.from) > Date.parse(input.to)) ctx.addIssue({ code: "custom", message: "from must be at or before to" });
|
|
1286
1256
|
});
|
|
1287
1257
|
var sentimentBackfillInputSchema = sentimentBackfillRequestSchema.extend({ project: projectNameSchema });
|
|
1288
|
-
var
|
|
1258
|
+
var rawCanonryMcpTools = [
|
|
1289
1259
|
defineTool({
|
|
1290
1260
|
name: "canonry_sentiment_settings",
|
|
1291
1261
|
title: "Read sentiment readiness and settings",
|
|
@@ -1591,6 +1561,34 @@ var canonryMcpTools = [
|
|
|
1591
1561
|
return client.getCompetitorLandscape(project, latestSweepUnlessPooled(query));
|
|
1592
1562
|
}
|
|
1593
1563
|
}),
|
|
1564
|
+
defineTool({
|
|
1565
|
+
name: "canonry_competitors_suggest",
|
|
1566
|
+
title: "Suggest competitors from stored evidence",
|
|
1567
|
+
description: "Read stored completed and partial answer evidence and rank possible direct competitors. Candidate naming and citation counts are separate, cited-only domains are excluded, listing and marketplace surfaces are excluded, and the response discloses the answer and sweep denominator. No provider, discovery, classifier, or write operation runs. A Simple project without a usable brand alias pools all query classes and echoes queryClass=all. Use the returned evidence and sample URLs to review a candidate before tracking it.",
|
|
1568
|
+
access: "read",
|
|
1569
|
+
tier: "setup",
|
|
1570
|
+
inputSchema: competitorSuggestionsInputSchema,
|
|
1571
|
+
annotations: readAnnotations(),
|
|
1572
|
+
openApiOperations: ["GET /api/v1/projects/{name}/competitor-suggestions"],
|
|
1573
|
+
handler: (client, input) => {
|
|
1574
|
+
const { project, ...query } = input;
|
|
1575
|
+
return client.suggestCompetitors(project, query);
|
|
1576
|
+
}
|
|
1577
|
+
}),
|
|
1578
|
+
defineTool({
|
|
1579
|
+
name: "canonry_competitors_change_preview",
|
|
1580
|
+
title: "Preview competitor change impact",
|
|
1581
|
+
description: "Preview the stored-evidence share impact of one explicit competitor add, remove, replace, or curated alias change. It reads the latest completed or partial sweep and never writes competitors, aliases, history, or provider state. Use this before a separate write when an operator wants the before and after denominator and percentage-point delta. Ordinary competitor writes do not call this implicitly.",
|
|
1582
|
+
access: "read",
|
|
1583
|
+
tier: "setup",
|
|
1584
|
+
inputSchema: competitorChangePreviewInputSchema,
|
|
1585
|
+
annotations: readAnnotations(),
|
|
1586
|
+
openApiOperations: ["POST /api/v1/projects/{name}/competitor-changes/preview"],
|
|
1587
|
+
handler: (client, input) => {
|
|
1588
|
+
const { project, ...request } = input;
|
|
1589
|
+
return client.previewCompetitorChange(project, request);
|
|
1590
|
+
}
|
|
1591
|
+
}),
|
|
1594
1592
|
defineTool({
|
|
1595
1593
|
name: "canonry_search",
|
|
1596
1594
|
title: "Search project (composite)",
|
|
@@ -1617,10 +1615,22 @@ var canonryMcpTools = [
|
|
|
1617
1615
|
openApiOperations: ["GET /api/v1/doctor", "GET /api/v1/projects/{name}/doctor"],
|
|
1618
1616
|
handler: (client, input) => client.runDoctor({ project: input.project, checkIds: input.checks, ...input.reportMonth ? { reportMonth: input.reportMonth } : {} })
|
|
1619
1617
|
}),
|
|
1618
|
+
defineTool({
|
|
1619
|
+
name: "canonry_status",
|
|
1620
|
+
title: "Read integration status",
|
|
1621
|
+
description: "Read stored synchronization status for one project or the instance. This is a read-only local database read and never calls providers or runs doctor checks.",
|
|
1622
|
+
access: "read",
|
|
1623
|
+
tier: "core",
|
|
1624
|
+
inputSchema: statusInputSchema,
|
|
1625
|
+
outputSchema: instanceStatusDtoSchema,
|
|
1626
|
+
annotations: readAnnotations(),
|
|
1627
|
+
openApiOperations: ["GET /api/v1/status"],
|
|
1628
|
+
handler: (client, input) => client.getStatus({ project: input.project, problems: input.problems })
|
|
1629
|
+
}),
|
|
1620
1630
|
defineTool({
|
|
1621
1631
|
name: "canonry_project_export",
|
|
1622
1632
|
title: "Export project config",
|
|
1623
|
-
description: "Export a Canonry project in config-as-code format.",
|
|
1633
|
+
description: "Export a Canonry project in config-as-code format. Notification webhook URLs are always redacted for MCP.",
|
|
1624
1634
|
access: "read",
|
|
1625
1635
|
tier: "setup",
|
|
1626
1636
|
inputSchema: projectInputSchema,
|
|
@@ -1652,6 +1662,10 @@ var canonryMcpTools = [
|
|
|
1652
1662
|
limit: input.limit,
|
|
1653
1663
|
offset: input.offset,
|
|
1654
1664
|
since: input.since,
|
|
1665
|
+
until: input.until,
|
|
1666
|
+
actionPrefix: input.actionPrefix,
|
|
1667
|
+
excludeEntityTypes: input.excludeEntityTypes,
|
|
1668
|
+
entityId: input.entityId,
|
|
1655
1669
|
action: input.action,
|
|
1656
1670
|
actor: input.actor,
|
|
1657
1671
|
entityType: input.entityType
|
|
@@ -1671,13 +1685,13 @@ var canonryMcpTools = [
|
|
|
1671
1685
|
defineTool({
|
|
1672
1686
|
name: "canonry_runs_list",
|
|
1673
1687
|
title: "List project runs",
|
|
1674
|
-
description: "List runs for a Canonry project. Includes both real runs (trigger='manual'/'scheduled'/'config-apply'/'backfill') AND probe runs (trigger='probe'). Probe runs are operator/agent test runs that don't influence dashboard, analytics, intelligence, or notifications
|
|
1688
|
+
description: "List runs for a Canonry project. Includes both real runs (trigger='manual'/'scheduled'/'config-apply'/'backfill') AND probe runs (trigger='probe'). Probe runs are operator/agent test runs that don't influence dashboard, analytics, intelligence, or notifications; filter by `trigger !== 'probe'` if you only want runs that feed project metrics. Narrow with `kind` and/or `status` (e.g. status='running' lists only in-flight work). Use `excludeKind` or `excludeKinds` to remove kinds before applying the limit. `since` bounds creation time; omitting limit returns every matching run.",
|
|
1675
1689
|
access: "read",
|
|
1676
1690
|
tier: "monitoring",
|
|
1677
1691
|
inputSchema: runsListInputSchema,
|
|
1678
1692
|
annotations: readAnnotations(),
|
|
1679
1693
|
openApiOperations: ["GET /api/v1/projects/{name}/runs"],
|
|
1680
|
-
handler: (client, input) => client.listRuns(input.project, input.limit, input.kind, input.status, input.excludeKind, input.excludeKinds)
|
|
1694
|
+
handler: (client, input) => client.listRuns(input.project, input.limit, input.kind, input.status, input.excludeKind, input.excludeKinds, input.since)
|
|
1681
1695
|
}),
|
|
1682
1696
|
defineTool({
|
|
1683
1697
|
name: "canonry_runs_latest",
|
|
@@ -1969,7 +1983,7 @@ var canonryMcpTools = [
|
|
|
1969
1983
|
defineTool({
|
|
1970
1984
|
name: "canonry_queries_list",
|
|
1971
1985
|
title: "List queries",
|
|
1972
|
-
description: "List tracked queries for a Canonry project.",
|
|
1986
|
+
description: "List tracked queries for a Canonry project. Each row carries queryClass as the server classes it: branded, non-brand, or null when no single class exists (no usable brand name, or the active measurement plan holds no single class for the query). A row with no queryClass comes from a server older than the field: the class is unknown, not null. Never infer a class from the query text.",
|
|
1973
1987
|
access: "read",
|
|
1974
1988
|
tier: "setup",
|
|
1975
1989
|
inputSchema: projectInputSchema,
|
|
@@ -2264,11 +2278,11 @@ var canonryMcpTools = [
|
|
|
2264
2278
|
defineTool({
|
|
2265
2279
|
name: "canonry_bing_coverage",
|
|
2266
2280
|
title: "Get Bing coverage",
|
|
2267
|
-
description: "Read
|
|
2268
|
-
access: "
|
|
2281
|
+
description: "Read Bing index coverage counts and URL inspections for a Canonry project. The route records an idempotent daily coverage snapshot while returning the result, but does not call Bing or start a sync. Preserves indexed, not indexed and unknown evidence, the server percentage and last inspection time. Project-wide for Simple and Advanced portfolios; Property, Target and market attribution are unavailable. Requires the existing Bing connection.",
|
|
2282
|
+
access: "write",
|
|
2269
2283
|
tier: "bing",
|
|
2270
2284
|
inputSchema: projectInputSchema,
|
|
2271
|
-
annotations:
|
|
2285
|
+
annotations: writeAnnotations({ idempotentHint: true }),
|
|
2272
2286
|
openApiOperations: ["GET /api/v1/projects/{name}/bing/coverage"],
|
|
2273
2287
|
handler: (client, input) => client.bingCoverage(input.project)
|
|
2274
2288
|
}),
|
|
@@ -2316,6 +2330,20 @@ var canonryMcpTools = [
|
|
|
2316
2330
|
openApiOperations: ["GET /api/v1/projects/{name}/ga/properties"],
|
|
2317
2331
|
handler: (client, input) => client.gaProperties(input.project)
|
|
2318
2332
|
}),
|
|
2333
|
+
defineTool({
|
|
2334
|
+
name: "canonry_ga_acquisition",
|
|
2335
|
+
title: "Read stored GA4 acquisition",
|
|
2336
|
+
description: "Read stored GA4 sessions by day, channel, source/medium, host and normalized landing page. Sessions only; totalSessions is the full filtered total, independent of grouping and pagination. No Google calls. Project-only attribution; stored rows cannot distinguish an older connected GA4 property. Meaningful page query parameters remain distinct.",
|
|
2337
|
+
access: "read",
|
|
2338
|
+
tier: "ga",
|
|
2339
|
+
inputSchema: gaAcquisitionQuerySchema.extend({ project: projectNameSchema, limit: z3.number().int().min(1).max(500).optional() }),
|
|
2340
|
+
annotations: readAnnotations(),
|
|
2341
|
+
openApiOperations: ["GET /api/v1/projects/{name}/ga/acquisition"],
|
|
2342
|
+
handler: (client, input) => {
|
|
2343
|
+
const { project, ...query } = input;
|
|
2344
|
+
return client.gaAcquisition(project, query);
|
|
2345
|
+
}
|
|
2346
|
+
}),
|
|
2319
2347
|
defineTool({
|
|
2320
2348
|
name: "canonry_ga_measurement_analysis",
|
|
2321
2349
|
title: "Analyze GA acquisition and search demand",
|
|
@@ -2462,7 +2490,7 @@ var canonryMcpTools = [
|
|
|
2462
2490
|
access: "write",
|
|
2463
2491
|
tier: "gbp",
|
|
2464
2492
|
inputSchema: gbpDiscoverInputSchema,
|
|
2465
|
-
annotations: writeAnnotations({ idempotentHint: true }),
|
|
2493
|
+
annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
|
|
2466
2494
|
openApiOperations: ["POST /api/v1/projects/{name}/gbp/locations/discover"],
|
|
2467
2495
|
handler: (client, input) => client.discoverGbpLocations(input.project, {
|
|
2468
2496
|
selectAllNew: input.selectAllNew,
|
|
@@ -2500,7 +2528,7 @@ var canonryMcpTools = [
|
|
|
2500
2528
|
access: "write",
|
|
2501
2529
|
tier: "gbp",
|
|
2502
2530
|
inputSchema: gbpSyncInputSchema,
|
|
2503
|
-
annotations: writeAnnotations({ idempotentHint: true }),
|
|
2531
|
+
annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
|
|
2504
2532
|
openApiOperations: ["POST /api/v1/projects/{name}/gbp/sync"],
|
|
2505
2533
|
handler: (client, input) => client.triggerGbpSync(input.project, {
|
|
2506
2534
|
locationNames: input.locationNames,
|
|
@@ -2654,6 +2682,20 @@ var canonryMcpTools = [
|
|
|
2654
2682
|
return client.trafficReferralAssessment(project, query);
|
|
2655
2683
|
}
|
|
2656
2684
|
}),
|
|
2685
|
+
defineTool({
|
|
2686
|
+
name: "canonry_traffic_samples",
|
|
2687
|
+
title: "Read stored traffic samples",
|
|
2688
|
+
description: "Read the stored sampled tail of server-side traffic with 30-day retention. Sample rows are not a count of visits. Default kind excludes unknown requests. Project/source only; Property, Target and market dimensions are unavailable. No provider call or write.",
|
|
2689
|
+
access: "read",
|
|
2690
|
+
tier: "traffic",
|
|
2691
|
+
inputSchema: trafficSamplesQuerySchema.extend({ project: projectNameSchema }),
|
|
2692
|
+
annotations: readAnnotations(),
|
|
2693
|
+
openApiOperations: ["GET /api/v1/projects/{name}/traffic/samples"],
|
|
2694
|
+
handler: (client, input) => {
|
|
2695
|
+
const { project, ...query } = input;
|
|
2696
|
+
return client.trafficListSamples(project, query);
|
|
2697
|
+
}
|
|
2698
|
+
}),
|
|
2657
2699
|
defineTool({
|
|
2658
2700
|
name: "canonry_traffic_events",
|
|
2659
2701
|
title: "List traffic events",
|
|
@@ -2762,10 +2804,21 @@ var canonryMcpTools = [
|
|
|
2762
2804
|
openApiOperations: ["PUT /api/v1/projects/{name}"],
|
|
2763
2805
|
handler: (client, input) => client.putProject(input.project, input.request)
|
|
2764
2806
|
}),
|
|
2807
|
+
defineTool({
|
|
2808
|
+
name: "canonry_project_update",
|
|
2809
|
+
title: "Update project fields",
|
|
2810
|
+
description: "Update named fields on an existing Canonry project with PATCH semantics. Omitted fields keep their stored values, measurement merges one level, and expectedConfigRevision prevents overwriting a newer edit. Prefer this for targeted changes over canonry_project_upsert.",
|
|
2811
|
+
access: "write",
|
|
2812
|
+
tier: "setup",
|
|
2813
|
+
inputSchema: projectPatchInputSchema,
|
|
2814
|
+
annotations: writeAnnotations({ idempotentHint: true }),
|
|
2815
|
+
openApiOperations: ["PATCH /api/v1/projects/{name}"],
|
|
2816
|
+
handler: (client, input) => client.patchProject(input.project, input.request)
|
|
2817
|
+
}),
|
|
2765
2818
|
defineTool({
|
|
2766
2819
|
name: "canonry_apply_config",
|
|
2767
2820
|
title: "Apply project config",
|
|
2768
|
-
description: "Apply one Canonry config-as-code project document. Replaces the project to match the config; fields omitted from the spec are reset to defaults, with these exceptions: a spec with neither queries nor keywords leaves the tracked-query basket unchanged (to clear the basket, pass an explicit empty queries list); an omitted providerDispatchModes keeps the stored preference; an omitted qualifiedAliases keeps the stored list, minus names that no longer qualify (a removed alias, a spelling of the display name, or a competitor's name); send [] to clear it; and a competitor given as a plain domain keeps its stored curated aliases, while `{ domain, aliases }` sets them exactly (`[]` clears). A spec identity that claims a competitor's alias drops that alias (audited); a new competitor whose name overlaps another competitor's alias (one brand key contains the other) or that is the project's own site fails the apply. An omitted siteAuditMaxPages keeps the stored Site Health page budget (null means the full site). An omitted competitorAutoAliases keeps the stored answer-derived competitor alias mode (off, preview or apply). For multi-document YAML, call this tool once per project document.",
|
|
2821
|
+
description: "Apply one Canonry config-as-code project document. Replaces the project to match the config; fields omitted from the spec are reset to defaults, with these exceptions: a spec with neither queries nor keywords leaves the tracked-query basket unchanged (to clear the basket, pass an explicit empty queries list); an omitted providerDispatchModes keeps the stored preference; an omitted qualifiedAliases keeps the stored list, minus names that no longer qualify (a removed alias, a spelling of the display name, or a competitor's name); send [] to clear it; and a competitor given as a plain domain keeps its stored curated aliases, while `{ domain, aliases }` sets them exactly (`[]` clears). A spec identity that claims a competitor's alias drops that alias (audited); a new competitor whose name overlaps another competitor's alias (one brand key contains the other) or that is the project's own site fails the apply. An omitted siteAuditMaxPages keeps the stored Site Health page budget (null means the full site). An omitted competitorAutoAliases keeps the stored answer-derived competitor alias mode (off, preview or apply). For multi-document YAML, call this tool once per project document. Call canonry_apply_config_preview first.",
|
|
2769
2822
|
access: "write",
|
|
2770
2823
|
tier: "core",
|
|
2771
2824
|
inputSchema: applyConfigInputSchema,
|
|
@@ -2774,6 +2827,17 @@ var canonryMcpTools = [
|
|
|
2774
2827
|
openApiOperations: ["POST /api/v1/apply"],
|
|
2775
2828
|
handler: (client, input) => client.apply(input.config)
|
|
2776
2829
|
}),
|
|
2830
|
+
defineTool({
|
|
2831
|
+
name: "canonry_apply_config_preview",
|
|
2832
|
+
title: "Preview project config apply",
|
|
2833
|
+
description: "Preview one Canonry config-as-code project document. Returns per-field and child-resource changes with notification hosts only; the server resolves notification DNS to preserve the real apply verdict, then rolls back the transaction before responding, so no database writes, audit rows, or callbacks persist.",
|
|
2834
|
+
access: "read",
|
|
2835
|
+
tier: "core",
|
|
2836
|
+
inputSchema: applyConfigInputSchema,
|
|
2837
|
+
annotations: readAnnotations(),
|
|
2838
|
+
openApiOperations: ["POST /api/v1/apply/preview"],
|
|
2839
|
+
handler: (client, input) => client.previewApply(input.config)
|
|
2840
|
+
}),
|
|
2777
2841
|
defineTool({
|
|
2778
2842
|
name: "canonry_queries_generate",
|
|
2779
2843
|
title: "Generate query suggestions",
|
|
@@ -3275,14 +3339,15 @@ var canonryMcpTools = [
|
|
|
3275
3339
|
defineTool({
|
|
3276
3340
|
name: "canonry_queries_add",
|
|
3277
3341
|
title: "Add queries",
|
|
3278
|
-
description: "Append tracked queries to a Canonry project; existing queries are skipped by the API.",
|
|
3342
|
+
description: "Append tracked queries to a Canonry project; existing queries are skipped by the API. Returns queryClasses: each requested query with the class the server gave it (branded, non-brand, or null when no single class exists). An entry with no queryClass means the server did not report one.",
|
|
3279
3343
|
access: "write",
|
|
3280
3344
|
tier: "setup",
|
|
3281
3345
|
inputSchema: queriesInputSchema,
|
|
3282
3346
|
annotations: writeAnnotations({ idempotentHint: true }),
|
|
3283
3347
|
openApiOperations: ["POST /api/v1/projects/{name}/queries"],
|
|
3284
3348
|
handler: async (client, input) => {
|
|
3285
|
-
|
|
3349
|
+
const queries = uniqueStrings(input.request.queries);
|
|
3350
|
+
return { ok: true, queryClasses: reportedQueryClasses(queries, await client.appendQueries(input.project, queries)) };
|
|
3286
3351
|
}
|
|
3287
3352
|
}),
|
|
3288
3353
|
defineTool({
|
|
@@ -3327,20 +3392,18 @@ var canonryMcpTools = [
|
|
|
3327
3392
|
defineTool({
|
|
3328
3393
|
name: "canonry_competitors_add",
|
|
3329
3394
|
title: "Add competitors",
|
|
3330
|
-
description: "Add tracked competitor domains to a Canonry project. Each entry is a domain, or `{ domain, aliases }` to also add curated answer-text names to that competitor (tracked already or not; existing aliases are kept, the same rules as canonry_competitors_aliases_set apply). A new domain whose name overlaps another competitor's curated alias, or the label or a curated alias of a competitor an Advanced market pins (one brand key contains the other, so the alias \"Tune\" claims tunespoke.example), is rejected until that name is removed, and so is the project's own site. Already tracked domains (any spelling) are skipped.",
|
|
3395
|
+
description: "Use canonry_competitors_change_preview to inspect the stored share impact before this separate write. Measured projects require `acknowledgeBulkAdd: true` when new domains plus recent additions exceed the shared five-domain, 24-hour guard. Review with canonry_competitors_suggest or canonry_competitors_change_preview first; the built-in agent cannot acknowledge bulk growth. Add tracked competitor domains to a Canonry project. Each entry is a domain, or `{ domain, aliases }` to also add curated answer-text names to that competitor (tracked already or not; existing aliases are kept, the same rules as canonry_competitors_aliases_set apply). A new domain whose name overlaps another competitor's curated alias, or the label or a curated alias of a competitor an Advanced market pins (one brand key contains the other, so the alias \"Tune\" claims tunespoke.example), is rejected until that name is removed, and so is the project's own site. Already tracked domains (any spelling) are skipped.",
|
|
3331
3396
|
access: "write",
|
|
3332
3397
|
tier: "setup",
|
|
3333
3398
|
inputSchema: competitorsAddInputSchema,
|
|
3334
3399
|
annotations: writeAnnotations({ idempotentHint: true }),
|
|
3335
3400
|
openApiOperations: ["POST /api/v1/projects/{name}/competitors"],
|
|
3336
|
-
handler:
|
|
3337
|
-
await client.appendCompetitors(input.project, input.request.competitors);
|
|
3338
|
-
}
|
|
3401
|
+
handler: (client, input) => client.appendCompetitors(input.project, input.request.competitors, { acknowledgeBulkAdd: input.request.acknowledgeBulkAdd })
|
|
3339
3402
|
}),
|
|
3340
3403
|
defineTool({
|
|
3341
3404
|
name: "canonry_competitors_aliases_set",
|
|
3342
3405
|
title: "Set competitor aliases",
|
|
3343
|
-
description: 'Set one tracked competitor\'s operator-curated aliases exactly (`[]` clears): the brand names it goes by in answer text when they differ from its domain, e.g. "TuneSpoke" for spoketuneworks.example or a 3-letter brand the domain label floor drops. Every competitor mention matcher (mention share, competitor landscape, mention gaps, run and history signals) uses them on stored answers at read time. Rejected: aliases under 3 letters or digits, over 80 characters, more than 10, or whose brand key contains, or sits inside, one of the project\'s own names or hosts or a name another tracked competitor answers to (its aliases, domain label or written host), because answers may split or join the words: "Tune" cannot belong to one competitor while another answers to "Tune Spoke", "TuneSpoke" or tunespoke.example, and joined-word lookalikes ("Tune" and "Tuner") are refused too. A competitor an Advanced market pins (active revision, pending draft, or a superseded revision the project\'s runs were measured under) counts as another competitor. Names detected automatically from stored answers (`autoAliases`) are matched the same way; a curated alias always wins, so an auto name the new list overlaps is dropped. Idempotent; returns the competitor.',
|
|
3406
|
+
description: 'Use canonry_competitors_change_preview to inspect the stored share impact before this separate write. Set one tracked competitor\'s operator-curated aliases exactly (`[]` clears): the brand names it goes by in answer text when they differ from its domain, e.g. "TuneSpoke" for spoketuneworks.example or a 3-letter brand the domain label floor drops. Every competitor mention matcher (mention share, competitor landscape, mention gaps, run and history signals) uses them on stored answers at read time. Rejected: aliases under 3 letters or digits, over 80 characters, more than 10, or whose brand key contains, or sits inside, one of the project\'s own names or hosts or a name another tracked competitor answers to (its aliases, domain label or written host), because answers may split or join the words: "Tune" cannot belong to one competitor while another answers to "Tune Spoke", "TuneSpoke" or tunespoke.example, and joined-word lookalikes ("Tune" and "Tuner") are refused too. A competitor an Advanced market pins (active revision, pending draft, or a superseded revision the project\'s runs were measured under) counts as another competitor. Names detected automatically from stored answers (`autoAliases`) are matched the same way; a curated alias always wins, so an auto name the new list overlaps is dropped. Idempotent; returns the competitor.',
|
|
3344
3407
|
access: "write",
|
|
3345
3408
|
tier: "setup",
|
|
3346
3409
|
inputSchema: competitorAliasesInputSchema,
|
|
@@ -3362,7 +3425,7 @@ var canonryMcpTools = [
|
|
|
3362
3425
|
defineTool({
|
|
3363
3426
|
name: "canonry_competitors_auto_aliases_apply",
|
|
3364
3427
|
title: "Apply competitor auto-aliases",
|
|
3365
|
-
description: "Run automatic competitor alias detection now from the project's stored answers and store the result, whatever the project's competitorAutoAliases mode (a one-off apply; a project in `apply` mode also gets this pass after every completed or partial sweep, a competitor add, an unblock and a market pin write that changes the pins). Stored names restate history at read time: every period's competitor counts change, and so does share of voice for a tracked competitor; competitorIdentityChangedAt on the landscape, project-frame visibility-compare and analytics metrics marks when. Idempotent: unchanged answers write nothing. Curated aliases and blocked names always win. A change is audited as the system pass plus competitors.auto-aliases-apply-requested naming who asked. Not available to the built-in Aero agent. Returns what was stored, per competitor, with evidence.",
|
|
3428
|
+
description: "Use canonry_competitors_auto_aliases_detect first to preview names and their stored share impact. Run automatic competitor alias detection now from the project's stored answers and store the result, whatever the project's competitorAutoAliases mode (a one-off apply; a project in `apply` mode also gets this pass after every completed or partial sweep, a competitor add, an unblock and a market pin write that changes the pins). Stored names restate history at read time: every period's competitor counts change, and so does share of voice for a tracked competitor; competitorIdentityChangedAt on the landscape, project-frame visibility-compare and analytics metrics marks when. Idempotent: unchanged answers write nothing. Curated aliases and blocked names always win. A change is audited as the system pass plus competitors.auto-aliases-apply-requested naming who asked. Not available to the built-in Aero agent. Returns what was stored, per competitor, with evidence.",
|
|
3366
3429
|
access: "write",
|
|
3367
3430
|
tier: "setup",
|
|
3368
3431
|
inputSchema: projectInputSchema,
|
|
@@ -3395,15 +3458,13 @@ var canonryMcpTools = [
|
|
|
3395
3458
|
defineTool({
|
|
3396
3459
|
name: "canonry_competitors_remove",
|
|
3397
3460
|
title: "Remove competitors",
|
|
3398
|
-
description: "Remove tracked competitor domains from a Canonry project.",
|
|
3461
|
+
description: "Use canonry_competitors_change_preview to inspect the stored share impact before this separate write. Remove tracked competitor domains from a Canonry project.",
|
|
3399
3462
|
access: "write",
|
|
3400
3463
|
tier: "setup",
|
|
3401
3464
|
inputSchema: competitorsInputSchema,
|
|
3402
3465
|
annotations: writeAnnotations({ idempotentHint: true, destructiveHint: true }),
|
|
3403
3466
|
openApiOperations: ["DELETE /api/v1/projects/{name}/competitors"],
|
|
3404
|
-
handler:
|
|
3405
|
-
await client.deleteCompetitors(input.project, uniqueStrings(input.request.competitors));
|
|
3406
|
-
}
|
|
3467
|
+
handler: (client, input) => client.deleteCompetitors(input.project, uniqueStrings(input.request.competitors))
|
|
3407
3468
|
}),
|
|
3408
3469
|
defineTool({
|
|
3409
3470
|
name: "canonry_schedule_set",
|
|
@@ -4433,29 +4494,24 @@ var canonryMcpTools = [
|
|
|
4433
4494
|
access: "write",
|
|
4434
4495
|
tier: "ads",
|
|
4435
4496
|
inputSchema: projectInputSchema,
|
|
4436
|
-
annotations: writeAnnotations({ idempotentHint: true }),
|
|
4497
|
+
annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
|
|
4437
4498
|
openApiOperations: ["POST /api/v1/projects/{name}/ads/sync"],
|
|
4438
4499
|
handler: (client, input) => client.triggerAdsSync(input.project)
|
|
4439
4500
|
})
|
|
4440
4501
|
];
|
|
4502
|
+
var canonryMcpTools = rawCanonryMcpTools.map((tool) => {
|
|
4503
|
+
if (tool.access !== "read" || toolOperationAccess(tool) !== OperationAccesses.live) return tool;
|
|
4504
|
+
return { ...tool, annotations: { ...tool.annotations, openWorldHint: true } };
|
|
4505
|
+
});
|
|
4441
4506
|
var CanonryMcpToolNames = Object.freeze(
|
|
4442
4507
|
Object.fromEntries(canonryMcpTools.map((tool) => [tool.name, tool.name]))
|
|
4443
4508
|
);
|
|
4444
4509
|
|
|
4445
4510
|
export {
|
|
4446
|
-
CANONRY_DISCORD_URL,
|
|
4447
|
-
CANONRY_ISSUES_URL,
|
|
4448
|
-
isMachineFormat,
|
|
4449
|
-
EXIT_USER_ERROR,
|
|
4450
|
-
EXIT_SYSTEM_ERROR,
|
|
4451
|
-
CliError,
|
|
4452
|
-
usageError,
|
|
4453
|
-
isEndpointMissing,
|
|
4454
|
-
systemError,
|
|
4455
|
-
printCliError,
|
|
4456
4511
|
PACKAGE_VERSION,
|
|
4457
4512
|
measurementDraftOperationSchema,
|
|
4458
4513
|
runMeasurementDraftAction,
|
|
4514
|
+
toolOperationAccess,
|
|
4459
4515
|
canonryMcpTools,
|
|
4460
4516
|
CanonryMcpToolNames
|
|
4461
4517
|
};
|