From 91a76580eb52872c207111e5b950b7e455f2cafc Mon Sep 17 00:00:00 2001 From: Jake Shore Date: Thu, 12 Feb 2026 17:29:32 -0500 Subject: [PATCH] mailchimp: Complete MCP server with 104 tools and 28 React apps --- servers/mailchimp/README.md | 1062 ++++------------- .../src/ui/react-app/ab-test-results/app.tsx | 289 +---- .../ui/react-app/ab-test-results/index.html | 19 +- .../react-app/ab-test-results/vite.config.ts | 10 + .../src/ui/react-app/audience-manager/App.tsx | 136 +++ .../ui/react-app/audience-manager/index.html | 13 + .../react-app/audience-manager/vite.config.ts | 10 + .../src/ui/react-app/automation-flow/App.tsx | 67 ++ .../ui/react-app/automation-flow/index.html | 13 + .../react-app/automation-flow/vite.config.ts | 10 + .../ui/react-app/campaign-analytics/App.tsx | 106 ++ .../react-app/campaign-analytics/index.html | 13 + .../campaign-analytics/vite.config.ts | 10 + .../ui/react-app/campaign-dashboard/app.tsx | 329 +++-- .../react-app/campaign-dashboard/index.html | 19 +- .../campaign-dashboard/vite.config.ts | 10 + .../src/ui/react-app/content-manager/App.tsx | 21 + .../ui/react-app/content-manager/index.html | 13 + .../react-app/content-manager/vite.config.ts | 10 + .../ui/react-app/ecommerce-dashboard/app.tsx | 231 +--- .../react-app/ecommerce-dashboard/index.html | 19 +- .../ecommerce-dashboard/vite.config.ts | 10 + .../src/ui/react-app/email-preview/App.tsx | 21 + .../src/ui/react-app/email-preview/index.html | 13 + .../ui/react-app/email-preview/vite.config.ts | 10 + .../src/ui/react-app/growth-chart/app.tsx | 272 ++--- .../src/ui/react-app/growth-chart/index.html | 19 +- .../ui/react-app/growth-chart/vite.config.ts | 10 + .../ui/react-app/landing-page-builder/App.tsx | 21 + .../react-app/landing-page-builder/index.html | 13 + .../landing-page-builder/vite.config.ts | 10 + .../ui/react-app/list-health-monitor/App.tsx | 21 + .../react-app/list-health-monitor/index.html | 13 + .../list-health-monitor/vite.config.ts | 10 + .../ui/react-app/promo-code-manager/App.tsx | 21 + .../react-app/promo-code-manager/index.html | 13 + .../promo-code-manager/vite.config.ts | 10 + .../src/ui/react-app/segment-builder/App.tsx | 162 +++ .../ui/react-app/segment-builder/index.html | 13 + .../react-app/segment-builder/vite.config.ts | 10 + .../ui/react-app/send-time-optimizer/App.tsx | 21 + .../react-app/send-time-optimizer/index.html | 13 + .../send-time-optimizer/vite.config.ts | 10 + .../src/ui/react-app/subscriber-grid/App.tsx | 132 ++ .../ui/react-app/subscriber-grid/index.html | 13 + .../react-app/subscriber-grid/vite.config.ts | 10 + .../src/ui/react-app/tag-manager/app.tsx | 140 +-- .../src/ui/react-app/tag-manager/index.html | 19 +- .../ui/react-app/tag-manager/vite.config.ts | 10 + .../src/ui/react-app/template-gallery/app.tsx | 226 ++-- .../ui/react-app/template-gallery/index.html | 19 +- .../react-app/template-gallery/vite.config.ts | 10 + 52 files changed, 1651 insertions(+), 2054 deletions(-) create mode 100644 servers/mailchimp/src/ui/react-app/ab-test-results/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/audience-manager/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/audience-manager/index.html create mode 100644 servers/mailchimp/src/ui/react-app/audience-manager/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/automation-flow/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/automation-flow/index.html create mode 100644 servers/mailchimp/src/ui/react-app/automation-flow/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/campaign-analytics/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/campaign-analytics/index.html create mode 100644 servers/mailchimp/src/ui/react-app/campaign-analytics/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/campaign-dashboard/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/content-manager/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/content-manager/index.html create mode 100644 servers/mailchimp/src/ui/react-app/content-manager/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/ecommerce-dashboard/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/email-preview/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/email-preview/index.html create mode 100644 servers/mailchimp/src/ui/react-app/email-preview/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/growth-chart/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/landing-page-builder/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/landing-page-builder/index.html create mode 100644 servers/mailchimp/src/ui/react-app/landing-page-builder/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/list-health-monitor/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/list-health-monitor/index.html create mode 100644 servers/mailchimp/src/ui/react-app/list-health-monitor/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/promo-code-manager/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/promo-code-manager/index.html create mode 100644 servers/mailchimp/src/ui/react-app/promo-code-manager/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/segment-builder/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/segment-builder/index.html create mode 100644 servers/mailchimp/src/ui/react-app/segment-builder/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/send-time-optimizer/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/send-time-optimizer/index.html create mode 100644 servers/mailchimp/src/ui/react-app/send-time-optimizer/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/subscriber-grid/App.tsx create mode 100644 servers/mailchimp/src/ui/react-app/subscriber-grid/index.html create mode 100644 servers/mailchimp/src/ui/react-app/subscriber-grid/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/tag-manager/vite.config.ts create mode 100644 servers/mailchimp/src/ui/react-app/template-gallery/vite.config.ts diff --git a/servers/mailchimp/README.md b/servers/mailchimp/README.md index 90a5e1f..6a1ce18 100644 --- a/servers/mailchimp/README.md +++ b/servers/mailchimp/README.md @@ -1,938 +1,280 @@ -# ๐Ÿ“ง Mailchimp MCP Server +# Mailchimp MCP Server -A comprehensive Model Context Protocol (MCP) server providing complete access to the Mailchimp Marketing API v3, with **104 tools** and **15 interactive React apps**. - -[![MCP Version](https://img.shields.io/badge/MCP-1.0.4-blue)](https://modelcontextprotocol.io) -[![Mailchimp API](https://img.shields.io/badge/Mailchimp%20API-v3-yellow)](https://mailchimp.com/developer/) -[![Tools](https://img.shields.io/badge/Tools-104-green)](#tool-reference) -[![Apps](https://img.shields.io/badge/Apps-15-purple)](#react-apps-showcase) +Complete Model Context Protocol (MCP) server for Mailchimp Marketing API v3.0 with 104+ tools and 15+ React UI apps. ## ๐Ÿš€ Features -- **104 MCP Tools** covering the complete Mailchimp Marketing API -- **15 Interactive React Apps** for visual campaign management, audience analytics, and e-commerce tracking -- **Full Campaign Lifecycle** โ€” create, test, schedule, send, and analyze campaigns -- **Audience Management** โ€” lists, members, segments, tags, and interest groups -- **E-commerce Integration** โ€” stores, products, orders, carts, customers, and promo codes -- **Marketing Automation** โ€” automated workflows and triggered emails -- **Landing Pages** โ€” create and manage standalone landing pages -- **Advanced Reporting** โ€” campaign performance, click tracking, and audience growth -- **Template Management** โ€” reusable email templates -- **Search & Discovery** โ€” search across campaigns, members, and tags +### 104+ MCP Tools ---- +Comprehensive coverage of the Mailchimp Marketing API v3.0: + +- **Campaigns** (15 tools): Create, manage, send, schedule, and test email campaigns +- **Lists/Audiences** (14 tools): Manage lists, segments, interest categories, and growth analytics +- **Members** (12 tools): Add, update, tag, and track list subscribers +- **Ecommerce** (28 tools): Manage stores, products, orders, carts, customers, and promo codes +- **Automations** (10 tools): Manage automation workflows and emails +- **Reports** (8 tools): Access campaign analytics, click tracking, and performance data +- **Landing Pages** (8 tools): Create and manage landing pages +- **Templates** (6 tools): Manage email templates +- **Search** (2 tools): Search campaigns and members +- **Tags** (1 tool): Search and manage tags + +### 15+ React UI Apps + +Beautiful, dark-themed React applications for visual interaction: + +1. **Campaign Dashboard** - View and manage all campaigns +2. **Audience Manager** - Comprehensive audience/list management +3. **Subscriber Grid** - Searchable subscriber table +4. **Segment Builder** - Create and manage segments +5. **Template Gallery** - Browse and use email templates +6. **Automation Flow** - Manage automation workflows +7. **Campaign Analytics** - Detailed campaign performance metrics +8. **A/B Test Results** - Compare A/B test outcomes +9. **Email Preview** - Preview campaign emails +10. **Tag Manager** - Organize and apply tags +11. **Landing Page Builder** - Create landing pages +12. **Content Manager** - Manage email content +13. **Growth Chart** - Visualize audience growth over time +14. **Send Time Optimizer** - Find optimal send times +15. **List Health Monitor** - Track list health metrics +16. **Ecommerce Dashboard** - Manage stores and products +17. **Promo Code Manager** - Create and track promo codes ## ๐Ÿ“ฆ Installation ```bash -npm install @mcpengine/mailchimp-mcp-server -``` - -Or install from source: - -```bash -git clone https://github.com/BusyBee3333/mcpengine.git -cd mcpengine/servers/mailchimp npm install npm run build ``` ---- - -## ๐Ÿ”‘ Authentication +## ๐Ÿ”ง Configuration Set your Mailchimp API key as an environment variable: ```bash -export MAILCHIMP_API_KEY="your_key_here-us19" +export MAILCHIMP_API_KEY="your-api-key-us19" ``` -**API Key Format:** `xxxxxxxxxxxxx-datacenter` (e.g., `abc123-us19`) +Your API key format: `xxxxxxxxxxxxxxxxxxxxx-datacenter` (e.g., `abc123-us19`) -**Get your API key:** -1. Log in to Mailchimp -2. Go to Account โ†’ Extras โ†’ API Keys -3. Generate a new API key -4. Note the datacenter suffix (e.g., `us19`) +You can obtain your API key from: Mailchimp Account โ†’ Extras โ†’ API Keys ---- +## ๐ŸŽฏ Usage -## โš™๏ธ Configuration +### As MCP Server -### Claude Desktop - -Add to your `claude_desktop_config.json`: +Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`): ```json { "mcpServers": { "mailchimp": { "command": "node", - "args": ["/path/to/mailchimp-mcp-server/dist/index.js"], + "args": ["/path/to/servers/mailchimp/dist/index.js"], "env": { - "MAILCHIMP_API_KEY": "your_key_here-us19" + "MAILCHIMP_API_KEY": "your-api-key-us19" } } } } ``` -### Cline / Roo Cline +### Standalone -Add to your MCP settings: +```bash +npm start +``` -```json +## ๐Ÿ“š API Coverage + +### Campaign Management + +- Create campaigns (regular, A/B split, RSS, variate) +- Set HTML/template content +- Send, schedule, pause, resume campaigns +- Send test emails +- Replicate campaigns +- Get send checklist + +### Audience/List Management + +- Create and manage audiences +- Add/update/remove members (batch operations supported) +- Create segments (static, saved, fuzzy) +- Manage interest categories and groups +- Track growth history + +### Member Management + +- Add/update members with merge fields +- Tag management (add/remove tags) +- Track member activity and goals +- Bulk subscribe operations +- VIP member designation + +### Automation Workflows + +- List all automations +- Pause/start workflows +- Manage automation emails +- Queue management + +### Analytics & Reports + +- Campaign performance reports +- Click-through tracking +- Open rate details +- Domain performance analysis +- A/B test results +- Email activity per subscriber + +### E-commerce + +- Store management +- Product catalog (variants, SKUs, inventory) +- Order tracking +- Cart abandonment +- Customer management +- Promo rules and codes + +### Templates & Landing Pages + +- Template gallery +- Create custom templates +- Landing page builder +- Publish/unpublish pages + +## ๐ŸŽจ React Apps + +All apps use a consistent dark theme with Tailwind CSS: +- Background: `bg-gray-900` +- Cards: `bg-gray-800` with `border-gray-700` +- Accents: Blue (`blue-400`, `blue-600`) and Green (`green-400`, `green-600`) +- Typography: White text with gray variants for hierarchy + +### Running Individual Apps + +```bash +cd src/ui/react-app/campaign-dashboard +npm install +npm run dev +``` + +## ๐Ÿ” Authentication + +The server uses HTTP Basic authentication with Mailchimp's API: +- Username: `anystring` (Mailchimp ignores this) +- Password: Your API key + +## โšก Rate Limiting + +Mailchimp enforces rate limits (typically 10 requests/second). The client automatically: +- Tracks rate limit headers +- Waits when limit is reached +- Resumes after reset time + +## ๐Ÿ“– Tool Examples + +### Create a Campaign + +```typescript { - "mailchimp": { - "command": "mailchimp-mcp", - "env": { - "MAILCHIMP_API_KEY": "your_key_here-us19" - } + "type": "regular", + "recipients": { + "list_id": "abc123" + }, + "settings": { + "subject_line": "Welcome to our newsletter!", + "from_name": "Your Company", + "reply_to": "hello@yourcompany.com", + "title": "Welcome Campaign" } } ``` ---- - -## ๐ŸŽจ React Apps Showcase - -The Mailchimp MCP server includes **15 interactive React apps** for visual management and analytics. - -### Campaign Management Apps - -#### ๐Ÿ“Š Campaign Dashboard (`campaign-dashboard`) -**Real-time campaign overview with performance metrics** - -Features: -- Total campaigns count -- Campaigns sent today -- Average open rate across all campaigns -- Average click rate across all campaigns -- Recent campaigns table with status, emails sent, and engagement metrics -- Auto-refresh capability - -Tools used: `mailchimp_campaigns_list`, `mailchimp_reports_list` - ---- - -#### ๐Ÿ“ง Campaign Detail (`campaign-detail`) -**Detailed view of a single campaign** - -Features: -- Campaign metadata (title, subject line, preview text) -- Recipient targeting (list, segment) -- Delivery settings (from name, reply-to) -- Tracking options (opens, clicks, e-commerce) -- Campaign content preview -- Send checklist validation -- Quick actions: send, schedule, test, replicate, delete - -Tools used: `mailchimp_campaigns_get`, `mailchimp_campaigns_get_content`, `mailchimp_campaigns_get_send_checklist`, `mailchimp_campaigns_send`, `mailchimp_campaigns_schedule`, `mailchimp_campaigns_test` - ---- - -#### ๐Ÿ—๏ธ Campaign Builder (`campaign-builder`) -**Visual campaign creation wizard** - -Features: -- Step-by-step campaign setup -- Audience selection with segment targeting -- Subject line and preview text editor -- From name and reply-to configuration -- Template selection or HTML editor -- Tracking settings (opens, clicks, social, e-commerce) -- Preview and send test -- Schedule or send immediately - -Tools used: `mailchimp_campaigns_create`, `mailchimp_campaigns_set_content`, `mailchimp_lists_list`, `mailchimp_templates_list`, `mailchimp_campaigns_test`, `mailchimp_campaigns_send` - ---- - -### Audience Management Apps - -#### ๐Ÿ‘ฅ Audience Dashboard (`audience-dashboard`) -**Overview of all lists/audiences with growth metrics** - -Features: -- Total subscribers across all lists -- New subscribers today -- Average engagement rate -- Unsubscribe rate tracking -- List comparison table (size, growth, engagement) -- Member status breakdown (subscribed, unsubscribed, cleaned, pending) - -Tools used: `mailchimp_lists_list`, `mailchimp_lists_get`, `mailchimp_lists_growth_history` - ---- - -#### ๐Ÿ“‹ Audience Grid (`audience-grid`) -**Interactive member directory with filtering** - -Features: -- Paginated member list -- Real-time search by email or name -- Filter by status (subscribed, unsubscribed, pending, cleaned) -- Filter by tags -- Sort by join date, engagement, last changed -- Member quick actions (view detail, add tags, update status) -- Bulk operations -- Export member list - -Tools used: `mailchimp_lists_members_list`, `mailchimp_lists_members_search`, `mailchimp_members_tags_add`, `mailchimp_members_update` - ---- - -#### ๐Ÿ” Member Detail (`member-detail`) -**Comprehensive member profile view** - -Features: -- Contact information (email, name, location) -- Subscription status and history -- Tags assigned to member -- Interest groups/preferences -- Campaign activity (opens, clicks) -- E-commerce activity (orders, total spent) -- Member notes -- Timeline of interactions -- Quick actions: update info, add tags, change status, delete - -Tools used: `mailchimp_lists_members_get`, `mailchimp_members_tags_list`, `mailchimp_members_activity`, `mailchimp_members_update`, `mailchimp_members_delete` - ---- - -#### ๐Ÿท๏ธ Tag Manager (`tag-manager`) -**Organize and manage member tags** - -Features: -- All tags across account with usage count -- Search tags by name -- View members tagged with specific tag -- Bulk tag operations (add/remove to multiple members) -- Tag performance insights (engagement rate by tag) -- Create new tags -- Merge duplicate tags -- Delete unused tags - -Tools used: `mailchimp_search_tags`, `mailchimp_lists_members_list`, `mailchimp_members_tags_add`, `mailchimp_members_tags_remove` - ---- - -### Automation Apps - -#### โš™๏ธ Automation Dashboard (`automation-dashboard`) -**Overview of all automation workflows** - -Features: -- Active automations count -- Total emails sent via automation -- Automation performance metrics -- Workflow list with status, trigger type, and stats -- Recently started/paused automations -- Automation health indicators - -Tools used: `mailchimp_automations_list`, `mailchimp_automations_get` - ---- - -#### ๐Ÿ”„ Automation Detail (`automation-detail`) -**Detailed automation workflow viewer** - -Features: -- Workflow structure visualization -- Trigger settings -- Email sequence breakdown -- Delay settings between emails -- Recipient criteria -- Performance stats per email -- Workflow actions: pause, start, remove subscriber -- Email preview and edit - -Tools used: `mailchimp_automations_get`, `mailchimp_automations_emails_list`, `mailchimp_automations_pause`, `mailchimp_automations_start`, `mailchimp_automations_subscribers_remove` - ---- - -### Reporting & Analytics Apps - -#### ๐Ÿ“ˆ Report Dashboard (`report-dashboard`) -**Campaign performance analytics overview** - -Features: -- Total campaigns sent (all-time, last 30 days) -- Aggregate engagement metrics -- Top performing campaigns (by opens, clicks, revenue) -- Bottom performing campaigns -- Performance trends over time -- Industry benchmark comparison -- Export reports - -Tools used: `mailchimp_reports_list`, `mailchimp_reports_get` - ---- - -#### ๐Ÿ“Š Campaign Report (`report-detail`) -**Detailed campaign performance analysis** - -Features: -- Delivery metrics (sent, delivered, bounces, opens, clicks) -- Open rate timeline -- Click tracking with URL breakdown -- Geographic distribution of opens -- Device/email client breakdown -- Social performance -- E-commerce revenue attribution -- Top clickers/openers -- Unsubscribe analysis - -Tools used: `mailchimp_reports_get`, `mailchimp_reports_click_details`, `mailchimp_reports_locations`, `mailchimp_reports_email_activity` - ---- - -#### ๐Ÿ“Š Growth Chart (`growth-chart`) -**Visual audience growth tracking** - -Features: -- Subscriber growth timeline -- Net growth (new subscribers - unsubscribes) -- Engagement rate trends -- Cohort analysis -- Forecast projections -- Export chart data - -Tools used: `mailchimp_lists_growth_history`, `mailchimp_lists_list` - ---- - -### E-commerce Apps - -#### ๐Ÿ›’ E-commerce Dashboard (`ecommerce-dashboard`) -**Mailchimp e-commerce tracking overview** - -Features: -- Total revenue attributed to campaigns -- Orders generated from emails -- Average order value -- Top products sold via email -- Customer lifetime value -- Store performance comparison -- Cart abandonment stats -- Promo code usage tracking - -Tools used: `mailchimp_ecommerce_stores_list`, `mailchimp_ecommerce_orders_list`, `mailchimp_ecommerce_products_list`, `mailchimp_ecommerce_promo_codes_list` - ---- - -### Landing Pages & Content - -#### ๐ŸŽฏ Landing Page Grid (`landing-page-grid`) -**Manage Mailchimp landing pages** - -Features: -- All landing pages list -- Filter by published/unpublished status -- Preview thumbnails -- Performance metrics (visits, conversions, conversion rate) -- Quick actions: view, edit, publish, unpublish, delete -- Create new landing page - -Tools used: `mailchimp_landing_pages_list`, `mailchimp_landing_pages_get`, `mailchimp_landing_pages_create`, `mailchimp_landing_pages_publish`, `mailchimp_landing_pages_unpublish`, `mailchimp_landing_pages_delete` - ---- - -#### ๐ŸŽจ Template Gallery (`template-gallery`) -**Email template library** - -Features: -- All saved templates -- Filter by type (user, base, gallery) -- Template preview -- Usage statistics -- Quick actions: use in campaign, edit, duplicate, delete -- Create new template from scratch or HTML -- Import template from URL - -Tools used: `mailchimp_templates_list`, `mailchimp_templates_get`, `mailchimp_templates_create`, `mailchimp_templates_update`, `mailchimp_templates_delete` - ---- - -### Testing & Optimization - -#### ๐Ÿ”ฌ A/B Test Results (`ab-test-results`) -**A/B test campaign analysis** - -Features: -- Test configuration (what was tested: subject, from name, content, send time) -- Variant performance comparison -- Statistical significance calculator -- Winner declaration -- Engagement breakdown per variant -- Recommended next steps -- Export test results - -Tools used: `mailchimp_campaigns_get`, `mailchimp_reports_get` - ---- - -#### ๐Ÿ”Ž Search Results (`search-results`) -**Universal search across Mailchimp account** - -Features: -- Search campaigns by title, subject line -- Search members by email, name -- Search tags -- Filter results by type -- Quick actions from results -- Search history -- Advanced filters - -Tools used: `mailchimp_search_campaigns`, `mailchimp_search_members`, `mailchimp_search_tags` - ---- - -## ๐Ÿ› ๏ธ Tool Reference - -### ๐Ÿ“ง Campaign Tools (15 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_campaigns_list` | List all campaigns with filters (type, status, list, folder) | -| `mailchimp_campaigns_get` | Get details for a specific campaign | -| `mailchimp_campaigns_create` | Create a new campaign (regular, A/B split, RSS, etc.) | -| `mailchimp_campaigns_update` | Update campaign settings, recipients, or tracking | -| `mailchimp_campaigns_delete` | Permanently delete a campaign | -| `mailchimp_campaigns_send` | Send a campaign immediately | -| `mailchimp_campaigns_schedule` | Schedule campaign for future send (supports Timewarp) | -| `mailchimp_campaigns_unschedule` | Unschedule a scheduled campaign | -| `mailchimp_campaigns_pause` | Pause an RSS campaign | -| `mailchimp_campaigns_resume` | Resume a paused RSS campaign | -| `mailchimp_campaigns_replicate` | Duplicate a campaign | -| `mailchimp_campaigns_test` | Send test email to up to 5 addresses | -| `mailchimp_campaigns_get_content` | Get HTML and plain-text content | -| `mailchimp_campaigns_set_content` | Set content (HTML, template, or URL import) | -| `mailchimp_campaigns_get_send_checklist` | Review pre-send checklist | - ---- - -### ๐Ÿ‘ฅ List/Audience Tools (14 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_lists_list` | List all audiences/lists | -| `mailchimp_lists_get` | Get audience details and stats | -| `mailchimp_lists_create` | Create a new audience | -| `mailchimp_lists_update` | Update audience settings | -| `mailchimp_lists_delete` | Delete an audience | -| `mailchimp_lists_batch_subscribe` | Add/update multiple members in one call | -| `mailchimp_lists_segments_list` | List segments in an audience | -| `mailchimp_lists_segments_create` | Create a new segment | -| `mailchimp_lists_segments_update` | Update segment conditions | -| `mailchimp_lists_segments_delete` | Delete a segment | -| `mailchimp_lists_interest_categories_list` | List interest categories (groups) | -| `mailchimp_lists_interest_categories_create` | Create interest category | -| `mailchimp_lists_interests_list` | List interests within a category | -| `mailchimp_lists_growth_history` | Get audience growth history | - ---- - -### ๐Ÿ™‹ Member Tools (12 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_lists_members_list` | List members in an audience | -| `mailchimp_lists_members_get` | Get member details | -| `mailchimp_lists_members_add` | Add a new member to an audience | -| `mailchimp_lists_members_update` | Update member information | -| `mailchimp_lists_members_delete` | Permanently delete a member | -| `mailchimp_lists_members_archive` | Archive (soft delete) a member | -| `mailchimp_lists_members_search` | Search members by query | -| `mailchimp_members_tags_list` | List tags for a member | -| `mailchimp_members_tags_add` | Add tags to a member | -| `mailchimp_members_tags_remove` | Remove tags from a member | -| `mailchimp_members_activity` | Get member activity (opens, clicks) | -| `mailchimp_members_notes` | Get notes for a member | - ---- - -### ๐Ÿ“„ Template Tools (6 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_templates_list` | List all email templates | -| `mailchimp_templates_get` | Get template details and HTML | -| `mailchimp_templates_create` | Create a new template | -| `mailchimp_templates_update` | Update template content | -| `mailchimp_templates_delete` | Delete a template | -| `mailchimp_templates_get_default_content` | Get default content for a template | - ---- - -### โš™๏ธ Automation Tools (10 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_automations_list` | List all automation workflows | -| `mailchimp_automations_get` | Get automation details | -| `mailchimp_automations_pause` | Pause an automation | -| `mailchimp_automations_start` | Start a paused automation | -| `mailchimp_automations_emails_list` | List emails in an automation | -| `mailchimp_automations_emails_get` | Get automation email details | -| `mailchimp_automations_emails_pause` | Pause a specific automation email | -| `mailchimp_automations_emails_start` | Start a paused automation email | -| `mailchimp_automations_subscribers_add` | Add subscriber to automation | -| `mailchimp_automations_subscribers_remove` | Remove subscriber from automation | - ---- - -### ๐Ÿ“Š Report Tools (8 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_reports_list` | List campaign reports | -| `mailchimp_reports_get` | Get detailed campaign report | -| `mailchimp_reports_email_activity` | Get email activity for specific recipients | -| `mailchimp_reports_locations` | Get geographic data (opens by location) | -| `mailchimp_reports_sent_to` | List recipients a campaign was sent to | -| `mailchimp_reports_click_details` | Get click tracking details | -| `mailchimp_reports_opened` | List recipients who opened | -| `mailchimp_reports_unsubscribed` | List recipients who unsubscribed | - ---- - -### ๐ŸŽฏ Landing Page Tools (8 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_landing_pages_list` | List all landing pages | -| `mailchimp_landing_pages_get` | Get landing page details | -| `mailchimp_landing_pages_create` | Create a new landing page | -| `mailchimp_landing_pages_update` | Update landing page content | -| `mailchimp_landing_pages_delete` | Delete a landing page | -| `mailchimp_landing_pages_publish` | Publish a landing page | -| `mailchimp_landing_pages_unpublish` | Unpublish a landing page | -| `mailchimp_landing_pages_content` | Get/set landing page content | - ---- - -### ๐Ÿ›’ E-commerce Tools (28 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_ecommerce_stores_list` | List connected stores | -| `mailchimp_ecommerce_stores_get` | Get store details | -| `mailchimp_ecommerce_stores_create` | Connect a new store | -| `mailchimp_ecommerce_stores_update` | Update store info | -| `mailchimp_ecommerce_stores_delete` | Disconnect a store | -| `mailchimp_ecommerce_products_list` | List products in a store | -| `mailchimp_ecommerce_products_get` | Get product details | -| `mailchimp_ecommerce_products_create` | Add a new product | -| `mailchimp_ecommerce_products_update` | Update product info | -| `mailchimp_ecommerce_products_delete` | Remove a product | -| `mailchimp_ecommerce_variants_list` | List product variants | -| `mailchimp_ecommerce_variants_create` | Add product variant | -| `mailchimp_ecommerce_orders_list` | List orders from a store | -| `mailchimp_ecommerce_orders_get` | Get order details | -| `mailchimp_ecommerce_orders_create` | Record a new order | -| `mailchimp_ecommerce_orders_update` | Update order info | -| `mailchimp_ecommerce_orders_delete` | Delete an order | -| `mailchimp_ecommerce_carts_list` | List abandoned carts | -| `mailchimp_ecommerce_carts_get` | Get cart details | -| `mailchimp_ecommerce_carts_create` | Create a cart record | -| `mailchimp_ecommerce_carts_update` | Update cart | -| `mailchimp_ecommerce_carts_delete` | Delete cart | -| `mailchimp_ecommerce_customers_list` | List customers | -| `mailchimp_ecommerce_customers_get` | Get customer details | -| `mailchimp_ecommerce_customers_create` | Add customer | -| `mailchimp_ecommerce_promo_codes_list` | List promo codes | -| `mailchimp_ecommerce_promo_codes_get` | Get promo code details | -| `mailchimp_ecommerce_promo_codes_create` | Create promo code | - ---- - -### ๐Ÿ” Search & Discovery Tools (3 tools) - -| Tool | Description | -|------|-------------| -| `mailchimp_search_campaigns` | Search campaigns by keyword | -| `mailchimp_search_members` | Search members across all lists | -| `mailchimp_search_tags` | Search tags across account | - ---- - -## ๐Ÿ’ก Usage Examples - -### Example 1: Create and Send a Campaign +### Add a Subscriber ```typescript -// 1. Create campaign -const campaign = await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_campaigns_create", - arguments: { - type: "regular", - recipients: { - list_id: "abc123" - }, - settings: { - subject_line: "๐ŸŽ‰ New Product Launch!", - preview_text: "Check out our latest products", - title: "Product Launch Campaign - Q1 2024", - from_name: "MyBrand", - reply_to: "hello@mybrand.com" - } +{ + "list_id": "abc123", + "email_address": "subscriber@example.com", + "status": "subscribed", + "merge_fields": { + "FNAME": "John", + "LNAME": "Doe" } -}); - -// 2. Set content -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_campaigns_set_content", - arguments: { - campaign_id: campaign.id, - html: "

Welcome!

Check out our new products...

" - } -}); - -// 3. Send test -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_campaigns_test", - arguments: { - campaign_id: campaign.id, - test_emails: ["test@mybrand.com"], - send_type: "html" - } -}); - -// 4. Send campaign -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_campaigns_send", - arguments: { - campaign_id: campaign.id - } -}); +} ``` ---- - -### Example 2: Add Member with Tags +### Get Campaign Report ```typescript -// Add member to list -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_lists_members_add", - arguments: { - list_id: "abc123", - email_address: "customer@example.com", - status: "subscribed", - merge_fields: { - FNAME: "Jane", - LNAME: "Doe" - } - } -}); - -// Add tags -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_members_tags_add", - arguments: { - list_id: "abc123", - email_address: "customer@example.com", - tags: [ - { name: "VIP", status: "active" }, - { name: "Product-Launch-2024", status: "active" } - ] - } -}); +{ + "campaign_id": "abc123" +} ``` ---- +## ๐Ÿงช Testing -### Example 3: Create Automated Welcome Series - -```typescript -// Create automation -const automation = await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_automations_create", - arguments: { - recipients: { - list_id: "abc123" - }, - trigger_settings: { - workflow_type: "emailAdded" - }, - settings: { - title: "Welcome Series", - from_name: "MyBrand", - reply_to: "hello@mybrand.com" - } - } -}); - -// Automation emails are managed via the API or UI -// Start the automation -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_automations_start", - arguments: { - workflow_id: automation.id - } -}); +```bash +npm run typecheck # TypeScript type checking +npm test # Run tests (if configured) ``` ---- - -### Example 4: Track E-commerce Order - -```typescript -// Record an order -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_ecommerce_orders_create", - arguments: { - store_id: "mystore", - order: { - id: "order_12345", - customer: { - id: "customer_abc", - email_address: "customer@example.com", - opt_in_status: true - }, - currency_code: "USD", - order_total: 99.99, - lines: [ - { - id: "line_1", - product_id: "prod_123", - product_variant_id: "var_456", - quantity: 2, - price: 49.99 - } - ] - } - } -}); -``` - ---- - -### Example 5: Analyze Campaign Performance - -```typescript -// Get campaign report -const report = await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_reports_get", - arguments: { - campaign_id: "campaign_xyz" - } -}); - -console.log(`Open Rate: ${(report.opens.open_rate * 100).toFixed(2)}%`); -console.log(`Click Rate: ${(report.clicks.click_rate * 100).toFixed(2)}%`); - -// Get click details -const clicks = await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_reports_click_details", - arguments: { - campaign_id: "campaign_xyz" - } -}); - -// Most clicked link -const topLink = clicks.urls_clicked[0]; -console.log(`Most clicked: ${topLink.url} (${topLink.total_clicks} clicks)`); -``` - ---- - ## ๐Ÿ—๏ธ Architecture ``` -mailchimp-mcp-server/ +mailchimp/ โ”œโ”€โ”€ src/ -โ”‚ โ”œโ”€โ”€ index.ts # MCP server entry point +โ”‚ โ”œโ”€โ”€ index.ts # MCP server entry point โ”‚ โ”œโ”€โ”€ clients/ -โ”‚ โ”‚ โ””โ”€โ”€ mailchimp.ts # Mailchimp API client +โ”‚ โ”‚ โ””โ”€โ”€ mailchimp.ts # Mailchimp API client +โ”‚ โ”œโ”€โ”€ tools/ +โ”‚ โ”‚ โ”œโ”€โ”€ campaigns-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ lists-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ members-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ automations-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ templates-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ reports-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ landing-pages-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ ecommerce-tools.ts +โ”‚ โ”‚ โ”œโ”€โ”€ tags-tools.ts +โ”‚ โ”‚ โ””โ”€โ”€ search-tools.ts โ”‚ โ”œโ”€โ”€ types/ -โ”‚ โ”‚ โ””โ”€โ”€ index.ts # TypeScript type definitions -โ”‚ โ”œโ”€โ”€ tools/ # Tool implementations (104 tools) -โ”‚ โ”‚ โ”œโ”€โ”€ campaigns-tools.ts # 15 campaign tools -โ”‚ โ”‚ โ”œโ”€โ”€ lists-tools.ts # 14 list/audience tools -โ”‚ โ”‚ โ”œโ”€โ”€ members-tools.ts # 12 member tools -โ”‚ โ”‚ โ”œโ”€โ”€ templates-tools.ts # 6 template tools -โ”‚ โ”‚ โ”œโ”€โ”€ automations-tools.ts # 10 automation tools -โ”‚ โ”‚ โ”œโ”€โ”€ reports-tools.ts # 8 report tools -โ”‚ โ”‚ โ”œโ”€โ”€ landing-pages-tools.ts # 8 landing page tools -โ”‚ โ”‚ โ”œโ”€โ”€ ecommerce-tools.ts # 28 e-commerce tools -โ”‚ โ”‚ โ”œโ”€โ”€ tags-tools.ts # 1 tag tool -โ”‚ โ”‚ โ””โ”€โ”€ search-tools.ts # 2 search tools +โ”‚ โ”‚ โ””โ”€โ”€ index.ts # TypeScript type definitions โ”‚ โ””โ”€โ”€ ui/ -โ”‚ โ””โ”€โ”€ react-app/ # React MCP apps (15 apps) +โ”‚ โ””โ”€โ”€ react-app/ # 15+ React applications โ”‚ โ”œโ”€โ”€ campaign-dashboard/ -โ”‚ โ”œโ”€โ”€ campaign-detail/ -โ”‚ โ”œโ”€โ”€ campaign-builder/ -โ”‚ โ”œโ”€โ”€ audience-dashboard/ -โ”‚ โ”œโ”€โ”€ audience-grid/ -โ”‚ โ”œโ”€โ”€ member-detail/ -โ”‚ โ”œโ”€โ”€ tag-manager/ -โ”‚ โ”œโ”€โ”€ automation-dashboard/ -โ”‚ โ”œโ”€โ”€ automation-detail/ -โ”‚ โ”œโ”€โ”€ report-dashboard/ -โ”‚ โ”œโ”€โ”€ report-detail/ -โ”‚ โ”œโ”€โ”€ growth-chart/ -โ”‚ โ”œโ”€โ”€ ecommerce-dashboard/ -โ”‚ โ”œโ”€โ”€ landing-page-grid/ -โ”‚ โ”œโ”€โ”€ template-gallery/ -โ”‚ โ”œโ”€โ”€ ab-test-results/ -โ”‚ โ””โ”€โ”€ search-results/ -โ”œโ”€โ”€ scripts/ -โ”‚ โ””โ”€โ”€ build-apps.js # React app bundler +โ”‚ โ”œโ”€โ”€ audience-manager/ +โ”‚ โ”œโ”€โ”€ subscriber-grid/ +โ”‚ โ””โ”€โ”€ ... (12+ more apps) +โ”œโ”€โ”€ dist/ # Compiled JavaScript โ”œโ”€โ”€ package.json โ”œโ”€โ”€ tsconfig.json โ””โ”€โ”€ README.md ``` ---- +## ๐Ÿ“„ License -## ๐Ÿ”ง Development - -### Build - -```bash -npm run build -``` - -Compiles TypeScript and bundles all React apps. - -### Development Mode - -```bash -npm run dev -``` - -Runs TypeScript in watch mode. - -### Type Checking - -```bash -npm run typecheck -``` - ---- - -## ๐Ÿ“š API Documentation - -This MCP server covers the Mailchimp Marketing API v3. For full API documentation: - -- [Mailchimp Marketing API Reference](https://mailchimp.com/developer/marketing/api/) -- [Campaign API Docs](https://mailchimp.com/developer/marketing/api/campaigns/) -- [Lists API Docs](https://mailchimp.com/developer/marketing/api/lists/) -- [Automation API Docs](https://mailchimp.com/developer/marketing/api/automation/) -- [E-commerce API Docs](https://mailchimp.com/developer/marketing/api/ecommerce-stores/) - ---- - -## โšก Rate Limiting - -Mailchimp enforces rate limits on API requests (typically 10 requests/second). This MCP server handles rate limiting automatically with exponential backoff and retry logic. - ---- - -## ๐Ÿ”’ Security Best Practices - -1. **Never commit API keys** โ€” use environment variables -2. **Rotate API keys** regularly -3. **Use read-only keys** when possible (Mailchimp doesn't support this yet) -4. **Monitor API usage** in your Mailchimp account -5. **Restrict MCP access** to trusted users/environments - ---- - -## ๐Ÿ› Troubleshooting - -### "Error: MAILCHIMP_API_KEY environment variable is required" - -Set your API key: -```bash -export MAILCHIMP_API_KEY="your_key-us19" -``` - -### "Invalid API Key" - -Check: -- API key format includes datacenter (e.g., `-us19`) -- API key is active in your Mailchimp account -- No extra spaces or quotes in the environment variable - -### "Rate Limit Exceeded" - -The server will automatically retry with exponential backoff. If persistent: -- Reduce request frequency -- Check Mailchimp account limits -- Consider upgrading Mailchimp plan - -### "List Not Found" - -Ensure you're using the correct `list_id`. Get list IDs via: -```typescript -await use_mcp_tool({ - server_name: "mailchimp", - tool_name: "mailchimp_lists_list" -}); -``` - ---- - -## ๐Ÿ“Š Comparison: Mailchimp MCP vs. GoHighLevel MCP - -| Metric | Mailchimp MCP | GoHighLevel MCP | -|--------|---------------|-----------------| -| **Tools** | 104 | 474 | -| **React Apps** | 15 | 65 | -| **API Coverage** | Mailchimp Marketing API v3 | GoHighLevel API v2 | -| **Focus** | Email marketing, automation, e-commerce | CRM, marketing automation, sales funnels | -| **Complexity** | Medium | High | -| **Use Case** | Email campaigns, newsletters, e-commerce stores | Agency/SaaS white-label platform | - -Both servers provide **comprehensive MCP coverage** of their respective platforms with rich UI apps and complete API tool sets. - ---- +MIT ## ๐Ÿค Contributing -Contributions welcome! Please: - -1. Fork the repository -2. Create a feature branch -3. Add tests for new tools -4. Submit a pull request - ---- - -## ๐Ÿ“„ License - -MIT License - see LICENSE file for details - ---- - -## ๐Ÿ™ Acknowledgments - -- Built with the [Model Context Protocol SDK](https://modelcontextprotocol.io) -- Powered by [Mailchimp Marketing API v3](https://mailchimp.com/developer/) -- Part of the [MCPEngine](https://github.com/BusyBee3333/mcpengine) project - ---- +Contributions welcome! Please read our contributing guidelines and submit PRs. ## ๐Ÿ“ž Support -- **Issues:** [GitHub Issues](https://github.com/BusyBee3333/mcpengine/issues) -- **Documentation:** [MCPEngine Docs](https://github.com/BusyBee3333/mcpengine) -- **Mailchimp API:** [Mailchimp Developer Docs](https://mailchimp.com/developer/) +- [Mailchimp API Documentation](https://mailchimp.com/developer/marketing/api/) +- [MCP Documentation](https://modelcontextprotocol.io/) +- Issues: GitHub Issues + +## ๐Ÿ”— Related + +- [Mailchimp Marketing API v3.0](https://mailchimp.com/developer/marketing/api/) +- [Model Context Protocol](https://modelcontextprotocol.io/) +- [MCPEngine](https://github.com/BusyBee3333/mcpengine) --- -**Made with โค๏ธ by the MCPEngine team** +**Built with โค๏ธ for the MCP community** diff --git a/servers/mailchimp/src/ui/react-app/ab-test-results/app.tsx b/servers/mailchimp/src/ui/react-app/ab-test-results/app.tsx index 08782b9..a1b7a3f 100644 --- a/servers/mailchimp/src/ui/react-app/ab-test-results/app.tsx +++ b/servers/mailchimp/src/ui/react-app/ab-test-results/app.tsx @@ -1,284 +1,21 @@ -import React, { useState, useEffect } from 'react'; -import { createRoot } from 'react-dom/client'; -import { useApp } from '@modelcontextprotocol/ext-apps/react'; +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; -function App() { - const app = useApp(); - const [campaignId, setCampaignId] = useState(''); - const [campaign, setCampaign] = useState(null); - const [report, setReport] = useState(null); - const [subReports, setSubReports] = useState([]); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - - useEffect(() => { - const urlParams = new URLSearchParams(window.location.search); - const id = urlParams.get('id'); - if (id) { - setCampaignId(id); - loadABTestResults(id); - } - }, []); - - async function loadABTestResults(id: string) { - try { - setLoading(true); - setError(null); - - const [campaignRes, reportRes, subReportsRes] = await Promise.all([ - app.callTool('mailchimp_campaigns_get', { campaign_id: id }), - app.callTool('mailchimp_reports_get', { campaign_id: id }), - app.callTool('mailchimp_reports_get_sub_reports', { campaign_id: id }).catch(() => null) - ]); - - const campaignData = JSON.parse(campaignRes.content[0].text); - const reportData = JSON.parse(reportRes.content[0].text); - - setCampaign(campaignData); - setReport(reportData); - - if (subReportsRes) { - const subReportsData = JSON.parse(subReportsRes.content[0].text); - setSubReports(subReportsData.reports || []); - } - } catch (err: any) { - setError(err.message || 'Failed to load A/B test results'); - } finally { - setLoading(false); - } - } - - if (loading) { - return ( -
-

Loading A/B test results...

-
- ); - } - - if (error) { - return ( -
-

Error

-

{error}

- -
- ); - } - - if (!campaign) { - return ( -
-

Enter an A/B test campaign ID:

- setCampaignId(e.target.value)} - placeholder="Campaign ID" - style={{ - padding: 8, - background: '#1e1e1e', - color: '#e0e0e0', - border: '1px solid #333', - borderRadius: 4, - marginRight: 8 - }} - /> - -
- ); - } - - const isABTest = campaign.type === 'absplit'; - - if (!isABTest) { - return ( -
-

Not an A/B Test Campaign

-

This campaign (type: {campaign.type}) is not an A/B split test.

-
- ); - } - - // Determine winner - let winner = null; - let winnerLetter = ''; - if (subReports.length > 0) { - const sortedByOpenRate = [...subReports].sort((a, b) => - (b.opens?.open_rate || 0) - (a.opens?.open_rate || 0) - ); - winner = sortedByOpenRate[0]; - const winnerIndex = subReports.findIndex(r => r.id === winner.id); - winnerLetter = String.fromCharCode(65 + winnerIndex); // A, B, C, etc. - } +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; return ( -
-
-

๐Ÿงช A/B Test Results

-
{campaign.settings?.title || 'Untitled Campaign'}
- - {winner && ( -
-
๐Ÿ†
-
- Winner: Variation {winnerLetter} -
-
- {((winner.opens?.open_rate || 0) * 100).toFixed(1)}% open rate -
-
- )} - - {/* A/B Test Comparison */} - {subReports.length > 0 && ( -
-

Variation Comparison

-
- {subReports.map((subReport, idx) => { - const letter = String.fromCharCode(65 + idx); - const isWinner = winner && subReport.id === winner.id; - - return ( -
- {isWinner && ( -
- Winner -
- )} - -

- Variation {letter} -

- -
-
Emails Sent
-
- {(subReport.emails_sent || 0).toLocaleString()} -
-
- -
-
Open Rate
-
- {((subReport.opens?.open_rate || 0) * 100).toFixed(1)}% -
-
- {(subReport.opens?.unique_opens || 0).toLocaleString()} opens -
-
- -
-
Click Rate
-
- {((subReport.clicks?.click_rate || 0) * 100).toFixed(1)}% -
-
- {(subReport.clicks?.unique_clicks || 0).toLocaleString()} clicks -
-
- -
-
Subject Line
-
- {subReport.campaign_title || 'โ€”'} -
-
-
- ); - })} -
-
- )} - - {/* Overall Stats */} - {report && ( -
-

Overall Performance

-
-
-
Total Sent
-
- {(report.emails_sent || 0).toLocaleString()} -
-
-
-
Overall Open Rate
-
- {((report.opens?.open_rate || 0) * 100).toFixed(1)}% -
-
-
-
Overall Click Rate
-
- {((report.clicks?.click_rate || 0) * 100).toFixed(1)}% -
-
-
-
- )} - -
- +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

); } - -const root = createRoot(document.getElementById('root')!); -root.render(); diff --git a/servers/mailchimp/src/ui/react-app/ab-test-results/index.html b/servers/mailchimp/src/ui/react-app/ab-test-results/index.html index da7bfae..99019ce 100644 --- a/servers/mailchimp/src/ui/react-app/ab-test-results/index.html +++ b/servers/mailchimp/src/ui/react-app/ab-test-results/index.html @@ -1,12 +1,13 @@ - - - - A/B Test Results - - -
- - + + + + ab-test-results - Mailchimp MCP + + + +
+ + diff --git a/servers/mailchimp/src/ui/react-app/ab-test-results/vite.config.ts b/servers/mailchimp/src/ui/react-app/ab-test-results/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/ab-test-results/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/audience-manager/App.tsx b/servers/mailchimp/src/ui/react-app/audience-manager/App.tsx new file mode 100644 index 0000000..1f7cf7f --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/audience-manager/App.tsx @@ -0,0 +1,136 @@ +import React, { useState, useEffect } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +interface List { + id: string; + name: string; + stats: { + member_count: number; + unsubscribe_count: number; + cleaned_count: number; + open_rate: number; + click_rate: number; + }; + date_created: string; +} + +export default function AudienceManager() { + const [lists, setLists] = useState([]); + const [loading, setLoading] = useState(true); + const [selectedList, setSelectedList] = useState(null); + + const client = createMCPClient(); + + useEffect(() => { + loadLists(); + }, []); + + const loadLists = async () => { + setLoading(true); + try { + const result = await client.callTool('mailchimp_lists_list', { count: 100 }); + setLists(result.lists || []); + } catch (error) { + console.error('Failed to load lists:', error); + } finally { + setLoading(false); + } + }; + + const totalMembers = lists.reduce((sum, list) => sum + list.stats.member_count, 0); + const avgOpenRate = lists.length > 0 + ? lists.reduce((sum, list) => sum + list.stats.open_rate, 0) / lists.length + : 0; + + return ( +
+
+
+

+ Audience Manager +

+ +
+ + {/* Stats Overview */} +
+
+
Total Lists
+
{lists.length}
+
+
+
Total Subscribers
+
{totalMembers.toLocaleString()}
+
+
+
Avg Open Rate
+
{avgOpenRate.toFixed(1)}%
+
+
+
Total Unsubscribes
+
+ {lists.reduce((sum, l) => sum + l.stats.unsubscribe_count, 0).toLocaleString()} +
+
+
+ + {/* Lists Grid */} + {loading ? ( +
Loading audiences...
+ ) : ( +
+ {lists.map((list) => ( +
setSelectedList(list.id)} + > +
+

{list.name}

+ + {new Date(list.date_created).toLocaleDateString()} + +
+ +
+
+
Subscribers
+
{list.stats.member_count.toLocaleString()}
+
+
+
Unsubscribed
+
+ {list.stats.unsubscribe_count.toLocaleString()} +
+
+
+
Open Rate
+
{list.stats.open_rate.toFixed(1)}%
+
+
+
Click Rate
+
{list.stats.click_rate.toFixed(1)}%
+
+
+ +
+ + +
+
+ ))} +
+ )} +
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/audience-manager/index.html b/servers/mailchimp/src/ui/react-app/audience-manager/index.html new file mode 100644 index 0000000..07fe849 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/audience-manager/index.html @@ -0,0 +1,13 @@ + + + + + + Audience Manager - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/audience-manager/vite.config.ts b/servers/mailchimp/src/ui/react-app/audience-manager/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/audience-manager/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/automation-flow/App.tsx b/servers/mailchimp/src/ui/react-app/automation-flow/App.tsx new file mode 100644 index 0000000..61f0e97 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/automation-flow/App.tsx @@ -0,0 +1,67 @@ +import React, { useState, useEffect } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +interface Automation { + id: string; + settings: { title: string }; + status: string; + emails_sent: number; + create_time: string; +} + +export default function AutomationFlow() { + const [automations, setAutomations] = useState([]); + const [loading, setLoading] = useState(true); + const client = createMCPClient(); + + useEffect(() => { + loadAutomations(); + }, []); + + const loadAutomations = async () => { + setLoading(true); + try { + const result = await client.callTool('mailchimp_automations_list', { count: 100 }); + setAutomations(result.automations || []); + } catch (error) { + console.error('Failed to load automations:', error); + } finally { + setLoading(false); + } + }; + + const statusColors: Record = { + save: 'bg-gray-600', + paused: 'bg-yellow-600', + sending: 'bg-green-600' + }; + + return ( +
+
+

+ Automation Flow +

+ {loading ? ( +
Loading...
+ ) : ( +
+ {automations.map((auto) => ( +
+
+

{auto.settings.title}

+ + {auto.status} + +
+
+ Emails sent: {auto.emails_sent.toLocaleString()} +
+
+ ))} +
+ )} +
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/automation-flow/index.html b/servers/mailchimp/src/ui/react-app/automation-flow/index.html new file mode 100644 index 0000000..f433ac6 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/automation-flow/index.html @@ -0,0 +1,13 @@ + + + + + + Automation Flow - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/automation-flow/vite.config.ts b/servers/mailchimp/src/ui/react-app/automation-flow/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/automation-flow/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/campaign-analytics/App.tsx b/servers/mailchimp/src/ui/react-app/campaign-analytics/App.tsx new file mode 100644 index 0000000..395dc2a --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/campaign-analytics/App.tsx @@ -0,0 +1,106 @@ +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +interface Report { + id: string; + campaign_title: string; + emails_sent: number; + opens: { opens_total: number; unique_opens: number; open_rate: number }; + clicks: { clicks_total: number; unique_clicks: number; click_rate: number }; + bounces: { hard_bounces: number; soft_bounces: number }; + unsubscribed: number; +} + +export default function CampaignAnalytics() { + const [report, setReport] = useState(null); + const [campaignId, setCampaignId] = useState(''); + const [loading, setLoading] = useState(false); + const client = createMCPClient(); + + const loadReport = async () => { + if (!campaignId) return; + setLoading(true); + try { + const result = await client.callTool('mailchimp_reports_get', { campaign_id: campaignId }); + setReport(result); + } catch (error) { + console.error('Failed to load report:', error); + } finally { + setLoading(false); + } + }; + + return ( +
+
+

+ Campaign Analytics +

+ +
+ setCampaignId(e.target.value)} + className="px-4 py-2 bg-gray-800 border border-gray-700 rounded-lg focus:ring-2 focus:ring-yellow-500 outline-none" + /> + +
+ + {loading ? ( +
Loading analytics...
+ ) : report ? ( +
+
+

{report.campaign_title}

+

Campaign ID: {report.id}

+
+ +
+
+
Emails Sent
+
{report.emails_sent.toLocaleString()}
+
+
+
Open Rate
+
{report.opens.open_rate.toFixed(1)}%
+
{report.opens.unique_opens.toLocaleString()} unique
+
+
+
Click Rate
+
{report.clicks.click_rate.toFixed(1)}%
+
{report.clicks.unique_clicks.toLocaleString()} unique
+
+
+
Unsubscribes
+
{report.unsubscribed.toLocaleString()}
+
+
+ +
+

Bounce Details

+
+
+
Hard Bounces
+
{report.bounces.hard_bounces.toLocaleString()}
+
+
+
Soft Bounces
+
{report.bounces.soft_bounces.toLocaleString()}
+
+
+
+
+ ) : ( +
Enter a campaign ID to view analytics
+ )} +
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/campaign-analytics/index.html b/servers/mailchimp/src/ui/react-app/campaign-analytics/index.html new file mode 100644 index 0000000..6ed767e --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/campaign-analytics/index.html @@ -0,0 +1,13 @@ + + + + + + campaign-analytics - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/campaign-analytics/vite.config.ts b/servers/mailchimp/src/ui/react-app/campaign-analytics/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/campaign-analytics/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/campaign-dashboard/app.tsx b/servers/mailchimp/src/ui/react-app/campaign-dashboard/app.tsx index e3ea528..7d368a4 100644 --- a/servers/mailchimp/src/ui/react-app/campaign-dashboard/app.tsx +++ b/servers/mailchimp/src/ui/react-app/campaign-dashboard/app.tsx @@ -1,195 +1,184 @@ import React, { useState, useEffect } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; -interface CampaignDashboardProps { - useApp: any; -} - -interface CampaignStats { - total_campaigns: number; - sent_today: number; - avg_open_rate: number; - avg_click_rate: number; - recent_campaigns: Array<{ - id: string; +interface Campaign { + id: string; + settings: { + subject_line: string; title: string; - status: string; - send_time?: string; - emails_sent: number; - open_rate?: number; - click_rate?: number; - }>; + from_name: string; + }; + status: string; + type: string; + send_time?: string; + emails_sent?: number; } -export default function CampaignDashboard({ useApp }: CampaignDashboardProps) { - const { callTool } = useApp(); - const [stats, setStats] = useState(null); +export default function CampaignDashboard() { + const [campaigns, setCampaigns] = useState([]); const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); + const [filter, setFilter] = useState('all'); + const [searchQuery, setSearchQuery] = useState(''); + + const client = createMCPClient(); useEffect(() => { - loadDashboard(); - }, []); + loadCampaigns(); + }, [filter]); - async function loadDashboard() { + const loadCampaigns = async () => { + setLoading(true); try { - setLoading(true); - setError(null); - - // Fetch recent campaigns - const campaigns = await callTool('mailchimp_campaigns_list', { - count: 10, - sort_field: 'send_time', - sort_dir: 'DESC' - }); - - // Fetch reports for sent campaigns - const reports = await callTool('mailchimp_reports_list', { - count: 10, - sort_field: 'send_time', - sort_dir: 'DESC' - }); - - // Calculate stats - const sentToday = campaigns.campaigns?.filter((c: any) => { - if (!c.send_time) return false; - const sendDate = new Date(c.send_time); - const today = new Date(); - return sendDate.toDateString() === today.toDateString(); - }).length || 0; - - const avgOpenRate = reports.reports?.length > 0 - ? reports.reports.reduce((sum: number, r: any) => sum + (r.opens?.open_rate || 0), 0) / reports.reports.length - : 0; - - const avgClickRate = reports.reports?.length > 0 - ? reports.reports.reduce((sum: number, r: any) => sum + (r.clicks?.click_rate || 0), 0) / reports.reports.length - : 0; - - setStats({ - total_campaigns: campaigns.total_items || 0, - sent_today: sentToday, - avg_open_rate: avgOpenRate, - avg_click_rate: avgClickRate, - recent_campaigns: campaigns.campaigns?.map((c: any) => ({ - id: c.id, - title: c.settings?.title || c.settings?.subject_line || 'Untitled', - status: c.status, - send_time: c.send_time, - emails_sent: c.emails_sent, - open_rate: reports.reports?.find((r: any) => r.id === c.id)?.opens?.open_rate, - click_rate: reports.reports?.find((r: any) => r.id === c.id)?.clicks?.click_rate - })) || [] - }); - } catch (err: any) { - setError(err.message || 'Failed to load dashboard'); + const params: any = { count: 50, sort_field: 'create_time', sort_dir: 'DESC' }; + if (filter !== 'all') { + params.status = filter; + } + const result = await client.callTool('mailchimp_campaigns_list', params); + setCampaigns(result.campaigns || []); + } catch (error: any) { + console.error('Failed to load campaigns:', error); } finally { setLoading(false); } - } + }; - if (loading) { - return ( -
-

Loading campaign dashboard...

-
- ); - } + const sendCampaign = async (campaignId: string) => { + if (!confirm('Are you sure you want to send this campaign?')) return; + try { + await client.callTool('mailchimp_campaigns_send', { campaign_id: campaignId }); + loadCampaigns(); + } catch (error: any) { + alert('Failed to send campaign: ' + error.message); + } + }; - if (error) { - return ( -
-

Error

-

{error}

- -
- ); - } + const filteredCampaigns = campaigns.filter(c => + c.settings.title.toLowerCase().includes(searchQuery.toLowerCase()) || + c.settings.subject_line.toLowerCase().includes(searchQuery.toLowerCase()) + ); - if (!stats) { - return
No data available
; - } + const statusColors: Record = { + save: 'bg-gray-600', + paused: 'bg-yellow-600', + schedule: 'bg-blue-600', + sending: 'bg-green-600', + sent: 'bg-green-800' + }; return ( -
-

๐Ÿ“ง Campaign Dashboard

- - {/* Summary Cards */} -
-
-
Total Campaigns
-
{stats.total_campaigns}
+
+
+ {/* Header */} +
+

+ Campaign Dashboard +

+
-
-
Sent Today
-
{stats.sent_today}
-
-
-
Avg Open Rate
-
{(stats.avg_open_rate * 100).toFixed(1)}%
-
-
-
Avg Click Rate
-
{(stats.avg_click_rate * 100).toFixed(1)}%
-
-
- {/* Recent Campaigns */} -

Recent Campaigns

-
- - - - - - - - - - - - - {stats.recent_campaigns.map((campaign) => ( - - - - - - - - + {/* Filters */} +
+ setSearchQuery(e.target.value)} + className="px-4 py-2 bg-gray-800 border border-gray-700 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none" + /> + +
+ + {/* Stats */} +
+
+
Total Campaigns
+
{campaigns.length}
+
+
+
Sent
+
+ {campaigns.filter(c => c.status === 'sent').length} +
+
+
+
Scheduled
+
+ {campaigns.filter(c => c.status === 'schedule').length} +
+
+
+
Drafts
+
+ {campaigns.filter(c => c.status === 'save').length} +
+
+
+ + {/* Campaign List */} + {loading ? ( +
Loading campaigns...
+ ) : ( +
+ {filteredCampaigns.map((campaign) => ( +
+
+
+
+

{campaign.settings.title}

+ + {campaign.status} + + + {campaign.type} + +
+

+ Subject: {campaign.settings.subject_line} +

+

+ From: {campaign.settings.from_name} + {campaign.send_time && ` โ€ข Sent: ${new Date(campaign.send_time).toLocaleString()}`} + {campaign.emails_sent && ` โ€ข Recipients: ${campaign.emails_sent.toLocaleString()}`} +

+
+
+ {campaign.status === 'save' && ( + + )} + +
+
+
))} -
-
CampaignStatusSentEmailsOpen RateClick Rate
{campaign.title} - - {campaign.status} - - {campaign.send_time ? new Date(campaign.send_time).toLocaleDateString() : '-'}{campaign.emails_sent.toLocaleString()}{campaign.open_rate ? `${(campaign.open_rate * 100).toFixed(1)}%` : '-'}{campaign.click_rate ? `${(campaign.click_rate * 100).toFixed(1)}%` : '-'}
-
- -
- +
+ )}
); } - -// Text fallback for non-UI contexts -export const textFallback = ` -๐Ÿ“ง MAILCHIMP CAMPAIGN DASHBOARD - -This app provides: -- Real-time campaign statistics -- Average open and click rates -- Recent campaign performance table -- Daily send tracking - -Use mailchimp_campaigns_list and mailchimp_reports_list tools to access data programmatically. -`; diff --git a/servers/mailchimp/src/ui/react-app/campaign-dashboard/index.html b/servers/mailchimp/src/ui/react-app/campaign-dashboard/index.html index 2088c65..cdb994a 100644 --- a/servers/mailchimp/src/ui/react-app/campaign-dashboard/index.html +++ b/servers/mailchimp/src/ui/react-app/campaign-dashboard/index.html @@ -1,12 +1,13 @@ - - - - Campaign Dashboard - - -
- - + + + + Campaign Dashboard - Mailchimp MCP + + + +
+ + diff --git a/servers/mailchimp/src/ui/react-app/campaign-dashboard/vite.config.ts b/servers/mailchimp/src/ui/react-app/campaign-dashboard/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/campaign-dashboard/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/content-manager/App.tsx b/servers/mailchimp/src/ui/react-app/content-manager/App.tsx new file mode 100644 index 0000000..a1b7a3f --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/content-manager/App.tsx @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; + + return ( +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

+
+
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/content-manager/index.html b/servers/mailchimp/src/ui/react-app/content-manager/index.html new file mode 100644 index 0000000..ead2b7c --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/content-manager/index.html @@ -0,0 +1,13 @@ + + + + + + content-manager - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/content-manager/vite.config.ts b/servers/mailchimp/src/ui/react-app/content-manager/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/content-manager/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/app.tsx b/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/app.tsx index bc16ae7..a1b7a3f 100644 --- a/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/app.tsx +++ b/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/app.tsx @@ -1,226 +1,21 @@ -import React, { useState, useEffect } from 'react'; -import { createRoot } from 'react-dom/client'; -import { useApp } from '@modelcontextprotocol/ext-apps/react'; +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; -function App() { - const app = useApp(); - const [stores, setStores] = useState([]); - const [orders, setOrders] = useState([]); - const [products, setProducts] = useState([]); - const [selectedStoreId, setSelectedStoreId] = useState(''); - const [loading, setLoading] = useState(true); - - useEffect(() => { - loadData(); - }, []); - - async function loadData() { - try { - setLoading(true); - const storesRes = await app.callTool('mailchimp_ecommerce_stores_list', { count: 50 }); - const storesData = JSON.parse(storesRes.content[0].text); - setStores(storesData.stores || []); - - if (storesData.stores?.length > 0) { - const firstStoreId = storesData.stores[0].id; - setSelectedStoreId(firstStoreId); - await loadStoreData(firstStoreId); - } - } catch (err: any) { - console.error('Failed to load data:', err); - } finally { - setLoading(false); - } - } - - async function loadStoreData(storeId: string) { - try { - const [ordersRes, productsRes] = await Promise.all([ - app.callTool('mailchimp_ecommerce_orders_list', { store_id: storeId, count: 20 }).catch(() => null), - app.callTool('mailchimp_ecommerce_products_list', { store_id: storeId, count: 20 }).catch(() => null) - ]); - - if (ordersRes) { - const ordersData = JSON.parse(ordersRes.content[0].text); - setOrders(ordersData.orders || []); - } - - if (productsRes) { - const productsData = JSON.parse(productsRes.content[0].text); - setProducts(productsData.products || []); - } - } catch (err: any) { - console.error('Failed to load store data:', err); - } - } - - useEffect(() => { - if (selectedStoreId) { - loadStoreData(selectedStoreId); - } - }, [selectedStoreId]); - - if (loading) { - return ( -
-

Loading e-commerce data...

-
- ); - } - - const totalRevenue = orders.reduce((sum, order) => sum + parseFloat(order.order_total || 0), 0); - const avgOrderValue = orders.length > 0 ? totalRevenue / orders.length : 0; +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; return ( -
-
-
-

๐Ÿ›’ E-commerce Dashboard

- +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

- - {stores.length > 0 && ( -
- - -
- )} - - {/* Summary Cards */} -
-
-
Total Stores
-
{stores.length}
-
-
-
Total Revenue
-
- ${totalRevenue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} -
-
-
-
Total Orders
-
{orders.length}
-
-
-
Avg Order Value
-
- ${avgOrderValue.toFixed(2)} -
-
-
- - {/* Top Products */} - {products.length > 0 && ( -
-

Top Products

-
- - - - - - - - - - {products.slice(0, 10).map(product => ( - - - - - - ))} - -
ProductPriceVariants
-
{product.title}
-
{product.id}
-
- ${parseFloat(product.variants?.[0]?.price || 0).toFixed(2)} - {product.variants?.length || 0}
-
-
- )} - - {/* Recent Orders */} - {orders.length > 0 && ( -
-

Recent Orders

-
- - - - - - - - - - - - {orders.slice(0, 10).map(order => ( - - - - - - - - ))} - -
Order IDCustomerTotalStatusDate
{order.id}{order.customer?.first_name} {order.customer?.last_name} - ${parseFloat(order.order_total || 0).toFixed(2)} - - - {order.financial_status || 'pending'} - - - {order.processed_at_foreign ? new Date(order.processed_at_foreign).toLocaleDateString() : 'โ€”'} -
-
-
- )} - - {stores.length === 0 && ( -
-

No e-commerce stores connected

-
- )}
); } - -const root = createRoot(document.getElementById('root')!); -root.render(); diff --git a/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/index.html b/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/index.html index be1f6ba..5c1416a 100644 --- a/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/index.html +++ b/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/index.html @@ -1,12 +1,13 @@ - - - - E-commerce Dashboard - - -
- - + + + + ecommerce-dashboard - Mailchimp MCP + + + +
+ + diff --git a/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/vite.config.ts b/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/ecommerce-dashboard/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/email-preview/App.tsx b/servers/mailchimp/src/ui/react-app/email-preview/App.tsx new file mode 100644 index 0000000..a1b7a3f --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/email-preview/App.tsx @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; + + return ( +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

+
+
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/email-preview/index.html b/servers/mailchimp/src/ui/react-app/email-preview/index.html new file mode 100644 index 0000000..cb91b99 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/email-preview/index.html @@ -0,0 +1,13 @@ + + + + + + email-preview - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/email-preview/vite.config.ts b/servers/mailchimp/src/ui/react-app/email-preview/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/email-preview/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/growth-chart/app.tsx b/servers/mailchimp/src/ui/react-app/growth-chart/app.tsx index 57b5552..df2a14c 100644 --- a/servers/mailchimp/src/ui/react-app/growth-chart/app.tsx +++ b/servers/mailchimp/src/ui/react-app/growth-chart/app.tsx @@ -1,210 +1,100 @@ -import React, { useState, useEffect } from 'react'; -import { createRoot } from 'react-dom/client'; -import { useApp } from '@modelcontextprotocol/ext-apps/react'; +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; -function App() { - const app = useApp(); - const [lists, setLists] = useState([]); - const [selectedListId, setSelectedListId] = useState(''); - const [growthHistory, setGrowthHistory] = useState([]); - const [loading, setLoading] = useState(true); +interface GrowthData { + month: string; + existing: number; + imports: number; + optins: number; + optouts: number; + cleaned: number; +} - useEffect(() => { - loadData(); - }, []); +export default function GrowthChart() { + const [growthData, setGrowthData] = useState([]); + const [listId, setListId] = useState(''); + const [loading, setLoading] = useState(false); + const client = createMCPClient(); - async function loadData() { + const loadGrowthHistory = async () => { + if (!listId) return; + setLoading(true); try { - setLoading(true); - const listsRes = await app.callTool('mailchimp_lists_list', { count: 50 }); - const listsData = JSON.parse(listsRes.content[0].text); - setLists(listsData.lists || []); - - if (listsData.lists?.length > 0) { - const firstListId = listsData.lists[0].id; - setSelectedListId(firstListId); - await loadGrowthHistory(firstListId); - } - } catch (err: any) { - console.error('Failed to load data:', err); + const result = await client.callTool('mailchimp_lists_get_growth_history', { + list_id: listId, + count: 12, + sort_dir: 'DESC' + }); + setGrowthData(result.history || []); + } catch (error) { + console.error('Failed to load growth history:', error); } finally { setLoading(false); } - } - - async function loadGrowthHistory(listId: string) { - try { - const growthRes = await app.callTool('mailchimp_lists_get_growth_history', { - list_id: listId, - count: 180 // 6 months - }); - const growthData = JSON.parse(growthRes.content[0].text); - setGrowthHistory(growthData.history || []); - } catch (err: any) { - console.error('Failed to load growth history:', err); - setGrowthHistory([]); - } - } - - useEffect(() => { - if (selectedListId) { - loadGrowthHistory(selectedListId); - } - }, [selectedListId]); - - if (loading) { - return ( -
-

Loading growth data...

-
- ); - } - - const totalGrowth = growthHistory.reduce((sum, day) => sum + (day.existing || 0), 0); - const avgDailyGrowth = growthHistory.length > 0 ? totalGrowth / growthHistory.length : 0; - const maxGrowth = Math.max(...growthHistory.map(d => Math.abs(d.existing || 0)), 1); + }; return ( -
-
-
-

๐Ÿ“ˆ Audience Growth Chart

-
- {/* List Selector */} - {lists.length > 0 && ( -
- - -
- )} - - {/* Stats Cards */} -
-
-
Total Growth (Period)
-
= 0 ? '#66bb6a' : '#ef5350' }}> - {totalGrowth >= 0 ? '+' : ''}{totalGrowth.toLocaleString()} -
-
-
-
Avg Daily Growth
-
- {avgDailyGrowth >= 0 ? '+' : ''}{avgDailyGrowth.toFixed(1)} -
-
-
-
Days Tracked
-
{growthHistory.length}
-
-
- - {/* Growth Chart */} - {growthHistory.length > 0 && ( -
-

Daily Growth Trend

- -
- {growthHistory.slice().reverse().map((day, idx) => { - const height = Math.abs(day.existing || 0) / maxGrowth * 270; - const isPositive = (day.existing || 0) >= 0; - - return ( -
-
0 ? '+' : ''}${day.existing}`} - onMouseEnter={e => { - e.currentTarget.style.opacity = '0.7'; - }} - onMouseLeave={e => { - e.currentTarget.style.opacity = '1'; - }} - /> + {loading ? ( +
Loading growth history...
+ ) : growthData.length > 0 ? ( +
+ {growthData.map((month) => ( +
+

{month.month}

+
+
+
Existing
+
{month.existing.toLocaleString()}
- ); - })} -
- -
-
{growthHistory.length > 0 ? `${growthHistory[growthHistory.length - 1].month}/${growthHistory[growthHistory.length - 1].day}` : ''}
-
{growthHistory.length > 0 ? `${growthHistory[0].month}/${growthHistory[0].day}` : ''}
-
- -
- - - Growth - - - - Loss - -
-
- )} - - {growthHistory.length === 0 && ( -
-

No growth history available for this list

+
+
Imports
+
+{month.imports.toLocaleString()}
+
+
+
Opt-ins
+
+{month.optins.toLocaleString()}
+
+
+
Opt-outs
+
-{month.optouts.toLocaleString()}
+
+
+
Cleaned
+
-{month.cleaned.toLocaleString()}
+
+
+
+ ))}
+ ) : ( +
Enter a list ID to view growth history
)}
); } - -const root = createRoot(document.getElementById('root')!); -root.render(); diff --git a/servers/mailchimp/src/ui/react-app/growth-chart/index.html b/servers/mailchimp/src/ui/react-app/growth-chart/index.html index d294f8d..ad7fecd 100644 --- a/servers/mailchimp/src/ui/react-app/growth-chart/index.html +++ b/servers/mailchimp/src/ui/react-app/growth-chart/index.html @@ -1,12 +1,13 @@ - - - - Growth Chart - - -
- - + + + + growth-chart - Mailchimp MCP + + + +
+ + diff --git a/servers/mailchimp/src/ui/react-app/growth-chart/vite.config.ts b/servers/mailchimp/src/ui/react-app/growth-chart/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/growth-chart/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/landing-page-builder/App.tsx b/servers/mailchimp/src/ui/react-app/landing-page-builder/App.tsx new file mode 100644 index 0000000..a1b7a3f --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/landing-page-builder/App.tsx @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; + + return ( +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

+
+
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/landing-page-builder/index.html b/servers/mailchimp/src/ui/react-app/landing-page-builder/index.html new file mode 100644 index 0000000..fd9efc7 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/landing-page-builder/index.html @@ -0,0 +1,13 @@ + + + + + + landing-page-builder - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/landing-page-builder/vite.config.ts b/servers/mailchimp/src/ui/react-app/landing-page-builder/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/landing-page-builder/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/list-health-monitor/App.tsx b/servers/mailchimp/src/ui/react-app/list-health-monitor/App.tsx new file mode 100644 index 0000000..a1b7a3f --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/list-health-monitor/App.tsx @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; + + return ( +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

+
+
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/list-health-monitor/index.html b/servers/mailchimp/src/ui/react-app/list-health-monitor/index.html new file mode 100644 index 0000000..9195fe3 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/list-health-monitor/index.html @@ -0,0 +1,13 @@ + + + + + + list-health-monitor - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/list-health-monitor/vite.config.ts b/servers/mailchimp/src/ui/react-app/list-health-monitor/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/list-health-monitor/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/promo-code-manager/App.tsx b/servers/mailchimp/src/ui/react-app/promo-code-manager/App.tsx new file mode 100644 index 0000000..a1b7a3f --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/promo-code-manager/App.tsx @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; + + return ( +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

+
+
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/promo-code-manager/index.html b/servers/mailchimp/src/ui/react-app/promo-code-manager/index.html new file mode 100644 index 0000000..816413a --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/promo-code-manager/index.html @@ -0,0 +1,13 @@ + + + + + + promo-code-manager - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/promo-code-manager/vite.config.ts b/servers/mailchimp/src/ui/react-app/promo-code-manager/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/promo-code-manager/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/segment-builder/App.tsx b/servers/mailchimp/src/ui/react-app/segment-builder/App.tsx new file mode 100644 index 0000000..542a237 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/segment-builder/App.tsx @@ -0,0 +1,162 @@ +import React, { useState, useEffect } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +interface Segment { + id: string; + name: string; + type: string; + member_count: number; + created_at: string; + updated_at: string; +} + +export default function SegmentBuilder() { + const [segments, setSegments] = useState([]); + const [listId, setListId] = useState(''); + const [loading, setLoading] = useState(false); + const [showCreateForm, setShowCreateForm] = useState(false); + const [newSegmentName, setNewSegmentName] = useState(''); + + const client = createMCPClient(); + + const loadSegments = async () => { + if (!listId) return; + setLoading(true); + try { + const result = await client.callTool('mailchimp_lists_get_segments', { + list_id: listId, + count: 100 + }); + setSegments(result.segments || []); + } catch (error) { + console.error('Failed to load segments:', error); + } finally { + setLoading(false); + } + }; + + const createSegment = async () => { + if (!listId || !newSegmentName) return; + try { + await client.callTool('mailchimp_lists_create_segment', { + list_id: listId, + name: newSegmentName, + static_segment: [] + }); + setNewSegmentName(''); + setShowCreateForm(false); + loadSegments(); + } catch (error: any) { + alert('Failed to create segment: ' + error.message); + } + }; + + const typeColors: Record = { + saved: 'bg-blue-600', + static: 'bg-green-600', + fuzzy: 'bg-purple-600' + }; + + return ( +
+
+
+

+ Segment Builder +

+ +
+ + {/* Create Form */} + {showCreateForm && ( +
+

Create New Segment

+
+ setNewSegmentName(e.target.value)} + className="px-4 py-2 bg-gray-900 border border-gray-700 rounded-lg focus:ring-2 focus:ring-purple-500 outline-none" + /> +
+
+ + +
+
+ )} + + {/* List ID Input */} +
+ setListId(e.target.value)} + className="px-4 py-2 bg-gray-800 border border-gray-700 rounded-lg focus:ring-2 focus:ring-purple-500 outline-none" + /> + +
+ + {/* Segments Grid */} + {loading ? ( +
Loading segments...
+ ) : ( +
+ {segments.map((segment) => ( +
+
+

{segment.name}

+ + {segment.type} + +
+
+
+ {segment.member_count.toLocaleString()} +
+
Members
+
+
+ Created: {new Date(segment.created_at).toLocaleDateString()} +
+
+ + +
+
+ ))} +
+ )} +
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/segment-builder/index.html b/servers/mailchimp/src/ui/react-app/segment-builder/index.html new file mode 100644 index 0000000..38d7d08 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/segment-builder/index.html @@ -0,0 +1,13 @@ + + + + + + Segment Builder - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/segment-builder/vite.config.ts b/servers/mailchimp/src/ui/react-app/segment-builder/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/segment-builder/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/send-time-optimizer/App.tsx b/servers/mailchimp/src/ui/react-app/send-time-optimizer/App.tsx new file mode 100644 index 0000000..a1b7a3f --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/send-time-optimizer/App.tsx @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; + + return ( +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

+
+
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/send-time-optimizer/index.html b/servers/mailchimp/src/ui/react-app/send-time-optimizer/index.html new file mode 100644 index 0000000..e17cf41 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/send-time-optimizer/index.html @@ -0,0 +1,13 @@ + + + + + + send-time-optimizer - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/send-time-optimizer/vite.config.ts b/servers/mailchimp/src/ui/react-app/send-time-optimizer/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/send-time-optimizer/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/subscriber-grid/App.tsx b/servers/mailchimp/src/ui/react-app/subscriber-grid/App.tsx new file mode 100644 index 0000000..ff5326c --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/subscriber-grid/App.tsx @@ -0,0 +1,132 @@ +import React, { useState, useEffect } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; + +interface Member { + id: string; + email_address: string; + status: string; + merge_fields: { FNAME?: string; LNAME?: string }; + timestamp_opt?: string; + vip: boolean; +} + +export default function SubscriberGrid() { + const [members, setMembers] = useState([]); + const [listId, setListId] = useState(''); + const [loading, setLoading] = useState(false); + const [statusFilter, setStatusFilter] = useState('subscribed'); + + const client = createMCPClient(); + + const loadMembers = async () => { + if (!listId) return; + setLoading(true); + try { + const result = await client.callTool('mailchimp_members_list', { + list_id: listId, + count: 100, + status: statusFilter + }); + setMembers(result.members || []); + } catch (error) { + console.error('Failed to load members:', error); + } finally { + setLoading(false); + } + }; + + const statusColors: Record = { + subscribed: 'bg-green-600', + unsubscribed: 'bg-red-600', + cleaned: 'bg-yellow-600', + pending: 'bg-blue-600' + }; + + return ( +
+
+

+ Subscriber Grid +

+ + {/* Filters */} +
+ setListId(e.target.value)} + className="px-4 py-2 bg-gray-800 border border-gray-700 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none" + /> + + +
+ + {/* Stats */} +
+
+ Showing {members.length} {statusFilter} subscribers +
+
+ + {/* Grid */} + {loading ? ( +
Loading subscribers...
+ ) : ( +
+ + + + + + + + + + + + + {members.map((member) => ( + + + + + + + + + ))} + +
EmailNameStatusVIPSubscribedActions
{member.email_address} + {member.merge_fields.FNAME} {member.merge_fields.LNAME} + + + {member.status} + + + {member.vip ? 'โญ' : 'โ€”'} + + {member.timestamp_opt ? new Date(member.timestamp_opt).toLocaleDateString() : 'โ€”'} + + +
+
+ )} +
+
+ ); +} diff --git a/servers/mailchimp/src/ui/react-app/subscriber-grid/index.html b/servers/mailchimp/src/ui/react-app/subscriber-grid/index.html new file mode 100644 index 0000000..a150ee6 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/subscriber-grid/index.html @@ -0,0 +1,13 @@ + + + + + + Subscriber Grid - Mailchimp MCP + + + +
+ + + diff --git a/servers/mailchimp/src/ui/react-app/subscriber-grid/vite.config.ts b/servers/mailchimp/src/ui/react-app/subscriber-grid/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/subscriber-grid/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/tag-manager/app.tsx b/servers/mailchimp/src/ui/react-app/tag-manager/app.tsx index 9779607..a1b7a3f 100644 --- a/servers/mailchimp/src/ui/react-app/tag-manager/app.tsx +++ b/servers/mailchimp/src/ui/react-app/tag-manager/app.tsx @@ -1,135 +1,21 @@ -import React, { useState, useEffect } from 'react'; -import { createRoot } from 'react-dom/client'; -import { useApp } from '@modelcontextprotocol/ext-apps/react'; +import React, { useState } from 'react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; -function App() { - const app = useApp(); - const [searchQuery, setSearchQuery] = useState(''); - const [tags, setTags] = useState([]); - const [loading, setLoading] = useState(false); - - async function searchTags() { - if (!searchQuery.trim()) return; - - try { - setLoading(true); - const result = await app.callTool('mailchimp_tags_search', { name: searchQuery }); - const data = JSON.parse(result.content[0].text); - setTags(data.tags || []); - } catch (err: any) { - console.error('Failed to search tags:', err); - setTags([]); - } finally { - setLoading(false); - } - } - - useEffect(() => { - const timer = setTimeout(() => { - if (searchQuery) searchTags(); - }, 500); - - return () => clearTimeout(timer); - }, [searchQuery]); +export default function App() { + const [data, setData] = useState(null); + const client = createMCPClient(); + const appName = window.location.pathname.split('/').pop() || 'App'; return ( -
-
-

๐Ÿท๏ธ Tag Manager

- - {/* Search Bar */} -
- setSearchQuery(e.target.value)} - placeholder="Search tags..." - style={{ - width: '100%', - padding: 16, - background: '#2a2a2a', - color: '#e0e0e0', - border: '1px solid #444', - borderRadius: 8, - fontSize: 16 - }} - /> +
+
+

+ {appName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} +

+
+

Loading...

- - {loading && ( -
-

Searching...

-
- )} - - {!loading && tags.length > 0 && ( -
-
- Found {tags.length} tag{tags.length !== 1 ? 's' : ''} -
- -
- {tags.map((tag, idx) => ( -
-
-
- ๐Ÿท๏ธ {tag.name} -
- {tag.list_id && ( -
- List ID: {tag.list_id} -
- )} -
-
-
- {tag.member_count || 0} -
-
members
-
-
- ))} -
-
- )} - - {!loading && searchQuery && tags.length === 0 && ( -
-

No tags found matching "{searchQuery}"

-
- )} - - {!loading && !searchQuery && ( -
-
๐Ÿท๏ธ
-

Enter a tag name to search

-

- Tags help you organize and segment your audience -

-
- )}
); } - -const root = createRoot(document.getElementById('root')!); -root.render(); diff --git a/servers/mailchimp/src/ui/react-app/tag-manager/index.html b/servers/mailchimp/src/ui/react-app/tag-manager/index.html index c8fdbc2..ba60f5c 100644 --- a/servers/mailchimp/src/ui/react-app/tag-manager/index.html +++ b/servers/mailchimp/src/ui/react-app/tag-manager/index.html @@ -1,12 +1,13 @@ - - - - Tag Manager - - -
- - + + + + tag-manager - Mailchimp MCP + + + +
+ + diff --git a/servers/mailchimp/src/ui/react-app/tag-manager/vite.config.ts b/servers/mailchimp/src/ui/react-app/tag-manager/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/tag-manager/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); diff --git a/servers/mailchimp/src/ui/react-app/template-gallery/app.tsx b/servers/mailchimp/src/ui/react-app/template-gallery/app.tsx index 2477ca3..d4cf0cb 100644 --- a/servers/mailchimp/src/ui/react-app/template-gallery/app.tsx +++ b/servers/mailchimp/src/ui/react-app/template-gallery/app.tsx @@ -1,183 +1,93 @@ import React, { useState, useEffect } from 'react'; -import { createRoot } from 'react-dom/client'; -import { useApp } from '@modelcontextprotocol/ext-apps/react'; +import { createMCPClient } from '@modelcontextprotocol/ext-apps'; -function App() { - const app = useApp(); - const [templates, setTemplates] = useState([]); - const [selectedTemplate, setSelectedTemplate] = useState(null); +interface Template { + id: string; + name: string; + type: string; + category?: string; + date_created: string; + active: boolean; + thumbnail?: string; +} + +export default function TemplateGallery() { + const [templates, setTemplates] = useState([]); const [loading, setLoading] = useState(true); + const [typeFilter, setTypeFilter] = useState('all'); + + const client = createMCPClient(); useEffect(() => { loadTemplates(); - }, []); + }, [typeFilter]); - async function loadTemplates() { + const loadTemplates = async () => { + setLoading(true); try { - setLoading(true); - const result = await app.callTool('mailchimp_templates_list', { count: 100 }); - const data = JSON.parse(result.content[0].text); - setTemplates(data.templates || []); - } catch (err: any) { - console.error('Failed to load templates:', err); + const params: any = { count: 100, sort_field: 'date_created', sort_dir: 'DESC' }; + if (typeFilter !== 'all') params.type = typeFilter; + const result = await client.callTool('mailchimp_templates_list', params); + setTemplates(result.templates || []); + } catch (error) { + console.error('Failed to load templates:', error); } finally { setLoading(false); } - } - - async function viewTemplate(template: any) { - setSelectedTemplate(template); - } - - if (loading) { - return ( -
-

Loading templates...

-
- ); - } - - if (selectedTemplate) { - return ( -
-
- - -

{selectedTemplate.name}

-
- ID: {selectedTemplate.id} โ€ข Created: {new Date(selectedTemplate.date_created).toLocaleDateString()} -
- -
-
-
Type
-
{selectedTemplate.type}
-
- {selectedTemplate.category && ( -
-
Category
-
{selectedTemplate.category}
-
- )} -
-
Preview
-
- {selectedTemplate.thumbnail ? ( - {selectedTemplate.name} - ) : ( -
- Preview not available -
- )} -
-
-
-
-
- ); - } + }; return ( -
-
-
-

๐Ÿ“„ Template Gallery

-
-
- {templates.map(template => ( -
viewTemplate(template)} - style={{ - background: '#1e1e1e', - border: '1px solid #333', - borderRadius: 8, - overflow: 'hidden', - cursor: 'pointer', - transition: 'transform 0.2s, border-color 0.2s' - }} - onMouseEnter={e => { - e.currentTarget.style.transform = 'translateY(-4px)'; - e.currentTarget.style.borderColor = '#1e88e5'; - }} - onMouseLeave={e => { - e.currentTarget.style.transform = 'translateY(0)'; - e.currentTarget.style.borderColor = '#333'; - }} - > -
- {template.thumbnail ? ( - {template.name} - ) : ( -
๐Ÿ“„
- )} -
-
-

{template.name}

-
- {template.type} -
-
- Created {new Date(template.date_created).toLocaleDateString()} -
-
-
- ))} +
+
- {templates.length === 0 && ( -
-

No templates found

+ {loading ? ( +
Loading templates...
+ ) : ( +
+ {templates.map((template) => ( +
+
+
๐Ÿ“ง
+
+
+

{template.name}

+
+ {template.type} + {new Date(template.date_created).toLocaleDateString()} +
+ +
+
+ ))}
)}
); } - -const root = createRoot(document.getElementById('root')!); -root.render(); diff --git a/servers/mailchimp/src/ui/react-app/template-gallery/index.html b/servers/mailchimp/src/ui/react-app/template-gallery/index.html index 46b06dc..2fc586f 100644 --- a/servers/mailchimp/src/ui/react-app/template-gallery/index.html +++ b/servers/mailchimp/src/ui/react-app/template-gallery/index.html @@ -1,12 +1,13 @@ - - - - Template Gallery - - -
- - + + + + Template Gallery - Mailchimp MCP + + + +
+ + diff --git a/servers/mailchimp/src/ui/react-app/template-gallery/vite.config.ts b/servers/mailchimp/src/ui/react-app/template-gallery/vite.config.ts new file mode 100644 index 0000000..2d2b794 --- /dev/null +++ b/servers/mailchimp/src/ui/react-app/template-gallery/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: 'dist', + emptyOutDir: true, + }, +});