MCP Integration
Model Context Protocol for AI Assistants
Model Context Protocol (MCP) is an open standard introduced by Anthropic that allows AI assistants (like Claude, Cursor, VS Code Copilot) to integrate with external tools and data sources.
How It Works
The AI assistant communicates with the MCP server via the STDIO protocol, and the MCP server performs operations on NetSendo using the REST API v1.
┌─────────────────┐ STDIO ┌─────────────────┐ HTTP/S ┌─────────────────┐ │ Claude/Cursor │ ◄──────────► │ MCP Server │ ◄───────────► │ NetSendo │ │ (AI Client) │ │ (Docker/npx) │ │ (Your inst.) │ └─────────────────┘ └─────────────────┘ └─────────────────┘
Installation
Requirements
- Node.js 18+
- API Key from NetSendo
Steps
- Generate API Key: Settings → API Keys
- Install Node.js from nodejs.org
- Configure your AI tool using the configuration below
Claude Desktop and Cursor
{
"mcpServers": {
"netsendo": {
"command": "npx",
"args": [
"-y",
"@netsendo/mcp-client",
"--url",
"https://your-domain.com",
"--api-key",
"YOUR_API_KEY"
]
}
}
}VS Code .vscode/mcp.json
VS Code reads MCP servers from .vscode/mcp.json in your workspace (or from your user profile via the "MCP: Open User Configuration" command). This file uses a top-level "servers" key instead of "mcpServers".
{
"servers": {
"netsendo": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@netsendo/mcp-client",
"--url",
"https://your-domain.com",
"--api-key",
"YOUR_API_KEY"
]
}
}
}Replace https://your-domain.com with your NetSendo instance URL and YOUR_API_KEY with your generated API key.
Requirements
- Docker installed and running
- Access to the NetSendo docker-compose.yml file
Steps
- Generate API Key: Settings → API Keys
- Mark the API key for MCP in settings
- Add the key to .env file:
MCP_API_KEY=your-api-key - Build the MCP container:
docker compose build mcp - Configure your AI tool using the configuration below
Claude Desktop and Cursor
{
"mcpServers": {
"netsendo": {
"command": "docker",
"args": [
"compose",
"-f",
"/path/to/NetSendo/docker-compose.yml",
"run",
"--rm",
"-i",
"mcp"
]
}
}
}Replace /path/to/NetSendo with the full path to your NetSendo installation directory.
In VS Code, put the same "netsendo" entry under a top-level "servers" key in .vscode/mcp.json, and add "type": "stdio".
Configuration File Locations
| Client | File Location |
|---|---|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json |
| Cursor IDE | Settings → MCP → Add Server |
| VS Code | .vscode/mcp.json |
Supported AI Clients
Official Claude desktop app from Anthropic
IDE with built-in AI for developers
Visual Studio Code with GitHub Copilot (agent mode)
Available Features
Subscribers
Manage contacts – add, edit, delete
Contact Lists
Browse and organize mailing lists
Email Messages
Send personalized email messages
SMS Messages
Send SMS messages to contacts
Tags
Categorize subscribers using tags
Statistics
Check account and deliverability statistics
Available Tools
Version 1.6.0 of @netsendo/mcp-client provides 140 tools in 21 groups.
Subscribers (6)
| Tool | Description |
|---|---|
| list_subscribers | List subscribers with filtering and pagination |
| get_subscriber | Get a subscriber by ID or email address |
| create_subscriber | Create a subscriber with optional list and tag assignments |
| update_subscriber | Update a subscriber's data |
| delete_subscriber | Permanently delete a subscriber |
| sync_subscriber_tags | Replace all tags assigned to a subscriber |
Contact lists and list settings (11)
| Tool | Description |
|---|---|
| list_contact_lists | Get all contact lists with subscriber counts and default mailbox |
| get_contact_list | Get a list's full configuration: settings, tags, co-registration, limits and webhook |
| get_list_subscribers | Get the subscribers of a contact list |
| get_list_stats | List snapshot: members by status, engagement, 30-day growth and sending settings |
| create_contact_list | Create an email or SMS list with any setting of the list editor |
| update_contact_list | Update a list's settings (only the fields you pass change) |
| get_list_cron_settings | Get a list's sending schedule: weekly windows, per-minute limit and whether it follows the global CRON settings |
| update_list_cron_settings | Set when and how fast a list's queued messages are sent, or return it to the global settings |
| get_list_defaults | Get the account-level list defaults and the instance-wide CRON settings |
| update_list_defaults | Change the account-level list defaults (only the keys you send change) |
| delete_contact_list | Delete a contact list; the contacts stay in the account |
Tags and custom fields (9)
| Tool | Description |
|---|---|
| list_tags | Get the account's tags with name, colour and description |
| list_custom_fields | Get the account's custom fields with their placeholders and scope |
| create_tag | Create a tag (names are unique per account) |
| update_tag | Rename a tag or change its colour and description |
| delete_tag | Delete a tag and remove it from subscribers, lists and messages |
| get_custom_field | Get one custom field with all its settings |
| create_custom_field | Create a global or list-specific custom field; its name becomes a placeholder |
| update_custom_field | Change a custom field's label, type, options or name (its scope stays fixed) |
| delete_custom_field | Delete a custom field and every value stored in it |
Import (2)
| Tool | Description |
|---|---|
| preview_list_import | Dry-run an import: column mapping, invalid addresses and duplicates, nothing is written |
| import_subscribers | Import contacts onto a list from CSV, TSV, JSON or plain addresses |
Export (3)
| Tool | Description |
|---|---|
| export_list | Export list members inline as JSON, CSV or NDJSON, with filters |
| get_export_fields | List the columns available for export, including custom fields |
| queue_list_export | Queue a full CSV export; the account owner gets a download link |
List hygiene (5)
| Tool | Description |
|---|---|
| analyze_list_health | Read-only hygiene report with a 0–100 health score and recommendations |
| clean_list | Apply an action to members in selected problem categories (dry run by default) |
| dedupe_list | Merge duplicate addresses, including Gmail dot and +tag aliases |
| verify_list_emails | Check deliverability: syntax, disposable and role addresses, typo domains, MX records |
| get_hygiene_options | Return the categories and actions accepted by clean_list |
List members (6)
| Tool | Description |
|---|---|
| add_list_members | Attach existing contacts to a list |
| remove_list_members | Detach contacts from a list and cancel their queued messages |
| set_member_status | Change membership status: active, inactive, unsubscribed or bounced |
| copy_list_members | Copy contacts to another list of the same channel |
| move_list_members | Move contacts to another list of the same channel |
| tag_list_members | Add or remove tags across a segment of a list |
Activity and engagement (3)
| Tool | Description |
|---|---|
| get_list_activity | Event feed for a list: signups, unsubscribes, bounces, sends, opens and clicks |
| get_list_engagement | List performance: growth, churn, open and click rates, top messages and links |
| get_subscriber_activity | Full history of one contact: lists, tags, queued messages and timeline |
Suppression list (3)
| Tool | Description |
|---|---|
| list_suppressions | Show the account-wide do-not-mail list with reasons and dates |
| suppress_emails | Add addresses to the do-not-mail list and unsubscribe them from every list |
| unsuppress_emails | Lift suppression for addresses (does not resubscribe anyone) |
Notifications (2)
| Tool | Description |
|---|---|
| send_notification | Post a notification to the account owner's notification centre |
| list_notifications | Read the owner's recent notifications and unread count |
Email and SMS messages (6)
| Tool | Description |
|---|---|
| list_mailboxes | Get available sending mailboxes |
| send_email | Send a single email to a subscriber |
| get_email_status | Check email delivery status |
| list_sms_providers | Get available SMS providers |
| send_sms | Send a single SMS to a subscriber or phone number |
| get_sms_status | Check SMS delivery status |
Campaigns (17)
| Tool | Description |
|---|---|
| list_campaigns | List email and SMS campaigns with filtering |
| get_campaign | Get every editable field of a campaign, including lists, trigger and translations |
| create_campaign | Create an email or SMS campaign (saved as a draft) |
| update_campaign | Update a draft or scheduled campaign |
| set_campaign_lists | Set the recipient lists of a campaign |
| set_campaign_exclusions | Set exclusion lists whose subscribers will not receive the campaign |
| schedule_campaign | Schedule a campaign for later, with time zone support |
| send_campaign | Send a campaign now or activate an autoresponder |
| get_campaign_stats | Get sending statistics for a campaign |
| delete_campaign | Delete a draft or scheduled campaign |
| send_campaign_test | Send a test of a campaign to up to 5 addresses; nothing is queued |
| preview_campaign | Render a campaign as a recipient sees it, with placeholders resolved |
| duplicate_campaign | Copy a campaign as a new draft |
| set_campaign_active | Activate or pause an autoresponder |
| get_campaign_recipient_count | Count who a campaign would reach now, after exclusions and filters |
| resend_campaign_failed | Re-queue recipients whose delivery failed (needs confirmation) |
| send_campaign_to_missed | Send an active autoresponder now to subscribers who missed it (needs confirmation) |
A/B tests (7)
| Tool | Description |
|---|---|
| list_ab_tests | List A/B tests, filtered by status or campaign |
| create_ab_test | Create an A/B test for a campaign |
| add_ab_variant | Add a variant to an A/B test |
| start_ab_test | Start an A/B test (requires at least 2 variants) |
| end_ab_test | End a running test and optionally pick the winner |
| get_ab_test_results | Get detailed results and statistics of a test |
| delete_ab_test | Delete an A/B test that is not running |
Funnels (automation) (12)
| Tool | Description |
|---|---|
| list_funnels | List automation funnels |
| get_funnel | Get a funnel with all its steps and statistics |
| create_funnel | Create an automation funnel |
| update_funnel | Rename a funnel or change its trigger |
| add_funnel_step | Add a step to a funnel and connect it |
| update_funnel_step | Change a step's settings and connections |
| delete_funnel_step | Delete a step and reconnect the funnel around it |
| enroll_subscriber_in_funnel | Put a subscriber into an active funnel right away |
| activate_funnel | Activate a funnel for new subscribers |
| pause_funnel | Pause a funnel |
| get_funnel_stats | Get funnel statistics: subscriber counts and completion rates |
| delete_funnel | Delete a funnel (pause it first) |
Personalization (1)
| Tool | Description |
|---|---|
| list_placeholders | Get the placeholders for personalizing email and SMS content |
Webhooks (8)
| Tool | Description |
|---|---|
| list_webhook_events | List the event names a webhook can subscribe to |
| list_webhooks | List the account's webhooks with status, failure count and last delivery |
| get_webhook | Get one webhook's settings (the secret is not returned) |
| create_webhook | Register a webhook for chosen events; the signing secret is shown once |
| update_webhook | Change a webhook's name, URL, events or active state |
| delete_webhook | Delete a webhook permanently |
| test_webhook | Send a test delivery and report whether the endpoint answered 2xx |
| regenerate_webhook_secret | Issue a new signing secret; the old one stops working immediately |
Email templates (13)
| Tool | Description |
|---|---|
| list_templates | List the account's own email templates and the system starter templates |
| get_template | Get a template with its HTML, MJML, builder blocks and settings |
| create_template | Create an email template from HTML or from builder blocks |
| update_template | Update an own template (only the fields you pass change) |
| delete_template | Delete an own template; campaigns created from it keep their content |
| duplicate_template | Copy an own or system template into the account to edit it |
| preview_template | Render a template's placeholders for a subscriber or sample data; nothing is sent |
| list_template_categories | List the system and own template categories |
| list_template_block_types | List the builder block types with their default content and settings |
| list_template_blocks | List saved builder blocks, own and global |
| create_template_block | Save a reusable builder block, such as a header, footer or button |
| update_template_block | Change an own saved block |
| delete_template_block | Delete an own saved block; templates that contain it are not changed |
System emails and pages (9)
| Tool | Description |
|---|---|
| list_system_emails | List the automatic system emails (double opt-in, welcome, unsubscribe…) for a list or globally |
| get_system_email | Get one system email with its subject, HTML and available placeholders |
| update_system_email | Change a system email's subject, content or active state, for one list or globally |
| set_system_email_active | Switch one system email on or off for one list |
| reset_system_email | Remove a list's override so it uses the global system email again |
| list_system_pages | List the system pages shown after signup, activation, unsubscribe and preference changes |
| get_system_page | Get one system page with its title, HTML, access and placeholders |
| update_system_page | Change a system page's title, content or access, for one list or globally |
| reset_system_page | Remove a list's override so it uses the global system page again |
Subscription forms (6)
| Tool | Description |
|---|---|
| list_forms | List subscription forms with status, list, submission count and hosted URL |
| get_form | Get a form's configuration plus its hosted URL and HTML, JS and iframe embed codes |
| create_form | Create a signup form for an email list (it starts as a draft) |
| update_form | Change a form, publish it or stop signups |
| delete_form | Delete a form; pages that embed it stop working, subscribers are kept |
| duplicate_form | Copy a form as a new draft with a new embed code |
Automation rules (9)
| Tool | Description |
|---|---|
| get_automation_options | Get the catalogue of trigger events, conditions and actions for building rules |
| list_automations | List automation rules with trigger, actions, active state and run counts |
| get_automation | Get one rule in full, with 7-day stats |
| create_automation | Create a rule: when an event happens and the conditions pass, run the actions |
| update_automation | Change a rule (only the fields you send change) |
| set_automation_active | Activate, deactivate or toggle a rule |
| duplicate_automation | Copy a rule; the copy starts inactive |
| delete_automation | Delete a rule permanently, with its execution log |
| get_automation_logs | Get a rule's execution log: status, subscriber and each action's result |
Account (2)
| Tool | Description |
|---|---|
| test_connection | Test the API connection and credentials |
| get_account_info | Get information about the connected account |
Besides tools, the client registers 5 prompts (analyze_subscribers, send_newsletter, cleanup_list, import_contacts, list_report) and 3 resources (netsendo://info, netsendo://stats, netsendo://lists).
Example Queries
Security
Troubleshooting
- Make sure NetSendo is running and accessible
- Check if the API key is valid
- Verify the URL is correct (include https://)
Restart your AI tool after configuration changes.
Install Node.js from nodejs.org (includes npm/npx).
Multiple NetSendo Instances
You can connect to multiple NetSendo instances using different server names:
{
"mcpServers": {
"netsendo-production": {
"command": "npx",
"args": ["-y", "@netsendo/mcp-client", "--url", "https://app.company.com", "--api-key", "prod-key"]
},
"netsendo-staging": {
"command": "npx",
"args": ["-y", "@netsendo/mcp-client", "--url", "https://staging.company.com", "--api-key", "staging-key"]
}
}
}
