image-tiler-mcp-server 1.6.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +95 -199
  2. package/dist/constants.d.ts +24 -5
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +28 -4
  5. package/dist/constants.js.map +1 -1
  6. package/dist/index.js +29 -8
  7. package/dist/index.js.map +1 -1
  8. package/dist/schemas/index.d.ts +11 -33
  9. package/dist/schemas/index.d.ts.map +1 -1
  10. package/dist/schemas/index.js +49 -62
  11. package/dist/schemas/index.js.map +1 -1
  12. package/dist/services/elicitation.d.ts +24 -0
  13. package/dist/services/elicitation.d.ts.map +1 -0
  14. package/dist/services/elicitation.js +49 -0
  15. package/dist/services/elicitation.js.map +1 -0
  16. package/dist/services/image-processor.d.ts +2 -1
  17. package/dist/services/image-processor.d.ts.map +1 -1
  18. package/dist/services/image-processor.js +51 -28
  19. package/dist/services/image-processor.js.map +1 -1
  20. package/dist/services/image-source-resolver.d.ts.map +1 -1
  21. package/dist/services/image-source-resolver.js +45 -9
  22. package/dist/services/image-source-resolver.js.map +1 -1
  23. package/dist/services/interactive-preview-generator.d.ts.map +1 -1
  24. package/dist/services/interactive-preview-generator.js +37 -8
  25. package/dist/services/interactive-preview-generator.js.map +1 -1
  26. package/dist/services/tile-analyzer.d.ts +4 -0
  27. package/dist/services/tile-analyzer.d.ts.map +1 -0
  28. package/dist/services/tile-analyzer.js +38 -0
  29. package/dist/services/tile-analyzer.js.map +1 -0
  30. package/dist/services/tiling-pipeline.d.ts +81 -0
  31. package/dist/services/tiling-pipeline.d.ts.map +1 -0
  32. package/dist/services/tiling-pipeline.js +325 -0
  33. package/dist/services/tiling-pipeline.js.map +1 -0
  34. package/dist/services/url-capture.d.ts +4 -0
  35. package/dist/services/url-capture.d.ts.map +1 -0
  36. package/dist/services/url-capture.js +619 -0
  37. package/dist/services/url-capture.js.map +1 -0
  38. package/dist/tools/tiler.d.ts +3 -0
  39. package/dist/tools/tiler.d.ts.map +1 -0
  40. package/dist/tools/tiler.js +501 -0
  41. package/dist/tools/tiler.js.map +1 -0
  42. package/dist/types.d.ts +37 -24
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/utils.d.ts +18 -0
  45. package/dist/utils.d.ts.map +1 -1
  46. package/dist/utils.js +140 -0
  47. package/dist/utils.js.map +1 -1
  48. package/package.json +16 -3
  49. package/dist/tools/get-tiles.d.ts +0 -3
  50. package/dist/tools/get-tiles.d.ts.map +0 -1
  51. package/dist/tools/get-tiles.js +0 -113
  52. package/dist/tools/get-tiles.js.map +0 -1
  53. package/dist/tools/prepare-image.d.ts +0 -3
  54. package/dist/tools/prepare-image.d.ts.map +0 -1
  55. package/dist/tools/prepare-image.js +0 -225
  56. package/dist/tools/prepare-image.js.map +0 -1
  57. package/dist/tools/recommend-settings.d.ts +0 -3
  58. package/dist/tools/recommend-settings.d.ts.map +0 -1
  59. package/dist/tools/recommend-settings.js +0 -198
  60. package/dist/tools/recommend-settings.js.map +0 -1
  61. package/dist/tools/tile-image.d.ts +0 -3
  62. package/dist/tools/tile-image.d.ts.map +0 -1
  63. package/dist/tools/tile-image.js +0 -219
  64. package/dist/tools/tile-image.js.map +0 -1
package/README.md CHANGED
@@ -1,11 +1,38 @@
1
1
  # image-tiler-mcp-server
2
2
 
3
- Split large images into optimally-sized tiles so LLM vision models see every detail - no downscaling, no lost text.
3
+ Capture, tile, analyze, and estimate vision tokens for LLM models - so nothing gets downscaled away.
4
4
 
5
5
  <p align="center">
6
6
  <img src="assets/preview.gif" alt="Preview of image tiling grid with advised vision models size and token estimates" width="100%" />
7
7
  </p>
8
8
 
9
+ ## Usage
10
+
11
+ ### Tile an image
12
+
13
+ > lets tile ~/Desktop/source.jpg
14
+
15
+ The server shows you a comparison of supported vision models with tile counts and token estimates.
16
+ Pick the model that matches your use case, and the server tiles the image and returns them in batches for analysis.
17
+
18
+ ### Capture a web page
19
+
20
+ > capture screenshot of https://example.com and analyze the content
21
+
22
+ 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.
23
+
24
+ To get only the screenshot without tiling, just ask for a screenshot and stop after the comparison step.
25
+
26
+ ### Customize tiling
27
+
28
+ | What | Example prompt |
29
+ |------|---------------|
30
+ | Target a specific model | "Tile hero.png for OpenAI" |
31
+ | Keep full resolution | "Tile banner.png at full resolution, no downscaling" |
32
+ | PNG output | "Tile diagram.png as lossless PNG" |
33
+ | Tile from URL | "Download and tile https://example.com/chart.png" |
34
+ | Tile from base64 | "Tile this base64 image: iVBORw0KGgo..." |
35
+
9
36
  ## Installation
10
37
 
11
38
  ### Claude Code
@@ -115,25 +142,25 @@ Then point your MCP config to the built file:
115
142
 
116
143
  ## Tiling for LLM Vision
117
144
 
118
- LLM vision systems have a **maximum input resolution**. When you send an image larger than that limit, the model silently downscales it before processing. A 3600×22810 full-page screenshot gets shrunk to ~247×1568 by Claude - text becomes unreadable, UI details disappear, and the model can't analyze what it can't see.
145
+ LLM vision systems have a **maximum input resolution**. When you send an image larger than that limit, the model downscales it before processing. A 3600×22810 full-page screenshot gets shrunk to ~247×1568 by Claude - text becomes unreadable, UI details disappear, and the model can't analyze what it can't see.
119
146
 
120
147
  **Tiling solves this.** This MCP server:
121
148
 
122
149
  1. Reads the image dimensions and the target model's vision config
123
150
  2. Calculates an optimal grid that keeps every tile within the model's sweet spot
124
- 3. Extracts tiles as individual PNGs and saves them to disk
151
+ 3. Extracts tiles as individual images (WebP default, PNG optional) and saves them to disk
125
152
  4. Returns metadata (grid layout, file paths, estimated token cost)
126
153
  5. Serves tiles back as base64 in paginated batches for the LLM to analyze
127
154
 
128
- Each tile is processed at **full resolution** - no downscaling - preserving text, UI elements, and fine detail across the entire image.
155
+ Each tile stays within the model's sweet spot - the LLM processes it at full resolution instead of downscaling, preserving text, UI elements, and fine detail.
129
156
 
130
- **Auto-downscaling:** Images over 10,000px on their longest side are automatically downscaled before tiling (configurable via `maxDimension`). This prevents extreme tile counts on very long screenshots - e.g., a 3600×22810 page drops from 84 tiles / ~134K tokens to 20 tiles / ~32K tokens with no visible quality loss. Set `maxDimension=0` to disable.
157
+ **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.
131
158
 
132
159
  ### Supported Models
133
160
 
134
161
  | Model | Default tile | Tokens/tile | Max tile | ID |
135
162
  |-------|-------------|-------------|----------|-----|
136
- | Claude (default) | 1092px | 1590 | 1568px | `claude` |
163
+ | Claude | 1092px | 1590 | 1568px | `claude` |
137
164
  | OpenAI (GPT-4o/o-series) | 768px | 765 | 2048px | `openai` |
138
165
  | Gemini | 768px | 258 | 768px | `gemini` |
139
166
  | Gemini 3 | 1536px | 1120 | 3072px | `gemini3` |
@@ -144,218 +171,81 @@ Each tile is processed at **full resolution** - no downscaling - preserving text
144
171
 
145
172
  ## Tools
146
173
 
147
- ### `tiler_tile_image`
174
+ ### `tiler`
148
175
 
149
- Splits a large image into tiles and saves them to disk.
176
+ One unified tool that handles all image tiling operations. The mode is auto-detected from the parameters you provide:
150
177
 
151
- | Parameter | Type | Required | Default | Description |
152
- |---|---|---|---|---|
153
- | `filePath` | string | no* | - | Absolute or relative path to the image file |
154
- | `sourceUrl` | string | no* | - | HTTPS URL to download the image from (max 50MB, 30s timeout) |
155
- | `dataUrl` | string | no* | - | Data URL with base64-encoded image |
156
- | `imageBase64` | string | no* | - | Raw base64-encoded image data |
157
- | `model` | string | no | `"claude"` | Target vision model: `"claude"`, `"openai"`, `"gemini"`, `"gemini3"` |
158
- | `tileSize` | number | no | Model default | Tile size in pixels. Clamped to model min/max with a warning if out of bounds. |
159
- | `maxDimension` | number | no | `10000` | Max dimension in px (0-65536). Pre-downscales the image so its longest side fits within this value before tiling. Defaults to 10000px. Set to 0 to disable auto-downscaling. No-op if already within bounds. |
160
- | `outputDir` | string | no | `tiles/{name}` subfolder next to source | Directory to save tiles |
178
+ - **`tilesDir`** present **Tile retrieval mode** (read-only pagination)
179
+ - **`url`** or **`screenshotPath`** present → **URL capture mode** (screenshot + tile)
180
+ - **`filePath`**, **`sourceUrl`**, **`dataUrl`**, or **`imageBase64`** present **Tile-image mode**
161
181
 
162
- *At least one image source (`filePath`, `sourceUrl`, `dataUrl`, or `imageBase64`) is required.
182
+ > **Mode priority:** When multiple mode params are present, the tool resolves by priority:
183
+ > `tilesDir` > `url`/`screenshotPath` > `filePath`/`sourceUrl`/`dataUrl`/`imageBase64`.
184
+ > Avoid passing params from different modes in the same call.
163
185
 
164
- Returns JSON metadata with grid dimensions, tile count, model used, estimated token cost, and per-tile file paths.
186
+ **Workflow:**
165
187
 
166
- ### `tiler_get_tiles`
188
+ The tool uses a two-step process to let you choose the right model before tiling:
167
189
 
168
- Returns tile images as base64 in batches of 5 for the LLM to see directly.
190
+ 1. **Compare** - Call with only the image source. Returns a comparison table showing tile counts and token estimates for each supported model, plus an interactive HTML preview.
191
+ 2. **Tile** - Call again with the chosen `model` + `outputDir` from step 1, plus:
192
+ - **Image sources:** re-include your original source param (`filePath`, `sourceUrl`, etc.)
193
+ - **Captures:** use `screenshotPath` from step 1 (not the original `url`)
169
194
 
170
- | Parameter | Type | Required | Default | Description |
171
- |---|---|---|---|---|
172
- | `tilesDir` | string | yes | - | Path to tiles directory (from `tiler_tile_image`) |
173
- | `start` | number | no | 0 | Start tile index (0-based, inclusive) |
174
- | `end` | number | no | start + 4 | End tile index (0-based, inclusive) |
175
-
176
- Returns text labels + image content blocks. Includes pagination hint for the next batch.
195
+ > **Skip the comparison step:** Provide `model` and `outputDir` on the first call to tile immediately.
177
196
 
178
- ### `tiler_recommend_settings`
197
+ > **Interactive model picker:** Clients that support MCP elicitation get a dropdown picker instead of the comparison table.
179
198
 
180
- Dry-run estimator: reads image dimensions and returns cost estimates **without tiling**.
199
+ #### Parameters - Image Source (tile-image mode)
181
200
 
182
201
  | Parameter | Type | Required | Default | Description |
183
202
  |---|---|---|---|---|
184
- | `filePath` | string | no* | - | Path to image file |
185
- | `sourceUrl` | string | no* | - | HTTPS URL to download from |
186
- | `dataUrl` | string | no* | - | Data URL with base64 image |
187
- | `imageBase64` | string | no* | - | Raw base64 image data |
188
- | `model` | string | no | `"claude"` | Target vision model |
189
- | `tileSize` | number | no | Model default | Override tile size (skips heuristics) |
190
- | `maxDimension` | number | no | - | Override max dimension (skips heuristics) |
191
- | `intent` | string | no | - | `"text_heavy"`, `"ui_screenshot"`, `"diagram"`, `"photo"`, `"general"` |
192
- | `budget` | string | no | - | `"low"`, `"default"`, `"max_detail"` |
193
-
194
- *At least one image source required.
195
-
196
- Returns JSON with recommended settings, rationale, image info, grid estimate, and a comparison across all 4 models.
203
+ | `filePath` | string | no* | - | Absolute or relative path to the image file |
204
+ | `sourceUrl` | string | no* | - | HTTPS URL to download the image from (max 50MB, 30s timeout) |
205
+ | `dataUrl` | string | no* | - | Data URL with base64-encoded image |
206
+ | `imageBase64` | string | no* | - | Raw base64-encoded image data |
197
207
 
198
- ### `tiler_prepare_image`
208
+ *At least one image source is required for tile-image mode.
199
209
 
200
- One-shot convenience tool: tiles an image AND returns the first batch of tiles in a single call.
210
+ #### Parameters - URL Capture (capture mode)
201
211
 
202
212
  | Parameter | Type | Required | Default | Description |
203
213
  |---|---|---|---|---|
204
- | `filePath` | string | no* | - | Path to image file |
205
- | `sourceUrl` | string | no* | - | HTTPS URL to download from |
206
- | `dataUrl` | string | no* | - | Data URL with base64 image |
207
- | `imageBase64` | string | no* | - | Raw base64 image data |
208
- | `model` | string | no | `"claude"` | Target vision model |
209
- | `tileSize` | number | no | Model default | Override tile size |
210
- | `maxDimension` | number | no | `10000` | Max dimension for auto-downscaling |
211
- | `outputDir` | string | no | `tiles/{name}` subfolder | Directory to save tiles |
212
- | `page` | number | no | `0` | Tile page (0 = tiles 0-4, 1 = tiles 5-9, etc.) |
213
-
214
- *At least one image source required.
215
-
216
- Returns tiling metadata + up to 5 tile images inline. Saves a round-trip compared to calling `tiler_tile_image` then `tiler_get_tiles` separately.
217
-
218
- ## Usage
219
-
220
- ### Quick Start
221
-
222
- ```
223
- > Tile the screenshot at ./screenshots/full-page.png and analyze the layout
214
+ | `url` | string | no | - | URL of the web page to capture. Requires Chrome/Chromium installed (or `CHROME_PATH` env var). |
215
+ | `screenshotPath` | string | no | - | Path to a previously captured screenshot. Skips URL capture when provided. |
216
+ | `viewportWidth` | number | no | Auto-detect (fallback 1280) | Browser viewport width in pixels (320-3840) |
217
+ | `waitUntil` | string | no | `"load"` | When to consider the page loaded: `"load"`, `"networkidle"`, or `"domcontentloaded"` |
218
+ | `delay` | number | no | `0` | Additional delay in ms after page load (max 30000) |
224
219
 
225
- Your MCP client will:
226
- 1. Call tiler_recommend_settings(filePath="./screenshots/full-page.png") to preview token costs
227
- 2. Call tiler_prepare_image(filePath="./screenshots/full-page.png") to tile and get the first batch
228
- 3. Call tiler_get_tiles(tilesDir="...", start=5, end=9) for subsequent batches
229
- ```
220
+ Supports scroll-stitching for pages taller than 16,384px. Automatically triggers lazy-loaded images (`loading="lazy"`) before capture by scrolling through the page. Pages without lazy images are unaffected.
230
221
 
231
- ### With Other Models
222
+ #### Parameters - Tile Retrieval (pagination mode)
232
223
 
233
- ```
234
- > Tile this image for GPT-4o analysis
235
-
236
- Your MCP client will:
237
- 1. Call tiler_tile_image(filePath="./image.png", model="openai")
238
- 2. Tiles sized at 768px for OpenAI's vision pipeline
239
- ```
240
-
241
- ### Auto-Downscaling
242
-
243
- Images over 10,000px are automatically downscaled before tiling. You can customize the limit:
244
-
245
- ```
246
- > Tile this 7680x4032 screenshot but downscale to 2048px first to save tokens
247
-
248
- Your MCP client will:
249
- 1. Call tiler_tile_image(filePath="./image.png", maxDimension=2048)
250
- 2. Image is downscaled to 2048x1076 before tiling
251
- 3. Fewer tiles = lower token cost (e.g., 4 tiles instead of 32)
252
- ```
253
-
254
- To disable auto-downscaling entirely:
255
-
256
- ```
257
- > Tile this image at full resolution, no downscaling
258
-
259
- Your MCP client will:
260
- 1. Call tiler_tile_image(filePath="./image.png", maxDimension=0)
261
- 2. Image is tiled at its original dimensions
262
- ```
263
-
264
- ### Estimating Costs
265
-
266
- Use `tiler_recommend_settings` to preview token costs before tiling:
267
-
268
- ```
269
- > How many tokens would it cost to tile this 3600x22810 screenshot?
270
-
271
- Your MCP client will:
272
- 1. Call tiler_recommend_settings(filePath="./screenshot.png")
273
- 2. See cost estimates for all 4 models
274
- 3. Make an informed decision before committing to tiling
275
- ```
276
-
277
- With intent and budget hints:
278
-
279
- ```
280
- > Estimate costs for this long document screenshot, keeping tokens low
281
-
282
- Your MCP client will:
283
- 1. Call tiler_recommend_settings(filePath="./doc.png", intent="text_heavy", budget="low")
284
- 2. Get optimized maxDimension recommendation for text-heavy content
285
- ```
286
-
287
- ### Using URLs / Base64
288
-
289
- All image-accepting tools (`tiler_tile_image`, `tiler_recommend_settings`, `tiler_prepare_image`) support multiple input sources:
290
-
291
- ```
292
- > Tile this image from a URL
293
-
294
- Your MCP client will:
295
- 1. Call tiler_tile_image(sourceUrl="https://example.com/screenshot.png")
296
-
297
- > Tile this base64 image
298
-
299
- Your MCP client will:
300
- 1. Call tiler_tile_image(imageBase64="iVBORw0KGgo...")
301
- ```
302
-
303
- ### One-Shot Usage
304
-
305
- Use `tiler_prepare_image` to tile and get the first batch in one call:
306
-
307
- ```
308
- > Analyze this screenshot
309
-
310
- Your MCP client will:
311
- 1. Call tiler_prepare_image(filePath="./screenshot.png")
312
- 2. Get tiling metadata + first 5 tiles in a single response
313
- 3. Continue with tiler_get_tiles for remaining tiles if needed
314
- ```
315
-
316
- ### Typical Workflow
317
-
318
- 1. Capture a full-page screenshot with your browser extension
319
- 2. Ask your AI assistant: _"Tile `/path/to/screencapture-localhost-3000.png` and review all sections"_
320
- 3. The client pages through tiles automatically, analyzing each batch
321
-
322
- ## Token Cost Reference
323
-
324
- Costs vary by model. Formula: `tokens = totalTiles x tokensPerTile`
325
-
326
- ### Claude (1092px tiles, 1590 tokens/tile)
327
-
328
- | Image Dimensions | Tiles | Estimated Tokens |
329
- |---|---|---|
330
- | 1440x3000 | 6 | ~9,540 |
331
- | 3600x5000 | 20 | ~31,800 |
332
- | 3600x22810 | 84 | ~133,560 |
333
-
334
- ### OpenAI - GPT-4o/o-series (768px tiles, 765 tokens/tile)
335
-
336
- | Image Dimensions | Tiles | Estimated Tokens |
337
- |---|---|---|
338
- | 1440x3000 | 8 | ~6,120 |
339
- | 3600x5000 | 35 | ~26,775 |
340
- | 3600x22810 | 150 | ~114,750 |
341
-
342
- ### Gemini (768px tiles, 258 tokens/tile)
343
-
344
- | Image Dimensions | Tiles | Estimated Tokens |
345
- |---|---|---|
346
- | 1440x3000 | 8 | ~2,064 |
347
- | 3600x5000 | 35 | ~9,030 |
348
- | 3600x22810 | 150 | ~38,700 |
349
-
350
- ### Gemini 3 (1536px tiles, 1120 tokens/tile)
224
+ | Parameter | Type | Required | Default | Description |
225
+ |---|---|---|---|---|
226
+ | `tilesDir` | string | no | - | Path to tiles directory (returned by a previous tiling call as `outputDir`) |
227
+ | `start` | number | no | `0` | Start tile index (0-based, inclusive) |
228
+ | `end` | number | no | start + 4 | End tile index (0-based, inclusive). Max 5 tiles per batch. |
351
229
 
352
- | Image Dimensions | Tiles | Estimated Tokens |
353
- |---|---|---|
354
- | 1440x3000 | 2 | ~2,240 |
355
- | 3600x5000 | 12 | ~13,440 |
356
- | 3600x22810 | 45 | ~50,400 |
230
+ #### Parameters - Tiling Config (shared across modes)
357
231
 
358
- > **Note:** Gemini 3 uses a fixed 1120 tokens per image regardless of dimensions. More tiles = more total tokens but better detail preservation.
232
+ | Parameter | Type | Required | Default | Description |
233
+ |---|---|---|---|---|
234
+ | `model` | string | no | Auto (cheapest) | Target vision model: `"claude"`, `"openai"`, `"gemini"`, `"gemini3"`. Auto-selects the most token-efficient preset when omitted. |
235
+ | `tileSize` | number | no | Model default | Tile size in pixels. Clamped to model's supported range with a warning if out of bounds. |
236
+ | `maxDimension` | number | no | `10000` | Max dimension in px (0 to disable, or 256-65536). Values 1-255 are silently clamped to 256. Pre-downscales the image so its longest side fits within this value before tiling. |
237
+ | `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). |
238
+ | `page` | number | no | `0` | Tile page to return (0 = first 5, 1 = next 5, etc.) |
239
+ | `format` | string | no | `"webp"` | Output format: `"webp"` (smaller, default) or `"png"` (lossless) |
240
+ | `includeMetadata` | boolean | no | `true` | Analyze each tile and return content hints (blank, low-detail, mixed, high-detail) and brightness stats |
241
+
242
+ ## Behaviors
243
+
244
+ - **Source conflict:** Multiple image source params → highest-precedence source is used with a warning (`filePath` > `sourceUrl` > `dataUrl` > `imageBase64`).
245
+ - **Re-entry:** If `outputDir` already has a preview from the comparison step, the server skips straight to tiling.
246
+ - **Elicitation cancellation:** Cancelling the model picker returns `"Tiling cancelled by user."` without tiling.
247
+ - **Versioned output:** Repeated tiling of the same source creates `_v1`, `_v2`, ..., `_vN` directories to avoid overwriting.
248
+ - **Tile naming:** `tile_ROW_COL.{format}` with zero-padded 3-digit indices (e.g., `tile_000_003.webp`), row-by-row, left-to-right.
359
249
 
360
250
  ## Supported Formats
361
251
 
@@ -363,21 +253,27 @@ PNG, JPEG, WebP, TIFF, GIF
363
253
 
364
254
  ## Troubleshooting
365
255
 
366
- **"Command not found"** - Make sure Node.js 18+ is installed: `node --version`
256
+ **"Command not found"** - Make sure Node.js 20+ is installed: `node --version`
367
257
 
368
258
  **"File not found"** - Use absolute paths. Relative paths resolve from the MCP server's working directory.
369
259
 
370
260
  **"MCP tools not available"** - Restart your MCP client after config changes. In Claude Code, run `/mcp` to check server status.
371
261
 
262
+ **"Chrome not found"** - Install Google Chrome or set the `CHROME_PATH` environment variable to the Chrome executable (must be an absolute path).
263
+
264
+ **Running as root / in Docker** - Set `CHROME_NO_SANDBOX=1` to launch Chrome without sandbox (also enabled automatically when running as root).
265
+
266
+ **`viewportWidth` auto-detection** - Auto-detection of screen width works on macOS only. On other platforms, falls back to 1280px.
267
+
372
268
  ## Security
373
269
 
374
- 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.
270
+ 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.
375
271
 
376
272
  **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.
377
273
 
378
274
  ## Requirements
379
275
 
380
- - Node.js 18+
276
+ - Node.js 20+
381
277
  - Compatible MCP client (Claude Code, Codex CLI, VS Code, Cursor, Claude Desktop)
382
278
 
383
279
  ## License
@@ -1,4 +1,4 @@
1
- export declare const VISION_MODELS: readonly ["claude", "openai", "gemini", "gemini3"];
1
+ export declare const VISION_MODELS: readonly ["claude", "openai", "gemini3", "gemini"];
2
2
  export type VisionModel = (typeof VISION_MODELS)[number];
3
3
  export interface ModelVisionConfig {
4
4
  defaultTileSize: number;
@@ -25,8 +25,27 @@ export declare const ALLOWED_URL_PROTOCOLS: readonly ["https:"];
25
25
  export declare const MAX_BASE64_LENGTH = 67108864;
26
26
  export declare const MAX_DATA_URL_LENGTH: number;
27
27
  export declare const MIN_REMAINDER_RATIO = 0.15;
28
- export declare const IMAGE_INTENTS: readonly ["text_heavy", "ui_screenshot", "diagram", "photo", "general"];
29
- export type ImageIntent = (typeof IMAGE_INTENTS)[number];
30
- export declare const BUDGET_LEVELS: readonly ["low", "default", "max_detail"];
31
- export type BudgetLevel = (typeof BUDGET_LEVELS)[number];
28
+ export declare const SHARP_OPERATION_TIMEOUT_MS = 30000;
29
+ export declare const TILE_OUTPUT_FORMATS: readonly ["png", "webp"];
30
+ export type TileOutputFormat = (typeof TILE_OUTPUT_FORMATS)[number];
31
+ export declare const WEBP_QUALITY = 80;
32
+ export declare const MAX_STITCH_BYTES: number;
33
+ export declare const MAX_CAPTURE_HEIGHT = 200000;
34
+ export declare const CHROME_MAX_CAPTURE_HEIGHT = 16384;
35
+ export declare const CAPTURE_DEFAULT_VIEWPORT_WIDTH = 1280;
36
+ export declare const CAPTURE_DEFAULT_VIEWPORT_HEIGHT = 800;
37
+ export declare const CAPTURE_DEFAULT_TIMEOUT_MS = 60000;
38
+ export declare const CAPTURE_STITCH_SETTLE_MS = 100;
39
+ export declare const CAPTURE_IDLE_TIMEOUT_MS = 500;
40
+ export declare const WAIT_UNTIL_OPTIONS: readonly ["load", "networkidle", "domcontentloaded"];
41
+ export type WaitUntil = (typeof WAIT_UNTIL_OPTIONS)[number];
42
+ export declare const ALLOWED_CAPTURE_PROTOCOLS: readonly ["https:", "http:"];
43
+ export declare const LAZY_LOAD_SCROLL_PAUSE_MS = 100;
44
+ export declare const LAZY_LOAD_IMAGE_TIMEOUT_MS = 5000;
45
+ export declare const LAZY_LOAD_TOTAL_TIMEOUT_MS = 15000;
46
+ export declare const MAX_IMAGE_PIXELS = 256000000;
47
+ export declare const MAX_CHROME_STDERR_BYTES = 1048576;
48
+ export declare const MAX_CHROME_JSON_BYTES = 1048576;
49
+ export declare const MAX_PREVIEW_PIXELS = 16000000;
50
+ export declare const MIN_PREVIEW_WIDTH = 800;
32
51
  //# 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,mBAAmB,OAAO,CAAC;AAGxC,eAAO,MAAM,aAAa,yEAA0E,CAAC;AACrG,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,aAAa,2CAA4C,CAAC;AACvE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC"}
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,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"}
package/dist/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export const VISION_MODELS = ["claude", "openai", "gemini", "gemini3"];
1
+ export const VISION_MODELS = ["claude", "openai", "gemini3", "gemini"];
2
2
  export const MODEL_CONFIGS = {
3
3
  claude: {
4
4
  defaultTileSize: 1092,
@@ -49,7 +49,31 @@ export const MAX_BASE64_LENGTH = 67_108_864; // ~50MB decoded (base64 is ~4/3x)
49
49
  export const MAX_DATA_URL_LENGTH = MAX_BASE64_LENGTH + 256; // base64 payload + data URL prefix overhead
50
50
  // Remainder absorption: if a remainder strip is < 15% of tileSize, absorb it into the last tile
51
51
  export const MIN_REMAINDER_RATIO = 0.15;
52
- // Intent and budget enums for recommend-settings
53
- export const IMAGE_INTENTS = ["text_heavy", "ui_screenshot", "diagram", "photo", "general"];
54
- export const BUDGET_LEVELS = ["low", "default", "max_detail"];
52
+ // Sharp operation timeout (guards against hangs on corrupted images)
53
+ export const SHARP_OPERATION_TIMEOUT_MS = 30_000; // 30 seconds
54
+ // Tile output formats
55
+ export const TILE_OUTPUT_FORMATS = ["png", "webp"];
56
+ export const WEBP_QUALITY = 80;
57
+ // URL capture
58
+ export const MAX_STITCH_BYTES = 500 * 1024 * 1024; // 500 MB cumulative buffer limit for scroll-stitching
59
+ export const MAX_CAPTURE_HEIGHT = 200_000; // max page height for scroll-stitching (~12 segments)
60
+ export const CHROME_MAX_CAPTURE_HEIGHT = 16384;
61
+ export const CAPTURE_DEFAULT_VIEWPORT_WIDTH = 1280;
62
+ export const CAPTURE_DEFAULT_VIEWPORT_HEIGHT = 800;
63
+ export const CAPTURE_DEFAULT_TIMEOUT_MS = 60_000;
64
+ export const CAPTURE_STITCH_SETTLE_MS = 100;
65
+ export const CAPTURE_IDLE_TIMEOUT_MS = 500;
66
+ export const WAIT_UNTIL_OPTIONS = ["load", "networkidle", "domcontentloaded"];
67
+ export const ALLOWED_CAPTURE_PROTOCOLS = ["https:", "http:"];
68
+ // Lazy loading
69
+ export const LAZY_LOAD_SCROLL_PAUSE_MS = 100;
70
+ export const LAZY_LOAD_IMAGE_TIMEOUT_MS = 5000;
71
+ export const LAZY_LOAD_TOTAL_TIMEOUT_MS = 15_000;
72
+ // Security limits
73
+ export const MAX_IMAGE_PIXELS = 256_000_000; // 256 megapixels (~1GB decoded RGBA)
74
+ export const MAX_CHROME_STDERR_BYTES = 1_048_576; // 1MB
75
+ export const MAX_CHROME_JSON_BYTES = 1_048_576; // 1MB
76
+ // Preview rendering
77
+ export const MAX_PREVIEW_PIXELS = 16_000_000; // Safari's canvas/image rendering limit
78
+ export const MIN_PREVIEW_WIDTH = 800; // Floor that prevents tall-image width crushing
55
79
  //# 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,QAAQ,EAAE,SAAS,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,gGAAgG;AAChG,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,iDAAiD;AACjD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAU,CAAC;AAGrG,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,CAAU,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,20 +2,33 @@
2
2
  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
- import { registerTileImageTool } from "./tools/tile-image.js";
6
- import { registerGetTilesTool } from "./tools/get-tiles.js";
7
- import { registerRecommendSettingsTool } from "./tools/recommend-settings.js";
8
- import { registerPrepareImageTool } from "./tools/prepare-image.js";
5
+ import { registerTilerTool } from "./tools/tiler.js";
9
6
  const require = createRequire(import.meta.url);
10
7
  const { version } = require("../package.json");
8
+ const args = process.argv.slice(2);
9
+ if (args.includes("--version") || args.includes("-v")) {
10
+ console.log(version);
11
+ process.exit(0);
12
+ }
13
+ if (args.includes("--help") || args.includes("-h")) {
14
+ console.log(`image-tiler-mcp-server v${version}
15
+
16
+ MCP server that splits large images into optimally-sized tiles for LLM vision.
17
+ Runs on stdio transport — designed to be launched by an MCP client.
18
+
19
+ Usage:
20
+ image-tiler-mcp-server Start the MCP server (stdio)
21
+ image-tiler-mcp-server --version Print version and exit
22
+ image-tiler-mcp-server --help Print this help and exit
23
+
24
+ More info: https://github.com/keiver/image-tiler-mcp-server`);
25
+ process.exit(0);
26
+ }
11
27
  const server = new McpServer({
12
28
  name: "image-tiler-mcp-server",
13
29
  version,
14
30
  });
15
- registerTileImageTool(server);
16
- registerGetTilesTool(server);
17
- registerRecommendSettingsTool(server);
18
- registerPrepareImageTool(server);
31
+ registerTilerTool(server);
19
32
  async function runStdio() {
20
33
  const transport = new StdioServerTransport();
21
34
  await server.connect(transport);
@@ -27,6 +40,14 @@ async function shutdown() {
27
40
  }
28
41
  process.on("SIGINT", shutdown);
29
42
  process.on("SIGTERM", shutdown);
43
+ process.on("uncaughtException", (error) => {
44
+ console.error("Uncaught exception:", error);
45
+ shutdown().catch(() => process.exit(1));
46
+ });
47
+ process.on("unhandledRejection", (reason) => {
48
+ console.error("Unhandled rejection:", reason);
49
+ shutdown().catch(() => process.exit(1));
50
+ });
30
51
  runStdio().catch((error) => {
31
52
  console.error("Server error:", error);
32
53
  process.exit(1);
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,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,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,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,wBAAwB;IAC9B,OAAO;CACR,CAAC,CAAC;AAEH,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,6BAA6B,CAAC,MAAM,CAAC,CAAC;AACtC,wBAAwB,CAAC,MAAM,CAAC,CAAC;AAEjC,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,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;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,45 +1,23 @@
1
1
  import { z } from "zod";
2
- export declare const imageSourceFields: {
2
+ export declare const TilerInputSchema: {
3
3
  filePath: z.ZodOptional<z.ZodString>;
4
4
  sourceUrl: z.ZodOptional<z.ZodString>;
5
5
  dataUrl: z.ZodOptional<z.ZodString>;
6
6
  imageBase64: z.ZodOptional<z.ZodString>;
7
- };
8
- export declare const TileImageInputSchema: {
9
- model: z.ZodDefault<z.ZodEnum<["claude", "openai", "gemini", "gemini3"]>>;
10
- tileSize: z.ZodOptional<z.ZodNumber>;
11
- maxDimension: z.ZodDefault<z.ZodNumber>;
12
- outputDir: z.ZodOptional<z.ZodString>;
13
- filePath: z.ZodOptional<z.ZodString>;
14
- sourceUrl: z.ZodOptional<z.ZodString>;
15
- dataUrl: z.ZodOptional<z.ZodString>;
16
- imageBase64: z.ZodOptional<z.ZodString>;
17
- };
18
- export declare const GetTilesInputSchema: {
19
- tilesDir: z.ZodString;
7
+ url: z.ZodOptional<z.ZodString>;
8
+ viewportWidth: z.ZodOptional<z.ZodNumber>;
9
+ waitUntil: z.ZodDefault<z.ZodEnum<["load", "networkidle", "domcontentloaded"]>>;
10
+ delay: z.ZodDefault<z.ZodNumber>;
11
+ screenshotPath: z.ZodOptional<z.ZodString>;
12
+ tilesDir: z.ZodOptional<z.ZodString>;
20
13
  start: z.ZodDefault<z.ZodNumber>;
21
14
  end: z.ZodOptional<z.ZodNumber>;
22
- };
23
- export declare const RecommendSettingsInputSchema: {
24
- model: z.ZodOptional<z.ZodEnum<["claude", "openai", "gemini", "gemini3"]>>;
15
+ model: z.ZodOptional<z.ZodEnum<["claude", "openai", "gemini3", "gemini"]>>;
25
16
  tileSize: z.ZodOptional<z.ZodNumber>;
26
- maxDimension: z.ZodOptional<z.ZodNumber>;
27
- intent: z.ZodOptional<z.ZodEnum<["text_heavy", "ui_screenshot", "diagram", "photo", "general"]>>;
28
- budget: z.ZodOptional<z.ZodEnum<["low", "default", "max_detail"]>>;
29
- filePath: z.ZodOptional<z.ZodString>;
30
- sourceUrl: z.ZodOptional<z.ZodString>;
31
- dataUrl: z.ZodOptional<z.ZodString>;
32
- imageBase64: z.ZodOptional<z.ZodString>;
33
- };
34
- export declare const PrepareImageInputSchema: {
35
- model: z.ZodDefault<z.ZodEnum<["claude", "openai", "gemini", "gemini3"]>>;
36
- tileSize: z.ZodOptional<z.ZodNumber>;
37
- maxDimension: z.ZodDefault<z.ZodNumber>;
17
+ maxDimension: z.ZodEffects<z.ZodDefault<z.ZodNumber>, number, number | undefined>;
38
18
  outputDir: z.ZodOptional<z.ZodString>;
39
19
  page: z.ZodDefault<z.ZodNumber>;
40
- filePath: z.ZodOptional<z.ZodString>;
41
- sourceUrl: z.ZodOptional<z.ZodString>;
42
- dataUrl: z.ZodOptional<z.ZodString>;
43
- imageBase64: z.ZodOptional<z.ZodString>;
20
+ format: z.ZodDefault<z.ZodEnum<["png", "webp"]>>;
21
+ includeMetadata: z.ZodDefault<z.ZodBoolean>;
44
22
  };
45
23
  //# sourceMappingURL=index.d.ts.map
@@ -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;AAuBxB,eAAO,MAAM,iBAAiB;;;;;CAqB7B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;CAmChC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;CAqB/B,CAAC;AAEF,eAAO,MAAM,4BAA4B;;;;;;;;;;CA8BxC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;CAoCnC,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;;;;;;;;;;;;;;;;;;;;CAmI5B,CAAC"}