@imenam/simple-scraper 1.0.15 → 1.0.16

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 CHANGED
@@ -332,7 +332,7 @@ The capture area is resolved by precedence: `selector` → `clip` → `full_page
332
332
  | `full_page` | boolean | | Capture the full scrollable page height (default: false, ignored when `selector` or `clip` is provided) |
333
333
  | `format` | `png` \| `jpeg` | | Image format (default: `png`) |
334
334
  | `output` | `inline` \| `file` \| `both` | ✅ | `inline` embeds the image in the response, `file` saves to disk and returns the path, `both` does both |
335
- | `path` | string | | Absolute or relative path for the saved file. Defaults to `./screenshots/screenshot-<timestamp>.<format>` |
335
+ | `path` | string | | **Absolute** path for the saved file — relative paths are rejected, since they would resolve against the server's working directory, which the client sets unpredictably. Missing parent directories are created. Defaults to `<server_root>/screenshots/screenshot-<timestamp>.<format>` |
336
336
 
337
337
  ---
338
338
 
package/dist/index.js CHANGED
@@ -592,7 +592,13 @@ server.tool('screenshot', 'Take a screenshot of a page. Provide either session_i
592
592
  full_page: z.boolean().optional().describe('Capture the full scrollable page height (default: false, ignored when selector or clip is provided)'),
593
593
  format: z.enum(['png', 'jpeg']).optional().describe('Image format (default: png)'),
594
594
  output: z.enum(['inline', 'file', 'both']).describe('Return format: "inline" embeds the image in the response, "file" saves to disk and returns the path, "both" does both'),
595
- path: z.string().optional().describe('Absolute or relative file path for the saved image (used when output is "file" or "both"). Relative paths are resolved from the MCP server\'s working directory. Defaults to <server_root>/screenshots/<timestamp>.<format>'),
595
+ path: z
596
+ .string()
597
+ .refine(p => path.isAbsolute(p), {
598
+ message: 'path must be absolute — a relative path would resolve against the MCP server\'s working directory, which is set by the client and not predictable.',
599
+ })
600
+ .optional()
601
+ .describe('Absolute file path for the saved image (used when output is "file" or "both"). Must be absolute; missing parent directories are created. Defaults to <server_root>/screenshots/screenshot-<timestamp>.<format>'),
596
602
  }, async ({ session_id, url, wait_for, timeout, selector, clip, viewport, full_page, format, output, path: filePath }) => {
597
603
  const effectiveTimeout = timeout ?? getDefaultTimeout();
598
604
  const fmt = format ?? 'png';
@@ -646,7 +652,8 @@ server.tool('screenshot', 'Take a screenshot of a page. Provide either session_i
646
652
  imageBuffer = Buffer.from(await page.screenshot({ type: fmt, fullPage: full_page ?? false }));
647
653
  }
648
654
  const base64 = imageBuffer.toString('base64');
649
- // Resolve file path
655
+ // Resolve file path. filePath is guaranteed absolute by the schema; resolve()
656
+ // is kept only to normalise separators and any ".." segments.
650
657
  const resolvedPath = (() => {
651
658
  if (filePath)
652
659
  return path.resolve(filePath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imenam/simple-scraper",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "MCP server for web scraping and JavaScript execution using Puppeteer",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",