dad-jokes-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dad-jokes-mcpget a random dad joke"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Agent instructions: See
AGENTS.mdfor architecture, commands, and how to add tools.
Available Tools
Tool Name | Description | Input | Output | Example | curl |
| Fetch a random dad joke and save it | None | Joke text |
|
|
| Fetch multiple random dad jokes at once |
| Array of jokes |
|
|
| Show server version, sources count, stored jokes, tools | None | JSON status |
|
|
| View all jokes stored in www/jokes.json | None | All saved jokes |
|
|
| Delete all saved jokes | None | Confirmation |
|
|
| Get joke from category |
| Joke from category |
|
|
| Ensure at least N jokes are stored; fetches if needed |
| N jokes from pool |
|
|
| Fetch and store N new jokes unconditionally |
| N new jokes added |
|
|
| Add a custom joke manually |
| Confirmation |
|
|
| Remove null/empty entries from the pool | None | Cleanup result |
|
|
Related MCP server: Jokes MCP Server
How MCP Tool Routing Works
The Short Answer
Nej, det er ikke hardkodet. Det er dynamisk routing baseret pΓ₯ tool-navn.
Hvad der sker nΓ₯r du skriver:
@dad-jokes-mcp get_multiple_jokes count=10Step 1: PA parser din besked
PA ser
@dad-jokes-mcp= server navnPA ser
get_multiple_jokes= tool navnPA ser
count=10= argument
Step 2: PA laver en JSON-RPC request
{
"jsonrpc": "2.0",
"id": 123,
"method": "tools/call",
"params": {
"name": "get_multiple_jokes",
"arguments": {
"count": 10
}
}
}Step 3: MCP Server modtager request
Serveren (dad_jokes_mcp.mjs) modtager JSON via POST /mcp:
if (request.method === "tools/call") {
const { name, arguments: args } = request.params;
// name = "get_multiple_jokes"
// args = { count: 10 }
**Step 4: Server matcher tool-navn og udfΓΈrer**
Serveren bruger et **handler lookup-objekt** i stedet for if/else:
```javascript
const handlers = {
get_random_joke: async () => { /* ... */ },
get_multiple_jokes: async () => { /* ... */ }, // β MATCH!
get_all_jokes: async () => { /* ... */ },
clear_jokes: async () => { /* ... */ },
get_joke_category: async () => { /* ... */ },
fill_jokes_batch: async () => { /* ... */ },
add_jokes: async () => { /* ... */ },
add_joke: async () => { /* ... */ },
clean_jokes: async () => { /* ... */ },
};
const handler = handlers[name];
if (handler) {
toolResponse = await handler(args);
} else {
toolResponse = { error: { code: -32601, message: `Tool not found: ${name}` } };
}Step 5: Server returnerer resultat
{
"jsonrpc": "2.0",
"id": 123,
"result": {
"content": [
{
"type": "text",
"text": "π 10 Dad Jokes:\n\n1. ...\n2. ..."
}
]
}
}Step 6: PA viser resultatet
PA modtager resultatet og viser det for brugeren.
Hvorfor er det ikke hardkodet?
Tool-navne er defineret dynamisk - I
tools/listmetoden returnerer serveren hvilke tools der findesArguments er dynamiske - Hver tool kan have forskellige inputs
Routing er baseret pΓ₯ string matching -
if (name === "tool_name")matcher kun hvis navn passer
Hvis du tilfΓΈjede en ny tool
Du skulle:
TilfΓΈje den til
tools/listresponse:
{
name: "my_new_tool",
description: "What it does",
inputSchema: { /* ... */ }
}TilfΓΈje en key i
handlers-objektet itools/call:
my_new_tool: async () => {
return { content: [{ type: "text", text: "Result" }] };
},PA ville automatisk detektere den næste gang den kalder
tools/list!
MCP Protocol Flow
PA Client MCP Server (dad_jokes_mcp.js)
β β
ββ POST /mcp (initialize) ββββββββββββββββ€
β β
β βββββ { serverInfo, capabilities } βββββ€
β β
ββ POST /mcp (tools/list) ββββββββββββββββ€
β β
β βββββ { tools: [...] } βββββββββββββββββ€
β β
ββ POST /mcp (tools/call) ββββββββββββββββ€
β { name: "get_multiple_jokes", ... } β
β β
β βββββ { result: { content: [...] } } βββ€
β βAPI Details
MCP Endpoint: /mcp
Method: POST
Headers:
Content-Type: application/jsonMcp-Session-Id(response header - auto-generated)
Request Format: JSON-RPC 2.0
Example request body for calling a tool:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_random_joke",
"arguments": {}
}
}Dad Jokes MCP Server
A Model Context Protocol (MCP) server that fetches and manages dad jokes via Streamable HTTP transport. Jokes are automatically saved to persistent storage.
Features
π― Streamable HTTP Transport - Uses MCP 2024-11-05 protocol
πΎ Persistent Storage - Jokes automatically saved to
www/jokes.jsonπ Multiple Joke Sources - Fetches from 9+ joke APIs
π³ Docker Ready - Full Docker setup with volume mounts
π§ 10 Tools:
get_random_joke- Fetch a random dad joke and save itget_multiple_jokes- Fetch multiple jokes at onceserver_status- View server status, version, and statsget_all_jokes- View all saved jokesclear_jokes- Clear saved jokesget_joke_category- Get jokes by category (Programming, Knock-knock, General, Chuck Norris)fill_jokes_batch- Ensure at least N jokes are storedadd_jokes- Fetch and store N new jokesadd_joke- Add a custom joke manuallyclean_jokes- Remove null/empty entries
Quick Start
Prerequisites
Docker & Docker Compose
Node.js 20+ (for local development)
Run with Docker
docker compose up -dThe server will start on http://localhost:5000/ (frontend) with MCP endpoint at /mcp
MCP Configuration
Add to your MCP client config (Gemini, Page Assist, etc):
{
"mcp": {
"servers": {
"dad-jokes": {
"url": "http://localhost:5000/mcp"
}
}
}
}Testing
See docs/test.md for the full test suite, JSON fixtures, and gotchas.
Test with curl
# Initialize
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
# List tools
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# Get a random joke
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_random_joke","arguments":{}}}'Project Structure
dad-jokes-mcp/
βββ dad_jokes_mcp.mjs # Main server code
βββ package.json # Node.js dependencies
βββ Dockerfile # Docker image definition
βββ docker-compose.yml # Docker Compose config
βββ .dockerignore # Docker build exclusions
βββ www/
β βββ jokes.json # Persistent jokes storage
βββ .git/ # Git repositoryJokes Storage
Jokes are automatically saved to www/jokes.json with the following structure:
[
"Chuck Norris can understand women.",
"Why did the scarecrow win an award? He was outstanding in his field.",
"..."
]The file persists across container restarts due to Docker volume mounting.
API Details
MCP Endpoint: /mcp
Method: POST
Headers:
Content-Type: application/jsonMcp-Session-Id(response header - auto-generated)
Request Format: JSON-RPC 2.0
Example request body for calling a tool:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_random_joke",
"arguments": {}
}
}Environment Variables
PORT- Server port (default: 5000)
Docker Volumes
./www:/app/www- Mounts localwww/directory for persistent joke storage
Development
Local Development (without Docker)
npm install
PORT=5000 node dad_jokes_mcp.mjsBuild Docker Image
docker compose buildView Logs
docker logs dad-jokes-mcp-server -fTroubleshooting
MCP Validation Failed
If you see "Legacy MCP SSE endpoints are not supported", ensure your MCP client is configured to use the Streamable HTTP endpoint:
http://localhost:5000/mcp β Correct
http://localhost:5000/sse β Deprecated (SSE)No Jokes Saved
Check Docker volume mount:
docker compose config | grep volumesVerify
www/directory exists:ls -la www/Check container logs:
docker logs dad-jokes-mcp-server
API Connection Issues
Ensure server is running:
curl http://localhost:5000/Check port availability:
netstat -an | grep 5000Verify firewall allows port 5000
Performance
Joke fetching: ~1-3 seconds (with retries)
JSON parsing: <100ms
File I/O: ~50-200ms depending on disk speed
License
MIT
Author
Michael G. Nielsen
Dad jokes duh π
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MichaelGNielsen/dad-jokes-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server