MCP Documentation

CONNECT YOUR
AGENT IN
5 MINUTES.

MemeForge exposes 18 image tools via MCP (Model Context Protocol). Your AI agent gets meme generation, background removal, filters, composition and more — no GUI required. Two transports: stdio for local, HTTP for hosted.

Step 0

QUICK START

The fastest path from zero to meme. One config line, then ask your agent to generate a meme — it handles the rest.

1

Add MemeForge to your MCP client

Claude Codeone command
claude mcp add memeforge https://memeforge.xyz/api/mcp

Or add manually to your config file

claude_desktop_config.json
{
  "mcpServers": {
    "memeforge": {
      "url": "https://memeforge.xyz/api/mcp"
    }
  }
}
2

Ask your agent to make a meme

"Make a Drake meme where he rejects writing tests and prefers deploying to production"

3

The agent calls MemeForge tools automatically

1. find_template query: "rejection vs approval comparison"
2. generate_meme description: "drake", texts: ["Writing tests", "Deploying to prod"]
→ Returns rendered meme image

That's it. Below is the detailed setup for both transports and the full tool reference.

Transport 1

STDIO (LOCAL)

Runs as a local subprocess. Your MCP client (Claude Code, Claude Desktop, Cursor) launches the server and communicates via stdin/stdout. Best for development and when you want everything local.

1. Build the server

Terminal
cd mcp-server
npm install
npm run build

2. Configure your client

Claude Coderecommended
claude mcp add memeforge -- node /path/to/MemeForge/mcp-server/dist/index.js

Or add manually to config files

Claude Desktop — claude_desktop_config.json
{
  "mcpServers": {
    "memeforge": {
      "command": "node",
      "args": ["/path/to/MemeForge/mcp-server/dist/index.js"]
    }
  }
}
Cursor — .cursor/mcp.json
{
  "mcpServers": {
    "memeforge": {
      "command": "node",
      "args": ["/path/to/MemeForge/mcp-server/dist/index.js"]
    }
  }
}
NOTEFile saving

In stdio mode, tools accept a saveTo parameter. Files are saved to /tmp/memeforge-output/ with path traversal protection. Example: saveTo: "my-meme.png"

Transport 2

HTTP (HOSTED)

Connect to the hosted MemeForge server via URL. No install, no build, no subprocess. Works with any MCP client that supports HTTP/SSE transport.

Claude Codeone command
claude mcp add memeforge https://memeforge.xyz/api/mcp

Or add manually to any MCP client config

JSON config
{
  "mcpServers": {
    "memeforge": {
      "url": "https://memeforge.xyz/api/mcp"
    }
  }
}

No install

Just paste the URL

Same 18 tools

Identical to stdio

Free tier

100 req/day, no key needed

TIPSelf-hosting

To self-host the HTTP endpoint, run the Next.js app (npm run dev) and point your config to http://localhost:3001/api/mcp. The HTTP transport includes auth middleware, CORS, and security headers.

Tools 1-5

MEME TOOLS

The core meme creation workflow. Search templates, generate memes from descriptions, or render with full control over text positions and styling.

generate_meme

The fastest path. Describe what you want and MemeForge auto-selects the best template and renders the meme in one call. Great when you know the vibe but not the exact template.

generate_meme({
  description: "drake approval meme",
  texts: [
    "Spending 6 hours debugging",
    "Adding console.log everywhere"
  ]
})
// → Returns rendered meme image
find_template

Search templates WITHOUT rendering. Returns zone labels, descriptions, and hints so you can verify the match before committing. Use this when you want to preview which template fits.

find_template({
  query: "plan that backfires",
  limit: 3
})
// → Returns:
// 1. gru-plan — Gru's Plan [featured]
//    Zones: [0] step-1, [1] step-2, [2] step-3, [3] realization
//    Use when: multi-step plan where step 3 or 4 backfires
meme_from_template

Generate a meme from a specific template ID. Texts are auto-positioned into the template's zones in order. Supports fuzzy matching if the exact ID isn't found.

meme_from_template({
  template: "expanding-brain",
  texts: [
    "Using var",
    "Using let",
    "Using const",
    "Using TypeScript enums"
  ]
})
render_meme

Full control rendering. Provide a custom image URL with manually positioned text overlays and optional deep-fry effects. Use this for non-template memes or custom layouts.

render_meme({
  image: "https://example.com/photo.jpg",
  width: 800,
  height: 600,
  texts: [{
    text: "TOP TEXT",
    x: 50, y: 20,
    width: 700, height: 100,
    fontSize: 64,
    color: "#FFFFFF",
    outlineColor: "#000000",
    outlineWidth: 4,
    font: "Impact",
    allCaps: true,
    textAlign: "center",
    textStyle: "outline"
  }],
  deepFry: {
    noise: 3,
    jpegIterations: 2,
    jpegQuality: 15
  }
})
list_templates

Browse all 220+ templates with optional search and tier filter. Returns template IDs, zone counts, and keywords. Paginated.

list_templates({
  query: "comparison",
  limit: 5,
  tier: "featured"
})
// → drake, distracted-boyfriend, two-buttons, ...

Tools 6-10

IMAGE OPERATIONS

Resize, crop, rotate, flip, and adjust. Accept image URLs or base64 data URIs. Return the processed image.

resize

Resize to target dimensions. Fit modes: cover (crop to fill), contain (fit within, may letterbox), stretch, inside (shrink only), outside (grow only).

resize({
  image: "https://example.com/photo.jpg",
  width: 400,
  height: 400,
  fit: "cover"
})
crop

Crop a rectangular region by pixel coordinates.

crop({
  image: "https://example.com/photo.jpg",
  x: 100, y: 50,
  width: 600, height: 400
})
rotate

Rotate by any angle. Canvas expands to fit. Positive = clockwise.

rotate({
  image: "https://example.com/photo.jpg",
  angle: 45,
  background: "#000000"
})
flip

Mirror an image horizontally, vertically, or both.

flip({
  image: "https://example.com/photo.jpg",
  direction: "horizontal"
})
adjust

Adjust brightness, contrast, saturation, blur, opacity. Toggle grayscale, sepia, or invert.

adjust({
  image: "https://example.com/photo.jpg",
  brightness: 20,
  contrast: 30,
  saturation: -50,
  grayscale: false,
  blur: 2
})

Tools 11-13

COMPOSITION

Combine multiple images. Layer with positioning, create collages, or stamp watermarks.

compose

Layer multiple images on a canvas. Each layer has position, size, opacity, rotation, and anchor point. Layers draw in array order (first = bottom).

compose({
  width: 1200,
  height: 800,
  background: "#000000",
  layers: [
    { image: "https://.../background.jpg" },
    {
      image: "https://.../logo.png",
      x: 50, y: 50,
      width: 200,
      opacity: 0.8,
      anchor: "top-left"
    },
    {
      image: "https://.../sticker.png",
      x: 900, y: 600,
      rotation: -15,
      anchor: "center"
    }
  ]
})
collage

Arrange up to 20 images in a grid, horizontal strip, or vertical strip. Auto-sizes cells. Configurable gap and background color.

collage({
  images: [
    "https://.../photo1.jpg",
    "https://.../photo2.jpg",
    "https://.../photo3.jpg",
    "https://.../photo4.jpg"
  ],
  layout: "grid",
  columns: 2,
  gap: 8,
  background: "#FFFFFF"
})
watermark

Stamp a watermark/logo onto an image. 5 positions, configurable opacity, scale, and margin.

watermark({
  image: "https://.../photo.jpg",
  watermark: "https://.../logo.png",
  position: "bottom-right",
  opacity: 0.3,
  scale: 0.15,
  margin: 20
})

Tools 14-15

CLEANUP

Remove text from memes or remove backgrounds from images. ML-powered where available.

remove_text

Strip text from a meme. First tries template matching (returns the clean original if found). Falls back to pixel-based inpainting. Adjustable sensitivity and radius.

remove_text({
  image: "https://.../meme-with-text.jpg"
})
// → "Text removed using template matching
//    (clean original found!)"

// Force pixel inpainting:
remove_text({
  image: "https://.../custom-meme.jpg",
  forceInpaint: true,
  sensitivity: 60,
  radius: 10
})
remove_background

5 methods: auto (ML first, fallback to color), ml (rembg U2-Net), sam (MobileSAM with bounding boxes — best quality), color (flood fill), threshold (brightness cutoff). Returns transparent PNG.

// Automatic (recommended)
remove_background({
  image: "https://.../product.jpg",
  method: "auto"
})

// SAM with bounding box (best for specific subjects)
remove_background({
  image: "https://.../group-photo.jpg",
  method: "sam",
  boxes: [
    { x1: 100, y1: 50, x2: 400, y2: 500 }
  ]
})

// Color-based (e.g. green screen)
remove_background({
  image: "https://.../greenscreen.jpg",
  method: "color",
  color: "#00FF00",
  tolerance: 30
})

Tools 16-18

FILTERS & PRESETS

Apply named filter presets in one call. Each preset is a curated combination of adjustments and deep-fry effects.

apply_filter

Apply a preset by ID. Use list_filters to see all options.

apply_filter({
  image: "https://.../photo.jpg",
  filter: "deep-fried"
})

Available presets

deep-friedOversaturated, noisy, JPEG artifacts
vintageWarm, faded retro with sepia
noirB&W with high contrast
vaporwaveHigh saturation pink/blue aesthetic
nuclearMaximum artifacts, bulge, distortion
softSlight blur, warm brightness
high-contrastPunchy contrast and saturation
negativeInverted colors
washed-outDesaturated, low contrast, faded
comicHigh contrast, sharp edges, vivid
list_filters

Returns all available filter presets with descriptions.

list_filters()
// → deep-fried, vintage, noir, vaporwave, nuclear,
//   soft, high-contrast, negative, washed-out, comic
list_fonts

Returns all fonts available for text rendering.

list_fonts()
// → Impact, Arial, Arial Black, Comic Sans MS,
//   Courier New, Georgia, Helvetica, Times New Roman,
//   Trebuchet MS, Verdana

Reference

TEMPLATE SYSTEM

220+ meme templates in two tiers. Featured templates (15) have hand-crafted text zones with hints. Extended templates (205+) come from the memegen.link MIT catalog with auto-generated zones.

Featured templates (15)

drake
Comparing two things — rejecting one, preferring another
Zones: reject, approve
distracted-boyfriend
Being tempted by something new over the current
Zones: distraction, boyfriend, girlfriend
two-buttons
Impossible choice between two options
Zones: button-1, button-2, person
change-my-mind
Provocative opinion stated as fact
Zones: statement
expanding-brain
Escalating ideas from simple to absurd
Zones: level-1, level-2, level-3, level-4
one-does-not-simply
Something that sounds easy but is not
Zones: statement
batman-slapping-robin
Shutting down a bad take
Zones: robin-says, batman-says
disaster-girl
Causing chaos and smiling about it
Zones: background, girl-text
this-is-fine
Pretending things are OK when they aren't
Zones: speech
always-has-been
Shocking reveal that was always true
Zones: panel-1, panel-2, panel-3, panel-4
bernie-asking
Asking for something again
Zones: top, bottom
is-this-a-pigeon
Misidentifying something obvious
Zones: butterfly, person, caption
left-exit
Choosing the obviously worse option
Zones: straight, exit, car
trade-offer
Unbalanced deal or negotiation
Zones: i-receive, you-receive
thinking
Deep or absurd philosophical question
Zones: question
IMPORTANTZone order matters

The texts array must match the template's zone order. For Drake: texts[0] = what gets rejected (top), texts[1] = what gets approved (bottom).

Always use find_template first if you're unsure about zone order. It returns labels and hints for each zone.

Reference

DEEP FRY EFFECTS

The deepFry parameter on render_meme, generate_meme, and meme_from_template accepts these settings. All are optional — combine any subset for your desired level of chaos.

Parameter
Range
Default
What it does
brightness
-50 to 50
0
Lighten or darken the image
contrast
-50 to 50
0
Increase or decrease contrast
saturation
-50 to 300
0
Color intensity. 300 = nuclear
sharpen
0 to 20
0
Edge sharpening. High = crunchy
noise
0 to 10
0
Random pixel noise grain
jpegIterations
0 to 20
0
Re-compress as JPEG N times
jpegQuality
1 to 100
100
JPEG quality per iteration. 5 = max artifact
bulgeAmount
-5 to 5
0
Center bulge distortion. Negative = pinch
bulgeRadius
1 to 100
50
Bulge radius as % of image

Recipe examples

Lightly toasted
deepFry: {
  brightness: 10,
  contrast: 15,
  saturation: 40,
  jpegIterations: 2,
  jpegQuality: 30
}
Fully nuclear
deepFry: {
  brightness: 25,
  contrast: 40,
  saturation: 250,
  sharpen: 15,
  noise: 8,
  jpegIterations: 10,
  jpegQuality: 5,
  bulgeAmount: 3,
  bulgeRadius: 70
}

Bonus

BUILT-IN PROMPTS

MemeForge includes 3 MCP prompts your agent can invoke for guidance. These inject context without using a tool call.

PROMPT
quickstart

60-second intro to MemeForge: workflow, key tools, common mistakes, first meme example.

PROMPT
template_cheatsheet

Zone order reference for all 15 featured templates. Which text goes where.

PROMPT
meme_guide

How to write meme text that actually lands. Tone, length, common patterns.

Common pitfalls

  • Emojis don't render (canvas has no emoji font). They're stripped automatically with a warning.
  • Fewer texts than zones = empty zones. The tool warns you.
  • Max image dimension is 4096x4096. Larger images are rejected.

Tips

  • Chain tools: remove_backgroundcompose to put subjects on new backgrounds.
  • Use find_template before generate_meme to verify zone order.
  • Featured templates have richer zones. Extended templates may need manual positioning via render_meme.