@canonry/canonry 7.19.0 → 7.20.1
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/assets/agent-workspace/skills/aero/references/agent-operations.md +14 -0
- package/assets/agent-workspace/skills/canonry/SKILL.md +14 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +33 -1
- package/assets/assets/{AuditHistoryPanel-DEEWm-4t.js → AuditHistoryPanel-DVtz1ZuT.js} +1 -1
- package/assets/assets/{BacklinksPage-F5QBgXbF.js → BacklinksPage-Tvt0-ppX.js} +1 -1
- package/assets/assets/{HistoryPage-CNp42sUO.js → HistoryPage-DqXwPH3k.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-XpI9hVMb.js → MeasurementPropertyPage-CsbfFEjB.js} +1 -1
- package/assets/assets/{ProjectPage-B_V4QpyI.js → ProjectPage-Cyvt96AV.js} +2 -2
- package/assets/assets/{RunsPage-PTHloZl3.js → RunsPage-Io7ZFw4-.js} +1 -1
- package/assets/assets/{SettingsPage-C-aDo2zf.js → SettingsPage-BPYxgchP.js} +1 -1
- package/assets/assets/{SiteHealthSection-DvoT8IuX.js → SiteHealthSection-CwffU3tv.js} +3 -3
- package/assets/assets/{TrafficPage-DahJoMKF.js → TrafficPage-DIm60m1J.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-BGlHXOlk.js → TrafficSourceDetailPage-DWT1Ip5P.js} +1 -1
- package/assets/assets/{extract-error-message-CP_fyJLM.js → extract-error-message-BVYchXhT.js} +1 -1
- package/assets/assets/{index-C5V8xlr0.js → index-DrQLR1jE.js} +20 -20
- package/assets/assets/{react-sigma_core.esm.min-DUS8srfg.js → react-sigma_core.esm.min-f31sqfAC.js} +1 -1
- package/assets/assets/{v2-overview-adapter-ycJ1guZb.js → v2-overview-adapter-By0930UY.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-A75L7CUV.js → chunk-222NAFTY.js} +2 -2
- package/dist/{chunk-UUI4HOEL.js → chunk-46JZR2IV.js} +46 -8
- package/dist/{chunk-VSTKTQPS.js → chunk-5IXQAOVK.js} +16 -1
- package/dist/{chunk-PBTTPZZE.js → chunk-6H2BC5EY.js} +3 -3
- package/dist/{chunk-OMP5OLBK.js → chunk-CIPWGVX6.js} +368 -211
- package/dist/{chunk-CYHUZ2JQ.js → chunk-MRKV43TV.js} +19 -0
- package/dist/{chunk-35IIFDIT.js → chunk-NDQOCFJQ.js} +61 -43
- package/dist/cli.js +213 -39
- package/dist/{demo-server-K5G54GOE.js → demo-server-32PU7BM6.js} +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-LV2TQMMR.js → intelligence-service-256DQBVR.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +12 -12
|
@@ -42,6 +42,7 @@ var ProviderNames = {
|
|
|
42
42
|
};
|
|
43
43
|
var providerNameSchema = z2.string().min(1);
|
|
44
44
|
var providerModelsSchema = z2.record(z2.string(), z2.string().trim().min(1));
|
|
45
|
+
var API_PROVIDER_NAMES = ["gemini", "openai", "claude", "perplexity", "muse", "local"];
|
|
45
46
|
var apiProviderNameSchema = z2.string().min(1);
|
|
46
47
|
function isBrowserProvider(name) {
|
|
47
48
|
return name.startsWith("cdp:");
|
|
@@ -15170,6 +15171,19 @@ var providerSummaryEntryDtoSchema = z40.object({
|
|
|
15170
15171
|
/** Whether Vertex AI is configured for this provider (Gemini only). */
|
|
15171
15172
|
vertexConfigured: z40.boolean().optional()
|
|
15172
15173
|
});
|
|
15174
|
+
var providerReloadRequestSchema = z40.object({
|
|
15175
|
+
configPath: z40.string().min(1).max(4096).optional(),
|
|
15176
|
+
databasePath: z40.string().min(1).max(4096).optional()
|
|
15177
|
+
}).strict().refine(
|
|
15178
|
+
(input) => input.configPath === void 0 === (input.databasePath === void 0),
|
|
15179
|
+
"configPath and databasePath must be supplied together"
|
|
15180
|
+
);
|
|
15181
|
+
var providerReloadErrorReasonSchema = z40.enum(["install-identity-mismatch"]);
|
|
15182
|
+
var ProviderReloadErrorReasons = providerReloadErrorReasonSchema.enum;
|
|
15183
|
+
var providerReloadResponseDtoSchema = z40.object({
|
|
15184
|
+
reloaded: z40.literal(true),
|
|
15185
|
+
providers: z40.array(providerSummaryEntryDtoSchema)
|
|
15186
|
+
});
|
|
15173
15187
|
var providerCatalogEntryDtoSchema = z40.object({
|
|
15174
15188
|
name: z40.string(),
|
|
15175
15189
|
displayName: z40.string(),
|
|
@@ -21914,6 +21928,7 @@ var UI_ROUTE_FIXED_CHILDREN = /* @__PURE__ */ new Set([
|
|
|
21914
21928
|
"locations/discover",
|
|
21915
21929
|
"notifications/events",
|
|
21916
21930
|
"operations/logs",
|
|
21931
|
+
"providers/reload",
|
|
21917
21932
|
"queries/generate",
|
|
21918
21933
|
"queries/replace-preview",
|
|
21919
21934
|
"runs/latest",
|
|
@@ -22637,6 +22652,7 @@ export {
|
|
|
22637
22652
|
RetrievalContracts,
|
|
22638
22653
|
providerQuotaPolicySchema,
|
|
22639
22654
|
ProviderNames,
|
|
22655
|
+
API_PROVIDER_NAMES,
|
|
22640
22656
|
isBrowserProvider,
|
|
22641
22657
|
resolveProviderInput,
|
|
22642
22658
|
locationContextSchema,
|
|
@@ -23224,6 +23240,9 @@ export {
|
|
|
23224
23240
|
LlmCapabilities,
|
|
23225
23241
|
LLM_CAPABILITIES,
|
|
23226
23242
|
providerSummaryEntryDtoSchema,
|
|
23243
|
+
providerReloadRequestSchema,
|
|
23244
|
+
ProviderReloadErrorReasons,
|
|
23245
|
+
providerReloadResponseDtoSchema,
|
|
23227
23246
|
integrationSettingsSummaryDtoSchema,
|
|
23228
23247
|
settingsDtoSchema,
|
|
23229
23248
|
ProviderBatchRequestOutcomes,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
PACKAGE_VERSION,
|
|
6
6
|
canonryMcpTools,
|
|
7
7
|
isMachineFormat
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5IXQAOVK.js";
|
|
9
9
|
import {
|
|
10
10
|
AGENT_PROVIDER_IDS,
|
|
11
11
|
CANONRY_NPM_PACKAGE_URL,
|
|
@@ -36,7 +36,6 @@ import {
|
|
|
36
36
|
operationalLogListReadSchema,
|
|
37
37
|
providerBatchConfigSchema,
|
|
38
38
|
providerPricingSchema,
|
|
39
|
-
providerQuotaPolicySchema,
|
|
40
39
|
resolveProviderModel,
|
|
41
40
|
restrictedWriteScopes,
|
|
42
41
|
schedulableRunKindSchema,
|
|
@@ -50,7 +49,7 @@ import {
|
|
|
50
49
|
skillsClientSchema,
|
|
51
50
|
upgradeCaveatFor,
|
|
52
51
|
upgradeCommandFor
|
|
53
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-MRKV43TV.js";
|
|
54
53
|
|
|
55
54
|
// src/config.ts
|
|
56
55
|
import fs from "fs";
|
|
@@ -153,6 +152,26 @@ var envSchema = z2.object({
|
|
|
153
152
|
CANONRY_RESEARCH_ALLOW_VIEWERS: z2.string().optional(),
|
|
154
153
|
CANONRY_RESEARCH_VIEWER_DAILY_RUN_LIMIT: z2.coerce.number().int().positive().default(DEFAULT_VIEWER_RESEARCH_DAILY_RUN_LIMIT)
|
|
155
154
|
});
|
|
155
|
+
var BOOTSTRAP_PROVIDER_DEFAULT_MODELS = {
|
|
156
|
+
gemini: "gemini-flash-latest",
|
|
157
|
+
openai: "gpt-5.4",
|
|
158
|
+
claude: "claude-sonnet-4-6",
|
|
159
|
+
perplexity: resolveProviderModel("perplexity", "fast"),
|
|
160
|
+
muse: "muse-spark-1.3",
|
|
161
|
+
local: "llama3"
|
|
162
|
+
};
|
|
163
|
+
var BOOTSTRAP_PROVIDER_DEFAULT_QUOTA = {
|
|
164
|
+
maxConcurrency: 2,
|
|
165
|
+
maxRequestsPerMinute: 10,
|
|
166
|
+
maxRequestsPerDay: 500
|
|
167
|
+
};
|
|
168
|
+
function withBootstrapProviderDefaults(name, entry) {
|
|
169
|
+
return {
|
|
170
|
+
...entry,
|
|
171
|
+
model: entry.model ?? BOOTSTRAP_PROVIDER_DEFAULT_MODELS[name],
|
|
172
|
+
quota: entry.quota ?? { ...BOOTSTRAP_PROVIDER_DEFAULT_QUOTA }
|
|
173
|
+
};
|
|
174
|
+
}
|
|
156
175
|
var bootstrapEnvSchema = z2.object({
|
|
157
176
|
CANONRY_API_KEY: z2.string().optional(),
|
|
158
177
|
CANONRY_API_URL: z2.string().optional(),
|
|
@@ -186,13 +205,9 @@ function getBootstrapEnv(source, overrides) {
|
|
|
186
205
|
if (parsed.GEMINI_API_KEY || parsed.GEMINI_VERTEX_PROJECT) {
|
|
187
206
|
providers.gemini = {
|
|
188
207
|
apiKey: parsed.GEMINI_API_KEY ?? "",
|
|
189
|
-
model: parsed.GEMINI_MODEL ||
|
|
208
|
+
model: parsed.GEMINI_MODEL || void 0,
|
|
190
209
|
baseUrl: parsed.GEMINI_BASE_URL,
|
|
191
|
-
quota:
|
|
192
|
-
maxConcurrency: 2,
|
|
193
|
-
maxRequestsPerMinute: 10,
|
|
194
|
-
maxRequestsPerDay: 500
|
|
195
|
-
}),
|
|
210
|
+
quota: void 0,
|
|
196
211
|
vertexProject: parsed.GEMINI_VERTEX_PROJECT,
|
|
197
212
|
vertexRegion: parsed.GEMINI_VERTEX_REGION,
|
|
198
213
|
vertexCredentials: parsed.GEMINI_VERTEX_CREDENTIALS
|
|
@@ -201,60 +216,41 @@ function getBootstrapEnv(source, overrides) {
|
|
|
201
216
|
if (parsed.OPENAI_API_KEY) {
|
|
202
217
|
providers.openai = {
|
|
203
218
|
apiKey: parsed.OPENAI_API_KEY,
|
|
204
|
-
model: parsed.OPENAI_MODEL ||
|
|
219
|
+
model: parsed.OPENAI_MODEL || void 0,
|
|
205
220
|
baseUrl: parsed.OPENAI_BASE_URL,
|
|
206
|
-
quota:
|
|
207
|
-
maxConcurrency: 2,
|
|
208
|
-
maxRequestsPerMinute: 10,
|
|
209
|
-
maxRequestsPerDay: 500
|
|
210
|
-
})
|
|
221
|
+
quota: void 0
|
|
211
222
|
};
|
|
212
223
|
}
|
|
213
224
|
if (parsed.ANTHROPIC_API_KEY) {
|
|
214
225
|
providers.claude = {
|
|
215
226
|
apiKey: parsed.ANTHROPIC_API_KEY,
|
|
216
|
-
model: parsed.ANTHROPIC_MODEL ||
|
|
217
|
-
quota:
|
|
218
|
-
maxConcurrency: 2,
|
|
219
|
-
maxRequestsPerMinute: 10,
|
|
220
|
-
maxRequestsPerDay: 500
|
|
221
|
-
})
|
|
227
|
+
model: parsed.ANTHROPIC_MODEL || void 0,
|
|
228
|
+
quota: void 0
|
|
222
229
|
};
|
|
223
230
|
}
|
|
224
231
|
if (parsed.PERPLEXITY_API_KEY) {
|
|
225
232
|
providers.perplexity = {
|
|
226
233
|
apiKey: parsed.PERPLEXITY_API_KEY,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
maxRequestsPerMinute: 10,
|
|
231
|
-
maxRequestsPerDay: 500
|
|
232
|
-
})
|
|
234
|
+
// A retired Sonar name resolves to the Agent API preset that now answers.
|
|
235
|
+
model: parsed.PERPLEXITY_MODEL ? resolveProviderModel("perplexity", parsed.PERPLEXITY_MODEL) : void 0,
|
|
236
|
+
quota: void 0
|
|
233
237
|
};
|
|
234
238
|
}
|
|
235
239
|
const museKey = parsed.MUSE_API_KEY?.trim();
|
|
236
240
|
if (museKey) {
|
|
237
241
|
providers.muse = {
|
|
238
242
|
apiKey: museKey,
|
|
239
|
-
model: parsed.MUSE_MODEL?.trim() ||
|
|
243
|
+
model: parsed.MUSE_MODEL?.trim() || void 0,
|
|
240
244
|
baseUrl: parsed.MUSE_BASE_URL?.trim() || void 0,
|
|
241
|
-
quota:
|
|
242
|
-
maxConcurrency: 2,
|
|
243
|
-
maxRequestsPerMinute: 10,
|
|
244
|
-
maxRequestsPerDay: 500
|
|
245
|
-
})
|
|
245
|
+
quota: void 0
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
248
|
if (parsed.LOCAL_BASE_URL) {
|
|
249
249
|
providers.local = {
|
|
250
250
|
baseUrl: parsed.LOCAL_BASE_URL,
|
|
251
251
|
apiKey: parsed.LOCAL_API_KEY,
|
|
252
|
-
model: parsed.LOCAL_MODEL ||
|
|
253
|
-
quota:
|
|
254
|
-
maxConcurrency: 2,
|
|
255
|
-
maxRequestsPerMinute: 10,
|
|
256
|
-
maxRequestsPerDay: 500
|
|
257
|
-
})
|
|
252
|
+
model: parsed.LOCAL_MODEL || void 0,
|
|
253
|
+
quota: void 0
|
|
258
254
|
};
|
|
259
255
|
}
|
|
260
256
|
return {
|
|
@@ -380,8 +376,7 @@ function getConfigDir() {
|
|
|
380
376
|
function getConfigPath() {
|
|
381
377
|
return path.join(getConfigDir(), "config.yaml");
|
|
382
378
|
}
|
|
383
|
-
function loadConfig() {
|
|
384
|
-
const configPath = getConfigPath();
|
|
379
|
+
function loadConfig(configPath = getConfigPath()) {
|
|
385
380
|
if (!fs.existsSync(configPath)) {
|
|
386
381
|
throw new Error(
|
|
387
382
|
`Config not found at ${configPath}.
|
|
@@ -3176,6 +3171,22 @@ var putApiV1SettingsProvidersByName = (options) => {
|
|
|
3176
3171
|
}
|
|
3177
3172
|
});
|
|
3178
3173
|
};
|
|
3174
|
+
var postApiV1SettingsProvidersReload = (options) => {
|
|
3175
|
+
return (options?.client ?? client).post({
|
|
3176
|
+
security: [
|
|
3177
|
+
{
|
|
3178
|
+
scheme: "bearer",
|
|
3179
|
+
type: "http"
|
|
3180
|
+
}
|
|
3181
|
+
],
|
|
3182
|
+
url: "/api/v1/settings/providers/reload",
|
|
3183
|
+
...options,
|
|
3184
|
+
headers: {
|
|
3185
|
+
"Content-Type": "application/json",
|
|
3186
|
+
...options?.headers
|
|
3187
|
+
}
|
|
3188
|
+
});
|
|
3189
|
+
};
|
|
3179
3190
|
var putApiV1SettingsGoogle = (options) => {
|
|
3180
3191
|
return (options.client ?? client).put({
|
|
3181
3192
|
security: [
|
|
@@ -6572,7 +6583,8 @@ var ApiClient = class {
|
|
|
6572
6583
|
throw new CliError({
|
|
6573
6584
|
code: "CONNECTION_ERROR",
|
|
6574
6585
|
message: connectionFailureMessage(this.originUrl),
|
|
6575
|
-
exitCode: EXIT_SYSTEM_ERROR
|
|
6586
|
+
exitCode: EXIT_SYSTEM_ERROR,
|
|
6587
|
+
details: { connectionUnavailable: true }
|
|
6576
6588
|
});
|
|
6577
6589
|
}
|
|
6578
6590
|
throw new CliError({ code: "CONNECTION_ERROR", message: msg, exitCode: EXIT_SYSTEM_ERROR });
|
|
@@ -7634,6 +7646,11 @@ var ApiClient = class {
|
|
|
7634
7646
|
() => putApiV1SettingsGoogle({ client: this.heyClient, body })
|
|
7635
7647
|
);
|
|
7636
7648
|
}
|
|
7649
|
+
async reloadProviders(body = {}, signal) {
|
|
7650
|
+
return this.invoke(
|
|
7651
|
+
() => postApiV1SettingsProvidersReload({ client: this.heyClient, body, signal })
|
|
7652
|
+
);
|
|
7653
|
+
}
|
|
7637
7654
|
async createSnapshot(body) {
|
|
7638
7655
|
return this.invoke(() => postApiV1Snapshot({ client: this.heyClient, body }));
|
|
7639
7656
|
}
|
|
@@ -10000,7 +10017,7 @@ var OPERATIONS_GUIDE = {
|
|
|
10000
10017
|
"guidance": "Build the requested summary from stored project overview, organic evidence, and the relevant visibility, measurement, integration, or traffic reads. Retain evidence dates, scope, sample sizes, missing data, and separate mention/citation signals; do not generate fresh runs implicitly."
|
|
10001
10018
|
}
|
|
10002
10019
|
},
|
|
10003
|
-
"markdown": "# Canonry Operations Guide v1\n\nCanonry is an agent-first AI visibility platform. MCP is the universal entry\npoint for connected agents. Host-native skills are optional upgrades, not a\nprerequisite or a permission mechanism.\n\n## Connect and choose a route\n\nRead the initialization guidance, then call `canonry_help` with an `intent`:\n`status`, `diagnose`, `operations`, `prospecting`, `measurement`, `integrations`,\n`reports`, or a short task\ndescription. Select an accessible project with `canonry_projects_list` before\nusing its exact name in project tools. Inspect each listed tool's input schema;\nhelp suggests tool names, not invented arguments or authorization.\n\nHelp returns a versioned, compact route: connection `mode`, available `next`\ntools, workflow guidance, approval boundaries, and this guide's URL. It performs\nno provider calls, reads no project data, and changes no permissions.\n`next` lists stored reads. Optional `actions` lists loaded tools for work that\nrequires approval; listing an action does not authorize or execute it.\n`includeCatalog: true` additionally returns toolkit details when needed.\n\nHosted connections use a fixed catalog. Help only suggests tools offered by that\nconnection; it never tells a hosted agent to dynamically load a toolkit. A\nprogressive local stdio connection may return `loadToolkits`: call\n`canonry_load_toolkit` with one returned name, await it, then call help again.\nLoading only changes local tool discovery, never server authority.\n\nThe optional `canonry://agent-operations/v1` MCP resource contains this same\nguide. If the host cannot read resources or open links, continue through help.\nDo not install a plugin, local runtime, or skill merely to use connected MCP.\nAn installed Codex or Claude Canonry skill contains a generated copy of this\nguide plus links to host-native references. It does not replace runtime help.\n\n## Vocabulary and evidence\n\n- **Mentioned** means the brand appears in answer text. **Cited** means its\n domain appears in source links. Either, both, or neither can occur; never\n compute one signal from the other.\n- `answerMentioned: null` means not checked, not false. Missing runs and empty\n populations mean no measurement, not zero visibility.\n- Preserve project, time window, provider, requested/served model, location,\n sample size, and query class when comparing evidence. Use server-returned\n metrics; do not invent a score from incompatible populations.\n- Simple projects and Advanced portfolios share the workflow. For Advanced\n results, preserve Property, Target, market, plan revision, and class scope.\n Groups organize navigation; do not infer an unrequested fan-out.\n- Research is isolated evidence, not tracked measurement. A probe still spends\n quota and persists evidence but is excluded from normal tracking metrics.\n\n## Workflows\n\n**Status:** read the stored overview and freshness first. Say when evidence is\nmissing instead of silently creating it.\n\n**Diagnose:** inspect stored history and comparable evidence. Explain what\nchanged separately from why it might have changed. A hypothesis is not a\nmeasured cause. Propose bounded verification if stored evidence is insufficient.\n\n**Prospecting:** generate a one-shot company snapshot without creating a project.\nInspect stored provider settings first. Agree on the company, domain, selected\nproviders, and queries before starting the quota-spending snapshot action.\nBrowser-only selection requires manual queries. Progressive stdio help offers\nthe discovery toolkit when this connection permits snapshots; load it, then\ncall help again. Fixed catalogs offer only already available actions. Read-only\nand restricted connections must not bypass missing snapshot access.\n\n**Measurement:** inspect the existing setup and results before proposing edits.\nKeep research, query tracking, plan publication, and sweep execution separate.\nFor direct research, submit the final editable query text in one context. For a\nreviewed batch, submit each explicit destination with its final text and one\nidempotency key. Pattern substitution happens in the client before either\nrequest; choosing a market or Property records a destination only and never\nrewrites a query or creates an automatic fan-out. `research.run` does not\nauthorize saving patterns, changing tracking, publishing plans, or settings.\nUse a supported preview where available, inspect its exact destination and\nrevision, then seek approval for the actual change. A preview may itself require\nwrite permission; never treat a dry-run flag as a universal safety guarantee.\n\n**Integrations:** inspect stored connection state and snapshot freshness first.\nProvider configuration evidence does not prove a browser event fired or a\nconversion was recorded. Connection, resource selection, refresh/sync, and live\nreads are separate actions. Credentials belong in the operator's secure setup\nflow, never in chat, tool arguments, reports, or public guidance.\n\n**Reports:** use saved evidence for the requested period and scope. Keep mention\nand citation signals separate, include dates and sample sizes, and state missing\nor stale inputs. For Advanced Property mention rankings, use\n`canonry_measurement_portfolio_summary` and its `mentionRanking.strongest`,\n`.weakest`, and `.excluded` lists. It defaults to non-brand questions; state the\nreturned class and report branded results separately. An unavailable portfolio\naggregate does not invalidate available Property mention rates. Flag excluded\nProperties individually; do not silently replace mention ranking with citation\nranking. Compact `nextCursor` completes only `pageList`; use `list` to enumerate\none ranking, markets, observed names or cited domains, preserving filters.\nFirst-page sibling lists are bounded summaries. Keep sample sizes and ties\nvisible. Preparing a report does not\nauthorize new measurement.\n\n## Authority and approval\n\n### Agent operations\n\nUse `canonry_key_self` (CLI `canonry key whoami --format json`) to inspect the\ncurrent credential's scopes, project boundary, and host-derived `operator`\nauthority without exposing its token. Missing `operator` means unapproved.\n`canonry_settings_get` and\n`canonry_telemetry_get` describe the connected server, not the agent's local\nmachine. Telemetry reports configured preference, effective state, and any\nenvironment override; inspecting status never creates an anonymous identifier.\nAfter approval, `canonry_telemetry_update` changes that preference and\n`canonry_provider_settings_update` changes an already-configured provider's\nmodel/quota. Both require `settings.write`; neither accepts credentials.\nServer telemetry reads and updates additionally require operator authority.\nOrdinary audit-history reads omit internal telemetry events and their state.\n\nOperator authority is deny-by-default and separate from customer admin roles.\nThe deployment owner must approve a dedicated, instance-wide API key's ID in\nthe server environment variable `CANONRY_OPERATOR_KEY_IDS` (comma-separated IDs),\nthen restart the server. Empty/unset approves nobody; wildcards are invalid.\nKeep the bearer private to internal operators; never approve a customer-held or\nshared proxy/bootstrap key. Use `logs.read` for read-only diagnostics, adding\n`settings.write` only when telemetry control is required. Ordinary key creation,\naccount roles, OAuth consent, and caller headers cannot grant operator status.\nRevoking an approved key invalidates it immediately. Host enrollment is a trust\nbootstrap step, intentionally unavailable through customer-facing APIs.\nAPI, CLI, and MCP enforce the same boundary; MCP hides internal tools unless\nthe server confirms operator authority, including in explicit read-only mode.\nProject analytics, research, and normal project permissions are unchanged.\n\n`canonry_logs_list` reads bounded, redacted runtime events from both the\napplication logger and Fastify request/error logging. It requires an\ninstance-wide `logs.read` grant (or wildcard) and a host-approved direct bearer.\nBrowser sessions, OAuth/delegated credentials, customer admins, and project-scoped\nkeys cannot use it, even with a project filter or a matching allowlist ID.\nA `logs.read`-only key is read-only automatically, without a\nsecond `read` marker. Named `*.read` scopes cannot grant mutations; an explicit\nwrite grant is needed and remains subject to its route gates. Returned messages\nare sanitized and bounded; raw request or response bodies, headers, cookies,\nprovider payloads, and stacks are not\npart of the queryable surface. The same secret-redaction policy runs before\nconsole output and storage. Do not deliberately log secrets: redaction is a\ndefense in depth, not permission to put credentials into diagnostic strings.\nOpaque escaped payloads containing secret assignments are omitted when safe\npartial masking cannot be guaranteed; correlate their retained error codes and IDs.\n\nFile-backed hosts retain runtime logs in SQLite across restarts, bounded to\n10,000 events and seven days. In-memory hosts report `retention: \"process\"`.\nFilter by `actor`, `requestId`, `runId`, `projectId`, `module`, `level`, or an\ninclusive `since`/`until` interval. Keep filters unchanged when resuming an\nopaque cursor; retention eviction can invalidate it. Inspect `retentionPolicy`,\n`captureErrors`, `dropped`, `truncated`, and `retention` before drawing\nconclusions. Missing logs are not proof that an action did not happen. Use\n`canonry_project_history` or `canonry_history_global` for persistent audit events;\noffset pages have deterministic ordering but are not snapshots of concurrent writes.\n\nAudit `actor` comes from authenticated identity (`user:<id>` or `api-key:<id>`),\nnot a caller-supplied header. A delegated MCP credential records its originating\nuser as actor and the actual credential in `credentialId`. `requestId` correlates\nHTTP events; `userAgent` and `actorSession` are bounded, untrusted client hints,\nnever identity or permission grants. Older audit rows are not backfilled with\nidentities the server cannot prove.\n\nBoth shipped HTTP hosts issue restart-safe UUID request IDs and return them in\n`x-request-id`. Use that value to correlate a CLI/API failure with log entries;\nHTTP diagnostics retain the method and route template, not raw URL parameters.\nRequest-bound loggers retain completion attribution, while generic background\ncontinuations stop inheriting caller identity after the response completes.\nCapture covers the owning server process after initialization, not arbitrary\nconsole output, other worker processes, or host/container logs. Run one server\ninstance per process and database, as required by the single-tenant deployment\nmodel; this is not a cross-tenant or distributed log collector.\n\nFor CLI use, settings reads are remote. Google setup and telemetry retain their\nlocal defaults: pass `--target server` explicitly to configure the connected\nserver. `schedule list <project>` lists all schedule kinds, and\n`notify events --target server` discovers the server's event catalog.\n\nMCP returns legacy text JSON plus structured results. Objects keep their shape;\narrays use `{items: [...]}` in `structuredContent`, and scalars use `{value: ...}`.\nErrors preserve the existing envelope and CLI exit codes: HTTP 4xx (including\n429 policy limits) use exit 1; HTTP 5xx use exit 2. Server-provided `Retry-After`\nand request IDs are exposed as `retryAfterMs` and `requestId` when available;\nclients do not infer retryability from HTTP 429 or retry automatically.\nFor a write with an ambiguous outcome, inspect saved state or its receipt before\nretrying; a retry hint is not proof that repeating a write is safe.\n\n### Action boundaries\n\nStart with stored evidence. Before a live provider read, sweep, probe, research\nrun, sync, write, or externally visible action, obtain approval covering its\nexact target, action, and bounded work. Approval already given for that exact\noperation need not be asked for again, but does not extend to more projects,\nlarger batches, retries with new identities, or recurring work.\n\nHTTP GET and MCP `readOnlyHint` describe aspects of an operation, not its cost\nor permission. Provider discovery, account reads, and live diagnostics may\nconsume quota even when labeled read-only. If the tool's effect is unclear,\ninspect its description and request direction before calling it.\n\nAuthentication, role/scope checks, project restrictions, quotas, and guarded\napproval receipts are enforced by the server. Help, skills, resources, and tool\nvisibility cannot grant authority. Never change credentials, endpoints, or\nproject identifiers to work around a missing tool or a `403` response.\n\nFor guarded ads writes, inspect unresolved operation receipts before retrying.\nUse the receipt's supported recovery action; do not replay a mutation under a\nnew identity. An executor cannot create or widen its own human approval grant.\nOn ambiguous results, exhausted bounds, or refusal, stop and report what is\nknown and what permission or operator action is needed.\n\n## Version and source\n\nThis public, versioned document is the source for initialization guidance,\nintent routes, the optional resource, and generated Canonry `SKILL.md` files.\nGuide v1 may receive compatible clarifications; incompatible routing contracts\nrequire a new guide version. The running server's help describes its actual\ncatalog and remains usable without fetching this document.\n"
|
|
10020
|
+
"markdown": "# Canonry Operations Guide v1\n\nCanonry is an agent-first AI visibility platform. MCP is the universal entry\npoint for connected agents. Host-native skills are optional upgrades, not a\nprerequisite or a permission mechanism.\n\n## Connect and choose a route\n\nRead the initialization guidance, then call `canonry_help` with an `intent`:\n`status`, `diagnose`, `operations`, `prospecting`, `measurement`, `integrations`,\n`reports`, or a short task\ndescription. Select an accessible project with `canonry_projects_list` before\nusing its exact name in project tools. Inspect each listed tool's input schema;\nhelp suggests tool names, not invented arguments or authorization.\n\nHelp returns a versioned, compact route: connection `mode`, available `next`\ntools, workflow guidance, approval boundaries, and this guide's URL. It performs\nno provider calls, reads no project data, and changes no permissions.\n`next` lists stored reads. Optional `actions` lists loaded tools for work that\nrequires approval; listing an action does not authorize or execute it.\n`includeCatalog: true` additionally returns toolkit details when needed.\n\nHosted connections use a fixed catalog. Help only suggests tools offered by that\nconnection; it never tells a hosted agent to dynamically load a toolkit. A\nprogressive local stdio connection may return `loadToolkits`: call\n`canonry_load_toolkit` with one returned name, await it, then call help again.\nLoading only changes local tool discovery, never server authority.\n\nThe optional `canonry://agent-operations/v1` MCP resource contains this same\nguide. If the host cannot read resources or open links, continue through help.\nDo not install a plugin, local runtime, or skill merely to use connected MCP.\nAn installed Codex or Claude Canonry skill contains a generated copy of this\nguide plus links to host-native references. It does not replace runtime help.\n\n## Vocabulary and evidence\n\n- **Mentioned** means the brand appears in answer text. **Cited** means its\n domain appears in source links. Either, both, or neither can occur; never\n compute one signal from the other.\n- `answerMentioned: null` means not checked, not false. Missing runs and empty\n populations mean no measurement, not zero visibility.\n- Preserve project, time window, provider, requested/served model, location,\n sample size, and query class when comparing evidence. Use server-returned\n metrics; do not invent a score from incompatible populations.\n- Simple projects and Advanced portfolios share the workflow. For Advanced\n results, preserve Property, Target, market, plan revision, and class scope.\n Groups organize navigation; do not infer an unrequested fan-out.\n- Research is isolated evidence, not tracked measurement. A probe still spends\n quota and persists evidence but is excluded from normal tracking metrics.\n\n## Workflows\n\n**Status:** read the stored overview and freshness first. Say when evidence is\nmissing instead of silently creating it.\n\n**Setup:** Page Health needs no answer-engine provider; AI Visibility does.\nAfter a Page Health result on an install with no provider (a `NO_PROVIDER`\nnotice, or doctor's `providers.none-configured`), propose AI Visibility setup\nas the next step. The operator adds the provider key in the dashboard or in\ntheir own terminal; never ask for it in chat.\nRerunning `canonry bootstrap` after a provider change reloads saved provider\nsettings on a matching running local server and reports whether they became\nactive. If the server is offline, start it to apply the saved settings. For an\nexplicit reload of the connected server's own config, use\n`canonry settings reload-providers` or `canonry_providers_reload` with install\nadministrator authority. Remote servers are never reloaded automatically by\nbootstrap, and a local server that belongs to another install is left alone.\nPorts and database settings still need a restart.\n\n**Diagnose:** inspect stored history and comparable evidence. Explain what\nchanged separately from why it might have changed. A hypothesis is not a\nmeasured cause. Propose bounded verification if stored evidence is insufficient.\n\n**Prospecting:** generate a one-shot company snapshot without creating a project.\nInspect stored provider settings first. Agree on the company, domain, selected\nproviders, and queries before starting the quota-spending snapshot action.\nBrowser-only selection requires manual queries. Progressive stdio help offers\nthe discovery toolkit when this connection permits snapshots; load it, then\ncall help again. Fixed catalogs offer only already available actions. Read-only\nand restricted connections must not bypass missing snapshot access.\n\n**Measurement:** inspect the existing setup and results before proposing edits.\nKeep research, query tracking, plan publication, and sweep execution separate.\nFor direct research, submit the final editable query text in one context. For a\nreviewed batch, submit each explicit destination with its final text and one\nidempotency key. Pattern substitution happens in the client before either\nrequest; choosing a market or Property records a destination only and never\nrewrites a query or creates an automatic fan-out. `research.run` does not\nauthorize saving patterns, changing tracking, publishing plans, or settings.\nUse a supported preview where available, inspect its exact destination and\nrevision, then seek approval for the actual change. A preview may itself require\nwrite permission; never treat a dry-run flag as a universal safety guarantee.\n\n**Integrations:** inspect stored connection state and snapshot freshness first.\nProvider configuration evidence does not prove a browser event fired or a\nconversion was recorded. Connection, resource selection, refresh/sync, and live\nreads are separate actions. Credentials belong in the operator's secure setup\nflow, never in chat, tool arguments, reports, or public guidance.\n\n**Reports:** use saved evidence for the requested period and scope. Keep mention\nand citation signals separate, include dates and sample sizes, and state missing\nor stale inputs. For Advanced Property mention rankings, use\n`canonry_measurement_portfolio_summary` and its `mentionRanking.strongest`,\n`.weakest`, and `.excluded` lists. It defaults to non-brand questions; state the\nreturned class and report branded results separately. An unavailable portfolio\naggregate does not invalidate available Property mention rates. Flag excluded\nProperties individually; do not silently replace mention ranking with citation\nranking. Compact `nextCursor` completes only `pageList`; use `list` to enumerate\none ranking, markets, observed names or cited domains, preserving filters.\nFirst-page sibling lists are bounded summaries. Keep sample sizes and ties\nvisible. Preparing a report does not\nauthorize new measurement.\n\n## Authority and approval\n\n### Agent operations\n\nUse `canonry_key_self` (CLI `canonry key whoami --format json`) to inspect the\ncurrent credential's scopes, project boundary, and host-derived `operator`\nauthority without exposing its token. Missing `operator` means unapproved.\n`canonry_settings_get` and\n`canonry_telemetry_get` describe the connected server, not the agent's local\nmachine. Telemetry reports configured preference, effective state, and any\nenvironment override; inspecting status never creates an anonymous identifier.\nAfter approval, `canonry_telemetry_update` changes that preference and\n`canonry_provider_settings_update` changes an already-configured provider's\nmodel/quota. Both require `settings.write`; neither accepts credentials.\nServer telemetry reads and updates additionally require operator authority.\nOrdinary audit-history reads omit internal telemetry events and their state.\n\nOperator authority is deny-by-default and separate from customer admin roles.\nThe deployment owner must approve a dedicated, instance-wide API key's ID in\nthe server environment variable `CANONRY_OPERATOR_KEY_IDS` (comma-separated IDs),\nthen restart the server. Empty/unset approves nobody; wildcards are invalid.\nKeep the bearer private to internal operators; never approve a customer-held or\nshared proxy/bootstrap key. Use `logs.read` for read-only diagnostics, adding\n`settings.write` only when telemetry control is required. Ordinary key creation,\naccount roles, OAuth consent, and caller headers cannot grant operator status.\nRevoking an approved key invalidates it immediately. Host enrollment is a trust\nbootstrap step, intentionally unavailable through customer-facing APIs.\nAPI, CLI, and MCP enforce the same boundary; MCP hides internal tools unless\nthe server confirms operator authority, including in explicit read-only mode.\nProject analytics, research, and normal project permissions are unchanged.\n\n`canonry_logs_list` reads bounded, redacted runtime events from both the\napplication logger and Fastify request/error logging. It requires an\ninstance-wide `logs.read` grant (or wildcard) and a host-approved direct bearer.\nBrowser sessions, OAuth/delegated credentials, customer admins, and project-scoped\nkeys cannot use it, even with a project filter or a matching allowlist ID.\nA `logs.read`-only key is read-only automatically, without a\nsecond `read` marker. Named `*.read` scopes cannot grant mutations; an explicit\nwrite grant is needed and remains subject to its route gates. Returned messages\nare sanitized and bounded; raw request or response bodies, headers, cookies,\nprovider payloads, and stacks are not\npart of the queryable surface. The same secret-redaction policy runs before\nconsole output and storage. Do not deliberately log secrets: redaction is a\ndefense in depth, not permission to put credentials into diagnostic strings.\nOpaque escaped payloads containing secret assignments are omitted when safe\npartial masking cannot be guaranteed; correlate their retained error codes and IDs.\n\nFile-backed hosts retain runtime logs in SQLite across restarts, bounded to\n10,000 events and seven days. In-memory hosts report `retention: \"process\"`.\nFilter by `actor`, `requestId`, `runId`, `projectId`, `module`, `level`, or an\ninclusive `since`/`until` interval. Keep filters unchanged when resuming an\nopaque cursor; retention eviction can invalidate it. Inspect `retentionPolicy`,\n`captureErrors`, `dropped`, `truncated`, and `retention` before drawing\nconclusions. Missing logs are not proof that an action did not happen. Use\n`canonry_project_history` or `canonry_history_global` for persistent audit events;\noffset pages have deterministic ordering but are not snapshots of concurrent writes.\n\nAudit `actor` comes from authenticated identity (`user:<id>` or `api-key:<id>`),\nnot a caller-supplied header. A delegated MCP credential records its originating\nuser as actor and the actual credential in `credentialId`. `requestId` correlates\nHTTP events; `userAgent` and `actorSession` are bounded, untrusted client hints,\nnever identity or permission grants. Older audit rows are not backfilled with\nidentities the server cannot prove.\n\nBoth shipped HTTP hosts issue restart-safe UUID request IDs and return them in\n`x-request-id`. Use that value to correlate a CLI/API failure with log entries;\nHTTP diagnostics retain the method and route template, not raw URL parameters.\nRequest-bound loggers retain completion attribution, while generic background\ncontinuations stop inheriting caller identity after the response completes.\nCapture covers the owning server process after initialization, not arbitrary\nconsole output, other worker processes, or host/container logs. Run one server\ninstance per process and database, as required by the single-tenant deployment\nmodel; this is not a cross-tenant or distributed log collector.\n\nFor CLI use, settings reads are remote. Google setup and telemetry retain their\nlocal defaults: pass `--target server` explicitly to configure the connected\nserver. `schedule list <project>` lists all schedule kinds, and\n`notify events --target server` discovers the server's event catalog.\n\nMCP returns legacy text JSON plus structured results. Objects keep their shape;\narrays use `{items: [...]}` in `structuredContent`, and scalars use `{value: ...}`.\nErrors preserve the existing envelope and CLI exit codes: HTTP 4xx (including\n429 policy limits) use exit 1; HTTP 5xx use exit 2. Server-provided `Retry-After`\nand request IDs are exposed as `retryAfterMs` and `requestId` when available;\nclients do not infer retryability from HTTP 429 or retry automatically.\nFor a write with an ambiguous outcome, inspect saved state or its receipt before\nretrying; a retry hint is not proof that repeating a write is safe.\n\n### Action boundaries\n\nStart with stored evidence. Before a live provider read, sweep, probe, research\nrun, sync, write, or externally visible action, obtain approval covering its\nexact target, action, and bounded work. Approval already given for that exact\noperation need not be asked for again, but does not extend to more projects,\nlarger batches, retries with new identities, or recurring work.\n\nHTTP GET and MCP `readOnlyHint` describe aspects of an operation, not its cost\nor permission. Provider discovery, account reads, and live diagnostics may\nconsume quota even when labeled read-only. If the tool's effect is unclear,\ninspect its description and request direction before calling it.\n\nAuthentication, role/scope checks, project restrictions, quotas, and guarded\napproval receipts are enforced by the server. Help, skills, resources, and tool\nvisibility cannot grant authority. Never change credentials, endpoints, or\nproject identifiers to work around a missing tool or a `403` response.\n\nFor guarded ads writes, inspect unresolved operation receipts before retrying.\nUse the receipt's supported recovery action; do not replay a mutation under a\nnew identity. An executor cannot create or widen its own human approval grant.\nOn ambiguous results, exhausted bounds, or refusal, stop and report what is\nknown and what permission or operator action is needed.\n\n## Version and source\n\nThis public, versioned document is the source for initialization guidance,\nintent routes, the optional resource, and generated Canonry `SKILL.md` files.\nGuide v1 may receive compatible clarifications; incompatible routing contracts\nrequire a new guide version. The running server's help describes its actual\ncatalog and remains usable without fetching this document.\n"
|
|
10004
10021
|
};
|
|
10005
10022
|
|
|
10006
10023
|
// src/mcp/operations-guide.ts
|
|
@@ -10561,6 +10578,7 @@ export {
|
|
|
10561
10578
|
sentimentInstallReadiness,
|
|
10562
10579
|
dashboardManagedRunKindsSchema,
|
|
10563
10580
|
resolveOperatorApiKeyIds,
|
|
10581
|
+
withBootstrapProviderDefaults,
|
|
10564
10582
|
getBootstrapEnv,
|
|
10565
10583
|
providerConfigFromEntry,
|
|
10566
10584
|
adapterSupportsBatch,
|