import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
/**
* Dad Jokes MCP Server
* A professional Model Context Protocol server for generating dad jokes
*/
class DadJokesMcpServer {
private server: McpServer;
constructor() {
this.server = new McpServer({
name: "dad-jokes-mcp",
version: "1.0.0",
});
this.setupPrompts();
this.setupTools();
}
/**
* Setup prompts for the MCP server
*/
private setupPrompts(): void {
// Topic-based joke generator prompt
this.server.prompt(
"generate-dad-joke",
{
topic: z.string().describe("The topic or theme for the dad joke"),
style: z.string().optional().describe("The style of dad joke: classic, punny, wholesome, or groan-worthy"),
},
({ topic, style = "classic" }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `${this.getDadJokeSystemPrompt(style)}\n\nGenerate a ${style} dad joke about: ${topic}`,
},
},
],
})
);
// Random joke prompt
this.server.prompt(
"random-dad-joke",
{
count: z.string().optional().describe("Number of jokes to generate (1-5)"),
},
({ count = "1" }) => {
const numCount = parseInt(count, 10) || 1;
const validCount = Math.min(Math.max(numCount, 1), 5);
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `${this.getDadJokeSystemPrompt("classic")}\n\n${validCount === 1
? "Generate a random dad joke"
: `Generate ${validCount} different random dad jokes`}`,
},
},
],
};
}
);
// Joke rating prompt
this.server.prompt(
"rate-dad-joke",
{
joke: z.string().describe("The dad joke to rate"),
},
({ joke }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `You are a dad joke connoisseur with impeccable taste in humor. Rate dad jokes on a scale of 1-10 based on their punniness, groan factor, and classic dad joke qualities. Provide constructive feedback.\n\nRate this dad joke and provide feedback: "${joke}"`,
},
},
],
})
);
}
/**
* Setup tools for the MCP server
*/
private setupTools(): void {
// Tool for getting joke categories
this.server.tool(
"get-joke-categories",
{},
{
description: "Get available categories for dad jokes",
},
async () => {
const categories = [
"Animals", "Food", "Technology", "Sports", "Weather",
"Work", "Family", "School", "Travel", "Movies",
"Music", "Books", "Science", "History", "Holidays"
];
return {
content: [
{
type: "text",
text: `Available dad joke categories:\n${categories.map(cat => `• ${cat}`).join('\n')}`,
},
],
};
}
);
// Tool for joke statistics
this.server.tool(
"joke-stats",
{},
{
description: "Get interesting statistics about dad jokes",
},
async () => {
const stats = {
"Average groan time": "2.3 seconds",
"Success rate with teenagers": "12%",
"Dad approval rating": "94%",
"Most popular category": "Food puns",
"Worst time to tell": "During serious conversations",
"Best time to tell": "Always (according to dads)",
};
return {
content: [
{
type: "text",
text: `Dad Joke Statistics:\n${Object.entries(stats)
.map(([key, value]) => `• ${key}: ${value}`)
.join('\n')}`,
},
],
};
}
);
}
/**
* Get system prompt for dad joke generation based on style
*/
private getDadJokeSystemPrompt(style: string): string {
const basePrompt = `You are a master of dad jokes with years of experience making people simultaneously laugh and groan. Your jokes are family-friendly, clever, and have that perfect "dad energy."`;
const stylePrompts = {
classic: `${basePrompt} Focus on timeless, traditional dad jokes that have been making people groan for generations.`,
punny: `${basePrompt} Emphasize wordplay and puns. The more groan-worthy the pun, the better the joke.`,
wholesome: `${basePrompt} Create heartwarming, positive jokes that bring smiles without any edge or sarcasm.`,
"groan-worthy": `${basePrompt} Go all-in on the groan factor. These should be so bad they're good.`,
};
return stylePrompts[style as keyof typeof stylePrompts] || stylePrompts.classic;
}
/**
* Start the MCP server
*/
async start(): Promise<void> {
try {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Dad Jokes MCP Server started successfully");
} catch (error) {
console.error("Failed to start Dad Jokes MCP Server:", error);
process.exit(1);
}
}
}
// Start the server
const main = async (): Promise<void> => {
const dadJokesServer = new DadJokesMcpServer();
await dadJokesServer.start();
};
// Handle graceful shutdown
process.on('SIGINT', () => {
console.error('Received SIGINT, shutting down gracefully');
process.exit(0);
});
process.on('SIGTERM', () => {
console.error('Received SIGTERM, shutting down gracefully');
process.exit(0);
});
main().catch((error) => {
console.error("Unhandled error:", error);
process.exit(1);
});