Make memes from a big catalog of templates and GIFs or your own photo, and get the finished image
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Create a meme on exactly one of: template (a catalog id), image (your own picture in base64 or a data: URL; JPEG, PNG, WebP or GIF, up to 5 MB and 25 megapixels (16 for WebP, 8 for GIF, less for a large progressive JPEG), 100 px or more a side, at most 4:1; a GIF gives its first frame) or image_url (an https address the server downloads). Your own picture is laid out like a template, with slots found in it (see get_template). Captions go in slots, classic top/bottom positions or boxes (fractions of the image, x and y the top-left corner), plus optional author, emojis, stickers, shapes with text and a filter. The server fits and colours every caption, and may write a line break (\n) into a returned caption text, to keep a short word or a number off the end of a line, to keep a quote on one line or to break a long word after an underscore: a returned text sent back as it is comes out the same. With author, the handle goes in the first corner free of other layers, and of faces when it can: bottom right, top right, bottom left, top left. When a top and a bottom caption leave no corner free, the bottom one moves up a little to free one for the handle, given or saved by the person in the studio. Returns the link that opens the meme in Meme Studio (an editor link, never an image source), what each caption got, warnings and a picture: picture "preview" (800 px to check, the default with a template) or "final" (the finished meme at 1200 px with the invisible watermark, like the studio download; the default with your own picture, because the link cannot carry it and only reopens the captions). For a file on disk, with a terminal, do not paste its base64 yourself: pipe the tools/call JSON from the shell into curl --data-binary @-, without a temporary copy of the picture, to the server's /mcp (Content-Type: application/json, Accept: application/json, text/event-stream; no initialize needed), then decode the data of the image item in result.content from base64 into a file for the person.
Your own picture instead of a template: JPEG, PNG, WebP or GIF in base64 (a data: URL works too), up to 5 MB and 25 megapixels (16 for WebP, 8 for GIF, less for a large progressive JPEG)
The person's handle, with or without @, only if they gave it
preview: 800 px to check (the default with a template); final: the finished meme at 1200 px (the default with image or image_url)
false: return no picture
Language of the person: es opens the Spanish studio, en the English one
Template id; or give image or image_url instead
Your own picture instead of a template: an https address the server downloads
0 to 1; the studio default when missing
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http memes https://memes.mrhyde.dev/mcp
Create a meme on exactly one of: template (a catalog id), image (your own picture in base64 or a data: URL; JPEG, PNG, WebP or GIF, up to 5 MB and 25 megapixels (16 for WebP, 8 for GIF, less for a large progressive JPEG), 100 px or more a side, at most 4:1; a GIF gives its first frame) or image_url (an https address the server downloads). Your own picture is laid out like a template, with slots found in it (see get_template). Captions go in slots, classic top/bottom positions or boxes (fractions of the image, x and y the top-left corner), plus optional author, emojis, stickers, shapes with text and a filter. The server fits and colours every caption, and may write a line break (\n) into a returned caption text, to keep a short word or a number off the end of a line, to keep a quote on one line or to break a long word after an underscore: a returned text sent back as it is comes out the same. With author, the handle goes in the first corner free of other layers, and of faces when it can: bottom right, top right, bottom left, top left. When a top and a bottom caption leave no corner free, the bottom one moves up a little to free one for the handle, given or saved by the person in the studio. Returns the link that opens the meme in Meme Studio (an editor link, never an image source), what each caption got, warnings and a picture: picture "preview" (800 px to check, the default with a template) or "final" (the finished meme at 1200 px with the invisible watermark, like the studio download; the default with your own picture, because the link cannot carry it and only reopens the captions). For a file on disk, with a terminal, do not paste its base64 yourself: pipe the tools/call JSON from the shell into curl --data-binary @-, without a temporary copy of the picture, to the server's /mcp (Content-Type: application/json, Accept: application/json, text/event-stream; no initialize needed), then decode the data of the image item in result.content from base64 into a file for the person.
| Argument | Type | Description |
|---|---|---|
| image | string | Your own picture instead of a template: JPEG, PNG, WebP or GIF in base64 (a data: URL works too), up to 5 MB and 25 megapixels (16 for WebP, 8 for GIF, less for a large progressive JPEG) |
| author | string | The person's handle, with or without @, only if they gave it |
| emojis | array | |
| filter | string | |
| shapes | array | |
| picture | string | preview: 800 px to check (the default with a template); final: the finished meme at 1200 px (the default with image or image_url) |
| preview | boolean | false: return no picture |
| captions* | array | |
| language | string | Language of the person: es opens the Spanish studio, en the English one |
| stickers | array | |
| template | string | Template id; or give image or image_url instead |
| image_url | string | Your own picture instead of a template: an https address the server downloads |
| filter_strength | number | 0 to 1; the studio default when missing |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"captions"
],
"properties": {
"image": {
"type": "string",
"maxLength": 8388608,
"minLength": 1,
"description": "Your own picture instead of a template: JPEG, PNG, WebP or GIF in base64 (a data: URL works too), up to 5 MB and 25 megapixels (16 for WebP, 8 for GIF, less for a large progressive JPEG)"
},
"author": {
"type": "string",
"maxLength": 25,
"minLength": 1,
"description": "The person's handle, with or without @, only if they gave it"
},
"emojis": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"center_x",
"center_y"
],
"properties": {
"angle": {
"type": "number",
"maximum": 180,
"minimum": -180
},
"emoji": {
"enum": [
"๐",
"๐คฃ",
"๐ญ",
"๐",
"๐ฅ",
"๐",
"๐คก",
"๐",
"๐",
"๐ณ",
"๐ฅฒ",
"๐ก",
"๐ค",
"๐ฑ",
"๐คฏ",
"๐ฅต",
"๐ฅถ",
"๐",
"๐ฟ",
"๐",
"๐",
"๐",
"๐",
"๐ช",
"๐ค",
"๐",
"๐ฏ",
"โค๏ธ",
"โค",
"๐",
"โจ",
"๐",
"๐",
"๐ฉ",
"๐",
"๐ธ",
"๐ฟ",
"โ",
"๐",
"๐งข",
"๐ง ",
"โ
",
"โ",
"โ ๏ธ",
"โ ",
"๐",
"๐",
"๐ฏ"
],
"type": "string",
"description": "One of the emojis Meme Studio offers"
},
"width": {
"type": "number",
"maximum": 0.6,
"minimum": 0.04,
"description": "Fraction of the width"
},
"center_x": {
"type": "number",
"maximum": 1,
"minimum": 0
},
"center_y": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "From the top: 0 is the top edge, 1 the bottom; a larger value moves it down"
}
}
},
"maxItems": 8
},
"filter": {
"enum": [
"grayscale",
"sepia",
"invert",
"contrast",
"brightness",
"saturation",
"pixelate",
"blur",
"deep_fried",
"vignette"
],
"type": "string"
},
"shapes": {
"type": "array",
"items": {
"type": "object",
"required": [
"shape",
"x",
"y",
"width",
"height"
],
"properties": {
"x": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Left edge"
},
"y": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Top edge"
},
"flip": {
"type": "boolean",
"description": "Mirror it; the bubble tail goes to the right"
},
"text": {
"type": "string",
"maxLength": 120,
"minLength": 1,
"description": "Text written inside the shape"
},
"angle": {
"type": "number",
"maximum": 45,
"minimum": -45
},
"color": {
"anyOf": [
{
"enum": [
"white",
"black",
"yellow"
],
"type": "string"
},
{
"type": "string",
"pattern": "^#[0-9a-f]{6}$"
}
],
"description": "white, black, yellow or #rrggbb"
},
"shape": {
"enum": [
"bubble",
"rect",
"rounded",
"ellipse",
"arrow",
"star",
"heart",
"diamond",
"triangle"
],
"type": "string"
},
"width": {
"type": "number",
"maximum": 1,
"minimum": 0.04
},
"height": {
"type": "number",
"maximum": 1,
"minimum": 0.04
},
"opacity": {
"type": "number",
"maximum": 1,
"minimum": 0.1
},
"text_color": {
"anyOf": [
{
"enum": [
"auto",
"white",
"yellow",
"black"
],
"type": "string"
},
{
"type": "string",
"pattern": "^#[0-9a-f]{6}$"
}
]
}
}
},
"maxItems": 6
},
"picture": {
"enum": [
"preview",
"final"
],
"type": "string",
"description": "preview: 800 px to check (the default with a template); final: the finished meme at 1200 px (the default with image or image_url)"
},
"preview": {
"type": "boolean",
"description": "false: return no picture"
},
"captions": {
"type": "array",
"items": {
"type": "object",
"required": [
"text"
],
"properties": {
"x": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Left edge of the box, fraction of the width"
},
"y": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Top edge of the box, fraction of the height"
},
"font": {
"enum": [
"impact",
"arial"
],
"type": "string",
"default": "impact"
},
"slot": {
"anyOf": [
{
"type": "string",
"maxLength": 40,
"minLength": 1
},
{
"type": "integer",
"maximum": 12,
"minimum": 1
}
],
"description": "Slot number or name from get_template"
},
"text": {
"type": "string",
"maxLength": 120,
"minLength": 1,
"description": "The caption, under the fits_chars of its slot. \\n forces a line break. It is written in capitals"
},
"align": {
"enum": [
"center",
"left",
"right"
],
"type": "string",
"default": "center"
},
"angle": {
"type": "number",
"maximum": 45,
"minimum": -45,
"description": "Degrees, clockwise"
},
"color": {
"anyOf": [
{
"enum": [
"auto",
"white",
"yellow",
"black"
],
"type": "string"
},
{
"type": "string",
"pattern": "^#[0-9a-f]{6}$"
}
],
"description": "auto, white, yellow, black or #rrggbb"
},
"style": {
"enum": [
"auto",
"outline",
"plain",
"box"
],
"type": "string",
"default": "auto",
"description": "outline, plain or box (text on a solid box)"
},
"width": {
"type": "number",
"maximum": 1,
"minimum": 0.08,
"description": "Box width, fraction of the width (0.9 by default)"
},
"height": {
"type": "number",
"maximum": 1,
"minimum": 0.03,
"description": "Box height, fraction of the height"
},
"max_size": {
"type": "number",
"maximum": 2,
"minimum": 0.4,
"description": "Largest text size, 1 = the usual meme size"
},
"position": {
"enum": [
"top",
"bottom",
"middle"
],
"type": "string",
"description": "Classic placement on a single photo; ignored with slot or x and y"
}
}
},
"maxItems": 12,
"minItems": 1
},
"language": {
"enum": [
"es",
"en"
],
"type": "string",
"default": "es",
"description": "Language of the person: es opens the Spanish studio, en the English one"
},
"stickers": {
"type": "array",
"items": {
"type": "object",
"required": [
"sticker",
"center_x",
"center_y"
],
"properties": {
"flip": {
"type": "boolean"
},
"angle": {
"type": "number",
"maximum": 180,
"minimum": -180
},
"width": {
"type": "number",
"maximum": 1,
"minimum": 0.04,
"description": "Fraction of the width"
},
"sticker": {
"enum": [
"pixel_glasses",
"laser_eye"
],
"type": "string"
},
"center_x": {
"type": "number",
"maximum": 1,
"minimum": 0
},
"center_y": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "From the top: 0 is the top edge, 1 the bottom; a larger value moves it down"
}
}
},
"maxItems": 4
},
"template": {
"type": "string",
"pattern": "^[a-z0-9]{6}$",
"description": "Template id; or give image or image_url instead"
},
"image_url": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "Your own picture instead of a template: an https address the server downloads"
},
"filter_strength": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "0 to 1; the studio default when missing"
}
}
}Details of one template: names, what it is used for, tags, size, whether it is animated and its slots (the boxes where captions go). Each slot has fits_chars, about how many characters fit in it at a good size (0 is a small slot for a word or two): keep its caption under that or the text comes out small. With image: true (or show_slots: true) it also returns the picture with the slots outlined and numbered. Instead of template, give your own picture as image (base64) or image_url, as in create_meme: you get the slots found in that picture, the same ones create_meme uses with it.
| Argument | Type | Description |
|---|---|---|
| image | any | true: also return the picture with the numbered slots. Or your own picture in base64 instead of template, as in create_meme |
| template | string | Template id from search_templates, the same you give create_meme; or give image or image_url instead |
| image_url | string | Your own picture instead of template: an https address the server downloads |
| show_slots | boolean | Also return the picture with the numbered slots, the same as image: true |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"image": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 8388608,
"minLength": 1
}
],
"description": "true: also return the picture with the numbered slots. Or your own picture in base64 instead of template, as in create_meme"
},
"template": {
"type": "string",
"pattern": "^[a-z0-9]{6}$",
"description": "Template id from search_templates, the same you give create_meme; or give image or image_url instead"
},
"image_url": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "Your own picture instead of template: an https address the server downloads"
},
"show_slots": {
"type": "boolean",
"description": "Also return the picture with the numbered slots, the same as image: true"
}
}
}Templates people choose most in Meme Studio: trending this week or most used overall.
| Argument | Type | Description |
|---|---|---|
| kind | string | |
| limit | integer | |
| animated | boolean |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"kind": {
"enum": [
"trending",
"most_used"
],
"type": "string",
"default": "trending"
},
"limit": {
"type": "integer",
"maximum": 30,
"minimum": 1
},
"animated": {
"type": "boolean"
}
}
}Search the Meme Studio catalog by name, keywords or what the meme is used for (intent), in Spanish or English. Best matches first, each with what it is used for.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| query* | string | The joke, the situation or the template name, in any language |
| animated | boolean | true: only animated templates; false: only still ones |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 20,
"minimum": 1
},
"query": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "The joke, the situation or the template name, in any language"
},
"animated": {
"type": "boolean",
"description": "true: only animated templates; false: only still ones"
}
}
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 4, 2026.