diff --git a/servers/toast/README.md b/servers/toast/README.md deleted file mode 100644 index 889f636..0000000 --- a/servers/toast/README.md +++ /dev/null @@ -1,380 +0,0 @@ -# Toast MCP Server - -A complete Model Context Protocol (MCP) server for Toast POS integration, providing comprehensive access to orders, menus, employees, labor, payments, inventory, customers, and reporting. - -## Features - -### 🔧 50+ MCP Tools - -#### Orders (9 tools) -- `toast_list_orders` - List orders with date range filtering -- `toast_get_order` - Get order details -- `toast_create_order` - Create new orders -- `toast_update_order` - Update order details -- `toast_add_order_item` - Add items to orders -- `toast_remove_order_item` - Remove items from orders -- `toast_apply_discount` - Apply discounts -- `toast_void_order` - Void orders -- `toast_list_order_checks` - List order checks - -#### Menus (8 tools) -- `toast_list_menus` - List all menus -- `toast_get_menu` - Get menu details -- `toast_list_menu_groups` - List menu groups -- `toast_get_menu_group` - Get group details -- `toast_list_menu_items` - List menu items -- `toast_get_menu_item` - Get item details -- `toast_list_item_modifiers` - List item modifiers -- `toast_update_item_price` - Update item pricing - -#### Employees (10 tools) -- `toast_list_employees` - List all employees -- `toast_get_employee` - Get employee details -- `toast_create_employee` - Create new employees -- `toast_update_employee` - Update employee info -- `toast_delete_employee` - Delete employees -- `toast_list_employee_jobs` - List employee jobs -- `toast_list_employee_shifts` - List employee shifts -- `toast_clock_in` - Clock in employees -- `toast_clock_out` - Clock out employees -- `toast_list_time_entries` - List time entries - -#### Labor (5 tools) -- `toast_list_shifts` - List all shifts -- `toast_get_shift` - Get shift details -- `toast_list_shift_breaks` - List shift breaks -- `toast_get_labor_cost` - Get labor cost reports -- `toast_list_jobs` - List job positions - -#### Restaurant (5 tools) -- `toast_get_restaurant_info` - Get restaurant info -- `toast_list_revenue_centers` - List revenue centers -- `toast_list_dining_options` - List dining options -- `toast_list_service_areas` - List service areas -- `toast_list_tables` - List tables - -#### Payments (5 tools) -- `toast_list_payments` - List payments -- `toast_get_payment` - Get payment details -- `toast_void_payment` - Void payments -- `toast_refund_payment` - Process refunds -- `toast_list_tips` - List tips - -#### Inventory (5 tools) -- `toast_list_inventory_items` - List inventory -- `toast_get_inventory_item` - Get item details -- `toast_update_inventory_count` - Update counts -- `toast_list_vendors` - List vendors -- `toast_create_purchase_order` - Create POs - -#### Customers (6 tools) -- `toast_list_customers` - List customers -- `toast_get_customer` - Get customer details -- `toast_create_customer` - Create customers -- `toast_update_customer` - Update customer info -- `toast_list_customer_loyalty` - List loyalty info -- `toast_add_loyalty_points` - Add loyalty points - -#### Reporting (5 tools) -- `toast_sales_summary` - Sales summary reports -- `toast_labor_cost_report` - Labor cost analysis -- `toast_menu_item_performance` - Menu performance -- `toast_revenue_by_hour` - Hourly revenue -- `toast_tip_summary` - Tip summaries - -#### Cash Management (2 tools) -- `toast_list_cash_entries` - List cash entries -- `toast_get_drawer_status` - Get drawer status - -### 📊 18 MCP Apps - -1. **order-dashboard** - Real-time order monitoring -2. **order-detail** - Detailed order view -3. **order-grid** - Searchable order grid -4. **menu-manager** - Menu management interface -5. **menu-item-detail** - Item detail view -6. **employee-dashboard** - Employee management -7. **employee-schedule** - Schedule planning -8. **labor-dashboard** - Labor analytics -9. **restaurant-overview** - Restaurant config -10. **table-map** - Interactive floor plan -11. **payment-history** - Payment tracking -12. **inventory-tracker** - Inventory management -13. **customer-detail** - Customer profiles -14. **customer-loyalty** - Loyalty program -15. **sales-dashboard** - Sales analytics -16. **menu-performance** - Menu analytics -17. **tip-summary** - Tip tracking -18. **revenue-by-hour** - Hourly revenue analysis - -## Installation - -```bash -npm install -npm run build -``` - -## Configuration - -Set the following environment variables: - -```bash -export TOAST_API_TOKEN="your-toast-api-token" -export TOAST_RESTAURANT_GUID="your-restaurant-guid" -export TOAST_BASE_URL="https://ws-api.toasttab.com" # Optional, defaults to production -``` - -### Getting Toast API Credentials - -1. Log in to Toast Web Admin -2. Navigate to Integrations → API -3. Create a new API token -4. Copy your Restaurant GUID from Settings → Restaurant Info - -## Usage - -### As MCP Server - -Add to your MCP client configuration: - -```json -{ - "mcpServers": { - "toast": { - "command": "node", - "args": ["/path/to/toast/dist/main.js"], - "env": { - "TOAST_API_TOKEN": "your-token", - "TOAST_RESTAURANT_GUID": "your-guid" - } - } - } -} -``` - -### Direct Execution - -```bash -npm start -``` - -## API Client Features - -- ✅ Bearer token authentication -- ✅ Restaurant GUID injection -- ✅ Automatic pagination handling -- ✅ Comprehensive error handling -- ✅ Rate limit awareness -- ✅ Retry logic -- ✅ Request/response logging - -## Tool Examples - -### List Today's Orders - -```typescript -{ - "name": "toast_list_orders", - "arguments": { - "startDate": "2025-01-28T00:00:00Z", - "endDate": "2025-01-28T23:59:59Z" - } -} -``` - -### Create New Order - -```typescript -{ - "name": "toast_create_order", - "arguments": { - "diningOptionGuid": "abc-123", - "tableGuid": "table-5", - "numberOfGuests": 4 - } -} -``` - -### Add Item to Order - -```typescript -{ - "name": "toast_add_order_item", - "arguments": { - "orderId": "order-123", - "checkGuid": "check-456", - "itemGuid": "item-789", - "quantity": 2, - "modifiers": [ - { "guid": "mod-1", "quantity": 1 } - ] - } -} -``` - -### Clock In Employee - -```typescript -{ - "name": "toast_clock_in", - "arguments": { - "employeeGuid": "emp-123", - "jobGuid": "job-server" - } -} -``` - -### Get Sales Summary - -```typescript -{ - "name": "toast_sales_summary", - "arguments": { - "startDate": "2025-01-28T00:00:00Z", - "endDate": "2025-01-28T23:59:59Z" - } -} -``` - -## MCP App Access - -Access apps via MCP resources: - -``` -toast://apps/order-dashboard -toast://apps/sales-dashboard -toast://apps/menu-manager -toast://apps/employee-schedule -toast://apps/table-map -``` - -## Architecture - -``` -toast/ -├── src/ -│ ├── api-client.ts # Toast API client with auth & pagination -│ ├── server.ts # MCP server implementation -│ ├── main.ts # Entry point -│ ├── types/ -│ │ └── index.ts # TypeScript type definitions -│ ├── tools/ -│ │ ├── orders-tools.ts # Order management tools -│ │ ├── menus-tools.ts # Menu management tools -│ │ ├── employees-tools.ts # Employee management tools -│ │ ├── labor-tools.ts # Labor tracking tools -│ │ ├── restaurant-tools.ts # Restaurant config tools -│ │ ├── payments-tools.ts # Payment processing tools -│ │ ├── inventory-tools.ts # Inventory management tools -│ │ ├── customers-tools.ts # Customer management tools -│ │ ├── reporting-tools.ts # Reporting & analytics tools -│ │ └── cash-tools.ts # Cash management tools -│ └── apps/ -│ └── index.ts # MCP app definitions -├── package.json -├── tsconfig.json -└── README.md -``` - -## Error Handling - -All tools return structured error responses: - -```json -{ - "content": [{ - "type": "text", - "text": "Error: Order not found (404)" - }], - "isError": true -} -``` - -## Pagination - -Tools support automatic pagination: - -```typescript -{ - "name": "toast_list_orders", - "arguments": { - "page": 2, - "pageSize": 50 - } -} -``` - -## Development - -```bash -# Install dependencies -npm install - -# Build TypeScript -npm run build - -# Watch mode for development -npm run dev - -# Start server -npm start -``` - -## API Documentation - -Toast API documentation: https://doc.toasttab.com/ - -### Key Endpoints - -- **Orders**: `/orders/v2/orders` -- **Menus**: `/menus/v2/menus` -- **Labor**: `/labor/v1/employees` -- **Payments**: `/payments/v1/payments` -- **Restaurant**: `/restaurants/v1/restaurants` - -## Security - -- API tokens stored in environment variables -- No credentials in code or logs -- Bearer token authentication -- HTTPS-only communication -- Restaurant GUID scoping - -## Support - -For Toast API support: https://central.toasttab.com/s/support - -## License - -MIT - -## Contributing - -1. Fork the repository -2. Create a feature branch -3. Commit your changes -4. Push to the branch -5. Create a Pull Request - -## Roadmap - -- [ ] WebSocket support for real-time updates -- [ ] Advanced reporting with custom date ranges -- [ ] Menu optimization recommendations -- [ ] Labor cost forecasting -- [ ] Inventory auto-reordering -- [ ] Customer segmentation -- [ ] A/B testing for menu items -- [ ] Integration with third-party delivery platforms -- [ ] Multi-location support -- [ ] Advanced analytics dashboards - -## Version History - -### 1.0.0 (2025-01-28) -- Initial release -- 50+ MCP tools -- 18 MCP apps -- Complete Toast API integration -- Comprehensive type definitions -- Error handling and pagination diff --git a/servers/toast/package-lock.json b/servers/toast/package-lock.json deleted file mode 100644 index 40b2b11..0000000 --- a/servers/toast/package-lock.json +++ /dev/null @@ -1,1313 +0,0 @@ -{ - "name": "@mcpengine/toast-server", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@mcpengine/toast-server", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@modelcontextprotocol/sdk": "^1.0.4", - "axios": "^1.7.9", - "zod": "^3.24.1" - }, - "bin": { - "toast-mcp": "dist/main.js" - }, - "devDependencies": { - "@types/node": "^22.10.5", - "typescript": "^5.7.3" - } - }, - "node_modules/@hono/node-server": { - "version": "1.19.9", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", - "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", - "license": "MIT", - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "hono": "^4" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", - "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==", - "license": "MIT", - "dependencies": { - "@hono/node-server": "^1.19.9", - "ajv": "^8.17.1", - "ajv-formats": "^3.0.1", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "eventsource-parser": "^3.0.0", - "express": "^5.2.1", - "express-rate-limit": "^8.2.1", - "hono": "^4.11.4", - "jose": "^6.1.3", - "json-schema-typed": "^8.0.2", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.25 || ^4.0", - "zod-to-json-schema": "^3.25.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@cfworker/json-schema": "^4.1.1", - "zod": "^3.25 || ^4.0" - }, - "peerDependenciesMeta": { - "@cfworker/json-schema": { - "optional": true - }, - "zod": { - "optional": false - } - } - }, - "node_modules/@types/node": { - "version": "22.19.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz", - "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "license": "MIT", - "peer": true, - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz", - "integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==", - "license": "MIT", - "dependencies": { - "ip-address": "10.0.1" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/form-data/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hono": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.9.tgz", - "integrity": "sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ip-address": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", - "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jose": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", - "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause" - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/pkce-challenge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", - "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.1", - "mime-types": "^3.0.2", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", - "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.25 || ^4" - } - } - } -} diff --git a/servers/toast/package.json b/servers/toast/package.json deleted file mode 100644 index 3369d31..0000000 --- a/servers/toast/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@mcpengine/toast-server", - "version": "1.0.0", - "description": "Complete Toast POS MCP Server - Orders, Menus, Employees, Labor, Payments, Inventory & More", - "type": "module", - "main": "dist/main.js", - "bin": { - "toast-mcp": "dist/main.js" - }, - "scripts": { - "build": "tsc", - "dev": "tsc --watch", - "start": "node dist/main.js", - "prepare": "npm run build" - }, - "keywords": [ - "mcp", - "toast", - "pos", - "restaurant", - "orders", - "payments" - ], - "author": "MCPEngine", - "license": "MIT", - "dependencies": { - "@modelcontextprotocol/sdk": "^1.0.4", - "axios": "^1.7.9", - "zod": "^3.24.1" - }, - "devDependencies": { - "@types/node": "^22.10.5", - "typescript": "^5.7.3" - } -} diff --git a/servers/toast/src/api-client.ts b/servers/toast/src/api-client.ts deleted file mode 100644 index 494cf74..0000000 --- a/servers/toast/src/api-client.ts +++ /dev/null @@ -1,365 +0,0 @@ -import axios, { AxiosInstance, AxiosError, AxiosRequestConfig } from 'axios'; -import type { ToastConfig, PaginationParams, PaginatedResponse } from './types/index.js'; - -export class ToastAPIError extends Error { - constructor( - message: string, - public statusCode?: number, - public response?: any - ) { - super(message); - this.name = 'ToastAPIError'; - } -} - -export class ToastAPIClient { - private client: AxiosInstance; - private config: ToastConfig; - - constructor(config: ToastConfig) { - this.config = { - baseUrl: config.baseUrl || 'https://ws-api.toasttab.com', - ...config, - }; - - this.client = axios.create({ - baseURL: this.config.baseUrl, - headers: { - 'Authorization': `Bearer ${this.config.apiToken}`, - 'Content-Type': 'application/json', - 'Toast-Restaurant-External-ID': this.config.restaurantGuid, - }, - timeout: 30000, - }); - - // Response interceptor for error handling - this.client.interceptors.response.use( - (response) => response, - (error: AxiosError) => { - if (error.response) { - const errorData = error.response.data as any; - throw new ToastAPIError( - errorData?.message || error.message, - error.response.status, - error.response.data - ); - } else if (error.request) { - throw new ToastAPIError('No response received from Toast API'); - } else { - throw new ToastAPIError(error.message); - } - } - ); - } - - // Generic GET request with pagination support - async get( - endpoint: string, - params?: Record, - config?: AxiosRequestConfig - ): Promise { - const response = await this.client.get(endpoint, { - params, - ...config, - }); - return response.data; - } - - // Generic POST request - async post( - endpoint: string, - data?: any, - config?: AxiosRequestConfig - ): Promise { - const response = await this.client.post(endpoint, data, config); - return response.data; - } - - // Generic PUT request - async put( - endpoint: string, - data?: any, - config?: AxiosRequestConfig - ): Promise { - const response = await this.client.put(endpoint, data, config); - return response.data; - } - - // Generic PATCH request - async patch( - endpoint: string, - data?: any, - config?: AxiosRequestConfig - ): Promise { - const response = await this.client.patch(endpoint, data, config); - return response.data; - } - - // Generic DELETE request - async delete( - endpoint: string, - config?: AxiosRequestConfig - ): Promise { - const response = await this.client.delete(endpoint, config); - return response.data; - } - - // Paginated GET request - async getPaginated( - endpoint: string, - pagination?: PaginationParams, - additionalParams?: Record - ): Promise> { - const params = { - page: pagination?.page || 1, - pageSize: pagination?.pageSize || 100, - ...additionalParams, - }; - - const response = await this.get(endpoint, params); - - // If the API returns pagination metadata, use it - // Otherwise, create a simple paginated response - return { - data: Array.isArray(response) ? response : [], - page: params.page, - pageSize: params.pageSize, - totalPages: 1, - totalCount: Array.isArray(response) ? response.length : 0, - }; - } - - // Get all pages automatically - async getAllPages( - endpoint: string, - pageSize: number = 100, - additionalParams?: Record - ): Promise { - const allData: T[] = []; - let page = 1; - let hasMore = true; - - while (hasMore) { - const response = await this.getPaginated( - endpoint, - { page, pageSize }, - additionalParams - ); - - allData.push(...response.data); - - // Check if there are more pages - hasMore = response.data.length === pageSize && page < response.totalPages; - page++; - } - - return allData; - } - - // Orders API - orders = { - list: (params?: { startDate?: string; endDate?: string; pagination?: PaginationParams }) => - this.getPaginated('/orders/v2/orders', params?.pagination, { - startDate: params?.startDate, - endDate: params?.endDate, - }), - - get: (orderId: string) => - this.get(`/orders/v2/orders/${orderId}`), - - create: (orderData: any) => - this.post('/orders/v2/orders', orderData), - - update: (orderId: string, orderData: any) => - this.put(`/orders/v2/orders/${orderId}`, orderData), - - void: (orderId: string, voidReason?: string) => - this.post(`/orders/v2/orders/${orderId}/void`, { voidReason }), - - listChecks: (orderId: string) => - this.get(`/orders/v2/orders/${orderId}/checks`), - - addItem: (orderId: string, checkId: string, itemData: any) => - this.post(`/orders/v2/orders/${orderId}/checks/${checkId}/selections`, itemData), - - removeItem: (orderId: string, checkId: string, selectionId: string) => - this.delete(`/orders/v2/orders/${orderId}/checks/${checkId}/selections/${selectionId}`), - - applyDiscount: (orderId: string, checkId: string, discountData: any) => - this.post(`/orders/v2/orders/${orderId}/checks/${checkId}/appliedDiscounts`, discountData), - }; - - // Menus API - menus = { - list: () => - this.get('/menus/v2/menus'), - - get: (menuId: string) => - this.get(`/menus/v2/menus/${menuId}`), - - listGroups: (menuId: string) => - this.get(`/menus/v2/menus/${menuId}/groups`), - - getGroup: (menuId: string, groupId: string) => - this.get(`/menus/v2/menus/${menuId}/groups/${groupId}`), - - listItems: (menuId: string, groupId?: string) => - groupId - ? this.get(`/menus/v2/menus/${menuId}/groups/${groupId}/items`) - : this.get(`/menus/v2/menus/${menuId}/items`), - - getItem: (menuId: string, itemId: string) => - this.get(`/menus/v2/menus/${menuId}/items/${itemId}`), - - listModifiers: (menuId: string, itemId: string) => - this.get(`/menus/v2/menus/${menuId}/items/${itemId}/modifierGroups`), - - updatePrice: (menuId: string, itemId: string, price: number) => - this.patch(`/menus/v2/menus/${menuId}/items/${itemId}`, { price }), - }; - - // Employees API - employees = { - list: (pagination?: PaginationParams) => - this.getPaginated('/labor/v1/employees', pagination), - - get: (employeeId: string) => - this.get(`/labor/v1/employees/${employeeId}`), - - create: (employeeData: any) => - this.post('/labor/v1/employees', employeeData), - - update: (employeeId: string, employeeData: any) => - this.put(`/labor/v1/employees/${employeeId}`, employeeData), - - delete: (employeeId: string) => - this.delete(`/labor/v1/employees/${employeeId}`), - - listJobs: (employeeId: string) => - this.get(`/labor/v1/employees/${employeeId}/jobs`), - - listShifts: (employeeId: string, startDate: string, endDate: string) => - this.get(`/labor/v1/employees/${employeeId}/shifts`, { startDate, endDate }), - - clockIn: (employeeId: string, jobId: string) => - this.post(`/labor/v1/employees/${employeeId}/timeEntries`, { - jobGuid: jobId, - inDate: new Date().toISOString(), - }), - - clockOut: (employeeId: string, timeEntryId: string) => - this.patch(`/labor/v1/employees/${employeeId}/timeEntries/${timeEntryId}`, { - outDate: new Date().toISOString(), - }), - - listTimeEntries: (employeeId: string, startDate: string, endDate: string) => - this.get(`/labor/v1/employees/${employeeId}/timeEntries`, { startDate, endDate }), - }; - - // Labor API - labor = { - listShifts: (startDate: string, endDate: string, pagination?: PaginationParams) => - this.getPaginated('/labor/v1/shifts', pagination, { startDate, endDate }), - - getShift: (shiftId: string) => - this.get(`/labor/v1/shifts/${shiftId}`), - - listBreaks: (shiftId: string) => - this.get(`/labor/v1/shifts/${shiftId}/breaks`), - - getLaborCost: (businessDate: string) => - this.get('/labor/v1/laborCost', { businessDate }), - - listJobs: () => - this.get('/labor/v1/jobs'), - }; - - // Restaurant API - restaurant = { - getInfo: () => - this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid), - - listRevenueCenters: () => - this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid + '/revenueCenters'), - - listDiningOptions: () => - this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid + '/diningOptions'), - - listServiceAreas: () => - this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid + '/serviceAreas'), - - listTables: (serviceAreaId?: string) => - serviceAreaId - ? this.get(`/restaurants/v1/restaurants/${this.config.restaurantGuid}/serviceAreas/${serviceAreaId}/tables`) - : this.get(`/restaurants/v1/restaurants/${this.config.restaurantGuid}/tables`), - }; - - // Payments API - payments = { - list: (startDate: string, endDate: string, pagination?: PaginationParams) => - this.getPaginated('/payments/v1/payments', pagination, { startDate, endDate }), - - get: (paymentId: string) => - this.get(`/payments/v1/payments/${paymentId}`), - - void: (paymentId: string, voidReason?: string) => - this.post(`/payments/v1/payments/${paymentId}/void`, { voidReason }), - - refund: (paymentId: string, refundAmount: number, refundReason?: string) => - this.post(`/payments/v1/payments/${paymentId}/refund`, { - refundAmount, - refundReason, - }), - - listTips: (startDate: string, endDate: string) => - this.get('/payments/v1/tips', { startDate, endDate }), - }; - - // Inventory API (Note: Toast may not have full inventory API, these are examples) - inventory = { - listItems: (pagination?: PaginationParams) => - this.getPaginated('/inventory/v1/items', pagination), - - getItem: (itemId: string) => - this.get(`/inventory/v1/items/${itemId}`), - - updateCount: (itemId: string, quantity: number) => - this.patch(`/inventory/v1/items/${itemId}`, { currentQuantity: quantity }), - - listVendors: () => - this.get('/inventory/v1/vendors'), - - createPurchaseOrder: (poData: any) => - this.post('/inventory/v1/purchaseOrders', poData), - }; - - // Customers API (Note: Toast may not have full customer API, these are examples) - customers = { - list: (pagination?: PaginationParams) => - this.getPaginated('/customers/v1/customers', pagination), - - get: (customerId: string) => - this.get(`/customers/v1/customers/${customerId}`), - - create: (customerData: any) => - this.post('/customers/v1/customers', customerData), - - update: (customerId: string, customerData: any) => - this.put(`/customers/v1/customers/${customerId}`, customerData), - - listLoyalty: (customerId: string) => - this.get(`/customers/v1/customers/${customerId}/loyalty`), - - addLoyaltyPoints: (customerId: string, points: number) => - this.post(`/customers/v1/customers/${customerId}/loyalty/points`, { points }), - }; - - // Cash Management API - cash = { - listEntries: (startDate: string, endDate: string, pagination?: PaginationParams) => - this.getPaginated('/cash/v1/entries', pagination, { startDate, endDate }), - - getDrawerStatus: (drawerId: string) => - this.get(`/cash/v1/drawers/${drawerId}`), - }; -} diff --git a/servers/toast/src/apps/index.ts b/servers/toast/src/apps/index.ts deleted file mode 100644 index dbc372b..0000000 --- a/servers/toast/src/apps/index.ts +++ /dev/null @@ -1,256 +0,0 @@ -// MCP Apps for Toast Server - -export const apps = [ - { - name: 'order-dashboard', - description: 'Real-time order dashboard showing active orders, status, and timeline', - version: '1.0.0', - ui: { - type: 'dashboard', - layout: 'grid', - sections: [ - { id: 'active-orders', title: 'Active Orders', type: 'list', dataSource: 'toast_list_orders' }, - { id: 'order-stats', title: 'Order Statistics', type: 'metrics' }, - { id: 'recent-activity', title: 'Recent Activity', type: 'timeline' }, - ], - }, - }, - { - name: 'order-detail', - description: 'Detailed order view with items, payments, and modification history', - version: '1.0.0', - ui: { - type: 'detail', - sections: [ - { id: 'order-info', title: 'Order Information', type: 'info-panel' }, - { id: 'order-items', title: 'Order Items', type: 'table', dataSource: 'toast_list_order_checks' }, - { id: 'order-payments', title: 'Payments', type: 'table' }, - { id: 'order-actions', title: 'Actions', type: 'action-panel' }, - ], - }, - }, - { - name: 'order-grid', - description: 'Searchable grid view of all orders with filters and bulk actions', - version: '1.0.0', - ui: { - type: 'grid', - features: ['search', 'filter', 'sort', 'export', 'bulk-actions'], - columns: ['orderNumber', 'date', 'customer', 'total', 'status', 'server'], - filters: ['dateRange', 'status', 'diningOption', 'server'], - actions: ['view', 'edit', 'void', 'print'], - }, - }, - { - name: 'menu-manager', - description: 'Menu management interface for viewing and editing menus, groups, and items', - version: '1.0.0', - ui: { - type: 'tree-view', - sections: [ - { id: 'menu-tree', title: 'Menu Structure', type: 'hierarchical-tree' }, - { id: 'item-editor', title: 'Item Editor', type: 'form' }, - { id: 'price-manager', title: 'Price Management', type: 'batch-editor' }, - ], - }, - }, - { - name: 'menu-item-detail', - description: 'Detailed menu item view with pricing, modifiers, sales data, and images', - version: '1.0.0', - ui: { - type: 'detail', - sections: [ - { id: 'item-info', title: 'Item Information', type: 'info-panel' }, - { id: 'item-pricing', title: 'Pricing & Cost', type: 'pricing-panel' }, - { id: 'item-modifiers', title: 'Modifiers', type: 'table', dataSource: 'toast_list_item_modifiers' }, - { id: 'item-performance', title: 'Sales Performance', type: 'chart' }, - ], - }, - }, - { - name: 'employee-dashboard', - description: 'Employee management dashboard with roster, schedules, and performance', - version: '1.0.0', - ui: { - type: 'dashboard', - layout: 'grid', - sections: [ - { id: 'employee-list', title: 'Employees', type: 'list', dataSource: 'toast_list_employees' }, - { id: 'employee-stats', title: 'Statistics', type: 'metrics' }, - { id: 'clock-status', title: 'Clock Status', type: 'status-board' }, - { id: 'employee-actions', title: 'Quick Actions', type: 'action-panel' }, - ], - }, - }, - { - name: 'employee-schedule', - description: 'Weekly/monthly schedule view with shift planning and time-off management', - version: '1.0.0', - ui: { - type: 'calendar', - views: ['week', 'month'], - features: ['drag-drop', 'shift-swap', 'time-off-requests'], - dataSource: 'toast_list_shifts', - }, - }, - { - name: 'labor-dashboard', - description: 'Labor cost and productivity dashboard with real-time metrics', - version: '1.0.0', - ui: { - type: 'dashboard', - layout: 'grid', - sections: [ - { id: 'labor-cost', title: 'Labor Cost', type: 'metrics', dataSource: 'toast_get_labor_cost' }, - { id: 'hours-breakdown', title: 'Hours Breakdown', type: 'chart' }, - { id: 'overtime-tracker', title: 'Overtime', type: 'alert-panel' }, - { id: 'productivity', title: 'Productivity Metrics', type: 'scorecard' }, - ], - }, - }, - { - name: 'restaurant-overview', - description: 'Restaurant configuration overview with settings and operational status', - version: '1.0.0', - ui: { - type: 'overview', - sections: [ - { id: 'restaurant-info', title: 'Restaurant Info', type: 'info-panel', dataSource: 'toast_get_restaurant_info' }, - { id: 'revenue-centers', title: 'Revenue Centers', type: 'list', dataSource: 'toast_list_revenue_centers' }, - { id: 'dining-options', title: 'Dining Options', type: 'list', dataSource: 'toast_list_dining_options' }, - { id: 'service-areas', title: 'Service Areas', type: 'list', dataSource: 'toast_list_service_areas' }, - ], - }, - }, - { - name: 'table-map', - description: 'Interactive floor plan showing table status, occupancy, and server assignments', - version: '1.0.0', - ui: { - type: 'floor-plan', - features: ['interactive', 'real-time-status', 'drag-drop-assignment'], - dataSource: 'toast_list_tables', - statusColors: { - available: 'green', - occupied: 'red', - reserved: 'yellow', - cleaning: 'blue', - }, - }, - }, - { - name: 'payment-history', - description: 'Payment transaction history with search, filters, and export', - version: '1.0.0', - ui: { - type: 'grid', - features: ['search', 'filter', 'sort', 'export'], - columns: ['date', 'orderId', 'paymentType', 'amount', 'tip', 'status'], - filters: ['dateRange', 'paymentType', 'status', 'server'], - dataSource: 'toast_list_payments', - }, - }, - { - name: 'inventory-tracker', - description: 'Inventory tracking with stock levels, alerts, and purchase order management', - version: '1.0.0', - ui: { - type: 'dashboard', - layout: 'grid', - sections: [ - { id: 'inventory-list', title: 'Inventory Items', type: 'table', dataSource: 'toast_list_inventory_items' }, - { id: 'low-stock-alerts', title: 'Low Stock Alerts', type: 'alert-panel' }, - { id: 'purchase-orders', title: 'Purchase Orders', type: 'list' }, - { id: 'inventory-actions', title: 'Actions', type: 'action-panel' }, - ], - }, - }, - { - name: 'customer-detail', - description: 'Customer profile with order history, preferences, and contact information', - version: '1.0.0', - ui: { - type: 'detail', - sections: [ - { id: 'customer-info', title: 'Customer Information', type: 'info-panel' }, - { id: 'order-history', title: 'Order History', type: 'table' }, - { id: 'customer-stats', title: 'Customer Statistics', type: 'metrics' }, - { id: 'customer-actions', title: 'Actions', type: 'action-panel' }, - ], - }, - }, - { - name: 'customer-loyalty', - description: 'Loyalty program dashboard with points, rewards, and tier status', - version: '1.0.0', - ui: { - type: 'dashboard', - layout: 'grid', - sections: [ - { id: 'loyalty-overview', title: 'Loyalty Overview', type: 'metrics' }, - { id: 'points-history', title: 'Points History', type: 'timeline' }, - { id: 'rewards-available', title: 'Available Rewards', type: 'card-grid' }, - { id: 'tier-progress', title: 'Tier Progress', type: 'progress-bar' }, - ], - }, - }, - { - name: 'sales-dashboard', - description: 'Comprehensive sales analytics with charts, trends, and comparisons', - version: '1.0.0', - ui: { - type: 'dashboard', - layout: 'grid', - sections: [ - { id: 'sales-overview', title: 'Sales Overview', type: 'metrics', dataSource: 'toast_sales_summary' }, - { id: 'sales-chart', title: 'Sales Trend', type: 'line-chart' }, - { id: 'category-breakdown', title: 'Sales by Category', type: 'pie-chart' }, - { id: 'payment-types', title: 'Payment Methods', type: 'bar-chart' }, - ], - }, - }, - { - name: 'menu-performance', - description: 'Menu item performance analytics with best/worst sellers and profitability', - version: '1.0.0', - ui: { - type: 'analytics', - sections: [ - { id: 'top-items', title: 'Top Selling Items', type: 'ranked-list', dataSource: 'toast_menu_item_performance' }, - { id: 'item-trends', title: 'Item Sales Trends', type: 'multi-line-chart' }, - { id: 'profitability', title: 'Profitability Analysis', type: 'table' }, - { id: 'recommendations', title: 'Recommendations', type: 'insight-panel' }, - ], - }, - }, - { - name: 'tip-summary', - description: 'Tip tracking and distribution dashboard with employee breakdown', - version: '1.0.0', - ui: { - type: 'dashboard', - layout: 'grid', - sections: [ - { id: 'tip-overview', title: 'Tip Overview', type: 'metrics', dataSource: 'toast_tip_summary' }, - { id: 'tip-by-employee', title: 'Tips by Employee', type: 'table' }, - { id: 'tip-trends', title: 'Tip Trends', type: 'line-chart' }, - { id: 'tip-percentage', title: 'Average Tip %', type: 'gauge' }, - ], - }, - }, - { - name: 'revenue-by-hour', - description: 'Hourly revenue breakdown showing peak times and patterns', - version: '1.0.0', - ui: { - type: 'analytics', - sections: [ - { id: 'hourly-chart', title: 'Revenue by Hour', type: 'bar-chart', dataSource: 'toast_revenue_by_hour' }, - { id: 'peak-times', title: 'Peak Times', type: 'highlight-panel' }, - { id: 'day-comparison', title: 'Day-over-Day Comparison', type: 'comparison-chart' }, - { id: 'hourly-metrics', title: 'Hourly Metrics', type: 'table' }, - ], - }, - }, -]; diff --git a/servers/toast/src/main.ts b/servers/toast/src/main.ts deleted file mode 100644 index a32d614..0000000 --- a/servers/toast/src/main.ts +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env node - -import { ToastMCPServer } from './server.js'; - -async function main() { - try { - const server = new ToastMCPServer(); - await server.start(); - } catch (error) { - console.error('Failed to start Toast MCP Server:', error); - process.exit(1); - } -} - -main(); diff --git a/servers/toast/src/server.ts b/servers/toast/src/server.ts deleted file mode 100644 index f992f00..0000000 --- a/servers/toast/src/server.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { Server } from '@modelcontextprotocol/sdk/server/index.js'; -import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; -import { - CallToolRequestSchema, - ListToolsRequestSchema, - ListResourcesRequestSchema, - ReadResourceRequestSchema, -} from '@modelcontextprotocol/sdk/types.js'; -import { ToastAPIClient } from './api-client.js'; -import { registerOrdersTools } from './tools/orders-tools.js'; -import { registerMenusTools } from './tools/menus-tools.js'; -import { registerEmployeesTools } from './tools/employees-tools.js'; -import { registerLaborTools } from './tools/labor-tools.js'; -import { registerRestaurantTools } from './tools/restaurant-tools.js'; -import { registerPaymentsTools } from './tools/payments-tools.js'; -import { registerInventoryTools } from './tools/inventory-tools.js'; -import { registerCustomersTools } from './tools/customers-tools.js'; -import { registerReportingTools } from './tools/reporting-tools.js'; -import { registerCashTools } from './tools/cash-tools.js'; -import { apps } from './apps/index.js'; - -export class ToastMCPServer { - private server: Server; - private client: ToastAPIClient; - private tools: any[]; - - constructor() { - // Get configuration from environment - const apiToken = process.env.TOAST_API_TOKEN; - const restaurantGuid = process.env.TOAST_RESTAURANT_GUID; - const baseUrl = process.env.TOAST_BASE_URL; - - if (!apiToken || !restaurantGuid) { - throw new Error('TOAST_API_TOKEN and TOAST_RESTAURANT_GUID environment variables are required'); - } - - // Initialize Toast API client - this.client = new ToastAPIClient({ - apiToken, - restaurantGuid, - baseUrl, - }); - - // Initialize MCP server - this.server = new Server( - { - name: 'toast-mcp-server', - version: '1.0.0', - }, - { - capabilities: { - tools: {}, - resources: {}, - }, - } - ); - - // Register all tools - this.tools = [ - ...registerOrdersTools(this.client), - ...registerMenusTools(this.client), - ...registerEmployeesTools(this.client), - ...registerLaborTools(this.client), - ...registerRestaurantTools(this.client), - ...registerPaymentsTools(this.client), - ...registerInventoryTools(this.client), - ...registerCustomersTools(this.client), - ...registerReportingTools(this.client), - ...registerCashTools(this.client), - ]; - - this.setupHandlers(); - } - - private setupHandlers() { - // List available tools - this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ - tools: this.tools.map((tool) => ({ - name: tool.name, - description: tool.description, - inputSchema: tool.inputSchema, - })), - })); - - // Execute tool calls - this.server.setRequestHandler(CallToolRequestSchema, async (request) => { - const tool = this.tools.find((t) => t.name === request.params.name); - - if (!tool) { - throw new Error(`Tool not found: ${request.params.name}`); - } - - try { - return await tool.execute(request.params.arguments); - } catch (error: any) { - return { - content: [ - { - type: 'text', - text: `Error executing ${request.params.name}: ${error.message}`, - }, - ], - isError: true, - }; - } - }); - - // List resources (MCP apps) - this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({ - resources: apps.map((app) => ({ - uri: `toast://apps/${app.name}`, - name: app.name, - description: app.description, - mimeType: 'application/json', - })), - })); - - // Read resource (get app definition) - this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { - const appName = request.params.uri.replace('toast://apps/', ''); - const app = apps.find((a) => a.name === appName); - - if (!app) { - throw new Error(`App not found: ${appName}`); - } - - return { - contents: [ - { - uri: request.params.uri, - mimeType: 'application/json', - text: JSON.stringify(app, null, 2), - }, - ], - }; - }); - - // Error handling - this.server.onerror = (error) => { - console.error('[MCP Error]', error); - }; - - process.on('SIGINT', async () => { - await this.server.close(); - process.exit(0); - }); - } - - async start() { - const transport = new StdioServerTransport(); - await this.server.connect(transport); - console.error('Toast MCP Server running on stdio'); - } -} diff --git a/servers/toast/src/tools/cash-tools.ts b/servers/toast/src/tools/cash-tools.ts deleted file mode 100644 index 4d71e91..0000000 --- a/servers/toast/src/tools/cash-tools.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerCashTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_cash_entries', - description: 'List cash entries (paid in/paid out) for a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - page: z.number().optional().describe('Page number (default: 1)'), - pageSize: z.number().optional().describe('Items per page (default: 100)'), - }), - execute: async (args: any) => { - const result = await client.cash.listEntries(args.startDate, args.endDate, { - page: args.page, - pageSize: args.pageSize, - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_drawer_status', - description: 'Get current status of a cash drawer', - inputSchema: z.object({ - drawerGuid: z.string().describe('Cash drawer GUID'), - }), - execute: async (args: any) => { - const result = await client.cash.getDrawerStatus(args.drawerGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/customers-tools.ts b/servers/toast/src/tools/customers-tools.ts deleted file mode 100644 index 68622e9..0000000 --- a/servers/toast/src/tools/customers-tools.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerCustomersTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_customers', - description: 'List all customers', - inputSchema: z.object({ - page: z.number().optional().describe('Page number (default: 1)'), - pageSize: z.number().optional().describe('Items per page (default: 100)'), - }), - execute: async (args: any) => { - const result = await client.customers.list({ - page: args.page, - pageSize: args.pageSize, - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_customer', - description: 'Get details of a specific customer', - inputSchema: z.object({ - customerGuid: z.string().describe('Customer GUID'), - }), - execute: async (args: any) => { - const result = await client.customers.get(args.customerGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_create_customer', - description: 'Create a new customer', - inputSchema: z.object({ - firstName: z.string().describe('First name'), - lastName: z.string().describe('Last name'), - email: z.string().optional().describe('Email address'), - phone: z.string().optional().describe('Phone number'), - company: z.string().optional().describe('Company name'), - }), - execute: async (args: any) => { - const customerData = { - firstName: args.firstName, - lastName: args.lastName, - ...(args.email && { email: args.email }), - ...(args.phone && { phone: args.phone }), - ...(args.company && { company: args.company }), - }; - const result = await client.customers.create(customerData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_update_customer', - description: 'Update an existing customer', - inputSchema: z.object({ - customerGuid: z.string().describe('Customer GUID'), - firstName: z.string().optional().describe('First name'), - lastName: z.string().optional().describe('Last name'), - email: z.string().optional().describe('Email address'), - phone: z.string().optional().describe('Phone number'), - company: z.string().optional().describe('Company name'), - }), - execute: async (args: any) => { - const updateData: any = {}; - if (args.firstName) updateData.firstName = args.firstName; - if (args.lastName) updateData.lastName = args.lastName; - if (args.email) updateData.email = args.email; - if (args.phone) updateData.phone = args.phone; - if (args.company) updateData.company = args.company; - - const result = await client.customers.update(args.customerGuid, updateData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_customer_loyalty', - description: 'List loyalty information for a customer', - inputSchema: z.object({ - customerGuid: z.string().describe('Customer GUID'), - }), - execute: async (args: any) => { - const result = await client.customers.listLoyalty(args.customerGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_add_loyalty_points', - description: 'Add loyalty points to a customer account', - inputSchema: z.object({ - customerGuid: z.string().describe('Customer GUID'), - points: z.number().describe('Points to add'), - }), - execute: async (args: any) => { - const result = await client.customers.addLoyaltyPoints(args.customerGuid, args.points); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/employees-tools.ts b/servers/toast/src/tools/employees-tools.ts deleted file mode 100644 index 1bfba9f..0000000 --- a/servers/toast/src/tools/employees-tools.ts +++ /dev/null @@ -1,234 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerEmployeesTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_employees', - description: 'List all employees', - inputSchema: z.object({ - page: z.number().optional().describe('Page number (default: 1)'), - pageSize: z.number().optional().describe('Items per page (default: 100)'), - }), - execute: async (args: any) => { - const result = await client.employees.list({ - page: args.page, - pageSize: args.pageSize, - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_employee', - description: 'Get details of a specific employee', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - }), - execute: async (args: any) => { - const result = await client.employees.get(args.employeeGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_create_employee', - description: 'Create a new employee', - inputSchema: z.object({ - firstName: z.string().describe('First name'), - lastName: z.string().describe('Last name'), - email: z.string().optional().describe('Email address'), - phoneNumber: z.string().optional().describe('Phone number'), - externalEmployeeId: z.string().optional().describe('External employee ID'), - chosenName: z.string().optional().describe('Chosen/preferred name'), - passcode: z.string().optional().describe('Employee passcode'), - }), - execute: async (args: any) => { - const employeeData = { - firstName: args.firstName, - lastName: args.lastName, - ...(args.email && { email: args.email }), - ...(args.phoneNumber && { phoneNumber: args.phoneNumber }), - ...(args.externalEmployeeId && { externalEmployeeId: args.externalEmployeeId }), - ...(args.chosenName && { chosenName: args.chosenName }), - ...(args.passcode && { passcode: args.passcode }), - }; - const result = await client.employees.create(employeeData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_update_employee', - description: 'Update an existing employee', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - firstName: z.string().optional().describe('First name'), - lastName: z.string().optional().describe('Last name'), - email: z.string().optional().describe('Email address'), - phoneNumber: z.string().optional().describe('Phone number'), - chosenName: z.string().optional().describe('Chosen/preferred name'), - disabled: z.boolean().optional().describe('Disabled status'), - }), - execute: async (args: any) => { - const updateData: any = {}; - if (args.firstName) updateData.firstName = args.firstName; - if (args.lastName) updateData.lastName = args.lastName; - if (args.email) updateData.email = args.email; - if (args.phoneNumber) updateData.phoneNumber = args.phoneNumber; - if (args.chosenName) updateData.chosenName = args.chosenName; - if (args.disabled !== undefined) updateData.disabled = args.disabled; - - const result = await client.employees.update(args.employeeGuid, updateData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_delete_employee', - description: 'Delete an employee', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - }), - execute: async (args: any) => { - const result = await client.employees.delete(args.employeeGuid); - return { - content: [ - { - type: 'text', - text: 'Employee deleted successfully', - }, - ], - }; - }, - }, - { - name: 'toast_list_employee_jobs', - description: 'List all jobs for an employee', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - }), - execute: async (args: any) => { - const result = await client.employees.listJobs(args.employeeGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_employee_shifts', - description: 'List shifts for an employee within a date range', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - }), - execute: async (args: any) => { - const result = await client.employees.listShifts( - args.employeeGuid, - args.startDate, - args.endDate - ); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_clock_in', - description: 'Clock in an employee for a job', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - jobGuid: z.string().describe('Job GUID'), - }), - execute: async (args: any) => { - const result = await client.employees.clockIn(args.employeeGuid, args.jobGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_clock_out', - description: 'Clock out an employee from a time entry', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - timeEntryGuid: z.string().describe('Time entry GUID'), - }), - execute: async (args: any) => { - const result = await client.employees.clockOut(args.employeeGuid, args.timeEntryGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_time_entries', - description: 'List time entries for an employee within a date range', - inputSchema: z.object({ - employeeGuid: z.string().describe('Employee GUID'), - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - }), - execute: async (args: any) => { - const result = await client.employees.listTimeEntries( - args.employeeGuid, - args.startDate, - args.endDate - ); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/inventory-tools.ts b/servers/toast/src/tools/inventory-tools.ts deleted file mode 100644 index 546fd0c..0000000 --- a/servers/toast/src/tools/inventory-tools.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerInventoryTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_inventory_items', - description: 'List all inventory items', - inputSchema: z.object({ - page: z.number().optional().describe('Page number (default: 1)'), - pageSize: z.number().optional().describe('Items per page (default: 100)'), - }), - execute: async (args: any) => { - const result = await client.inventory.listItems({ - page: args.page, - pageSize: args.pageSize, - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_inventory_item', - description: 'Get details of a specific inventory item', - inputSchema: z.object({ - itemGuid: z.string().describe('Inventory item GUID'), - }), - execute: async (args: any) => { - const result = await client.inventory.getItem(args.itemGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_update_inventory_count', - description: 'Update the current quantity of an inventory item', - inputSchema: z.object({ - itemGuid: z.string().describe('Inventory item GUID'), - quantity: z.number().describe('New quantity'), - }), - execute: async (args: any) => { - const result = await client.inventory.updateCount(args.itemGuid, args.quantity); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_vendors', - description: 'List all vendors', - inputSchema: z.object({}), - execute: async (args: any) => { - const result = await client.inventory.listVendors(); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_create_purchase_order', - description: 'Create a new purchase order', - inputSchema: z.object({ - vendorGuid: z.string().describe('Vendor GUID'), - expectedDeliveryDate: z.string().optional().describe('Expected delivery date (ISO 8601)'), - items: z.array(z.object({ - itemGuid: z.string(), - quantity: z.number(), - unitCost: z.number(), - })).describe('Purchase order items'), - }), - execute: async (args: any) => { - const poData = { - vendor: { guid: args.vendorGuid }, - ...(args.expectedDeliveryDate && { expectedDeliveryDate: args.expectedDeliveryDate }), - items: args.items.map((item: any) => ({ - inventoryItem: { guid: item.itemGuid }, - quantity: item.quantity, - unitCost: item.unitCost, - totalCost: item.quantity * item.unitCost, - })), - }; - const result = await client.inventory.createPurchaseOrder(poData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/labor-tools.ts b/servers/toast/src/tools/labor-tools.ts deleted file mode 100644 index 2e0ded4..0000000 --- a/servers/toast/src/tools/labor-tools.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerLaborTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_shifts', - description: 'List all shifts within a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - page: z.number().optional().describe('Page number (default: 1)'), - pageSize: z.number().optional().describe('Items per page (default: 100)'), - }), - execute: async (args: any) => { - const result = await client.labor.listShifts(args.startDate, args.endDate, { - page: args.page, - pageSize: args.pageSize, - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_shift', - description: 'Get details of a specific shift', - inputSchema: z.object({ - shiftGuid: z.string().describe('Shift GUID'), - }), - execute: async (args: any) => { - const result = await client.labor.getShift(args.shiftGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_shift_breaks', - description: 'List all breaks for a specific shift', - inputSchema: z.object({ - shiftGuid: z.string().describe('Shift GUID'), - }), - execute: async (args: any) => { - const result = await client.labor.listBreaks(args.shiftGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_labor_cost', - description: 'Get labor cost summary for a business date', - inputSchema: z.object({ - businessDate: z.string().describe('Business date (YYYYMMDD format)'), - }), - execute: async (args: any) => { - const result = await client.labor.getLaborCost(args.businessDate); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_jobs', - description: 'List all available jobs/positions', - inputSchema: z.object({}), - execute: async (args: any) => { - const result = await client.labor.listJobs(); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/menus-tools.ts b/servers/toast/src/tools/menus-tools.ts deleted file mode 100644 index c528f5d..0000000 --- a/servers/toast/src/tools/menus-tools.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerMenusTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_menus', - description: 'List all menus for the restaurant', - inputSchema: z.object({}), - execute: async (args: any) => { - const result = await client.menus.list(); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_menu', - description: 'Get details of a specific menu', - inputSchema: z.object({ - menuGuid: z.string().describe('Menu GUID'), - }), - execute: async (args: any) => { - const result = await client.menus.get(args.menuGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_menu_groups', - description: 'List all groups in a menu', - inputSchema: z.object({ - menuGuid: z.string().describe('Menu GUID'), - }), - execute: async (args: any) => { - const result = await client.menus.listGroups(args.menuGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_menu_group', - description: 'Get details of a specific menu group', - inputSchema: z.object({ - menuGuid: z.string().describe('Menu GUID'), - groupGuid: z.string().describe('Menu group GUID'), - }), - execute: async (args: any) => { - const result = await client.menus.getGroup(args.menuGuid, args.groupGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_menu_items', - description: 'List all items in a menu or menu group', - inputSchema: z.object({ - menuGuid: z.string().describe('Menu GUID'), - groupGuid: z.string().optional().describe('Menu group GUID (optional)'), - }), - execute: async (args: any) => { - const result = await client.menus.listItems(args.menuGuid, args.groupGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_menu_item', - description: 'Get details of a specific menu item', - inputSchema: z.object({ - menuGuid: z.string().describe('Menu GUID'), - itemGuid: z.string().describe('Menu item GUID'), - }), - execute: async (args: any) => { - const result = await client.menus.getItem(args.menuGuid, args.itemGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_item_modifiers', - description: 'List all modifier groups for a menu item', - inputSchema: z.object({ - menuGuid: z.string().describe('Menu GUID'), - itemGuid: z.string().describe('Menu item GUID'), - }), - execute: async (args: any) => { - const result = await client.menus.listModifiers(args.menuGuid, args.itemGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_update_item_price', - description: 'Update the price of a menu item', - inputSchema: z.object({ - menuGuid: z.string().describe('Menu GUID'), - itemGuid: z.string().describe('Menu item GUID'), - price: z.number().describe('New price in cents (e.g., 1299 for $12.99)'), - }), - execute: async (args: any) => { - const result = await client.menus.updatePrice(args.menuGuid, args.itemGuid, args.price); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/orders-tools.ts b/servers/toast/src/tools/orders-tools.ts deleted file mode 100644 index 14a467d..0000000 --- a/servers/toast/src/tools/orders-tools.ts +++ /dev/null @@ -1,224 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerOrdersTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_orders', - description: 'List orders with optional date range filter', - inputSchema: z.object({ - startDate: z.string().optional().describe('Start date (ISO 8601 format)'), - endDate: z.string().optional().describe('End date (ISO 8601 format)'), - page: z.number().optional().describe('Page number (default: 1)'), - pageSize: z.number().optional().describe('Items per page (default: 100)'), - }), - execute: async (args: any) => { - const result = await client.orders.list({ - startDate: args.startDate, - endDate: args.endDate, - pagination: { - page: args.page, - pageSize: args.pageSize, - }, - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_order', - description: 'Get details of a specific order by ID', - inputSchema: z.object({ - orderId: z.string().describe('Order GUID'), - }), - execute: async (args: any) => { - const result = await client.orders.get(args.orderId); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_create_order', - description: 'Create a new order', - inputSchema: z.object({ - diningOptionGuid: z.string().describe('Dining option GUID'), - revenueCenterGuid: z.string().optional().describe('Revenue center GUID'), - tableGuid: z.string().optional().describe('Table GUID'), - numberOfGuests: z.number().optional().describe('Number of guests'), - estimatedFulfillmentDate: z.string().optional().describe('Estimated fulfillment date (ISO 8601)'), - }), - execute: async (args: any) => { - const orderData = { - diningOption: { guid: args.diningOptionGuid }, - ...(args.revenueCenterGuid && { revenueCenterGuid: args.revenueCenterGuid }), - ...(args.tableGuid && { table: { guid: args.tableGuid } }), - ...(args.numberOfGuests && { numberOfGuests: args.numberOfGuests }), - ...(args.estimatedFulfillmentDate && { estimatedFulfillmentDate: args.estimatedFulfillmentDate }), - }; - const result = await client.orders.create(orderData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_update_order', - description: 'Update an existing order', - inputSchema: z.object({ - orderId: z.string().describe('Order GUID'), - numberOfGuests: z.number().optional().describe('Number of guests'), - tableGuid: z.string().optional().describe('Table GUID'), - estimatedFulfillmentDate: z.string().optional().describe('Estimated fulfillment date (ISO 8601)'), - }), - execute: async (args: any) => { - const updateData: any = {}; - if (args.numberOfGuests !== undefined) updateData.numberOfGuests = args.numberOfGuests; - if (args.tableGuid) updateData.table = { guid: args.tableGuid }; - if (args.estimatedFulfillmentDate) updateData.estimatedFulfillmentDate = args.estimatedFulfillmentDate; - - const result = await client.orders.update(args.orderId, updateData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_add_order_item', - description: 'Add an item to an order check', - inputSchema: z.object({ - orderId: z.string().describe('Order GUID'), - checkGuid: z.string().describe('Check GUID'), - itemGuid: z.string().describe('Menu item GUID'), - quantity: z.number().describe('Quantity'), - modifiers: z.array(z.object({ - guid: z.string(), - quantity: z.number().optional(), - })).optional().describe('Item modifiers'), - specialRequest: z.string().optional().describe('Special instructions'), - }), - execute: async (args: any) => { - const itemData = { - item: { guid: args.itemGuid }, - quantity: args.quantity, - ...(args.modifiers && { modifiers: args.modifiers }), - ...(args.specialRequest && { specialRequest: args.specialRequest }), - }; - const result = await client.orders.addItem(args.orderId, args.checkGuid, itemData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_remove_order_item', - description: 'Remove an item from an order check', - inputSchema: z.object({ - orderId: z.string().describe('Order GUID'), - checkGuid: z.string().describe('Check GUID'), - selectionGuid: z.string().describe('Selection GUID to remove'), - }), - execute: async (args: any) => { - const result = await client.orders.removeItem(args.orderId, args.checkGuid, args.selectionGuid); - return { - content: [ - { - type: 'text', - text: 'Item removed successfully', - }, - ], - }; - }, - }, - { - name: 'toast_apply_discount', - description: 'Apply a discount to an order check', - inputSchema: z.object({ - orderId: z.string().describe('Order GUID'), - checkGuid: z.string().describe('Check GUID'), - discountGuid: z.string().optional().describe('Discount configuration GUID'), - discountAmount: z.number().optional().describe('Discount amount (for fixed amount)'), - discountPercent: z.number().optional().describe('Discount percentage (0-100)'), - }), - execute: async (args: any) => { - const discountData: any = {}; - if (args.discountGuid) discountData.guid = args.discountGuid; - if (args.discountAmount !== undefined) discountData.amount = args.discountAmount; - if (args.discountPercent !== undefined) discountData.discountPercent = args.discountPercent; - - const result = await client.orders.applyDiscount(args.orderId, args.checkGuid, discountData); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_void_order', - description: 'Void an entire order', - inputSchema: z.object({ - orderId: z.string().describe('Order GUID'), - voidReason: z.string().optional().describe('Reason for voiding'), - }), - execute: async (args: any) => { - const result = await client.orders.void(args.orderId, args.voidReason); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_order_checks', - description: 'List all checks for an order', - inputSchema: z.object({ - orderId: z.string().describe('Order GUID'), - }), - execute: async (args: any) => { - const result = await client.orders.listChecks(args.orderId); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/payments-tools.ts b/servers/toast/src/tools/payments-tools.ts deleted file mode 100644 index d921aca..0000000 --- a/servers/toast/src/tools/payments-tools.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerPaymentsTools(client: ToastAPIClient) { - return [ - { - name: 'toast_list_payments', - description: 'List all payments within a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - page: z.number().optional().describe('Page number (default: 1)'), - pageSize: z.number().optional().describe('Items per page (default: 100)'), - }), - execute: async (args: any) => { - const result = await client.payments.list(args.startDate, args.endDate, { - page: args.page, - pageSize: args.pageSize, - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_get_payment', - description: 'Get details of a specific payment', - inputSchema: z.object({ - paymentGuid: z.string().describe('Payment GUID'), - }), - execute: async (args: any) => { - const result = await client.payments.get(args.paymentGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_void_payment', - description: 'Void a payment', - inputSchema: z.object({ - paymentGuid: z.string().describe('Payment GUID'), - voidReason: z.string().optional().describe('Reason for voiding'), - }), - execute: async (args: any) => { - const result = await client.payments.void(args.paymentGuid, args.voidReason); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_refund_payment', - description: 'Refund a payment', - inputSchema: z.object({ - paymentGuid: z.string().describe('Payment GUID'), - refundAmount: z.number().describe('Amount to refund in cents'), - refundReason: z.string().optional().describe('Reason for refund'), - }), - execute: async (args: any) => { - const result = await client.payments.refund( - args.paymentGuid, - args.refundAmount, - args.refundReason - ); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_tips', - description: 'List all tips within a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - }), - execute: async (args: any) => { - const result = await client.payments.listTips(args.startDate, args.endDate); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/reporting-tools.ts b/servers/toast/src/tools/reporting-tools.ts deleted file mode 100644 index 09b28d0..0000000 --- a/servers/toast/src/tools/reporting-tools.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerReportingTools(client: ToastAPIClient) { - return [ - { - name: 'toast_sales_summary', - description: 'Get sales summary report for a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - }), - execute: async (args: any) => { - // This would aggregate data from orders and payments - const orders = await client.orders.list({ - startDate: args.startDate, - endDate: args.endDate, - }); - - const payments = await client.payments.list(args.startDate, args.endDate); - - // Calculate summary metrics - const summary = { - dateRange: { startDate: args.startDate, endDate: args.endDate }, - orders: orders.data, - payments: payments.data, - summary: { - totalOrders: orders.totalCount, - totalPayments: payments.totalCount, - message: 'Sales summary data retrieved. Process orders and payments to calculate metrics.', - }, - }; - - return { - content: [ - { - type: 'text', - text: JSON.stringify(summary, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_labor_cost_report', - description: 'Get labor cost report for a business date', - inputSchema: z.object({ - businessDate: z.string().describe('Business date (YYYYMMDD format)'), - }), - execute: async (args: any) => { - const result = await client.labor.getLaborCost(args.businessDate); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_menu_item_performance', - description: 'Get menu item sales performance for a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - }), - execute: async (args: any) => { - // Fetch orders and aggregate item sales - const orders = await client.orders.list({ - startDate: args.startDate, - endDate: args.endDate, - }); - - const report = { - dateRange: { startDate: args.startDate, endDate: args.endDate }, - orders: orders.data, - message: 'Menu item performance data retrieved. Process order selections to calculate metrics.', - }; - - return { - content: [ - { - type: 'text', - text: JSON.stringify(report, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_revenue_by_hour', - description: 'Get revenue breakdown by hour for a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - }), - execute: async (args: any) => { - const orders = await client.orders.list({ - startDate: args.startDate, - endDate: args.endDate, - }); - - const report = { - dateRange: { startDate: args.startDate, endDate: args.endDate }, - orders: orders.data, - message: 'Hourly revenue data retrieved. Process order timestamps to calculate hourly breakdown.', - }; - - return { - content: [ - { - type: 'text', - text: JSON.stringify(report, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_tip_summary', - description: 'Get tip summary report for a date range', - inputSchema: z.object({ - startDate: z.string().describe('Start date (ISO 8601 format)'), - endDate: z.string().describe('End date (ISO 8601 format)'), - }), - execute: async (args: any) => { - const tips = await client.payments.listTips(args.startDate, args.endDate); - - return { - content: [ - { - type: 'text', - text: JSON.stringify(tips, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/tools/restaurant-tools.ts b/servers/toast/src/tools/restaurant-tools.ts deleted file mode 100644 index bfbddf8..0000000 --- a/servers/toast/src/tools/restaurant-tools.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { z } from 'zod'; -import type { ToastAPIClient } from '../api-client.js'; - -export function registerRestaurantTools(client: ToastAPIClient) { - return [ - { - name: 'toast_get_restaurant_info', - description: 'Get restaurant information and configuration', - inputSchema: z.object({}), - execute: async (args: any) => { - const result = await client.restaurant.getInfo(); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_revenue_centers', - description: 'List all revenue centers for the restaurant', - inputSchema: z.object({}), - execute: async (args: any) => { - const result = await client.restaurant.listRevenueCenters(); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_dining_options', - description: 'List all dining options (dine-in, takeout, delivery, etc.)', - inputSchema: z.object({}), - execute: async (args: any) => { - const result = await client.restaurant.listDiningOptions(); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_service_areas', - description: 'List all service areas (sections) in the restaurant', - inputSchema: z.object({}), - execute: async (args: any) => { - const result = await client.restaurant.listServiceAreas(); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - { - name: 'toast_list_tables', - description: 'List all tables, optionally filtered by service area', - inputSchema: z.object({ - serviceAreaGuid: z.string().optional().describe('Service area GUID (optional)'), - }), - execute: async (args: any) => { - const result = await client.restaurant.listTables(args.serviceAreaGuid); - return { - content: [ - { - type: 'text', - text: JSON.stringify(result, null, 2), - }, - ], - }; - }, - }, - ]; -} diff --git a/servers/toast/src/types/index.ts b/servers/toast/src/types/index.ts deleted file mode 100644 index 9be232f..0000000 --- a/servers/toast/src/types/index.ts +++ /dev/null @@ -1,594 +0,0 @@ -// Toast API Types - -export interface ToastConfig { - apiToken: string; - restaurantGuid: string; - baseUrl?: string; -} - -export interface PaginationParams { - page?: number; - pageSize?: number; -} - -export interface PaginatedResponse { - data: T[]; - page: number; - pageSize: number; - totalPages: number; - totalCount: number; -} - -// Order Types -export interface Order { - guid: string; - entityType: string; - externalId?: string; - openedDate: string; - modifiedDate: string; - promisedDate?: string; - closedDate?: string; - deletedDate?: string; - deleted: boolean; - businessDate: number; - server?: Employee; - pricingFeatures: string[]; - source: string; - duration: number; - diningOption: DiningOption; - checks: Check[]; - table?: Table; - serviceArea?: ServiceArea; - restaurantService: string; - revenueCenterGuid: string; - voided: boolean; - voidDate?: string; - voidBusinessDate?: number; - voidUser?: Employee; - approvalStatus: string; - deliveryInfo?: DeliveryInfo; - numberOfGuests?: number; - estimatedFulfillmentDate?: string; - curbsidePickupInfo?: CurbsidePickupInfo; -} - -export interface Check { - guid: string; - entityType: string; - externalId?: string; - openedDate: string; - modifiedDate: string; - deletedDate?: string; - deleted: boolean; - selections: Selection[]; - customer?: Customer; - appliedDiscounts: Discount[]; - amount: number; - taxAmount: number; - totalAmount: number; - payments: Payment[]; - tabName?: string; - paymentStatus: string; - closedDate?: string; - voided: boolean; - voidDate?: string; - voidUser?: Employee; -} - -export interface Selection { - guid: string; - entityType: string; - externalId?: string; - itemGroup?: MenuGroup; - item: MenuItem; - optionGroups?: OptionGroup[]; - modifiers?: Modifier[]; - quantity: number; - unitOfMeasure: string; - price: number; - tax: number; - voided: boolean; - voidDate?: string; - voidBusinessDate?: number; - voidUser?: Employee; - displayName: string; - preDiscountPrice: number; - appliedDiscounts: Discount[]; - diningOption: DiningOption; - salesCategory: SalesCategory; - fulfillmentStatus: string; - seat?: number; -} - -export interface Discount { - guid: string; - entityType: string; - externalId?: string; - name: string; - amount: number; - discountType: string; - discountPercent?: number; - nonTaxDiscountAmount?: number; - approvalStatus: string; - processingState: string; -} - -// Menu Types -export interface Menu { - guid: string; - entityType: string; - externalId?: string; - name: string; - visibility: string; - groups: MenuGroup[]; -} - -export interface MenuGroup { - guid: string; - entityType: string; - externalId?: string; - name: string; - description?: string; - items: MenuItem[]; - visibility: string; -} - -export interface MenuItem { - guid: string; - entityType: string; - externalId?: string; - name: string; - description?: string; - sku?: string; - plu?: string; - price: number; - calories?: number; - visibility: string; - salesCategory?: SalesCategory; - optionGroups?: OptionGroup[]; - modifierGroups?: ModifierGroup[]; - images?: Image[]; - tags?: string[]; - isDiscountable: boolean; - unitOfMeasure: string; -} - -export interface OptionGroup { - guid: string; - entityType: string; - name: string; - minSelections: number; - maxSelections: number; - options: Option[]; -} - -export interface Option { - guid: string; - entityType: string; - name: string; - price: number; - isDefault: boolean; -} - -export interface ModifierGroup { - guid: string; - entityType: string; - name: string; - minSelections: number; - maxSelections: number; - modifiers: Modifier[]; -} - -export interface Modifier { - guid: string; - entityType: string; - name: string; - price: number; - calories?: number; -} - -export interface SalesCategory { - guid: string; - entityType: string; - name: string; -} - -export interface Image { - guid: string; - entityType: string; - url: string; -} - -// Employee Types -export interface Employee { - guid: string; - entityType: string; - externalId?: string; - firstName: string; - lastName: string; - email?: string; - phoneNumber?: string; - externalEmployeeId?: string; - chosenName?: string; - passcode?: string; - createdDate: string; - modifiedDate: string; - deletedDate?: string; - deleted: boolean; - disabled: boolean; - jobs: Job[]; -} - -export interface Job { - guid: string; - entityType: string; - title: string; - wage: number; - wageType: string; -} - -export interface Shift { - guid: string; - entityType: string; - createdDate: string; - modifiedDate: string; - deletedDate?: string; - deleted: boolean; - businessDate: number; - inDate: string; - outDate?: string; - employee: Employee; - job: Job; - breaks: Break[]; - regularHours: number; - overtimeHours: number; - totalHours: number; - laborCost: number; - tips?: number; - declaredTips?: number; -} - -export interface Break { - guid: string; - entityType: string; - inDate: string; - outDate?: string; - isPaid: boolean; - duration: number; -} - -export interface TimeEntry { - guid: string; - entityType: string; - createdDate: string; - businessDate: number; - inDate: string; - outDate?: string; - employee: Employee; - job: Job; - hourlyWage: number; -} - -// Labor Types -export interface LaborEntry { - guid: string; - entityType: string; - businessDate: number; - employee: Employee; - job: Job; - regularHours: number; - overtimeHours: number; - doubleOvertimeHours: number; - totalHours: number; - regularPay: number; - overtimePay: number; - doubleOvertimePay: number; - totalPay: number; -} - -// Restaurant Types -export interface Restaurant { - guid: string; - entityType: string; - name: string; - description?: string; - timeZone: string; - closeoutHour: number; - managementGroupGuid: string; - externalGroupRef?: string; - locationName?: string; - locationCode?: string; - address1?: string; - address2?: string; - city?: string; - stateCode?: string; - zipCode?: string; - country?: string; - phone?: string; - createdDate: string; - modifiedDate: string; -} - -export interface RevenueCenter { - guid: string; - entityType: string; - name: string; -} - -export interface DiningOption { - guid: string; - entityType: string; - name: string; - behavior: string; - curbside: boolean; -} - -export interface ServiceArea { - guid: string; - entityType: string; - name: string; - tables: Table[]; -} - -export interface Table { - guid: string; - entityType: string; - name: string; - seatingCapacity: number; - serviceArea?: ServiceArea; -} - -// Payment Types -export interface Payment { - guid: string; - entityType: string; - externalId?: string; - paymentDate: string; - businessDate: number; - amount: number; - tipAmount: number; - amountTendered: number; - cardEntryMode?: string; - last4Digits?: string; - paymentType: string; - paymentStatus: string; - voidInfo?: VoidInfo; - refundInfo?: RefundInfo; - originalProcessingFee?: number; - server?: Employee; - cashDrawer?: CashDrawer; - otherPayment?: OtherPayment; - houseAccount?: HouseAccount; - cardType?: string; -} - -export interface VoidInfo { - voidDate: string; - voidBusinessDate: number; - voidUser: Employee; - voidApprover?: Employee; - voidReason?: string; -} - -export interface RefundInfo { - refundDate: string; - refundBusinessDate: number; - refundAmount: number; - refundUser: Employee; - refundReason?: string; -} - -export interface OtherPayment { - guid: string; - entityType: string; - name: string; - isDefaultForTakeout: boolean; -} - -export interface HouseAccount { - guid: string; - entityType: string; - name: string; -} - -// Inventory Types -export interface InventoryItem { - guid: string; - entityType: string; - name: string; - description?: string; - unitOfMeasure: string; - currentQuantity: number; - parLevel?: number; - reorderPoint?: number; - cost: number; - vendor?: Vendor; - lastCountDate?: string; -} - -export interface Vendor { - guid: string; - entityType: string; - name: string; - contactName?: string; - phone?: string; - email?: string; - address?: string; -} - -export interface PurchaseOrder { - guid: string; - entityType: string; - orderNumber: string; - vendor: Vendor; - orderDate: string; - expectedDeliveryDate?: string; - status: string; - items: PurchaseOrderItem[]; - totalAmount: number; -} - -export interface PurchaseOrderItem { - guid: string; - entityType: string; - inventoryItem: InventoryItem; - quantity: number; - unitCost: number; - totalCost: number; -} - -// Customer Types -export interface Customer { - guid: string; - entityType: string; - firstName: string; - lastName: string; - email?: string; - phone?: string; - company?: string; - createdDate: string; - modifiedDate: string; - loyaltyPoints?: number; - totalVisits?: number; - totalSpent?: number; -} - -export interface LoyaltyAccount { - guid: string; - entityType: string; - customer: Customer; - points: number; - tier?: string; - enrollmentDate: string; - lastActivityDate?: string; -} - -// Cash Management Types -export interface CashDrawer { - guid: string; - entityType: string; - name: string; - employee?: Employee; - openedDate?: string; - closedDate?: string; - status: string; - openingFloat: number; - closingCash: number; - expectedCash: number; - variance: number; -} - -export interface CashEntry { - guid: string; - entityType: string; - entryDate: string; - businessDate: number; - amount: number; - type: string; - reason?: string; - employee: Employee; - cashDrawer: CashDrawer; -} - -// Reporting Types -export interface SalesSummary { - businessDate: number; - netSales: number; - grossSales: number; - discounts: number; - refunds: number; - tax: number; - tips: number; - totalPayments: number; - guestCount: number; - checkCount: number; - averageCheck: number; - averageGuest: number; - salesByHour: HourlySales[]; - salesByCategory: CategorySales[]; - paymentsByType: PaymentTypeSales[]; -} - -export interface HourlySales { - hour: number; - netSales: number; - grossSales: number; - checkCount: number; - guestCount: number; -} - -export interface CategorySales { - category: string; - netSales: number; - quantity: number; - percentOfTotal: number; -} - -export interface PaymentTypeSales { - paymentType: string; - amount: number; - count: number; - percentOfTotal: number; -} - -export interface LaborCostReport { - businessDate: number; - totalHours: number; - totalLaborCost: number; - salesAmount: number; - laborCostPercent: number; - employeeCount: number; - averageHourlyRate: number; - overtimeHours: number; - overtimeCost: number; -} - -export interface MenuItemPerformance { - item: MenuItem; - quantitySold: number; - netSales: number; - grossSales: number; - costOfGoods?: number; - grossProfit?: number; - grossProfitMargin?: number; - percentOfTotalSales: number; -} - -export interface TipSummary { - businessDate: number; - totalTips: number; - cashTips: number; - cardTips: number; - declaredTips: number; - tipsByEmployee: EmployeeTips[]; - averageTipPercent: number; -} - -export interface EmployeeTips { - employee: Employee; - totalTips: number; - cashTips: number; - cardTips: number; - hoursWorked: number; - tipsPerHour: number; -} - -// Delivery Types -export interface DeliveryInfo { - address1: string; - address2?: string; - city: string; - state: string; - zipCode: string; - deliveryNotes?: string; - estimatedDeliveryTime?: string; - deliveryEmployee?: Employee; - deliveryFee?: number; -} - -export interface CurbsidePickupInfo { - transportDescription?: string; - transportColor?: string; - notes?: string; - arrivedDate?: string; -} diff --git a/servers/toast/tsconfig.json b/servers/toast/tsconfig.json deleted file mode 100644 index 156b6d5..0000000 --- a/servers/toast/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "Node16", - "moduleResolution": "Node16", - "lib": ["ES2022"], - "outDir": "./dist", - "rootDir": "./src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] -}