Intro
Hello! I'm Ninja Web Developer. Hi-Yah!🥷
I have been playing with studying MCP lately.↓
🧠🥷How to make AI controled Avatar 2 (Vroid MCP + Cline and Cursor + Unity)
🧠🥷How to make cool Ninja game (Unity MCP + Blender MCP (Cline and Cursor))
🧠🥷How to make cool Ninja (Blender MCP (Cline and Cursor))
First, I made an Image generation and editing Next.js Web App.↓
🧠🥷Gemini API 2 (Image generation and editing (free and fast))
Next, I changed it to an Image generation and editing MCP.↓
🧠🥷How to make Image generation and editing MCP (Gemini API + Cline and Cursor)
So this time, I will change it to a Meme Generating MCP!
OK! Let's begin!🚀
What is Meme?
Meme is a cultural phenomenon that spreads on the Internet, such as funny images, videos and text.
People who watch Meme will have benefit, such as reduce stress, sleep well, and laugh from bottom of heart.
Here is an interviews who watched Meme.
Web Developer C: After watching Meme, my old little brain is rebuild completely new, and I can find ways to solves the bugs in the code.
*Note: Effect of Meme has individual differences.
Consideration when making Meme MCP.
First, I prepared a famous Meme template.
However, I wanted to avoid illegal copy, so I changed it to an Anime style.↓
I still thought it is too similar to the original template, so I deleted the black jumping man mark in the T-shirt, and change the color of the hair and clothes.↓
For these edits, I used my Image generating and edit MCP or App that I made last time.
Outline of system
This system has a simple three layer structure.
Cline or Cursor → MCP → Next.js Web App
1️⃣ Cline or Cursor part will send the instruction to MCP.
2️⃣ MCP part will relay the instruction to Next.js Web App.
3️⃣ Next.js Web App part will display Meme on the browser.
Ok! Let's setup the Meme MCP.
How to set Next.js Web App
1️⃣ Make a Next.js project
npx create-next-app@latest
https://nextjs.org/docs/app/getting-started/installation
2️⃣ Set the codes
Code of frontend (app/page.tsx)
"use client";
import { useState, useEffect } from "react";
export default function Home() {
const [noText, setNoText] = useState("");
const [yesText, setYesText] = useState("");
const [error, setError] = useState<string | null>(null);
const fetchMemeText = async () => {
setError(null);
try {
const response = await fetch("/api/generate-meme", {
method: "GET",
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(
`HTTP error! status: ${response.status}, body: ${errorText}`
);
}
const data = await response.json();
if (data.receivedText) {
setNoText(data.receivedText.noText);
setYesText(data.receivedText.yesText);
}
} catch (error) {
console.error("Error fetching meme text:", error);
const errorMessage =
error instanceof Error ? error.message : "An unknown error occurred";
setError(errorMessage);
}
};
useEffect(() => {
const intervalId = setInterval(() => {
fetchMemeText();
}, 4000);
return () => clearInterval(intervalId);
}, []);
return (
<div className="flex flex-col items-center justify-center min-h-screen py-2">
<h1 className="text-6xl font-bold mb-4">Meme Generating MCP</h1>
{error && <p className="text-red-500">Error: {error}</p>}
{noText && yesText && (
<div>
<div className="flex items-center">
<img src="/template_no.png" alt="template_no" className="mr-4" />
<p className="text-6xl font-bold">{noText}</p>
</div>
<div className="flex items-center">
<img src="/template_yes.png" alt="template_yes" className="mr-4" />
<p className="text-6xl font-bold">{yesText}</p>
</div>
</div>
)}
</div>
);
}
Code of meme generation (app/api/generate-meme/route.ts)
import { NextResponse } from "next/server";
let storedNoText: string = "";
let storedYesText: string = "";
export async function POST(request: Request) {
try {
const { noText, yesText } = await request.json();
console.log("Received text in Next.js API:", { noText, yesText });
storedNoText = noText;
storedYesText = yesText;
return NextResponse.json({
message: "Text received successfully",
receivedText: { noText, yesText },
});
} catch (error) {
console.error("Error processing request in Next.js API:", error);
const errorMessage =
error instanceof Error ? error.message : "An unknown error occurred";
return NextResponse.json(
{
message: "Error processing request",
error: errorMessage,
},
{ status: 500 }
);
}
}
export async function GET(request: Request) {
return NextResponse.json({
message: "Text retrieved successfully",
receivedText: { noText: storedNoText, yesText: storedYesText },
});
}
Set template_no.png
and template_yes.png
inside public
folder.
template_no.png↓
template_yes.png↓
How to set Meme MCP
1️⃣ Make a folder for Meme MCP Server and open it from your editor.
2️⃣ Make package.json
.↓
npm init
3️⃣ Install MCP SDK
.↓
npm install @modelcontextprotocol/sdk
4️⃣ Make tsconfig.json
.↓
tsc --init
5️⃣ Add "build": "tsc",
to scripts
of package.json
.
6️⃣ Add index.ts
of Meme MCP Server.↓
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ErrorCode,
ListToolsRequestSchema,
McpError,
} from "@modelcontextprotocol/sdk/types.js";
class MemeServer {
private server: Server;
constructor() {
this.server = new Server(
{
name: "meme-mcp-server",
version: "0.1.0",
},
{
capabilities: {
resources: {},
tools: {},
},
}
);
this.setupToolHandlers();
this.server.onerror = (error) => console.error("[MCP Error]", error);
process.on("SIGINT", async () => {
await this.server.close();
process.exit(0);
});
}
private setupToolHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "generate_meme",
description:
"Generates a meme by sending text to the Next.js backend.",
inputSchema: {
type: "object",
properties: {
noText: {
type: "string",
description:
"The text to display at the top of the meme (No text).",
},
yesText: {
type: "string",
description:
"The text to display at the bottom of the meme (Yes text).",
},
},
required: ["noText", "yesText"],
},
},
],
}));
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "generate_meme") {
const { noText, yesText } = request.params.arguments as {
noText: string;
yesText: string;
};
try {
const response = await fetch(
"http://localhost:3000/api/generate-meme",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ noText, yesText }),
}
);
return {
content: [
{
type: "text",
text: "Meme generated successfully",
},
],
};
} catch (error: any) {
console.error("Error calling Next.js API:", error);
return {
content: [
{
type: "text",
text: `Error generating meme: ${error.message}`,
},
],
isError: true,
};
}
}
throw new McpError(
ErrorCode.MethodNotFound,
`Unknown tool: ${request.params.name}`
);
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Meme MCP server running on stdio");
console.log("mcp ok!");
}
}
const server = new MemeServer();
server.run().catch(console.error);
7️⃣ Build index.ts
to index.js
.↓
run npm build
8️⃣ Set cline_mcp_settings.json
for Cline and mcp.json
for Cursor.↓
{
"mcpServers": {
"meme-mcp-server": {
"command": "node",
"args": ["path to index.js"]
}
}
}
How to use
1️⃣ npm run dev
, and start the Next.js App, and access http://localhost:3000
.
2️⃣ Ask your Cline or Cursor to generate a Meme.
For example,
Use "generate_meme" tool of "meme-mcp-server",
and send "noText": “Before watching Meme Monday”
and “yesText”: “After watching Meme Monday”.
3️⃣ Or ask your Cline or Cursor to think one of the text instead of you.
For example,
Use "generate_meme" tool of "meme-mcp-server",
and send "noText": “”
and “yesText”: “After watching Meme Monday”.
Think the noText part and fill in the text.
4️⃣ Or ask your Cline or Cursor to think both texts instead of you.
For example,
Use "generate_meme" tool of "meme-mcp-server",
and send "noText": “Before watching Meme Monday”
and “yesText”: “After watching Meme Monday”.
Think unique and humorous texts and replace noText and yesText.
5️⃣ Yay! We can generate Memes from Cline and Cursor.🎉
Future improvements
1️⃣ It would be more fun if there are other templates.
For example↓
Example of text↓
Boy: Web Developer
Girl in right: Concentrate on Work
Girl in left: Watch Meme Monday.
2️⃣ Making the Meme image by AI would also be fun.
Outro
Meme will bring us little joy and happiness in our daily lives.😊
Trivial things around us might be a good idea for a new Meme.💡
I hope you will learn something from this post, or maybe learn nothing but enjoy a little.
Thank you for reading.
Happy AI coding!🤖 Hi-Yah!🥷