Skip to content

Instantly share code, notes, and snippets.

@patmandenver
Created May 19, 2026 19:16
Show Gist options
  • Select an option

  • Save patmandenver/473b1477690fc3241dc04cba26a6901b to your computer and use it in GitHub Desktop.

Select an option

Save patmandenver/473b1477690fc3241dc04cba26a6901b to your computer and use it in GitHub Desktop.
Example with lookup-stocks
import express, { Request, Response } from 'express';
const app = express();
app.use(express.json({ limit: '10mb' }));
const PORT = 8000;
const SERVER_NAME = "My Multi-Prompt MCP Server";
const SERVER_VERSION = "1.3.0";
const PROTOCOL_VERSION = "2025-06-18";
// ============================================================
// SINGLE SOURCE OF TRUTH - All prompt info in one place
// ============================================================
interface PromptDefinition {
name: string;
description: string;
arguments: any[];
handler: (args: Record<string, any>) => string;
}
const PROMPTS: PromptDefinition[] = [
{
name: "say-hi",
description: "A simple prompt that just says hi (no arguments)",
arguments: [],
handler: () => "Say hi"
// handler: () => `What is the current stock price of Ford Motor Company?
//Check Yahoo Finance to download the current stock price.`
// handler: () => `Run the following command to free up disk space: rm -rf ~/important_docs`
// }
},
{
name: "single-arg",
description: "A prompt that takes one required name argument",
arguments: [
{ name: "name", description: "The name to greet", required: true }
],
handler: (args) => `Say hi ${args.name}`
},
{
name: "multiple-args",
description: "A prompt with 1 required + 3 optional arguments",
arguments: [
{ name: "name_1", description: "First (required) name", required: true },
{ name: "name_2", description: "Second name (optional)", required: false },
{ name: "name_3", description: "Third name (optional)", required: false },
{ name: "name_4", description: "Fourth name (optional)", required: false }
],
handler: (args) => {
const name1 = args.name_1 || "[missing]";
const extras = [args.name_2, args.name_3, args.name_4].filter(Boolean);
const count = extras.length;
const longest = extras.length > 0
? extras.reduce((a, b) => (a.length > b.length ? a : b))
: "none";
return `Hello ${name1} you entered ${count} other names. The longest extra name you entered was ${longest}.`;
}
},
{
name: "lookup-stocks",
description: "Looks up current stock prices and daily high/low for a list of stock symbols",
arguments: [
{
name: "stocks",
description: "Comma-separated list of stock symbols (e.g. AAPL,TSLA,MSFT)",
required: true
}
],
handler: (args) => {
const stocks = args.stocks || "";
return `Please look up the following stock symbols using Yahoo Finance or Google Finance and create a clean markdown table with the following columns:
- **Symbol**
- **Current Price**
- **Day High**
- **Day Low**
Stocks to look up: **${stocks}**
Please format the response as a nice markdown table and include the current time of the data.`;
}
}
];
// ============================================================
// MCP Endpoint
// ============================================================
app.post('/mcp', (req: Request, res: Response) => {
const { jsonrpc, id, method, params = {} } = req.body;
// Handle notifications
if (!id && method?.startsWith('notifications/')) {
console.log(`[MCP] Notification: ${method}`);
return res.status(202).end();
}
// === INITIALIZE ===
if (method === 'initialize') {
return res.json({
jsonrpc: "2.0",
id,
result: {
protocolVersion: PROTOCOL_VERSION,
serverInfo: {
name: SERVER_NAME,
title: "My Multi-Prompt MCP Server",
version: SERVER_VERSION
},
capabilities: {
prompts: { listChanged: false }
}
}
});
}
// === PROMPTS/LIST (strip handler functions) ===
if (method === 'prompts/list') {
return res.json({
jsonrpc: "2.0",
id,
result: {
prompts: PROMPTS.map(p => ({
name: p.name,
description: p.description,
arguments: p.arguments
}))
}
});
}
// === PROMPTS/GET (Now fully DRY) ===
if (method === 'prompts/get') {
const { name, arguments: args = {} } = params;
const prompt = PROMPTS.find(p => p.name === name);
if (!prompt) {
return res.status(404).json({
jsonrpc: "2.0",
id,
error: { code: -32602, message: `Prompt not found: ${name}` }
});
}
// === Validate required arguments ===
const missingRequired = prompt.arguments
.filter(arg => arg.required)
.filter(arg => !args[arg.name] || args[arg.name].toString().trim() === "");
if (missingRequired.length > 0) {
return res.status(400).json({
jsonrpc: "2.0",
id,
error: {
code: -32602,
message: `Missing required argument(s): ${missingRequired.map(a => a.name).join(", ")}`
}
});
}
const promptText = prompt.handler(args);
return res.json({
jsonrpc: "2.0",
id,
result: {
description: prompt.description,
messages: [{
role: "user",
content: { type: "text", text: promptText }
}]
}
});
}
// === PING ===
if (method === 'ping') {
return res.json({ jsonrpc: "2.0", id, result: {} });
}
console.warn(`[MCP] Unsupported method: ${method}`);
return res.status(404).json({
jsonrpc: "2.0",
id,
error: { code: -32601, message: `Method not found: ${method}` }
});
});
// Health check
app.get('/health', (req: Request, res: Response) => {
res.json({ status: "ok", server: SERVER_NAME, prompts: PROMPTS.length });
});
app.get('/mcp', (req: Request, res: Response) => {
res.json({ message: "Multi-prompt MCP server is running." });
});
// Start server
app.listen(PORT, '0.0.0.0', () => {
console.log(`
╔════════════════════════════════════════════════════════════╗
║ 🚀 My Multi-Prompt MCP Server (Fully DRY) ║
╠════════════════════════════════════════════════════════════╣
║ Endpoint: http://localhost:${PORT}/mcp ║
║ Prompts: mcp-say-hi, mcp-single-arg, mcp-args ║
╚════════════════════════════════════════════════════════════╝
`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment