Jake Shore 6d342a1545 Phase 1: Tier 2 complete — 13 servers upgraded to gold standard architecture
- READMEs added: asana, close, freshdesk, google-console, gusto, square
- main.ts + server.ts (lazy loading): activecampaign, clickup, klaviyo, mailchimp, pipedrive, trello, touchbistro, closebot, close, google-console
- All 13 compile with 0 TSC errors
2026-02-14 05:47:14 -05:00

176 lines
4.7 KiB
TypeScript

/**
* Klaviyo MCP Server Class
* Implements lazy-loaded tool modules for optimal performance
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { KlaviyoClient } from './client/index.js';
type ToolModule = any[];
export class KlaviyoMCPServer {
private server: Server;
private client: KlaviyoClient;
private toolModules: Map<string, () => Promise<ToolModule>>;
private loadedTools: any[] | null = null;
constructor(client: KlaviyoClient) {
this.client = client;
this.toolModules = new Map();
this.server = new Server(
{
name: '@mcpengine/klaviyo',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
this.setupToolModules();
this.setupHandlers();
}
private setupToolModules() {
// Register lazy-loaded tool modules
this.toolModules.set('profiles', async () => {
const module = await import('./tools/klaviyo_profiles.js');
return module.profileTools(this.client);
});
this.toolModules.set('lists', async () => {
const module = await import('./tools/klaviyo_lists.js');
return module.listTools(this.client);
});
this.toolModules.set('segments', async () => {
const module = await import('./tools/klaviyo_segments.js');
return module.segmentTools(this.client);
});
this.toolModules.set('campaigns', async () => {
const module = await import('./tools/klaviyo_campaigns.js');
return module.campaignTools(this.client);
});
this.toolModules.set('flows', async () => {
const module = await import('./tools/klaviyo_flows.js');
return module.flowTools(this.client);
});
this.toolModules.set('templates', async () => {
const module = await import('./tools/klaviyo_templates.js');
return module.templateTools(this.client);
});
this.toolModules.set('metrics', async () => {
const module = await import('./tools/klaviyo_metrics.js');
return module.metricTools(this.client);
});
this.toolModules.set('events', async () => {
const module = await import('./tools/klaviyo_events.js');
return module.eventTools(this.client);
});
this.toolModules.set('catalogs', async () => {
const module = await import('./tools/klaviyo_catalogs.js');
return module.catalogTools(this.client);
});
this.toolModules.set('forms', async () => {
const module = await import('./tools/klaviyo_forms.js');
return module.formTools(this.client);
});
this.toolModules.set('tags', async () => {
const module = await import('./tools/klaviyo_tags.js');
return module.tagTools(this.client);
});
this.toolModules.set('reporting', async () => {
const module = await import('./tools/klaviyo_reporting.js');
return module.reportingTools(this.client);
});
}
private async loadAllTools(): Promise<any[]> {
if (this.loadedTools) {
return this.loadedTools;
}
const allTools: any[] = [];
for (const [name, loader] of this.toolModules.entries()) {
const tools = await loader();
allTools.push(...tools);
}
this.loadedTools = allTools;
return allTools;
}
private setupHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
const allTools = await this.loadAllTools();
return {
tools: allTools.map((tool) => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
})),
};
});
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const allTools = await this.loadAllTools();
const tool = allTools.find((t) => t.name === request.params.name);
if (!tool) {
throw new Error(`Unknown tool: ${request.params.name}`);
}
try {
const result = await tool.execute(request.params.arguments || {});
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
} catch (error: any) {
return {
content: [
{
type: 'text',
text: JSON.stringify(
{
error: error.message || 'Unknown error',
details: error.response?.data || error.toString(),
},
null,
2
),
},
],
isError: true,
};
}
});
}
async connect(transport: any) {
await this.server.connect(transport);
}
}