seo 0.2.5 → 0.2.6
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/PRIVACY.md +41 -4
- package/README.md +11 -3
- package/dist/cli.js +91 -88
- package/dist/cli.js.map +1 -1
- package/dist/{dist-oOrG0Vub.js → dist-PRmi6cXV.js} +70 -65
- package/dist/dist-PRmi6cXV.js.map +1 -0
- package/dist/{dist-oHPXlHac.js → dist-Xkhuyn70.js} +1 -1
- package/dist/index.d.ts +78 -3
- package/dist/index.js +375 -6
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +3 -1
- package/dist/mcp.js +333 -6
- package/dist/mcp.js.map +1 -1
- package/dist/{package-BF_XgK7-.js → package-B9-D646K.js} +2 -2
- package/dist/{package-BF_XgK7-.js.map → package-B9-D646K.js.map} +1 -1
- package/package.json +2 -2
- package/dist/dist-oOrG0Vub.js.map +0 -1
package/dist/mcp.d.ts
CHANGED
|
@@ -65,7 +65,9 @@ declare function executeReport(id: string, params?: Record<string, unknown>): Pr
|
|
|
65
65
|
declare function runReport(id: string, params?: Record<string, unknown>): Promise<ToolResult>;
|
|
66
66
|
//#endregion
|
|
67
67
|
//#region packages/mcp/src/index.d.ts
|
|
68
|
-
declare function createServer(
|
|
68
|
+
declare function createServer(options?: {
|
|
69
|
+
telemetry?: boolean;
|
|
70
|
+
}): McpServer;
|
|
69
71
|
declare function startMcpServer(opts?: {
|
|
70
72
|
test?: boolean;
|
|
71
73
|
}): Promise<void>;
|
package/dist/mcp.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRequire as __seoCreateRequire } from 'node:module'; const require = __seoCreateRequire(import.meta.url);
|
|
2
|
-
import { n as load, t as version } from "./package-
|
|
2
|
+
import { n as load, t as version } from "./package-B9-D646K.js";
|
|
3
3
|
import { Headers, fetch as fetch$1 } from "undici";
|
|
4
4
|
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { homedir } from "node:os";
|
|
5
|
+
import { arch, homedir, platform } from "node:os";
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import lockfile from "proper-lockfile";
|
|
@@ -149,6 +149,7 @@ function resolveSeoCliPaths(input = {}) {
|
|
|
149
149
|
configFile: join(configDir, "config.json"),
|
|
150
150
|
tokensFile: join(configDir, "tokens.json"),
|
|
151
151
|
oauthClientFile: join(configDir, "oauth-client.json"),
|
|
152
|
+
telemetryStateFile: join(configDir, "telemetry.json"),
|
|
152
153
|
cacheDbFile: join(cacheDir, "cache.db")
|
|
153
154
|
};
|
|
154
155
|
}
|
|
@@ -25882,6 +25883,317 @@ new LocalCredentialsProvider();
|
|
|
25882
25883
|
//#endregion
|
|
25883
25884
|
//#region packages/core/dist/version.js
|
|
25884
25885
|
const SEO_VERSION = version;
|
|
25886
|
+
const TELEMETRY_TIMEOUT_MS = 2e3;
|
|
25887
|
+
const TELEMETRY_REPORTS = [
|
|
25888
|
+
"affected-urls",
|
|
25889
|
+
"agent-readiness",
|
|
25890
|
+
"ai-readiness",
|
|
25891
|
+
"ai-referrals",
|
|
25892
|
+
"ai-search-scorecard",
|
|
25893
|
+
"audit-page",
|
|
25894
|
+
"audit-urls",
|
|
25895
|
+
"cannibalisation",
|
|
25896
|
+
"community-intent",
|
|
25897
|
+
"compare-crawls",
|
|
25898
|
+
"content-optimization",
|
|
25899
|
+
"crawl-diff",
|
|
25900
|
+
"site-crawl",
|
|
25901
|
+
"ctr-underperformers",
|
|
25902
|
+
"decaying-pages",
|
|
25903
|
+
"setup-check",
|
|
25904
|
+
"entity-readiness",
|
|
25905
|
+
"explain-crawl-issue",
|
|
25906
|
+
"geo-gaps",
|
|
25907
|
+
"crawl-report",
|
|
25908
|
+
"index-coverage",
|
|
25909
|
+
"index-coverage-plan",
|
|
25910
|
+
"index-monitor",
|
|
25911
|
+
"index-watch",
|
|
25912
|
+
"internal-links",
|
|
25913
|
+
"link-recovery",
|
|
25914
|
+
"crawl-history",
|
|
25915
|
+
"crawler-rules",
|
|
25916
|
+
"llms-txt-audit",
|
|
25917
|
+
"generate-llms-txt",
|
|
25918
|
+
"measure-change",
|
|
25919
|
+
"monthly-report",
|
|
25920
|
+
"okf-build",
|
|
25921
|
+
"okf-validate",
|
|
25922
|
+
"page-opportunities",
|
|
25923
|
+
"performance-audit",
|
|
25924
|
+
"pseo-audit",
|
|
25925
|
+
"query-clusters",
|
|
25926
|
+
"quick-wins",
|
|
25927
|
+
"redirect-trace",
|
|
25928
|
+
"narrative-report",
|
|
25929
|
+
"second-page",
|
|
25930
|
+
"segment-impact",
|
|
25931
|
+
"striking-distance",
|
|
25932
|
+
"seo-to-ai-query",
|
|
25933
|
+
"top-fixes",
|
|
25934
|
+
"traffic-anomaly",
|
|
25935
|
+
"update-correlation",
|
|
25936
|
+
"search-performance-overview",
|
|
25937
|
+
"monthly-action-plan",
|
|
25938
|
+
"refresh-priorities",
|
|
25939
|
+
"technical-watch",
|
|
25940
|
+
"update-postmortem"
|
|
25941
|
+
];
|
|
25942
|
+
const RETENTION_MILESTONES = [
|
|
25943
|
+
{
|
|
25944
|
+
days: 1,
|
|
25945
|
+
event: "active_d1"
|
|
25946
|
+
},
|
|
25947
|
+
{
|
|
25948
|
+
days: 7,
|
|
25949
|
+
event: "active_d7"
|
|
25950
|
+
},
|
|
25951
|
+
{
|
|
25952
|
+
days: 30,
|
|
25953
|
+
event: "active_d30"
|
|
25954
|
+
}
|
|
25955
|
+
];
|
|
25956
|
+
const CI_ENVIRONMENT_KEYS = [
|
|
25957
|
+
"GITHUB_ACTIONS",
|
|
25958
|
+
"GITLAB_CI",
|
|
25959
|
+
"CIRCLECI",
|
|
25960
|
+
"TRAVIS",
|
|
25961
|
+
"BUILDKITE",
|
|
25962
|
+
"JENKINS_URL",
|
|
25963
|
+
"TEAMCITY_VERSION",
|
|
25964
|
+
"TF_BUILD",
|
|
25965
|
+
"BITBUCKET_BUILD_NUMBER",
|
|
25966
|
+
"CODEBUILD_BUILD_ID"
|
|
25967
|
+
];
|
|
25968
|
+
const TELEMETRY_NOTICE = `SEO Skill collects anonymous usage data to improve the tool (event name,
|
|
25969
|
+
report id, version, agent, OS, architecture, Node major, and install week;
|
|
25970
|
+
never URLs, report data, or identifiers of any kind).
|
|
25971
|
+
Docs: https://seoskill.dev/telemetry
|
|
25972
|
+
Disable: seo telemetry disable (or set DO_NOT_TRACK=1)\n`;
|
|
25973
|
+
function optionEnv(options) {
|
|
25974
|
+
return options.env ?? process.env;
|
|
25975
|
+
}
|
|
25976
|
+
function optionNow(options) {
|
|
25977
|
+
return options.now ?? /* @__PURE__ */ new Date();
|
|
25978
|
+
}
|
|
25979
|
+
function optionStateFile(options) {
|
|
25980
|
+
return options.stateFile ?? getSeoCliPaths().telemetryStateFile;
|
|
25981
|
+
}
|
|
25982
|
+
function isEnvEnabled(value) {
|
|
25983
|
+
return value === "1" || value?.toLowerCase() === "true";
|
|
25984
|
+
}
|
|
25985
|
+
function isTelemetryCi(env = process.env) {
|
|
25986
|
+
return env.NODE_ENV === "test" || Boolean(env.NODE_TEST_CONTEXT) || isEnvEnabled(env.CI) || CI_ENVIRONMENT_KEYS.some((key) => Boolean(env[key]));
|
|
25987
|
+
}
|
|
25988
|
+
function environmentDisableReason(env) {
|
|
25989
|
+
if (isTelemetryCi(env)) return "ci";
|
|
25990
|
+
if (isEnvEnabled(env.DO_NOT_TRACK)) return "do_not_track";
|
|
25991
|
+
if (isEnvEnabled(env.SEOSKILL_TELEMETRY_DISABLED) || isEnvEnabled(env.SEO_TELEMETRY_DISABLED)) return "environment";
|
|
25992
|
+
}
|
|
25993
|
+
function isTelemetryMilestone(value) {
|
|
25994
|
+
return typeof value === "string" && [
|
|
25995
|
+
"first_run",
|
|
25996
|
+
"setup_complete",
|
|
25997
|
+
"first_audit_complete",
|
|
25998
|
+
"active_d1",
|
|
25999
|
+
"active_d7",
|
|
26000
|
+
"active_d30"
|
|
26001
|
+
].includes(value);
|
|
26002
|
+
}
|
|
26003
|
+
function isTelemetryReport(value) {
|
|
26004
|
+
return typeof value === "string" && TELEMETRY_REPORTS.includes(value);
|
|
26005
|
+
}
|
|
26006
|
+
function isValidCohort(value) {
|
|
26007
|
+
return typeof value === "string" && /^\d{4}-W(?:0[1-9]|[1-4]\d|5[0-3])$/.test(value);
|
|
26008
|
+
}
|
|
26009
|
+
function isTelemetryState(value) {
|
|
26010
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
26011
|
+
const state = value;
|
|
26012
|
+
return typeof state.telemetryEnabled === "boolean" && typeof state.firstRunAt === "string" && Number.isFinite(Date.parse(state.firstRunAt)) && isValidCohort(state.cohort) && Array.isArray(state.sentMilestones) && state.sentMilestones.every(isTelemetryMilestone);
|
|
26013
|
+
}
|
|
26014
|
+
function readState(path) {
|
|
26015
|
+
if (!existsSync(path)) return { kind: "missing" };
|
|
26016
|
+
const value = readJsonFile(path);
|
|
26017
|
+
return isTelemetryState(value) ? {
|
|
26018
|
+
kind: "valid",
|
|
26019
|
+
state: value
|
|
26020
|
+
} : { kind: "invalid" };
|
|
26021
|
+
}
|
|
26022
|
+
function writeState(path, state) {
|
|
26023
|
+
writeJsonAtomic(path, state, 384);
|
|
26024
|
+
}
|
|
26025
|
+
function isoWeek(date) {
|
|
26026
|
+
const utc = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
|
|
26027
|
+
const day = utc.getUTCDay() || 7;
|
|
26028
|
+
utc.setUTCDate(utc.getUTCDate() + 4 - day);
|
|
26029
|
+
const yearStart = new Date(Date.UTC(utc.getUTCFullYear(), 0, 1));
|
|
26030
|
+
const week = Math.ceil(((utc.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
|
|
26031
|
+
return `${utc.getUTCFullYear()}-W${String(week).padStart(2, "0")}`;
|
|
26032
|
+
}
|
|
26033
|
+
function newState(options, enabled = true) {
|
|
26034
|
+
const now = optionNow(options);
|
|
26035
|
+
return {
|
|
26036
|
+
telemetryEnabled: enabled,
|
|
26037
|
+
firstRunAt: now.toISOString(),
|
|
26038
|
+
cohort: isoWeek(now),
|
|
26039
|
+
sentMilestones: []
|
|
26040
|
+
};
|
|
26041
|
+
}
|
|
26042
|
+
function detectTelemetryAgent(input = {}) {
|
|
26043
|
+
const env = input.env ?? process.env;
|
|
26044
|
+
const clientName = input.clientName?.toLowerCase() ?? "";
|
|
26045
|
+
if (clientName.includes("claude")) return "claude-code";
|
|
26046
|
+
if (clientName.includes("cursor")) return "cursor";
|
|
26047
|
+
if (clientName.includes("codex")) return "codex";
|
|
26048
|
+
if (input.clientName) return "unknown";
|
|
26049
|
+
if (env.CLAUDECODE || env.CLAUDE_CODE) return "claude-code";
|
|
26050
|
+
if (env.CURSOR_AGENT || env.CURSOR_TRACE_ID || env.CURSOR_SESSION_ID) return "cursor";
|
|
26051
|
+
if (env.CODEX_HOME || env.CODEX_THREAD_ID || env.CODEX_SANDBOX) return "codex";
|
|
26052
|
+
return "cli";
|
|
26053
|
+
}
|
|
26054
|
+
function telemetryAgent(options) {
|
|
26055
|
+
return options.agent ?? detectTelemetryAgent({
|
|
26056
|
+
clientName: options.clientName,
|
|
26057
|
+
env: optionEnv(options)
|
|
26058
|
+
});
|
|
26059
|
+
}
|
|
26060
|
+
function nodeMajor(version) {
|
|
26061
|
+
return version.replace(/^v/, "").split(".")[0] || "unknown";
|
|
26062
|
+
}
|
|
26063
|
+
function buildTelemetryPayload(event, state, fields = {}, options = {}) {
|
|
26064
|
+
return {
|
|
26065
|
+
event,
|
|
26066
|
+
version: options.version ?? SEO_VERSION,
|
|
26067
|
+
agent: telemetryAgent(options),
|
|
26068
|
+
os: options.processPlatform ?? platform(),
|
|
26069
|
+
arch: options.processArch ?? arch(),
|
|
26070
|
+
node: nodeMajor(options.nodeVersion ?? process.version),
|
|
26071
|
+
cohort: state.cohort,
|
|
26072
|
+
schema: 1,
|
|
26073
|
+
...fields.errorCategory ? { errorCategory: fields.errorCategory } : {},
|
|
26074
|
+
...fields.report ? { report: fields.report } : {}
|
|
26075
|
+
};
|
|
26076
|
+
}
|
|
26077
|
+
function dispatchTelemetry(payload, options) {
|
|
26078
|
+
const fetchTelemetry = options.fetch ?? globalThis.fetch;
|
|
26079
|
+
try {
|
|
26080
|
+
fetchTelemetry(options.endpoint ?? "https://seoskill.dev/api/t", {
|
|
26081
|
+
method: "POST",
|
|
26082
|
+
headers: { "content-type": "application/json" },
|
|
26083
|
+
body: JSON.stringify(payload),
|
|
26084
|
+
signal: AbortSignal.timeout(TELEMETRY_TIMEOUT_MS)
|
|
26085
|
+
}).catch(() => void 0);
|
|
26086
|
+
} catch {}
|
|
26087
|
+
}
|
|
26088
|
+
function statusFromState(options) {
|
|
26089
|
+
const stateFile = optionStateFile(options);
|
|
26090
|
+
const envReason = environmentDisableReason(optionEnv(options));
|
|
26091
|
+
const stored = readState(stateFile);
|
|
26092
|
+
if (envReason) return {
|
|
26093
|
+
enabled: false,
|
|
26094
|
+
reason: envReason,
|
|
26095
|
+
stateFile,
|
|
26096
|
+
...stored.kind === "valid" ? { state: stored.state } : {}
|
|
26097
|
+
};
|
|
26098
|
+
if (stored.kind === "invalid") return {
|
|
26099
|
+
enabled: false,
|
|
26100
|
+
reason: "invalid_state",
|
|
26101
|
+
stateFile
|
|
26102
|
+
};
|
|
26103
|
+
if (stored.kind === "valid" && !stored.state.telemetryEnabled) return {
|
|
26104
|
+
enabled: false,
|
|
26105
|
+
reason: "local_setting",
|
|
26106
|
+
stateFile,
|
|
26107
|
+
state: stored.state
|
|
26108
|
+
};
|
|
26109
|
+
return {
|
|
26110
|
+
enabled: true,
|
|
26111
|
+
stateFile,
|
|
26112
|
+
...stored.kind === "valid" ? { state: stored.state } : {}
|
|
26113
|
+
};
|
|
26114
|
+
}
|
|
26115
|
+
function enabledState(options) {
|
|
26116
|
+
const status = statusFromState(options);
|
|
26117
|
+
return status.enabled ? status.state : void 0;
|
|
26118
|
+
}
|
|
26119
|
+
function initializeTelemetry(options = {}) {
|
|
26120
|
+
const initialStatus = statusFromState(options);
|
|
26121
|
+
if (!initialStatus.enabled) return initialStatus;
|
|
26122
|
+
const stateFile = initialStatus.stateFile;
|
|
26123
|
+
const state = initialStatus.state ?? newState(options);
|
|
26124
|
+
const events = [];
|
|
26125
|
+
if (!state.sentMilestones.includes("first_run")) {
|
|
26126
|
+
try {
|
|
26127
|
+
(options.notice ?? ((message) => process.stderr.write(message)))(TELEMETRY_NOTICE);
|
|
26128
|
+
} catch {
|
|
26129
|
+
return {
|
|
26130
|
+
enabled: false,
|
|
26131
|
+
reason: "invalid_state",
|
|
26132
|
+
stateFile
|
|
26133
|
+
};
|
|
26134
|
+
}
|
|
26135
|
+
state.sentMilestones.push("first_run");
|
|
26136
|
+
events.push("first_run");
|
|
26137
|
+
}
|
|
26138
|
+
const daysSinceFirstRun = (optionNow(options).getTime() - Date.parse(state.firstRunAt)) / 864e5;
|
|
26139
|
+
for (const milestone of RETENTION_MILESTONES) if (daysSinceFirstRun >= milestone.days && !state.sentMilestones.includes(milestone.event)) {
|
|
26140
|
+
state.sentMilestones.push(milestone.event);
|
|
26141
|
+
events.push(milestone.event);
|
|
26142
|
+
}
|
|
26143
|
+
try {
|
|
26144
|
+
writeState(stateFile, state);
|
|
26145
|
+
} catch {
|
|
26146
|
+
return {
|
|
26147
|
+
enabled: false,
|
|
26148
|
+
reason: "invalid_state",
|
|
26149
|
+
stateFile
|
|
26150
|
+
};
|
|
26151
|
+
}
|
|
26152
|
+
for (const event of events) dispatchTelemetry(buildTelemetryPayload(event, state, {}, options), options);
|
|
26153
|
+
return {
|
|
26154
|
+
enabled: true,
|
|
26155
|
+
stateFile,
|
|
26156
|
+
state
|
|
26157
|
+
};
|
|
26158
|
+
}
|
|
26159
|
+
function sendEvent(event, fields, options) {
|
|
26160
|
+
const state = enabledState(options);
|
|
26161
|
+
if (!state) return;
|
|
26162
|
+
dispatchTelemetry(buildTelemetryPayload(event, state, fields, options), options);
|
|
26163
|
+
}
|
|
26164
|
+
function trackTelemetryReportStart(report, options = {}) {
|
|
26165
|
+
if (!isTelemetryReport(report)) return;
|
|
26166
|
+
sendEvent("audit_start", { report }, options);
|
|
26167
|
+
}
|
|
26168
|
+
function trackTelemetryReportComplete(report, options = {}) {
|
|
26169
|
+
if (!isTelemetryReport(report)) return;
|
|
26170
|
+
const state = enabledState(options);
|
|
26171
|
+
if (!state) return;
|
|
26172
|
+
dispatchTelemetry(buildTelemetryPayload("audit_complete", state, { report }, options), options);
|
|
26173
|
+
if (state.sentMilestones.includes("first_audit_complete")) return;
|
|
26174
|
+
state.sentMilestones.push("first_audit_complete");
|
|
26175
|
+
try {
|
|
26176
|
+
writeState(optionStateFile(options), state);
|
|
26177
|
+
} catch {
|
|
26178
|
+
return;
|
|
26179
|
+
}
|
|
26180
|
+
dispatchTelemetry(buildTelemetryPayload("first_audit_complete", state, { report }, options), options);
|
|
26181
|
+
}
|
|
26182
|
+
function trackTelemetryReportFailed(report, errorCategory, options = {}) {
|
|
26183
|
+
if (!isTelemetryReport(report)) return;
|
|
26184
|
+
sendEvent("audit_failed", {
|
|
26185
|
+
errorCategory,
|
|
26186
|
+
report
|
|
26187
|
+
}, options);
|
|
26188
|
+
}
|
|
26189
|
+
function telemetryErrorCategory(error) {
|
|
26190
|
+
if (error instanceof Error && error.name === "AbortError") return "crawl_timeout";
|
|
26191
|
+
const code = error && typeof error === "object" && "code" in error ? String(error.code) : void 0;
|
|
26192
|
+
if (code === "ACCESS_DENIED" || code === "AUTH_CONFIG_REQUIRED" || code === "AUTH_EXPIRED" || code === "AUTH_REQUIRED") return "auth";
|
|
26193
|
+
if (code === "INVALID_INPUT" || code === "PROPERTY_NOT_FOUND") return "config";
|
|
26194
|
+
if (code === "OPTIONAL_PROVIDER_UNAVAILABLE" || code === "PROVIDER_UNAVAILABLE" || code === "RATE_LIMITED") return "network";
|
|
26195
|
+
return "unknown";
|
|
26196
|
+
}
|
|
25885
26197
|
//#endregion
|
|
25886
26198
|
//#region packages/mcp/src/input-schemas.ts
|
|
25887
26199
|
const calendarDateSchema = z$1.iso.date("Use a YYYY-MM-DD date.");
|
|
@@ -30053,7 +30365,8 @@ async function runReport(id, params = {}) {
|
|
|
30053
30365
|
//#endregion
|
|
30054
30366
|
//#region packages/mcp/src/discovery-tools.ts
|
|
30055
30367
|
const openOutputSchema = z$1.looseObject({});
|
|
30056
|
-
|
|
30368
|
+
const reportIds = new Set(listReports().map((report) => report.id));
|
|
30369
|
+
function registerDiscoveryTools(server, options = {}) {
|
|
30057
30370
|
server.registerTool("seo_list_reports", {
|
|
30058
30371
|
description: "List compact SEO report ids, names, and purposes, optionally by category",
|
|
30059
30372
|
inputSchema: { category: z$1.enum(REPORT_CATEGORIES).optional() },
|
|
@@ -30097,17 +30410,31 @@ function registerDiscoveryTools(server) {
|
|
|
30097
30410
|
outputSchema: openOutputSchema,
|
|
30098
30411
|
annotations: { destructiveHint: false }
|
|
30099
30412
|
}, async ({ id, params }) => {
|
|
30100
|
-
|
|
30413
|
+
const telemetry = reportIds.has(id) ? options.telemetry?.() : void 0;
|
|
30414
|
+
if (telemetry) trackTelemetryReportStart(id, telemetry);
|
|
30415
|
+
try {
|
|
30416
|
+
const result = await runReport(id, params);
|
|
30417
|
+
if (telemetry) if (result.isError) trackTelemetryReportFailed(id, telemetryErrorCategory(result.structuredContent?.error), telemetry);
|
|
30418
|
+
else trackTelemetryReportComplete(id, telemetry);
|
|
30419
|
+
return result;
|
|
30420
|
+
} catch (error) {
|
|
30421
|
+
if (telemetry) trackTelemetryReportFailed(id, telemetryErrorCategory(error), telemetry);
|
|
30422
|
+
throw error;
|
|
30423
|
+
}
|
|
30101
30424
|
});
|
|
30102
30425
|
}
|
|
30103
30426
|
//#endregion
|
|
30104
30427
|
//#region packages/mcp/src/index.ts
|
|
30105
|
-
function createServer() {
|
|
30428
|
+
function createServer(options = {}) {
|
|
30106
30429
|
const server = new McpServer({
|
|
30107
30430
|
name: "seo",
|
|
30108
30431
|
version: SEO_VERSION
|
|
30109
30432
|
}, { capabilities: { logging: {} } });
|
|
30110
|
-
|
|
30433
|
+
const telemetryOptions = () => ({ clientName: server.server.getClientVersion()?.name });
|
|
30434
|
+
registerDiscoveryTools(server, { telemetry: options.telemetry === false ? void 0 : telemetryOptions });
|
|
30435
|
+
if (options.telemetry !== false) server.server.oninitialized = () => {
|
|
30436
|
+
initializeTelemetry(telemetryOptions());
|
|
30437
|
+
};
|
|
30111
30438
|
return server;
|
|
30112
30439
|
}
|
|
30113
30440
|
async function startMcpServer(opts = {}) {
|