mcp-researchpowerpack 3.9.4 → 4.3.0
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 +116 -208
- package/dist/index.js +280 -337
- package/dist/index.js.map +7 -1
- package/dist/mcp-use.json +7 -0
- package/dist/src/clients/reddit.js +278 -0
- package/dist/src/clients/reddit.js.map +7 -0
- package/dist/src/clients/scraper.js +326 -0
- package/dist/src/clients/scraper.js.map +7 -0
- package/dist/src/clients/search.js +217 -0
- package/dist/src/clients/search.js.map +7 -0
- package/dist/src/config/index.js +138 -0
- package/dist/src/config/index.js.map +7 -0
- package/dist/src/prompts/deep-research.js +41 -0
- package/dist/src/prompts/deep-research.js.map +7 -0
- package/dist/src/prompts/reddit-sentiment.js +47 -0
- package/dist/src/prompts/reddit-sentiment.js.map +7 -0
- package/dist/src/schemas/reddit.js +21 -0
- package/dist/src/schemas/reddit.js.map +7 -0
- package/dist/src/schemas/scrape-links.js +26 -0
- package/dist/src/schemas/scrape-links.js.map +7 -0
- package/dist/src/schemas/start-research.js +17 -0
- package/dist/src/schemas/start-research.js.map +7 -0
- package/dist/src/schemas/web-search.js +53 -0
- package/dist/src/schemas/web-search.js.map +7 -0
- package/dist/src/services/llm-processor.js +675 -0
- package/dist/src/services/llm-processor.js.map +7 -0
- package/dist/src/services/markdown-cleaner.js +62 -0
- package/dist/src/services/markdown-cleaner.js.map +7 -0
- package/dist/src/services/workflow-state.js +116 -0
- package/dist/src/services/workflow-state.js.map +7 -0
- package/dist/src/tools/mcp-helpers.js +50 -0
- package/dist/src/tools/mcp-helpers.js.map +7 -0
- package/dist/src/tools/reddit.js +277 -0
- package/dist/src/tools/reddit.js.map +7 -0
- package/dist/src/tools/registry.js +18 -0
- package/dist/src/tools/registry.js.map +7 -0
- package/dist/src/tools/scrape.js +334 -0
- package/dist/src/tools/scrape.js.map +7 -0
- package/dist/src/tools/search.js +423 -0
- package/dist/src/tools/search.js.map +7 -0
- package/dist/src/tools/start-research.js +199 -0
- package/dist/src/tools/start-research.js.map +7 -0
- package/dist/src/tools/utils.js +29 -0
- package/dist/src/tools/utils.js.map +7 -0
- package/dist/src/utils/bootstrap-guard.js +27 -0
- package/dist/src/utils/bootstrap-guard.js.map +7 -0
- package/dist/src/utils/concurrency.js +62 -0
- package/dist/src/utils/concurrency.js.map +7 -0
- package/dist/src/utils/content-extractor.js +61 -0
- package/dist/src/utils/content-extractor.js.map +7 -0
- package/dist/src/utils/errors.js +211 -0
- package/dist/src/utils/errors.js.map +7 -0
- package/dist/src/utils/logger.js +25 -0
- package/dist/src/utils/logger.js.map +7 -0
- package/dist/src/utils/markdown-formatter.js +15 -0
- package/dist/src/utils/markdown-formatter.js.map +7 -0
- package/dist/src/utils/reddit-keyword-guard.js +29 -0
- package/dist/src/utils/reddit-keyword-guard.js.map +7 -0
- package/dist/src/utils/response.js +81 -0
- package/dist/src/utils/response.js.map +7 -0
- package/dist/src/utils/retry.js +13 -0
- package/dist/src/utils/retry.js.map +7 -0
- package/dist/src/utils/sanitize.js +10 -0
- package/dist/src/utils/sanitize.js.map +7 -0
- package/dist/src/utils/source-type.js +41 -0
- package/dist/src/utils/source-type.js.map +7 -0
- package/dist/src/utils/url-aggregator.js +227 -0
- package/dist/src/utils/url-aggregator.js.map +7 -0
- package/dist/src/utils/workflow-key.js +14 -0
- package/dist/src/utils/workflow-key.js.map +7 -0
- package/dist/src/version.js +32 -0
- package/dist/src/version.js.map +7 -0
- package/package.json +33 -28
- package/dist/clients/reddit.d.ts +0 -69
- package/dist/clients/reddit.d.ts.map +0 -1
- package/dist/clients/reddit.js +0 -369
- package/dist/clients/reddit.js.map +0 -1
- package/dist/clients/research.d.ts +0 -67
- package/dist/clients/research.d.ts.map +0 -1
- package/dist/clients/research.js +0 -290
- package/dist/clients/research.js.map +0 -1
- package/dist/clients/scraper.d.ts +0 -72
- package/dist/clients/scraper.d.ts.map +0 -1
- package/dist/clients/scraper.js +0 -338
- package/dist/clients/scraper.js.map +0 -1
- package/dist/clients/search.d.ts +0 -57
- package/dist/clients/search.d.ts.map +0 -1
- package/dist/clients/search.js +0 -223
- package/dist/clients/search.js.map +0 -1
- package/dist/config/index.d.ts +0 -78
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js +0 -201
- package/dist/config/index.js.map +0 -1
- package/dist/config/loader.d.ts +0 -40
- package/dist/config/loader.d.ts.map +0 -1
- package/dist/config/loader.js +0 -322
- package/dist/config/loader.js.map +0 -1
- package/dist/config/types.d.ts +0 -81
- package/dist/config/types.d.ts.map +0 -1
- package/dist/config/types.js +0 -6
- package/dist/config/types.js.map +0 -1
- package/dist/config/yaml/tools.yaml +0 -146
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/schemas/deep-research.d.ts +0 -64
- package/dist/schemas/deep-research.d.ts.map +0 -1
- package/dist/schemas/deep-research.js +0 -224
- package/dist/schemas/deep-research.js.map +0 -1
- package/dist/schemas/scrape-links.d.ts +0 -32
- package/dist/schemas/scrape-links.d.ts.map +0 -1
- package/dist/schemas/scrape-links.js +0 -34
- package/dist/schemas/scrape-links.js.map +0 -1
- package/dist/schemas/web-search.d.ts +0 -22
- package/dist/schemas/web-search.d.ts.map +0 -1
- package/dist/schemas/web-search.js +0 -21
- package/dist/schemas/web-search.js.map +0 -1
- package/dist/services/file-attachment.d.ts +0 -30
- package/dist/services/file-attachment.d.ts.map +0 -1
- package/dist/services/file-attachment.js +0 -207
- package/dist/services/file-attachment.js.map +0 -1
- package/dist/services/llm-processor.d.ts +0 -29
- package/dist/services/llm-processor.d.ts.map +0 -1
- package/dist/services/llm-processor.js +0 -244
- package/dist/services/llm-processor.js.map +0 -1
- package/dist/services/markdown-cleaner.d.ts +0 -8
- package/dist/services/markdown-cleaner.d.ts.map +0 -1
- package/dist/services/markdown-cleaner.js +0 -74
- package/dist/services/markdown-cleaner.js.map +0 -1
- package/dist/tools/definitions.d.ts +0 -16
- package/dist/tools/definitions.d.ts.map +0 -1
- package/dist/tools/definitions.js +0 -17
- package/dist/tools/definitions.js.map +0 -1
- package/dist/tools/reddit.d.ts +0 -14
- package/dist/tools/reddit.d.ts.map +0 -1
- package/dist/tools/reddit.js +0 -265
- package/dist/tools/reddit.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -71
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -252
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/research.d.ts +0 -14
- package/dist/tools/research.d.ts.map +0 -1
- package/dist/tools/research.js +0 -196
- package/dist/tools/research.js.map +0 -1
- package/dist/tools/scrape.d.ts +0 -14
- package/dist/tools/scrape.d.ts.map +0 -1
- package/dist/tools/scrape.js +0 -234
- package/dist/tools/scrape.js.map +0 -1
- package/dist/tools/search.d.ts +0 -10
- package/dist/tools/search.d.ts.map +0 -1
- package/dist/tools/search.js +0 -158
- package/dist/tools/search.js.map +0 -1
- package/dist/tools/utils.d.ts +0 -105
- package/dist/tools/utils.d.ts.map +0 -1
- package/dist/tools/utils.js +0 -159
- package/dist/tools/utils.js.map +0 -1
- package/dist/utils/concurrency.d.ts +0 -28
- package/dist/utils/concurrency.d.ts.map +0 -1
- package/dist/utils/concurrency.js +0 -92
- package/dist/utils/concurrency.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -95
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -390
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -39
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -57
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/markdown-formatter.d.ts +0 -5
- package/dist/utils/markdown-formatter.d.ts.map +0 -1
- package/dist/utils/markdown-formatter.js +0 -15
- package/dist/utils/markdown-formatter.js.map +0 -1
- package/dist/utils/response.d.ts +0 -93
- package/dist/utils/response.d.ts.map +0 -1
- package/dist/utils/response.js +0 -170
- package/dist/utils/response.js.map +0 -1
- package/dist/utils/retry.d.ts +0 -43
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/retry.js +0 -57
- package/dist/utils/retry.js.map +0 -1
- package/dist/utils/url-aggregator.d.ts +0 -90
- package/dist/utils/url-aggregator.d.ts.map +0 -1
- package/dist/utils/url-aggregator.js +0 -538
- package/dist/utils/url-aggregator.js.map +0 -1
- package/dist/version.d.ts +0 -29
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -55
- package/dist/version.js.map +0 -1
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Markdown cleaner service using Turndown for HTML to Markdown conversion
|
|
3
|
-
*/
|
|
4
|
-
import TurndownService from 'turndown';
|
|
5
|
-
const turndown = new TurndownService({
|
|
6
|
-
headingStyle: 'atx',
|
|
7
|
-
codeBlockStyle: 'fenced',
|
|
8
|
-
bulletListMarker: '-',
|
|
9
|
-
});
|
|
10
|
-
// Remove script, style, nav, footer, aside elements
|
|
11
|
-
turndown.remove(['script', 'style', 'nav', 'footer', 'aside', 'noscript']);
|
|
12
|
-
/** Maximum HTML content length in characters — prevents event loop blocking on huge pages */
|
|
13
|
-
const MAX_CONTENT_LENGTH = 524_288; // 512 * 1024
|
|
14
|
-
/**
|
|
15
|
-
* Remove HTML comments using linear-time indexOf loop.
|
|
16
|
-
* Avoids catastrophic backtracking from /<!--[\s\S]*?-->/g on malformed HTML.
|
|
17
|
-
*/
|
|
18
|
-
function removeHtmlComments(html) {
|
|
19
|
-
const parts = [];
|
|
20
|
-
let pos = 0;
|
|
21
|
-
while (pos < html.length) {
|
|
22
|
-
const start = html.indexOf('<!--', pos);
|
|
23
|
-
if (start === -1) {
|
|
24
|
-
parts.push(html.substring(pos));
|
|
25
|
-
break;
|
|
26
|
-
}
|
|
27
|
-
if (start > pos)
|
|
28
|
-
parts.push(html.substring(pos, start));
|
|
29
|
-
const end = html.indexOf('-->', start + 4);
|
|
30
|
-
if (end === -1) {
|
|
31
|
-
parts.push(html.substring(start)); // preserve unclosed comment + rest
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
pos = end + 3;
|
|
35
|
-
}
|
|
36
|
-
return parts.join('');
|
|
37
|
-
}
|
|
38
|
-
export class MarkdownCleaner {
|
|
39
|
-
/**
|
|
40
|
-
* Process HTML content and convert to clean Markdown
|
|
41
|
-
* NEVER throws - returns original content on any error for graceful degradation
|
|
42
|
-
*/
|
|
43
|
-
processContent(htmlContent) {
|
|
44
|
-
try {
|
|
45
|
-
// Handle null/undefined/non-string inputs gracefully
|
|
46
|
-
if (!htmlContent || typeof htmlContent !== 'string') {
|
|
47
|
-
return htmlContent || '';
|
|
48
|
-
}
|
|
49
|
-
// If already markdown (no HTML tags), return as-is
|
|
50
|
-
if (!htmlContent.includes('<')) {
|
|
51
|
-
return htmlContent.trim();
|
|
52
|
-
}
|
|
53
|
-
// Truncate oversized HTML to prevent blocking the event loop
|
|
54
|
-
if (htmlContent.length > MAX_CONTENT_LENGTH) {
|
|
55
|
-
htmlContent = htmlContent.substring(0, MAX_CONTENT_LENGTH);
|
|
56
|
-
}
|
|
57
|
-
// Remove HTML comments before conversion (linear-time)
|
|
58
|
-
let content = removeHtmlComments(htmlContent);
|
|
59
|
-
// Convert HTML to Markdown using Turndown
|
|
60
|
-
content = turndown.turndown(content);
|
|
61
|
-
// Clean up whitespace
|
|
62
|
-
content = content.replace(/\n{3,}/g, '\n\n');
|
|
63
|
-
content = content.trim();
|
|
64
|
-
return content;
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
// Log error but don't crash - return original content for graceful degradation
|
|
68
|
-
console.error('[MarkdownCleaner] processContent failed:', error instanceof Error ? error.message : String(error), '| Content length:', htmlContent?.length ?? 0);
|
|
69
|
-
// Return original content if conversion fails
|
|
70
|
-
return htmlContent || '';
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
//# sourceMappingURL=markdown-cleaner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-cleaner.js","sourceRoot":"","sources":["../../src/services/markdown-cleaner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tool Definitions
|
|
3
|
-
* Generated from YAML configuration for consistency
|
|
4
|
-
*/
|
|
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[];
|
|
16
|
-
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tool Definitions
|
|
3
|
-
* Generated from YAML configuration for consistency
|
|
4
|
-
*/
|
|
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();
|
|
17
|
-
//# sourceMappingURL=definitions.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reddit Tools - Search and Fetch
|
|
3
|
-
* NEVER throws - always returns structured response for graceful degradation
|
|
4
|
-
*/
|
|
5
|
-
export declare function handleSearchReddit(queries: string[], apiKey: string, dateAfter?: string): Promise<string>;
|
|
6
|
-
interface GetRedditPostsOptions {
|
|
7
|
-
fetchComments?: boolean;
|
|
8
|
-
maxCommentsOverride?: number;
|
|
9
|
-
use_llm?: boolean;
|
|
10
|
-
what_to_extract?: string;
|
|
11
|
-
}
|
|
12
|
-
export declare function handleGetRedditPosts(urls: string[], clientId: string, clientSecret: string, maxComments?: number, options?: GetRedditPostsOptions): Promise<string>;
|
|
13
|
-
export {};
|
|
14
|
-
//# sourceMappingURL=reddit.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reddit.d.ts","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqGH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAMD,UAAU,qBAAqB;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA4MD,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,CA8BjB"}
|
package/dist/tools/reddit.js
DELETED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reddit Tools - Search and Fetch
|
|
3
|
-
* NEVER throws - always returns structured response for graceful degradation
|
|
4
|
-
*/
|
|
5
|
-
import { SearchClient } from '../clients/search.js';
|
|
6
|
-
import { RedditClient, calculateCommentAllocation } from '../clients/reddit.js';
|
|
7
|
-
import { aggregateAndRankReddit, generateRedditEnhancedOutput } from '../utils/url-aggregator.js';
|
|
8
|
-
import { REDDIT } from '../config/index.js';
|
|
9
|
-
import { classifyError } from '../utils/errors.js';
|
|
10
|
-
import { createLLMProcessor, processContentWithLLM } from '../services/llm-processor.js';
|
|
11
|
-
import { pMap } from '../utils/concurrency.js';
|
|
12
|
-
import { getToolConfig } from '../config/loader.js';
|
|
13
|
-
import { mcpLog, formatSuccess, formatError, formatBatchHeader, TOKEN_BUDGETS, } from './utils.js';
|
|
14
|
-
// ============================================================================
|
|
15
|
-
// Formatters
|
|
16
|
-
// ============================================================================
|
|
17
|
-
function formatComments(comments) {
|
|
18
|
-
let md = '';
|
|
19
|
-
for (const c of comments) {
|
|
20
|
-
const indent = ' '.repeat(c.depth);
|
|
21
|
-
const op = c.isOP ? ' **[OP]**' : '';
|
|
22
|
-
const score = c.score >= 0 ? `+${c.score}` : `${c.score}`;
|
|
23
|
-
md += `${indent}- **u/${c.author}**${op} _(${score})_\n`;
|
|
24
|
-
const bodyLines = c.body.split('\n').map(line => `${indent} ${line}`).join('\n');
|
|
25
|
-
md += `${bodyLines}\n\n`;
|
|
26
|
-
}
|
|
27
|
-
return md;
|
|
28
|
-
}
|
|
29
|
-
function formatPost(result, fetchComments) {
|
|
30
|
-
const { post, comments, allocatedComments } = result;
|
|
31
|
-
let md = `## ${post.title}\n\n`;
|
|
32
|
-
md += `**r/${post.subreddit}** • u/${post.author} • ⬆️ ${post.score} • 💬 ${post.commentCount} comments\n`;
|
|
33
|
-
md += `🔗 ${post.url}\n\n`;
|
|
34
|
-
if (post.body) {
|
|
35
|
-
md += `### Post Content\n\n${post.body}\n\n`;
|
|
36
|
-
}
|
|
37
|
-
if (fetchComments && comments.length > 0) {
|
|
38
|
-
md += `### Top Comments (${comments.length}/${post.commentCount} shown, allocated: ${allocatedComments})\n\n`;
|
|
39
|
-
md += formatComments(comments);
|
|
40
|
-
}
|
|
41
|
-
else if (!fetchComments) {
|
|
42
|
-
md += `_Comments not fetched (fetch_comments=false)_\n\n`;
|
|
43
|
-
}
|
|
44
|
-
return md;
|
|
45
|
-
}
|
|
46
|
-
// ============================================================================
|
|
47
|
-
// Search Reddit Handler
|
|
48
|
-
// ============================================================================
|
|
49
|
-
function countTotalResults(results) {
|
|
50
|
-
let total = 0;
|
|
51
|
-
for (const items of results.values()) {
|
|
52
|
-
total += items.length;
|
|
53
|
-
}
|
|
54
|
-
return total;
|
|
55
|
-
}
|
|
56
|
-
function formatNoSearchResults(queryCount) {
|
|
57
|
-
return formatError({
|
|
58
|
-
code: 'NO_RESULTS',
|
|
59
|
-
message: `No results found for any of the ${queryCount} queries`,
|
|
60
|
-
toolName: 'search_reddit',
|
|
61
|
-
howToFix: [
|
|
62
|
-
'Try broader or simpler search terms',
|
|
63
|
-
'Check spelling of technical terms',
|
|
64
|
-
'Remove date filters if using them',
|
|
65
|
-
],
|
|
66
|
-
alternatives: [
|
|
67
|
-
'web_search(keywords=["topic best practices", "topic guide", "topic recommendations 2025"]) — get results from the broader web instead',
|
|
68
|
-
'scrape_links(urls=[...any URLs you already have...], use_llm=true) — if you have URLs from earlier searches, scrape them now',
|
|
69
|
-
'deep_research(questions=[{question: "What are the key findings about [topic]?"}]) — synthesize from AI research',
|
|
70
|
-
],
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
function formatSearchRedditError(error) {
|
|
74
|
-
const structuredError = classifyError(error);
|
|
75
|
-
return formatError({
|
|
76
|
-
code: structuredError.code,
|
|
77
|
-
message: structuredError.message,
|
|
78
|
-
retryable: structuredError.retryable,
|
|
79
|
-
toolName: 'search_reddit',
|
|
80
|
-
howToFix: ['Verify SERPER_API_KEY is set correctly'],
|
|
81
|
-
alternatives: [
|
|
82
|
-
'web_search(keywords=["topic recommendations", "topic best practices", "topic vs alternatives"]) — uses the same API key, but try anyway as it may work for general search',
|
|
83
|
-
'deep_research(questions=[{question: "What does the community recommend for [topic]?"}]) — uses a different API (OpenRouter), not affected by this error',
|
|
84
|
-
'scrape_links(urls=[...any URLs you already have...], use_llm=true) — if you have URLs from prior steps, scrape them now',
|
|
85
|
-
],
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
export async function handleSearchReddit(queries, apiKey, dateAfter) {
|
|
89
|
-
try {
|
|
90
|
-
const limited = queries.slice(0, 50);
|
|
91
|
-
const client = new SearchClient(apiKey);
|
|
92
|
-
const results = await client.searchRedditMultiple(limited, dateAfter);
|
|
93
|
-
const totalResults = countTotalResults(results);
|
|
94
|
-
if (totalResults === 0) {
|
|
95
|
-
return formatNoSearchResults(limited.length);
|
|
96
|
-
}
|
|
97
|
-
const aggregation = aggregateAndRankReddit(results, 3);
|
|
98
|
-
return generateRedditEnhancedOutput(aggregation, limited, results);
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
return formatSearchRedditError(error);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
// Get extraction suffix from YAML config (fallback to hardcoded if not found)
|
|
105
|
-
function getExtractionSuffix() {
|
|
106
|
-
const config = getToolConfig('get_reddit_post');
|
|
107
|
-
const suffix = config?.limits?.extraction_suffix;
|
|
108
|
-
if (typeof suffix === 'string')
|
|
109
|
-
return suffix;
|
|
110
|
-
return `
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
⚠️ IMPORTANT: Extract and synthesize the key insights, opinions, and recommendations from these Reddit discussions. Focus on:
|
|
114
|
-
- Common themes and consensus across posts
|
|
115
|
-
- Specific recommendations with context
|
|
116
|
-
- Contrasting viewpoints and debates
|
|
117
|
-
- Real-world experiences and lessons learned
|
|
118
|
-
- Technical details and implementation tips
|
|
119
|
-
|
|
120
|
-
Be comprehensive but concise. Prioritize actionable insights.
|
|
121
|
-
|
|
122
|
-
---`;
|
|
123
|
-
}
|
|
124
|
-
function enhanceExtractionInstruction(instruction) {
|
|
125
|
-
const base = instruction || 'Extract key insights, recommendations, and community consensus from these Reddit discussions.';
|
|
126
|
-
return `${base}\n\n${getExtractionSuffix()}`;
|
|
127
|
-
}
|
|
128
|
-
// --- Helpers ---
|
|
129
|
-
function validatePostCount(urlCount) {
|
|
130
|
-
if (urlCount < REDDIT.MIN_POSTS) {
|
|
131
|
-
return formatError({
|
|
132
|
-
code: 'MIN_POSTS',
|
|
133
|
-
message: `Minimum ${REDDIT.MIN_POSTS} Reddit posts required. Received: ${urlCount}`,
|
|
134
|
-
toolName: 'get_reddit_post',
|
|
135
|
-
howToFix: [`Add at least ${REDDIT.MIN_POSTS - urlCount} more Reddit URL(s)`],
|
|
136
|
-
alternatives: [
|
|
137
|
-
`search_reddit(queries=["topic discussion", "topic recommendations", "topic experiences"]) — find more Reddit posts first, then call get_reddit_post with ${REDDIT.MIN_POSTS}+ URLs`,
|
|
138
|
-
],
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
if (urlCount > REDDIT.MAX_POSTS) {
|
|
142
|
-
return formatError({
|
|
143
|
-
code: 'MAX_POSTS',
|
|
144
|
-
message: `Maximum ${REDDIT.MAX_POSTS} Reddit posts allowed. Received: ${urlCount}`,
|
|
145
|
-
toolName: 'get_reddit_post',
|
|
146
|
-
howToFix: [`Remove ${urlCount - REDDIT.MAX_POSTS} URL(s) and retry`],
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
async function applyLlmToPost(postContent, result, url, llmProcessor, enhancedInstruction, tokensPerUrl, index, total) {
|
|
152
|
-
mcpLog('info', `[${index}/${total}] Applying LLM extraction to ${url}`, 'reddit');
|
|
153
|
-
const llmResult = await processContentWithLLM(postContent, { use_llm: true, what_to_extract: enhancedInstruction, max_tokens: tokensPerUrl }, llmProcessor);
|
|
154
|
-
if (llmResult.processed) {
|
|
155
|
-
mcpLog('debug', `[${index}/${total}] LLM extraction complete`, 'reddit');
|
|
156
|
-
const header = `## LLM Analysis: ${result.post.title}\n\n**r/${result.post.subreddit}** • u/${result.post.author} • ⬆️ ${result.post.score} • 💬 ${result.post.commentCount} comments\n🔗 ${result.post.url}\n\n`;
|
|
157
|
-
return { content: header + llmResult.content, llmFailed: false };
|
|
158
|
-
}
|
|
159
|
-
mcpLog('warning', `[${index}/${total}] LLM extraction failed: ${llmResult.error || 'unknown'}`, 'reddit');
|
|
160
|
-
return { content: postContent, llmFailed: true };
|
|
161
|
-
}
|
|
162
|
-
async function fetchAndProcessPosts(results, urls, fetchComments, use_llm, what_to_extract) {
|
|
163
|
-
const llmProcessor = use_llm ? createLLMProcessor() : null;
|
|
164
|
-
const tokensPerUrl = use_llm ? Math.floor(TOKEN_BUDGETS.RESEARCH / urls.length) : 0;
|
|
165
|
-
const enhancedInstruction = use_llm ? enhanceExtractionInstruction(what_to_extract) : undefined;
|
|
166
|
-
let failed = 0;
|
|
167
|
-
const failedContents = [];
|
|
168
|
-
const successEntries = [];
|
|
169
|
-
for (const [url, result] of results) {
|
|
170
|
-
if (result instanceof Error) {
|
|
171
|
-
failed++;
|
|
172
|
-
failedContents.push(`## ❌ Failed: ${url}\n\n_${result.message}_`);
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
successEntries.push({ url, result, content: formatPost(result, fetchComments) });
|
|
176
|
-
}
|
|
177
|
-
let llmErrors = 0;
|
|
178
|
-
let processedEntries;
|
|
179
|
-
if (use_llm && llmProcessor && successEntries.length > 0) {
|
|
180
|
-
const llmResults = await pMap(successEntries, async (entry, index) => {
|
|
181
|
-
const llmOut = await applyLlmToPost(entry.content, entry.result, entry.url, llmProcessor, enhancedInstruction, tokensPerUrl, index + 1, successEntries.length);
|
|
182
|
-
if (llmOut.llmFailed)
|
|
183
|
-
llmErrors++;
|
|
184
|
-
return { ...entry, content: llmOut.content };
|
|
185
|
-
}, 3);
|
|
186
|
-
processedEntries = llmResults;
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
processedEntries = successEntries;
|
|
190
|
-
}
|
|
191
|
-
const contents = [...failedContents, ...processedEntries.map(e => e.content)];
|
|
192
|
-
return { successful: successEntries.length, failed, llmErrors, llmAvailable: llmProcessor !== null, contents };
|
|
193
|
-
}
|
|
194
|
-
function buildRedditStatusExtras(rateLimitHits, use_llm, llmAvailable, llmErrors) {
|
|
195
|
-
const extras = [];
|
|
196
|
-
if (rateLimitHits > 0)
|
|
197
|
-
extras.push(`⚠️ ${rateLimitHits} rate limit retries`);
|
|
198
|
-
if (use_llm && !llmAvailable) {
|
|
199
|
-
extras.push('⚠️ LLM unavailable (OPENROUTER_API_KEY not set)');
|
|
200
|
-
}
|
|
201
|
-
else if (llmErrors > 0) {
|
|
202
|
-
extras.push(`⚠️ ${llmErrors} LLM extraction failures`);
|
|
203
|
-
}
|
|
204
|
-
return extras.length > 0 ? `\n${extras.join(' | ')}` : '';
|
|
205
|
-
}
|
|
206
|
-
function formatRedditOutput(urls, processResult, fetchComments, commentsPerPost, totalBatches, use_llm, tokensPerUrl, extraStatus) {
|
|
207
|
-
const batchHeader = formatBatchHeader({
|
|
208
|
-
title: `Reddit Posts`,
|
|
209
|
-
totalItems: urls.length,
|
|
210
|
-
successful: processResult.successful,
|
|
211
|
-
failed: processResult.failed,
|
|
212
|
-
...(fetchComments ? { extras: { 'Comments/post': commentsPerPost } } : {}),
|
|
213
|
-
...(use_llm ? { tokensPerItem: tokensPerUrl } : {}),
|
|
214
|
-
batches: totalBatches,
|
|
215
|
-
});
|
|
216
|
-
const nextSteps = [
|
|
217
|
-
processResult.successful > 0 ? 'VERIFY CLAIMS: web_search(keywords=["topic claim1 verify", "topic claim2 official docs", "topic best practices"]) — community says X, verify with web' : null,
|
|
218
|
-
processResult.successful > 0 ? 'SCRAPE REFERENCED LINKS: scrape_links(urls=[...URLs found in comments...], use_llm=true, what_to_extract="Extract evidence | data | recommendations") — follow external links from discussions' : null,
|
|
219
|
-
'BROADEN: search_reddit(queries=[...related angles...]) — if more perspectives needed',
|
|
220
|
-
processResult.successful > 0 ? 'SYNTHESIZE (only after verifying + scraping): deep_research(questions=[{question: "Based on verified Reddit findings about [topic]..."}])' : null,
|
|
221
|
-
processResult.failed > 0 ? 'Retry failed URLs individually' : null,
|
|
222
|
-
].filter(Boolean);
|
|
223
|
-
return formatSuccess({
|
|
224
|
-
title: `Reddit Posts Fetched (${processResult.successful}/${urls.length})`,
|
|
225
|
-
summary: batchHeader + extraStatus,
|
|
226
|
-
data: processResult.contents.join('\n\n---\n\n'),
|
|
227
|
-
nextSteps,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
function formatGetRedditPostsError(error) {
|
|
231
|
-
const structuredError = classifyError(error);
|
|
232
|
-
return formatError({
|
|
233
|
-
code: structuredError.code,
|
|
234
|
-
message: structuredError.message,
|
|
235
|
-
retryable: structuredError.retryable,
|
|
236
|
-
toolName: 'get_reddit_post',
|
|
237
|
-
howToFix: ['Verify REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET are set'],
|
|
238
|
-
alternatives: [
|
|
239
|
-
'web_search(keywords=["topic reddit discussion", "topic reddit recommendations"]) — search for Reddit content via web search instead',
|
|
240
|
-
'scrape_links(urls=[...the Reddit URLs...], use_llm=true, what_to_extract="Extract post content | top comments | recommendations") — scrape Reddit pages directly as a fallback',
|
|
241
|
-
'deep_research(questions=[{question: "What are community opinions on [topic]?"}]) — get AI-synthesized community perspective',
|
|
242
|
-
],
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
export async function handleGetRedditPosts(urls, clientId, clientSecret, maxComments = 100, options = {}) {
|
|
246
|
-
try {
|
|
247
|
-
const { fetchComments = true, maxCommentsOverride, use_llm = false, what_to_extract } = options;
|
|
248
|
-
const validationError = validatePostCount(urls.length);
|
|
249
|
-
if (validationError)
|
|
250
|
-
return validationError;
|
|
251
|
-
const allocation = calculateCommentAllocation(urls.length);
|
|
252
|
-
const commentsPerPost = fetchComments ? (maxCommentsOverride || allocation.perPostCapped) : 0;
|
|
253
|
-
const totalBatches = Math.ceil(urls.length / REDDIT.BATCH_SIZE);
|
|
254
|
-
const client = new RedditClient(clientId, clientSecret);
|
|
255
|
-
const batchResult = await client.batchGetPosts(urls, commentsPerPost, fetchComments);
|
|
256
|
-
const processResult = await fetchAndProcessPosts(batchResult.results, urls, fetchComments, use_llm, what_to_extract);
|
|
257
|
-
const tokensPerUrl = use_llm ? Math.floor(TOKEN_BUDGETS.RESEARCH / urls.length) : 0;
|
|
258
|
-
const extraStatus = buildRedditStatusExtras(batchResult.rateLimitHits, use_llm, processResult.llmAvailable, processResult.llmErrors);
|
|
259
|
-
return formatRedditOutput(urls, processResult, fetchComments, commentsPerPost, totalBatches, use_llm, tokensPerUrl, extraStatus);
|
|
260
|
-
}
|
|
261
|
-
catch (error) {
|
|
262
|
-
return formatGetRedditPostsError(error);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
//# sourceMappingURL=reddit.js.map
|
package/dist/tools/reddit.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reddit.js","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/registry.d.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
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
|
-
readonly content: Array<{
|
|
12
|
-
readonly type: 'text';
|
|
13
|
-
readonly text: string;
|
|
14
|
-
}>;
|
|
15
|
-
readonly isError?: boolean;
|
|
16
|
-
[key: string]: unknown;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Configuration for a registered tool
|
|
20
|
-
*/
|
|
21
|
-
export interface ToolRegistration {
|
|
22
|
-
readonly name: string;
|
|
23
|
-
readonly capability?: keyof Capabilities;
|
|
24
|
-
readonly schema: z.ZodSchema;
|
|
25
|
-
readonly handler: (params: unknown) => Promise<string>;
|
|
26
|
-
readonly postValidate?: (params: unknown) => string | undefined;
|
|
27
|
-
readonly 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
|
|
@@ -1 +0,0 @@
|
|
|
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,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,YAAY,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;IAChE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACzF;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAqF5D;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,YA+C1B,CAAC;AAiEF;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,cAAc,CAAC,CA4BzB;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"}
|