Skip to main content
Glama

MCP Prompts Server

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; import { logger } from './utils.js'; import { readFileSync } from 'fs'; import { join } from 'path'; // Define the prompt schema const PromptSchema = z.object({ id: z.string(), name: z.string(), content: z.string(), isTemplate: z.boolean().default(false), tags: z.array(z.string()).default([]), variables: z.array(z.union([z.string(), z.object({ name: z.string(), description: z.string().optional(), required: z.boolean().default(true), type: z.enum(['string', 'number', 'boolean']).default('string') })])).optional(), metadata: z.record(z.any()).optional() }); const CreatePromptParams = PromptSchema.omit({ id: true }); const UpdatePromptParams = PromptSchema.partial().omit({ id: true }); // In-memory storage for prompts const prompts = new Map<string, any>(); // Load sample prompts on startup function loadSamplePrompts() { try { const sampleDataPath = join(process.cwd(), 'data', 'sample-prompts.json'); const sampleData = JSON.parse(readFileSync(sampleDataPath, 'utf8')); for (const prompt of sampleData.prompts) { prompts.set(prompt.id, { ...prompt, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), version: 1 }); } logger.info(`Loaded ${sampleData.prompts.length} sample prompts`); } catch (error) { logger.warn('Could not load sample prompts:', error); } } export async function createMcpServer() { const server = new McpServer({ name: 'mcp-prompts', version: '3.0.8', }); // Load sample prompts loadSamplePrompts(); // Tool: Add a new prompt server.tool('add_prompt', async (params: any) => { try { const validatedParams = CreatePromptParams.parse(params); const id = `prompt_${Date.now()}_${Math.random().toString(36).substring(2)}`; const prompt = { ...validatedParams, id, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), version: 1 }; prompts.set(id, prompt); logger.info(`Added prompt: ${id}`); return { content: [ { type: 'text', text: `Prompt "${prompt.name}" added successfully with ID: ${id}` } ] }; } catch (error) { logger.error('Error adding prompt:', error); throw new Error(`Failed to add prompt: ${error}`); } }); // Tool: Get a prompt by ID server.tool('get_prompt', async (params: any) => { try { const { id } = z.object({ id: z.string() }).parse(params); const prompt = prompts.get(id); if (!prompt) { throw new Error(`Prompt with ID ${id} not found`); } return { content: [ { type: 'text', text: JSON.stringify(prompt, null, 2) } ] }; } catch (error) { logger.error('Error getting prompt:', error); throw new Error(`Failed to get prompt: ${error}`); } }); // Tool: List all prompts server.tool('list_prompts', async (params: any = {}) => { try { const validatedParams = z.object({ tags: z.array(z.string()).optional(), search: z.string().optional() }).optional().parse(params); let promptList = Array.from(prompts.values()); // Filter by tags if provided if (validatedParams?.tags && validatedParams.tags.length > 0) { promptList = promptList.filter(prompt => validatedParams.tags!.some(tag => prompt.tags.includes(tag)) ); } // Filter by search term if provided if (validatedParams?.search) { const searchLower = validatedParams.search.toLowerCase(); promptList = promptList.filter(prompt => prompt.name.toLowerCase().includes(searchLower) || prompt.content.toLowerCase().includes(searchLower) ); } return { content: [ { type: 'text', text: JSON.stringify(promptList, null, 2) } ] }; } catch (error) { logger.error('Error listing prompts:', error); throw new Error(`Failed to list prompts: ${error}`); } }); // Tool: Update a prompt server.tool('update_prompt', async (params: any) => { try { const { id, updates } = z.object({ id: z.string(), updates: UpdatePromptParams }).parse(params); const prompt = prompts.get(id); if (!prompt) { throw new Error(`Prompt with ID ${id} not found`); } const updatedPrompt = { ...prompt, ...updates, updatedAt: new Date().toISOString(), version: prompt.version + 1 }; prompts.set(id, updatedPrompt); logger.info(`Updated prompt: ${id}`); return { content: [ { type: 'text', text: `Prompt "${updatedPrompt.name}" updated successfully` } ] }; } catch (error) { logger.error('Error updating prompt:', error); throw new Error(`Failed to update prompt: ${error}`); } }); // Tool: Delete a prompt server.tool('delete_prompt', async (params: any) => { try { const { id } = z.object({ id: z.string() }).parse(params); const prompt = prompts.get(id); if (!prompt) { throw new Error(`Prompt with ID ${id} not found`); } prompts.delete(id); logger.info(`Deleted prompt: ${id}`); return { content: [ { type: 'text', text: `Prompt "${prompt.name}" deleted successfully` } ] }; } catch (error) { logger.error('Error deleting prompt:', error); throw new Error(`Failed to delete prompt: ${error}`); } }); // Tool: Apply template variables to a prompt server.tool('apply_template', async (params: any) => { try { const { id, variables } = z.object({ id: z.string(), variables: z.record(z.any()) }).parse(params); const prompt = prompts.get(id); if (!prompt) { throw new Error(`Prompt with ID ${id} not found`); } if (!prompt.isTemplate) { throw new Error(`Prompt "${prompt.name}" is not a template`); } let result = prompt.content; // Simple variable substitution for (const [key, value] of Object.entries(variables)) { const placeholder = `{{${key}}}`; result = result.replace(new RegExp(placeholder, 'g'), String(value)); } return { content: [ { type: 'text', text: result } ] }; } catch (error) { logger.error('Error applying template:', error); throw new Error(`Failed to apply template: ${error}`); } }); // Tool: Get prompt statistics server.tool('get_stats', async () => { try { const promptList = Array.from(prompts.values()); const stats = { total: promptList.length, templates: promptList.filter(p => p.isTemplate).length, regular: promptList.filter(p => !p.isTemplate).length, tags: Array.from(new Set(promptList.flatMap(p => p.tags || []))), categories: Array.from(new Set(promptList.map(p => p.metadata?.category).filter(Boolean))) }; return { content: [ { type: 'text', text: JSON.stringify(stats, null, 2) } ] }; } catch (error) { logger.error('Error getting stats:', error); throw new Error(`Failed to get stats: ${error}`); } }); return server; } export async function startMcpServer() { const server = await createMcpServer(); const transport = new StdioServerTransport(); await server.connect(transport); logger.info('MCP Prompts server started on stdio transport'); return server; }

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/sparesparrow/mcp-prompts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server