@recapt/mcp 0.0.18-beta → 0.0.20-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.d.ts +0 -11
- package/dist/cli/index.js +1059 -21
- package/dist/index.d.ts +0 -18
- package/dist/index.js +3205 -247
- package/dist/tools/catalog/anthropicToolCatalog.json +1306 -0
- package/dist/tools/catalog/toolCatalog.json +4078 -382
- package/package.json +10 -3
- package/skills/self-improvement.md +388 -222
- package/templates/self-improvement-full.md +91 -0
- package/templates/{self-improvement.md → self-improvement-lite.md} +13 -9
- package/dist/api/client.d.ts +0 -14
- package/dist/api/client.js +0 -67
- package/dist/cli/commands/setup-self-improvement-gh.d.ts +0 -7
- package/dist/cli/commands/setup-self-improvement-gh.js +0 -310
- package/dist/cli/commands/setup.d.ts +0 -7
- package/dist/cli/commands/setup.js +0 -173
- package/dist/cli/commands/skill.d.ts +0 -24
- package/dist/cli/commands/skill.js +0 -264
- package/dist/cli/utils/ide-config.d.ts +0 -31
- package/dist/cli/utils/ide-config.js +0 -294
- package/dist/cli/utils/prompts.d.ts +0 -22
- package/dist/cli/utils/prompts.js +0 -71
- package/dist/tools/analyzeFlow.d.ts +0 -7
- package/dist/tools/analyzeFlow.js +0 -68
- package/dist/tools/analyzeFunnel.d.ts +0 -7
- package/dist/tools/analyzeFunnel.js +0 -63
- package/dist/tools/catalog/callTool.d.ts +0 -22
- package/dist/tools/catalog/callTool.js +0 -92
- package/dist/tools/catalog/index.d.ts +0 -11
- package/dist/tools/catalog/index.js +0 -11
- package/dist/tools/catalog/searchTools.d.ts +0 -22
- package/dist/tools/catalog/searchTools.js +0 -194
- package/dist/tools/compareCohorts.d.ts +0 -6
- package/dist/tools/compareCohorts.js +0 -84
- package/dist/tools/comparePeriods.d.ts +0 -6
- package/dist/tools/comparePeriods.js +0 -54
- package/dist/tools/detectDrift.d.ts +0 -6
- package/dist/tools/detectDrift.js +0 -55
- package/dist/tools/detectRegressions.d.ts +0 -6
- package/dist/tools/detectRegressions.js +0 -63
- package/dist/tools/diagnostic.d.ts +0 -6
- package/dist/tools/diagnostic.js +0 -109
- package/dist/tools/discoverPersonas.d.ts +0 -6
- package/dist/tools/discoverPersonas.js +0 -50
- package/dist/tools/getActionableIssues.d.ts +0 -7
- package/dist/tools/getActionableIssues.js +0 -55
- package/dist/tools/getAnomalies.d.ts +0 -6
- package/dist/tools/getAnomalies.js +0 -53
- package/dist/tools/getConsoleErrors.d.ts +0 -6
- package/dist/tools/getConsoleErrors.js +0 -61
- package/dist/tools/getDeadClicks.d.ts +0 -6
- package/dist/tools/getDeadClicks.js +0 -42
- package/dist/tools/getDomains.d.ts +0 -6
- package/dist/tools/getDomains.js +0 -34
- package/dist/tools/getElementFriction.d.ts +0 -6
- package/dist/tools/getElementFriction.js +0 -45
- package/dist/tools/getFlowFriction.d.ts +0 -7
- package/dist/tools/getFlowFriction.js +0 -57
- package/dist/tools/getFormFriction.d.ts +0 -6
- package/dist/tools/getFormFriction.js +0 -42
- package/dist/tools/getIssues.d.ts +0 -6
- package/dist/tools/getIssues.js +0 -82
- package/dist/tools/getJourneyPatterns.d.ts +0 -7
- package/dist/tools/getJourneyPatterns.js +0 -50
- package/dist/tools/getPageMetrics.d.ts +0 -6
- package/dist/tools/getPageMetrics.js +0 -47
- package/dist/tools/getPageTrends.d.ts +0 -6
- package/dist/tools/getPageTrends.js +0 -46
- package/dist/tools/getSessionDetails.d.ts +0 -6
- package/dist/tools/getSessionDetails.js +0 -70
- package/dist/tools/getSessionPages.d.ts +0 -7
- package/dist/tools/getSessionPages.js +0 -74
- package/dist/tools/getUxHealthReport.d.ts +0 -7
- package/dist/tools/getUxHealthReport.js +0 -50
- package/dist/tools/improvementRun.d.ts +0 -6
- package/dist/tools/improvementRun.js +0 -315
- package/dist/tools/knowledge.d.ts +0 -6
- package/dist/tools/knowledge.js +0 -186
- package/dist/tools/listPages.d.ts +0 -6
- package/dist/tools/listPages.js +0 -50
- package/dist/tools/listSessions.d.ts +0 -7
- package/dist/tools/listSessions.js +0 -67
- package/dist/tools/memory.d.ts +0 -7
- package/dist/tools/memory.js +0 -119
- package/dist/tools/predictOutcomes.d.ts +0 -6
- package/dist/tools/predictOutcomes.js +0 -66
- package/dist/tools/remediation.d.ts +0 -6
- package/dist/tools/remediation.js +0 -223
- package/dist/tools/scanSite.d.ts +0 -6
- package/dist/tools/scanSite.js +0 -51
- package/dist/tools/searchSessions.d.ts +0 -6
- package/dist/tools/searchSessions.js +0 -51
- package/dist/tools/triage.d.ts +0 -6
- package/dist/tools/triage.js +0 -114
- package/dist/tools/triageSessions.d.ts +0 -8
- package/dist/tools/triageSessions.js +0 -197
- package/dist/tools/upgradeOptions.d.ts +0 -7
- package/dist/tools/upgradeOptions.js +0 -67
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IDE Configuration Utilities
|
|
3
|
-
*
|
|
4
|
-
* Handles detection and configuration of MCP servers across different AI IDEs.
|
|
5
|
-
*/
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import path from "path";
|
|
8
|
-
import os from "os";
|
|
9
|
-
export const IDE_CONFIGS = [
|
|
10
|
-
{
|
|
11
|
-
name: "Cursor",
|
|
12
|
-
globalPath: "~/.cursor/mcp.json",
|
|
13
|
-
projectPath: ".cursor/mcp.json",
|
|
14
|
-
rootKey: "mcpServers",
|
|
15
|
-
format: "json",
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: "Claude Code",
|
|
19
|
-
globalPath: "~/.claude.json",
|
|
20
|
-
projectPath: ".mcp.json",
|
|
21
|
-
rootKey: "mcpServers",
|
|
22
|
-
format: "json",
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
name: "Windsurf",
|
|
26
|
-
globalPath: "~/.windsurf/mcp.json",
|
|
27
|
-
projectPath: ".windsurf/mcp.json",
|
|
28
|
-
rootKey: "mcpServers",
|
|
29
|
-
format: "json",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: "VS Code",
|
|
33
|
-
globalPath: null,
|
|
34
|
-
projectPath: ".vscode/mcp.json",
|
|
35
|
-
rootKey: "servers",
|
|
36
|
-
format: "json",
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: "Codex CLI",
|
|
40
|
-
globalPath: "~/.codex/config.toml",
|
|
41
|
-
projectPath: ".codex/config.toml",
|
|
42
|
-
rootKey: "mcp_servers",
|
|
43
|
-
format: "toml",
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
name: "Zed",
|
|
47
|
-
globalPath: "~/.config/zed/settings.json",
|
|
48
|
-
projectPath: ".zed/settings.json",
|
|
49
|
-
rootKey: "context_servers",
|
|
50
|
-
format: "json",
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: "GitHub Copilot",
|
|
54
|
-
globalPath: null,
|
|
55
|
-
projectPath: ".github/mcp.json",
|
|
56
|
-
rootKey: "servers",
|
|
57
|
-
format: "json",
|
|
58
|
-
},
|
|
59
|
-
];
|
|
60
|
-
function expandPath(p) {
|
|
61
|
-
if (p.startsWith("~/")) {
|
|
62
|
-
return path.join(os.homedir(), p.slice(2));
|
|
63
|
-
}
|
|
64
|
-
return p;
|
|
65
|
-
}
|
|
66
|
-
function ideExists(config) {
|
|
67
|
-
if (!config.globalPath) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
const resolved = expandPath(config.globalPath);
|
|
71
|
-
const dir = path.dirname(resolved);
|
|
72
|
-
if (config.name === "Claude Code") {
|
|
73
|
-
return (fs.existsSync(resolved) ||
|
|
74
|
-
fs.existsSync(path.join(os.homedir(), ".claude")));
|
|
75
|
-
}
|
|
76
|
-
if (config.name === "Zed") {
|
|
77
|
-
return fs.existsSync(path.join(os.homedir(), ".config", "zed"));
|
|
78
|
-
}
|
|
79
|
-
if (config.name === "Codex CLI") {
|
|
80
|
-
return fs.existsSync(path.join(os.homedir(), ".codex"));
|
|
81
|
-
}
|
|
82
|
-
return fs.existsSync(dir);
|
|
83
|
-
}
|
|
84
|
-
export function detectInstalledIdes() {
|
|
85
|
-
return IDE_CONFIGS.map((config) => ({
|
|
86
|
-
config,
|
|
87
|
-
detected: ideExists(config),
|
|
88
|
-
globalPathResolved: config.globalPath
|
|
89
|
-
? expandPath(config.globalPath)
|
|
90
|
-
: null,
|
|
91
|
-
}));
|
|
92
|
-
}
|
|
93
|
-
function getRecaptServerConfig(secretKey) {
|
|
94
|
-
return {
|
|
95
|
-
type: "stdio",
|
|
96
|
-
command: "npx",
|
|
97
|
-
args: ["-y", "@recapt/mcp@latest"],
|
|
98
|
-
env: {
|
|
99
|
-
RECAPT_SECRET_KEY: secretKey,
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
export function readIdeConfig(configPath, format = "json") {
|
|
104
|
-
const resolved = expandPath(configPath);
|
|
105
|
-
if (!fs.existsSync(resolved)) {
|
|
106
|
-
return {};
|
|
107
|
-
}
|
|
108
|
-
try {
|
|
109
|
-
const content = fs.readFileSync(resolved, "utf-8");
|
|
110
|
-
if (format === "toml") {
|
|
111
|
-
return parseToml(content);
|
|
112
|
-
}
|
|
113
|
-
return JSON.parse(content);
|
|
114
|
-
}
|
|
115
|
-
catch {
|
|
116
|
-
return {};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function parseToml(content) {
|
|
120
|
-
const result = {};
|
|
121
|
-
let currentSection = "";
|
|
122
|
-
let currentSubSection = "";
|
|
123
|
-
for (const line of content.split("\n")) {
|
|
124
|
-
const trimmed = line.trim();
|
|
125
|
-
if (!trimmed || trimmed.startsWith("#")) {
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
const sectionMatch = trimmed.match(/^\[([^\]]+)\]$/);
|
|
129
|
-
if (sectionMatch) {
|
|
130
|
-
const section = sectionMatch[1];
|
|
131
|
-
const parts = section.split(".");
|
|
132
|
-
if (parts.length === 1) {
|
|
133
|
-
currentSection = parts[0];
|
|
134
|
-
currentSubSection = "";
|
|
135
|
-
if (!result[currentSection]) {
|
|
136
|
-
result[currentSection] = {};
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
else if (parts.length === 2) {
|
|
140
|
-
currentSection = parts[0];
|
|
141
|
-
currentSubSection = parts[1];
|
|
142
|
-
if (!result[currentSection]) {
|
|
143
|
-
result[currentSection] = {};
|
|
144
|
-
}
|
|
145
|
-
const sectionObj = result[currentSection];
|
|
146
|
-
if (!sectionObj[currentSubSection]) {
|
|
147
|
-
sectionObj[currentSubSection] = {};
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
const kvMatch = trimmed.match(/^(\w+)\s*=\s*(.+)$/);
|
|
153
|
-
if (kvMatch) {
|
|
154
|
-
const [, key, rawValue] = kvMatch;
|
|
155
|
-
const value = parseTomlValue(rawValue);
|
|
156
|
-
if (currentSubSection) {
|
|
157
|
-
const sectionObj = result[currentSection];
|
|
158
|
-
const subSectionObj = sectionObj[currentSubSection];
|
|
159
|
-
subSectionObj[key] = value;
|
|
160
|
-
}
|
|
161
|
-
else if (currentSection) {
|
|
162
|
-
const sectionObj = result[currentSection];
|
|
163
|
-
sectionObj[key] = value;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
result[key] = value;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return result;
|
|
171
|
-
}
|
|
172
|
-
function parseTomlValue(raw) {
|
|
173
|
-
const trimmed = raw.trim();
|
|
174
|
-
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
175
|
-
return trimmed.slice(1, -1);
|
|
176
|
-
}
|
|
177
|
-
if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
178
|
-
return trimmed.slice(1, -1);
|
|
179
|
-
}
|
|
180
|
-
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
181
|
-
const inner = trimmed.slice(1, -1);
|
|
182
|
-
if (!inner.trim())
|
|
183
|
-
return [];
|
|
184
|
-
return inner.split(",").map((item) => {
|
|
185
|
-
const t = item.trim();
|
|
186
|
-
if ((t.startsWith('"') && t.endsWith('"')) ||
|
|
187
|
-
(t.startsWith("'") && t.endsWith("'"))) {
|
|
188
|
-
return t.slice(1, -1);
|
|
189
|
-
}
|
|
190
|
-
return t;
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
if (trimmed === "true")
|
|
194
|
-
return true;
|
|
195
|
-
if (trimmed === "false")
|
|
196
|
-
return false;
|
|
197
|
-
const num = Number(trimmed);
|
|
198
|
-
if (!isNaN(num))
|
|
199
|
-
return num;
|
|
200
|
-
return trimmed;
|
|
201
|
-
}
|
|
202
|
-
function stringifyToml(obj, prefix = "") {
|
|
203
|
-
const lines = [];
|
|
204
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
205
|
-
if (value === null || value === undefined)
|
|
206
|
-
continue;
|
|
207
|
-
if (typeof value === "object" && !Array.isArray(value)) {
|
|
208
|
-
const sectionKey = prefix ? `${prefix}.${key}` : key;
|
|
209
|
-
const nested = value;
|
|
210
|
-
const hasNestedObjects = Object.values(nested).some((v) => typeof v === "object" && !Array.isArray(v));
|
|
211
|
-
if (hasNestedObjects) {
|
|
212
|
-
for (const [subKey, subValue] of Object.entries(nested)) {
|
|
213
|
-
if (typeof subValue === "object" && !Array.isArray(subValue)) {
|
|
214
|
-
lines.push(`[${sectionKey}.${subKey}]`);
|
|
215
|
-
for (const [k, v] of Object.entries(subValue)) {
|
|
216
|
-
lines.push(`${k} = ${tomlValue(v)}`);
|
|
217
|
-
}
|
|
218
|
-
lines.push("");
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
lines.push(`[${sectionKey}]`);
|
|
224
|
-
for (const [k, v] of Object.entries(nested)) {
|
|
225
|
-
lines.push(`${k} = ${tomlValue(v)}`);
|
|
226
|
-
}
|
|
227
|
-
lines.push("");
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return lines.join("\n");
|
|
232
|
-
}
|
|
233
|
-
function tomlValue(value) {
|
|
234
|
-
if (typeof value === "string") {
|
|
235
|
-
return `"${value}"`;
|
|
236
|
-
}
|
|
237
|
-
if (Array.isArray(value)) {
|
|
238
|
-
return `[${value.map((v) => (typeof v === "string" ? `"${v}"` : String(v))).join(", ")}]`;
|
|
239
|
-
}
|
|
240
|
-
return String(value);
|
|
241
|
-
}
|
|
242
|
-
export function writeIdeConfig(configPath, config, format = "json") {
|
|
243
|
-
const resolved = expandPath(configPath);
|
|
244
|
-
const dir = path.dirname(resolved);
|
|
245
|
-
if (!fs.existsSync(dir)) {
|
|
246
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
247
|
-
}
|
|
248
|
-
if (format === "toml") {
|
|
249
|
-
fs.writeFileSync(resolved, stringifyToml(config));
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
fs.writeFileSync(resolved, JSON.stringify(config, null, 2) + "\n");
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
export function addRecaptToIdeConfig(ide, secretKey, useGlobal = true) {
|
|
256
|
-
const configPath = useGlobal && ide.globalPath ? ide.globalPath : ide.projectPath;
|
|
257
|
-
const resolved = expandPath(configPath);
|
|
258
|
-
const existing = readIdeConfig(configPath, ide.format);
|
|
259
|
-
const rootKey = ide.rootKey;
|
|
260
|
-
const servers = existing[rootKey] || {};
|
|
261
|
-
servers["recapt"] = getRecaptServerConfig(secretKey);
|
|
262
|
-
existing[rootKey] = servers;
|
|
263
|
-
writeIdeConfig(configPath, existing, ide.format);
|
|
264
|
-
return resolved;
|
|
265
|
-
}
|
|
266
|
-
export function removeRecaptFromIdeConfig(ide, useGlobal = true) {
|
|
267
|
-
const configPath = useGlobal && ide.globalPath ? ide.globalPath : ide.projectPath;
|
|
268
|
-
const resolved = expandPath(configPath);
|
|
269
|
-
if (!fs.existsSync(resolved)) {
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
const existing = readIdeConfig(configPath, ide.format);
|
|
273
|
-
const rootKey = ide.rootKey;
|
|
274
|
-
const servers = existing[rootKey] || {};
|
|
275
|
-
if (!("recapt" in servers)) {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
delete servers["recapt"];
|
|
279
|
-
existing[rootKey] = servers;
|
|
280
|
-
writeIdeConfig(configPath, existing, ide.format);
|
|
281
|
-
return true;
|
|
282
|
-
}
|
|
283
|
-
export function isRecaptConfigured(ide) {
|
|
284
|
-
if (ide.globalPath) {
|
|
285
|
-
const globalConfig = readIdeConfig(ide.globalPath, ide.format);
|
|
286
|
-
const servers = globalConfig[ide.rootKey] || {};
|
|
287
|
-
if ("recapt" in servers) {
|
|
288
|
-
return true;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
const projectConfig = readIdeConfig(ide.projectPath, ide.format);
|
|
292
|
-
const servers = projectConfig[ide.rootKey] || {};
|
|
293
|
-
return "recapt" in servers;
|
|
294
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive Prompts
|
|
3
|
-
*
|
|
4
|
-
* Arrow-key navigable prompts for CLI interactions using @inquirer/prompts.
|
|
5
|
-
*/
|
|
6
|
-
export declare function confirm(message: string, defaultYes?: boolean): Promise<boolean>;
|
|
7
|
-
export declare function input(message: string, defaultValue?: string): Promise<string>;
|
|
8
|
-
export declare function secret(message: string): Promise<string>;
|
|
9
|
-
export interface SelectOption<T = string> {
|
|
10
|
-
label: string;
|
|
11
|
-
value: T;
|
|
12
|
-
selected?: boolean;
|
|
13
|
-
}
|
|
14
|
-
export declare function multiSelect<T = string>(message: string, options: SelectOption<T>[]): Promise<T[]>;
|
|
15
|
-
export declare function select<T = string>(message: string, options: SelectOption<T>[]): Promise<T | null>;
|
|
16
|
-
export declare function print(message: string): void;
|
|
17
|
-
export declare function success(message: string): void;
|
|
18
|
-
export declare function error(message: string): void;
|
|
19
|
-
export declare function info(message: string): void;
|
|
20
|
-
export declare function warn(message: string): void;
|
|
21
|
-
export declare function newline(): void;
|
|
22
|
-
export declare function header(title: string): void;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive Prompts
|
|
3
|
-
*
|
|
4
|
-
* Arrow-key navigable prompts for CLI interactions using @inquirer/prompts.
|
|
5
|
-
*/
|
|
6
|
-
import { confirm as inquirerConfirm, input as inquirerInput, password as inquirerPassword, select as inquirerSelect, checkbox as inquirerCheckbox, } from "@inquirer/prompts";
|
|
7
|
-
export async function confirm(message, defaultYes = true) {
|
|
8
|
-
return inquirerConfirm({
|
|
9
|
-
message,
|
|
10
|
-
default: defaultYes,
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
export async function input(message, defaultValue) {
|
|
14
|
-
return inquirerInput({
|
|
15
|
-
message,
|
|
16
|
-
default: defaultValue,
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
export async function secret(message) {
|
|
20
|
-
const value = await inquirerPassword({
|
|
21
|
-
message,
|
|
22
|
-
mask: "*",
|
|
23
|
-
});
|
|
24
|
-
return value.trim();
|
|
25
|
-
}
|
|
26
|
-
export async function multiSelect(message, options) {
|
|
27
|
-
return inquirerCheckbox({
|
|
28
|
-
message,
|
|
29
|
-
choices: options.map((opt) => ({
|
|
30
|
-
name: opt.label,
|
|
31
|
-
value: opt.value,
|
|
32
|
-
checked: opt.selected ?? false,
|
|
33
|
-
})),
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
export async function select(message, options) {
|
|
37
|
-
if (options.length === 0) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
return inquirerSelect({
|
|
41
|
-
message,
|
|
42
|
-
choices: options.map((opt) => ({
|
|
43
|
-
name: opt.label,
|
|
44
|
-
value: opt.value,
|
|
45
|
-
})),
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
export function print(message) {
|
|
49
|
-
console.log(message);
|
|
50
|
-
}
|
|
51
|
-
export function success(message) {
|
|
52
|
-
console.log(`✓ ${message}`);
|
|
53
|
-
}
|
|
54
|
-
export function error(message) {
|
|
55
|
-
console.error(`✗ ${message}`);
|
|
56
|
-
}
|
|
57
|
-
export function info(message) {
|
|
58
|
-
console.log(`ℹ ${message}`);
|
|
59
|
-
}
|
|
60
|
-
export function warn(message) {
|
|
61
|
-
console.log(`⚠ ${message}`);
|
|
62
|
-
}
|
|
63
|
-
export function newline() {
|
|
64
|
-
console.log();
|
|
65
|
-
}
|
|
66
|
-
export function header(title) {
|
|
67
|
-
console.log();
|
|
68
|
-
console.log(title);
|
|
69
|
-
console.log("=".repeat(title.length));
|
|
70
|
-
console.log();
|
|
71
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* analyze_flow tool
|
|
3
|
-
*
|
|
4
|
-
* Analyzes user navigation flows between pages.
|
|
5
|
-
* Thin proxy to external-api /flows/analyze endpoint.
|
|
6
|
-
*/
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
import { apiPost, isApiConfigured } from "../api/client.js";
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
-
export function registerAnalyzeFlow(server) {
|
|
11
|
-
server.registerTool("analyze_flow", {
|
|
12
|
-
description: "Analyze user navigation flows between pages. Returns paths with steps, " +
|
|
13
|
-
"behavioral metrics (frustration, confusion), success rates, and bottlenecks. " +
|
|
14
|
-
"Use this to understand how users navigate between specific pages.",
|
|
15
|
-
inputSchema: z.object({
|
|
16
|
-
start_page: z
|
|
17
|
-
.string()
|
|
18
|
-
.optional()
|
|
19
|
-
.describe("Starting page path (e.g., /pricing). Partial match supported."),
|
|
20
|
-
end_page: z
|
|
21
|
-
.string()
|
|
22
|
-
.optional()
|
|
23
|
-
.describe("Ending page path (e.g., /checkout). Partial match supported."),
|
|
24
|
-
days: z
|
|
25
|
-
.number()
|
|
26
|
-
.optional()
|
|
27
|
-
.default(7)
|
|
28
|
-
.describe("Number of days to analyze (default: 7)"),
|
|
29
|
-
}),
|
|
30
|
-
}, async ({ start_page, end_page, days, }) => {
|
|
31
|
-
if (!isApiConfigured()) {
|
|
32
|
-
return {
|
|
33
|
-
content: [
|
|
34
|
-
{
|
|
35
|
-
type: "text",
|
|
36
|
-
text: JSON.stringify({ error: "API not configured" }),
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
isError: true,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
if (!start_page && !end_page) {
|
|
43
|
-
return {
|
|
44
|
-
content: [
|
|
45
|
-
{
|
|
46
|
-
type: "text",
|
|
47
|
-
text: JSON.stringify({
|
|
48
|
-
error: "At least one of start_page or end_page is required",
|
|
49
|
-
}),
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
isError: true,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
const { data, error } = await apiPost("/flows/analyze", {
|
|
56
|
-
start_page,
|
|
57
|
-
end_page,
|
|
58
|
-
days: days ?? 7,
|
|
59
|
-
});
|
|
60
|
-
if (error) {
|
|
61
|
-
return {
|
|
62
|
-
content: [{ type: "text", text: JSON.stringify({ error }) }],
|
|
63
|
-
isError: true,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
67
|
-
});
|
|
68
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* analyze_funnel tool
|
|
3
|
-
*
|
|
4
|
-
* Analyzes conversion funnels through a defined sequence of pages.
|
|
5
|
-
* Thin proxy to external-api /flows/funnel endpoint.
|
|
6
|
-
*/
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
import { apiPost, isApiConfigured } from "../api/client.js";
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
-
export function registerAnalyzeFunnel(server) {
|
|
11
|
-
server.registerTool("analyze_funnel", {
|
|
12
|
-
description: "Analyze a conversion funnel through a sequence of pages. Returns per-step metrics " +
|
|
13
|
-
"(entered, converted, dropped, dwell time, frustration, confusion) and dropoff analysis " +
|
|
14
|
-
'showing where users exit. Supports wildcards: "/checkout*" matches all checkout pages.',
|
|
15
|
-
inputSchema: z.object({
|
|
16
|
-
steps: z
|
|
17
|
-
.array(z.string())
|
|
18
|
-
.min(2)
|
|
19
|
-
.describe('Ordered page paths forming the funnel (e.g., ["/cart", "/checkout", "/payment"])'),
|
|
20
|
-
days: z
|
|
21
|
-
.number()
|
|
22
|
-
.optional()
|
|
23
|
-
.default(7)
|
|
24
|
-
.describe("Number of days to analyze (default: 7)"),
|
|
25
|
-
}),
|
|
26
|
-
}, async ({ steps, days }) => {
|
|
27
|
-
if (!isApiConfigured()) {
|
|
28
|
-
return {
|
|
29
|
-
content: [
|
|
30
|
-
{
|
|
31
|
-
type: "text",
|
|
32
|
-
text: JSON.stringify({ error: "API not configured" }),
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
isError: true,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
if (!steps || steps.length < 2) {
|
|
39
|
-
return {
|
|
40
|
-
content: [
|
|
41
|
-
{
|
|
42
|
-
type: "text",
|
|
43
|
-
text: JSON.stringify({
|
|
44
|
-
error: "At least 2 steps are required for funnel analysis",
|
|
45
|
-
}),
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
isError: true,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
const { data, error } = await apiPost("/flows/funnel", {
|
|
52
|
-
steps,
|
|
53
|
-
days: days ?? 7,
|
|
54
|
-
});
|
|
55
|
-
if (error) {
|
|
56
|
-
return {
|
|
57
|
-
content: [{ type: "text", text: JSON.stringify({ error }) }],
|
|
58
|
-
isError: true,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
62
|
-
});
|
|
63
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Call Tool — Universal tool proxy for executing any tool by name.
|
|
3
|
-
*
|
|
4
|
-
* This tool allows the agent to invoke ANY tool by name without having
|
|
5
|
-
* all tool descriptions in context. The agent discovers tools via search_tools,
|
|
6
|
-
* then calls them through this proxy.
|
|
7
|
-
*
|
|
8
|
-
* Benefits:
|
|
9
|
-
* - Minimal context: Only ~10 tools have descriptions in the prompt
|
|
10
|
-
* - All 40+ analysis tools accessible on-demand
|
|
11
|
-
* - Scales to any number of tools without context bloat
|
|
12
|
-
*/
|
|
13
|
-
export type ToolHandler = (args: Record<string, unknown>) => Promise<{
|
|
14
|
-
content: Array<{
|
|
15
|
-
type: string;
|
|
16
|
-
text: string;
|
|
17
|
-
}>;
|
|
18
|
-
isError?: boolean;
|
|
19
|
-
}>;
|
|
20
|
-
export declare function registerToolHandler(name: string, handler: ToolHandler): void;
|
|
21
|
-
export declare function getToolHandler(name: string): ToolHandler | undefined;
|
|
22
|
-
export declare function registerCallTool(server: any): void;
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Call Tool — Universal tool proxy for executing any tool by name.
|
|
3
|
-
*
|
|
4
|
-
* This tool allows the agent to invoke ANY tool by name without having
|
|
5
|
-
* all tool descriptions in context. The agent discovers tools via search_tools,
|
|
6
|
-
* then calls them through this proxy.
|
|
7
|
-
*
|
|
8
|
-
* Benefits:
|
|
9
|
-
* - Minimal context: Only ~10 tools have descriptions in the prompt
|
|
10
|
-
* - All 40+ analysis tools accessible on-demand
|
|
11
|
-
* - Scales to any number of tools without context bloat
|
|
12
|
-
*/
|
|
13
|
-
import { z } from "zod";
|
|
14
|
-
import { getToolByName } from "./searchTools.js";
|
|
15
|
-
const toolRegistry = new Map();
|
|
16
|
-
export function registerToolHandler(name, handler) {
|
|
17
|
-
toolRegistry.set(name, handler);
|
|
18
|
-
}
|
|
19
|
-
export function getToolHandler(name) {
|
|
20
|
-
return toolRegistry.get(name);
|
|
21
|
-
}
|
|
22
|
-
const callToolSchema = z.object({
|
|
23
|
-
tool_name: z
|
|
24
|
-
.string()
|
|
25
|
-
.describe("The exact name of the tool to call (e.g., 'get_page_metrics', 'analyze_flow', 'compare_cohorts')"),
|
|
26
|
-
arguments: z
|
|
27
|
-
.record(z.string(), z.unknown())
|
|
28
|
-
.describe("The arguments to pass to the tool as a JSON object. Check the tool description from search_tools for required parameters."),
|
|
29
|
-
});
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
-
export function registerCallTool(server) {
|
|
32
|
-
server.registerTool("call_tool", {
|
|
33
|
-
description: "Execute any analysis tool by name. Use search_tools first to discover available tools, " +
|
|
34
|
-
"then call them through this proxy. Pass the exact tool name and arguments as a JSON object. " +
|
|
35
|
-
"Example: call_tool({ tool_name: 'get_page_metrics', arguments: { page_path: '/checkout' } })",
|
|
36
|
-
inputSchema: callToolSchema,
|
|
37
|
-
}, async ({ tool_name, arguments: args }) => {
|
|
38
|
-
const handler = toolRegistry.get(tool_name);
|
|
39
|
-
if (!handler) {
|
|
40
|
-
const catalogEntry = getToolByName(tool_name);
|
|
41
|
-
if (catalogEntry) {
|
|
42
|
-
return {
|
|
43
|
-
content: [
|
|
44
|
-
{
|
|
45
|
-
type: "text",
|
|
46
|
-
text: JSON.stringify({
|
|
47
|
-
error: `Tool "${tool_name}" exists in catalog but is not registered. This may be a server configuration issue.`,
|
|
48
|
-
tool_info: {
|
|
49
|
-
name: catalogEntry.name,
|
|
50
|
-
description: catalogEntry.description,
|
|
51
|
-
category: catalogEntry.category,
|
|
52
|
-
},
|
|
53
|
-
}),
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
isError: true,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
content: [
|
|
61
|
-
{
|
|
62
|
-
type: "text",
|
|
63
|
-
text: JSON.stringify({
|
|
64
|
-
error: `Unknown tool: ${tool_name}`,
|
|
65
|
-
hint: "Use search_tools to discover available tools first.",
|
|
66
|
-
}),
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
isError: true,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
return await handler(args);
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
77
|
-
return {
|
|
78
|
-
content: [
|
|
79
|
-
{
|
|
80
|
-
type: "text",
|
|
81
|
-
text: JSON.stringify({
|
|
82
|
-
error: `Tool execution failed: ${message}`,
|
|
83
|
-
tool_name,
|
|
84
|
-
arguments: args,
|
|
85
|
-
}),
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
isError: true,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Catalog — Registry and discovery for MCP tools.
|
|
3
|
-
*
|
|
4
|
-
* Exports:
|
|
5
|
-
* - searchTools: Find tools by natural language query
|
|
6
|
-
* - registerSearchTools: Register the search_tools MCP tool
|
|
7
|
-
* - registerCallTool: Register the call_tool MCP tool
|
|
8
|
-
* - registerToolHandler: Register a tool handler for call_tool to invoke
|
|
9
|
-
*/
|
|
10
|
-
export { searchTools, getToolByName, getAllTools, registerSearchTools, type ToolEntry, } from "./searchTools.js";
|
|
11
|
-
export { registerCallTool, registerToolHandler, getToolHandler, type ToolHandler, } from "./callTool.js";
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Catalog — Registry and discovery for MCP tools.
|
|
3
|
-
*
|
|
4
|
-
* Exports:
|
|
5
|
-
* - searchTools: Find tools by natural language query
|
|
6
|
-
* - registerSearchTools: Register the search_tools MCP tool
|
|
7
|
-
* - registerCallTool: Register the call_tool MCP tool
|
|
8
|
-
* - registerToolHandler: Register a tool handler for call_tool to invoke
|
|
9
|
-
*/
|
|
10
|
-
export { searchTools, getToolByName, getAllTools, registerSearchTools, } from "./searchTools.js";
|
|
11
|
-
export { registerCallTool, registerToolHandler, getToolHandler, } from "./callTool.js";
|