research-powerpack-mcp 3.3.2 → 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/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.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/web-search.js +2 -2
- package/dist/schemas/web-search.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 -159
- package/dist/tools/definitions.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/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -5,49 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
7
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, McpError
|
|
8
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import { TOOLS } from './tools/definitions.js';
|
|
10
|
-
import {
|
|
11
|
-
import { handleDeepResearch } from './tools/research.js';
|
|
12
|
-
import { handleScrapeLinks } from './tools/scrape.js';
|
|
13
|
-
import { handleWebSearch } from './tools/search.js';
|
|
14
|
-
import { deepResearchParamsSchema } from './schemas/deep-research.js';
|
|
15
|
-
import { scrapeLinksParamsSchema } from './schemas/scrape-links.js';
|
|
16
|
-
import { webSearchParamsSchema } from './schemas/web-search.js';
|
|
10
|
+
import { executeTool, getToolCapabilities } from './tools/registry.js';
|
|
17
11
|
import { classifyError, createToolErrorFromStructured } from './utils/errors.js';
|
|
18
|
-
import {
|
|
12
|
+
import { SERVER, getCapabilities } from './config/index.js';
|
|
19
13
|
// ============================================================================
|
|
20
|
-
// Capability Detection (
|
|
14
|
+
// Capability Detection (uses registry for tool capability mapping)
|
|
21
15
|
// ============================================================================
|
|
22
|
-
const env = parseEnv();
|
|
23
16
|
const capabilities = getCapabilities();
|
|
24
|
-
|
|
25
|
-
const enabledTools = [];
|
|
26
|
-
const disabledTools = [];
|
|
27
|
-
if (capabilities.search) {
|
|
28
|
-
enabledTools.push('web_search', 'search_reddit');
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
disabledTools.push('web_search', 'search_reddit');
|
|
32
|
-
}
|
|
33
|
-
if (capabilities.reddit) {
|
|
34
|
-
enabledTools.push('get_reddit_post');
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
disabledTools.push('get_reddit_post');
|
|
38
|
-
}
|
|
39
|
-
if (capabilities.scraping) {
|
|
40
|
-
enabledTools.push('scrape_links');
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
disabledTools.push('scrape_links');
|
|
44
|
-
}
|
|
45
|
-
if (capabilities.deepResearch) {
|
|
46
|
-
enabledTools.push('deep_research');
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
disabledTools.push('deep_research');
|
|
50
|
-
}
|
|
17
|
+
const { enabled: enabledTools, disabled: disabledTools } = getToolCapabilities();
|
|
51
18
|
if (enabledTools.length > 0) {
|
|
52
19
|
console.error(`✅ Enabled tools: ${enabledTools.join(', ')}`);
|
|
53
20
|
}
|
|
@@ -62,104 +29,28 @@ if (capabilities.scraping && !capabilities.llmExtraction) {
|
|
|
62
29
|
// ============================================================================
|
|
63
30
|
const server = new Server({ name: SERVER.NAME, version: SERVER.VERSION }, { capabilities: { tools: {} } });
|
|
64
31
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
32
|
+
/**
|
|
33
|
+
* Tool execution handler - uses registry pattern for clean routing
|
|
34
|
+
* All capability checks, validation, and error handling are in executeTool
|
|
35
|
+
*/
|
|
65
36
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
66
37
|
const { name, arguments: args } = request.params;
|
|
67
38
|
try {
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
// Check capability
|
|
71
|
-
if (!capabilities.search) {
|
|
72
|
-
return { content: [{ type: 'text', text: getMissingEnvMessage('search') }], isError: true };
|
|
73
|
-
}
|
|
74
|
-
const { queries, date_after } = args;
|
|
75
|
-
if (!Array.isArray(queries) || queries.length === 0) {
|
|
76
|
-
return { content: [{ type: 'text', text: 'Error: queries must be a non-empty array of strings' }], isError: true };
|
|
77
|
-
}
|
|
78
|
-
const result = await handleSearchReddit(queries, env.SEARCH_API_KEY, date_after);
|
|
79
|
-
return { content: [{ type: 'text', text: result }] };
|
|
80
|
-
}
|
|
81
|
-
// ========== GET_REDDIT_POST ==========
|
|
82
|
-
if (name === 'get_reddit_post') {
|
|
83
|
-
// Check capability
|
|
84
|
-
if (!capabilities.reddit) {
|
|
85
|
-
return { content: [{ type: 'text', text: getMissingEnvMessage('reddit') }], isError: true };
|
|
86
|
-
}
|
|
87
|
-
const { urls, max_comments = 100, fetch_comments = true } = args;
|
|
88
|
-
if (!Array.isArray(urls) || urls.length === 0) {
|
|
89
|
-
return { content: [{ type: 'text', text: 'Error: urls must be a non-empty array of Reddit post URLs' }], isError: true };
|
|
90
|
-
}
|
|
91
|
-
const result = await handleGetRedditPosts(urls, env.REDDIT_CLIENT_ID, env.REDDIT_CLIENT_SECRET, max_comments, {
|
|
92
|
-
fetchComments: fetch_comments,
|
|
93
|
-
maxCommentsOverride: max_comments !== 100 ? max_comments : undefined,
|
|
94
|
-
});
|
|
95
|
-
return { content: [{ type: 'text', text: result }] };
|
|
96
|
-
}
|
|
97
|
-
// ========== DEEP_RESEARCH ==========
|
|
98
|
-
if (name === 'deep_research') {
|
|
99
|
-
// Check capability
|
|
100
|
-
if (!capabilities.deepResearch) {
|
|
101
|
-
return { content: [{ type: 'text', text: getMissingEnvMessage('deepResearch') }], isError: true };
|
|
102
|
-
}
|
|
103
|
-
const validatedParams = deepResearchParamsSchema.parse(args);
|
|
104
|
-
const { content, structuredContent } = await handleDeepResearch(validatedParams);
|
|
105
|
-
if (structuredContent && typeof structuredContent === 'object' && 'error' in structuredContent && structuredContent.error) {
|
|
106
|
-
return { content: [{ type: 'text', text: content }], isError: true };
|
|
107
|
-
}
|
|
108
|
-
return { content: [{ type: 'text', text: content }] };
|
|
109
|
-
}
|
|
110
|
-
// ========== SCRAPE_LINKS ==========
|
|
111
|
-
if (name === 'scrape_links') {
|
|
112
|
-
// Check capability
|
|
113
|
-
if (!capabilities.scraping) {
|
|
114
|
-
return { content: [{ type: 'text', text: getMissingEnvMessage('scraping') }], isError: true };
|
|
115
|
-
}
|
|
116
|
-
const validatedParams = scrapeLinksParamsSchema.parse(args);
|
|
117
|
-
// Warn if use_llm requested but LLM not available
|
|
118
|
-
if (validatedParams.use_llm && !capabilities.llmExtraction) {
|
|
119
|
-
console.error('[scrape_links] use_llm requested but OPENROUTER_API_KEY not set - proceeding without AI extraction');
|
|
120
|
-
validatedParams.use_llm = false;
|
|
121
|
-
}
|
|
122
|
-
const { content, structuredContent } = await handleScrapeLinks(validatedParams);
|
|
123
|
-
if (structuredContent.metadata.failed === structuredContent.metadata.total_urls) {
|
|
124
|
-
return { content: [{ type: 'text', text: content }], isError: true };
|
|
125
|
-
}
|
|
126
|
-
return { content: [{ type: 'text', text: content }] };
|
|
127
|
-
}
|
|
128
|
-
// ========== WEB_SEARCH ==========
|
|
129
|
-
if (name === 'web_search') {
|
|
130
|
-
// Check capability
|
|
131
|
-
if (!capabilities.search) {
|
|
132
|
-
return { content: [{ type: 'text', text: getMissingEnvMessage('search') }], isError: true };
|
|
133
|
-
}
|
|
134
|
-
const validatedParams = webSearchParamsSchema.parse(args);
|
|
135
|
-
const { content, structuredContent } = await handleWebSearch(validatedParams);
|
|
136
|
-
if (structuredContent.metadata.total_results === 0) {
|
|
137
|
-
return { content: [{ type: 'text', text: content }], isError: true };
|
|
138
|
-
}
|
|
139
|
-
return { content: [{ type: 'text', text: content }] };
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Protocol Error: Unknown tool requested
|
|
143
|
-
* Per MCP spec, use McpError for protocol-level errors (tool not found, invalid params)
|
|
144
|
-
* vs isError:true for tool execution failures (network, API, timeout)
|
|
145
|
-
*/
|
|
146
|
-
throw new McpError(McpErrorCode.MethodNotFound, `Method not found: ${name}. Available tools: search_reddit, get_reddit_post, deep_research, scrape_links, web_search`);
|
|
39
|
+
// All routing handled by registry - no more if/else blocks!
|
|
40
|
+
return await executeTool(name, args, capabilities);
|
|
147
41
|
}
|
|
148
42
|
catch (error) {
|
|
149
|
-
// McpError
|
|
43
|
+
// McpError propagates to client as protocol error
|
|
150
44
|
if (error instanceof McpError) {
|
|
151
45
|
throw error;
|
|
152
46
|
}
|
|
153
|
-
//
|
|
47
|
+
// Unexpected error - format as tool error
|
|
154
48
|
const structuredError = classifyError(error);
|
|
155
|
-
// Log for debugging
|
|
156
49
|
console.error(`[MCP Server] Tool "${name}" error:`, {
|
|
157
50
|
code: structuredError.code,
|
|
158
51
|
message: structuredError.message,
|
|
159
52
|
retryable: structuredError.retryable,
|
|
160
53
|
});
|
|
161
|
-
// Create standardized error response with errorCode for client programmatic handling
|
|
162
|
-
// This response includes: content (markdown), isError: true, errorCode, and retryAfter (for rate limits)
|
|
163
54
|
return createToolErrorFromStructured(structuredError);
|
|
164
55
|
}
|
|
165
56
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,9 +11,9 @@ const keywordsSchema = z
|
|
|
11
11
|
required_error: 'web_search: Keywords array is required',
|
|
12
12
|
invalid_type_error: 'web_search: Keywords must be an array'
|
|
13
13
|
})
|
|
14
|
-
.min(
|
|
14
|
+
.min(3, { message: 'web_search: MINIMUM 3 keywords required. You provided {#}. Add {#} more diverse keywords covering different perspectives.' })
|
|
15
15
|
.max(100, { message: 'web_search: Maximum 100 keywords allowed per request' })
|
|
16
|
-
.describe('Array of search keywords (
|
|
16
|
+
.describe('Array of search keywords (MINIMUM 3, RECOMMENDED 5-7, MAX 100). Each keyword runs as a separate Google search in parallel. Use diverse keywords covering different angles for comprehensive results.');
|
|
17
17
|
const webSearchParamsShape = {
|
|
18
18
|
keywords: keywordsSchema,
|
|
19
19
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/schemas/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iCAAiC;AACjC,MAAM,aAAa,GAAG,CAAC;KACpB,MAAM,CAAC,EAAE,cAAc,EAAE,iCAAiC,EAAE,CAAC;KAC7D,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,qCAAqC,EAAE,CAAC;KAC1D,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC;KAC1E,MAAM,CACL,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EACxB,EAAE,OAAO,EAAE,+CAA+C,EAAE,CAC7D,CAAC;AAEJ,mCAAmC;AACnC,MAAM,cAAc,GAAG,CAAC;KACrB,KAAK,CAAC,aAAa,EAAE;IACpB,cAAc,EAAE,wCAAwC;IACxD,kBAAkB,EAAE,uCAAuC;CAC5D,CAAC;KACD,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/schemas/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iCAAiC;AACjC,MAAM,aAAa,GAAG,CAAC;KACpB,MAAM,CAAC,EAAE,cAAc,EAAE,iCAAiC,EAAE,CAAC;KAC7D,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,qCAAqC,EAAE,CAAC;KAC1D,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC;KAC1E,MAAM,CACL,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EACxB,EAAE,OAAO,EAAE,+CAA+C,EAAE,CAC7D,CAAC;AAEJ,mCAAmC;AACnC,MAAM,cAAc,GAAG,CAAC;KACrB,KAAK,CAAC,aAAa,EAAE;IACpB,cAAc,EAAE,wCAAwC;IACxD,kBAAkB,EAAE,uCAAuC;CAC5D,CAAC;KACD,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,2HAA2H,EAAE,CAAC;KAChJ,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,sDAAsD,EAAE,CAAC;KAC7E,QAAQ,CAAC,sMAAsM,CAAC,CAAC;AAEpN,MAAM,oBAAoB,GAAG;IAC3B,QAAQ,EAAE,cAAc;CACzB,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC"}
|
|
@@ -1,66 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Tool Definitions
|
|
3
|
-
*
|
|
3
|
+
* Generated from YAML configuration for consistency
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
description: string;
|
|
17
|
-
};
|
|
18
|
-
date_after: {
|
|
19
|
-
type: string;
|
|
20
|
-
description: string;
|
|
21
|
-
};
|
|
22
|
-
urls?: undefined;
|
|
23
|
-
fetch_comments?: undefined;
|
|
24
|
-
max_comments?: undefined;
|
|
25
|
-
};
|
|
26
|
-
required: string[];
|
|
27
|
-
};
|
|
28
|
-
} | {
|
|
29
|
-
name: string;
|
|
30
|
-
description: string;
|
|
31
|
-
inputSchema: {
|
|
32
|
-
type: "object";
|
|
33
|
-
properties: {
|
|
34
|
-
urls: {
|
|
35
|
-
type: string;
|
|
36
|
-
items: {
|
|
37
|
-
type: string;
|
|
38
|
-
};
|
|
39
|
-
description: string;
|
|
40
|
-
};
|
|
41
|
-
fetch_comments: {
|
|
42
|
-
type: string;
|
|
43
|
-
description: string;
|
|
44
|
-
default: boolean;
|
|
45
|
-
};
|
|
46
|
-
max_comments: {
|
|
47
|
-
type: string;
|
|
48
|
-
description: string;
|
|
49
|
-
default: number;
|
|
50
|
-
};
|
|
51
|
-
queries?: undefined;
|
|
52
|
-
date_after?: undefined;
|
|
53
|
-
};
|
|
54
|
-
required: string[];
|
|
55
|
-
};
|
|
56
|
-
} | {
|
|
57
|
-
name: string;
|
|
58
|
-
description: string;
|
|
59
|
-
inputSchema: import("zod-to-json-schema").JsonSchema7Type & {
|
|
60
|
-
$schema?: string | undefined;
|
|
61
|
-
definitions?: {
|
|
62
|
-
[key: string]: import("zod-to-json-schema").JsonSchema7Type;
|
|
63
|
-
} | undefined;
|
|
64
|
-
};
|
|
65
|
-
})[];
|
|
5
|
+
/**
|
|
6
|
+
* TOOLS array is now loaded from src/config/yaml/tools.yaml
|
|
7
|
+
* This provides a single source of truth for all tool metadata
|
|
8
|
+
*
|
|
9
|
+
* Benefits:
|
|
10
|
+
* - Descriptions defined once in YAML
|
|
11
|
+
* - Easy to update without touching TypeScript
|
|
12
|
+
* - Consistent format across all tools
|
|
13
|
+
* - Validation rules co-located with descriptions
|
|
14
|
+
*/
|
|
15
|
+
export declare const TOOLS: import("../config/types.js").McpTool[];
|
|
66
16
|
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;GASG;AACH,eAAO,MAAM,KAAK,wCAAqB,CAAC"}
|
|
@@ -1,163 +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
|
-
**QUERY REQUIREMENTS:**
|
|
18
|
-
- **Minimum:** 3 queries (hard limit)
|
|
19
|
-
- **Recommended:** 10+ queries (for meaningful consensus analysis)
|
|
20
|
-
- **Optimal:** 20-30 queries covering all angles of the topic
|
|
21
|
-
- **Maximum:** 50 queries (for comprehensive deep research)
|
|
22
|
-
|
|
23
|
-
**OUTPUT FORMAT:**
|
|
24
|
-
1. **High-Consensus Posts** - Posts appearing in multiple queries (ranked by CTR score)
|
|
25
|
-
2. **All Results (CTR-Ranked)** - Aggregated unique posts sorted by weighted score
|
|
26
|
-
3. **Per-Query Raw Results** - Complete results for each individual query before aggregation
|
|
27
|
-
|
|
28
|
-
**QUERY CRAFTING STRATEGY (aim for 10-50 distinct queries):**
|
|
29
|
-
- Direct topic variations (3-5 queries)
|
|
30
|
-
- Recommendation/best-of queries (3-5 queries)
|
|
31
|
-
- Specific tool/project names (5-10 queries)
|
|
32
|
-
- Comparison queries (3-5 queries)
|
|
33
|
-
- Alternative/replacement queries (3-5 queries)
|
|
34
|
-
- Subreddit-specific queries (5-10 queries)
|
|
35
|
-
- Problem/issue queries (3-5 queries)
|
|
36
|
-
- Year-specific queries for recency (2-3 queries)
|
|
37
|
-
|
|
38
|
-
**OPERATORS:** intitle:, "exact phrase", OR, -exclude. Auto-adds site:reddit.com.`,
|
|
39
|
-
inputSchema: {
|
|
40
|
-
type: 'object',
|
|
41
|
-
properties: {
|
|
42
|
-
queries: {
|
|
43
|
-
type: 'array',
|
|
44
|
-
items: { type: 'string' },
|
|
45
|
-
description: `**3-50 queries for Reddit research.** Minimum 3 required, but generate at least 10 for meaningful consensus. More queries = better consensus detection.
|
|
46
|
-
|
|
47
|
-
**QUERY CATEGORIES (aim for coverage across all):**
|
|
48
|
-
|
|
49
|
-
1. **Direct Topic (3-5):** "YouTube Music Mac app", "YTM desktop application"
|
|
50
|
-
2. **Recommendations (3-5):** "best YouTube Music client Mac", "recommended YTM app"
|
|
51
|
-
3. **Specific Tools (5-10):** "YTMDesktop Mac", "th-ch youtube-music", "steve228uk YT Music"
|
|
52
|
-
4. **Comparisons (3-5):** "YouTube Music vs Spotify Mac", "YTM vs Apple Music desktop"
|
|
53
|
-
5. **Alternatives (3-5):** "YouTube Music Mac alternative", "YTM replacement app"
|
|
54
|
-
6. **Subreddits (5-10):** "r/YoutubeMusic desktop", "r/macapps YouTube Music", "r/opensource YTM"
|
|
55
|
-
7. **Problems/Issues (3-5):** "YouTube Music desktop performance", "YTM app crashes Mac"
|
|
56
|
-
8. **Year-Specific (2-3):** "best YouTube Music app 2024", "YTM desktop 2025"
|
|
57
|
-
9. **Features (3-5):** "YouTube Music offline Mac", "YTM lyrics desktop"
|
|
58
|
-
10. **Developer/GitHub (3-5):** "youtube-music electron app", "YTM github project"`,
|
|
59
|
-
},
|
|
60
|
-
date_after: {
|
|
61
|
-
type: 'string',
|
|
62
|
-
description: 'Filter results after date (YYYY-MM-DD). Optional.',
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
required: ['queries'],
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: 'get_reddit_post',
|
|
70
|
-
description: `**Fetch Reddit posts with smart comment allocation (2-50 posts supported).**
|
|
71
|
-
|
|
72
|
-
**SMART COMMENT BUDGET:** 1,000 comments distributed across all posts automatically.
|
|
73
|
-
- 2 posts: ~500 comments/post (deep dive)
|
|
74
|
-
- 10 posts: 100 comments/post
|
|
75
|
-
- 50 posts: 20 comments/post (quick scan)
|
|
76
|
-
|
|
77
|
-
**PARAMETERS:**
|
|
78
|
-
- \`urls\`: 2-50 Reddit post URLs. More posts = broader community perspective.
|
|
79
|
-
- \`fetch_comments\`: Set to false for post-only queries (faster). Default: true.
|
|
80
|
-
- \`max_comments\`: Override auto-allocation if needed.
|
|
81
|
-
|
|
82
|
-
**USE:** After search_reddit. Maximize post count for research breadth. Comment allocation is automatic and optimized.`,
|
|
83
|
-
inputSchema: {
|
|
84
|
-
type: 'object',
|
|
85
|
-
properties: {
|
|
86
|
-
urls: {
|
|
87
|
-
type: 'array',
|
|
88
|
-
items: { type: 'string' },
|
|
89
|
-
description: 'Reddit URLs (2-50). More posts = broader community perspective.',
|
|
90
|
-
},
|
|
91
|
-
fetch_comments: {
|
|
92
|
-
type: 'boolean',
|
|
93
|
-
description: 'Fetch comments? Set false for quick post overview. Default: true',
|
|
94
|
-
default: true,
|
|
95
|
-
},
|
|
96
|
-
max_comments: {
|
|
97
|
-
type: 'number',
|
|
98
|
-
description: 'Override auto-allocation. Leave empty for smart allocation.',
|
|
99
|
-
default: 100,
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
required: ['urls'],
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
// === DEEP RESEARCH TOOL ===
|
|
106
|
-
{
|
|
107
|
-
name: 'deep_research',
|
|
108
|
-
description: `**Batch deep research (2-10 questions) with dynamic token allocation.**
|
|
109
|
-
|
|
110
|
-
**TOKEN BUDGET:** 32,000 tokens distributed across all questions:
|
|
111
|
-
- 2 questions: 16,000 tokens/question (deep dive)
|
|
112
|
-
- 5 questions: 6,400 tokens/question (balanced)
|
|
113
|
-
- 10 questions: 3,200 tokens/question (rapid multi-topic)
|
|
114
|
-
|
|
115
|
-
**WHEN TO USE:**
|
|
116
|
-
- Need multi-perspective analysis on related topics
|
|
117
|
-
- Researching a domain from multiple angles
|
|
118
|
-
- Validating understanding across different aspects
|
|
119
|
-
- Comparing approaches/technologies side-by-side
|
|
120
|
-
|
|
121
|
-
**EACH QUESTION SHOULD INCLUDE:**
|
|
122
|
-
- Topic & context (what decision it informs)
|
|
123
|
-
- Your current understanding (to fill gaps)
|
|
124
|
-
- Specific sub-questions (2-5 per topic)
|
|
125
|
-
|
|
126
|
-
**USE:** Maximize question count for comprehensive coverage. All questions run in parallel. Group related questions for coherent research.`,
|
|
127
|
-
inputSchema: zodToJsonSchema(deepResearchParamsSchema, { $refStrategy: 'none' }),
|
|
128
|
-
},
|
|
129
|
-
// === SCRAPE LINKS TOOL ===
|
|
130
|
-
{
|
|
131
|
-
name: 'scrape_links',
|
|
132
|
-
description: `**Universal URL content extraction (3-50 URLs) with dynamic token allocation.**
|
|
133
|
-
|
|
134
|
-
**TOKEN ALLOCATION:** 32,000 tokens distributed across all URLs automatically.
|
|
135
|
-
- 3 URLs: ~10,666 tokens/URL (deep extraction)
|
|
136
|
-
- 10 URLs: 3,200 tokens/URL (detailed)
|
|
137
|
-
- 50 URLs: 640 tokens/URL (high-level scan)
|
|
138
|
-
|
|
139
|
-
**AUTOMATIC FALLBACK:** Basic → JavaScript → JavaScript+US geo-targeting.
|
|
140
|
-
|
|
141
|
-
**AI EXTRACTION:** Set use_llm=true with what_to_extract for intelligent filtering. Extraction is concise + comprehensive (high info density).
|
|
142
|
-
|
|
143
|
-
**BATCHING:** Max 30 concurrent requests. 50 URLs = [30] then [20] batches.
|
|
144
|
-
|
|
145
|
-
**USE:** Provide 3-50 URLs. More URLs = broader coverage, fewer tokens per URL. Choose based on research scope. Maximize URL count for comprehensive research.`,
|
|
146
|
-
inputSchema: zodToJsonSchema(scrapeLinksParamsSchema, { $refStrategy: 'none' }),
|
|
147
|
-
},
|
|
148
|
-
// === WEB SEARCH TOOL ===
|
|
149
|
-
{
|
|
150
|
-
name: 'web_search',
|
|
151
|
-
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.
|
|
152
|
-
|
|
153
|
-
**FEATURES:**
|
|
154
|
-
- Supports Google search operators (site:, -exclusion, "exact phrase", filetype:)
|
|
155
|
-
- Returns clickable markdown links with snippets
|
|
156
|
-
- Provides related search suggestions
|
|
157
|
-
- Identifies frequently appearing URLs across queries
|
|
158
|
-
|
|
159
|
-
**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.`,
|
|
160
|
-
inputSchema: zodToJsonSchema(webSearchParamsSchema, { $refStrategy: 'none' }),
|
|
161
|
-
},
|
|
162
|
-
];
|
|
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();
|
|
163
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"}
|
|
@@ -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"}
|