=== NEW === - studio/ — MCPEngine Studio scaffold (Next.js monorepo, build plan) - docs/FACTORY-V2.md — Factory v2 architecture doc - docs/CALENDLY_MCP_BUILD_SUMMARY.md — Calendly MCP build report === UPDATED SERVERS === - fieldedge: Added jobs-tools, UI build script, main entry update - lightspeed: Updated main + server entry points - squarespace: Added collection-browser + page-manager apps - toast: Added main + server entry points === INFRA === - infra/command-center/state.json — Updated pipeline state - infra/command-center/FACTORY-V2.md — Factory v2 operator playbook
155 lines
4.5 KiB
TypeScript
155 lines
4.5 KiB
TypeScript
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');
|
|
}
|
|
}
|