research-powerpack-mcp 3.3.1 → 3.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/dist/clients/reddit.d.ts +4 -3
- package/dist/clients/reddit.d.ts.map +1 -1
- package/dist/clients/research.d.ts +12 -2
- package/dist/clients/research.d.ts.map +1 -1
- package/dist/clients/research.js +108 -36
- package/dist/clients/research.js.map +1 -1
- package/dist/clients/scraper.d.ts +4 -3
- package/dist/clients/scraper.d.ts.map +1 -1
- package/dist/clients/search.d.ts +3 -2
- package/dist/clients/search.d.ts.map +1 -1
- package/dist/config/index.d.ts +3 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -3
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts +40 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +300 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/types.d.ts +80 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +6 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/yaml/tools.yaml +1308 -0
- package/dist/index.js +13 -122
- package/dist/index.js.map +1 -1
- package/dist/schemas/deep-research.d.ts +0 -37
- package/dist/schemas/deep-research.d.ts.map +1 -1
- package/dist/schemas/deep-research.js +2 -1
- package/dist/schemas/deep-research.js.map +1 -1
- package/dist/schemas/scrape-links.d.ts +0 -6
- package/dist/schemas/scrape-links.d.ts.map +1 -1
- package/dist/schemas/scrape-links.js +1 -1
- package/dist/schemas/scrape-links.js.map +1 -1
- package/dist/schemas/web-search.d.ts +0 -3
- package/dist/schemas/web-search.d.ts.map +1 -1
- package/dist/schemas/web-search.js +3 -3
- package/dist/schemas/web-search.js.map +1 -1
- package/dist/services/llm-processor.d.ts +0 -10
- package/dist/services/llm-processor.d.ts.map +1 -1
- package/dist/services/llm-processor.js +2 -1
- package/dist/services/llm-processor.js.map +1 -1
- package/dist/tools/definitions.d.ts +12 -62
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +13 -121
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/reddit.d.ts +2 -1
- package/dist/tools/reddit.d.ts.map +1 -1
- package/dist/tools/reddit.js +3 -3
- package/dist/tools/reddit.js.map +1 -1
- package/dist/tools/registry.d.ts +71 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +238 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/utils.d.ts +92 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +142 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/utils/errors.d.ts +3 -51
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +10 -7
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/url-aggregator.d.ts +5 -4
- package/dist/utils/url-aggregator.d.ts.map +1 -1
- package/dist/utils/url-aggregator.js +30 -1
- package/dist/utils/url-aggregator.js.map +1 -1
- package/dist/version.d.ts +0 -10
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -10
- package/dist/version.js.map +1 -1
- package/package.json +3 -2
|
@@ -1,125 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Tool Definitions
|
|
3
|
-
*
|
|
3
|
+
* Generated from YAML configuration for consistency
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
queries: {
|
|
18
|
-
type: 'array',
|
|
19
|
-
items: { type: 'string' },
|
|
20
|
-
description: 'Distinct queries (max 10). Maximize count for multiple perspectives. eg: ["best IDE 2025", "best AI features on IDEs", "best IDE for Python", "top alternatives to vscode", "top alternatives to intitle:cursor -windsurf", "intitle:comparison of top IDEs","new IDEs like intitle:zed"]',
|
|
21
|
-
},
|
|
22
|
-
date_after: {
|
|
23
|
-
type: 'string',
|
|
24
|
-
description: 'Filter results after date (YYYY-MM-DD). Optional.',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
required: ['queries'],
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: 'get_reddit_post',
|
|
32
|
-
description: `**Fetch Reddit posts with smart comment allocation (2-50 posts supported).**
|
|
33
|
-
|
|
34
|
-
**SMART COMMENT BUDGET:** 1,000 comments distributed across all posts automatically.
|
|
35
|
-
- 2 posts: ~500 comments/post (deep dive)
|
|
36
|
-
- 10 posts: 100 comments/post
|
|
37
|
-
- 50 posts: 20 comments/post (quick scan)
|
|
38
|
-
|
|
39
|
-
**PARAMETERS:**
|
|
40
|
-
- \`urls\`: 2-50 Reddit post URLs. More posts = broader community perspective.
|
|
41
|
-
- \`fetch_comments\`: Set to false for post-only queries (faster). Default: true.
|
|
42
|
-
- \`max_comments\`: Override auto-allocation if needed.
|
|
43
|
-
|
|
44
|
-
**USE:** After search_reddit. Maximize post count for research breadth. Comment allocation is automatic and optimized.`,
|
|
45
|
-
inputSchema: {
|
|
46
|
-
type: 'object',
|
|
47
|
-
properties: {
|
|
48
|
-
urls: {
|
|
49
|
-
type: 'array',
|
|
50
|
-
items: { type: 'string' },
|
|
51
|
-
description: 'Reddit URLs (2-50). More posts = broader community perspective.',
|
|
52
|
-
},
|
|
53
|
-
fetch_comments: {
|
|
54
|
-
type: 'boolean',
|
|
55
|
-
description: 'Fetch comments? Set false for quick post overview. Default: true',
|
|
56
|
-
default: true,
|
|
57
|
-
},
|
|
58
|
-
max_comments: {
|
|
59
|
-
type: 'number',
|
|
60
|
-
description: 'Override auto-allocation. Leave empty for smart allocation.',
|
|
61
|
-
default: 100,
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
required: ['urls'],
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
// === DEEP RESEARCH TOOL ===
|
|
68
|
-
{
|
|
69
|
-
name: 'deep_research',
|
|
70
|
-
description: `**Batch deep research (2-10 questions) with dynamic token allocation.**
|
|
71
|
-
|
|
72
|
-
**TOKEN BUDGET:** 32,000 tokens distributed across all questions:
|
|
73
|
-
- 2 questions: 16,000 tokens/question (deep dive)
|
|
74
|
-
- 5 questions: 6,400 tokens/question (balanced)
|
|
75
|
-
- 10 questions: 3,200 tokens/question (rapid multi-topic)
|
|
76
|
-
|
|
77
|
-
**WHEN TO USE:**
|
|
78
|
-
- Need multi-perspective analysis on related topics
|
|
79
|
-
- Researching a domain from multiple angles
|
|
80
|
-
- Validating understanding across different aspects
|
|
81
|
-
- Comparing approaches/technologies side-by-side
|
|
82
|
-
|
|
83
|
-
**EACH QUESTION SHOULD INCLUDE:**
|
|
84
|
-
- Topic & context (what decision it informs)
|
|
85
|
-
- Your current understanding (to fill gaps)
|
|
86
|
-
- Specific sub-questions (2-5 per topic)
|
|
87
|
-
|
|
88
|
-
**USE:** Maximize question count for comprehensive coverage. All questions run in parallel. Group related questions for coherent research.`,
|
|
89
|
-
inputSchema: zodToJsonSchema(deepResearchParamsSchema, { $refStrategy: 'none' }),
|
|
90
|
-
},
|
|
91
|
-
// === SCRAPE LINKS TOOL ===
|
|
92
|
-
{
|
|
93
|
-
name: 'scrape_links',
|
|
94
|
-
description: `**Universal URL content extraction (3-50 URLs) with dynamic token allocation.**
|
|
95
|
-
|
|
96
|
-
**TOKEN ALLOCATION:** 32,000 tokens distributed across all URLs automatically.
|
|
97
|
-
- 3 URLs: ~10,666 tokens/URL (deep extraction)
|
|
98
|
-
- 10 URLs: 3,200 tokens/URL (detailed)
|
|
99
|
-
- 50 URLs: 640 tokens/URL (high-level scan)
|
|
100
|
-
|
|
101
|
-
**AUTOMATIC FALLBACK:** Basic → JavaScript → JavaScript+US geo-targeting.
|
|
102
|
-
|
|
103
|
-
**AI EXTRACTION:** Set use_llm=true with what_to_extract for intelligent filtering. Extraction is concise + comprehensive (high info density).
|
|
104
|
-
|
|
105
|
-
**BATCHING:** Max 30 concurrent requests. 50 URLs = [30] then [20] batches.
|
|
106
|
-
|
|
107
|
-
**USE:** Provide 3-50 URLs. More URLs = broader coverage, fewer tokens per URL. Choose based on research scope. Maximize URL count for comprehensive research.`,
|
|
108
|
-
inputSchema: zodToJsonSchema(scrapeLinksParamsSchema, { $refStrategy: 'none' }),
|
|
109
|
-
},
|
|
110
|
-
// === WEB SEARCH TOOL ===
|
|
111
|
-
{
|
|
112
|
-
name: 'web_search',
|
|
113
|
-
description: `**Batch web search** using Google via SERPER API. Search up to 100 keywords in parallel, get top 10 results per keyword with snippets, links, and related searches.
|
|
114
|
-
|
|
115
|
-
**FEATURES:**
|
|
116
|
-
- Supports Google search operators (site:, -exclusion, "exact phrase", filetype:)
|
|
117
|
-
- Returns clickable markdown links with snippets
|
|
118
|
-
- Provides related search suggestions
|
|
119
|
-
- Identifies frequently appearing URLs across queries
|
|
120
|
-
|
|
121
|
-
**USE:** For research tasks requiring multiple perspectives. Use distinct keywords to maximize coverage. Follow up with scrape_links to extract full content from promising URLs.`,
|
|
122
|
-
inputSchema: zodToJsonSchema(webSearchParamsSchema, { $refStrategy: 'none' }),
|
|
123
|
-
},
|
|
124
|
-
];
|
|
5
|
+
import { generateMcpTools } from '../config/loader.js';
|
|
6
|
+
/**
|
|
7
|
+
* TOOLS array is now loaded from src/config/yaml/tools.yaml
|
|
8
|
+
* This provides a single source of truth for all tool metadata
|
|
9
|
+
*
|
|
10
|
+
* Benefits:
|
|
11
|
+
* - Descriptions defined once in YAML
|
|
12
|
+
* - Easy to update without touching TypeScript
|
|
13
|
+
* - Consistent format across all tools
|
|
14
|
+
* - Validation rules co-located with descriptions
|
|
15
|
+
*/
|
|
16
|
+
export const TOOLS = generateMcpTools();
|
|
125
17
|
//# sourceMappingURL=definitions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC"}
|
package/dist/tools/reddit.d.ts
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* NEVER throws - always returns structured response for graceful degradation
|
|
4
4
|
*/
|
|
5
5
|
export declare function handleSearchReddit(queries: string[], apiKey: string, dateAfter?: string): Promise<string>;
|
|
6
|
-
|
|
6
|
+
interface GetRedditPostsOptions {
|
|
7
7
|
fetchComments?: boolean;
|
|
8
8
|
maxCommentsOverride?: number;
|
|
9
9
|
}
|
|
10
10
|
export declare function handleGetRedditPosts(urls: string[], clientId: string, clientSecret: string, maxComments?: number, options?: GetRedditPostsOptions): Promise<string>;
|
|
11
|
+
export {};
|
|
11
12
|
//# sourceMappingURL=reddit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reddit.d.ts","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiDH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAMD,
|
|
1
|
+
{"version":3,"file":"reddit.d.ts","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiDH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAMD,UAAU,qBAAqB;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,WAAW,SAAM,EACjB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAwDjB"}
|
package/dist/tools/reddit.js
CHANGED
|
@@ -44,7 +44,7 @@ function formatPost(result, fetchComments) {
|
|
|
44
44
|
// ============================================================================
|
|
45
45
|
export async function handleSearchReddit(queries, apiKey, dateAfter) {
|
|
46
46
|
try {
|
|
47
|
-
const limited = queries.slice(0,
|
|
47
|
+
const limited = queries.slice(0, 50);
|
|
48
48
|
const client = new SearchClient(apiKey);
|
|
49
49
|
const results = await client.searchRedditMultiple(limited, dateAfter);
|
|
50
50
|
// Check if any results were found
|
|
@@ -57,8 +57,8 @@ export async function handleSearchReddit(queries, apiKey, dateAfter) {
|
|
|
57
57
|
}
|
|
58
58
|
// Aggregate and rank results by CTR
|
|
59
59
|
const aggregation = aggregateAndRankReddit(results, 3);
|
|
60
|
-
// Generate enhanced output with consensus highlighting
|
|
61
|
-
return generateRedditEnhancedOutput(aggregation, limited);
|
|
60
|
+
// Generate enhanced output with consensus highlighting AND per-query raw results
|
|
61
|
+
return generateRedditEnhancedOutput(aggregation, limited, results);
|
|
62
62
|
}
|
|
63
63
|
catch (error) {
|
|
64
64
|
const structuredError = classifyError(error);
|
package/dist/tools/reddit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reddit.js","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"reddit.js","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler Registry - Central tool registration and execution
|
|
3
|
+
* Eliminates repetitive if/else routing with declarative registration
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { type Capabilities } from '../config/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* MCP-compliant tool result with index signature for SDK compatibility
|
|
9
|
+
*/
|
|
10
|
+
export interface CallToolResult {
|
|
11
|
+
content: Array<{
|
|
12
|
+
type: 'text';
|
|
13
|
+
text: string;
|
|
14
|
+
}>;
|
|
15
|
+
isError?: boolean;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Configuration for a registered tool
|
|
20
|
+
*/
|
|
21
|
+
export interface ToolRegistration {
|
|
22
|
+
name: string;
|
|
23
|
+
capability?: keyof Capabilities;
|
|
24
|
+
schema: z.ZodSchema;
|
|
25
|
+
handler: (params: unknown) => Promise<string>;
|
|
26
|
+
postValidate?: (params: unknown) => string | undefined;
|
|
27
|
+
transformResponse?: (result: string) => {
|
|
28
|
+
content: string;
|
|
29
|
+
isError?: boolean;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Registry type
|
|
34
|
+
*/
|
|
35
|
+
export type ToolRegistry = Record<string, ToolRegistration>;
|
|
36
|
+
/**
|
|
37
|
+
* Central registry of all MCP tools
|
|
38
|
+
*/
|
|
39
|
+
export declare const toolRegistry: ToolRegistry;
|
|
40
|
+
/**
|
|
41
|
+
* Execute a tool by name with full middleware chain
|
|
42
|
+
*
|
|
43
|
+
* Middleware steps:
|
|
44
|
+
* 1. Lookup tool in registry (throw McpError if not found)
|
|
45
|
+
* 2. Check capability (return error response if missing)
|
|
46
|
+
* 3. Validate params with Zod (return error response if invalid)
|
|
47
|
+
* 4. Execute handler (catch and format any errors)
|
|
48
|
+
* 5. Transform response if needed
|
|
49
|
+
*
|
|
50
|
+
* @param name - Tool name from request
|
|
51
|
+
* @param args - Raw arguments from request
|
|
52
|
+
* @param capabilities - Current capabilities from getCapabilities()
|
|
53
|
+
* @returns MCP-compliant tool result
|
|
54
|
+
*/
|
|
55
|
+
export declare function executeTool(name: string, args: unknown, capabilities: Capabilities): Promise<CallToolResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Get list of all registered tool names
|
|
58
|
+
*/
|
|
59
|
+
export declare function getRegisteredToolNames(): string[];
|
|
60
|
+
/**
|
|
61
|
+
* Check if a tool is registered
|
|
62
|
+
*/
|
|
63
|
+
export declare function isToolRegistered(name: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Get tool capabilities for logging
|
|
66
|
+
*/
|
|
67
|
+
export declare function getToolCapabilities(): {
|
|
68
|
+
enabled: string[];
|
|
69
|
+
disabled: string[];
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAY,MAAM,KAAK,CAAC;AAGlC,OAAO,EAAmD,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAkBxG;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,YAAY,CAAC;IAChC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;IACvD,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAChF;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AA4E5D;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,YA+C1B,CAAC;AAMF;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,cAAc,CAAC,CAuEzB;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAe/E"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler Registry - Central tool registration and execution
|
|
3
|
+
* Eliminates repetitive if/else routing with declarative registration
|
|
4
|
+
*/
|
|
5
|
+
import { z, ZodError } from 'zod';
|
|
6
|
+
import { McpError, ErrorCode as McpErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { parseEnv, getCapabilities, getMissingEnvMessage } from '../config/index.js';
|
|
8
|
+
import { classifyError, createToolErrorFromStructured } from '../utils/errors.js';
|
|
9
|
+
// Import schemas
|
|
10
|
+
import { deepResearchParamsSchema } from '../schemas/deep-research.js';
|
|
11
|
+
import { scrapeLinksParamsSchema } from '../schemas/scrape-links.js';
|
|
12
|
+
import { webSearchParamsSchema } from '../schemas/web-search.js';
|
|
13
|
+
// Import handlers
|
|
14
|
+
import { handleSearchReddit, handleGetRedditPosts } from './reddit.js';
|
|
15
|
+
import { handleDeepResearch } from './research.js';
|
|
16
|
+
import { handleScrapeLinks } from './scrape.js';
|
|
17
|
+
import { handleWebSearch } from './search.js';
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Schemas for Simple Tools (inline definitions)
|
|
20
|
+
// ============================================================================
|
|
21
|
+
const searchRedditParamsSchema = z.object({
|
|
22
|
+
queries: z.array(z.string()).min(10).max(50),
|
|
23
|
+
date_after: z.string().optional(),
|
|
24
|
+
});
|
|
25
|
+
const getRedditPostParamsSchema = z.object({
|
|
26
|
+
urls: z.array(z.string()).min(2).max(50),
|
|
27
|
+
fetch_comments: z.boolean().default(true),
|
|
28
|
+
max_comments: z.number().default(100),
|
|
29
|
+
});
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Handler Wrappers
|
|
32
|
+
// ============================================================================
|
|
33
|
+
const env = parseEnv();
|
|
34
|
+
/**
|
|
35
|
+
* Wrapper for search_reddit handler
|
|
36
|
+
*/
|
|
37
|
+
async function searchRedditHandler(params) {
|
|
38
|
+
const p = params;
|
|
39
|
+
return handleSearchReddit(p.queries, env.SEARCH_API_KEY, p.date_after);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Wrapper for get_reddit_post handler
|
|
43
|
+
*/
|
|
44
|
+
async function getRedditPostHandler(params) {
|
|
45
|
+
const p = params;
|
|
46
|
+
return handleGetRedditPosts(p.urls, env.REDDIT_CLIENT_ID, env.REDDIT_CLIENT_SECRET, p.max_comments, {
|
|
47
|
+
fetchComments: p.fetch_comments,
|
|
48
|
+
maxCommentsOverride: p.max_comments !== 100 ? p.max_comments : undefined,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Wrapper for deep_research handler
|
|
53
|
+
*/
|
|
54
|
+
async function deepResearchHandler(params) {
|
|
55
|
+
const { content } = await handleDeepResearch(params);
|
|
56
|
+
return content;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Wrapper for scrape_links handler
|
|
60
|
+
*/
|
|
61
|
+
async function scrapeLinksHandler(params) {
|
|
62
|
+
const { content } = await handleScrapeLinks(params);
|
|
63
|
+
return content;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Wrapper for web_search handler
|
|
67
|
+
*/
|
|
68
|
+
async function webSearchHandler(params) {
|
|
69
|
+
const { content } = await handleWebSearch(params);
|
|
70
|
+
return content;
|
|
71
|
+
}
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Tool Registry
|
|
74
|
+
// ============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Central registry of all MCP tools
|
|
77
|
+
*/
|
|
78
|
+
export const toolRegistry = {
|
|
79
|
+
search_reddit: {
|
|
80
|
+
name: 'search_reddit',
|
|
81
|
+
capability: 'search',
|
|
82
|
+
schema: searchRedditParamsSchema,
|
|
83
|
+
handler: searchRedditHandler,
|
|
84
|
+
},
|
|
85
|
+
get_reddit_post: {
|
|
86
|
+
name: 'get_reddit_post',
|
|
87
|
+
capability: 'reddit',
|
|
88
|
+
schema: getRedditPostParamsSchema,
|
|
89
|
+
handler: getRedditPostHandler,
|
|
90
|
+
},
|
|
91
|
+
deep_research: {
|
|
92
|
+
name: 'deep_research',
|
|
93
|
+
capability: 'deepResearch',
|
|
94
|
+
schema: deepResearchParamsSchema,
|
|
95
|
+
handler: deepResearchHandler,
|
|
96
|
+
transformResponse: (result) => ({
|
|
97
|
+
content: result,
|
|
98
|
+
isError: result.includes('# ❌ Error'),
|
|
99
|
+
}),
|
|
100
|
+
},
|
|
101
|
+
scrape_links: {
|
|
102
|
+
name: 'scrape_links',
|
|
103
|
+
capability: 'scraping',
|
|
104
|
+
schema: scrapeLinksParamsSchema,
|
|
105
|
+
handler: scrapeLinksHandler,
|
|
106
|
+
transformResponse: (result) => ({
|
|
107
|
+
content: result,
|
|
108
|
+
isError: result.includes('# ❌ Scraping Failed'),
|
|
109
|
+
}),
|
|
110
|
+
},
|
|
111
|
+
web_search: {
|
|
112
|
+
name: 'web_search',
|
|
113
|
+
capability: 'search',
|
|
114
|
+
schema: webSearchParamsSchema,
|
|
115
|
+
handler: webSearchHandler,
|
|
116
|
+
transformResponse: (result) => ({
|
|
117
|
+
content: result,
|
|
118
|
+
isError: result.includes('# ❌ web_search'),
|
|
119
|
+
}),
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
// ============================================================================
|
|
123
|
+
// Execute Tool (Main Entry Point)
|
|
124
|
+
// ============================================================================
|
|
125
|
+
/**
|
|
126
|
+
* Execute a tool by name with full middleware chain
|
|
127
|
+
*
|
|
128
|
+
* Middleware steps:
|
|
129
|
+
* 1. Lookup tool in registry (throw McpError if not found)
|
|
130
|
+
* 2. Check capability (return error response if missing)
|
|
131
|
+
* 3. Validate params with Zod (return error response if invalid)
|
|
132
|
+
* 4. Execute handler (catch and format any errors)
|
|
133
|
+
* 5. Transform response if needed
|
|
134
|
+
*
|
|
135
|
+
* @param name - Tool name from request
|
|
136
|
+
* @param args - Raw arguments from request
|
|
137
|
+
* @param capabilities - Current capabilities from getCapabilities()
|
|
138
|
+
* @returns MCP-compliant tool result
|
|
139
|
+
*/
|
|
140
|
+
export async function executeTool(name, args, capabilities) {
|
|
141
|
+
// Step 1: Lookup tool
|
|
142
|
+
const tool = toolRegistry[name];
|
|
143
|
+
if (!tool) {
|
|
144
|
+
throw new McpError(McpErrorCode.MethodNotFound, `Method not found: ${name}. Available tools: ${Object.keys(toolRegistry).join(', ')}`);
|
|
145
|
+
}
|
|
146
|
+
// Step 2: Check capability
|
|
147
|
+
if (tool.capability && !capabilities[tool.capability]) {
|
|
148
|
+
return {
|
|
149
|
+
content: [{ type: 'text', text: getMissingEnvMessage(tool.capability) }],
|
|
150
|
+
isError: true,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
// Step 3: Validate params with Zod
|
|
154
|
+
let validatedParams;
|
|
155
|
+
try {
|
|
156
|
+
validatedParams = tool.schema.parse(args);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
if (error instanceof ZodError) {
|
|
160
|
+
const issues = error.issues
|
|
161
|
+
.map((i) => `- **${i.path.join('.') || 'root'}**: ${i.message}`)
|
|
162
|
+
.join('\n');
|
|
163
|
+
return {
|
|
164
|
+
content: [{ type: 'text', text: `# ❌ Validation Error\n\n${issues}` }],
|
|
165
|
+
isError: true,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
// Non-Zod validation error
|
|
169
|
+
const structured = classifyError(error);
|
|
170
|
+
return createToolErrorFromStructured(structured);
|
|
171
|
+
}
|
|
172
|
+
// Step 3.5: Optional post-validation
|
|
173
|
+
if (tool.postValidate) {
|
|
174
|
+
const postError = tool.postValidate(validatedParams);
|
|
175
|
+
if (postError) {
|
|
176
|
+
return {
|
|
177
|
+
content: [{ type: 'text', text: `# ❌ Validation Error\n\n${postError}` }],
|
|
178
|
+
isError: true,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Step 4: Execute handler
|
|
183
|
+
let result;
|
|
184
|
+
try {
|
|
185
|
+
result = await tool.handler(validatedParams);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
// Handler threw (shouldn't happen if handlers follow "never throw" pattern)
|
|
189
|
+
const structured = classifyError(error);
|
|
190
|
+
return createToolErrorFromStructured(structured);
|
|
191
|
+
}
|
|
192
|
+
// Step 5: Transform response
|
|
193
|
+
if (tool.transformResponse) {
|
|
194
|
+
const transformed = tool.transformResponse(result);
|
|
195
|
+
return {
|
|
196
|
+
content: [{ type: 'text', text: transformed.content }],
|
|
197
|
+
isError: transformed.isError,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// Default: success response
|
|
201
|
+
return {
|
|
202
|
+
content: [{ type: 'text', text: result }],
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
// ============================================================================
|
|
206
|
+
// Utility Functions
|
|
207
|
+
// ============================================================================
|
|
208
|
+
/**
|
|
209
|
+
* Get list of all registered tool names
|
|
210
|
+
*/
|
|
211
|
+
export function getRegisteredToolNames() {
|
|
212
|
+
return Object.keys(toolRegistry);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Check if a tool is registered
|
|
216
|
+
*/
|
|
217
|
+
export function isToolRegistered(name) {
|
|
218
|
+
return name in toolRegistry;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get tool capabilities for logging
|
|
222
|
+
*/
|
|
223
|
+
export function getToolCapabilities() {
|
|
224
|
+
const caps = getCapabilities();
|
|
225
|
+
const enabled = [];
|
|
226
|
+
const disabled = [];
|
|
227
|
+
for (const [name, tool] of Object.entries(toolRegistry)) {
|
|
228
|
+
const capKey = tool.capability;
|
|
229
|
+
if (!capKey || caps[capKey]) {
|
|
230
|
+
enabled.push(name);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
disabled.push(name);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return { enabled, disabled };
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Tool Utilities
|
|
3
|
+
* Extracted from individual handlers to eliminate duplication
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Logger function type used by tools
|
|
7
|
+
*/
|
|
8
|
+
export type ToolLogger = (level: 'info' | 'error' | 'debug', message: string, sessionId: string) => Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Standard tool options passed to handlers
|
|
11
|
+
*/
|
|
12
|
+
export interface ToolOptions {
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
logger?: ToolLogger;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Safe logger wrapper - NEVER throws
|
|
18
|
+
* Logs to provided logger or falls back to console.error
|
|
19
|
+
*
|
|
20
|
+
* @param logger - Optional logger function
|
|
21
|
+
* @param sessionId - Session ID for logging context
|
|
22
|
+
* @param level - Log level
|
|
23
|
+
* @param message - Message to log
|
|
24
|
+
* @param toolName - Name of the tool for prefixing
|
|
25
|
+
*/
|
|
26
|
+
export declare function safeLog(logger: ToolLogger | undefined, sessionId: string | undefined, level: 'info' | 'error' | 'debug', message: string, toolName: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Calculate token allocation for batch operations
|
|
29
|
+
* Distributes a fixed budget across multiple items
|
|
30
|
+
*
|
|
31
|
+
* @param count - Number of items to distribute budget across
|
|
32
|
+
* @param budget - Total token budget
|
|
33
|
+
* @returns Tokens per item
|
|
34
|
+
*/
|
|
35
|
+
export declare function calculateTokenAllocation(count: number, budget: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Format retry hint based on error retryability
|
|
38
|
+
*
|
|
39
|
+
* @param retryable - Whether the error is retryable
|
|
40
|
+
* @returns Hint string or empty string
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatRetryHint(retryable: boolean): string;
|
|
43
|
+
/**
|
|
44
|
+
* Create a standard error markdown response
|
|
45
|
+
*
|
|
46
|
+
* @param toolName - Name of the tool that errored
|
|
47
|
+
* @param errorCode - Error code
|
|
48
|
+
* @param message - Error message
|
|
49
|
+
* @param retryable - Whether error is retryable
|
|
50
|
+
* @param tip - Optional tip for resolution
|
|
51
|
+
* @returns Formatted markdown error string
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatToolError(toolName: string, errorCode: string, message: string, retryable: boolean, tip?: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Validate that a value is a non-empty array
|
|
56
|
+
*
|
|
57
|
+
* @param value - Value to check
|
|
58
|
+
* @param fieldName - Field name for error message
|
|
59
|
+
* @returns Error message or undefined if valid
|
|
60
|
+
*/
|
|
61
|
+
export declare function validateNonEmptyArray(value: unknown, fieldName: string): string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Validate array length is within bounds
|
|
64
|
+
*
|
|
65
|
+
* @param arr - Array to check
|
|
66
|
+
* @param min - Minimum length
|
|
67
|
+
* @param max - Maximum length
|
|
68
|
+
* @param fieldName - Field name for error message
|
|
69
|
+
* @returns Error message or undefined if valid
|
|
70
|
+
*/
|
|
71
|
+
export declare function validateArrayBounds(arr: unknown[], min: number, max: number, fieldName: string): string | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Build standard header for batch operation results
|
|
74
|
+
*
|
|
75
|
+
* @param title - Title of the results section
|
|
76
|
+
* @param count - Number of items processed
|
|
77
|
+
* @param tokensPerItem - Tokens allocated per item
|
|
78
|
+
* @param totalBudget - Total token budget
|
|
79
|
+
* @returns Formatted header string
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildBatchHeader(title: string, count: number, tokensPerItem: number, totalBudget: number): string;
|
|
82
|
+
/**
|
|
83
|
+
* Build status line for batch results
|
|
84
|
+
*
|
|
85
|
+
* @param successful - Number of successful items
|
|
86
|
+
* @param failed - Number of failed items
|
|
87
|
+
* @param batches - Number of batches processed
|
|
88
|
+
* @param extras - Optional extra status items
|
|
89
|
+
* @returns Formatted status line
|
|
90
|
+
*/
|
|
91
|
+
export declare function buildStatusLine(successful: number, failed: number, batches: number, extras?: string[]): string;
|
|
92
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAQf;AAMD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAG9E;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAI1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,CAIR;AAMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAQpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EAAE,EACd,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAQpB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EAAE,GAChB,MAAM,CAMR"}
|