research-powerpack-mcp 3.0.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.
Files changed (82) hide show
  1. package/README.md +486 -0
  2. package/dist/clients/reddit.d.ts +61 -0
  3. package/dist/clients/reddit.d.ts.map +1 -0
  4. package/dist/clients/reddit.js +179 -0
  5. package/dist/clients/reddit.js.map +1 -0
  6. package/dist/clients/research.d.ts +41 -0
  7. package/dist/clients/research.d.ts.map +1 -0
  8. package/dist/clients/research.js +77 -0
  9. package/dist/clients/research.js.map +1 -0
  10. package/dist/clients/scraper.d.ts +44 -0
  11. package/dist/clients/scraper.d.ts.map +1 -0
  12. package/dist/clients/scraper.js +171 -0
  13. package/dist/clients/scraper.js.map +1 -0
  14. package/dist/clients/search.d.ts +46 -0
  15. package/dist/clients/search.d.ts.map +1 -0
  16. package/dist/clients/search.js +91 -0
  17. package/dist/clients/search.js.map +1 -0
  18. package/dist/config/index.d.ts +59 -0
  19. package/dist/config/index.d.ts.map +1 -0
  20. package/dist/config/index.js +100 -0
  21. package/dist/config/index.js.map +1 -0
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +152 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/schemas/deep-research.d.ts +100 -0
  27. package/dist/schemas/deep-research.d.ts.map +1 -0
  28. package/dist/schemas/deep-research.js +57 -0
  29. package/dist/schemas/deep-research.js.map +1 -0
  30. package/dist/schemas/scrape-links.d.ts +38 -0
  31. package/dist/schemas/scrape-links.d.ts.map +1 -0
  32. package/dist/schemas/scrape-links.js +26 -0
  33. package/dist/schemas/scrape-links.js.map +1 -0
  34. package/dist/schemas/web-search.d.ts +24 -0
  35. package/dist/schemas/web-search.d.ts.map +1 -0
  36. package/dist/schemas/web-search.js +12 -0
  37. package/dist/schemas/web-search.js.map +1 -0
  38. package/dist/services/file-attachment.d.ts +30 -0
  39. package/dist/services/file-attachment.d.ts.map +1 -0
  40. package/dist/services/file-attachment.js +196 -0
  41. package/dist/services/file-attachment.js.map +1 -0
  42. package/dist/services/llm-processor.d.ts +19 -0
  43. package/dist/services/llm-processor.d.ts.map +1 -0
  44. package/dist/services/llm-processor.js +44 -0
  45. package/dist/services/llm-processor.js.map +1 -0
  46. package/dist/services/markdown-cleaner.d.ts +8 -0
  47. package/dist/services/markdown-cleaner.d.ts.map +1 -0
  48. package/dist/services/markdown-cleaner.js +56 -0
  49. package/dist/services/markdown-cleaner.js.map +1 -0
  50. package/dist/tools/definitions.d.ts +66 -0
  51. package/dist/tools/definitions.d.ts.map +1 -0
  52. package/dist/tools/definitions.js +125 -0
  53. package/dist/tools/definitions.js.map +1 -0
  54. package/dist/tools/reddit.d.ts +10 -0
  55. package/dist/tools/reddit.d.ts.map +1 -0
  56. package/dist/tools/reddit.js +105 -0
  57. package/dist/tools/reddit.js.map +1 -0
  58. package/dist/tools/research.d.ts +14 -0
  59. package/dist/tools/research.d.ts.map +1 -0
  60. package/dist/tools/research.js +126 -0
  61. package/dist/tools/research.js.map +1 -0
  62. package/dist/tools/scrape.d.ts +14 -0
  63. package/dist/tools/scrape.d.ts.map +1 -0
  64. package/dist/tools/scrape.js +111 -0
  65. package/dist/tools/scrape.js.map +1 -0
  66. package/dist/tools/search.d.ts +14 -0
  67. package/dist/tools/search.d.ts.map +1 -0
  68. package/dist/tools/search.js +121 -0
  69. package/dist/tools/search.js.map +1 -0
  70. package/dist/utils/errors.d.ts +8 -0
  71. package/dist/utils/errors.d.ts.map +1 -0
  72. package/dist/utils/errors.js +30 -0
  73. package/dist/utils/errors.js.map +1 -0
  74. package/dist/utils/markdown-formatter.d.ts +5 -0
  75. package/dist/utils/markdown-formatter.d.ts.map +1 -0
  76. package/dist/utils/markdown-formatter.js +15 -0
  77. package/dist/utils/markdown-formatter.js.map +1 -0
  78. package/dist/utils/url-aggregator.d.ts +55 -0
  79. package/dist/utils/url-aggregator.d.ts.map +1 -0
  80. package/dist/utils/url-aggregator.js +246 -0
  81. package/dist/utils/url-aggregator.js.map +1 -0
  82. package/package.json +56 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Web Search Client
3
+ * Generic interface for web search via Google (Serper implementation)
4
+ */
5
+ import { parseEnv } from '../config/index.js';
6
+ export class SearchClient {
7
+ apiKey;
8
+ baseURL = 'https://google.serper.dev';
9
+ constructor(apiKey) {
10
+ const env = parseEnv();
11
+ this.apiKey = apiKey || env.SEARCH_API_KEY || '';
12
+ if (!this.apiKey) {
13
+ throw new Error('SERPER_API_KEY is required for search functionality');
14
+ }
15
+ }
16
+ /**
17
+ * Search multiple keywords in parallel
18
+ */
19
+ async searchMultiple(keywords) {
20
+ const startTime = Date.now();
21
+ try {
22
+ const searchQueries = keywords.map(keyword => ({ q: keyword }));
23
+ const response = await fetch(`${this.baseURL}/search`, {
24
+ method: 'POST',
25
+ headers: {
26
+ 'X-API-KEY': this.apiKey,
27
+ 'Content-Type': 'application/json',
28
+ },
29
+ body: JSON.stringify(searchQueries),
30
+ });
31
+ if (!response.ok) {
32
+ const errorText = await response.text().catch(() => '');
33
+ throw new Error(`Search API error: ${response.status} ${errorText}`);
34
+ }
35
+ const data = await response.json();
36
+ const responses = Array.isArray(data) ? data : [data];
37
+ const searches = responses.map((resp, index) => {
38
+ const organic = (resp.organic || []);
39
+ const results = organic.map((item, idx) => ({
40
+ title: item.title || 'No title',
41
+ link: item.link || '#',
42
+ snippet: item.snippet || '',
43
+ date: item.date,
44
+ position: item.position || idx + 1,
45
+ }));
46
+ const searchInfo = resp.searchInformation;
47
+ const totalResults = searchInfo?.totalResults
48
+ ? parseInt(String(searchInfo.totalResults).replace(/,/g, ''), 10)
49
+ : results.length;
50
+ const relatedSearches = (resp.relatedSearches || []);
51
+ const related = relatedSearches.map((r) => r.query || '');
52
+ return { keyword: keywords[index] || '', results, totalResults, related };
53
+ });
54
+ return { searches, totalKeywords: keywords.length, executionTime: Date.now() - startTime };
55
+ }
56
+ catch (error) {
57
+ throw new Error(`Failed to search: ${error instanceof Error ? error.message : String(error)}`);
58
+ }
59
+ }
60
+ /**
61
+ * Search Reddit via Google (adds site:reddit.com automatically)
62
+ */
63
+ async searchReddit(query, dateAfter) {
64
+ let q = /site:\s*reddit\.com/i.test(query) ? query : `${query} site:reddit.com`;
65
+ if (dateAfter) {
66
+ q += ` after:${dateAfter}`;
67
+ }
68
+ const res = await fetch(`${this.baseURL}/search`, {
69
+ method: 'POST',
70
+ headers: { 'X-API-KEY': this.apiKey, 'Content-Type': 'application/json' },
71
+ body: JSON.stringify({ q, num: 10 }),
72
+ });
73
+ if (!res.ok)
74
+ throw new Error(`Search error: ${res.status}`);
75
+ const data = await res.json();
76
+ return (data.organic || []).map((r) => ({
77
+ title: r.title.replace(/ : r\/\w+$/, '').replace(/ - Reddit$/, ''),
78
+ url: r.link,
79
+ snippet: r.snippet,
80
+ date: r.date,
81
+ }));
82
+ }
83
+ /**
84
+ * Search Reddit with multiple queries in parallel
85
+ */
86
+ async searchRedditMultiple(queries, dateAfter) {
87
+ const results = await Promise.all(queries.map(q => this.searchReddit(q, dateAfter).catch(() => [])));
88
+ return new Map(queries.map((q, i) => [q, results[i]]));
89
+ }
90
+ }
91
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/clients/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Consolidated configuration
3
+ * All environment variables, constants, and LLM config in one place
4
+ */
5
+ export interface EnvConfig {
6
+ SCRAPER_API_KEY: string;
7
+ SEARCH_API_KEY: string | undefined;
8
+ REDDIT_CLIENT_ID: string | undefined;
9
+ REDDIT_CLIENT_SECRET: string | undefined;
10
+ }
11
+ export declare function parseEnv(): EnvConfig;
12
+ export declare const RESEARCH: {
13
+ readonly BASE_URL: string;
14
+ readonly MODEL: string;
15
+ readonly API_KEY: string;
16
+ readonly TIMEOUT_MS: number;
17
+ readonly REASONING_EFFORT: "low" | "medium" | "high";
18
+ readonly MAX_URLS: number;
19
+ };
20
+ export declare const SERVER: {
21
+ readonly NAME: "research-powerpack-mcp";
22
+ readonly VERSION: "3.0.0";
23
+ readonly DESCRIPTION: "The ultimate research MCP toolkit with modular capabilities";
24
+ };
25
+ export interface Capabilities {
26
+ reddit: boolean;
27
+ search: boolean;
28
+ scraping: boolean;
29
+ deepResearch: boolean;
30
+ llmExtraction: boolean;
31
+ }
32
+ export declare function getCapabilities(): Capabilities;
33
+ export declare function getMissingEnvMessage(capability: keyof Capabilities): string;
34
+ export declare const SCRAPER: {
35
+ readonly MAX_CONCURRENT: 30;
36
+ readonly BATCH_SIZE: 30;
37
+ readonly MAX_TOKENS_BUDGET: 32000;
38
+ readonly MIN_URLS: 3;
39
+ readonly MAX_URLS: 50;
40
+ readonly RETRY_COUNT: 3;
41
+ readonly RETRY_DELAYS: readonly [2000, 4000, 8000];
42
+ readonly EXTRACTION_SUFFIX: "Try to answer this information as comprehensive as possible while keeping info density super high without adding unnecessary words but satisfy the scope defined by previous instructions even more.";
43
+ };
44
+ export declare const REDDIT: {
45
+ readonly MAX_CONCURRENT: 10;
46
+ readonly BATCH_SIZE: 10;
47
+ readonly MAX_COMMENT_BUDGET: 1000;
48
+ readonly MAX_COMMENTS_PER_POST: 200;
49
+ readonly MIN_POSTS: 2;
50
+ readonly MAX_POSTS: 50;
51
+ readonly RETRY_COUNT: 5;
52
+ readonly RETRY_DELAYS: readonly [2000, 4000, 8000, 16000, 32000];
53
+ };
54
+ export declare const CTR_WEIGHTS: Record<number, number>;
55
+ export declare const LLM_EXTRACTION: {
56
+ readonly MODEL: string;
57
+ readonly MAX_TOKENS: 4000;
58
+ };
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,wBAAgB,QAAQ,IAAI,SAAS,CAOpC;AAMD,eAAO,MAAM,QAAQ;;;;;;;CAOX,CAAC;AAMX,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAMX,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,eAAe,IAAI,YAAY,CAS9C;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,YAAY,GAAG,MAAM,CAS3E;AAMD,eAAO,MAAM,OAAO;;;;;;;;;CASV,CAAC;AAMX,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AAMX,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAWrC,CAAC;AAMX,eAAO,MAAM,cAAc;;;CAGjB,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Consolidated configuration
3
+ * All environment variables, constants, and LLM config in one place
4
+ */
5
+ export function parseEnv() {
6
+ return {
7
+ SCRAPER_API_KEY: process.env.SCRAPEDO_API_KEY || '',
8
+ SEARCH_API_KEY: process.env.SERPER_API_KEY || undefined,
9
+ REDDIT_CLIENT_ID: process.env.REDDIT_CLIENT_ID || undefined,
10
+ REDDIT_CLIENT_SECRET: process.env.REDDIT_CLIENT_SECRET || undefined,
11
+ };
12
+ }
13
+ // ============================================================================
14
+ // Research API Configuration
15
+ // ============================================================================
16
+ export const RESEARCH = {
17
+ BASE_URL: process.env.OPENROUTER_BASE_URL || 'https://openrouter.ai/api/v1',
18
+ MODEL: process.env.RESEARCH_MODEL || 'perplexity/sonar-deep-research',
19
+ API_KEY: process.env.OPENROUTER_API_KEY || '',
20
+ TIMEOUT_MS: parseInt(process.env.API_TIMEOUT_MS || '1800000', 10),
21
+ REASONING_EFFORT: process.env.DEFAULT_REASONING_EFFORT || 'high',
22
+ MAX_URLS: parseInt(process.env.DEFAULT_MAX_URLS || '100', 10),
23
+ };
24
+ // ============================================================================
25
+ // MCP Server Configuration
26
+ // ============================================================================
27
+ export const SERVER = {
28
+ NAME: 'research-powerpack-mcp',
29
+ VERSION: '3.0.0',
30
+ DESCRIPTION: 'The ultimate research MCP toolkit with modular capabilities',
31
+ };
32
+ export function getCapabilities() {
33
+ const env = parseEnv();
34
+ return {
35
+ reddit: !!(env.REDDIT_CLIENT_ID && env.REDDIT_CLIENT_SECRET),
36
+ search: !!env.SEARCH_API_KEY,
37
+ scraping: !!env.SCRAPER_API_KEY,
38
+ deepResearch: !!RESEARCH.API_KEY,
39
+ llmExtraction: !!RESEARCH.API_KEY, // Reuses OPENROUTER for LLM extraction
40
+ };
41
+ }
42
+ export function getMissingEnvMessage(capability) {
43
+ const messages = {
44
+ reddit: '❌ **Reddit tools unavailable.** Set `REDDIT_CLIENT_ID` and `REDDIT_CLIENT_SECRET` to enable.\n\n👉 Create a Reddit app at: https://www.reddit.com/prefs/apps (select "script" type)',
45
+ search: '❌ **Search unavailable.** Set `SERPER_API_KEY` to enable web search and Reddit search.\n\n👉 Get your free API key at: https://serper.dev (2,500 free queries)',
46
+ scraping: '❌ **Web scraping unavailable.** Set `SCRAPEDO_API_KEY` to enable URL content extraction.\n\n👉 Sign up at: https://scrape.do (1,000 free credits)',
47
+ deepResearch: '❌ **Deep research unavailable.** Set `OPENROUTER_API_KEY` to enable AI-powered research.\n\n👉 Get your API key at: https://openrouter.ai/keys',
48
+ llmExtraction: '⚠️ **AI extraction disabled.** The `use_llm` and `what_to_extract` features require `OPENROUTER_API_KEY`.\n\nScraping will work but without intelligent content filtering.',
49
+ };
50
+ return messages[capability];
51
+ }
52
+ // ============================================================================
53
+ // Scraper Configuration (Scrape.do implementation)
54
+ // ============================================================================
55
+ export const SCRAPER = {
56
+ MAX_CONCURRENT: 30,
57
+ BATCH_SIZE: 30,
58
+ MAX_TOKENS_BUDGET: 32000,
59
+ MIN_URLS: 3,
60
+ MAX_URLS: 50,
61
+ RETRY_COUNT: 3,
62
+ RETRY_DELAYS: [2000, 4000, 8000],
63
+ EXTRACTION_SUFFIX: 'Try to answer this information as comprehensive as possible while keeping info density super high without adding unnecessary words but satisfy the scope defined by previous instructions even more.',
64
+ };
65
+ // ============================================================================
66
+ // Reddit Configuration
67
+ // ============================================================================
68
+ export const REDDIT = {
69
+ MAX_CONCURRENT: 10,
70
+ BATCH_SIZE: 10,
71
+ MAX_COMMENT_BUDGET: 1000,
72
+ MAX_COMMENTS_PER_POST: 200,
73
+ MIN_POSTS: 2,
74
+ MAX_POSTS: 50,
75
+ RETRY_COUNT: 5,
76
+ RETRY_DELAYS: [2000, 4000, 8000, 16000, 32000],
77
+ };
78
+ // ============================================================================
79
+ // CTR Weights for URL Ranking
80
+ // ============================================================================
81
+ export const CTR_WEIGHTS = {
82
+ 1: 100.00,
83
+ 2: 60.00,
84
+ 3: 48.89,
85
+ 4: 33.33,
86
+ 5: 28.89,
87
+ 6: 26.44,
88
+ 7: 24.44,
89
+ 8: 17.78,
90
+ 9: 13.33,
91
+ 10: 12.56,
92
+ };
93
+ // ============================================================================
94
+ // LLM Extraction Model (uses OPENROUTER for scrape_links AI extraction)
95
+ // ============================================================================
96
+ export const LLM_EXTRACTION = {
97
+ MODEL: process.env.LLM_EXTRACTION_MODEL || 'anthropic/claude-3.5-sonnet',
98
+ MAX_TOKENS: 4000,
99
+ };
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
5
+ import { TOOLS } from './tools/definitions.js';
6
+ import { handleSearchReddit, handleGetRedditPosts } from './tools/reddit.js';
7
+ import { handleDeepResearch } from './tools/research.js';
8
+ import { handleScrapeLinks } from './tools/scrape.js';
9
+ import { handleWebSearch } from './tools/search.js';
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 { createSimpleError } from './utils/errors.js';
14
+ import { parseEnv, SERVER, getCapabilities, getMissingEnvMessage } from './config/index.js';
15
+ // ============================================================================
16
+ // Capability Detection (no ENV required - tools fail gracefully when called)
17
+ // ============================================================================
18
+ const env = parseEnv();
19
+ const capabilities = getCapabilities();
20
+ // Log available capabilities for debugging
21
+ const enabledTools = [];
22
+ const disabledTools = [];
23
+ if (capabilities.search) {
24
+ enabledTools.push('web_search', 'search_reddit');
25
+ }
26
+ else {
27
+ disabledTools.push('web_search', 'search_reddit');
28
+ }
29
+ if (capabilities.reddit) {
30
+ enabledTools.push('get_reddit_post');
31
+ }
32
+ else {
33
+ disabledTools.push('get_reddit_post');
34
+ }
35
+ if (capabilities.scraping) {
36
+ enabledTools.push('scrape_links');
37
+ }
38
+ else {
39
+ disabledTools.push('scrape_links');
40
+ }
41
+ if (capabilities.deepResearch) {
42
+ enabledTools.push('deep_research');
43
+ }
44
+ else {
45
+ disabledTools.push('deep_research');
46
+ }
47
+ if (enabledTools.length > 0) {
48
+ console.error(`✅ Enabled tools: ${enabledTools.join(', ')}`);
49
+ }
50
+ if (disabledTools.length > 0) {
51
+ console.error(`⚠️ Disabled tools (missing ENV): ${disabledTools.join(', ')}`);
52
+ }
53
+ if (capabilities.scraping && !capabilities.llmExtraction) {
54
+ console.error(`ℹ️ scrape_links: AI extraction (use_llm) disabled - set OPENROUTER_API_KEY to enable`);
55
+ }
56
+ // ============================================================================
57
+ // Server Setup
58
+ // ============================================================================
59
+ const server = new Server({ name: SERVER.NAME, version: SERVER.VERSION }, { capabilities: { tools: {} } });
60
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
61
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
62
+ const { name, arguments: args } = request.params;
63
+ try {
64
+ // ========== SEARCH_REDDIT ==========
65
+ if (name === 'search_reddit') {
66
+ // Check capability
67
+ if (!capabilities.search) {
68
+ return { content: [{ type: 'text', text: getMissingEnvMessage('search') }], isError: true };
69
+ }
70
+ const { queries, date_after } = args;
71
+ if (!Array.isArray(queries) || queries.length === 0) {
72
+ return { content: [{ type: 'text', text: 'Error: queries must be a non-empty array of strings' }], isError: true };
73
+ }
74
+ const result = await handleSearchReddit(queries, env.SEARCH_API_KEY, date_after);
75
+ return { content: [{ type: 'text', text: result }] };
76
+ }
77
+ // ========== GET_REDDIT_POST ==========
78
+ if (name === 'get_reddit_post') {
79
+ // Check capability
80
+ if (!capabilities.reddit) {
81
+ return { content: [{ type: 'text', text: getMissingEnvMessage('reddit') }], isError: true };
82
+ }
83
+ const { urls, max_comments = 100, fetch_comments = true } = args;
84
+ if (!Array.isArray(urls) || urls.length === 0) {
85
+ return { content: [{ type: 'text', text: 'Error: urls must be a non-empty array of Reddit post URLs' }], isError: true };
86
+ }
87
+ const result = await handleGetRedditPosts(urls, env.REDDIT_CLIENT_ID, env.REDDIT_CLIENT_SECRET, max_comments, {
88
+ fetchComments: fetch_comments,
89
+ maxCommentsOverride: max_comments !== 100 ? max_comments : undefined,
90
+ });
91
+ return { content: [{ type: 'text', text: result }] };
92
+ }
93
+ // ========== DEEP_RESEARCH ==========
94
+ if (name === 'deep_research') {
95
+ // Check capability
96
+ if (!capabilities.deepResearch) {
97
+ return { content: [{ type: 'text', text: getMissingEnvMessage('deepResearch') }], isError: true };
98
+ }
99
+ const validatedParams = deepResearchParamsSchema.parse(args);
100
+ const { content, structuredContent } = await handleDeepResearch(validatedParams);
101
+ if (structuredContent && typeof structuredContent === 'object' && 'error' in structuredContent && structuredContent.error) {
102
+ return { content: [{ type: 'text', text: content }], isError: true };
103
+ }
104
+ return { content: [{ type: 'text', text: content }] };
105
+ }
106
+ // ========== SCRAPE_LINKS ==========
107
+ if (name === 'scrape_links') {
108
+ // Check capability
109
+ if (!capabilities.scraping) {
110
+ return { content: [{ type: 'text', text: getMissingEnvMessage('scraping') }], isError: true };
111
+ }
112
+ const validatedParams = scrapeLinksParamsSchema.parse(args);
113
+ // Warn if use_llm requested but LLM not available
114
+ if (validatedParams.use_llm && !capabilities.llmExtraction) {
115
+ console.error('[scrape_links] use_llm requested but OPENROUTER_API_KEY not set - proceeding without AI extraction');
116
+ validatedParams.use_llm = false;
117
+ }
118
+ const { content, structuredContent } = await handleScrapeLinks(validatedParams);
119
+ if (structuredContent.metadata.failed === structuredContent.metadata.total_urls) {
120
+ return { content: [{ type: 'text', text: content }], isError: true };
121
+ }
122
+ return { content: [{ type: 'text', text: content }] };
123
+ }
124
+ // ========== WEB_SEARCH ==========
125
+ if (name === 'web_search') {
126
+ // Check capability
127
+ if (!capabilities.search) {
128
+ return { content: [{ type: 'text', text: getMissingEnvMessage('search') }], isError: true };
129
+ }
130
+ const validatedParams = webSearchParamsSchema.parse(args);
131
+ const { content, structuredContent } = await handleWebSearch(validatedParams);
132
+ if (structuredContent.metadata.total_results === 0) {
133
+ return { content: [{ type: 'text', text: content }], isError: true };
134
+ }
135
+ return { content: [{ type: 'text', text: content }] };
136
+ }
137
+ return { content: [{ type: 'text', text: `⚠️ **Unknown tool:** \`${name}\`\n\nAvailable tools: search_reddit, get_reddit_post, deep_research, scrape_links, web_search` }], isError: true };
138
+ }
139
+ catch (error) {
140
+ const simpleError = createSimpleError(error);
141
+ // Format error as helpful markdown
142
+ const errorText = `## ❌ Error\n\n**${simpleError.code}:** ${simpleError.message}\n\nPlease check your input parameters and try again.`;
143
+ return { content: [{ type: 'text', text: errorText }], isError: true };
144
+ }
145
+ });
146
+ // ============================================================================
147
+ // Start Server
148
+ // ============================================================================
149
+ const transport = new StdioServerTransport();
150
+ server.connect(transport);
151
+ console.error(`🚀 ${SERVER.NAME} v${SERVER.VERSION} ready`);
152
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Deep research schema - batch research with dynamic token allocation
3
+ */
4
+ import { z } from 'zod';
5
+ export declare const deepResearchParamsShape: {
6
+ questions: z.ZodArray<z.ZodObject<{
7
+ question: z.ZodString;
8
+ file_attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
9
+ path: z.ZodString;
10
+ start_line: z.ZodOptional<z.ZodNumber>;
11
+ end_line: z.ZodOptional<z.ZodNumber>;
12
+ description: z.ZodOptional<z.ZodString>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ path: string;
15
+ start_line?: number | undefined;
16
+ end_line?: number | undefined;
17
+ description?: string | undefined;
18
+ }, {
19
+ path: string;
20
+ start_line?: number | undefined;
21
+ end_line?: number | undefined;
22
+ description?: string | undefined;
23
+ }>, "many">>;
24
+ }, "strip", z.ZodTypeAny, {
25
+ question: string;
26
+ file_attachments?: {
27
+ path: string;
28
+ start_line?: number | undefined;
29
+ end_line?: number | undefined;
30
+ description?: string | undefined;
31
+ }[] | undefined;
32
+ }, {
33
+ question: string;
34
+ file_attachments?: {
35
+ path: string;
36
+ start_line?: number | undefined;
37
+ end_line?: number | undefined;
38
+ description?: string | undefined;
39
+ }[] | undefined;
40
+ }>, "many">;
41
+ };
42
+ export declare const deepResearchParamsSchema: z.ZodObject<{
43
+ questions: z.ZodArray<z.ZodObject<{
44
+ question: z.ZodString;
45
+ file_attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
46
+ path: z.ZodString;
47
+ start_line: z.ZodOptional<z.ZodNumber>;
48
+ end_line: z.ZodOptional<z.ZodNumber>;
49
+ description: z.ZodOptional<z.ZodString>;
50
+ }, "strip", z.ZodTypeAny, {
51
+ path: string;
52
+ start_line?: number | undefined;
53
+ end_line?: number | undefined;
54
+ description?: string | undefined;
55
+ }, {
56
+ path: string;
57
+ start_line?: number | undefined;
58
+ end_line?: number | undefined;
59
+ description?: string | undefined;
60
+ }>, "many">>;
61
+ }, "strip", z.ZodTypeAny, {
62
+ question: string;
63
+ file_attachments?: {
64
+ path: string;
65
+ start_line?: number | undefined;
66
+ end_line?: number | undefined;
67
+ description?: string | undefined;
68
+ }[] | undefined;
69
+ }, {
70
+ question: string;
71
+ file_attachments?: {
72
+ path: string;
73
+ start_line?: number | undefined;
74
+ end_line?: number | undefined;
75
+ description?: string | undefined;
76
+ }[] | undefined;
77
+ }>, "many">;
78
+ }, "strip", z.ZodTypeAny, {
79
+ questions: {
80
+ question: string;
81
+ file_attachments?: {
82
+ path: string;
83
+ start_line?: number | undefined;
84
+ end_line?: number | undefined;
85
+ description?: string | undefined;
86
+ }[] | undefined;
87
+ }[];
88
+ }, {
89
+ questions: {
90
+ question: string;
91
+ file_attachments?: {
92
+ path: string;
93
+ start_line?: number | undefined;
94
+ end_line?: number | undefined;
95
+ description?: string | undefined;
96
+ }[] | undefined;
97
+ }[];
98
+ }>;
99
+ export type DeepResearchParams = z.infer<typeof deepResearchParamsSchema>;
100
+ //# sourceMappingURL=deep-research.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-research.d.ts","sourceRoot":"","sources":["../../src/schemas/deep-research.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoBxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnC,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAoC,CAAC;AAC1E,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Deep research schema - batch research with dynamic token allocation
3
+ */
4
+ import { z } from 'zod';
5
+ const researchQuestionSchema = z.object({
6
+ question: z
7
+ .string()
8
+ .min(10, 'Research question must be at least 10 characters')
9
+ .describe('A specific research question with context, scope, and what you need answered.'),
10
+ file_attachments: z
11
+ .array(z.object({
12
+ path: z.string().describe('File path (absolute or relative)'),
13
+ start_line: z.number().int().positive().optional().describe('Start line (1-indexed)'),
14
+ end_line: z.number().int().positive().optional().describe('End line (1-indexed)'),
15
+ description: z.string().optional().describe('What to focus on'),
16
+ }))
17
+ .optional()
18
+ .describe('Optional file attachments for this specific question'),
19
+ });
20
+ export const deepResearchParamsShape = {
21
+ questions: z
22
+ .array(researchQuestionSchema)
23
+ .min(2, 'Minimum 2 research questions required for comprehensive analysis')
24
+ .max(10, 'Maximum 10 research questions per batch')
25
+ .describe(`**BATCH RESEARCH (2-10 questions) with dynamic token allocation.**
26
+
27
+ **TOKEN BUDGET:** 32,000 tokens distributed across all questions:
28
+ - 2 questions: 16,000 tokens/question (deep dive)
29
+ - 5 questions: 6,400 tokens/question (balanced)
30
+ - 10 questions: 3,200 tokens/question (quick multi-topic scan)
31
+
32
+ **EACH QUESTION SHOULD INCLUDE:**
33
+ 1. **Topic & Why:** What you're researching and what decision it informs
34
+ 2. **Your Understanding:** What you know (so it fills gaps, not repeats)
35
+ 3. **Scope:** Depth needed, format preferred, examples wanted
36
+ 4. **Specific Questions:** 2-5 pointed questions you need answered
37
+
38
+ **BEST PRACTICES:**
39
+ - Use 2-3 questions for deep dives on related topics
40
+ - Use 5-7 questions for broad research across a domain
41
+ - Use 8-10 questions for rapid multi-topic scanning
42
+ - Group related questions together for coherent research
43
+
44
+ **EXAMPLE:**
45
+ \`\`\`json
46
+ {
47
+ "questions": [
48
+ { "question": "What are best practices for MCP server authentication in TypeScript? Cover OAuth2, API keys, session management. Include code examples." },
49
+ { "question": "How do production MCP servers handle rate limiting and error recovery? Looking for patterns from Anthropic, Microsoft, and community servers." }
50
+ ]
51
+ }
52
+ \`\`\`
53
+
54
+ Maximize question count for comprehensive coverage. Each question runs in parallel.`),
55
+ };
56
+ export const deepResearchParamsSchema = z.object(deepResearchParamsShape);
57
+ //# sourceMappingURL=deep-research.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-research.js","sourceRoot":"","sources":["../../src/schemas/deep-research.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,EAAE,EAAE,kDAAkD,CAAC;SAC3D,QAAQ,CAAC,+EAA+E,CAAC;IAC5F,gBAAgB,EAAE,CAAC;SAChB,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QAC7D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QACrF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACjF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;KAChE,CAAC,CACH;SACA,QAAQ,EAAE;SACV,QAAQ,CAAC,sDAAsD,CAAC;CACpE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAAE,CAAC;SACT,KAAK,CAAC,sBAAsB,CAAC;SAC7B,GAAG,CAAC,CAAC,EAAE,kEAAkE,CAAC;SAC1E,GAAG,CAAC,EAAE,EAAE,yCAAyC,CAAC;SAClD,QAAQ,CACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oFA6B8E,CAC/E;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { z } from 'zod';
2
+ export declare const scrapeLinksParamsShape: {
3
+ urls: z.ZodArray<z.ZodString, "many">;
4
+ timeout: z.ZodDefault<z.ZodNumber>;
5
+ use_llm: z.ZodDefault<z.ZodBoolean>;
6
+ what_to_extract: z.ZodOptional<z.ZodString>;
7
+ };
8
+ export declare const scrapeLinksParamsSchema: z.ZodObject<{
9
+ urls: z.ZodArray<z.ZodString, "many">;
10
+ timeout: z.ZodDefault<z.ZodNumber>;
11
+ use_llm: z.ZodDefault<z.ZodBoolean>;
12
+ what_to_extract: z.ZodOptional<z.ZodString>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ urls: string[];
15
+ timeout: number;
16
+ use_llm: boolean;
17
+ what_to_extract?: string | undefined;
18
+ }, {
19
+ urls: string[];
20
+ timeout?: number | undefined;
21
+ use_llm?: boolean | undefined;
22
+ what_to_extract?: string | undefined;
23
+ }>;
24
+ export type ScrapeLinksParams = z.infer<typeof scrapeLinksParamsSchema>;
25
+ export interface ScrapeLinksOutput {
26
+ content: string;
27
+ metadata: {
28
+ total_urls: number;
29
+ successful: number;
30
+ failed: number;
31
+ total_credits: number;
32
+ execution_time_ms: number;
33
+ tokens_per_url?: number;
34
+ total_token_budget?: number;
35
+ batches_processed?: number;
36
+ };
37
+ }
38
+ //# sourceMappingURL=scrape-links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrape-links.d.ts","sourceRoot":"","sources":["../../src/schemas/scrape-links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,sBAAsB;;;;;CAqBlC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;EAAmC,CAAC;AACxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAGxE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CACH"}