research-powerpack-mcp 3.5.0 → 3.6.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 +674 -63
- package/dist/clients/reddit.d.ts +6 -1
- package/dist/clients/reddit.d.ts.map +1 -1
- package/dist/clients/reddit.js +60 -24
- package/dist/clients/reddit.js.map +1 -1
- package/dist/clients/scraper.d.ts +6 -1
- package/dist/clients/scraper.d.ts.map +1 -1
- package/dist/clients/scraper.js +71 -33
- package/dist/clients/scraper.js.map +1 -1
- package/dist/clients/search.d.ts +2 -2
- package/dist/clients/search.d.ts.map +1 -1
- package/dist/clients/search.js +11 -6
- package/dist/clients/search.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +5 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +6 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/index.js +28 -86
- package/dist/index.js.map +1 -1
- package/dist/schemas/web-search.js +1 -1
- package/dist/schemas/web-search.js.map +1 -1
- package/dist/services/file-attachment.d.ts.map +1 -1
- package/dist/services/file-attachment.js +25 -22
- package/dist/services/file-attachment.js.map +1 -1
- package/dist/tools/reddit.d.ts.map +1 -1
- package/dist/tools/reddit.js +43 -55
- package/dist/tools/reddit.js.map +1 -1
- package/dist/tools/registry.js +2 -2
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/research.d.ts +1 -2
- package/dist/tools/research.d.ts.map +1 -1
- package/dist/tools/research.js +69 -59
- package/dist/tools/research.js.map +1 -1
- package/dist/tools/scrape.d.ts +1 -2
- package/dist/tools/scrape.d.ts.map +1 -1
- package/dist/tools/scrape.js +63 -94
- package/dist/tools/scrape.js.map +1 -1
- package/dist/tools/search.d.ts +1 -2
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +19 -21
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/utils.d.ts +68 -16
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +75 -22
- package/dist/tools/utils.js.map +1 -1
- package/dist/utils/concurrency.d.ts +29 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +73 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/logger.d.ts +21 -25
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +27 -24
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mcp-logger.d.ts +8 -0
- package/dist/utils/mcp-logger.d.ts.map +1 -0
- package/dist/utils/mcp-logger.js +14 -0
- package/dist/utils/mcp-logger.js.map +1 -0
- package/dist/utils/response.d.ts +49 -62
- package/dist/utils/response.d.ts.map +1 -1
- package/dist/utils/response.js +102 -134
- package/dist/utils/response.js.map +1 -1
- package/dist/utils/url-aggregator.d.ts.map +1 -1
- package/dist/utils/url-aggregator.js +6 -4
- package/dist/utils/url-aggregator.js.map +1 -1
- package/package.json +2 -8
package/dist/config/loader.js
CHANGED
|
@@ -11,6 +11,8 @@ import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
|
11
11
|
// Get directory of this file for relative YAML path
|
|
12
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
13
|
const __dirname = dirname(__filename);
|
|
14
|
+
// Cached YAML config - loaded once, reused for all subsequent calls
|
|
15
|
+
let cachedYamlConfig = null;
|
|
14
16
|
// ============================================================================
|
|
15
17
|
// YAML to Zod Schema Conversion
|
|
16
18
|
// ============================================================================
|
|
@@ -173,9 +175,12 @@ function zodToMcpInputSchema(schema) {
|
|
|
173
175
|
* Load and parse tools.yaml
|
|
174
176
|
*/
|
|
175
177
|
export function loadYamlConfig() {
|
|
178
|
+
if (cachedYamlConfig)
|
|
179
|
+
return cachedYamlConfig;
|
|
176
180
|
const yamlPath = join(__dirname, 'yaml', 'tools.yaml');
|
|
177
181
|
const yamlContent = readFileSync(yamlPath, 'utf8');
|
|
178
|
-
|
|
182
|
+
cachedYamlConfig = parseYaml(yamlContent);
|
|
183
|
+
return cachedYamlConfig;
|
|
179
184
|
}
|
|
180
185
|
/**
|
|
181
186
|
* Convert a single YAML tool config to MCP Tool
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { TOOLS } from './tools/definitions.js';
|
|
|
10
10
|
import { executeTool, getToolCapabilities } from './tools/registry.js';
|
|
11
11
|
import { classifyError, createToolErrorFromStructured } from './utils/errors.js';
|
|
12
12
|
import { SERVER, getCapabilities } from './config/index.js';
|
|
13
|
+
import { initLogger } from './utils/mcp-logger.js';
|
|
13
14
|
// ============================================================================
|
|
14
15
|
// Capability Detection (uses registry for tool capability mapping)
|
|
15
16
|
// ============================================================================
|
|
@@ -27,7 +28,8 @@ if (capabilities.scraping && !capabilities.llmExtraction) {
|
|
|
27
28
|
// ============================================================================
|
|
28
29
|
// Server Setup
|
|
29
30
|
// ============================================================================
|
|
30
|
-
const server = new Server({ name: SERVER.NAME, version: SERVER.VERSION }, { capabilities: { tools: {} } });
|
|
31
|
+
const server = new Server({ name: SERVER.NAME, version: SERVER.VERSION }, { capabilities: { tools: {}, logging: {} } });
|
|
32
|
+
initLogger(server);
|
|
31
33
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
32
34
|
/**
|
|
33
35
|
* Tool execution handler - uses registry pattern for clean routing
|
|
@@ -61,130 +63,70 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
61
63
|
// Track shutdown state to prevent double shutdown
|
|
62
64
|
let isShuttingDown = false;
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* ERR_STREAM_DESTROYED / write-after-end). This helper swallows those errors
|
|
67
|
-
* so that shutdown code paths never enter an infinite exception loop.
|
|
68
|
-
*/
|
|
69
|
-
function safeStderrWrite(msg) {
|
|
70
|
-
try {
|
|
71
|
-
process.stderr.write(msg + '\n');
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
// stderr is dead — silently discard. Nothing we can do.
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Graceful shutdown handler - closes server and exits.
|
|
79
|
-
*
|
|
80
|
-
* IMPORTANT: This function guarantees process.exit() is always reached by:
|
|
81
|
-
* 1. Using safeStderrWrite instead of console.error (prevents throw on dead FD)
|
|
82
|
-
* 2. Setting a hard 2-second deadline via setTimeout + process.exit()
|
|
83
|
-
* 3. Calling process.exit() synchronously on re-entrant calls instead of
|
|
84
|
-
* silently returning (prevents the "isShuttingDown guard eats the exit" bug)
|
|
66
|
+
* Graceful shutdown handler - closes server and exits
|
|
67
|
+
* @param exitCode - Exit code (0 for clean shutdown, 1 for error)
|
|
85
68
|
*/
|
|
86
69
|
async function gracefulShutdown(exitCode) {
|
|
87
|
-
if (isShuttingDown)
|
|
88
|
-
|
|
89
|
-
// Returning here was the original bug: the first call could be stuck in
|
|
90
|
-
// await server.close(), and all subsequent calls would return without
|
|
91
|
-
// ever reaching process.exit().
|
|
92
|
-
process.exit(exitCode);
|
|
93
|
-
return; // unreachable, but satisfies TypeScript
|
|
94
|
-
}
|
|
70
|
+
if (isShuttingDown)
|
|
71
|
+
return;
|
|
95
72
|
isShuttingDown = true;
|
|
96
|
-
// Hard deadline: if server.close() hangs or anything else goes wrong,
|
|
97
|
-
// force-exit after 2 seconds. unref() so this timer doesn't keep the
|
|
98
|
-
// event loop alive on its own.
|
|
99
|
-
const forceExitTimer = setTimeout(() => {
|
|
100
|
-
process.exit(exitCode);
|
|
101
|
-
}, 2000);
|
|
102
|
-
forceExitTimer.unref();
|
|
103
73
|
try {
|
|
104
74
|
await server.close();
|
|
105
|
-
|
|
75
|
+
console.error(`[MCP Server] Server closed at ${new Date().toISOString()}`);
|
|
106
76
|
}
|
|
107
|
-
catch {
|
|
108
|
-
|
|
77
|
+
catch (closeError) {
|
|
78
|
+
console.error('[MCP Server] Error closing server:', closeError);
|
|
109
79
|
}
|
|
110
80
|
finally {
|
|
111
81
|
process.exit(exitCode);
|
|
112
82
|
}
|
|
113
83
|
}
|
|
114
84
|
// Handle uncaught exceptions - MUST EXIT per Node.js docs
|
|
115
|
-
// The VM is in an unstable state after uncaught exception
|
|
116
|
-
//
|
|
117
|
-
// CRITICAL: This handler must NEVER call console.error() because stderr may
|
|
118
|
-
// be a dead unix socket. Writing to a dead socket throws a NEW uncaught
|
|
119
|
-
// exception, creating an infinite loop that consumes 60%+ CPU forever.
|
|
120
|
-
// Instead, we use safeStderrWrite and call process.exit() synchronously.
|
|
85
|
+
// The VM is in an unstable state after uncaught exception
|
|
121
86
|
process.on('uncaughtException', (error) => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// normal operation after 'uncaughtException'."
|
|
127
|
-
process.exit(1);
|
|
87
|
+
console.error(`[MCP Server] FATAL uncaughtException at ${new Date().toISOString()}:`);
|
|
88
|
+
console.error(` Message: ${error.message}`);
|
|
89
|
+
console.error(` Stack: ${error.stack}`);
|
|
90
|
+
gracefulShutdown(1);
|
|
128
91
|
});
|
|
129
92
|
// Handle unhandled promise rejections - MUST EXIT (Node v15+ behavior)
|
|
130
93
|
// Suppressing this risks memory leaks and corrupted state
|
|
131
94
|
process.on('unhandledRejection', (reason) => {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
95
|
+
const error = classifyError(reason);
|
|
96
|
+
console.error(`[MCP Server] FATAL unhandledRejection at ${new Date().toISOString()}:`);
|
|
97
|
+
console.error(` Message: ${error.message}`);
|
|
98
|
+
console.error(` Code: ${error.code}`);
|
|
99
|
+
gracefulShutdown(1);
|
|
136
100
|
});
|
|
137
101
|
// Handle SIGTERM gracefully (Docker/Kubernetes stop signal)
|
|
138
102
|
process.on('SIGTERM', () => {
|
|
139
|
-
|
|
103
|
+
console.error(`[MCP Server] Received SIGTERM at ${new Date().toISOString()}, shutting down gracefully`);
|
|
140
104
|
gracefulShutdown(0);
|
|
141
105
|
});
|
|
142
106
|
// Handle SIGINT gracefully (Ctrl+C) - use once() to prevent double-fire
|
|
143
107
|
process.once('SIGINT', () => {
|
|
144
|
-
|
|
108
|
+
console.error(`[MCP Server] Received SIGINT at ${new Date().toISOString()}, shutting down gracefully`);
|
|
145
109
|
gracefulShutdown(0);
|
|
146
110
|
});
|
|
147
111
|
// ============================================================================
|
|
148
112
|
// Stdin disconnect detection
|
|
149
|
-
//
|
|
150
113
|
// The MCP SDK's StdioServerTransport does NOT listen for stdin 'close'/'end'.
|
|
151
114
|
// When the parent process disconnects (closes the pipe), stdin emits these
|
|
152
|
-
// events but nobody handles them — Node.js keeps polling the dead fd
|
|
153
|
-
//
|
|
154
|
-
// HOWEVER: When FD 0 is a unix domain socket (as when spawned via `npx`),
|
|
155
|
-
// 'close'/'end' events may NOT fire reliably on macOS. To handle this case,
|
|
156
|
-
// we also poll stdin every 5 seconds using a read() probe. If the read
|
|
157
|
-
// returns null AND stdin has ended, we trigger shutdown.
|
|
115
|
+
// events but nobody handles them — Node.js keeps polling the dead fd at 100%
|
|
116
|
+
// CPU. We fix this by detecting the disconnect and exiting cleanly.
|
|
158
117
|
// ============================================================================
|
|
159
118
|
process.stdin.on('close', () => {
|
|
160
|
-
|
|
119
|
+
console.error(`[MCP Server] stdin closed (parent disconnected) at ${new Date().toISOString()}, shutting down`);
|
|
161
120
|
gracefulShutdown(0);
|
|
162
121
|
});
|
|
163
122
|
process.stdin.on('end', () => {
|
|
164
|
-
|
|
165
|
-
gracefulShutdown(0);
|
|
166
|
-
});
|
|
167
|
-
// Periodic stdin liveness check for unix domain sockets where 'close'/'end'
|
|
168
|
-
// don't fire. If stdin becomes unreadable, the parent is gone.
|
|
169
|
-
const stdinWatchdog = setInterval(() => {
|
|
170
|
-
// readableEnded is true once the 'end' event has been emitted.
|
|
171
|
-
// destroyed is true if the stream has been explicitly destroyed.
|
|
172
|
-
if (process.stdin.readableEnded || process.stdin.destroyed) {
|
|
173
|
-
safeStderrWrite(`[MCP Server] stdin watchdog: stream ended/destroyed, shutting down`);
|
|
174
|
-
gracefulShutdown(0);
|
|
175
|
-
}
|
|
176
|
-
}, 5000);
|
|
177
|
-
stdinWatchdog.unref(); // Don't let this timer keep the process alive
|
|
178
|
-
// Also handle stderr errors — prevents throws from propagating into
|
|
179
|
-
// uncaughtException when stderr is dead
|
|
180
|
-
process.stderr.on('error', () => {
|
|
181
|
-
// stderr is dead. Trigger shutdown without trying to log.
|
|
123
|
+
console.error(`[MCP Server] stdin ended (parent disconnected) at ${new Date().toISOString()}, shutting down`);
|
|
182
124
|
gracefulShutdown(0);
|
|
183
125
|
});
|
|
184
|
-
//
|
|
126
|
+
// Also handle stdout errors (broken pipe when parent is gone)
|
|
185
127
|
process.stdout.on('error', (err) => {
|
|
186
128
|
if (err.code === 'EPIPE' || err.code === 'ERR_STREAM_DESTROYED') {
|
|
187
|
-
|
|
129
|
+
console.error(`[MCP Server] stdout broken pipe at ${new Date().toISOString()}, shutting down`);
|
|
188
130
|
gracefulShutdown(0);
|
|
189
131
|
}
|
|
190
132
|
});
|
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,MAAM,oCAAoC,CAAC;AAE7G,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ 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(3, { message: 'web_search: MINIMUM 3 keywords required.
|
|
14
|
+
.min(3, { message: 'web_search: MINIMUM 3 keywords required. Add more diverse keywords covering different perspectives.' })
|
|
15
15
|
.max(100, { message: 'web_search: Maximum 100 keywords allowed per request' })
|
|
16
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 = {
|
|
@@ -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,qGAAqG,EAAE,CAAC;KAC1H,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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-attachment.d.ts","sourceRoot":"","sources":["../../src/services/file-attachment.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AASD,qBAAa,qBAAqB;IAChC;;OAEG;IACG,iBAAiB,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"file-attachment.d.ts","sourceRoot":"","sources":["../../src/services/file-attachment.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AASD,qBAAa,qBAAqB;IAChC;;OAEG;IACG,iBAAiB,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBvE;;OAEG;YACW,gBAAgB;IAsE9B;;OAEG;IACH,OAAO,CAAC,eAAe;IAiCvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoEzB,OAAO,CAAC,cAAc;CAcvB"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* File attachment service for reading and formatting file contents
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { access, readFile } from 'node:fs/promises';
|
|
6
5
|
import { extname } from 'node:path';
|
|
6
|
+
import { pMap } from '../utils/concurrency.js';
|
|
7
7
|
export class FileAttachmentService {
|
|
8
8
|
/**
|
|
9
9
|
* Format multiple file attachments into a markdown section
|
|
@@ -12,15 +12,15 @@ export class FileAttachmentService {
|
|
|
12
12
|
if (!attachments || attachments.length === 0) {
|
|
13
13
|
return '';
|
|
14
14
|
}
|
|
15
|
-
const results = await
|
|
15
|
+
const results = await pMap(attachments, (attachment) => this.formatSingleFile(attachment), 5);
|
|
16
16
|
// Build the attachments section
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const parts = ['\n\n---\n\n# 📎 ATTACHED FILES\n\n'];
|
|
18
|
+
parts.push(`*${results.length} file${results.length > 1 ? 's' : ''} attached for context*\n\n`);
|
|
19
19
|
for (const result of results) {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
parts.push(result.content);
|
|
21
|
+
parts.push('\n\n');
|
|
22
22
|
}
|
|
23
|
-
return
|
|
23
|
+
return parts.join('');
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Format a single file attachment
|
|
@@ -28,7 +28,10 @@ export class FileAttachmentService {
|
|
|
28
28
|
async formatSingleFile(attachment) {
|
|
29
29
|
const { path, start_line, end_line, description } = attachment;
|
|
30
30
|
// Check if file exists
|
|
31
|
-
|
|
31
|
+
try {
|
|
32
|
+
await access(path);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
32
35
|
return {
|
|
33
36
|
success: false,
|
|
34
37
|
path,
|
|
@@ -87,33 +90,33 @@ export class FileAttachmentService {
|
|
|
87
90
|
* Format code block with line numbers and smart truncation
|
|
88
91
|
*/
|
|
89
92
|
formatCodeBlock(lines, language, startIdx) {
|
|
90
|
-
|
|
93
|
+
const parts = [`\`\`\`${language.toLowerCase()}\n`];
|
|
91
94
|
// Smart truncation for very large files (keep first 500 lines + last 100 lines)
|
|
92
95
|
if (lines.length > 600) {
|
|
93
96
|
// First 500 lines
|
|
94
97
|
const firstLines = lines.slice(0, 500);
|
|
95
|
-
firstLines.
|
|
98
|
+
for (let idx = 0; idx < firstLines.length; idx++) {
|
|
96
99
|
const lineNumber = startIdx + idx + 1;
|
|
97
|
-
|
|
98
|
-
}
|
|
100
|
+
parts.push(`${lineNumber.toString().padStart(4, ' ')}: ${firstLines[idx]}\n`);
|
|
101
|
+
}
|
|
99
102
|
// Truncation marker
|
|
100
|
-
|
|
103
|
+
parts.push(`\n... [${lines.length - 600} lines truncated for brevity] ...\n\n`);
|
|
101
104
|
// Last 100 lines
|
|
102
105
|
const lastLines = lines.slice(-100);
|
|
103
|
-
lastLines.
|
|
106
|
+
for (let idx = 0; idx < lastLines.length; idx++) {
|
|
104
107
|
const lineNumber = startIdx + lines.length - 100 + idx + 1;
|
|
105
|
-
|
|
106
|
-
}
|
|
108
|
+
parts.push(`${lineNumber.toString().padStart(4, ' ')}: ${lastLines[idx]}\n`);
|
|
109
|
+
}
|
|
107
110
|
}
|
|
108
111
|
else {
|
|
109
112
|
// Show all lines with numbers
|
|
110
|
-
lines.
|
|
113
|
+
for (let idx = 0; idx < lines.length; idx++) {
|
|
111
114
|
const lineNumber = startIdx + idx + 1;
|
|
112
|
-
|
|
113
|
-
}
|
|
115
|
+
parts.push(`${lineNumber.toString().padStart(4, ' ')}: ${lines[idx]}\n`);
|
|
116
|
+
}
|
|
114
117
|
}
|
|
115
|
-
|
|
116
|
-
return
|
|
118
|
+
parts.push('```');
|
|
119
|
+
return parts.join('');
|
|
117
120
|
}
|
|
118
121
|
/**
|
|
119
122
|
* Validate line range and return corrected values
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-attachment.js","sourceRoot":"","sources":["../../src/services/file-attachment.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"file-attachment.js","sourceRoot":"","sources":["../../src/services/file-attachment.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reddit.d.ts","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"reddit.d.ts","sourceRoot":"","sources":["../../src/tools/reddit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0DH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CA6CjB;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;AAyBD,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,CAmHjB"}
|
package/dist/tools/reddit.js
CHANGED
|
@@ -9,7 +9,7 @@ import { REDDIT } from '../config/index.js';
|
|
|
9
9
|
import { classifyError } from '../utils/errors.js';
|
|
10
10
|
import { createLLMProcessor, processContentWithLLM } from '../services/llm-processor.js';
|
|
11
11
|
import { getToolConfig } from '../config/loader.js';
|
|
12
|
-
import { formatSuccess, formatError, formatBatchHeader, TOKEN_BUDGETS, } from './utils.js';
|
|
12
|
+
import { mcpLog, formatSuccess, formatError, formatBatchHeader, TOKEN_BUDGETS, } from './utils.js';
|
|
13
13
|
// ============================================================================
|
|
14
14
|
// Formatters
|
|
15
15
|
// ============================================================================
|
|
@@ -56,13 +56,18 @@ export async function handleSearchReddit(queries, apiKey, dateAfter) {
|
|
|
56
56
|
totalResults += items.length;
|
|
57
57
|
}
|
|
58
58
|
if (totalResults === 0) {
|
|
59
|
-
return
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
'
|
|
65
|
-
'
|
|
59
|
+
return formatError({
|
|
60
|
+
code: 'NO_RESULTS',
|
|
61
|
+
message: `No results found for any of the ${limited.length} queries`,
|
|
62
|
+
toolName: 'search_reddit',
|
|
63
|
+
howToFix: [
|
|
64
|
+
'Try broader or simpler search terms',
|
|
65
|
+
'Check spelling of technical terms',
|
|
66
|
+
'Remove date filters if using them',
|
|
67
|
+
],
|
|
68
|
+
alternatives: [
|
|
69
|
+
'web_search(keywords=[...]) for general web results',
|
|
70
|
+
'deep_research(questions=[...]) for synthesized analysis',
|
|
66
71
|
],
|
|
67
72
|
});
|
|
68
73
|
}
|
|
@@ -78,8 +83,8 @@ export async function handleSearchReddit(queries, apiKey, dateAfter) {
|
|
|
78
83
|
message: structuredError.message,
|
|
79
84
|
retryable: structuredError.retryable,
|
|
80
85
|
toolName: 'search_reddit',
|
|
81
|
-
howToFix: ['
|
|
82
|
-
alternatives: ['
|
|
86
|
+
howToFix: ['Verify SERPER_API_KEY is set correctly'],
|
|
87
|
+
alternatives: ['web_search(keywords=[...]) as backup'],
|
|
83
88
|
});
|
|
84
89
|
}
|
|
85
90
|
}
|
|
@@ -109,18 +114,16 @@ export async function handleGetRedditPosts(urls, clientId, clientSecret, maxComm
|
|
|
109
114
|
const { fetchComments = true, maxCommentsOverride, use_llm = false, what_to_extract } = options;
|
|
110
115
|
if (urls.length < REDDIT.MIN_POSTS) {
|
|
111
116
|
return formatError({
|
|
112
|
-
code: '
|
|
117
|
+
code: 'MIN_POSTS',
|
|
113
118
|
message: `Minimum ${REDDIT.MIN_POSTS} Reddit posts required. Received: ${urls.length}`,
|
|
114
|
-
retryable: false,
|
|
115
119
|
toolName: 'get_reddit_post',
|
|
116
|
-
howToFix: [`Add at least ${REDDIT.MIN_POSTS - urls.length} more
|
|
120
|
+
howToFix: [`Add at least ${REDDIT.MIN_POSTS - urls.length} more Reddit URL(s)`],
|
|
117
121
|
});
|
|
118
122
|
}
|
|
119
123
|
if (urls.length > REDDIT.MAX_POSTS) {
|
|
120
124
|
return formatError({
|
|
121
|
-
code: '
|
|
125
|
+
code: 'MAX_POSTS',
|
|
122
126
|
message: `Maximum ${REDDIT.MAX_POSTS} Reddit posts allowed. Received: ${urls.length}`,
|
|
123
|
-
retryable: false,
|
|
124
127
|
toolName: 'get_reddit_post',
|
|
125
128
|
howToFix: [`Remove ${urls.length - REDDIT.MAX_POSTS} URL(s) and retry`],
|
|
126
129
|
});
|
|
@@ -131,21 +134,10 @@ export async function handleGetRedditPosts(urls, clientId, clientSecret, maxComm
|
|
|
131
134
|
const client = new RedditClient(clientId, clientSecret);
|
|
132
135
|
const batchResult = await client.batchGetPosts(urls, commentsPerPost, fetchComments);
|
|
133
136
|
const results = batchResult.results;
|
|
134
|
-
// Initialize LLM processor if needed
|
|
137
|
+
// Initialize LLM processor if needed
|
|
135
138
|
const llmProcessor = use_llm ? createLLMProcessor() : null;
|
|
136
139
|
const tokensPerUrl = use_llm ? Math.floor(TOKEN_BUDGETS.RESEARCH / urls.length) : 0;
|
|
137
140
|
const enhancedInstruction = use_llm ? enhanceExtractionInstruction(what_to_extract) : undefined;
|
|
138
|
-
// Build header info
|
|
139
|
-
const headerParts = [];
|
|
140
|
-
if (fetchComments) {
|
|
141
|
-
headerParts.push(`**Comment Allocation:** ${commentsPerPost} comments/post (${urls.length} posts, ${REDDIT.MAX_COMMENT_BUDGET} total budget)`);
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
headerParts.push(`**Comments:** Not fetched (fetch_comments=false)`);
|
|
145
|
-
}
|
|
146
|
-
if (use_llm) {
|
|
147
|
-
headerParts.push(`**Token Allocation:** ${tokensPerUrl.toLocaleString()} tokens/post (${urls.length} posts, ${TOKEN_BUDGETS.RESEARCH.toLocaleString()} total budget)`);
|
|
148
|
-
}
|
|
149
141
|
let successful = 0;
|
|
150
142
|
let failed = 0;
|
|
151
143
|
let llmErrors = 0;
|
|
@@ -160,52 +152,49 @@ export async function handleGetRedditPosts(urls, clientId, clientSecret, maxComm
|
|
|
160
152
|
let postContent = formatPost(result, fetchComments);
|
|
161
153
|
// Apply LLM extraction per-URL if enabled
|
|
162
154
|
if (use_llm && llmProcessor) {
|
|
163
|
-
|
|
155
|
+
mcpLog('info', `[${successful}/${urls.length}] Applying LLM extraction to ${url}`, 'reddit');
|
|
164
156
|
const llmResult = await processContentWithLLM(postContent, { use_llm: true, what_to_extract: enhancedInstruction, max_tokens: tokensPerUrl }, llmProcessor);
|
|
165
157
|
if (llmResult.processed) {
|
|
166
158
|
postContent = `## 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${llmResult.content}`;
|
|
167
|
-
|
|
159
|
+
mcpLog('debug', `[${successful}/${urls.length}] LLM extraction complete`, 'reddit');
|
|
168
160
|
}
|
|
169
161
|
else {
|
|
170
162
|
llmErrors++;
|
|
171
|
-
|
|
172
|
-
// Continue with original content - graceful degradation
|
|
163
|
+
mcpLog('warning', `[${successful}/${urls.length}] LLM extraction failed: ${llmResult.error || 'unknown'}`, 'reddit');
|
|
173
164
|
}
|
|
174
165
|
}
|
|
175
166
|
contents.push(postContent);
|
|
176
167
|
}
|
|
177
168
|
}
|
|
178
|
-
// Build
|
|
179
|
-
const statusExtras = [];
|
|
180
|
-
if (batchResult.rateLimitHits > 0) {
|
|
181
|
-
statusExtras.push(`⚠️ ${batchResult.rateLimitHits} rate limit retries`);
|
|
182
|
-
}
|
|
183
|
-
if (use_llm && !llmProcessor) {
|
|
184
|
-
statusExtras.push(`⚠️ LLM unavailable (no API key)`);
|
|
185
|
-
}
|
|
186
|
-
else if (use_llm && llmErrors > 0) {
|
|
187
|
-
statusExtras.push(`⚠️ ${llmErrors} LLM extraction failures`);
|
|
188
|
-
}
|
|
169
|
+
// Build 70/20/10 response
|
|
189
170
|
const batchHeader = formatBatchHeader({
|
|
190
|
-
title:
|
|
171
|
+
title: `Reddit Posts`,
|
|
191
172
|
totalItems: urls.length,
|
|
192
173
|
successful,
|
|
193
174
|
failed,
|
|
175
|
+
...(fetchComments ? { extras: { 'Comments/post': commentsPerPost } } : {}),
|
|
176
|
+
...(use_llm ? { tokensPerItem: tokensPerUrl } : {}),
|
|
194
177
|
batches: totalBatches,
|
|
195
|
-
extras: statusExtras.length > 0 ? statusExtras : undefined,
|
|
196
178
|
});
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
179
|
+
const statusExtras = [];
|
|
180
|
+
if (batchResult.rateLimitHits > 0) {
|
|
181
|
+
statusExtras.push(`⚠️ ${batchResult.rateLimitHits} rate limit retries`);
|
|
182
|
+
}
|
|
183
|
+
if (use_llm && !llmProcessor) {
|
|
184
|
+
statusExtras.push('⚠️ LLM unavailable (OPENROUTER_API_KEY not set)');
|
|
202
185
|
}
|
|
203
|
-
if (
|
|
204
|
-
|
|
186
|
+
else if (llmErrors > 0) {
|
|
187
|
+
statusExtras.push(`⚠️ ${llmErrors} LLM extraction failures`);
|
|
205
188
|
}
|
|
189
|
+
const nextSteps = [
|
|
190
|
+
successful > 0 ? 'Research further: deep_research(questions=[{question: "Based on Reddit discussion..."}])' : null,
|
|
191
|
+
failed > 0 ? 'Retry failed URLs individually' : null,
|
|
192
|
+
'Search related topics: search_reddit(queries=[...related terms...])',
|
|
193
|
+
].filter(Boolean);
|
|
194
|
+
const extraStatus = statusExtras.length > 0 ? `\n${statusExtras.join(' | ')}` : '';
|
|
206
195
|
return formatSuccess({
|
|
207
|
-
title: `Reddit Posts (${urls.length}
|
|
208
|
-
summary:
|
|
196
|
+
title: `Reddit Posts Fetched (${successful}/${urls.length})`,
|
|
197
|
+
summary: batchHeader + extraStatus,
|
|
209
198
|
data: contents.join('\n\n---\n\n'),
|
|
210
199
|
nextSteps,
|
|
211
200
|
});
|
|
@@ -217,8 +206,7 @@ export async function handleGetRedditPosts(urls, clientId, clientSecret, maxComm
|
|
|
217
206
|
message: structuredError.message,
|
|
218
207
|
retryable: structuredError.retryable,
|
|
219
208
|
toolName: 'get_reddit_post',
|
|
220
|
-
howToFix: ['
|
|
221
|
-
alternatives: ['Use scrape_links() as fallback for reading Reddit post content'],
|
|
209
|
+
howToFix: ['Verify REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET are set'],
|
|
222
210
|
});
|
|
223
211
|
}
|
|
224
212
|
}
|