Skip to main content
Glama

Fake Store API MCP Server

by op-enny
products.ts6.73 kB
/** * Product-related MCP tools */ import { get, post, put, del } from '../utils/api.js'; import { Product, SortOrder } from '../types/fakestore.js'; import { validatePositiveInteger, validateSortOrder, validateLimit, validateUrl, sanitizePathSegment } from '../utils/validators.js'; /** * Get all products with optional limit and sort */ export async function getAllProducts(args: { limit?: number; sort?: SortOrder }): Promise<Product[]> { const { limit, sort } = args; if (limit !== undefined) { validateLimit(limit); } if (sort !== undefined) { validateSortOrder(sort); } const params: Record<string, unknown> = {}; if (limit) params.limit = limit; if (sort) params.sort = sort; return get<Product[]>('/products', params); } /** * Get a single product by ID */ export async function getProductById(args: { id: number }): Promise<Product> { const { id } = args; validatePositiveInteger(id, 'Product ID'); return get<Product>(`/products/${id}`); } /** * Get all product categories */ export async function getCategories(): Promise<string[]> { return get<string[]>('/products/categories'); } /** * Get products by category */ export async function getProductsByCategory(args: { category: string }): Promise<Product[]> { const { category } = args; if (!category || typeof category !== 'string') { throw new Error('Category must be a non-empty string'); } const sanitizedCategory = sanitizePathSegment(category); return get<Product[]>(`/products/category/${sanitizedCategory}`); } /** * Add a new product (simulation - returns the product with an ID) */ export async function addProduct(args: { title: string; price: number; description: string; image: string; category: string; }): Promise<Product> { const { title, price, description, image, category } = args; if (!title || typeof title !== 'string') { throw new Error('Title must be a non-empty string'); } if (typeof price !== 'number' || price <= 0) { throw new Error('Price must be a positive number'); } if (!description || typeof description !== 'string') { throw new Error('Description must be a non-empty string'); } validateUrl(image, 'Image URL'); if (!category || typeof category !== 'string') { throw new Error('Category must be a non-empty string'); } return post<Product>('/products', { title, price, description, image, category, }); } /** * Update a product (simulation) */ export async function updateProduct(args: { id: number; title?: string; price?: number; description?: string; image?: string; category?: string; }): Promise<Product> { const { id, title, price, description, image, category } = args; validatePositiveInteger(id, 'Product ID'); const updateData: Record<string, unknown> = {}; if (title !== undefined) updateData.title = title; if (price !== undefined) updateData.price = price; if (description !== undefined) updateData.description = description; if (image !== undefined) { validateUrl(image, 'Image URL'); updateData.image = image; } if (category !== undefined) updateData.category = category; return put<Product>(`/products/${id}`, updateData); } /** * Delete a product (simulation) */ export async function deleteProduct(args: { id: number }): Promise<Product> { const { id } = args; validatePositiveInteger(id, 'Product ID'); return del<Product>(`/products/${id}`); } /** * Product tools definitions for MCP */ export const productTools = [ { name: 'fakestore_get_products', description: 'Get all products from the store. Optionally limit results and sort by price.', inputSchema: { type: 'object', properties: { limit: { type: 'number', description: 'Limit the number of products returned', }, sort: { type: 'string', enum: ['asc', 'desc'], description: 'Sort products by price (asc or desc)', }, }, }, }, { name: 'fakestore_get_product', description: 'Get a single product by its ID', inputSchema: { type: 'object', properties: { id: { type: 'number', description: 'Product ID', }, }, required: ['id'], }, }, { name: 'fakestore_get_categories', description: 'Get all available product categories', inputSchema: { type: 'object', properties: {}, }, }, { name: 'fakestore_get_products_by_category', description: 'Get all products in a specific category', inputSchema: { type: 'object', properties: { category: { type: 'string', description: 'Product category name', }, }, required: ['category'], }, }, { name: 'fakestore_add_product', description: 'Add a new product to the store (simulation - does not persist)', inputSchema: { type: 'object', properties: { title: { type: 'string', description: 'Product title', }, price: { type: 'number', description: 'Product price', }, description: { type: 'string', description: 'Product description', }, image: { type: 'string', description: 'Product image URL', }, category: { type: 'string', description: 'Product category', }, }, required: ['title', 'price', 'description', 'image', 'category'], }, }, { name: 'fakestore_update_product', description: 'Update an existing product (simulation - does not persist)', inputSchema: { type: 'object', properties: { id: { type: 'number', description: 'Product ID to update', }, title: { type: 'string', description: 'New product title', }, price: { type: 'number', description: 'New product price', }, description: { type: 'string', description: 'New product description', }, image: { type: 'string', description: 'New product image URL', }, category: { type: 'string', description: 'New product category', }, }, required: ['id'], }, }, { name: 'fakestore_delete_product', description: 'Delete a product (simulation - does not persist)', inputSchema: { type: 'object', properties: { id: { type: 'number', description: 'Product ID to delete', }, }, required: ['id'], }, }, ];

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/op-enny/mcp-server-fakestore'

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