Skip to main content
Glama
fluent-crm.ts15 kB
import { z } from 'zod'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { makeWordPressRequest } from '../wordpress.js'; /** * FluentCRM Tools - Email Marketing & CRM * Uses FluentCRM's native REST API at /fluent-crm/v2/ * Documentation: https://fluentcrm.com/docs/rest-api/ */ // ==================== ZOD SCHEMA DEFINITIONS ==================== // Contact schemas const listContactsSchema = z.object({ page: z.number().optional(), per_page: z.number().optional(), search: z.string().optional(), status: z.enum(['subscribed', 'unsubscribed', 'bounced', 'complained']).optional(), tags: z.array(z.number()).optional(), lists: z.array(z.number()).optional(), }); const createContactSchema = z.object({ email: z.string().email(), first_name: z.string().optional(), last_name: z.string().optional(), status: z.enum(['subscribed', 'unsubscribed', 'pending']).optional(), tags: z.array(z.number()).optional(), lists: z.array(z.number()).optional(), custom_fields: z.record(z.any()).optional(), }); // List schemas const listListsSchema = z.object({ page: z.number().optional(), per_page: z.number().optional(), search: z.string().optional(), }); const createListSchema = z.object({ title: z.string(), slug: z.string().optional(), description: z.string().optional(), }); // Tag schemas const listTagsSchema = z.object({ page: z.number().optional(), per_page: z.number().optional(), search: z.string().optional(), }); const createTagSchema = z.object({ title: z.string(), slug: z.string().optional(), description: z.string().optional(), }); // Campaign schemas const listCampaignsSchema = z.object({ page: z.number().optional(), per_page: z.number().optional(), status: z.enum(['draft', 'scheduled', 'sent', 'archived']).optional(), }); const createCampaignSchema = z.object({ title: z.string(), subject: z.string(), email_body: z.string(), status: z.enum(['draft', 'scheduled']).optional(), scheduled_at: z.string().optional(), }); // ==================== TOOL DEFINITIONS ==================== export const fluentCRMTools: Tool[] = [ // Contact Management { name: 'fcrm_list_contacts', description: 'List FluentCRM contacts with filtering and pagination', inputSchema: { type: 'object' as const, properties: listContactsSchema.shape } }, { name: 'fcrm_get_contact', description: 'Get a specific FluentCRM contact by ID', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number() }).shape } }, { name: 'fcrm_create_contact', description: 'Create a new FluentCRM contact', inputSchema: { type: 'object' as const, properties: createContactSchema.shape } }, { name: 'fcrm_update_contact', description: 'Update an existing FluentCRM contact', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number(), email: z.string().email().optional(), first_name: z.string().optional(), last_name: z.string().optional(), status: z.enum(['subscribed', 'unsubscribed', 'pending']).optional(), }).shape } }, { name: 'fcrm_delete_contact', description: 'Delete a FluentCRM contact', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number() }).shape } }, // List Management { name: 'fcrm_list_lists', description: 'List all FluentCRM contact lists', inputSchema: { type: 'object' as const, properties: listListsSchema.shape } }, { name: 'fcrm_get_list', description: 'Get a specific FluentCRM list by ID', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number() }).shape } }, { name: 'fcrm_create_list', description: 'Create a new FluentCRM list', inputSchema: { type: 'object' as const, properties: createListSchema.shape } }, { name: 'fcrm_update_list', description: 'Update a FluentCRM list', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number(), title: z.string().optional(), description: z.string().optional(), }).shape } }, { name: 'fcrm_delete_list', description: 'Delete a FluentCRM list', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number() }).shape } }, // Tag Management { name: 'fcrm_list_tags', description: 'List all FluentCRM tags', inputSchema: { type: 'object' as const, properties: listTagsSchema.shape } }, { name: 'fcrm_get_tag', description: 'Get a specific FluentCRM tag by ID', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number() }).shape } }, { name: 'fcrm_create_tag', description: 'Create a new FluentCRM tag', inputSchema: { type: 'object' as const, properties: createTagSchema.shape } }, { name: 'fcrm_update_tag', description: 'Update a FluentCRM tag', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number(), title: z.string().optional(), description: z.string().optional(), }).shape } }, { name: 'fcrm_delete_tag', description: 'Delete a FluentCRM tag', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number() }).shape } }, // Campaign Management { name: 'fcrm_list_campaigns', description: 'List all FluentCRM email campaigns', inputSchema: { type: 'object' as const, properties: listCampaignsSchema.shape } }, { name: 'fcrm_get_campaign', description: 'Get a specific FluentCRM campaign by ID', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number() }).shape } }, { name: 'fcrm_create_campaign', description: 'Create a new FluentCRM email campaign', inputSchema: { type: 'object' as const, properties: createCampaignSchema.shape } }, { name: 'fcrm_send_campaign', description: 'Send a FluentCRM campaign', inputSchema: { type: 'object' as const, properties: z.object({ id: z.number(), scheduled_at: z.string().optional(), }).shape } }, ]; // ==================== TOOL HANDLERS ==================== export const fluentCRMHandlers: Record<string, (args: any) => Promise<any>> = { // Contact handlers fcrm_list_contacts: async (args: any) => { try { const params = new URLSearchParams(); if (args.page) params.append('page', args.page); if (args.per_page) params.append('per_page', args.per_page); if (args.search) params.append('search', args.search); if (args.status) params.append('status', args.status); const response = await makeWordPressRequest('GET', `fluent-crm/v2/contacts?${params}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_get_contact: async (args: any) => { try { const response = await makeWordPressRequest('GET', `fluent-crm/v2/contacts/${args.id}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_create_contact: async (args: any) => { try { const response = await makeWordPressRequest('POST', 'fluent-crm/v2/contacts', args); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_update_contact: async (args: any) => { try { const { id, ...data } = args; const response = await makeWordPressRequest('PUT', `fluent-crm/v2/contacts/${id}`, data); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_delete_contact: async (args: any) => { try { const response = await makeWordPressRequest('DELETE', `fluent-crm/v2/contacts/${args.id}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, // List handlers fcrm_list_lists: async (args: any) => { try { const params = new URLSearchParams(); if (args.page) params.append('page', args.page); if (args.per_page) params.append('per_page', args.per_page); if (args.search) params.append('search', args.search); const response = await makeWordPressRequest('GET', `fluent-crm/v2/lists?${params}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_get_list: async (args: any) => { try { const response = await makeWordPressRequest('GET', `fluent-crm/v2/lists/${args.id}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_create_list: async (args: any) => { try { const response = await makeWordPressRequest('POST', 'fluent-crm/v2/lists', args); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_update_list: async (args: any) => { try { const { id, ...data } = args; const response = await makeWordPressRequest('PUT', `fluent-crm/v2/lists/${id}`, data); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_delete_list: async (args: any) => { try { const response = await makeWordPressRequest('DELETE', `fluent-crm/v2/lists/${args.id}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, // Tag handlers fcrm_list_tags: async (args: any) => { try { const params = new URLSearchParams(); if (args.page) params.append('page', args.page); if (args.per_page) params.append('per_page', args.per_page); if (args.search) params.append('search', args.search); const response = await makeWordPressRequest('GET', `fluent-crm/v2/tags?${params}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_get_tag: async (args: any) => { try { const response = await makeWordPressRequest('GET', `fluent-crm/v2/tags/${args.id}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_create_tag: async (args: any) => { try { const response = await makeWordPressRequest('POST', 'fluent-crm/v2/tags', args); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_update_tag: async (args: any) => { try { const { id, ...data } = args; const response = await makeWordPressRequest('PUT', `fluent-crm/v2/tags/${id}`, data); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_delete_tag: async (args: any) => { try { const response = await makeWordPressRequest('DELETE', `fluent-crm/v2/tags/${args.id}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, // Campaign handlers fcrm_list_campaigns: async (args: any) => { try { const params = new URLSearchParams(); if (args.page) params.append('page', args.page); if (args.per_page) params.append('per_page', args.per_page); if (args.status) params.append('status', args.status); const response = await makeWordPressRequest('GET', `fluent-crm/v2/campaigns?${params}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_get_campaign: async (args: any) => { try { const response = await makeWordPressRequest('GET', `fluent-crm/v2/campaigns/${args.id}`); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_create_campaign: async (args: any) => { try { const response = await makeWordPressRequest('POST', 'fluent-crm/v2/campaigns', args); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, fcrm_send_campaign: async (args: any) => { try { const { id, ...data } = args; const response = await makeWordPressRequest('POST', `fluent-crm/v2/campaigns/${id}/send`, data); return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } }; } catch (error: any) { return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } }; } }, };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wplaunchify/fluent-community-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server