@iflow-mcp/mcp-webresearch 0.1.7

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 The Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # MCP Web Research Server
2
+
3
+ A Model Context Protocol (MCP) server for web research.
4
+
5
+ Bring real-time info into Claude and easily research any topic.
6
+
7
+ ## Features
8
+
9
+ - Google search integration
10
+ - Webpage content extraction
11
+ - Research session tracking (list of visited pages, search queries, etc.)
12
+ - Screenshot capture
13
+
14
+ ## Prerequisites
15
+
16
+ - [Node.js](https://nodejs.org/) >= 18 (includes `npm` and `npx`)
17
+ - [Claude Desktop app](https://claude.ai/download)
18
+
19
+ ## Installation
20
+
21
+ First, ensure you've downloaded and installed the [Claude Desktop app](https://claude.ai/download) and you have npm installed.
22
+
23
+ Next, add this entry to your `claude_desktop_config.json` (on Mac, found at `~/Library/Application\ Support/Claude/claude_desktop_config.json`):
24
+
25
+ ```json
26
+ {
27
+ "mcpServers": {
28
+ "webresearch": {
29
+ "command": "npx",
30
+ "args": ["-y", "@mzxrai/mcp-webresearch@latest"]
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ This config allows Claude Desktop to automatically start the web research MCP server when needed.
37
+
38
+ ## Usage
39
+
40
+ Simply start a chat with Claude and send a prompt that would benefit from web research. If you'd like a prebuilt prompt customized for deeper web research, you can use the `agentic-research` prompt that we provide through this package. Access that prompt in Claude Desktop by clicking the Paperclip icon in the chat input and then selecting `Choose an integration` → `webresearch` → `agentic-research`.
41
+
42
+ <img src="https://i.ibb.co/N6Y3C0q/Screenshot-2024-12-05-at-11-01-27-PM.png" alt="Example screenshot of web research" width="400"/>
43
+
44
+ ### Tools
45
+
46
+ 1. `search_google`
47
+ - Performs Google searches and extracts results
48
+ - Arguments: `{ query: string }`
49
+
50
+ 2. `visit_page`
51
+ - Visits a webpage and extracts its content
52
+ - Arguments: `{ url: string, takeScreenshot?: boolean }`
53
+
54
+ 3. `take_screenshot`
55
+ - Takes a screenshot of the current page
56
+ - No arguments required
57
+
58
+ ### Prompts
59
+
60
+ #### `agentic-research`
61
+ A guided research prompt that helps Claude conduct thorough web research. The prompt instructs Claude to:
62
+ - Start with broad searches to understand the topic landscape
63
+ - Prioritize high-quality, authoritative sources
64
+ - Iteratively refine the research direction based on findings
65
+ - Keep you informed and let you guide the research interactively
66
+ - Always cite sources with URLs
67
+
68
+ ### Resources
69
+
70
+ We expose two things as MCP resources: (1) captured webpage screenshots, and (2) the research session.
71
+
72
+ #### Screenshots
73
+
74
+ When you take a screenshot, it's saved as an MCP resource. You can access captured screenshots in Claude Desktop via the Paperclip icon.
75
+
76
+ #### Research Session
77
+
78
+ The server maintains a research session that includes:
79
+ - Search queries
80
+ - Visited pages
81
+ - Extracted content
82
+ - Screenshots
83
+ - Timestamps
84
+
85
+ ### Suggestions
86
+
87
+ For the best results, if you choose not to use the `agentic-research` prompt when doing your research, it may be helpful to suggest high-quality sources for Claude to use when researching general topics. For example, you could prompt `news today from reuters or AP` instead of `news today`.
88
+
89
+ ## Problems
90
+
91
+ This is very much pre-alpha code. And it is also AIGC, so expect bugs.
92
+
93
+ If you run into issues, it may be helpful to check Claude Desktop's MCP logs:
94
+
95
+ ```bash
96
+ tail -n 20 -f ~/Library/Logs/Claude/mcp*.log
97
+ ```
98
+
99
+ ## Development
100
+
101
+ ```bash
102
+ # Install dependencies
103
+ pnpm install
104
+
105
+ # Build the project
106
+ pnpm build
107
+
108
+ # Watch for changes
109
+ pnpm watch
110
+
111
+ # Run in development mode
112
+ pnpm dev
113
+ ```
114
+
115
+ ## Requirements
116
+
117
+ - Node.js >= 18
118
+ - Playwright (automatically installed as a dependency)
119
+
120
+ ## Verified Platforms
121
+
122
+ - [x] macOS
123
+ - [ ] Linux
124
+
125
+ ## License
126
+
127
+ MIT
128
+
129
+ ## Author
130
+
131
+ [mzxrai](https://github.com/mzxrai)
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,1016 @@
1
+ #!/usr/bin/env node
2
+ // Core dependencies for MCP server and protocol handling
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, McpError, ErrorCode, } from "@modelcontextprotocol/sdk/types.js";
6
+ // Web scraping and content processing dependencies
7
+ import { chromium } from 'playwright';
8
+ import TurndownService from "turndown";
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import * as os from 'os';
12
+ // Initialize temp directory for screenshots
13
+ const SCREENSHOTS_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'mcp-screenshots-'));
14
+ // Initialize Turndown service for converting HTML to Markdown
15
+ // Configure with specific formatting preferences
16
+ const turndownService = new TurndownService({
17
+ headingStyle: 'atx', // Use # style headings
18
+ hr: '---', // Horizontal rule style
19
+ bulletListMarker: '-', // List item marker
20
+ codeBlockStyle: 'fenced', // Use ``` for code blocks
21
+ emDelimiter: '_', // Italics style
22
+ strongDelimiter: '**', // Bold style
23
+ linkStyle: 'inlined', // Use inline links
24
+ });
25
+ // Custom Turndown rules for better content extraction
26
+ // Remove script and style tags completely
27
+ turndownService.addRule('removeScripts', {
28
+ filter: ['script', 'style', 'noscript'],
29
+ replacement: () => ''
30
+ });
31
+ // Preserve link elements with their href attributes
32
+ turndownService.addRule('preserveLinks', {
33
+ filter: 'a',
34
+ replacement: (content, node) => {
35
+ const element = node;
36
+ const href = element.getAttribute('href');
37
+ return href ? `[${content}](${href})` : content;
38
+ }
39
+ });
40
+ // Preserve image elements with their src and alt attributes
41
+ turndownService.addRule('preserveImages', {
42
+ filter: 'img',
43
+ replacement: (content, node) => {
44
+ const element = node;
45
+ const alt = element.getAttribute('alt') || '';
46
+ const src = element.getAttribute('src');
47
+ return src ? `![${alt}](${src})` : '';
48
+ }
49
+ });
50
+ // Screenshot management functions
51
+ async function saveScreenshot(screenshot, title) {
52
+ // Convert screenshot from base64 to buffer
53
+ const buffer = Buffer.from(screenshot, 'base64');
54
+ // Check size before saving
55
+ const MAX_SIZE = 5 * 1024 * 1024; // 5MB
56
+ if (buffer.length > MAX_SIZE) {
57
+ throw new McpError(ErrorCode.InvalidRequest, `Screenshot too large: ${Math.round(buffer.length / (1024 * 1024))}MB exceeds ${MAX_SIZE / (1024 * 1024)}MB limit`);
58
+ }
59
+ // Generate a safe filename
60
+ const timestamp = new Date().getTime();
61
+ const safeTitle = title.replace(/[^a-z0-9]/gi, '_').toLowerCase();
62
+ const filename = `${safeTitle}-${timestamp}.png`;
63
+ const filepath = path.join(SCREENSHOTS_DIR, filename);
64
+ // Save the validated screenshot
65
+ await fs.promises.writeFile(filepath, buffer);
66
+ // Return the filepath to the saved screenshot
67
+ return filepath;
68
+ }
69
+ // Cleanup function to remove all screenshots from disk
70
+ async function cleanupScreenshots() {
71
+ try {
72
+ // Remove all files in the screenshots directory
73
+ const files = await fs.promises.readdir(SCREENSHOTS_DIR);
74
+ await Promise.all(files.map(file => fs.promises.unlink(path.join(SCREENSHOTS_DIR, file))));
75
+ // Remove the directory itself
76
+ await fs.promises.rmdir(SCREENSHOTS_DIR);
77
+ }
78
+ catch (error) {
79
+ console.error('Error cleaning up screenshots:', error);
80
+ }
81
+ }
82
+ // Available tools for web research functionality
83
+ const TOOLS = [
84
+ {
85
+ name: "search_google",
86
+ description: "Search Google for a query",
87
+ inputSchema: {
88
+ type: "object",
89
+ properties: {
90
+ query: { type: "string", description: "Search query" },
91
+ },
92
+ required: ["query"],
93
+ },
94
+ },
95
+ {
96
+ name: "visit_page",
97
+ description: "Visit a webpage and extract its content",
98
+ inputSchema: {
99
+ type: "object",
100
+ properties: {
101
+ url: { type: "string", description: "URL to visit" },
102
+ takeScreenshot: { type: "boolean", description: "Whether to take a screenshot" },
103
+ },
104
+ required: ["url"],
105
+ },
106
+ },
107
+ {
108
+ name: "take_screenshot",
109
+ description: "Take a screenshot of the current page",
110
+ inputSchema: {
111
+ type: "object",
112
+ properties: {}, // No parameters needed
113
+ },
114
+ },
115
+ ];
116
+ // Configure available prompts with their specifications
117
+ const PROMPTS = {
118
+ // Agentic research prompt configuration
119
+ "agentic-research": {
120
+ name: "agentic-research", // Type-safe name
121
+ description: "Conduct iterative web research on a topic, exploring it thoroughly through multiple steps while maintaining a dialogue with the user",
122
+ arguments: [
123
+ {
124
+ name: "topic", // Topic argument specification
125
+ description: "The topic or question to research", // Description of the argument
126
+ required: true // Topic is mandatory
127
+ }
128
+ ]
129
+ }
130
+ }; // Make object immutable
131
+ // Global state management for browser and research session
132
+ let browser; // Puppeteer browser instance
133
+ let page; // Current active page
134
+ let currentSession; // Current research session data
135
+ // Configuration constants for session management
136
+ const MAX_RESULTS_PER_SESSION = 100; // Maximum number of results to store per session
137
+ const MAX_RETRIES = 3; // Maximum retry attempts for operations
138
+ const RETRY_DELAY = 1000; // Delay between retries in milliseconds
139
+ // Generic retry mechanism for handling transient failures
140
+ async function withRetry(operation, // Operation to retry
141
+ retries = MAX_RETRIES, // Number of retry attempts
142
+ delay = RETRY_DELAY // Delay between retries
143
+ ) {
144
+ let lastError;
145
+ // Attempt operation up to max retries
146
+ for (let i = 0; i < retries; i++) {
147
+ try {
148
+ return await operation();
149
+ }
150
+ catch (error) {
151
+ lastError = error;
152
+ if (i < retries - 1) {
153
+ console.error(`Attempt ${i + 1} failed, retrying in ${delay}ms:`, error);
154
+ await new Promise(resolve => setTimeout(resolve, delay));
155
+ }
156
+ }
157
+ }
158
+ throw lastError; // Throw last error if all retries failed
159
+ }
160
+ // Add a new research result to the current session with data management
161
+ function addResult(result) {
162
+ // If no current session exists, initialize a new one
163
+ if (!currentSession) {
164
+ currentSession = {
165
+ query: "Research Session",
166
+ results: [],
167
+ lastUpdated: new Date().toISOString(),
168
+ };
169
+ }
170
+ // If the session has reached the maximum number of results, remove the oldest result
171
+ if (currentSession.results.length >= MAX_RESULTS_PER_SESSION) {
172
+ currentSession.results.shift();
173
+ }
174
+ // Add the new result to the session and update the last updated timestamp
175
+ currentSession.results.push(result);
176
+ currentSession.lastUpdated = new Date().toISOString();
177
+ }
178
+ /**
179
+ * Specifically handles Google's consent dialog in regions that require it
180
+ * @param page - Playwright Page object
181
+ */
182
+ async function dismissGoogleConsent(page) {
183
+ // Regions that commonly show cookie/consent banners
184
+ const regions = [
185
+ // Europe
186
+ '.google.de', '.google.fr', '.google.co.uk',
187
+ '.google.it', '.google.es', '.google.nl',
188
+ '.google.pl', '.google.ie', '.google.dk',
189
+ '.google.no', '.google.se', '.google.fi',
190
+ '.google.at', '.google.ch', '.google.be',
191
+ '.google.pt', '.google.gr', '.google.com.tr',
192
+ // Asia Pacific
193
+ '.google.co.id', '.google.com.sg', '.google.co.th',
194
+ '.google.com.my', '.google.com.ph', '.google.com.au',
195
+ '.google.co.nz', '.google.com.vn',
196
+ // Generic domains
197
+ '.google.com', '.google.co'
198
+ ];
199
+ try {
200
+ // Get current URL
201
+ const currentUrl = page.url();
202
+ // Skip consent check if not in a supported region
203
+ if (!regions.some(domain => currentUrl.includes(domain))) {
204
+ return;
205
+ }
206
+ // Quick check for consent dialog existence
207
+ const hasConsent = await page.$('form:has(button[aria-label]), div[aria-modal="true"], ' +
208
+ // Common dialog containers
209
+ 'div[role="dialog"], div[role="alertdialog"], ' +
210
+ // Common cookie/consent specific elements
211
+ 'div[class*="consent"], div[id*="consent"], ' +
212
+ 'div[class*="cookie"], div[id*="cookie"], ' +
213
+ // Common modal/popup classes
214
+ 'div[class*="modal"]:has(button), div[class*="popup"]:has(button), ' +
215
+ // Common banner patterns
216
+ 'div[class*="banner"]:has(button), div[id*="banner"]:has(button)').then(Boolean);
217
+ // If no consent dialog is found, return
218
+ if (!hasConsent) {
219
+ return;
220
+ }
221
+ // Handle the consent dialog using common consent button patterns
222
+ await page.evaluate(() => {
223
+ const consentPatterns = {
224
+ // Common accept button text patterns across languages
225
+ text: [
226
+ // English
227
+ 'accept all', 'agree', 'consent',
228
+ // German
229
+ 'alle akzeptieren', 'ich stimme zu', 'zustimmen',
230
+ // French
231
+ 'tout accepter', 'j\'accepte',
232
+ // Spanish
233
+ 'aceptar todo', 'acepto',
234
+ // Italian
235
+ 'accetta tutto', 'accetto',
236
+ // Portuguese
237
+ 'aceitar tudo', 'concordo',
238
+ // Dutch
239
+ 'alles accepteren', 'akkoord',
240
+ // Polish
241
+ 'zaakceptuj wszystko', 'zgadzam się',
242
+ // Swedish
243
+ 'godkänn alla', 'godkänn',
244
+ // Danish
245
+ 'accepter alle', 'accepter',
246
+ // Norwegian
247
+ 'godta alle', 'godta',
248
+ // Finnish
249
+ 'hyväksy kaikki', 'hyväksy',
250
+ // Indonesian
251
+ 'terima semua', 'setuju', 'saya setuju',
252
+ // Malay
253
+ 'terima semua', 'setuju',
254
+ // Thai
255
+ 'ยอมรับทั้งหมด', 'ยอมรับ',
256
+ // Vietnamese
257
+ 'chấp nhận tất cả', 'đồng ý',
258
+ // Filipino/Tagalog
259
+ 'tanggapin lahat', 'sumang-ayon',
260
+ // Japanese
261
+ 'すべて同意する', '同意する',
262
+ // Korean
263
+ '모두 동의', '동의'
264
+ ],
265
+ // Common aria-label patterns
266
+ ariaLabels: [
267
+ 'consent', 'accept', 'agree',
268
+ 'cookie', 'privacy', 'terms',
269
+ 'persetujuan', 'setuju', // Indonesian
270
+ 'ยอมรับ', // Thai
271
+ 'đồng ý', // Vietnamese
272
+ '同意' // Japanese/Chinese
273
+ ]
274
+ };
275
+ // Finds the accept button by text or aria-label
276
+ const findAcceptButton = () => {
277
+ // Get all buttons on the page
278
+ const buttons = Array.from(document.querySelectorAll('button'));
279
+ // Find the accept button
280
+ return buttons.find(button => {
281
+ // Get the text content and aria-label of the button
282
+ const text = button.textContent?.toLowerCase() || '';
283
+ const label = button.getAttribute('aria-label')?.toLowerCase() || '';
284
+ // Check for matching text patterns
285
+ const hasMatchingText = consentPatterns.text.some(pattern => text.includes(pattern));
286
+ // Check for matching aria-labels
287
+ const hasMatchingLabel = consentPatterns.ariaLabels.some(pattern => label.includes(pattern));
288
+ // Return true if either text or aria-label matches
289
+ return hasMatchingText || hasMatchingLabel;
290
+ });
291
+ };
292
+ // Find the accept button
293
+ const acceptButton = findAcceptButton();
294
+ // If an accept button is found, click it
295
+ if (acceptButton) {
296
+ acceptButton.click();
297
+ }
298
+ });
299
+ }
300
+ catch (error) {
301
+ console.log('Consent handling failed:', error);
302
+ }
303
+ }
304
+ // Safe page navigation with error handling and bot detection
305
+ async function safePageNavigation(page, url) {
306
+ try {
307
+ // Step 1: Set cookies to bypass consent banner
308
+ await page.context().addCookies([{
309
+ name: 'CONSENT',
310
+ value: 'YES+',
311
+ domain: '.google.com',
312
+ path: '/'
313
+ }]);
314
+ // Step 2: Initial navigation
315
+ const response = await page.goto(url, {
316
+ waitUntil: 'domcontentloaded',
317
+ timeout: 15000
318
+ });
319
+ // Step 3: Basic response validation
320
+ if (!response) {
321
+ throw new Error('Navigation failed: no response received');
322
+ }
323
+ // Check HTTP status code; if 400 or higher, throw an error
324
+ const status = response.status();
325
+ if (status >= 400) {
326
+ throw new Error(`HTTP ${status}: ${response.statusText()}`);
327
+ }
328
+ // Step 4: Wait for network to become idle or timeout
329
+ await Promise.race([
330
+ page.waitForLoadState('networkidle', { timeout: 5000 })
331
+ .catch(() => { }),
332
+ // Fallback timeout in case networkidle never occurs
333
+ new Promise(resolve => setTimeout(resolve, 5000))
334
+ ]);
335
+ // Step 5: Security and content validation
336
+ const validation = await page.evaluate(() => {
337
+ const botProtectionExists = [
338
+ '#challenge-running', // Cloudflare
339
+ '#cf-challenge-running', // Cloudflare
340
+ '#px-captcha', // PerimeterX
341
+ '#ddos-protection', // Various
342
+ '#waf-challenge-html' // Various WAFs
343
+ ].some(selector => document.querySelector(selector));
344
+ // Check for suspicious page titles
345
+ const suspiciousTitle = [
346
+ 'security check',
347
+ 'ddos protection',
348
+ 'please wait',
349
+ 'just a moment',
350
+ 'attention required'
351
+ ].some(phrase => document.title.toLowerCase().includes(phrase));
352
+ // Count words in the page content
353
+ const bodyText = document.body.innerText || '';
354
+ const words = bodyText.trim().split(/\s+/).length;
355
+ // Return validation results
356
+ return {
357
+ wordCount: words,
358
+ botProtection: botProtectionExists,
359
+ suspiciousTitle,
360
+ title: document.title
361
+ };
362
+ });
363
+ // If bot protection is detected, throw an error
364
+ if (validation.botProtection) {
365
+ throw new Error('Bot protection detected');
366
+ }
367
+ // If the page title is suspicious, throw an error
368
+ if (validation.suspiciousTitle) {
369
+ throw new Error(`Suspicious page title detected: "${validation.title}"`);
370
+ }
371
+ // If the page contains insufficient content, throw an error
372
+ if (validation.wordCount < 10) {
373
+ throw new Error('Page contains insufficient content');
374
+ }
375
+ }
376
+ catch (error) {
377
+ // If an error occurs during navigation, throw an error with the URL and the error message
378
+ throw new Error(`Navigation to ${url} failed: ${error.message}`);
379
+ }
380
+ }
381
+ // Take and optimize a screenshot
382
+ async function takeScreenshotWithSizeLimit(page) {
383
+ const MAX_SIZE = 5 * 1024 * 1024;
384
+ const MAX_DIMENSION = 1920;
385
+ const MIN_DIMENSION = 800;
386
+ // Set viewport size
387
+ await page.setViewportSize({
388
+ width: 1600,
389
+ height: 900
390
+ });
391
+ // Take initial screenshot
392
+ let screenshot = await page.screenshot({
393
+ type: 'png',
394
+ fullPage: false
395
+ });
396
+ // Handle buffer conversion
397
+ let buffer = screenshot;
398
+ let attempts = 0;
399
+ const MAX_ATTEMPTS = 3;
400
+ // While screenshot is too large, reduce size
401
+ while (buffer.length > MAX_SIZE && attempts < MAX_ATTEMPTS) {
402
+ // Get current viewport size
403
+ const viewport = page.viewportSize();
404
+ if (!viewport)
405
+ continue;
406
+ // Calculate new dimensions
407
+ const scaleFactor = Math.pow(0.75, attempts + 1);
408
+ let newWidth = Math.round(viewport.width * scaleFactor);
409
+ let newHeight = Math.round(viewport.height * scaleFactor);
410
+ // Ensure dimensions are within bounds
411
+ newWidth = Math.max(MIN_DIMENSION, Math.min(MAX_DIMENSION, newWidth));
412
+ newHeight = Math.max(MIN_DIMENSION, Math.min(MAX_DIMENSION, newHeight));
413
+ // Update viewport with new dimensions
414
+ await page.setViewportSize({
415
+ width: newWidth,
416
+ height: newHeight
417
+ });
418
+ // Take new screenshot
419
+ screenshot = await page.screenshot({
420
+ type: 'png',
421
+ fullPage: false
422
+ });
423
+ // Update buffer with new screenshot
424
+ buffer = screenshot;
425
+ // Increment retry attempts
426
+ attempts++;
427
+ }
428
+ // Final attempt with minimum settings
429
+ if (buffer.length > MAX_SIZE) {
430
+ await page.setViewportSize({
431
+ width: MIN_DIMENSION,
432
+ height: MIN_DIMENSION
433
+ });
434
+ // Take final screenshot
435
+ screenshot = await page.screenshot({
436
+ type: 'png',
437
+ fullPage: false
438
+ });
439
+ // Update buffer with final screenshot
440
+ buffer = screenshot;
441
+ // Throw error if final screenshot is still too large
442
+ if (buffer.length > MAX_SIZE) {
443
+ throw new McpError(ErrorCode.InvalidRequest, `Failed to reduce screenshot to under 5MB even with minimum settings`);
444
+ }
445
+ }
446
+ // Convert Buffer to base64 string before returning
447
+ return buffer.toString('base64');
448
+ }
449
+ // Initialize MCP server with basic configuration
450
+ const server = new Server({
451
+ name: "webresearch", // Server name identifier
452
+ version: "0.1.7", // Server version number
453
+ }, {
454
+ capabilities: {
455
+ tools: {}, // Available tool configurations
456
+ resources: {}, // Resource handling capabilities
457
+ prompts: {} // Prompt processing capabilities
458
+ },
459
+ });
460
+ // Register handler for tool listing requests
461
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
462
+ tools: TOOLS // Return list of available research tools
463
+ }));
464
+ // Register handler for resource listing requests
465
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
466
+ // Return empty list if no active session
467
+ if (!currentSession) {
468
+ return { resources: [] };
469
+ }
470
+ // Compile list of available resources
471
+ const resources = [
472
+ // Add session summary resource
473
+ {
474
+ uri: "research://current/summary", // Resource identifier
475
+ name: "Current Research Session Summary",
476
+ description: "Summary of the current research session including queries and results",
477
+ mimeType: "application/json"
478
+ },
479
+ // Add screenshot resources if available
480
+ ...currentSession.results
481
+ .map((r, i) => r.screenshotPath ? {
482
+ uri: `research://screenshots/${i}`,
483
+ name: `Screenshot of ${r.title}`,
484
+ description: `Screenshot taken from ${r.url}`,
485
+ mimeType: "image/png"
486
+ } : undefined)
487
+ .filter((r) => r !== undefined)
488
+ ];
489
+ // Return compiled list of resources
490
+ return { resources };
491
+ });
492
+ // Register handler for resource content requests
493
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
494
+ const uri = request.params.uri.toString();
495
+ // Handle session summary requests for research data
496
+ if (uri === "research://current/summary") {
497
+ if (!currentSession) {
498
+ throw new McpError(ErrorCode.InvalidRequest, "No active research session");
499
+ }
500
+ // Return compiled list of resources
501
+ return {
502
+ contents: [{
503
+ uri,
504
+ mimeType: "application/json",
505
+ text: JSON.stringify({
506
+ query: currentSession.query,
507
+ resultCount: currentSession.results.length,
508
+ lastUpdated: currentSession.lastUpdated,
509
+ results: currentSession.results.map(r => ({
510
+ title: r.title,
511
+ url: r.url,
512
+ timestamp: r.timestamp,
513
+ screenshotPath: r.screenshotPath
514
+ }))
515
+ }, null, 2)
516
+ }]
517
+ };
518
+ }
519
+ // Handle screenshot requests
520
+ if (uri.startsWith("research://screenshots/")) {
521
+ const index = parseInt(uri.split("/").pop() || "", 10);
522
+ // Verify session exists
523
+ if (!currentSession) {
524
+ throw new McpError(ErrorCode.InvalidRequest, "No active research session");
525
+ }
526
+ // Verify index is within bounds
527
+ if (isNaN(index) || index < 0 || index >= currentSession.results.length) {
528
+ throw new McpError(ErrorCode.InvalidRequest, `Screenshot index out of bounds: ${index}`);
529
+ }
530
+ // Get result containing screenshot
531
+ const result = currentSession.results[index];
532
+ if (!result?.screenshotPath) {
533
+ throw new McpError(ErrorCode.InvalidRequest, `No screenshot available at index: ${index}`);
534
+ }
535
+ try {
536
+ // Read the binary data and convert to base64
537
+ const screenshotData = await fs.promises.readFile(result.screenshotPath);
538
+ // Convert Buffer to base64 string before returning
539
+ const base64Data = screenshotData.toString('base64');
540
+ // Return compiled list of resources
541
+ return {
542
+ contents: [{
543
+ uri,
544
+ mimeType: "image/png",
545
+ blob: base64Data
546
+ }]
547
+ };
548
+ }
549
+ catch (error) {
550
+ // Handle error if screenshot cannot be read
551
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
552
+ throw new McpError(ErrorCode.InternalError, `Failed to read screenshot: ${errorMessage}`);
553
+ }
554
+ }
555
+ // Handle unknown resource types
556
+ throw new McpError(ErrorCode.InvalidRequest, `Unknown resource: ${uri}`);
557
+ });
558
+ // Initialize MCP server connection using stdio transport
559
+ const transport = new StdioServerTransport();
560
+ server.connect(transport).catch((error) => {
561
+ console.error("Failed to start server:", error);
562
+ process.exit(1);
563
+ });
564
+ // Convert HTML content to clean, readable markdown format
565
+ async function extractContentAsMarkdown(page, // Puppeteer page to extract from
566
+ selector // Optional CSS selector to target specific content
567
+ ) {
568
+ // Step 1: Execute content extraction in browser context
569
+ const html = await page.evaluate((sel) => {
570
+ // Handle case where specific selector is provided
571
+ if (sel) {
572
+ const element = document.querySelector(sel);
573
+ // Return element content or empty string if not found
574
+ return element ? element.outerHTML : '';
575
+ }
576
+ // Step 2: Try standard content containers first
577
+ const contentSelectors = [
578
+ 'main', // HTML5 semantic main content
579
+ 'article', // HTML5 semantic article content
580
+ '[role="main"]', // ARIA main content role
581
+ '#content', // Common content ID
582
+ '.content', // Common content class
583
+ '.main', // Alternative main class
584
+ '.post', // Blog post content
585
+ '.article', // Article content container
586
+ ];
587
+ // Try each selector in priority order
588
+ for (const contentSelector of contentSelectors) {
589
+ const element = document.querySelector(contentSelector);
590
+ if (element) {
591
+ return element.outerHTML; // Return first matching content
592
+ }
593
+ }
594
+ // Step 3: Fallback to cleaning full body content
595
+ const body = document.body;
596
+ // Define elements to remove for cleaner content
597
+ const elementsToRemove = [
598
+ // Navigation elements
599
+ 'header', // Page header
600
+ 'footer', // Page footer
601
+ 'nav', // Navigation sections
602
+ '[role="navigation"]', // ARIA navigation elements
603
+ // Sidebars and complementary content
604
+ 'aside', // Sidebar content
605
+ '.sidebar', // Sidebar by class
606
+ '[role="complementary"]', // ARIA complementary content
607
+ // Navigation-related elements
608
+ '.nav', // Navigation classes
609
+ '.menu', // Menu elements
610
+ // Page structure elements
611
+ '.header', // Header classes
612
+ '.footer', // Footer classes
613
+ // Advertising and notices
614
+ '.advertisement', // Advertisement containers
615
+ '.ads', // Ad containers
616
+ '.cookie-notice', // Cookie consent notices
617
+ ];
618
+ // Remove each unwanted element from content
619
+ elementsToRemove.forEach(sel => {
620
+ body.querySelectorAll(sel).forEach(el => el.remove());
621
+ });
622
+ // Return cleaned body content
623
+ return body.outerHTML;
624
+ }, selector);
625
+ // Step 4: Handle empty content case
626
+ if (!html) {
627
+ return '';
628
+ }
629
+ try {
630
+ // Step 5: Convert HTML to Markdown
631
+ const markdown = turndownService.turndown(html);
632
+ // Step 6: Clean up and format markdown
633
+ return markdown
634
+ .replace(/\n{3,}/g, '\n\n') // Replace excessive newlines with double
635
+ .replace(/^- $/gm, '') // Remove empty list items
636
+ .replace(/^\s+$/gm, '') // Remove whitespace-only lines
637
+ .trim(); // Remove leading/trailing whitespace
638
+ }
639
+ catch (error) {
640
+ // Log conversion errors and return original HTML as fallback
641
+ console.error('Error converting HTML to Markdown:', error);
642
+ return html;
643
+ }
644
+ }
645
+ // Validate URL format and ensure security constraints
646
+ function isValidUrl(urlString) {
647
+ try {
648
+ // Attempt to parse URL string
649
+ const url = new URL(urlString);
650
+ // Only allow HTTP and HTTPS protocols for security
651
+ return url.protocol === 'http:' || url.protocol === 'https:';
652
+ }
653
+ catch {
654
+ // Return false for any invalid URL format
655
+ return false;
656
+ }
657
+ }
658
+ // Tool request handler for executing research operations
659
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
660
+ // Initialize browser for tool operations
661
+ const page = await ensureBrowser();
662
+ switch (request.params.name) {
663
+ // Handle Google search operations
664
+ case "search_google": {
665
+ // Extract search query from request parameters
666
+ const { query } = request.params.arguments;
667
+ try {
668
+ // Execute search with retry mechanism
669
+ const results = await withRetry(async () => {
670
+ // Step 1: Navigate to Google search page
671
+ await safePageNavigation(page, 'https://www.google.com');
672
+ await dismissGoogleConsent(page);
673
+ // Step 2: Find and interact with search input
674
+ await withRetry(async () => {
675
+ // Wait for any search input element to appear
676
+ await Promise.race([
677
+ // Try multiple possible selectors for search input
678
+ page.waitForSelector('input[name="q"]', { timeout: 5000 }),
679
+ page.waitForSelector('textarea[name="q"]', { timeout: 5000 }),
680
+ page.waitForSelector('input[type="text"]', { timeout: 5000 })
681
+ ]).catch(() => {
682
+ throw new Error('Search input not found - no matching selectors');
683
+ });
684
+ // Find the actual search input element
685
+ const searchInput = await page.$('input[name="q"]') ||
686
+ await page.$('textarea[name="q"]') ||
687
+ await page.$('input[type="text"]');
688
+ // Verify search input was found
689
+ if (!searchInput) {
690
+ throw new Error('Search input element not found after waiting');
691
+ }
692
+ // Step 3: Enter search query
693
+ await searchInput.click({ clickCount: 3 }); // Select all existing text
694
+ await searchInput.press('Backspace'); // Clear selected text
695
+ await searchInput.type(query); // Type new query
696
+ }, 3, 2000); // Allow 3 retries with 2s delay
697
+ // Step 4: Submit search and wait for results
698
+ await withRetry(async () => {
699
+ await Promise.all([
700
+ page.keyboard.press('Enter'),
701
+ page.waitForLoadState('networkidle', { timeout: 15000 }),
702
+ ]);
703
+ });
704
+ // Step 5: Extract search results
705
+ const searchResults = await withRetry(async () => {
706
+ const results = await page.evaluate(() => {
707
+ // Find all search result containers
708
+ const elements = document.querySelectorAll('div.g');
709
+ if (!elements || elements.length === 0) {
710
+ throw new Error('No search results found');
711
+ }
712
+ // Extract data from each result
713
+ return Array.from(elements).map((el) => {
714
+ // Find required elements within result container
715
+ const titleEl = el.querySelector('h3'); // Title element
716
+ const linkEl = el.querySelector('a'); // Link element
717
+ const snippetEl = el.querySelector('div.VwiC3b'); // Snippet element
718
+ // Skip results missing required elements
719
+ if (!titleEl || !linkEl || !snippetEl) {
720
+ return null;
721
+ }
722
+ // Return structured result data
723
+ return {
724
+ title: titleEl.textContent || '', // Result title
725
+ url: linkEl.getAttribute('href') || '', // Result URL
726
+ snippet: snippetEl.textContent || '', // Result description
727
+ };
728
+ }).filter(result => result !== null); // Remove invalid results
729
+ });
730
+ // Verify we found valid results
731
+ if (!results || results.length === 0) {
732
+ throw new Error('No valid search results found');
733
+ }
734
+ // Return compiled list of results
735
+ return results;
736
+ });
737
+ // Step 6: Store results in session
738
+ searchResults.forEach((result) => {
739
+ addResult({
740
+ url: result.url,
741
+ title: result.title,
742
+ content: result.snippet,
743
+ timestamp: new Date().toISOString(),
744
+ });
745
+ });
746
+ // Return compiled list of results
747
+ return searchResults;
748
+ });
749
+ // Step 7: Return formatted results
750
+ return {
751
+ content: [{
752
+ type: "text",
753
+ text: JSON.stringify(results, null, 2) // Pretty-print JSON results
754
+ }]
755
+ };
756
+ }
757
+ catch (error) {
758
+ // Handle and format search errors
759
+ return {
760
+ content: [{
761
+ type: "text",
762
+ text: `Failed to perform search: ${error.message}`
763
+ }],
764
+ isError: true
765
+ };
766
+ }
767
+ }
768
+ // Handle webpage visit and content extraction
769
+ case "visit_page": {
770
+ // Extract URL and screenshot flag from request
771
+ const { url, takeScreenshot } = request.params.arguments;
772
+ // Step 1: Validate URL format and security
773
+ if (!isValidUrl(url)) {
774
+ return {
775
+ content: [{
776
+ type: "text",
777
+ text: `Invalid URL: ${url}. Only http and https protocols are supported.`
778
+ }],
779
+ isError: true
780
+ };
781
+ }
782
+ try {
783
+ // Step 2: Visit page and extract content with retry mechanism
784
+ const result = await withRetry(async () => {
785
+ // Navigate to target URL safely
786
+ await safePageNavigation(page, url);
787
+ const title = await page.title();
788
+ // Step 3: Extract and process page content
789
+ const content = await withRetry(async () => {
790
+ // Convert page content to markdown
791
+ const extractedContent = await extractContentAsMarkdown(page);
792
+ // If no content is extracted, throw an error
793
+ if (!extractedContent) {
794
+ throw new Error('Failed to extract content');
795
+ }
796
+ // Return the extracted content
797
+ return extractedContent;
798
+ });
799
+ // Step 4: Create result object with page data
800
+ const pageResult = {
801
+ url, // Original URL
802
+ title, // Page title
803
+ content, // Markdown content
804
+ timestamp: new Date().toISOString(), // Capture time
805
+ };
806
+ // Step 5: Take screenshot if requested
807
+ let screenshotUri;
808
+ if (takeScreenshot) {
809
+ // Capture and process screenshot
810
+ const screenshot = await takeScreenshotWithSizeLimit(page);
811
+ pageResult.screenshotPath = await saveScreenshot(screenshot, title);
812
+ // Get the index for the resource URI
813
+ const resultIndex = currentSession ? currentSession.results.length : 0;
814
+ screenshotUri = `research://screenshots/${resultIndex}`;
815
+ // Notify clients about new screenshot resource
816
+ server.notification({
817
+ method: "notifications/resources/list_changed"
818
+ });
819
+ }
820
+ // Step 6: Store result in session
821
+ addResult(pageResult);
822
+ return { pageResult, screenshotUri };
823
+ });
824
+ // Step 7: Return formatted result with screenshot URI if taken
825
+ const response = {
826
+ content: [{
827
+ type: "text",
828
+ text: JSON.stringify({
829
+ url: result.pageResult.url,
830
+ title: result.pageResult.title,
831
+ content: result.pageResult.content,
832
+ timestamp: result.pageResult.timestamp,
833
+ screenshot: result.screenshotUri ? `View screenshot via *MCP Resources* (Paperclip icon) @ URI: ${result.screenshotUri}` : undefined
834
+ }, null, 2)
835
+ }]
836
+ };
837
+ return response;
838
+ }
839
+ catch (error) {
840
+ // Handle and format page visit errors
841
+ return {
842
+ content: [{
843
+ type: "text",
844
+ text: `Failed to visit page: ${error.message}`
845
+ }],
846
+ isError: true
847
+ };
848
+ }
849
+ }
850
+ // Handle standalone screenshot requests
851
+ case "take_screenshot": {
852
+ try {
853
+ // Step 1: Capture screenshot with retry mechanism
854
+ const screenshot = await withRetry(async () => {
855
+ // Take and optimize screenshot with default size limits
856
+ return await takeScreenshotWithSizeLimit(page);
857
+ });
858
+ // Step 2: Initialize session if needed
859
+ if (!currentSession) {
860
+ currentSession = {
861
+ query: "Screenshot Session", // Session identifier
862
+ results: [], // Empty results array
863
+ lastUpdated: new Date().toISOString(), // Current timestamp
864
+ };
865
+ }
866
+ // Step 3: Get current page information
867
+ const pageUrl = await page.url(); // Current page URL
868
+ const pageTitle = await page.title(); // Current page title
869
+ // Step 4: Save screenshot to disk
870
+ const screenshotPath = await saveScreenshot(screenshot, pageTitle || 'untitled');
871
+ // Step 5: Create and store screenshot result
872
+ const resultIndex = currentSession ? currentSession.results.length : 0;
873
+ addResult({
874
+ url: pageUrl,
875
+ title: pageTitle || "Untitled Page", // Fallback title if none available
876
+ content: "Screenshot taken", // Simple content description
877
+ timestamp: new Date().toISOString(), // Capture time
878
+ screenshotPath // Path to screenshot file
879
+ });
880
+ // Step 6: Notify clients about new screenshot resource
881
+ server.notification({
882
+ method: "notifications/resources/list_changed"
883
+ });
884
+ // Step 7: Return success message with resource URI
885
+ const resourceUri = `research://screenshots/${resultIndex}`;
886
+ return {
887
+ content: [{
888
+ type: "text",
889
+ text: `Screenshot taken successfully. You can view it via *MCP Resources* (Paperclip icon) @ URI: ${resourceUri}`
890
+ }]
891
+ };
892
+ }
893
+ catch (error) {
894
+ // Handle and format screenshot errors
895
+ return {
896
+ content: [{
897
+ type: "text",
898
+ text: `Failed to take screenshot: ${error.message}`
899
+ }],
900
+ isError: true
901
+ };
902
+ }
903
+ }
904
+ // Handle unknown tool requests
905
+ default:
906
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
907
+ }
908
+ });
909
+ // Register handler for prompt listing requests
910
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
911
+ // Return all available prompts
912
+ return { prompts: Object.values(PROMPTS) };
913
+ });
914
+ // Register handler for prompt retrieval and execution
915
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
916
+ // Extract and validate prompt name
917
+ const promptName = request.params.name;
918
+ const prompt = PROMPTS[promptName];
919
+ // Handle unknown prompt requests
920
+ if (!prompt) {
921
+ throw new McpError(ErrorCode.InvalidRequest, `Prompt not found: ${promptName}`);
922
+ }
923
+ // Handle agentic research prompt
924
+ if (promptName === "agentic-research") {
925
+ // Extract research topic from request arguments
926
+ const args = request.params.arguments;
927
+ const topic = args?.topic || ""; // Use empty string if no topic provided
928
+ // Return research assistant prompt with instructions
929
+ return {
930
+ messages: [
931
+ // Initial assistant message establishing role
932
+ {
933
+ role: "assistant",
934
+ content: {
935
+ type: "text",
936
+ text: "I am ready to help you with your research. I will conduct thorough web research, explore topics deeply, and maintain a dialogue with you throughout the process."
937
+ }
938
+ },
939
+ // Detailed research instructions for the user
940
+ {
941
+ role: "user",
942
+ content: {
943
+ type: "text",
944
+ text: `I'd like to research this topic: <topic>${topic}</topic>
945
+
946
+ Please help me explore it deeply, like you're a thoughtful, highly-trained research assistant.
947
+
948
+ General instructions:
949
+ 1. Start by proposing your research approach -- namely, formulate what initial query you will use to search the web. Propose a relatively broad search to understand the topic landscape. At the same time, make your queries optimized for returning high-quality results based on what you know about constructing Google search queries.
950
+ 2. Next, get my input on whether you should proceed with that query or if you should refine it.
951
+ 3. Once you have an approved query, perform the search.
952
+ 4. Prioritize high quality, authoritative sources when they are available and relevant to the topic. Avoid low quality or spammy sources.
953
+ 5. Retrieve information that is relevant to the topic at hand.
954
+ 6. Iteratively refine your research direction based on what you find.
955
+ 7. Keep me informed of what you find and let *me* guide the direction of the research interactively.
956
+ 8. If you run into a dead end while researching, do a Google search for the topic and attempt to find a URL for a relevant page. Then, explore that page in depth.
957
+ 9. Only conclude when my research goals are met.
958
+ 10. **Always cite your sources**, providing URLs to the sources you used in a citation block at the end of your response.
959
+
960
+ You can use these tools:
961
+ - search_google: Search for information
962
+ - visit_page: Visit and extract content from web pages
963
+
964
+ Do *NOT* use the following tools:
965
+ - Anything related to knowledge graphs or memory, unless explicitly instructed to do so by the user.`
966
+ }
967
+ }
968
+ ]
969
+ };
970
+ }
971
+ // Handle unsupported prompt types
972
+ throw new McpError(ErrorCode.InvalidRequest, "Prompt implementation not found");
973
+ });
974
+ // Ensures browser is running, and creates a new page if needed
975
+ async function ensureBrowser() {
976
+ // Launch browser if not already running
977
+ if (!browser) {
978
+ browser = await chromium.launch({
979
+ headless: true, // Run in headless mode for automation
980
+ });
981
+ // Create initial context and page
982
+ const context = await browser.newContext();
983
+ page = await context.newPage();
984
+ }
985
+ // Create new page if current one is closed/invalid
986
+ if (!page) {
987
+ const context = await browser.newContext();
988
+ page = await context.newPage();
989
+ }
990
+ // Return the current page
991
+ return page;
992
+ }
993
+ // Cleanup function
994
+ async function cleanup() {
995
+ try {
996
+ // Clean up screenshots first
997
+ await cleanupScreenshots();
998
+ // Then close the browser
999
+ if (browser) {
1000
+ await browser.close();
1001
+ }
1002
+ }
1003
+ catch (error) {
1004
+ console.error('Error during cleanup:', error);
1005
+ }
1006
+ finally {
1007
+ browser = undefined;
1008
+ page = undefined;
1009
+ }
1010
+ }
1011
+ // Register cleanup handlers
1012
+ process.on('exit', cleanup);
1013
+ process.on('SIGTERM', cleanup);
1014
+ process.on('SIGINT', cleanup);
1015
+ process.on('SIGHUP', cleanup);
1016
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@iflow-mcp/mcp-webresearch",
3
+ "version": "0.1.7",
4
+ "description": "MCP server for web research",
5
+ "license": "MIT",
6
+ "author": "mzxrai",
7
+ "homepage": "https://github.com/mzxrai/mcp-webresearch",
8
+ "bugs": "https://github.com/mzxrai/mcp-webresearch/issues",
9
+ "type": "module",
10
+ "bin": {
11
+ "mcp-server-webresearch": "dist/index.js"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc && shx chmod +x dist/*.js",
18
+ "prepare": "pnpm run build",
19
+ "postinstall": "playwright install chromium",
20
+ "watch": "tsc --watch",
21
+ "dev": "tsx watch index.ts"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "web-research",
30
+ "ai",
31
+ "web-scraping"
32
+ ],
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "1.0.1",
35
+ "playwright": "^1.49.0",
36
+ "turndown": "^7.1.2"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^24.9.1",
40
+ "@types/turndown": "^5.0.4",
41
+ "shx": "^0.3.4",
42
+ "tsx": "^4.19.2",
43
+ "typescript": "^5.6.2"
44
+ }
45
+ }