203 lines
5.4 KiB
JavaScript
203 lines
5.4 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* ActiveCampaign MCP Server
|
|
* Complete integration with 60+ tools and 16 apps
|
|
*/
|
|
|
|
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 { ActiveCampaignClient } from './client/index.js';
|
|
import { createContactTools } from './tools/contacts.js';
|
|
import { createDealTools } from './tools/deals.js';
|
|
import { createListTools } from './tools/lists.js';
|
|
import { createCampaignTools } from './tools/campaigns.js';
|
|
import { createAutomationTools } from './tools/automations.js';
|
|
import { createFormTools } from './tools/forms.js';
|
|
import { createTagTools } from './tools/tags.js';
|
|
import { createTaskTools } from './tools/tasks.js';
|
|
import { createNoteTools } from './tools/notes.js';
|
|
import { createPipelineTools } from './tools/pipelines.js';
|
|
import { createAccountTools } from './tools/accounts.js';
|
|
import { createWebhookTools } from './tools/webhooks.js';
|
|
|
|
// Available app resources
|
|
const APPS = [
|
|
'contact-manager',
|
|
'deal-pipeline',
|
|
'list-builder',
|
|
'campaign-dashboard',
|
|
'automation-builder',
|
|
'form-manager',
|
|
'tag-organizer',
|
|
'task-center',
|
|
'notes-viewer',
|
|
'pipeline-settings',
|
|
'account-directory',
|
|
'webhook-manager',
|
|
'email-analytics',
|
|
'segment-viewer',
|
|
'site-tracking',
|
|
'score-dashboard',
|
|
];
|
|
|
|
class ActiveCampaignServer {
|
|
private server: Server;
|
|
private client: ActiveCampaignClient;
|
|
private allTools: Record<string, any> = {};
|
|
|
|
constructor() {
|
|
const account = process.env.ACTIVECAMPAIGN_ACCOUNT;
|
|
const apiKey = process.env.ACTIVECAMPAIGN_API_KEY;
|
|
|
|
if (!account || !apiKey) {
|
|
throw new Error(
|
|
'Missing required environment variables: ACTIVECAMPAIGN_ACCOUNT and ACTIVECAMPAIGN_API_KEY'
|
|
);
|
|
}
|
|
|
|
this.client = new ActiveCampaignClient(account, apiKey);
|
|
this.server = new Server(
|
|
{
|
|
name: 'activecampaign-server',
|
|
version: '1.0.0',
|
|
},
|
|
{
|
|
capabilities: {
|
|
tools: {},
|
|
resources: {},
|
|
},
|
|
}
|
|
);
|
|
|
|
this.setupTools();
|
|
this.setupHandlers();
|
|
}
|
|
|
|
private setupTools() {
|
|
// Aggregate all tools from different modules
|
|
this.allTools = {
|
|
...createContactTools(this.client),
|
|
...createDealTools(this.client),
|
|
...createListTools(this.client),
|
|
...createCampaignTools(this.client),
|
|
...createAutomationTools(this.client),
|
|
...createFormTools(this.client),
|
|
...createTagTools(this.client),
|
|
...createTaskTools(this.client),
|
|
...createNoteTools(this.client),
|
|
...createPipelineTools(this.client),
|
|
...createAccountTools(this.client),
|
|
...createWebhookTools(this.client),
|
|
};
|
|
}
|
|
|
|
private setupHandlers() {
|
|
// List available tools
|
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
return {
|
|
tools: Object.entries(this.allTools).map(([name, tool]) => ({
|
|
name,
|
|
description: tool.description,
|
|
inputSchema: tool.inputSchema,
|
|
})),
|
|
};
|
|
});
|
|
|
|
// Execute tool
|
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
const toolName = request.params.name;
|
|
const tool = this.allTools[toolName];
|
|
|
|
if (!tool) {
|
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
}
|
|
|
|
try {
|
|
const result = await tool.handler(request.params.arguments || {});
|
|
return {
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: JSON.stringify(result, null, 2),
|
|
},
|
|
],
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
},
|
|
],
|
|
isError: true,
|
|
};
|
|
}
|
|
});
|
|
|
|
// List app resources
|
|
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
return {
|
|
resources: APPS.map((app) => ({
|
|
uri: `activecampaign://app/${app}`,
|
|
mimeType: 'text/html',
|
|
name: app
|
|
.split('-')
|
|
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
.join(' '),
|
|
})),
|
|
};
|
|
});
|
|
|
|
// Read app resource
|
|
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
const uri = request.params.uri;
|
|
const match = uri.match(/^activecampaign:\/\/app\/(.+)$/);
|
|
|
|
if (!match) {
|
|
throw new Error(`Invalid resource URI: ${uri}`);
|
|
}
|
|
|
|
const appName = match[1];
|
|
if (!APPS.includes(appName)) {
|
|
throw new Error(`Unknown app: ${appName}`);
|
|
}
|
|
|
|
try {
|
|
// Dynamically import the app
|
|
const appModule = await import(`./apps/${appName}/index.js`);
|
|
const html = appModule.default();
|
|
|
|
return {
|
|
contents: [
|
|
{
|
|
uri,
|
|
mimeType: 'text/html',
|
|
text: html,
|
|
},
|
|
],
|
|
};
|
|
} catch (error) {
|
|
throw new Error(`Failed to load app ${appName}: ${error}`);
|
|
}
|
|
});
|
|
}
|
|
|
|
async run() {
|
|
const transport = new StdioServerTransport();
|
|
await this.server.connect(transport);
|
|
console.error('ActiveCampaign MCP Server running on stdio');
|
|
}
|
|
}
|
|
|
|
const server = new ActiveCampaignServer();
|
|
server.run().catch(console.error);
|