@recapt/mcp 0.0.30 → 0.0.32
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/index.js +185 -78
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18,6 +18,9 @@ function getSecretKey() {
|
|
|
18
18
|
function getOrganizationId() {
|
|
19
19
|
return _config.organizationId || process.env.MCP_ORGANIZATION_ID;
|
|
20
20
|
}
|
|
21
|
+
function getDomainFilter() {
|
|
22
|
+
return _config.domainFilter;
|
|
23
|
+
}
|
|
21
24
|
function isApiConfigured() {
|
|
22
25
|
return !!getSecretKey();
|
|
23
26
|
}
|
|
@@ -36,6 +39,17 @@ async function request(options) {
|
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
}
|
|
42
|
+
const domainFilter = getDomainFilter();
|
|
43
|
+
const skipDomainFilter = ["/domains", "/upgrade-options", "/remediations"];
|
|
44
|
+
const shouldFilter = domainFilter?.length && !skipDomainFilter.some((p) => path.startsWith(p));
|
|
45
|
+
let requestBody = body;
|
|
46
|
+
if (shouldFilter) {
|
|
47
|
+
if (method === "GET") {
|
|
48
|
+
url.searchParams.set("domain", domainFilter.join(","));
|
|
49
|
+
} else if (requestBody) {
|
|
50
|
+
requestBody = { ...requestBody, domain: domainFilter.join(",") };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
39
53
|
const controller = new AbortController();
|
|
40
54
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
41
55
|
const headers = {
|
|
@@ -50,7 +64,7 @@ async function request(options) {
|
|
|
50
64
|
const res = await fetch(url.toString(), {
|
|
51
65
|
method,
|
|
52
66
|
headers,
|
|
53
|
-
body:
|
|
67
|
+
body: requestBody ? JSON.stringify(requestBody) : void 0,
|
|
54
68
|
signal: controller.signal
|
|
55
69
|
});
|
|
56
70
|
clearTimeout(timeout);
|
|
@@ -267,6 +281,161 @@ function registerAllToolHandlers() {
|
|
|
267
281
|
}
|
|
268
282
|
registerAllToolHandlers();
|
|
269
283
|
|
|
284
|
+
// ../../libraries/mcp-tools/dist/embedder.js
|
|
285
|
+
var embedder = null;
|
|
286
|
+
var loadingPromise = null;
|
|
287
|
+
var loadError = null;
|
|
288
|
+
async function getEmbedder() {
|
|
289
|
+
if (embedder)
|
|
290
|
+
return embedder;
|
|
291
|
+
if (loadError)
|
|
292
|
+
throw loadError;
|
|
293
|
+
if (!loadingPromise) {
|
|
294
|
+
loadingPromise = (async () => {
|
|
295
|
+
try {
|
|
296
|
+
const transformers = await import("@xenova/transformers");
|
|
297
|
+
if (transformers.env?.backends?.onnx?.wasm) {
|
|
298
|
+
transformers.env.backends.onnx.wasm.numThreads = 1;
|
|
299
|
+
}
|
|
300
|
+
const model = await transformers.pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2", { quantized: true });
|
|
301
|
+
embedder = model;
|
|
302
|
+
return model;
|
|
303
|
+
} catch (err) {
|
|
304
|
+
loadError = err instanceof Error ? err : new Error(String(err));
|
|
305
|
+
loadingPromise = null;
|
|
306
|
+
throw loadError;
|
|
307
|
+
}
|
|
308
|
+
})();
|
|
309
|
+
}
|
|
310
|
+
return loadingPromise;
|
|
311
|
+
}
|
|
312
|
+
async function embedText(text) {
|
|
313
|
+
const model = await getEmbedder();
|
|
314
|
+
const output = await model(text, { pooling: "mean", normalize: true });
|
|
315
|
+
return Array.from(output.data);
|
|
316
|
+
}
|
|
317
|
+
function cosineSimilarity(a, b) {
|
|
318
|
+
if (a.length === 0 || b.length === 0 || a.length !== b.length)
|
|
319
|
+
return 0;
|
|
320
|
+
let dot = 0;
|
|
321
|
+
for (let i = 0; i < a.length; i++) {
|
|
322
|
+
dot += a[i] * b[i];
|
|
323
|
+
}
|
|
324
|
+
return dot;
|
|
325
|
+
}
|
|
326
|
+
function preloadEmbedder() {
|
|
327
|
+
getEmbedder().catch(() => {
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ../../libraries/mcp-tools/dist/search.js
|
|
332
|
+
var _catalog = null;
|
|
333
|
+
var _catalogLoader = null;
|
|
334
|
+
function setCatalogLoader(loader) {
|
|
335
|
+
_catalogLoader = loader;
|
|
336
|
+
_catalog = null;
|
|
337
|
+
}
|
|
338
|
+
function loadCatalog() {
|
|
339
|
+
if (_catalog)
|
|
340
|
+
return _catalog;
|
|
341
|
+
if (_catalogLoader) {
|
|
342
|
+
_catalog = _catalogLoader();
|
|
343
|
+
return _catalog;
|
|
344
|
+
}
|
|
345
|
+
console.warn("[searchTools] No catalog loader set, using empty catalog");
|
|
346
|
+
_catalog = [];
|
|
347
|
+
return _catalog;
|
|
348
|
+
}
|
|
349
|
+
function searchByKeyword(query, limit) {
|
|
350
|
+
const catalog = loadCatalog();
|
|
351
|
+
const normalizedQuery = query.toLowerCase();
|
|
352
|
+
const queryWords = normalizedQuery.split(/[\s_-]+/).filter((w) => w.length >= 2);
|
|
353
|
+
const queryPhrases = [normalizedQuery];
|
|
354
|
+
const synonyms = {
|
|
355
|
+
error: ["console", "js", "javascript", "bug", "crash", "exception"],
|
|
356
|
+
page: ["pages", "route", "url", "path"],
|
|
357
|
+
user: ["users", "session", "visitor"],
|
|
358
|
+
click: ["clicks", "tap", "press", "rage"],
|
|
359
|
+
form: ["forms", "input", "field", "submit"],
|
|
360
|
+
flow: ["flows", "journey", "funnel", "navigation", "path"],
|
|
361
|
+
issue: ["issues", "problem", "bug", "friction"],
|
|
362
|
+
fix: ["fixes", "remediation", "repair", "resolve"],
|
|
363
|
+
compare: ["comparison", "diff", "versus", "cohort"],
|
|
364
|
+
health: ["score", "metrics", "ux"],
|
|
365
|
+
dead: ["unresponsive", "broken", "stuck"],
|
|
366
|
+
rage: ["angry", "frustrated", "frustration"],
|
|
367
|
+
git: ["branch", "file", "repository", "pr", "merge", "commit", "push"],
|
|
368
|
+
pr: ["merge", "request", "pull", "mr"],
|
|
369
|
+
branch: ["git", "create", "checkout"],
|
|
370
|
+
file: ["read", "write", "update", "content", "repository"],
|
|
371
|
+
repository: ["repo", "git", "github", "gitlab"],
|
|
372
|
+
status: ["state", "mark", "set", "change", "update"],
|
|
373
|
+
waiting: ["pending", "open", "pr"],
|
|
374
|
+
deployed: ["merged", "live", "production"],
|
|
375
|
+
dismissed: ["closed", "rejected", "cancelled"],
|
|
376
|
+
remediation: ["fix", "fixes", "repair", "patch", "solution"],
|
|
377
|
+
propose: ["create", "suggest", "recommend"],
|
|
378
|
+
update: ["change", "modify", "set", "mark", "edit"],
|
|
379
|
+
create: ["add", "new", "make", "propose"],
|
|
380
|
+
list: ["get", "fetch", "find", "show", "query"]
|
|
381
|
+
};
|
|
382
|
+
const expandedWords = new Set(queryWords);
|
|
383
|
+
for (const word of queryWords) {
|
|
384
|
+
if (synonyms[word]) {
|
|
385
|
+
synonyms[word].forEach((syn) => expandedWords.add(syn));
|
|
386
|
+
}
|
|
387
|
+
for (const [key, values] of Object.entries(synonyms)) {
|
|
388
|
+
if (values.includes(word)) {
|
|
389
|
+
expandedWords.add(key);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return catalog.map((tool) => {
|
|
394
|
+
const toolName = tool.name.toLowerCase().replace(/_/g, " ");
|
|
395
|
+
const toolNameParts = tool.name.toLowerCase().split("_");
|
|
396
|
+
const text = `${toolName} ${tool.description} ${tool.category}`.toLowerCase();
|
|
397
|
+
let score = 0;
|
|
398
|
+
for (const phrase of queryPhrases) {
|
|
399
|
+
if (phrase.length > 3 && text.includes(phrase))
|
|
400
|
+
score += 5;
|
|
401
|
+
}
|
|
402
|
+
for (const word of expandedWords) {
|
|
403
|
+
if (toolNameParts.includes(word))
|
|
404
|
+
score += 4;
|
|
405
|
+
if (toolName.includes(word))
|
|
406
|
+
score += 3;
|
|
407
|
+
if (tool.category.toLowerCase() === word)
|
|
408
|
+
score += 2;
|
|
409
|
+
if (text.includes(word))
|
|
410
|
+
score += 1;
|
|
411
|
+
}
|
|
412
|
+
return { tool, score };
|
|
413
|
+
}).filter((s) => s.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((s) => s.tool);
|
|
414
|
+
}
|
|
415
|
+
async function searchBySemantic(limit, queryEmbedding) {
|
|
416
|
+
const catalog = loadCatalog();
|
|
417
|
+
return catalog.filter((t) => t.embedding && t.embedding.length > 0).map((tool) => ({
|
|
418
|
+
tool,
|
|
419
|
+
score: cosineSimilarity(queryEmbedding, tool.embedding)
|
|
420
|
+
})).sort((a, b) => b.score - a.score).slice(0, limit).map((s) => s.tool);
|
|
421
|
+
}
|
|
422
|
+
async function searchTools(query, limit = 5, queryEmbedding) {
|
|
423
|
+
if (queryEmbedding && queryEmbedding.length > 0) {
|
|
424
|
+
const results = await searchBySemantic(limit, queryEmbedding);
|
|
425
|
+
if (results.length > 0)
|
|
426
|
+
return results;
|
|
427
|
+
return searchByKeyword(query, limit);
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
const embedding = await embedText(query);
|
|
431
|
+
const results = await searchBySemantic(limit, embedding);
|
|
432
|
+
if (results.length > 0)
|
|
433
|
+
return results;
|
|
434
|
+
} catch {
|
|
435
|
+
}
|
|
436
|
+
return searchByKeyword(query, limit);
|
|
437
|
+
}
|
|
438
|
+
|
|
270
439
|
// ../../node_modules/zod-to-json-schema/dist/esm/selectParser.js
|
|
271
440
|
import { ZodFirstPartyTypeKind as ZodFirstPartyTypeKind3 } from "zod/v3";
|
|
272
441
|
|
|
@@ -3586,92 +3755,30 @@ import { fileURLToPath } from "url";
|
|
|
3586
3755
|
import { dirname, join } from "path";
|
|
3587
3756
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
3588
3757
|
var __dirname2 = dirname(__filename2);
|
|
3589
|
-
var
|
|
3590
|
-
function
|
|
3591
|
-
if (
|
|
3758
|
+
var _catalog2 = null;
|
|
3759
|
+
function loadCatalog2() {
|
|
3760
|
+
if (_catalog2) return _catalog2;
|
|
3592
3761
|
try {
|
|
3593
3762
|
const catalogPath = join(__dirname2, "toolCatalog.json");
|
|
3594
3763
|
const raw = readFileSync(catalogPath, "utf-8");
|
|
3595
|
-
|
|
3596
|
-
return
|
|
3764
|
+
_catalog2 = JSON.parse(raw);
|
|
3765
|
+
return _catalog2;
|
|
3597
3766
|
} catch {
|
|
3598
3767
|
console.warn(
|
|
3599
3768
|
"[searchTools] Failed to load toolCatalog.json, using empty catalog"
|
|
3600
3769
|
);
|
|
3601
|
-
|
|
3602
|
-
return
|
|
3603
|
-
}
|
|
3604
|
-
}
|
|
3605
|
-
function cosineSimilarity(a, b) {
|
|
3606
|
-
if (a.length === 0 || b.length === 0 || a.length !== b.length) return 0;
|
|
3607
|
-
let dot = 0;
|
|
3608
|
-
for (let i = 0; i < a.length; i++) {
|
|
3609
|
-
dot += a[i] * b[i];
|
|
3770
|
+
_catalog2 = [];
|
|
3771
|
+
return _catalog2;
|
|
3610
3772
|
}
|
|
3611
|
-
return dot;
|
|
3612
3773
|
}
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
const
|
|
3617
|
-
|
|
3618
|
-
const synonyms = {
|
|
3619
|
-
error: ["console", "js", "javascript", "bug", "crash", "exception"],
|
|
3620
|
-
page: ["pages", "route", "url", "path"],
|
|
3621
|
-
user: ["users", "session", "visitor"],
|
|
3622
|
-
click: ["clicks", "tap", "press", "rage"],
|
|
3623
|
-
form: ["forms", "input", "field", "submit"],
|
|
3624
|
-
flow: ["flows", "journey", "funnel", "navigation", "path"],
|
|
3625
|
-
issue: ["issues", "problem", "bug", "friction"],
|
|
3626
|
-
fix: ["fixes", "remediation", "repair", "resolve"],
|
|
3627
|
-
compare: ["comparison", "diff", "versus", "cohort"],
|
|
3628
|
-
health: ["score", "metrics", "ux"],
|
|
3629
|
-
dead: ["unresponsive", "broken", "stuck"],
|
|
3630
|
-
rage: ["angry", "frustrated", "frustration"]
|
|
3631
|
-
};
|
|
3632
|
-
const expandedWords = new Set(queryWords);
|
|
3633
|
-
for (const word of queryWords) {
|
|
3634
|
-
if (synonyms[word]) {
|
|
3635
|
-
synonyms[word].forEach((syn) => expandedWords.add(syn));
|
|
3636
|
-
}
|
|
3637
|
-
for (const [key, values] of Object.entries(synonyms)) {
|
|
3638
|
-
if (values.includes(word)) {
|
|
3639
|
-
expandedWords.add(key);
|
|
3640
|
-
}
|
|
3641
|
-
}
|
|
3642
|
-
}
|
|
3643
|
-
return catalog.map((tool) => {
|
|
3644
|
-
const toolName = tool.name.toLowerCase().replace(/_/g, " ");
|
|
3645
|
-
const toolNameParts = tool.name.toLowerCase().split("_");
|
|
3646
|
-
const text = `${toolName} ${tool.description} ${tool.category}`.toLowerCase();
|
|
3647
|
-
let score = 0;
|
|
3648
|
-
for (const phrase of queryPhrases) {
|
|
3649
|
-
if (phrase.length > 3 && text.includes(phrase)) score += 5;
|
|
3650
|
-
}
|
|
3651
|
-
for (const word of expandedWords) {
|
|
3652
|
-
if (toolNameParts.includes(word)) score += 4;
|
|
3653
|
-
if (toolName.includes(word)) score += 3;
|
|
3654
|
-
if (tool.category.toLowerCase() === word) score += 2;
|
|
3655
|
-
if (text.includes(word)) score += 1;
|
|
3656
|
-
}
|
|
3657
|
-
return { tool, score };
|
|
3658
|
-
}).filter((s) => s.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((s) => s.tool);
|
|
3659
|
-
}
|
|
3660
|
-
async function searchBySemantic(query, limit, queryEmbedding) {
|
|
3661
|
-
const catalog = loadCatalog();
|
|
3662
|
-
return catalog.filter((t) => t.embedding && t.embedding.length > 0).map((tool) => ({
|
|
3663
|
-
tool,
|
|
3664
|
-
score: cosineSimilarity(queryEmbedding, tool.embedding)
|
|
3665
|
-
})).sort((a, b) => b.score - a.score).slice(0, limit).map((s) => s.tool);
|
|
3666
|
-
}
|
|
3667
|
-
async function searchTools2(query, limit = 5, queryEmbedding) {
|
|
3668
|
-
if (queryEmbedding && queryEmbedding.length > 0) {
|
|
3669
|
-
return searchBySemantic(query, limit, queryEmbedding);
|
|
3670
|
-
}
|
|
3671
|
-
return searchByKeyword(query, limit);
|
|
3774
|
+
setCatalogLoader(loadCatalog2);
|
|
3775
|
+
preloadEmbedder();
|
|
3776
|
+
async function searchTools2(query, limit = 5) {
|
|
3777
|
+
const results = await searchTools(query, limit);
|
|
3778
|
+
return results;
|
|
3672
3779
|
}
|
|
3673
3780
|
function getToolByName3(name) {
|
|
3674
|
-
return
|
|
3781
|
+
return loadCatalog2().find((t) => t.name === name);
|
|
3675
3782
|
}
|
|
3676
3783
|
var DEFAULT_TOOL_LIMIT = 5;
|
|
3677
3784
|
var searchToolsSchema = z39.object({
|
|
@@ -3684,7 +3791,7 @@ function registerSearchTools(server) {
|
|
|
3684
3791
|
server.registerTool(
|
|
3685
3792
|
"search_tools",
|
|
3686
3793
|
{
|
|
3687
|
-
description: "Discover analysis tools by describing what data or capability you need. You have access to 40+ specialized tools covering sessions, pages, behaviors, journeys, forms, errors, performance, cohorts, issues, and remediation.
|
|
3794
|
+
description: "Discover analysis tools by describing what data or capability you need. You have access to 40+ specialized tools covering sessions, pages, behaviors, journeys, forms, errors, performance, cohorts, issues, and remediation. Semantic search matches your intent to relevant tools. Returns tool names, descriptions, categories, and parameters. Use call_tool to execute discovered tools.",
|
|
3688
3795
|
inputSchema: searchToolsSchema
|
|
3689
3796
|
},
|
|
3690
3797
|
async ({ query, limit }) => {
|
|
@@ -3697,7 +3804,7 @@ function registerSearchTools(server) {
|
|
|
3697
3804
|
type: "text",
|
|
3698
3805
|
text: JSON.stringify({
|
|
3699
3806
|
tools: [],
|
|
3700
|
-
message: "No matching tools found. Try rephrasing your query or
|
|
3807
|
+
message: "No matching tools found. Try rephrasing your query or describing what you want to analyze."
|
|
3701
3808
|
})
|
|
3702
3809
|
}
|
|
3703
3810
|
]
|