image-tiler-mcp-server 2.1.0 → 3.0.1

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 (42) hide show
  1. package/README.md +129 -39
  2. package/dist/constants.d.ts +8 -1
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +10 -1
  5. package/dist/constants.js.map +1 -1
  6. package/dist/index.js +4 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/prompts/index.d.ts +3 -0
  9. package/dist/prompts/index.d.ts.map +1 -0
  10. package/dist/prompts/index.js +81 -0
  11. package/dist/prompts/index.js.map +1 -0
  12. package/dist/resources/index.d.ts +3 -0
  13. package/dist/resources/index.d.ts.map +1 -0
  14. package/dist/resources/index.js +76 -0
  15. package/dist/resources/index.js.map +1 -0
  16. package/dist/schemas/index.d.ts +3 -0
  17. package/dist/schemas/index.d.ts.map +1 -1
  18. package/dist/schemas/index.js +18 -2
  19. package/dist/schemas/index.js.map +1 -1
  20. package/dist/security.d.ts +21 -0
  21. package/dist/security.d.ts.map +1 -0
  22. package/dist/security.js +94 -0
  23. package/dist/security.js.map +1 -0
  24. package/dist/services/image-processor.d.ts.map +1 -1
  25. package/dist/services/image-processor.js +7 -2
  26. package/dist/services/image-processor.js.map +1 -1
  27. package/dist/services/image-source-resolver.d.ts.map +1 -1
  28. package/dist/services/image-source-resolver.js +122 -75
  29. package/dist/services/image-source-resolver.js.map +1 -1
  30. package/dist/services/tiling-pipeline.d.ts +1 -1
  31. package/dist/services/tiling-pipeline.d.ts.map +1 -1
  32. package/dist/services/tiling-pipeline.js +20 -11
  33. package/dist/services/tiling-pipeline.js.map +1 -1
  34. package/dist/services/url-capture.d.ts.map +1 -1
  35. package/dist/services/url-capture.js +59 -33
  36. package/dist/services/url-capture.js.map +1 -1
  37. package/dist/tools/tiler.d.ts.map +1 -1
  38. package/dist/tools/tiler.js +98 -100
  39. package/dist/tools/tiler.js.map +1 -1
  40. package/dist/types.d.ts +5 -0
  41. package/dist/types.d.ts.map +1 -1
  42. package/package.json +3 -2
package/README.md CHANGED
@@ -2,15 +2,28 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/image-tiler-mcp-server)](https://www.npmjs.com/package/image-tiler-mcp-server)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/keiver/image-tiler-mcp-server/blob/main/LICENSE)
5
- [![Node.js >= 20](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org/)
5
+ [![Node.js >= 20](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org/en)
6
+ [![MCP Badge](https://lobehub.com/badge/mcp/keiver-image-tiler-mcp-server)](https://lobehub.com/mcp/keiver-image-tiler-mcp-server)
6
7
 
7
- MCP server that tiles large images for LLM vision analysis.
8
+ MCP server that gives LLMs full-resolution vision by tiling images and capturing web pages before details are lost.
8
9
 
9
10
  <figure align="center">
10
11
  <img src="assets/preview.gif" alt="Preview of image tiling grid with advised vision models size and token estimates" width="100%" />
11
12
  <figcaption><i>The server generates an interactive HTML preview for every image, showing per-model tile grids and token estimates</i></figcaption>
12
13
  </figure>
13
14
 
15
+ ## What You Can Do
16
+
17
+ - **Visual QA for web pages.** Capture a URL, tile it, and let the LLM spot misaligned elements, wrong colors, and broken layouts at full resolution. Fix the code, re-capture, and verify the fix visually.
18
+
19
+ - **Mobile responsive testing.** Capture at any viewport width with mobile emulation, retina scaling, and a real mobile user agent. The LLM reviews the full mobile layout tile by tile, catching responsive breakpoint issues that only appear on small screens.
20
+
21
+ - **Full-resolution image analysis.** Diagrams, infographics, and design mockups lose critical details when LLMs downscale them. A 3,600 x 20,220px full-page capture that Claude would crush to ~279 x 1,568 becomes 76 analyzable tiles, each at native resolution.
22
+
23
+ - **Token-efficient tile inspection.** Each tile gets entropy-based content classification: blank, low-detail, mixed, or high-detail. The LLM skips blank tiles entirely and focuses tokens on what matters.
24
+
25
+ - **Iterative visual workflow.** Capture, analyze, fix, re-capture. Versioned output directories (`_v1`, `_v2`, ...) preserve each iteration so you can compare before and after without overwriting previous results.
26
+
14
27
  ## Quick Start
15
28
 
16
29
  ### Claude Code
@@ -21,7 +34,7 @@ claude mcp add image-tiler -- npx -y image-tiler-mcp-server
21
34
 
22
35
  > `image-tiler` is a local alias. You can name it anything you like. `image-tiler-mcp-server` is the npm package that gets downloaded and run.
23
36
 
24
- See [Claude Code MCP docs](https://docs.anthropic.com/en/docs/claude-code/mcp) for more info.
37
+ See [Claude Code MCP docs](https://code.claude.com/docs/en/mcp) for more info.
25
38
 
26
39
  <details>
27
40
  <summary>Codex CLI</summary>
@@ -140,19 +153,24 @@ Then point your MCP config to the built file:
140
153
 
141
154
  ### Tile an image
142
155
 
143
- > lets tile ~/Desktop/source.jpg
156
+ > tile ~/source.png and analyze content
144
157
 
145
- The server shows you a comparison of supported vision models with tile counts and token estimates.
146
- Pick the model that matches your use case, and the server tiles the image and returns them in batches for analysis.
158
+ The server reads image dimensions and generates an interactive HTML preview with per-model tabs showing grid overlays, tile counts, and token estimates. Pick the model that matches your use case, and the server tiles and returns batches for analysis.
147
159
 
148
160
  ### Capture a web page
149
161
 
150
- > capture screenshot of https://example.com and analyze the content
162
+ > capture full page screenshot of https://tomotv.app
151
163
 
152
- The server launches Chrome, captures a full-page screenshot (scroll-stitching pages over 16,384px), then presents the same model comparison. Choose a model and the server tiles the capture for analysis.
164
+ The server launches headless Chrome, scrolls through the page to trigger lazy-loaded images (`loading="lazy"`), then captures a full-page screenshot (scroll-stitching pages over 16,384px). Your assistant receives each section at full resolution and can identify layout issues, misaligned elements, or broken styling that downscaling would hide.
153
165
 
154
166
  To get only the screenshot without tiling, just ask for a screenshot and stop after the comparison step.
155
167
 
168
+ ### Test a mobile layout
169
+
170
+ > capture https://tomotv.app in mobile view
171
+
172
+ This is responsive QA, not just a different viewport. The server captures with `mobile: true`, which sets a 390px viewport, 2x retina scale, and a mobile Safari user agent. Sites that check for mobile UA or touch capability serve their mobile layout, so the LLM reviews exactly what a real phone user sees.
173
+
156
174
  ### Customize tiling
157
175
 
158
176
  | What | Example prompt |
@@ -160,13 +178,13 @@ To get only the screenshot without tiling, just ask for a screenshot and stop af
160
178
  | Target a specific model | "Tile hero.png for OpenAI" |
161
179
  | Keep full resolution | "Tile banner.png at full resolution, no downscaling" |
162
180
  | PNG output | "Tile diagram.png as lossless PNG" |
163
- | Tile from URL | "Download and tile https://example.com/chart.png" |
181
+ | Tile from URL | "Download and tile https://keiver.dev/source.png" |
164
182
  | Tile from base64 | "Tile this base64 image: iVBORw0KGgo..." |
165
183
 
166
- ## Supported Models
184
+ ## Presets
167
185
 
168
- | Model | Default tile | Tokens/tile | Max tile | ID |
169
- |-------|-------------|-------------|----------|-----|
186
+ | Preset | Default tile | Tokens/tile | Max tile | ID |
187
+ |--------|-------------|-------------|----------|-----|
170
188
  | Claude | 1092px | 1590 | 1568px | `claude` |
171
189
  | OpenAI (GPT-4o/o-series) | 768px | 765 | 2048px | `openai` |
172
190
  | Gemini | 768px | 258 | 768px | `gemini` |
@@ -174,18 +192,15 @@ To get only the screenshot without tiling, just ask for a screenshot and stop af
174
192
 
175
193
  > **OpenAI note:** The `openai` config targets the GPT-4o / o-series vision pipeline (512px tile patches). GPT-4.1 uses a fundamentally different pipeline (32x32 pixel patches) and is not currently supported. It would require a separate model config with a different calculation approach.
176
194
 
177
- > **Gemini 3 note:** Gemini 3 uses a fixed token budget per image (1,120 tokens at default resolution, regardless of dimensions). Tiling increases total token cost but preserves fine detail. For cases where detail isn't critical, consider sending a single image instead.
195
+ > **Gemini 3 note:** Gemini 3 uses a fixed token budget per image (1,120 tokens regardless of dimensions). Tiling increases total token cost but preserves fine detail. For cases where detail isn't critical, consider sending a single image instead.
178
196
 
179
- <details>
180
- <summary>Why tile? What LLMs do to large images</summary>
181
-
182
- ### The Problem
197
+ ## Why Tile?
183
198
 
184
- You screenshot a full page, paste it into Claude, and Claude **rejects it**. Your 20,000px full-page screenshot? Claude won't even look at it. Anything over 8,000px on either dimension gets refused outright.
199
+ You screenshot a full page, paste it into Claude, and Claude **crushes it to a thumbnail**. Any image with a long edge over 1,568 pixels gets auto-downscaled to fit within ~1.15 megapixels. A 3,600 x 20,220px full-page capture becomes ~279 x 1,568, losing over 99% of its pixels before the model even sees it.
185
200
 
186
- GPT-4o is more forgiving but still destructive: it first scales your image to fit within 2,048px, then scales the shortest side down to 768px, *then* tiles internally. An 8,192px-wide NASA panorama becomes ~1,456 x 768 before GPT-4o's own tiling even begins.
201
+ GPT-4o is more forgiving but still destructive: it scales your image to fit within 2,048px, then scales the shortest side down to 768px, *then* tiles internally. An 8,192px-wide NASA panorama becomes ~1,456 x 768 before GPT-4o's own tiling even begins.
187
202
 
188
- Gemini 1.5/2.0 handles large images natively at 768px tiles without downscaling. Gemini 3, however, caps each image at a fixed token budget (1,120 tokens at default resolution) regardless of size. Tiling gives each piece its own budget.
203
+ Gemini 1.5/2.0 handles large images natively at 768px tiles without downscaling. Gemini 3, however, caps each image at a fixed token budget (1,120 tokens) regardless of size. Tiling gives each piece its own budget.
189
204
 
190
205
  Each tile stays within the model's sweet spot, so the LLM processes it at full resolution.
191
206
 
@@ -195,7 +210,7 @@ Using `assets/portrait.png` (3,600 x 20,220, a full-page National Geographic cap
195
210
 
196
211
  | Model | What happens | Impact |
197
212
  |-------|-------------|--------|
198
- | Claude | **Rejected**, exceeds 8,000px dimension limit | Cannot analyze the image at all |
213
+ | Claude | Auto-downscaled to ~279 x 1,568 | ~0.6% of original pixels survive |
199
214
  | GPT-4o | Downscaled to ~365 x 2,048, then internally tiled | ~1% of original pixels survive the downscale |
200
215
  | Gemini 3 | Capped at 1,120 tokens per image (default) | Fixed token budget regardless of image size |
201
216
 
@@ -206,37 +221,38 @@ Using `assets/portrait.png` (3,600 x 20,220, a full-page National Geographic cap
206
221
 
207
222
  | Model | Tiles | Result |
208
223
  |-------|-------|--------|
209
- | Claude | 76 tiles at 1,092px | Every tile under 8,000px and 1,568px limits, full analysis |
224
+ | Claude | 76 tiles at 1,092px | Every tile within 1,568px sweet spot, no downscaling |
210
225
  | GPT-4o | 135 tiles at 768px | Every tile under 2,048px, no pre-downscale needed |
211
- | Gemini 3 | 135 tiles at 768px | Each tile gets its own token budget |
226
+ | Gemini 3 | 42 tiles at 1,536px | Each tile gets its own 1,120-token budget |
212
227
 
213
228
  Using `assets/landscape.png` (8,192 x 4,320, NASA image gallery):
214
229
 
215
230
  | Model | Without tiling | With tiling |
216
231
  |-------|----------------|-------------|
217
- | Claude | **Rejected** (8,192 > 8,000px limit) | 32 tiles at 1,092px, full analysis |
232
+ | Claude | Auto-downscaled to ~1,568 x 827 (~3.7% of pixels survive) | 32 tiles at 1,092px, full analysis |
218
233
  | GPT-4o | Downscaled to ~1,456 x 768 (~3% of pixels survive) | 66 tiles at 768px, full resolution |
219
234
  | Gemini 3 | Capped at 1,120 tokens | 18 tiles at 1,536px, 18x token budget |
220
235
 
221
236
  *Based on published model vision documentation as of Feb 2026:
222
- [Claude vision limits](https://docs.anthropic.com/en/docs/build-with-claude/vision) ·
223
- [OpenAI vision guide](https://platform.openai.com/docs/guides/vision) ·
237
+ [Claude vision limits](https://platform.claude.com/docs/en/build-with-claude/vision) ·
238
+ [OpenAI vision guide](https://developers.openai.com/api/docs/guides/images-vision) ·
224
239
  [Gemini image understanding](https://ai.google.dev/gemini-api/docs/image-understanding) ·
225
240
  [Gemini media resolution](https://ai.google.dev/gemini-api/docs/media-resolution)*
226
241
 
227
- </details>
228
-
229
242
  ## How It Works
230
243
 
231
244
  This MCP server:
232
245
 
233
246
  1. Reads the image dimensions and the target model's vision config
234
- 2. Calculates an optimal grid that keeps every tile within the model's sweet spot
235
- 3. Extracts tiles as individual images (WebP default, PNG optional) and saves them to disk
236
- 4. Returns a metadata summary (grid layout, file paths, token cost, per-tile content hints)
237
- 5. Serves tiles on demand call with `tilesDir` + `start`/`end` to retrieve batches of up to 5 tiles
247
+ 2. Generates an interactive HTML preview with per-model tabs showing grid overlays, tile numbering, and token estimates
248
+ 3. Calculates an optimal grid that keeps every tile within the model's sweet spot
249
+ 4. Extracts tiles as individual images (WebP default, PNG optional) and saves them to disk
250
+ 5. Returns a metadata summary (grid layout, file paths, token cost, per-tile content hints)
251
+ 6. Serves tiles on demand: call with `tilesDir` + `start`/`end` to retrieve batches of up to 5 tiles
252
+
253
+ **Web capture pipeline.** For URLs, the server launches headless Chrome, triggers lazy-loaded images by scrolling the page, captures a full-page screenshot (scroll-stitching pages over 16,384px), then feeds the screenshot into the same tiling pipeline.
238
254
 
239
- **Auto-downscaling:** Images over 10,000px on their longest side are automatically downscaled before tiling (configurable via `maxDimension`). This keeps tile counts reasonable and improves LLM comprehension by increasing content density per tile. Set `maxDimension=0` to disable, or pass a custom value (e.g., `maxDimension=5000`) for more aggressive downscaling.
255
+ **Auto-downscaling.** Images over 10,000px on their longest side are automatically downscaled before tiling (configurable via `maxDimension`). This keeps tile counts reasonable and improves LLM comprehension by increasing content density per tile. Set `maxDimension=0` to disable, or pass a custom value (e.g., `maxDimension=5000`) for more aggressive downscaling.
240
256
 
241
257
  <details>
242
258
  <summary>Tool Reference</summary>
@@ -271,7 +287,7 @@ The tool uses a two-step process to let you choose the right model before tiling
271
287
  | Parameter | Type | Required | Default | Description |
272
288
  |---|---|---|---|---|
273
289
  | `filePath` | string | no* | - | Absolute or relative path to the image file |
274
- | `sourceUrl` | string | no* | - | HTTPS URL to download the image from (max 50MB, 30s timeout) |
290
+ | `sourceUrl` | string | no* | - | URL to download the image from (max 50MB, 30s timeout). `https:` uses SSRF filtering; `http:` is allowed without filtering for local dev servers |
275
291
  | `dataUrl` | string | no* | - | Data URL with base64-encoded image |
276
292
  | `imageBase64` | string | no* | - | Raw base64-encoded image data |
277
293
 
@@ -283,7 +299,10 @@ The tool uses a two-step process to let you choose the right model before tiling
283
299
  |---|---|---|---|---|
284
300
  | `url` | string | no | - | URL of the web page to capture. Requires Chrome/Chromium installed (or `CHROME_PATH` env var). |
285
301
  | `screenshotPath` | string | no | - | Path to a previously captured screenshot. Skips URL capture when provided. |
286
- | `viewportWidth` | number | no | `1280` | Browser viewport width in pixels (320-3840) |
302
+ | `viewportWidth` | number | no | `1280` (`390` when `mobile`) | Browser viewport width in pixels (320-3840) |
303
+ | `mobile` | boolean | no | `false` | Whether to emulate a mobile device. When true, defaults `viewportWidth` to 390, `deviceScaleFactor` to 2, and sets a mobile user agent. |
304
+ | `deviceScaleFactor` | number | no | `1` (`2` when `mobile`) | Device pixel ratio (0.1-5). Use `2` for retina, `3` for high-DPI mobile. |
305
+ | `userAgent` | string | no | - | Custom user agent string. Auto-set to a mobile Safari UA when `mobile: true` and no explicit value provided. |
287
306
  | `waitUntil` | string | no | `"load"` | When to consider the page loaded: `"load"`, `"networkidle"`, or `"domcontentloaded"` |
288
307
  | `delay` | number | no | `0` | Additional delay in ms after page load (max 30000) |
289
308
 
@@ -308,11 +327,34 @@ Supports scroll-stitching for pages taller than 16,384px. Automatically triggers
308
327
  | `outputDir` | string | no | See below | Directory to save tiles. Defaults: for `filePath` sources, `tiles/{name}_vN/` next to source (auto-incrementing: `_v1`, `_v2`, ..., `_vN`); for `sourceUrl`/`dataUrl`/`imageBase64`, `{base}/tiles/tiled_{timestamp}_{hex}/`; for captures, `{base}/tiles/capture_{timestamp}_{hex}/`. `{base}` is `~/Desktop`, `~/Downloads`, or `~` (first available). |
309
328
  | `page` | number | no | `0` | Tile page to return (0 = first 5, 1 = next 5, etc.) |
310
329
  | `format` | string | no | `"webp"` | Output format: `"webp"` (smaller, default) or `"png"` (lossless) |
311
- | `includeMetadata` | boolean | no | `true` | Analyze each tile using Shannon entropy and return content classification (blank, low-detail, mixed, high-detail) plus `entropy` and `sharpness` values per tile |
330
+ | `includeMetadata` | boolean | no | `true` | Analyze each tile using image stats and return content classification (blank, low-detail, mixed, high-detail) plus `stdDev` and `entropy` values per tile |
312
331
  | `model` | string | no | - | **Deprecated.** Use `preset` instead. Still accepted; emits a deprecation warning in the response. |
313
332
 
314
333
  </details>
315
334
 
335
+ <details>
336
+ <summary>MCP Prompts and Resources</summary>
337
+
338
+ ### Prompts
339
+
340
+ Guided workflows for clients that support [MCP prompts](https://modelcontextprotocol.io/docs/concepts/prompts):
341
+
342
+ | Prompt | Arguments | Description |
343
+ |--------|-----------|-------------|
344
+ | `tile-and-analyze` | `filePath` (required), `preset` (optional), `focus` (optional) | Walks through tiling a local image and analyzing each tile at full resolution. The `focus` argument narrows analysis (e.g., "UI layout", "text readability"). |
345
+ | `capture-and-analyze` | `url` (required), `focus` (optional) | Walks through capturing a web page screenshot and analyzing it tile by tile. |
346
+
347
+ ### Resources
348
+
349
+ Static references for clients that support [MCP resources](https://modelcontextprotocol.io/docs/concepts/resources):
350
+
351
+ | URI | Format | Description |
352
+ |-----|--------|-------------|
353
+ | `tiler://models` | JSON | All supported vision model presets with tile sizes, min/max bounds, and per-tile token rates. |
354
+ | `tiler://guide` | Plain text | Quick reference covering the tiling workflow, preset summary, and usage tips. |
355
+
356
+ </details>
357
+
316
358
  ## Behaviors
317
359
 
318
360
  - **Source conflict:** Multiple image source params → highest-precedence source is used with a warning (`filePath` > `sourceUrl` > `dataUrl` > `imageBase64`).
@@ -339,18 +381,66 @@ PNG, JPEG, WebP, TIFF, GIF
339
381
 
340
382
  ## Security
341
383
 
342
- Local stdio server - runs with the same filesystem permissions as the MCP client that spawns it. No path sandboxing, no SSRF protection on URL downloads.
384
+ **Transport:** stdio only. The server is a single-session local process spawned by the MCP client. It never listens on a network socket.
385
+
386
+ ### URL download protection (always-on)
387
+
388
+ `https:` `sourceUrl` downloads use [`request-filtering-agent`](https://github.com/azu/request-filtering-agent), which blocks requests to private IP ranges before they are made:
389
+
390
+ - RFC 1918 (10.x, 172.16-31.x, 192.168.x)
391
+ - Loopback (127.x, ::1)
392
+ - Link-local / IMDS (169.254.x, fe80::/10) including IPv4-mapped IPv6 (`::ffff:169.254.169.254`)
393
+ - CGNAT (100.64.x), ULA (fc00::/7)
394
+
395
+ HTTP redirects are followed up to 5 hops. Each hop re-applies SSRF filtering for `https:` URLs, so a redirect to a private IP is blocked even if the initial URL was public. `https:` to `http:` downgrades are blocked. `http:` downloads bypass SSRF filtering, intended for local dev servers (localhost, LAN IPs). Use `https:` for all remote/production URLs.
396
+
397
+ **Limitation:** DNS rebinding is mitigated but not fully prevented at the application layer.
398
+
399
+ ### Path containment (opt-in via `TILER_ALLOWED_DIRS`)
400
+
401
+ Set `TILER_ALLOWED_DIRS` to a comma-separated list of absolute paths to restrict all file I/O to those directories:
402
+
403
+ ```
404
+ TILER_ALLOWED_DIRS=/app/uploads,/tmp/tiler-work
405
+ ```
406
+
407
+ When set:
408
+ - `filePath` and `tilesDir` inputs are checked via `fs.realpath()` (resolves symlinks) before access.
409
+ - `outputDir` writes are checked against the nearest existing ancestor to prevent path traversal through non-existing directories.
410
+ - Any path outside the allowed list is rejected with an `[TILER_ALLOWED_DIRS]` error.
343
411
 
344
- **If deploying remotely:** Add path validation, SSRF protection (block private/internal IP ranges), and authentication. This server is not designed for multi-tenant or network-exposed use.
412
+ When unset, no path restriction is applied (preserves backward-compatible local behaviour).
413
+
414
+ ### Chrome URL capture kill switch
415
+
416
+ Chrome headless can reach any network address the host can reach. Application-level IP checks cannot reliably constrain it. For cloud deployments without a `NetworkPolicy` or equivalent, disable URL capture entirely:
417
+
418
+ ```
419
+ TILER_DISABLE_URL_CAPTURE=1
420
+ ```
421
+
422
+ Any call with a `url` parameter will return an error instead of spawning Chrome.
423
+
424
+ **Docker example:**
425
+
426
+ ```env
427
+ CHROME_NO_SANDBOX=1
428
+ TILER_ALLOWED_DIRS=/app/uploads
429
+ TILER_DISABLE_URL_CAPTURE=1 # remove only if Chrome is network-isolated
430
+ ```
345
431
 
346
432
  ## Requirements
347
433
 
348
434
  - Node.js 20+
349
435
  - Compatible MCP client (Claude Code, Codex CLI, VS Code, Cursor, Claude Desktop)
350
436
 
437
+ ## Contributing
438
+
439
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for how to report bugs, suggest changes, and submit PRs.
440
+
351
441
  ## Acknowledgments
352
442
 
353
- Built with the help of [Claude Code](https://claude.ai/claude-code) as an AI assistant for code drafting, testing, and documentation.
443
+ Built with the help of [Claude Code](https://code.claude.com/docs/en/setup) as an AI assistant for code drafting, testing, and documentation.
354
444
 
355
445
  ## License
356
446
 
@@ -21,7 +21,8 @@ export declare const PNG_COMPRESSION_LEVEL = 6;
21
21
  export declare const DEFAULT_MAX_DIMENSION = 10000;
22
22
  export declare const MAX_DOWNLOAD_SIZE_BYTES: number;
23
23
  export declare const DOWNLOAD_TIMEOUT_MS = 30000;
24
- export declare const ALLOWED_URL_PROTOCOLS: readonly ["https:"];
24
+ export declare const ALLOWED_URL_PROTOCOLS: readonly ["https:", "http:"];
25
+ export declare const MAX_REDIRECT_HOPS = 5;
25
26
  export declare const MAX_BASE64_LENGTH = 67108864;
26
27
  export declare const MAX_DATA_URL_LENGTH: number;
27
28
  export declare const BLANK_STDDEV_THRESHOLD = 5;
@@ -38,6 +39,8 @@ export declare const CHROME_MAX_CAPTURE_HEIGHT = 16384;
38
39
  export declare const CAPTURE_DEFAULT_VIEWPORT_WIDTH = 1280;
39
40
  export declare const CAPTURE_DEFAULT_VIEWPORT_HEIGHT = 800;
40
41
  export declare const CAPTURE_DEFAULT_TIMEOUT_MS = 60000;
42
+ export declare const CAPTURE_MOBILE_VIEWPORT_WIDTH = 390;
43
+ export declare const CAPTURE_MOBILE_DEVICE_SCALE_FACTOR = 2;
41
44
  export declare const CAPTURE_STITCH_SETTLE_MS = 100;
42
45
  export declare const CAPTURE_IDLE_TIMEOUT_MS = 500;
43
46
  export declare const WAIT_UNTIL_OPTIONS: readonly ["load", "networkidle", "domcontentloaded"];
@@ -51,4 +54,8 @@ export declare const MAX_CHROME_STDERR_BYTES = 1048576;
51
54
  export declare const MAX_CHROME_JSON_BYTES = 1048576;
52
55
  export declare const MAX_PREVIEW_PIXELS = 16000000;
53
56
  export declare const MIN_PREVIEW_WIDTH = 800;
57
+ export declare const DEFAULT_MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1";
58
+ export declare const ALLOWED_DIRS_ENV_VAR = "TILER_ALLOWED_DIRS";
59
+ export declare const DISABLE_URL_CAPTURE_ENV_VAR = "TILER_DISABLE_URL_CAPTURE";
60
+ export declare const DENY_HTTP_PRIVATE_ENV_VAR = "TILER_DENY_HTTP_PRIVATE";
54
61
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,oDAAqD,CAAC;AAChF,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,iBAAiB,CA6BhE,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,WAAsB,CAAC;AAGnD,eAAO,MAAM,iBAAiB,QAAuC,CAAC;AACtE,eAAO,MAAM,aAAa,QAAmC,CAAC;AAC9D,eAAO,MAAM,aAAa,QAAmC,CAAC;AAC9D,eAAO,MAAM,eAAe,QAAqC,CAAC;AAElE,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AACzC,eAAO,MAAM,eAAe,QAAQ,CAAC;AACrC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,iBAAiB,wDAAyD,CAAC;AACxF,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAG3C,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AACxD,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAC1C,eAAO,MAAM,qBAAqB,qBAAsB,CAAC;AACzD,eAAO,MAAM,iBAAiB,WAAa,CAAC;AAC5C,eAAO,MAAM,mBAAmB,QAA0B,CAAC;AAG3D,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,4BAA4B,IAAM,CAAC;AAChD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAGjD,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAGxC,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAGjD,eAAO,MAAM,mBAAmB,0BAA2B,CAAC;AAC5D,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,eAAO,MAAM,YAAY,KAAK,CAAC;AAG/B,eAAO,MAAM,gBAAgB,QAAoB,CAAC;AAClD,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAC/C,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,kBAAkB,sDAAuD,CAAC;AACvF,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5D,eAAO,MAAM,yBAAyB,8BAA+B,CAAC;AAGtE,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAGjD,eAAO,MAAM,gBAAgB,YAAc,CAAC;AAC5C,eAAO,MAAM,uBAAuB,UAAY,CAAC;AACjD,eAAO,MAAM,qBAAqB,UAAY,CAAC;AAG/C,eAAO,MAAM,kBAAkB,WAAa,CAAC;AAC7C,eAAO,MAAM,iBAAiB,MAAM,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
package/dist/constants.js CHANGED
@@ -44,7 +44,8 @@ export const DEFAULT_MAX_DIMENSION = 10000;
44
44
  // Image source resolution
45
45
  export const MAX_DOWNLOAD_SIZE_BYTES = 50 * 1024 * 1024; // 50 MB
46
46
  export const DOWNLOAD_TIMEOUT_MS = 30_000; // 30 seconds
47
- export const ALLOWED_URL_PROTOCOLS = ["https:"];
47
+ export const ALLOWED_URL_PROTOCOLS = ["https:", "http:"];
48
+ export const MAX_REDIRECT_HOPS = 5;
48
49
  export const MAX_BASE64_LENGTH = 67_108_864; // ~50MB decoded (base64 is ~4/3x)
49
50
  export const MAX_DATA_URL_LENGTH = MAX_BASE64_LENGTH + 256; // base64 payload + data URL prefix overhead
50
51
  // Tile content classification thresholds
@@ -65,6 +66,8 @@ export const CHROME_MAX_CAPTURE_HEIGHT = 16384;
65
66
  export const CAPTURE_DEFAULT_VIEWPORT_WIDTH = 1280;
66
67
  export const CAPTURE_DEFAULT_VIEWPORT_HEIGHT = 800;
67
68
  export const CAPTURE_DEFAULT_TIMEOUT_MS = 60_000;
69
+ export const CAPTURE_MOBILE_VIEWPORT_WIDTH = 390;
70
+ export const CAPTURE_MOBILE_DEVICE_SCALE_FACTOR = 2;
68
71
  export const CAPTURE_STITCH_SETTLE_MS = 100;
69
72
  export const CAPTURE_IDLE_TIMEOUT_MS = 500;
70
73
  export const WAIT_UNTIL_OPTIONS = ["load", "networkidle", "domcontentloaded"];
@@ -80,4 +83,10 @@ export const MAX_CHROME_JSON_BYTES = 1_048_576; // 1MB
80
83
  // Preview rendering
81
84
  export const MAX_PREVIEW_PIXELS = 16_000_000; // Safari's canvas/image rendering limit
82
85
  export const MIN_PREVIEW_WIDTH = 800; // Floor that prevents tall-image width crushing
86
+ // Mobile emulation
87
+ export const DEFAULT_MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1";
88
+ // Security environment variable names
89
+ export const ALLOWED_DIRS_ENV_VAR = "TILER_ALLOWED_DIRS";
90
+ export const DISABLE_URL_CAPTURE_ENV_VAR = "TILER_DISABLE_URL_CAPTURE";
91
+ export const DENY_HTTP_PRIVATE_ENV_VAR = "TILER_DENY_HTTP_PRIVATE";
83
92
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAWhF,MAAM,CAAC,MAAM,aAAa,GAA2C;IACnE,MAAM,EAAE;QACN,eAAe,EAAE,IAAI;QACrB,WAAW,EAAE,GAAG;QAChB,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,QAAQ;KAChB;IACD,MAAM,EAAE;QACN,eAAe,EAAE,GAAG;QACpB,WAAW,EAAE,GAAG;QAChB,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE,GAAG;QAClB,KAAK,EAAE,QAAQ;KAChB;IACD,MAAM,EAAE;QACN,eAAe,EAAE,GAAG;QACpB,WAAW,EAAE,GAAG;QAChB,WAAW,EAAE,GAAG;QAChB,aAAa,EAAE,GAAG;QAClB,KAAK,EAAE,QAAQ;KAChB;IACD,OAAO,EAAE;QACP,eAAe,EAAE,IAAI;QACrB,WAAW,EAAE,GAAG;QAChB,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,UAAU;KAClB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAgB,QAAQ,CAAC;AAEnD,uDAAuD;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,eAAe,CAAC;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC;AAC9D,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC;AAC9D,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC;AAElE,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAC;AACxF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAE3C,0BAA0B;AAC1B,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,CAAC,aAAa;AACxD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAAQ,CAAU,CAAC;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,CAAC,kCAAkC;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,GAAG,CAAC,CAAC,4CAA4C;AAExG,yCAAyC;AACzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAChD,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAEjD,gGAAgG;AAChG,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,qEAAqE;AACrE,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,CAAC,aAAa;AAE/D,sBAAsB;AACtB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,MAAM,CAAU,CAAC;AAE5D,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B,cAAc;AACd,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,sDAAsD;AACzG,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,CAAC,sDAAsD;AACjG,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAC/C,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAC;AACnD,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAG,CAAC;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AACjD,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAC5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,kBAAkB,CAAU,CAAC;AAEvF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAU,CAAC;AAEtE,eAAe;AACf,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAC7C,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAC/C,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD,kBAAkB;AAClB,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,qCAAqC;AAClF,MAAM,CAAC,MAAM,uBAAuB,GAAG,SAAS,CAAC,CAAC,MAAM;AACxD,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAC,CAAC,MAAM;AAEtD,oBAAoB;AACpB,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC,CAAC,wCAAwC;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAC,gDAAgD"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -3,6 +3,8 @@ import { createRequire } from "node:module";
3
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
5
  import { registerTilerTool } from "./tools/tiler.js";
6
+ import { registerPrompts } from "./prompts/index.js";
7
+ import { registerResources } from "./resources/index.js";
6
8
  const require = createRequire(import.meta.url);
7
9
  const { version } = require("../package.json");
8
10
  const args = process.argv.slice(2);
@@ -29,6 +31,8 @@ const server = new McpServer({
29
31
  version,
30
32
  });
31
33
  registerTilerTool(server);
34
+ registerPrompts(server);
35
+ registerResources(server);
32
36
  async function runStdio() {
33
37
  const transport = new StdioServerTransport();
34
38
  await server.connect(transport);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,2BAA2B,OAAO;;;;;;;;;;4DAUY,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,wBAAwB;IAC9B,OAAO;CACR,CAAC,CAAC;AAEH,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE1B,KAAK,UAAU,QAAQ;IACrB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;AAC3D,CAAC;AAED,KAAK,UAAU,QAAQ;IACrB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEhC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAY,EAAE,EAAE;IAC/C,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC5C,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE;IACnD,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;IAC9C,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAClC,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,2BAA2B,OAAO;;;;;;;;;;4DAUY,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,wBAAwB;IAC9B,OAAO;CACR,CAAC,CAAC;AAEH,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,eAAe,CAAC,MAAM,CAAC,CAAC;AACxB,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE1B,KAAK,UAAU,QAAQ;IACrB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;AAC3D,CAAC;AAED,KAAK,UAAU,QAAQ;IACrB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEhC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAY,EAAE,EAAE;IAC/C,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC5C,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE;IACnD,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;IAC9C,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAClC,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerPrompts(server: McpServer): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwFvD"}
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ import { VISION_MODELS } from "../constants.js";
3
+ export function registerPrompts(server) {
4
+ server.registerPrompt("tile-and-analyze", {
5
+ title: "Tile and Analyze Image",
6
+ description: "Tile a local image and analyze every tile at full resolution",
7
+ argsSchema: {
8
+ filePath: z.string().describe("Absolute or relative path to the image file"),
9
+ preset: z
10
+ .enum([...VISION_MODELS])
11
+ .optional()
12
+ .describe("Vision model preset (claude, openai, gemini3, gemini)"),
13
+ focus: z
14
+ .string()
15
+ .optional()
16
+ .describe("Analysis focus area (e.g. 'text readability', 'UI layout')"),
17
+ },
18
+ }, ({ filePath, preset, focus }) => {
19
+ const presetNote = preset ? ` with preset="${preset}"` : "";
20
+ const focusNote = focus ? `\n\nFocus your analysis on: ${focus}` : "";
21
+ return {
22
+ messages: [
23
+ {
24
+ role: "user",
25
+ content: {
26
+ type: "text",
27
+ text: `Tile and analyze "${filePath}" at full resolution. Follow this exact workflow:
28
+
29
+ 1. Phase 1: call tiler(filePath="${filePath}"${presetNote}). Returns a model comparison table and an outputDir.
30
+ Present the table and let the user pick a preset (or auto-select the cheapest).
31
+ 2. Phase 2: call tiler(filePath="${filePath}", preset=<chosen>, outputDir=<from step 1>).
32
+ This tiles the image and returns a metadata summary (no tile images yet).
33
+ 3. Retrieve tiles: call tiler(tilesDir=<outputDir>, start=0, end=4) to get the first batch.
34
+ 4. Analyze each tile. Note its row/col grid position to understand spatial layout.
35
+ 5. Paginate: increment start/end by 5 and repeat until all tiles are reviewed.
36
+ 6. Synthesize a full-image summary from your tile-by-tile observations.${focusNote}
37
+
38
+ LLM vision systems downscale large images automatically. Tiling preserves the detail that would otherwise be lost.`,
39
+ },
40
+ },
41
+ ],
42
+ };
43
+ });
44
+ server.registerPrompt("capture-and-analyze", {
45
+ title: "Capture and Analyze Web Page",
46
+ description: "Capture a web page screenshot via Chrome, tile it, and analyze each tile",
47
+ argsSchema: {
48
+ url: z.string().url().describe("URL of the web page to capture"),
49
+ focus: z
50
+ .string()
51
+ .optional()
52
+ .describe("Analysis focus area (e.g. 'accessibility', 'responsive layout')"),
53
+ },
54
+ }, ({ url, focus }) => {
55
+ const focusNote = focus ? `\n\nFocus your analysis on: ${focus}` : "";
56
+ return {
57
+ messages: [
58
+ {
59
+ role: "user",
60
+ content: {
61
+ type: "text",
62
+ text: `Capture and analyze "${url}" at full resolution. Follow this exact workflow:
63
+
64
+ 1. Phase 1: call tiler(url="${url}"). Captures the page and returns a model comparison table,
65
+ an outputDir, and a screenshotPath. Present the table and let the user pick a preset.
66
+ 2. Phase 2: call tiler(screenshotPath=<from step 1>, preset=<chosen>, outputDir=<from step 1>).
67
+ Important: use screenshotPath (not url) to reuse the existing screenshot.
68
+ Returns a metadata summary (no tile images yet).
69
+ 3. Retrieve tiles: call tiler(tilesDir=<outputDir>, start=0, end=4) to get the first batch.
70
+ 4. Analyze each tile. Note spatial layout and content at each grid position.
71
+ 5. Paginate: increment start/end by 5 and repeat until all tiles are reviewed.
72
+ 6. Synthesize a complete page analysis from your tile-by-tile observations.${focusNote}
73
+
74
+ Requires Chrome/Chromium installed. Pages taller than 16,384px are scroll-stitched automatically.`,
75
+ },
76
+ },
77
+ ],
78
+ };
79
+ });
80
+ }
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,cAAc,CACnB,kBAAkB,EAClB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,8DAA8D;QAChE,UAAU,EAAE;YACV,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YAC5E,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,GAAG,aAAa,CAA0B,CAAC;iBACjD,QAAQ,EAAE;iBACV,QAAQ,CAAC,uDAAuD,CAAC;YACpE,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,4DAA4D,CAAC;SAC1E;KACF,EACD,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,iBAAiB,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,qBAAqB,QAAQ;;mCAEd,QAAQ,IAAI,UAAU;;mCAEtB,QAAQ;;;;;yEAK8B,SAAS;;mHAEiC;qBACtG;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,qBAAqB,EACrB;QACE,KAAK,EAAE,8BAA8B;QACrC,WAAW,EACT,0EAA0E;QAC5E,UAAU,EAAE;YACV,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YAChE,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iEAAiE,CAAC;SAC/E;KACF,EACD,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;QACjB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,wBAAwB,GAAG;;8BAEjB,GAAG;;;;;;;;6EAQ4C,SAAS;;kGAEY;qBACrF;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerResources(server: McpServer): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgFzD"}
@@ -0,0 +1,76 @@
1
+ import { MODEL_CONFIGS, VISION_MODELS } from "../constants.js";
2
+ const _maxModelLen = Math.max(...VISION_MODELS.map((m) => m.length));
3
+ const _maxSizeDigits = Math.max(...VISION_MODELS.map((m) => String(MODEL_CONFIGS[m].defaultTileSize).length));
4
+ const PRESET_LINES = VISION_MODELS.map((model) => {
5
+ const c = MODEL_CONFIGS[model];
6
+ const modelPad = " ".repeat(_maxModelLen - model.length + 2);
7
+ const sizePad = " ".repeat(_maxSizeDigits - String(c.defaultTileSize).length + 1);
8
+ return ` ${model}${modelPad}-- ${c.defaultTileSize}px tiles,${sizePad}~${c.tokensPerTile} tokens/tile`;
9
+ }).join("\n");
10
+ export function registerResources(server) {
11
+ server.registerResource("model-configs", "tiler://models", {
12
+ title: "Vision Model Presets",
13
+ description: "Supported vision model presets with tile sizes and per-tile token estimates",
14
+ mimeType: "application/json",
15
+ }, (uri) => {
16
+ const configs = Object.fromEntries(VISION_MODELS.map((model) => {
17
+ const c = MODEL_CONFIGS[model];
18
+ return [
19
+ model,
20
+ {
21
+ label: c.label,
22
+ defaultTileSize: c.defaultTileSize,
23
+ minTileSize: c.minTileSize,
24
+ maxTileSize: c.maxTileSize,
25
+ tokensPerTile: c.tokensPerTile,
26
+ },
27
+ ];
28
+ }));
29
+ return {
30
+ contents: [
31
+ {
32
+ uri: uri.href,
33
+ mimeType: "application/json",
34
+ text: JSON.stringify(configs, null, 2),
35
+ },
36
+ ],
37
+ };
38
+ });
39
+ server.registerResource("usage-guide", "tiler://guide", {
40
+ title: "Usage Guide",
41
+ description: "Quick reference: workflow, presets, and tips for the image tiler",
42
+ mimeType: "text/plain",
43
+ }, (uri) => ({
44
+ contents: [
45
+ {
46
+ uri: uri.href,
47
+ mimeType: "text/plain",
48
+ text: `Image Tiler MCP Server -- Quick Reference
49
+
50
+ WHY TILE:
51
+ LLM vision systems downscale large images. A 3600x20220px screenshot sent whole
52
+ to Claude becomes ~279x1568px, losing all fine text. Tiling splits the image into
53
+ chunks that stay within each model's resolution sweet spot.
54
+
55
+ WORKFLOW (minimum three tool calls):
56
+ 1. tiler(filePath=...) -- Phase 1: returns model comparison table and outputDir.
57
+ 2. tiler(filePath=..., preset=..., outputDir=...) -- Phase 2: tiles the image, returns metadata summary.
58
+ Re-include the original image source. For captures, use screenshotPath instead of url.
59
+ 3. tiler(tilesDir=..., start=0, end=4) -- Get-tiles: retrieve tile images in batches of 5.
60
+ Increment start/end by 5 to paginate through remaining tiles.
61
+
62
+ PRESETS:
63
+ ${PRESET_LINES}
64
+
65
+ TIPS:
66
+ - Review ALL tiles before drawing conclusions about the full image.
67
+ - Tile row/col coordinates map to spatial position in the original.
68
+ - includeMetadata is on by default; blank tiles are auto-skipped in get-tiles mode.
69
+ - URL capture requires Chrome/Chromium. Set CHROME_PATH to override detection.
70
+ - Pages taller than 16,384px are scroll-stitched automatically.
71
+ - maxDimension (default 10000px) downscales very large inputs before tiling.`,
72
+ },
73
+ ],
74
+ }));
75
+ }
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE/D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACrE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9G,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IAC/C,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClF,OAAO,KAAK,KAAK,GAAG,QAAQ,MAAM,CAAC,CAAC,eAAe,YAAY,OAAO,IAAI,CAAC,CAAC,aAAa,cAAc,CAAC;AAC1G,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEd,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,gBAAgB,EAChB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,6EAA6E;QAC/E,QAAQ,EAAE,kBAAkB;KAC7B,EACD,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAChC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAC1B,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO;gBACL,KAAK;gBACL;oBACE,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,eAAe,EAAE,CAAC,CAAC,eAAe;oBAClC,WAAW,EAAE,CAAC,CAAC,WAAW;oBAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;oBAC1B,aAAa,EAAE,CAAC,CAAC,aAAa;iBAC/B;aACF,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QACF,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,gBAAgB,CACrB,aAAa,EACb,eAAe,EACf;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,kEAAkE;QACpE,QAAQ,EAAE,YAAY;KACvB,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACR,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,YAAY;gBACtB,IAAI,EAAE;;;;;;;;;;;;;;;EAed,YAAY;;;;;;;;6EAQ+D;aACpE;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -8,6 +8,9 @@ export declare const TilerInputSchema: {
8
8
  viewportWidth: z.ZodOptional<z.ZodNumber>;
9
9
  waitUntil: z.ZodDefault<z.ZodEnum<["load", "networkidle", "domcontentloaded"]>>;
10
10
  delay: z.ZodDefault<z.ZodNumber>;
11
+ mobile: z.ZodOptional<z.ZodBoolean>;
12
+ deviceScaleFactor: z.ZodOptional<z.ZodNumber>;
13
+ userAgent: z.ZodOptional<z.ZodString>;
11
14
  screenshotPath: z.ZodOptional<z.ZodString>;
12
15
  tilesDir: z.ZodOptional<z.ZodString>;
13
16
  start: z.ZodDefault<z.ZodNumber>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;CA8I5B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;CAgK5B,CAAC"}