Constant Contact MCP server for AI agents

Live

OAUTH 2.0

EMAIL MARKETING

Marketing

Constant Contact gives your agent email marketing on your Constant Contact account: manage contacts, lists, tags, and segments, create, test, and schedule email campaigns, read campaign reports, and set up events.

  • Per-user credentials: each call uses the actual user's token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Constant Contact
agent · Acme Q3
Run
How did Tuesday's spring sale email perform?
S
constantcontact_email_campaign_stats_get
134ms
Email marketing agent
The spring sale email reached 6,820 contacts with a 38% open rate and a 4.1% click rate. 11 contacts opted out.
Sources: Constant Contact campaign stats, 1 campaign
constantcontact
1 campaign
18:29
Message Claude...

Tools your email marketing agent reaches for on Constant Contact, scoped per user.

CALL ANY TOOL
95 tools for email marketing in Constant Contact: create and update contacts, manage lists, tags, segments, and custom fields, create, test, and schedule email campaigns, read open, click, and bounce reports, and manage events.
constantcontact_account_email_create
Create account email
Add an email address to the account. Constant Contact emails it a confirmation link; it stays UNCONFIRMED until clicked. Returns the new address with its confirm_status. Use to add a sender address for campaigns. Returns 409 if the address already exists.
Parameters
Name
Type
Required
Description
email_address
string
Required
The email address to add (max 80 characters).
constantcontact_account_emails_list
List account emails
constantcontact_account_physical_address_get
Get account physical address
constantcontact_automation_get
Get automation
constantcontact_contact_counts_get
Get contact counts
constantcontact_contact_delete
Delete contact
constantcontact_contact_list_create
Create contact list
constantcontact_contact_list_update
Update contact list
constantcontact_contact_resubscribe
Contact resubscribe
constantcontact_contact_update
Update contact
constantcontact_contact_upsert
Upsert contact
constantcontact_contacts_add_tags
Contacts add tags
constantcontact_contacts_export_file_get
Get contacts export file
constantcontact_contacts_remove_from_lists
Contacts remove from lists
constantcontact_custom_field_delete
Delete custom field
constantcontact_email_ab_test_create
Create email ab test
constantcontact_email_bounces_report
Email bounces report
constantcontact_email_campaign_activity_preview_get
Get email campaign activity preview
constantcontact_email_campaign_activity_test_send
Send email campaign activity test
constantcontact_email_campaign_activity_update
Update email campaign activity
constantcontact_email_campaign_get
Get email campaign
constantcontact_email_campaign_rename
Email campaign rename
constantcontact_email_campaigns_list
List email campaigns
constantcontact_email_didnotopens_report
Email didnotopens report
constantcontact_email_opens_report
Email opens report
constantcontact_email_resend_to_non_openers_delete
Delete email resend to non openers
constantcontact_email_unique_opens_report
Email unique opens report
constantcontact_event_create
Create event
constantcontact_event_registration_get
Get event registration
constantcontact_segments_list
List segments

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Constant Contact tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["constantcontact"], toolNames: [
    "constantcontact_contact_upsert",
    "constantcontact_email_campaign_create",
    "constantcontact_email_campaign_activity_schedule"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Create the June Update email and schedule it for Thursday at 10am" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["constantcontact"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Create the June Update email and schedule it for Thursday at 10am" }],
  tools,
});

// Execute the tool call with the user's vaulted Constant Contact OAuth token
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["constantcontact"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Create the June Update email and schedule it for Thursday at 10am" }],
  tools,
});

// Tool call runs with the user's vaulted Constant Contact OAuth token
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["constantcontact"] }, pageSize: 100,
});

const agent = new Agent({
  name: "email_marketing_agent",
  model: "gemini-2.5-pro",
  instruction: "Constant Contact tools scoped to this user",
  tools,
});

await agent.run("Create the June Update email and schedule it for Thursday at 10am");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Constant Contact tool. Click to copy, paste into your agent, done.
Contacts
Copy the prompt
Copied
Add jordan@acme.com to the Newsletter list, or update them if they already exist.
Copy the prompt
Copied
Tag every contact on the Spring Event list as attendee.
Copy the prompt
Copied
Export the contacts on the VIP list to a CSV file.
Campaigns
Copy the prompt
Copied
Create a draft email campaign called June Update from this HTML.
Copy the prompt
Copied
Send a test of the June Update email to me.
Copy the prompt
Copied
Schedule the June Update email for Thursday at 10am.
Reports
Copy the prompt
Copied
Show open and click rates for campaigns sent last month.
Copy the prompt
Copied
List contacts who did not open the spring sale email.
Copy the prompt
Copied
Which links in the spring sale email got the most clicks?
SEE HOW AUTH WORKS
Each user signs in to Constant Contact once, and Scalekit stores and refreshes their tokens. Credentials stay vaulted, every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Constant Contact
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Constant Contact
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Constant Contact
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Constant Contact
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other email marketing connectors.
GTM and RevOps Teams
CRM AI agent
Reads the Granola transcript after every call, extracts next steps and updates the HubSpot record, drafts the follow-up in Gmail, and confirms in Slack, all on the rep's own delegated OAuth.
Test other agents
See the same per-user auth pattern across other email marketing connectors.
GTM
CRM AI agent
Turn each Granola call transcript into a HubSpot record update, a drafted Gmail follow-up, and a Slack recap.
GTM
HubSpot to Slack updates agent
Watch HubSpot deal stage changes and post structured updates to the right Slack channel. Reps stop checking the CRM all day.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Constant Contact token looks fine in a demo. In production every campaign send looks like one service account, and you cannot tell which user triggered it. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Constant Contact today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Constant Contact as the user or through a shared service account?
As the user. Each user signs in to Constant Contact once, and Scalekit stores and refreshes their tokens. Contact changes and campaign sends are attributed to that user in your audit trail, not a shared service account.
Where is the Constant Contact OAuth token stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. Refresh is automatic. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Constant Contact?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example contact and report tools without constantcontact_contacts_bulk_delete or constantcontact_email_campaign_delete. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Constant Contact access?
The connection is invalidated on the next tool call. Subsequent requests for that user fail closed with a clear error. Other users in the tenant remain unaffected. The event is logged for audit.
Can the agent send a Constant Contact campaign right away?
Yes. constantcontact_email_campaign_activity_schedule sends an email campaign activity now or schedules it for a date. constantcontact_email_campaign_activity_test_send sends a test copy to up to 5 addresses first, and constantcontact_email_campaign_activity_unschedule cancels a scheduled send.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""constantcontact"": {
""url"": ""https://mcp.scalekit.com/constantcontact"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.constantcontact]
url = ""https://mcp.scalekit.com/constantcontact""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""constantcontact"": {
""url"": ""https://mcp.scalekit.com/constantcontact"",
""type"": ""http""
}
}
}