Created
June 28, 2025 16:52
-
-
Save ngauthier/12a125ef369f43584a37d54609c5f4f0 to your computer and use it in GitHub Desktop.
Drip MCP Server - Complete API Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; | |
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; | |
import { | |
CallToolRequestSchema, | |
ListToolsRequestSchema, | |
} from "@modelcontextprotocol/sdk/types.js"; | |
import fetch from "node-fetch"; | |
class DripAPI { | |
constructor(apiKey) { | |
this.apiKey = apiKey; | |
this.baseUrl = "https://api.getdrip.com/v2"; | |
} | |
getAuthHeader() { | |
return `Basic ${Buffer.from(`${this.apiKey}:`).toString('base64')}`; | |
} | |
async makeRequest(endpoint, method = 'GET', body = null) { | |
const url = `${this.baseUrl}${endpoint}`; | |
const options = { | |
method, | |
headers: { | |
'Authorization': this.getAuthHeader(), | |
'Content-Type': 'application/json' | |
} | |
}; | |
if (body) { | |
options.body = JSON.stringify(body); | |
} | |
const response = await fetch(url, options); | |
if (!response.ok) { | |
throw new Error(`Drip API error: ${response.status} ${response.statusText}`); | |
} | |
return await response.json(); | |
} | |
async listAccounts() { | |
const data = await this.makeRequest('/v2/accounts'); | |
return data.accounts; | |
} | |
async fetchAccount(accountId) { | |
const data = await this.makeRequest(`/v2/accounts/${accountId}`); | |
return data.accounts[0]; | |
} | |
// Campaign endpoints | |
async listCampaigns(accountId) { | |
const data = await this.makeRequest(`/v2/${accountId}/campaigns`); | |
return data.campaigns; | |
} | |
async fetchCampaign(accountId, campaignId) { | |
const data = await this.makeRequest(`/v2/${accountId}/campaigns/${campaignId}`); | |
return data.campaigns[0]; | |
} | |
async activateCampaign(accountId, campaignId) { | |
return await this.makeRequest(`/v2/${accountId}/campaigns/${campaignId}/activate`, 'POST'); | |
} | |
async pauseCampaign(accountId, campaignId) { | |
return await this.makeRequest(`/v2/${accountId}/campaigns/${campaignId}/pause`, 'POST'); | |
} | |
async listCampaignSubscribers(accountId, campaignId) { | |
const data = await this.makeRequest(`/v2/${accountId}/campaigns/${campaignId}/subscribers`); | |
return data.subscribers; | |
} | |
async subscribeToCampaign(accountId, campaignId, subscriberData) { | |
return await this.makeRequest(`/v2/${accountId}/campaigns/${campaignId}/subscribers`, 'POST', subscriberData); | |
} | |
// Subscriber endpoints | |
async createOrUpdateSubscriber(accountId, subscriberData) { | |
return await this.makeRequest(`/v2/${accountId}/subscribers`, 'POST', subscriberData); | |
} | |
async listSubscribers(accountId, status = null, page = null) { | |
let endpoint = `/v2/${accountId}/subscribers`; | |
const params = new URLSearchParams(); | |
if (status) params.append('status', status); | |
if (page) params.append('page', page); | |
if (params.toString()) endpoint += `?${params.toString()}`; | |
const data = await this.makeRequest(endpoint); | |
return data.subscribers; | |
} | |
async fetchSubscriber(accountId, subscriberId) { | |
const data = await this.makeRequest(`/v2/${accountId}/subscribers/${subscriberId}`); | |
return data.subscribers[0]; | |
} | |
async deleteSubscriber(accountId, subscriberId) { | |
return await this.makeRequest(`/v2/${accountId}/subscribers/${subscriberId}`, 'DELETE'); | |
} | |
async unsubscribeFromCampaign(accountId, subscriberId, campaignId) { | |
return await this.makeRequest(`/v2/${accountId}/subscribers/${subscriberId}/unsubscribe`, 'POST', { | |
campaign_id: campaignId | |
}); | |
} | |
// Event endpoints | |
async recordEvent(accountId, eventData) { | |
return await this.makeRequest(`/v2/${accountId}/events`, 'POST', eventData); | |
} | |
async listEventActions(accountId) { | |
const data = await this.makeRequest(`/v2/${accountId}/event_actions`); | |
return data.event_actions; | |
} | |
// Custom field endpoints | |
async listCustomFields(accountId) { | |
const data = await this.makeRequest(`/v2/${accountId}/custom_field_identifiers`); | |
return data.custom_field_identifiers; | |
} | |
// Form endpoints | |
async listForms(accountId) { | |
const data = await this.makeRequest(`/v2/${accountId}/forms`); | |
return data.forms; | |
} | |
async fetchForm(accountId, formId) { | |
const data = await this.makeRequest(`/v2/${accountId}/forms/${formId}`); | |
return data.forms[0]; | |
} | |
// Conversion endpoints | |
async listConversions(accountId) { | |
const data = await this.makeRequest(`/v2/${accountId}/goals`); | |
return data.goals; | |
} | |
async fetchConversion(accountId, conversionId) { | |
const data = await this.makeRequest(`/v2/${accountId}/goals/${conversionId}`); | |
return data.goals[0]; | |
} | |
// Webhook endpoints | |
async listWebhooks(accountId) { | |
const data = await this.makeRequest(`/v2/${accountId}/webhooks`); | |
return data.webhooks; | |
} | |
async createWebhook(accountId, webhookData) { | |
return await this.makeRequest(`/v2/${accountId}/webhooks`, 'POST', webhookData); | |
} | |
async fetchWebhook(accountId, webhookId) { | |
const data = await this.makeRequest(`/v2/${accountId}/webhooks/${webhookId}`); | |
return data.webhooks[0]; | |
} | |
async updateWebhook(accountId, webhookId, webhookData) { | |
return await this.makeRequest(`/v2/${accountId}/webhooks/${webhookId}`, 'PUT', webhookData); | |
} | |
async deleteWebhook(accountId, webhookId) { | |
return await this.makeRequest(`/v2/${accountId}/webhooks/${webhookId}`, 'DELETE'); | |
} | |
// Batch endpoints | |
async batchSubscribers(accountId, subscribersData) { | |
return await this.makeRequest(`/v2/${accountId}/subscribers/batches`, 'POST', subscribersData); | |
} | |
async batchUnsubscribes(accountId, unsubscribesData) { | |
return await this.makeRequest(`/v2/${accountId}/unsubscribes/batches`, 'POST', unsubscribesData); | |
} | |
async batchEvents(accountId, eventsData) { | |
return await this.makeRequest(`/v2/${accountId}/events/batches`, 'POST', eventsData); | |
} | |
// Shopper Activity endpoints (v3) | |
async batchCarts(accountId, cartsData) { | |
return await this.makeRequest(`/v3/${accountId}/shopper_activity/cart/batch`, 'POST', cartsData); | |
} | |
async batchOrders(accountId, ordersData) { | |
return await this.makeRequest(`/v3/${accountId}/shopper_activity/order/batch`, 'POST', ordersData); | |
} | |
async batchProducts(accountId, productsData) { | |
return await this.makeRequest(`/v3/${accountId}/shopper_activity/product/batch`, 'POST', productsData); | |
} | |
} | |
const server = new Server( | |
{ | |
name: "drip-mcp", | |
version: "0.1.0", | |
}, | |
{ | |
capabilities: { | |
tools: {}, | |
}, | |
} | |
); | |
const baseApiSchema = { | |
type: "object", | |
properties: { | |
api_key: { | |
type: "string", | |
description: "Drip API key for authentication", | |
}, | |
}, | |
required: ["api_key"], | |
}; | |
const accountApiSchema = { | |
type: "object", | |
properties: { | |
api_key: { | |
type: "string", | |
description: "Drip API key for authentication", | |
}, | |
account_id: { | |
type: "string", | |
description: "Account ID", | |
}, | |
}, | |
required: ["api_key", "account_id"], | |
}; | |
server.setRequestHandler(ListToolsRequestSchema, async () => { | |
return { | |
tools: [ | |
{ | |
name: "echo", | |
description: "Echo back the provided text", | |
inputSchema: { | |
type: "object", | |
properties: { | |
text: { | |
type: "string", | |
description: "Text to echo back", | |
}, | |
}, | |
required: ["text"], | |
}, | |
}, | |
// Account endpoints | |
{ | |
name: "list_accounts", | |
description: "List all Drip accounts", | |
inputSchema: baseApiSchema, | |
}, | |
{ | |
name: "fetch_account", | |
description: "Fetch a specific Drip account", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID to fetch" }, | |
}, | |
required: ["api_key", "account_id"], | |
}, | |
}, | |
// Campaign endpoints | |
{ | |
name: "list_campaigns", | |
description: "List all campaigns for an account", | |
inputSchema: accountApiSchema, | |
}, | |
{ | |
name: "fetch_campaign", | |
description: "Fetch a specific campaign", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
campaign_id: { type: "string", description: "Campaign ID" }, | |
}, | |
required: ["api_key", "account_id", "campaign_id"], | |
}, | |
}, | |
{ | |
name: "activate_campaign", | |
description: "Activate a campaign", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
campaign_id: { type: "string", description: "Campaign ID" }, | |
}, | |
required: ["api_key", "account_id", "campaign_id"], | |
}, | |
}, | |
{ | |
name: "pause_campaign", | |
description: "Pause a campaign", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
campaign_id: { type: "string", description: "Campaign ID" }, | |
}, | |
required: ["api_key", "account_id", "campaign_id"], | |
}, | |
}, | |
{ | |
name: "list_campaign_subscribers", | |
description: "List subscribers for a campaign", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
campaign_id: { type: "string", description: "Campaign ID" }, | |
}, | |
required: ["api_key", "account_id", "campaign_id"], | |
}, | |
}, | |
{ | |
name: "subscribe_to_campaign", | |
description: "Subscribe someone to a campaign", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
campaign_id: { type: "string", description: "Campaign ID" }, | |
subscriber_data: { type: "object", description: "Subscriber data" }, | |
}, | |
required: ["api_key", "account_id", "campaign_id", "subscriber_data"], | |
}, | |
}, | |
// Subscriber endpoints | |
{ | |
name: "create_or_update_subscriber", | |
description: "Create or update a subscriber", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
subscriber_data: { type: "object", description: "Subscriber data" }, | |
}, | |
required: ["api_key", "account_id", "subscriber_data"], | |
}, | |
}, | |
{ | |
name: "list_subscribers", | |
description: "List subscribers for an account", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
status: { type: "string", description: "Filter by status (optional)" }, | |
page: { type: "string", description: "Page number (optional)" }, | |
}, | |
required: ["api_key", "account_id"], | |
}, | |
}, | |
{ | |
name: "fetch_subscriber", | |
description: "Fetch a specific subscriber", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
subscriber_id: { type: "string", description: "Subscriber ID" }, | |
}, | |
required: ["api_key", "account_id", "subscriber_id"], | |
}, | |
}, | |
{ | |
name: "delete_subscriber", | |
description: "Delete a subscriber", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
subscriber_id: { type: "string", description: "Subscriber ID" }, | |
}, | |
required: ["api_key", "account_id", "subscriber_id"], | |
}, | |
}, | |
// Event endpoints | |
{ | |
name: "record_event", | |
description: "Record an event for a subscriber", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
event_data: { type: "object", description: "Event data" }, | |
}, | |
required: ["api_key", "account_id", "event_data"], | |
}, | |
}, | |
{ | |
name: "list_event_actions", | |
description: "List custom event actions", | |
inputSchema: accountApiSchema, | |
}, | |
// Form endpoints | |
{ | |
name: "list_forms", | |
description: "List forms for an account", | |
inputSchema: accountApiSchema, | |
}, | |
{ | |
name: "fetch_form", | |
description: "Fetch a specific form", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
form_id: { type: "string", description: "Form ID" }, | |
}, | |
required: ["api_key", "account_id", "form_id"], | |
}, | |
}, | |
// Custom field endpoints | |
{ | |
name: "list_custom_fields", | |
description: "List custom field identifiers", | |
inputSchema: accountApiSchema, | |
}, | |
// Conversion endpoints | |
{ | |
name: "list_conversions", | |
description: "List conversions/goals for an account", | |
inputSchema: accountApiSchema, | |
}, | |
{ | |
name: "fetch_conversion", | |
description: "Fetch a specific conversion/goal", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
conversion_id: { type: "string", description: "Conversion ID" }, | |
}, | |
required: ["api_key", "account_id", "conversion_id"], | |
}, | |
}, | |
// Webhook endpoints | |
{ | |
name: "list_webhooks", | |
description: "List webhooks for an account", | |
inputSchema: accountApiSchema, | |
}, | |
{ | |
name: "create_webhook", | |
description: "Create a new webhook", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
webhook_data: { type: "object", description: "Webhook data" }, | |
}, | |
required: ["api_key", "account_id", "webhook_data"], | |
}, | |
}, | |
{ | |
name: "fetch_webhook", | |
description: "Fetch a specific webhook", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
webhook_id: { type: "string", description: "Webhook ID" }, | |
}, | |
required: ["api_key", "account_id", "webhook_id"], | |
}, | |
}, | |
{ | |
name: "update_webhook", | |
description: "Update a webhook", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
webhook_id: { type: "string", description: "Webhook ID" }, | |
webhook_data: { type: "object", description: "Updated webhook data" }, | |
}, | |
required: ["api_key", "account_id", "webhook_id", "webhook_data"], | |
}, | |
}, | |
{ | |
name: "delete_webhook", | |
description: "Delete a webhook", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
webhook_id: { type: "string", description: "Webhook ID" }, | |
}, | |
required: ["api_key", "account_id", "webhook_id"], | |
}, | |
}, | |
// Batch endpoints | |
{ | |
name: "batch_subscribers", | |
description: "Create or update subscribers in batch", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
subscribers_data: { type: "object", description: "Batch subscribers data" }, | |
}, | |
required: ["api_key", "account_id", "subscribers_data"], | |
}, | |
}, | |
{ | |
name: "batch_events", | |
description: "Record events in batch", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
events_data: { type: "object", description: "Batch events data" }, | |
}, | |
required: ["api_key", "account_id", "events_data"], | |
}, | |
}, | |
// Shopper Activity endpoints | |
{ | |
name: "batch_carts", | |
description: "Submit cart data in batch", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
carts_data: { type: "object", description: "Batch carts data" }, | |
}, | |
required: ["api_key", "account_id", "carts_data"], | |
}, | |
}, | |
{ | |
name: "batch_orders", | |
description: "Submit order data in batch", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
orders_data: { type: "object", description: "Batch orders data" }, | |
}, | |
required: ["api_key", "account_id", "orders_data"], | |
}, | |
}, | |
{ | |
name: "batch_products", | |
description: "Submit product data in batch", | |
inputSchema: { | |
type: "object", | |
properties: { | |
api_key: { type: "string", description: "Drip API key" }, | |
account_id: { type: "string", description: "Account ID" }, | |
products_data: { type: "object", description: "Batch products data" }, | |
}, | |
required: ["api_key", "account_id", "products_data"], | |
}, | |
}, | |
], | |
}; | |
}); | |
async function handleEcho(args) { | |
return { | |
content: [ | |
{ | |
type: "text", | |
text: `Echo: ${args?.text || ""}`, | |
}, | |
], | |
}; | |
} | |
async function handleListAccounts(args) { | |
try { | |
const dripApi = new DripAPI(args?.api_key); | |
const accounts = await dripApi.listAccounts(); | |
return { | |
content: [ | |
{ | |
type: "text", | |
text: `Found ${accounts.length} Drip accounts:\n\n${accounts.map(account => | |
`• ${account.name} (ID: ${account.id})${account.url ? ` - ${account.url}` : ''}` | |
).join('\n')}`, | |
}, | |
], | |
}; | |
} catch (error) { | |
return { | |
content: [ | |
{ | |
type: "text", | |
text: `Error fetching accounts: ${error instanceof Error ? error.message : 'Unknown error'}`, | |
}, | |
], | |
isError: true, | |
}; | |
} | |
} | |
function createHandler(apiMethod, formatResult = null) { | |
return async (args) => { | |
try { | |
const dripApi = new DripAPI(args?.api_key); | |
const result = await apiMethod(dripApi, args); | |
return { | |
content: [ | |
{ | |
type: "text", | |
text: formatResult ? formatResult(result) : JSON.stringify(result, null, 2), | |
}, | |
], | |
}; | |
} catch (error) { | |
return { | |
content: [ | |
{ | |
type: "text", | |
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, | |
}, | |
], | |
isError: true, | |
}; | |
} | |
}; | |
} | |
const handleFetchAccount = createHandler((api, args) => api.fetchAccount(args.account_id)); | |
const handleListCampaigns = createHandler((api, args) => api.listCampaigns(args.account_id)); | |
const handleFetchCampaign = createHandler((api, args) => api.fetchCampaign(args.account_id, args.campaign_id)); | |
const handleActivateCampaign = createHandler((api, args) => api.activateCampaign(args.account_id, args.campaign_id)); | |
const handlePauseCampaign = createHandler((api, args) => api.pauseCampaign(args.account_id, args.campaign_id)); | |
const handleListCampaignSubscribers = createHandler((api, args) => api.listCampaignSubscribers(args.account_id, args.campaign_id)); | |
const handleSubscribeToCampaign = createHandler((api, args) => api.subscribeToCampaign(args.account_id, args.campaign_id, args.subscriber_data)); | |
const handleCreateOrUpdateSubscriber = createHandler((api, args) => api.createOrUpdateSubscriber(args.account_id, args.subscriber_data)); | |
const handleListSubscribers = createHandler((api, args) => api.listSubscribers(args.account_id, args.status, args.page)); | |
const handleFetchSubscriber = createHandler((api, args) => api.fetchSubscriber(args.account_id, args.subscriber_id)); | |
const handleDeleteSubscriber = createHandler((api, args) => api.deleteSubscriber(args.account_id, args.subscriber_id)); | |
const handleRecordEvent = createHandler((api, args) => api.recordEvent(args.account_id, args.event_data)); | |
const handleListEventActions = createHandler((api, args) => api.listEventActions(args.account_id)); | |
const handleListCustomFields = createHandler((api, args) => api.listCustomFields(args.account_id)); | |
const handleListForms = createHandler((api, args) => api.listForms(args.account_id)); | |
const handleFetchForm = createHandler((api, args) => api.fetchForm(args.account_id, args.form_id)); | |
const handleListConversions = createHandler((api, args) => api.listConversions(args.account_id)); | |
const handleFetchConversion = createHandler((api, args) => api.fetchConversion(args.account_id, args.conversion_id)); | |
const handleListWebhooks = createHandler((api, args) => api.listWebhooks(args.account_id)); | |
const handleCreateWebhook = createHandler((api, args) => api.createWebhook(args.account_id, args.webhook_data)); | |
const handleFetchWebhook = createHandler((api, args) => api.fetchWebhook(args.account_id, args.webhook_id)); | |
const handleUpdateWebhook = createHandler((api, args) => api.updateWebhook(args.account_id, args.webhook_id, args.webhook_data)); | |
const handleDeleteWebhook = createHandler((api, args) => api.deleteWebhook(args.account_id, args.webhook_id)); | |
const handleBatchSubscribers = createHandler((api, args) => api.batchSubscribers(args.account_id, args.subscribers_data)); | |
const handleBatchEvents = createHandler((api, args) => api.batchEvents(args.account_id, args.events_data)); | |
const handleBatchCarts = createHandler((api, args) => api.batchCarts(args.account_id, args.carts_data)); | |
const handleBatchOrders = createHandler((api, args) => api.batchOrders(args.account_id, args.orders_data)); | |
const handleBatchProducts = createHandler((api, args) => api.batchProducts(args.account_id, args.products_data)); | |
const commandHandlers = { | |
echo: handleEcho, | |
// Account endpoints | |
list_accounts: handleListAccounts, | |
fetch_account: handleFetchAccount, | |
// Campaign endpoints | |
list_campaigns: handleListCampaigns, | |
fetch_campaign: handleFetchCampaign, | |
activate_campaign: handleActivateCampaign, | |
pause_campaign: handlePauseCampaign, | |
list_campaign_subscribers: handleListCampaignSubscribers, | |
subscribe_to_campaign: handleSubscribeToCampaign, | |
// Subscriber endpoints | |
create_or_update_subscriber: handleCreateOrUpdateSubscriber, | |
list_subscribers: handleListSubscribers, | |
fetch_subscriber: handleFetchSubscriber, | |
delete_subscriber: handleDeleteSubscriber, | |
// Event endpoints | |
record_event: handleRecordEvent, | |
list_event_actions: handleListEventActions, | |
// Form endpoints | |
list_forms: handleListForms, | |
fetch_form: handleFetchForm, | |
// Custom field endpoints | |
list_custom_fields: handleListCustomFields, | |
// Conversion endpoints | |
list_conversions: handleListConversions, | |
fetch_conversion: handleFetchConversion, | |
// Webhook endpoints | |
list_webhooks: handleListWebhooks, | |
create_webhook: handleCreateWebhook, | |
fetch_webhook: handleFetchWebhook, | |
update_webhook: handleUpdateWebhook, | |
delete_webhook: handleDeleteWebhook, | |
// Batch endpoints | |
batch_subscribers: handleBatchSubscribers, | |
batch_events: handleBatchEvents, | |
// Shopper Activity endpoints | |
batch_carts: handleBatchCarts, | |
batch_orders: handleBatchOrders, | |
batch_products: handleBatchProducts, | |
}; | |
server.setRequestHandler(CallToolRequestSchema, async (request) => { | |
const { name, arguments: args } = request.params; | |
const handler = commandHandlers[name]; | |
if (handler) { | |
return await handler(args); | |
} | |
throw new Error(`Unknown tool: ${name}`); | |
}); | |
async function main() { | |
const transport = new StdioServerTransport(); | |
await server.connect(transport); | |
} | |
main().catch((error) => { | |
console.error("Server error:", error); | |
process.exit(1); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "drip-mcp", | |
"version": "0.1.0", | |
"description": "A minimal MCP server", | |
"type": "module", | |
"main": "index.js", | |
"bin": { | |
"drip-mcp": "index.js" | |
}, | |
"scripts": { | |
"start": "node index.js" | |
}, | |
"dependencies": { | |
"@modelcontextprotocol/sdk": "^0.5.0", | |
"node-fetch": "^3.3.0" | |
}, | |
"engines": { | |
"node": ">=18" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
import { spawn } from 'child_process'; | |
const server = spawn('node', ['index.js'], { | |
stdio: ['pipe', 'pipe', 'inherit'] | |
}); | |
// Test MCP protocol - initialize | |
const initMessage = { | |
jsonrpc: "2.0", | |
id: 1, | |
method: "initialize", | |
params: { | |
protocolVersion: "2024-11-05", | |
capabilities: { | |
tools: {} | |
}, | |
clientInfo: { | |
name: "test-client", | |
version: "0.1.0" | |
} | |
} | |
}; | |
server.stdin.write(JSON.stringify(initMessage) + '\n'); | |
// Test listing tools | |
const listToolsMessage = { | |
jsonrpc: "2.0", | |
id: 2, | |
method: "tools/list", | |
params: {} | |
}; | |
setTimeout(() => { | |
server.stdin.write(JSON.stringify(listToolsMessage) + '\n'); | |
}, 100); | |
// Test calling echo tool | |
const callToolMessage = { | |
jsonrpc: "2.0", | |
id: 3, | |
method: "tools/call", | |
params: { | |
name: "echo", | |
arguments: { | |
text: "Hello MCP!" | |
} | |
} | |
}; | |
// Test calling list_accounts tool (will fail without real API key) | |
const listAccountsMessage = { | |
jsonrpc: "2.0", | |
id: 4, | |
method: "tools/call", | |
params: { | |
name: "list_accounts", | |
arguments: { | |
api_key: "test_key_will_fail" | |
} | |
} | |
}; | |
setTimeout(() => { | |
server.stdin.write(JSON.stringify(callToolMessage) + '\n'); | |
}, 200); | |
setTimeout(() => { | |
server.stdin.write(JSON.stringify(listAccountsMessage) + '\n'); | |
}, 300); | |
server.stdout.on('data', (data) => { | |
console.log('Server response:', data.toString()); | |
}); | |
setTimeout(() => { | |
server.kill(); | |
}, 1500); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment