Skip to main content
Glama
README.md
# overtooled-mcp

MCP server for local file conversion, analysis, and image processing. Images, audio, video, documents, and structured data -- all processed locally, nothing uploaded anywhere.

**44 supported formats** across 5 categories. **7 tools** for converting, analyzing, processing, merging, and generating files.

## Install

```bash
npx overtooled-mcp
```

Or install globally:

```bash
npm install -g overtooled-mcp
```

Requires **Node.js >= 18**.

## Configure

### Claude Code / Claude Desktop

Add to your MCP settings:

```json
{
  "mcpServers": {
    "overtooled": {
      "command": "npx",
      "args": ["-y", "overtooled-mcp"]
    }
  }
}
```

### Cursor

Add to `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "overtooled": {
      "command": "npx",
      "args": ["-y", "overtooled-mcp"]
    }
  }
}
```

## Tools

### `convert_file`

Convert a file from one format to another.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `input_path` | string | Yes | Absolute path to the source file |
| `output_format` | string | Yes | Target format as MIME type (`image/png`) or extension (`png`) |
| `output_path` | string | No | Output file path. Defaults to input location with new extension |
| `options` | object | No | Format-specific options (e.g. `{ quality: 80 }`) |

```
input_path: "/photos/vacation.heic"
output_format: "jpg"
options: { quality: 90 }
```

Returns the output path, input/output sizes, and format-specific metadata (dimensions for images, duration for audio/video, etc.).

---

### `analyze_file`

Get detailed metadata about any file. For images: dimensions, color space, DPI, EXIF. For audio/video: duration, codec, bitrate, sample rate. For all files: size, format detection, entropy.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `input_path` | string | Yes | Absolute path to the file to analyze |
| `include_exif` | boolean | No | Include full EXIF data for images (default: `true`) |

```
input_path: "/photos/sunset.jpg"
```

Example output:

```json
{
  "file": "sunset.jpg",
  "size": 2457600,
  "sizeHuman": "2.3 MB",
  "format": "image/jpeg",
  "category": "image",
  "entropy": 7.45,
  "width": 3840,
  "height": 2160,
  "colorSpace": "srgb",
  "dpi": 72,
  "exif": { "Make": "Canon", "Model": "EOS 5D", "FocalLength": 50 }
}
```

For audio/video files, returns duration, codec, bitrate, sample rate, channels, and stream details.

---

### `process_image`

Apply one or more image operations: resize, compress, rotate, flip, blur, sharpen, grayscale, negate, strip metadata, or change format. Operations are chained in order.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `input_path` | string | Yes | Absolute path to the source image |
| `output_path` | string | No | Output path. Defaults to `input_processed.[ext]` |
| `operations` | array | Yes | Array of operations to apply in order (min 1) |

**Operations:**

| Type | Parameters | Description |
|------|-----------|-------------|
| `resize` | `width`, `height`, `fit` | Scale image. `fit`: cover, contain, fill, inside (default), outside |
| `compress` | `quality` (1-100, default 80) | Reduce file size |
| `rotate` | `angle` (degrees) | Rotate by arbitrary angle |
| `flip` | -- | Flip vertically |
| `flop` | -- | Flip horizontally |
| `blur` | `sigma` (0.3-100, default 3) | Gaussian blur |
| `sharpen` | `sigma` (default 1) | Sharpen edges |
| `grayscale` | -- | Convert to grayscale |
| `negate` | -- | Invert colors |
| `strip_metadata` | -- | Remove EXIF and other metadata |
| `format` | `format`, `quality` | Convert to jpeg, png, webp, tiff, or avif |

```
input_path: "/photos/large.jpg"
operations: [
  { type: "resize", width: 1280 },
  { type: "compress", quality: 75 },
  { type: "format", format: "webp" }
]
```

---

### `merge_files`

Combine multiple files into one. Supports PDF merging, images-to-PDF, text concatenation, and CSV merging.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `input_paths` | array | Yes | Array of absolute file paths (min 2) |
| `output_path` | string | Yes | Absolute path for the merged output |
| `mode` | string | No | `auto` (default), `pdf_merge`, `images_to_pdf`, `concatenate`, `csv_merge` |
| `options.separator` | string | No | Separator between concatenated files (default: newline) |
| `options.page_size` | string | No | PDF page size: `a4` (default), `letter`, `legal` |
| `options.landscape` | boolean | No | Landscape orientation for PDF (default: `false`) |

Auto-detection: all PDFs -> `pdf_merge`, all images -> `images_to_pdf`, all CSVs -> `csv_merge`, otherwise -> `concatenate`.

```
input_paths: ["/docs/ch1.pdf", "/docs/ch2.pdf", "/docs/ch3.pdf"]
output_path: "/docs/combined.pdf"
```

---

### `generate_file`

Generate placeholder/test files from scratch. No input file needed.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string | Yes | `text`, `image`, `audio`, `video`, or `data` |
| `output_path` | string | Yes | Absolute path for the generated file |

**Text options** (lorem ipsum):

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `text_mode` | string | `paragraphs` | `paragraphs`, `sentences`, or `words` |
| `text_count` | number | 3 | Number of units to generate |

**Image options** (placeholder with dimensions label, requires sharp):

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `width` | number | 800 | Width in pixels (max 4096) |
| `height` | number | 600 | Height in pixels (max 4096) |
| `bg_color` | string | `#cccccc` | Background color (hex) |
| `text_color` | string | `#666666` | Text color (hex) |
| `label` | string | `WIDTHxHEIGHT` | Custom text overlay |
| `image_format` | string | `png` | `png`, `jpeg`, or `webp` |
| `quality` | number | 92 | Quality for JPEG/WebP (1-100) |

**Audio options** (WAV, pure JS -- no ffmpeg needed):

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `audio_type` | string | `tone` | `tone`, `noise`, `chirp`, or `silence` |
| `frequency` | number | 440 | Tone frequency in Hz |
| `duration` | number | 3 | Duration in seconds (max 30) |
| `sample_rate` | number | 44100 | Sample rate |
| `waveform` | string | `sine` | `sine`, `square`, `sawtooth`, or `triangle` |

**Video options** (MP4/WebM with test patterns, requires ffmpeg):

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `width` | number | 640 | Width in pixels (max 1920) |
| `height` | number | 480 | Height in pixels (max 1080) |
| `duration` | number | 3 | Duration in seconds (max 30) |
| `fps` | number | 30 | Frames per second (max 60) |
| `video_format` | string | `mp4` | `mp4` or `webm` |
| `video_pattern` | string | `solid` | `solid`, `counter`, `gradient`, or `bars` (SMPTE) |
| `bg_color` | string | `#336699` | Background color (hex) |
| `text_color` | string | `#ffffff` | Text color (hex) |

**Data options** (mock JSON/CSV):

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `data_format` | string | `json` | `json` or `csv` |
| `data_preset` | string | `user-profile` | `user-profile`, `address-book`, `employee-list`, or `products` |
| `row_count` | number | 10 | Number of rows (max 1000) |

```
type: "image"
output_path: "/tmp/placeholder.png"
width: 1280
height: 720
label: "Hero Image"
```

```
type: "audio"
output_path: "/tmp/test-tone.wav"
audio_type: "tone"
frequency: 1000
duration: 5
waveform: "square"
```

---

### `list_formats`

List all supported formats, optionally filtered by category or by what a given input format can convert to.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `category` | string | No | Filter by category: `image`, `audio`, `video`, `text`, `document` |
| `input_format` | string | No | Show only formats this input can convert to (MIME or extension) |

```
category: "image"
```
```
input_format: "csv"    # shows what CSV can convert to
```

---

### `get_conversion_options`

Get available options and their defaults for a specific output format.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `output_format` | string | Yes | Target format as MIME type or extension |

```
output_format: "mp3"
```

Returns format info plus configurable options (quality, bitrate, compression level, etc.).

## Supported Formats

### Images (9 input, 4 output)

| Format | Input | Output | Options |
|--------|:-----:|:------:|---------|
| PNG | yes | yes | -- |
| JPEG | yes | yes | quality: 1-100 (default 92) |
| WebP | yes | yes | quality: 1-100 (default 80) |
| GIF | yes | -- | -- |
| BMP | yes | -- | -- |
| SVG | yes | -- | -- |
| HEIC | yes | -- | -- |
| HEIF | yes | -- | -- |
| TIFF | yes | yes | -- |

### Audio (8 input, 7 output)

| Format | Input | Output | Options |
|--------|:-----:|:------:|---------|
| WAV | yes | yes | bitDepth: 16/24/32 |
| MP3 | yes | yes | bitrate: 128/192/256/320 kbps |
| FLAC | yes | yes | compressionLevel: 0-8 |
| OGG | yes | -- | -- |
| AAC | yes | yes | bitrate: 128/192/256/320 kbps |
| M4A | yes | yes | bitrate: 128/192/256/320 kbps |
| Opus | yes | yes | bitrate: 64/128/192/256 kbps |
| AIFF | yes | yes | bitDepth: 16/24/32 |

### Video (6 input, 6 output)

| Format | Input | Output | Options |
|--------|:-----:|:------:|---------|
| MP4 | yes | yes | crf: 0-51 (default 28), preset, maxHeight |
| WebM | yes | yes | crf: 0-63 (default 32), preset, maxHeight |
| MOV | yes | yes | crf: 0-51 (default 28), preset, maxHeight |
| AVI | yes | -- | -- |
| MKV | yes | yes | crf: 0-51 (default 28), preset, maxHeight |
| MPEG-TS | yes | yes | crf: 0-51 (default 28), preset, maxHeight |
| GIF | -- | yes | fps: 5-30 (default 10), maxHeight |

**Video options:** `preset` (ultrafast/fast/medium/slow), `maxHeight` (4K/1440/1080/720/480/360), `stripAudio` (boolean).

### Data (9 input, 10 output)

| Format | Input | Output | Options |
|--------|:-----:|:------:|---------|
| JSON | yes | yes | indent: 0-8 (default 2) |
| CSV | yes | yes | delimiter: comma/semicolon/pipe |
| TSV | yes | yes | -- |
| XML | yes | yes | indent: 0-8 (default 2) |
| YAML | yes | yes | -- |
| TOML | yes | yes | -- |
| INI | yes | yes | -- |
| XLSX | yes | yes | -- |
| SQL | -- | yes | tableName, dialect: insert/create-insert |

### Markup

| Format | Input | Output |
|--------|:-----:|:------:|
| Markdown | yes | yes |
| HTML | yes | yes |
| Plain Text | yes | yes |

### Documents (7 input, 1 output)

| Format | Input | Output | Notes |
|--------|:-----:|:------:|-------|
| PDF | yes | yes | Also converts to images or plain text |
| DOCX | yes | -- | Converts to PDF |
| PPTX | yes | -- | Converts to PDF |
| ODT | yes | -- | Converts to PDF |
| ODP | yes | -- | Converts to PDF |
| ODS | yes | -- | Converts to PDF |
| RTF | yes | -- | Converts to PDF |

**Cross-category:** All images, structured data, and markup can also convert to PDF.

## Conversion Rules

- **Within category:** Any input -> all outputs in the same category (excluding same format)
- **To PDF:** Images, structured data, and markup can all convert to PDF
- **From PDF:** PDF -> images (first page rendered) or plain text (extracted)
- **Documents -> PDF:** DOCX, PPTX, ODT, ODP, ODS, RTF all convert to PDF only
- **No cross-category:** Audio cannot convert to images, video cannot convert to data, etc.

## Dependencies

**Required (installed automatically):** Text and data conversion works out of the box.

**Optional (install for full format support):**

| Package | Enables | Install |
|---------|---------|---------|
| `sharp` | Image conversion and analysis | `npm install sharp` |
| `ffmpeg-static` | Audio/video conversion | `npm install ffmpeg-static` |
| `canvas` | PDF-to-image rendering | `npm install canvas` |

If `ffmpeg-static` is not installed, the server looks for `ffmpeg` in your system PATH.

Missing optional dependencies produce clear error messages telling you what to install.

## Architecture

Ported from [Overtooled](https://overtooled.com) -- a 179-tool browser utility suite. The conversion engines were adapted from client-side (Canvas, Web Audio, WebCodecs) to Node.js (sharp, FFmpeg, PDFKit).

```
src/
  server.ts              # MCP server + tool registration
  tools/                 # 7 tool handlers
    convert-file.ts
    analyze-file.ts
    process-image.ts
    merge-files.ts
    generate-file.ts
    list-formats.ts
    get-options.ts
  engines/               # Conversion engines by category
    engine-image.ts      # sharp
    engine-audio.ts      # FFmpeg CLI
    engine-video.ts      # FFmpeg CLI
    engine-text.ts       # Pure JS
    engine-pdf.ts        # PDFKit + pdfjs-dist + mammoth
  registry/
    format-registry.ts   # Format definitions + conversion matrix
  utils/
    mime.ts              # MIME detection from extension
    ffmpeg.ts            # FFmpeg binary resolution
    ffprobe.ts           # Media metadata extraction via ffprobe
    magic-bytes.ts       # File type detection by header bytes
```

### Engines

- **Text engine:** Pure JS. JSON, CSV, XML, YAML, TOML, INI, SQL, XLSX, Markdown, HTML. Two-stage conversion: parse input -> JS objects -> serialize output.
- **Image engine:** sharp for decode/encode. Handles HEIC, TIFF, SVG natively.
- **Audio engine:** FFmpeg CLI with codec selection and bitrate/quality mapping. 5-minute timeout.
- **Video engine:** FFmpeg CLI with CRF quality, resolution scaling, GIF palette generation. 10-minute timeout.
- **PDF engine:** PDFKit for generation, pdfjs-dist for text extraction, mammoth for DOCX, pdf-lib for merging.

## Development

```bash
npm run build          # Compile TypeScript
npm run dev            # Watch mode
npm test               # Run tests (vitest)
npm run test:watch     # Watch mode tests
npm run lint           # Type check
```

## License

MIT