Announcing CIMD support for MCP Client registration
Learn more

MailerLite MCP vs MailerLite API for AI Agents (2026)

Nishant Choudhary
Tech Evangelist

TL;DR

  • MailerLite's hosted MCP server exposes 76 tools; the Scalekit connector surfaces 68 of them. The MCP is not a strict subset of the REST API. It can create automations with triggers and ordered steps, create segments with filter rules, and edit automation email and delay steps, none of which the public REST reference documents.
  • The REST API still wins on consent metadata (opted_in_at, optin_ip, ip_address, subscribed_at), GDPR forget, filtered subscriber activity logs, segment-targeted campaigns, A/B and multivariate settings, and receiving webhook events.
  • Auth diverges hard. The MCP path is browser OAuth per user. The REST API documents exactly one method: a bearer API key that MailerLite explicitly binds to its creating user, so it dies when that employee is deprovisioned. Neither is a multi-tenant credential model on its own.
  • The MCP tool batch_requests maps onto POST /api/batch, which accepts any api/-prefixed path. One allowlisted tool closes most of the capability gap and simultaneously hands the model an arbitrary API-call primitive. Scope it deliberately.
  • Scalekit's MailerLite MCP connector handles the OAuth flow, per-user token storage, and refresh, and Virtual MCP servers let you cut the 68-tool surface down to the four your agent actually needs. The MCP vs API decision does not change your auth infrastructure.

Your agent needs to read and write MailerLite: pull campaign performance, add subscribers to groups, build a welcome automation. MailerLite ships two paths, and unlike most vendors in this series, the usual assumption is inverted here. The hosted MCP server authenticates with OAuth and can create automations and segments. The REST API authenticates with a single bearer key that is bound to the human who generated it. Picking wrong costs you either capability or a clean multi-tenant identity model. Here's how to decide.

What MailerLite MCP and MailerLite API actually are

Two objects, two different design intents. One was built for an LLM to drive a marketing account conversationally. The other was built in 2022 for deterministic server-to-server integration and has not been reshaped for agents.

The MailerLite MCP server

MailerLite Labs shipped the MCP server in September 2025 and MailerLite's developer documentation still labels it beta. It is hosted, not self-deployed, at https://mcp.mailerlite.com/mcp over streamable HTTP, and clients authenticate through a browser OAuth flow against the user's MailerLite account. Official documentation lives at the MailerLite MCP Server reference.

The MailerLite REST API

The current REST API is versioned by date and served from https://connect.mailerlite.com/api. It covers subscribers, groups, segments, fields, automations, campaigns, forms, webhooks, batching, timezones, campaign languages, and a separate e-commerce surface. Authentication is a bearer API key in the Authorization header. Conventions, errors, and limits are documented in MailerLite's getting started guide.

Comparing them where it matters for agents

Four dimensions decide this: what the agent can actually do, which auth path you inherit, what breaks in production, and which mode your agent runs in.

What your agent can actually do

The table below covers the actions that matter for email marketing agents specifically. Rows reflect what each path exposes as a first-class, schema-described operation.

Capability
MailerLite MCP
MailerLite REST API
Subscriber create, read, update, delete
Yes
Yes
Write consent metadata (opted_in_at, optin_ip, ip_address)
No
Yes
GDPR forget a subscriber
No dedicated tool
Yes (POST /api/subscribers/:id/forget)
Filtered subscriber activity log
No filter or pagination params
Yes (filter[log_name], limit, page)
Create campaign (regular, ab, resend)
Yes
Yes
Multivariate campaigns, A/B and resend settings
No
Yes
Target a campaign at segments
No (groups only)
Yes (segments array)
Create a segment with filter rules
Yes
No create endpoint documented
Create automation with trigger and ordered steps
Yes
Draft with a name only
Edit automation email and delay steps, dry run
Yes
No
Webhook create, read, update, delete
Yes
Yes
Receive webhook events
No
Yes (14 events, HMAC-signed)
E-commerce shops, products, orders, carts
Upstream only, not in the Scalekit connector
Yes
Arbitrary API call
Yes, via batch_requests
Native

Where the MCP surface goes further than the API

This is the part most MCP-versus-API comparisons get backwards for MailerLite. mailerlitemcp_create_automation accepts a trigger type, trigger config, and ordered email and delay steps. The REST equivalent, POST /api/automations, accepts a name and returns an automation with an empty steps array. mailerlitemcp_create_segment accepts a filter rules object; the Segments API reference documents list, read, rename, and delete, with no create. There are also LLM-shaped tools with no REST analogue at all: suggest_subject_lines, generate_email_content, discover_automation_templates, and dry_run_automation.

Where the REST API goes further than the MCP surface

The gaps that bite are compliance gaps, not feature gaps. mailerlitemcp_add_subscriber takes email, name, fields, groups, status, and resubscribe. The REST upsert additionally takes subscribed_at, opted_in_at, optin_ip, ip_address, and unsubscribed_at. If your agent is the system of record for how a subscriber consented, the MCP surface cannot write that provenance. Same story for the GDPR forget endpoint and for GET /api/subscribers/:id/activity-log, where the REST call filters by log type and paginates and the MCP tool takes only a subscriber ID.

The batch_requests escape hatch, and what it costs you

mailerlitemcp_batch_requests takes an array of up to 50 requests and carries the same "webhooks are not supported" restriction as POST /api/batch. That endpoint accepts any relative path starting with api/. So an agent holding this one tool can reach the forget endpoint, the e-commerce surface, and everything else the MCP does not model.

That is convenient and it is also the whole least-privilege story collapsing into a single tool. The model has to construct raw paths and bodies with no input schema to guide it, and a mis-planned batch is 50 unvalidated writes. Allowlist batch_requests only when a specific gap requires it, and never alongside a broad read surface.

The auth path each one puts you on

The MCP server is OAuth. Every user completes a browser consent flow against their own MailerLite account, and the resulting session is bound to that user. Scalekit's connector page classifies the MailerLite MCP auth as OAuth 2.1 with Dynamic Client Registration.

The REST API documents exactly one method: Authorization: Bearer <api_key>. There is no self-serve OAuth app registration in MailerLite's public API reference for third-party integrations. MailerLite's own CLI offers an OAuth login, and the MCP server is OAuth-backed, but neither is a documented path for your application to obtain per-user REST tokens.

Why an API key is the wrong primitive for a multi-tenant agent

MailerLite states it plainly in its own documentation: API keys are permanently bound to the user who created them, and if that user is removed from the account or their account is deleted, the key stops authenticating. Read that as an operational spec, not a footnote.

An agent running on a customer's MailerLite key inherits a credential whose lifetime is tied to one employee's employment. It carries no per-user scope, so every action in the audit trail resolves to whoever generated the key rather than the person who triggered the agent. And because MailerLite does not store keys in plaintext, rotation means a human regenerating and re-pasting a secret per tenant. As explored in OAuth vs API Keys for AI Agents, static credentials create structural liabilities at production scale.

What you own in production

On the MCP path, MailerLite owns hosting, tool schemas, and the OAuth consent surface. You own per-user token storage, refresh, revocation on disconnect, and tenant isolation. You also own the fact that the server is labeled beta, so tool schemas can move without a versioning contract.

On the REST path you own all of that plus endpoint selection, pagination, error handling, and retries. You do get a versioning lever the MCP does not offer: pin X-Version to an implementation date and migrate on your own schedule. For a deterministic nightly pipeline, that pin is worth real money.

Rate limits are the constraint you will hit first

MailerLite enforces a global 120 requests per minute and returns 429 with X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers. Import creation is separately capped at 5 requests per minute, and that cap applies to POST /api/subscribers/import, POST /api/groups/{group_id}/import-subscribers, and any batch composed entirely of subscriber upserts.

Agentic workflows issue several sequential calls per user action, so a list-then-fetch-then-update loop across a few hundred subscribers burns the minute budget faster than a traditional sync job. MCP tool calls travel over the same API and count the same way. For a deeper look at agent tool calling auth production problems and patterns, the failure modes extend well beyond rate limits.

When to use MCP, when to use the API

Use the MailerLite MCP server when:

  • Your agent is interactive and a user is present for the OAuth consent, such as a marketing assistant in Claude, Cursor, or your own chat surface
  • The job is campaign reporting, subscriber lookup, group management, or drafting, which is the bulk of practical email marketing agent work
  • You need to build or edit automations programmatically, since the MCP models triggers and steps and the REST API does not
  • You want per-user identity by default rather than a shared account-level key

Use the MailerLite REST API directly when:

  • Your agent runs headless on a schedule and no browser session exists at execution time
  • You must write consent provenance or honour a GDPR erasure request with the documented forget endpoint
  • The agent reacts to events rather than polling, since webhook delivery needs an HTTP endpoint and signature verification that no tool call can provide
  • You need segment-targeted, multivariate, or A/B campaigns, or the e-commerce surface
  • Schema stability matters more than tool convenience and you want to pin X-Version

Building a MailerLite agent with Scalekit

Scalekit ships MailerLite as an MCP connector with the slug mailerlitemcp. The connector handles the OAuth flow, stores the resulting token per user in the vault, and executes tool calls with the right credential resolved at call time. Reference material is on the MailerLite MCP connector docs page and the MailerLite connector page.

Connect the user once

Install the SDK and set SCALEKIT_ENV_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET from your dashboard. The connection_name string must match the connection you configured under AgentKit and Connections exactly. A mismatch here is the single most common integration error.

pip install scalekit-sdk-python langchain langchain-openai
import os from scalekit.client import ScalekitClient scalekit_client = ScalekitClient( client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], env_url=os.environ["SCALEKIT_ENV_URL"], ) actions = scalekit_client.actions # Must match the connection name in your Scalekit dashboard exactly. CONNECTION_NAME = "mailerlitemcp" IDENTIFIER = "user_123" account = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) if account.connected_account.status != "ACTIVE": magic_link = actions.get_authorization_link( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) print("Authorize MailerLite:", magic_link.link) input("Press Enter after authorizing...")

Retrieve the authorized tool surface

Before the agent sees a single tool, decide what it is allowed to see. list_scoped_tools returns the tools this user's connected account is authorized to call, not a catalog. Filtering by tool name on top of that turns a 68-tool connector into a four-tool reporting agent.

scoped, _ = actions.tools.list_scoped_tools( identifier=IDENTIFIER, filter={ "connection_names": [CONNECTION_NAME], "tool_names": [ "mailerlitemcp_list_campaigns", "mailerlitemcp_get_campaign", "mailerlitemcp_get_campaign_subscribers", "mailerlitemcp_get_campaign_links", ], }, page_size=100, ) print(len(scoped.tools), "tools authorized for", IDENTIFIER)

Run the agent loop with LangChain

actions.langchain.get_tools returns native StructuredTool objects with the same scoping filters, so the agent code carries no Scalekit-specific logic beyond initialization. For more on how LangChain tool calling works and where it stops, the integration pattern is consistent across connectors.

from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, ToolMessage tools = actions.langchain.get_tools( identifier=IDENTIFIER, connection_names=[CONNECTION_NAME], tool_names=[ "mailerlitemcp_list_campaigns", "mailerlitemcp_get_campaign", "mailerlitemcp_get_campaign_subscribers", "mailerlitemcp_get_campaign_links", ], page_size=100, ) tool_map = {t.name: t for t in tools} llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [ HumanMessage( "Look at my three most recent sent campaigns and tell me which " "links got the most clicks in each." ) ] while True: response = llm.invoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tc in response.tool_calls: result = tool_map[tc["name"]].invoke(tc["args"]) messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

The same pattern in TypeScript with the Claude SDK

Scalekit returns schemas with input_schema, which is the exact shape Anthropic's tool use API expects, so no reshaping is needed. This example scopes a write agent down to subscriber intake.

npm install @scalekit-sdk/node @anthropic-ai/sdk
import { ScalekitClient } from '@scalekit-sdk/node'; import Anthropic from '@anthropic-ai/sdk'; const scalekit = new ScalekitClient( process.env.SCALEKIT_ENV_URL!, process.env.SCALEKIT_CLIENT_ID!, process.env.SCALEKIT_CLIENT_SECRET!, ); const anthropic = new Anthropic(); const identifier = 'user_123'; const { tools } = await scalekit.tools.listScopedTools(identifier, { filter: { connectionNames: ['mailerlitemcp'], toolNames: [ 'mailerlitemcp_list_resources', 'mailerlitemcp_add_subscriber', 'mailerlitemcp_assign_subscriber_to_group', ], }, pageSize: 100, }); const llmTools = tools.map((t) => ({ name: t.tool.definition.name, description: t.tool.definition.description, input_schema: t.tool.definition.input_schema, })); const messages: Anthropic.MessageParam[] = [ { role: 'user', content: 'Add jamie@acme.com to the Product Updates group.' }, ]; while (true) { const response = await anthropic.messages.create({ model: 'claude-sonnet-4-6', max_tokens: 1024, tools: llmTools, messages, }); if (response.stop_reason === 'end_turn') { const text = response.content.find((b) => b.type === 'text'); if (text?.type === 'text') console.log(text.text); break; } const toolResults: Anthropic.ToolResultBlockParam[] = []; for (const block of response.content) { if (block.type === 'tool_use') { const result = await scalekit.actions.executeTool({ toolName: block.name, identifier, toolInput: block.input as Record, }); toolResults.push({ type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(result.data), }); } } messages.push({ role: 'assistant', content: response.content }); messages.push({ role: 'user', content: toolResults }); }

Reaching REST endpoints the MCP surface does not expose

When you need the GDPR forget endpoint or another REST-only path, mailerlitemcp_batch_requests gets you there through the same connected account. Keep this behind your own application logic rather than in the model's tool list, so the path is code you wrote and not a path the model invented.

result = actions.execute_tool( tool_name="mailerlitemcp_batch_requests", identifier=IDENTIFIER, tool_input={ "requests": [ {"method": "POST", "path": f"api/subscribers/{subscriber_id}/forget"} ] }, ) print(result.execution_id, result.data)

If you would rather model MailerLite's REST API as a first-class connector with its own OAuth config, tool schemas, and proxy routing, use the bring your own connector approach and call actions.request against it directly.

Scoping the surface with a Virtual MCP server

Handing an agent the whole MailerLite MCP server means 68 tools in context. At roughly 200 tokens per tool definition, that is around 13,600 tokens burned before the agent does any work, and a decision space no model handles well. A Virtual MCP server declares exactly which tools the agent sees and whose credentials it acts with. This is the same insight behind why MCP can be significantly more expensive than CLI when tool surfaces are not carefully scoped.

from scalekit.actions.types import McpConfigConnectionToolMapping actions.mcp.create_config( name="mailerlite-campaign-reporter", description="Read-only MailerLite campaign reporting", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="mailerlitemcp", tools=[ "mailerlitemcp_list_campaigns", "mailerlitemcp_get_campaign", "mailerlitemcp_get_campaign_subscribers", "mailerlitemcp_get_campaign_links", ], ) ], ) instance = actions.mcp.ensure_instance( config_name="mailerlite-campaign-reporter", user_identifier=IDENTIFIER, ) mcp_url = instance.instance.url

Why this matters for multi-tool and multi-tenant agents

Four tools instead of 68 is roughly a 94 percent reduction in tool-surface tokens, and the accuracy effect is the larger half of that win. Surface reduction is the lever; model upgrades help, but they are not the lever.

The setup is once per agent role, not once per user. One server definition serves every tenant, and ensure_instance mints a per-user endpoint bound to that user's connected accounts. Add Slack or HubSpot to the same config and the isolation property holds across all of them. The challenges of moving from single-tenant to multi-tenant tool calling are exactly what this architecture is designed to solve.

Checking authorization state before a run

Background runs fail badly when a user has quietly disconnected. Check auth state first and surface a fresh link rather than letting the agent discover a dead credential mid-task.

auth_state = actions.mcp.get_instance_auth_state( instance_id=instance.instance.id, include_auth_links=True, ) for conn in auth_state.connections: if conn.connected_account_status != "ACTIVE": print(f"{conn.connection_name} needs auth: {conn.authentication_link}")

What the auth logs give you downstream

Every execute_tool call returns an execution_id, and every call resolves through a named connected account rather than a shared key. That combination is what makes an audit answer possible: which agent, acting for which user, called which MailerLite tool, when, and with what result.

That matters more for email than for most tools. A campaign send and a subscriber deletion are both irreversible and both are things a compliance reviewer will ask about by name. Connected accounts also expose status, token_expires_at, and last_used_at, and Agent Webhooks push connected account lifecycle, auth, and token events to your systems without polling. Proper audit trails for agent auth in B2B SaaS are the difference between an answerable compliance question and an incident.

The credential problem that exists on both paths

Both paths hand you a credential per user or per account. Neither hands you a vault, rotation logic, or a revocation flow. That gap is where MailerLite agents break in month three, not week one.

The N-credential problem for MailerLite agents

Run a MailerLite agent for 40 customers and you hold 40 credentials with 40 independent lifecycles. On the MCP path they are OAuth tokens a user can revoke from MailerLite at any time, and your agent learns about it through a failed call unless you are watching for it. On the REST path they are API keys tied to individual employees, which means a routine offboarding at your customer silently kills your integration for that tenant.

Where Scalekit fits

Scalekit's MailerLite MCP connector handles the OAuth flow, encrypted per-tenant token storage, and refresh, so the MCP versus API decision does not change what you have to build at the credential layer. Credentials stay in the vault and never enter the agent runtime or the model's context. Understanding who holds the token and why credential ownership patterns matter is foundational for building production-grade agentic systems.

Which one to build against

The decision is not really about capability coverage. Both paths cover most of what an email agent needs, and the MCP actually covers more of the automation surface.

If your agent is interactive

Build on the MCP path. A user is present for OAuth, per-user identity is the default rather than something you retrofit, and the automation and content tools have no REST equivalent. Scope it with a Virtual MCP server from day one rather than after the first bad tool selection.

If your agent is headless, compliance-facing, or multi-tenant

Go to the REST API for the specific operations that demand it: consent provenance, GDPR erasure, webhook ingestion, segment-targeted sends. Most production MailerLite agents will end up running both, with the interactive assistant on MCP and the scheduled pipeline on REST. The credential management problem is identical either way, and that is the part that needs production-grade infrastructure.

Talk to other MailerLite agent builders

Building an email marketing agent and hitting an auth or scoping wall? Join the Scalekit Slack community and ask, or talk to us if you want a walkthrough against your own architecture.

Browse the Scalekit MailerLite MCP connector or start from the connector docs.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
zero upfront cost.

Every feature unlocked. No hidden fees.