=== UPDATES === - fieldedge: Added apps, tools, main server entry, full rebuild - lightspeed: Added complete src/ directory with tools + apps - squarespace: Full rebuild — new apps, clients, tools, types modules - toast: Full rebuild — api-client, apps, tools, types - touchbistro: Full rebuild — api-client, tools, types, gitignore - servicetitan: Added 4 React UI apps (call-tracking, lead-source-analytics, performance-metrics, schedule-calendar) All servers restructured from single-file to modular architecture.
120 lines
5.5 KiB
TypeScript
120 lines
5.5 KiB
TypeScript
/**
|
|
* Product Management Tools
|
|
*/
|
|
|
|
import { z } from 'zod';
|
|
import type { LightspeedClient } from '../clients/lightspeed.js';
|
|
|
|
export function registerProductTools(client: LightspeedClient) {
|
|
return [
|
|
{
|
|
name: 'lightspeed_list_products',
|
|
description: 'List all products in Lightspeed POS. Supports pagination and filtering by category.',
|
|
inputSchema: z.object({
|
|
limit: z.number().optional().describe('Number of products to return (default 100)'),
|
|
offset: z.number().optional().describe('Offset for pagination'),
|
|
categoryID: z.string().optional().describe('Filter by category ID')
|
|
}),
|
|
handler: async (args: any) => {
|
|
const result = await client.getProducts(args);
|
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
}
|
|
},
|
|
{
|
|
name: 'lightspeed_get_product',
|
|
description: 'Get a single product by ID with all details including pricing, cost, SKU, UPC, and category.',
|
|
inputSchema: z.object({
|
|
productID: z.string().describe('The product ID')
|
|
}),
|
|
handler: async (args: any) => {
|
|
const result = await client.getProduct(args.productID);
|
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
}
|
|
},
|
|
{
|
|
name: 'lightspeed_create_product',
|
|
description: 'Create a new product in Lightspeed. Requires description and default price at minimum.',
|
|
inputSchema: z.object({
|
|
description: z.string().describe('Product description/name'),
|
|
sku: z.string().optional().describe('Stock keeping unit'),
|
|
upc: z.string().optional().describe('Universal product code'),
|
|
defaultCost: z.number().optional().describe('Default cost price'),
|
|
defaultPrice: z.number().describe('Default selling price'),
|
|
categoryID: z.string().optional().describe('Category ID'),
|
|
manufacturerID: z.string().optional().describe('Manufacturer ID'),
|
|
supplierID: z.string().optional().describe('Primary supplier ID'),
|
|
tax: z.boolean().optional().describe('Whether product is taxable'),
|
|
discountable: z.boolean().optional().describe('Whether product can be discounted'),
|
|
onlinePrice: z.number().optional().describe('Online store price'),
|
|
msrp: z.number().optional().describe('Manufacturer suggested retail price')
|
|
}),
|
|
handler: async (args: any) => {
|
|
const result = await client.createProduct(args);
|
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
}
|
|
},
|
|
{
|
|
name: 'lightspeed_update_product',
|
|
description: 'Update an existing product. Can modify any product field including prices, description, category, etc.',
|
|
inputSchema: z.object({
|
|
productID: z.string().describe('The product ID to update'),
|
|
description: z.string().optional().describe('Product description/name'),
|
|
sku: z.string().optional().describe('Stock keeping unit'),
|
|
defaultCost: z.number().optional().describe('Default cost price'),
|
|
defaultPrice: z.number().optional().describe('Default selling price'),
|
|
onlinePrice: z.number().optional().describe('Online store price'),
|
|
categoryID: z.string().optional().describe('Category ID'),
|
|
manufacturerID: z.string().optional().describe('Manufacturer ID'),
|
|
supplierID: z.string().optional().describe('Primary supplier ID'),
|
|
tax: z.boolean().optional().describe('Whether product is taxable'),
|
|
archived: z.boolean().optional().describe('Archive the product')
|
|
}),
|
|
handler: async (args: any) => {
|
|
const { productID, ...updates } = args;
|
|
const result = await client.updateProduct(productID, updates);
|
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
}
|
|
},
|
|
{
|
|
name: 'lightspeed_delete_product',
|
|
description: 'Delete a product from Lightspeed. This action cannot be undone.',
|
|
inputSchema: z.object({
|
|
productID: z.string().describe('The product ID to delete')
|
|
}),
|
|
handler: async (args: any) => {
|
|
const result = await client.deleteProduct(args.productID);
|
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
}
|
|
},
|
|
{
|
|
name: 'lightspeed_archive_product',
|
|
description: 'Archive a product (soft delete). Archived products are hidden but can be restored.',
|
|
inputSchema: z.object({
|
|
productID: z.string().describe('The product ID to archive')
|
|
}),
|
|
handler: async (args: any) => {
|
|
const result = await client.updateProduct(args.productID, { archived: true });
|
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
}
|
|
},
|
|
{
|
|
name: 'lightspeed_search_products_by_sku',
|
|
description: 'Search for products by SKU or partial SKU match.',
|
|
inputSchema: z.object({
|
|
sku: z.string().describe('SKU to search for')
|
|
}),
|
|
handler: async (args: any) => {
|
|
const result = await client.getProducts({ limit: 100 });
|
|
if (result.success) {
|
|
const filtered = result.data.filter(p =>
|
|
p.sku?.toLowerCase().includes(args.sku.toLowerCase()) ||
|
|
p.customSku?.toLowerCase().includes(args.sku.toLowerCase())
|
|
);
|
|
return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: filtered }, null, 2) }] };
|
|
}
|
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
}
|
|
}
|
|
];
|
|
}
|