Documentação

GetWebP MCP Server

Connect AI coding assistants to GetWebP image conversion through the Model Context Protocol (MCP).

GetWebP MCP Server

Connect AI coding assistants to GetWebP image conversion through the Model Context Protocol (MCP).

Install via npm: npx -y @getwebp/mcp-server — see Installation below for client-specific setup.

See also: Commands Reference | JSON Output | README


What Is MCP?#

MCP (Model Context Protocol) is an open standard that lets AI agents call local tools directly. Instead of generating shell commands for you to copy-paste, an agent with MCP access can convert images, scan directories, and check license status on its own.

Without MCPWith MCP
Agent generates a shell command, you run it manuallyAgent calls convert_images directly
You run --dry-run and paste the output backAgent calls scan_images and reads structured JSON
You check getwebp status and relay the resultAgent calls get_status and decides autonomously

Tools#

The MCP server exposes three tools. All return structured JSON that AI agents can parse directly.

convert_images#

Convert images to WebP or AVIF. Input formats accepted: .jpg, .jpeg, .png, .bmp, .webp, .heic, .heif, .avif.

Parameters:

ParameterTypeRequiredDefaultDescription
inputstringYes--Input file or directory path (absolute or relative)
outputstringNoSame as sourceOutput directory for converted files
qualitynumberNoauto (WebP) / 55 (AVIF)Quality 1--100. Omit for SSIM-driven auto-quality on WebP; AVIF uses an explicit default
recursivebooleanNofalseRecursively process subdirectories
skip_existingbooleanNotrueSkip files that already have a sibling in the chosen output format
format"webp" | "avif"No"webp"Output format. AVIF is slower but produces smaller files at similar quality
manifest_pathstringNo--If set, writes a JSON manifest with SHA-256 fingerprints for every successful conversion

Response:

{
  "success": true,
  "plan": "pro",
  "total": 3,
  "succeeded": 3,
  "failed": 0,
  "skipped": 0,
  "warnings": [],
  "results": [
    {
      "file": "/path/to/photo.jpg",
      "status": "success",
      "original_size": 204800,
      "new_size": 133120,
      "saved_ratio": 0.35
    }
  ]
}

On the Free plan, when the batch exceeds the per-run file cap, the response also includes skipped_by_limit (count of extras that were not processed) and an upgrade_url pointing to getwebp.com/pricing. When manifest_path is provided and at least one file converted successfully, the response includes manifest: { path, entries, generated_at }.

Notes:

  • Relative paths are resolved against the MCP server process's working directory.
  • Free plan: max 20 files per convert_images call (extras are returned as skipped_by_limit, not an error). Free calls are also subject to a rolling-window rate limit — see Rate Limits below.
  • Paid plans: unlimited files with parallel processing.

scan_images#

Scan a directory for convertible image files without modifying anything.

Parameters:

ParameterTypeRequiredDefaultDescription
pathstringYes--Directory or file path to scan (absolute or relative)
recursivebooleanNofalseRecursively scan subdirectories

Response:

{
  "total": 4,
  "files": [
    {
      "path": "/project/images/hero.jpg",
      "size": 204800,
      "format": "jpg",
      "has_webp": false
    },
    {
      "path": "/project/images/logo.png",
      "size": 51200,
      "format": "png",
      "has_webp": true
    }
  ]
}

The has_webp field indicates whether a .webp file with the same name already exists in the same directory. The format field normalizes .jpeg to jpg.


get_status#

Check the current license status and plan limits. No parameters required.

Response:

{
  "activated": true,
  "expired": false,
  "plan": "pro",
  "expires_at": "2027-04-01T00:00:00.000Z",
  "limits": {
    "max_files_per_run": null,
    "concurrent_workers": 7,
    "cooldown_seconds": 0
  },
  "tarpit_recent_calls": 0,
  "tarpit_next_delay_seconds": 0
}
FieldDescription
activatedWhether a license is currently active
expiredtrue only if a license was previously active and has expired
plan"free" or "pro"
expires_atISO 8601 expiry date (omitted on the Free plan)
limits.max_files_per_run20 on Free, null (unlimited) on paid plans
limits.concurrent_workers1 on Free, CPU cores - 1 on paid plans
limits.cooldown_seconds3 on Free, 0 on paid plans
tarpit_recent_callsCalls recorded in the current rolling window
tarpit_next_delay_secondsCooldown the next call would incur (0 if still in the free band)

An expired Pro license is treated as effectively Free for limits and rate-limits, but plan still reports the license type so clients can distinguish "never paid" from "paid but expired".


Error Model#

Every tool returns a JSON object. Success vs failure is signalled by the success boolean on convert_images (and the MCP isError flag the server sets when success === false).

Errors are structured:

{
  "success": false,
  "error": {
    "code": "rate_limited",
    "message": "Rate limit: 10s cooldown (4 calls in 60s).",
    "context": { "delay_seconds": 10, "recent_calls": 4 }
  },
  "upgrade_url": "https://getwebp.com/pricing"
}

Stable error codes include:

error.codeMeaning
rate_limitedFree-tier rolling-window limit hit. context carries delay_seconds and recent_calls. Surface the message; don't silently retry.
input_not_foundThe input path does not exist.
io_errorOther I/O failures.

Free-tier truncation (more than 20 files in a single call) is not an error: success: true, skipped_by_limit > 0, upgrade_url set.


Rate Limits#

The MCP server does not sleep on free-tier cooldowns — it returns rate_limited immediately so the agent can decide when to retry.

Call # in rolling 60s windowResult
1 -- 3No delay
4rate_limited with delay_seconds: 10
5rate_limited with delay_seconds: 20
6+rate_limited with delay_seconds: 30 (cap)

The counter is shared on disk with the CLI (see Shared state) — alternating CLI runs and MCP calls are rate-limited together, not per-tool.


Installation#

Prerequisites#

  • Node.js 18 or later
  • License (optional): The MCP server shares the CLI's local state directory. If you have already activated a license via getwebp auth <key>, the MCP server recognizes it automatically. Without a license, it runs on the Free plan.

Claude Desktop#

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent path on your OS:

{
  "mcpServers": {
    "getwebp": {
      "command": "npx",
      "args": ["-y", "@getwebp/mcp-server"]
    }
  }
}

Restart Claude Desktop after saving.

Cursor#

Edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "getwebp": {
      "command": "npx",
      "args": ["-y", "@getwebp/mcp-server"]
    }
  }
}

Other MCP Clients#

Any MCP client that supports the stdio transport can connect. Point it at:

npx -y @getwebp/mcp-server

Faster Startup (Optional)#

npx downloads the package on first run, which may be slow due to bundled WASM dependencies. For faster cold starts, install globally:

npm install -g @getwebp/mcp-server

Then replace the command and args in your configuration:

{
  "mcpServers": {
    "getwebp": {
      "command": "getwebp-mcp"
    }
  }
}

Integration Examples#

Claude Desktop#

After configuration, you can ask Claude to work with images directly:

"Convert all images in ./src/assets to WebP at quality 90."

Claude will call convert_images with {"input": "./src/assets", "quality": 90} and report the results, including file sizes and compression ratios.

"Re-encode the hero photos to AVIF instead."

Claude will call convert_images with {"input": "./src/assets/hero", "format": "avif"}.

"Which images in my project haven't been converted to WebP yet?"

Claude will call scan_images with {"path": ".", "recursive": true} and filter the results by has_webp: false.

"Am I on the free plan?"

Claude will call get_status and tell you your current plan, limits, and expiry date.

Cursor#

Cursor's agent mode can use GetWebP tools during code generation workflows:

  1. The agent scans the project for unconverted images using scan_images.
  2. It converts them with convert_images.
  3. It updates <img> tags in your source code to reference the new .webp files.

Typical Agent Workflow#

1. get_status        -- Check plan and limits
2. scan_images       -- Discover convertible files
3. convert_images    -- Convert the files (optionally with manifest_path)
4. Report results    -- Summarize savings to the user

Shared state with the CLI#

The MCP server is stateless except for one shared artefact: the CLI's on-disk license cache and rate-limit counter (usage.json), both stored under the platform-dependent state directory resolved by getStateDir():

  • macOS: ~/Library/Preferences/getwebp-nodejs/
  • Linux: ~/.config/getwebp/
  • Override: $GETWEBP_CONFIG_DIR (both CLI and MCP respect it)

License activation is CLI-owned — run getwebp auth <key> once and the MCP server picks up the cached JWT via the same loader.


Architecture#

The MCP server reuses the CLI's core modules directly (not via subprocess), ensuring identical conversion behavior:

AI Client (Claude Desktop / Cursor / ...)
        | stdio (JSON-RPC)
        v
   MCP Server (Node.js)
        |-- convert_images  --> processImages()       (cli/core/processor.ts)
        |-- scan_images     --> collectImageFiles()   (cli/core/file-scanner.ts)
        |-- get_status      --> checkLicense()        (cli/core/license.ts)
  • Transport: stdio (standard MCP transport, universally supported)
  • Runtime: Node.js >= 18
  • Package: @getwebp/mcp-server (npm)
  • Binary: getwebp-mcp

Free vs Pro#

Plan limits apply identically in the MCP server and the CLI.

LimitFreePro
Files per convert_images call20 (extras returned as skipped_by_limit)Unlimited
Per-file delay3sNone
Calls per 60s window3 free, then rate_limited with 10s / 20s / 30s cooldownsUnlimited
Parallel workers1 (serial)Auto (CPU cores - 1)
Output formatsWebP, AVIFWebP, AVIF

To upgrade, purchase a license at getwebp.com/pricing and activate it:

getwebp auth <your-license-key>

The MCP server picks up the new license automatically on its next tool call.


Troubleshooting#

Server not detected by the client#

  1. Verify Node.js >= 18 is installed: node --version
  2. Check that the config file path is correct for your client.
  3. Restart the client application after editing configuration.
  4. Test manually: npx -y @getwebp/mcp-server should start without output (it communicates via stdio).

First call is slow#

WASM codecs are initialized on the first conversion. Subsequent calls within the same server session are fast. AVIF output is noticeably slower than WebP — this is inherent to the codec, not a bug.

Free plan rate_limited responses#

Unlike the CLI (which sleeps), the MCP server returns rate_limited immediately after the 3rd free call in a 60s window. Surface the message to the user and wait at least context.delay_seconds before retrying, or upgrade to Pro for unlimited calls.

License not recognized#

The MCP server reads the CLI's license cache from the shared state directory (see Shared state). Ensure you have activated your license on the same machine:

getwebp auth <your-key>
getwebp status   # verify activation

If you set $GETWEBP_CONFIG_DIR for the CLI, make sure the MCP server process inherits the same value.