MCP Maker

/** * Example Resource for {{project_name}} * * This is a simple example resource that demonstrates the basic structure * of an MCP server resource with REST endpoints. */ import { Router } from 'express'; import { z } from 'zod'; import { body, param, validationResult } from 'express-validator'; const router = Router(); // Simple in-memory storage for the example const exampleItems: Record<string, ExampleItem> = {}; // Resource schema const exampleItemSchema = z.object({ id: z.string().optional(), name: z.string().min(1).max(100), description: z.string().optional(), createdAt: z.date().optional(), updatedAt: z.date().optional(), }); // Type for the resource type ExampleItem = z.infer<typeof exampleItemSchema>; // GET all items router.get('/', (req, res) => { const items = Object.values(exampleItems); res.status(200).json({ items }); }); // GET item by ID router.get('/:id', param('id').isString().notEmpty().withMessage('Valid ID is required'), (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { id } = req.params; const item = exampleItems[id]; if (!item) { return res.status(404).json({ error: 'Item not found' }); } res.status(200).json(item); } ); // CREATE item router.post('/', body('name').isString().notEmpty().withMessage('Name is required'), body('description').optional().isString().withMessage('Description must be a string'), (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } try { const parsedInput = exampleItemSchema.safeParse(req.body); if (!parsedInput.success) { return res.status(400).json({ error: 'Invalid input', details: parsedInput.error.format() }); } const now = new Date(); const id = `example-${Date.now()}`; const newItem: ExampleItem = { ...parsedInput.data, id, createdAt: now, updatedAt: now }; exampleItems[id] = newItem; res.status(201).json(newItem); } catch (error) { console.error('Error creating item:', error); res.status(500).json({ error: 'Failed to create item' }); } } ); // UPDATE item router.put('/:id', param('id').isString().notEmpty().withMessage('Valid ID is required'), body('name').optional().isString().notEmpty().withMessage('Name cannot be empty'), body('description').optional().isString().withMessage('Description must be a string'), (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { id } = req.params; const existingItem = exampleItems[id]; if (!existingItem) { return res.status(404).json({ error: 'Item not found' }); } try { // Only update fields that are provided const updatedItem: ExampleItem = { ...existingItem, ...req.body, id, // Ensure ID remains the same updatedAt: new Date() }; exampleItems[id] = updatedItem; res.status(200).json(updatedItem); } catch (error) { console.error('Error updating item:', error); res.status(500).json({ error: 'Failed to update item' }); } } ); // DELETE item router.delete('/:id', param('id').isString().notEmpty().withMessage('Valid ID is required'), (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { id } = req.params; if (!exampleItems[id]) { return res.status(404).json({ error: 'Item not found' }); } delete exampleItems[id]; res.status(204).send(); } ); export default router;
ID: gsr895nac1