
Your agent needs to send email through SendGrid: an order confirmation, an incident notice, a follow-up drafted from a support ticket. Then it needs to answer whether that email bounced. SendGrid's v3 API has covered all of this for years, but SendGrid has no MCP server of its own that can execute a call. That leaves three real options: a community MCP server, the direct API, or Scalekit's connector. Each one puts the same long-lived API key in a different place.
All three paths end at the same SendGrid v3 endpoints. What differs is who writes the tool schemas, who holds the API key, and what code runs between the model and SendGrid.
Public SendGrid MCP servers on GitHub and npm range from a single send-email tool to a couple dozen Marketing Campaigns tools. Most run as local processes started by the MCP host and read one key from a SENDGRID_API_KEY environment variable. At least one HTTP-based server guards its endpoint with a single shared secret. None is published or supported by Twilio.
Twilio's official MCP server is a Public Beta documentation service. It indexes Twilio SendGrid docs and support articles, requires no authentication, and is read-only: it does not execute API calls. It helps a coding agent write SendGrid integration code. It cannot send an email at runtime. Twilio lists execute-ready, OAuth-authenticated MCP tools as a planned addition, with no date given.
The v3 API is a REST surface covering Mail Send, templates, Marketing Campaigns contacts and lists, suppressions, stats, Email Activity and Email Logs, sender and domain authentication, subusers, and webhooks. Authentication is an API key in an Authorization: Bearer header. SendGrid ended username and password Basic Authentication in Q4 2020; SMTP and some services accept Basic Authentication with the username apikey and the key as the password. SendGrid documents all of it in its v3 API reference and maintains SDKs in seven languages.
The Scalekit SendGrid connector docs cover 391 prebuilt SendGrid tools, each authenticated with the calling user's own SendGrid key. Your agent calls them through execute_tool or a framework adapter. Scalekit injects the key at request time, so it never enters agent code or LLM context. The same tools can be served over a Virtual MCP server scoped to what one agent role needs. The SendGrid connector overview summarizes the model.
The three paths expose the same SendGrid account through very different surfaces. Capability is the smallest difference between them. Credential placement is the largest.
Community coverage reflects public servers today; any single server covers only a slice.
The gap that matters is not sending. It is everything after the send. Mail Send returns 202 Accepted with an empty body, which means SendGrid queued the message, not that it arrived. Addresses on the bounce or unsubscribe lists are dropped after acceptance. An agent answering "did the password reset arrive?" needs per-message lookup, and the Email Activity API requires a paid history add-on, a key with Email Activity permission, and is limited to 6 requests per minute. Community servers rarely expose any of this.
SendGrid's push surfaces, the Event Webhook and Inbound Parse, POST to an HTTPS endpoint you host. No MCP server or connector replaces that endpoint. An agent can configure a webhook; your service still receives the events. The OAuth that does appear in SendGrid's docs runs in the other direction: the Event Webhook can use the Client Credentials grant to authenticate to your endpoint.
Every path, including Scalekit's, ends with a SendGrid API key in an Authorization: Bearer header. SendGrid's Authentication docs describe no user-delegated OAuth consent flow for third-party apps. There is no consent screen, no refresh token, and no scope negotiation at connect time. The key-creation call takes a name and optional scopes, nothing else. There is no expiry field, so a key stays valid until someone deletes it.
Full Access covers every endpoint except billing and Email Address Validation. Restricted (Custom) Access sets No, Read, or Full Access per permission. A key cannot exceed its creator's permissions, and each account caps out at 100 keys. Two details matter for agents. A key created through the API without a scopes field defaults to Full Access. A Full Access key can also call the API Keys endpoints, so a leaked key can mint replacement keys that survive its own deletion.
If each customer brings their own SendGrid account, your agent holds one key per customer. If you run customers as subusers under one Pro or Premier account, a parent key with the on-behalf-of header can administer every subuser, but that header does not work with Mail Send. Sending as a subuser, with its own reputation, stats, and suppressions, requires that subuser's key.
Both paths require per-tenant credential isolation. A community server holds one key per process. The direct API holds one key per tenant in your storage. Neither path stores, rotates, or revokes those keys for you. This is a core challenge covered in depth in the article on how tool calling auth changes when you move from single-tenant to multi-tenant.
Ownership splits three ways: the server code, the tool schemas, and the key lifecycle. Each path assigns them differently.
You own the key, the host config file that stores it, and a dependency you did not write. Tool schemas change when the maintainer publishes, and an npx -y launch resolves the latest published version unless you pin one. SendGrid surface changes, such as the newer Email Logs API or the split between legacy and current Marketing Campaigns APIs, reach the server when its maintainer gets to them. There is no SLA and no support path.
You own everything: tool schemas written for an LLM rather than a human reader, pagination, 429 handling against per-endpoint rate limits, and Mail Send limits of 30MB, 1,000 recipients, and 10,000 bytes of custom arguments per request. You also own the key store. Writing the schema is the hard part, not the API call. In exchange you get a stable v3 contract and immediate access to any new endpoint.
Scalekit owns the 391 tool schemas, key storage, and per-user key injection. You own the connection configuration, which tools each agent role sees, and the SendGrid-side lifecycle. Revoking a SendGrid key happens in SendGrid: deleting the connected account stops your agent from using it, and the customer should still delete the key in their SendGrid account.
Community servers earn their place in local experiments, and some maintainers deliberately keep write tools out of auto-approve lists. The failure modes are still specific, and all of them trace back to one long-lived key held by code outside your review process.
The key sits in plaintext in an MCP host config file or shell profile, readable by any process running as that user and copied into every environment the config travels to. Public setup guides commonly tell readers to pick Full Access, including Twilio's own tutorial for building a SendGrid MCP server. A Full Access key on a laptop can send as your authenticated domain from anywhere. Disabling the owner's SSO account when they leave does not delete it.
Recommended reading: When an employee leaves, who revokes their AI agent's access?
An MCP server can call any endpoint its key allows, not only the tools it advertises. A server that lists four read tools, run with a Full Access key, still holds a key that can delete suppressions or create API keys. Twilio Labs, in the docs for its own MCP server, advises users not to run community MCP servers alongside official Twilio ones, to guard against injection attacks that could expose account data.
Email is an exfiltration channel. An agent that reads untrusted text, such as an inbound ticket, a scraped page, or a parsed reply, and also holds a send tool can be steered into mailing data out from your authenticated domain, with your domain's reputation behind it. One public server's sample config sets autoApprove to "*", which removes the human check on exactly that call.
Recommended reading: MCP security risks for AI agents
Single-maintainer projects stall, get abandoned, or change tool names between releases. When one breaks on a SendGrid change, the failure shows up inside your agent. Your team then debugs someone else's code, often during an incident when the agent was supposed to be sending notices.
SendGrid's Email Logs record the api_key_id that authenticated each send. With one shared key behind a community server, every message traces to the same key ID, not to the user, the agent run, or the prompt that caused it. When a customer asks who sent an email in their name, that log cannot answer.
Recommended reading: Audit trails for agent auth in B2B SaaS
The Twilio Email Policy, part of the Twilio Acceptable Use Policy, requires affirmative consent before any non-transactional email and rules out blanket or third-party consent. Every such message needs a physical mailing address, a working unsubscribe link, and a privacy policy link, with opt-outs honored within 10 days. An agent that emails a list it assembled does not shift that obligation. The account owner carries the violation, and SendGrid's support docs warn that ignoring consent jeopardizes account status.
The right path depends on who owns the SendGrid account and who is in the loop when the agent acts.
For coding agents writing SendGrid integration code, Twilio's read-only documentation MCP server is the safer companion: it answers API questions without holding a key.
Swap MCP for the API, or the API for a connector, and the credential stays the same: a long-lived SendGrid key per tenant.
SendGrid gives you scoped keys and a revocation lever: delete the key and every call made with it fails. It does not give you expiry, per-user identity on a shared key, or a record of which user caused a call.
Take a B2B support platform with 40 customers, each on its own SendGrid account. That is 40 keys to store encrypted and isolated per tenant, 40 rotations you schedule yourself since no key expires, a reconnect flow for each customer who replaces a key, and 40 clean-ups as customers churn. Add a Restricted key per agent role and the count multiplies. The key type never changes, and the infrastructure required is identical on the MCP path and the API path.
Scalekit's SendGrid connector stores each user's key in its token vault, injects it on every execute_tool call, and collects replacement keys through the same hosted form, so the MCP vs API decision does not change your credential infrastructure.
Recommended reading: Why a token vault is critical for AI agent workflows
The model has two objects: a connection, created once per environment, and a connected account per user that holds that user's SendGrid key.
Create the SendGrid connection once in the Scalekit dashboard under AgentKit > Connections, following the SendGrid connector docs. Each user then supplies their own key through a Scalekit-hosted form. The connection name in your code must match the dashboard name exactly; a mismatch is the most common integration error.
Ask users for a Restricted key with only the permissions the agent needs. What the user's key can't do, the agent can't do.
Set SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET in .env, and ANTHROPIC_API_KEY for the Claude client.
For API-key connectors, get_authorization_link opens a hosted form that collects the user's SendGrid key and stores it on their connected account. See Authorize a user for production handling.
Loading all 391 SendGrid tools at roughly 200 tokens each would spend about 78,000 tokens before the agent does any work, and SendGrid's tool descriptions run longer than that estimate. Tool selection also degrades as the catalog grows. The fix is not better prompting. It is surface reduction.
The agent does not load a connector catalog. list_scoped_tools returns the tools this user's connected account is authorized to call, filtered here to four tools for a delivery assistant.
Scalekit returns schemas with input_schema, the format Claude's tool use API expects. The loop runs until Claude stops requesting tools. See the Anthropic example for the Node.js version.
The rest of the same loop body runs each requested tool with execute_tool, returns results to Claude, and appends both turns to the history. SendGrid errors, such as a 403 from a key missing a permission, go back to Claude as error results.
A Virtual MCP server gives each agent role one static MCP endpoint that exposes only the tools you allow. Each run authenticates with a short-lived session token bound to one user's connected accounts.
A delivery-troubleshooting agent needs to read logs, bounces, and stats. It never needs to send. Leave sendgrid_send_mail off the server and a prompt injection has no send tool to reach, whatever the user's key allows. One server definition serves every user, with no MCP server to deploy, host, or maintain. Multi-tool agents add mappings for other connections, such as Zendesk or Slack, to the same server.
Run this once, not per user. The response carries a static mcp_server_url you reuse for every session. The Virtual MCP setup guide covers updates and deletion.
Check that the user's connections are active, then mint a token. Tokens default to about one hour. There is no refresh endpoint; call create_session_token again to remint.
Install the adapters with pip install "langchain-mcp-adapters>=0.3,<1" langchain-anthropic, then pass the URL and token as bearer auth. The LangChain example shows the same pattern.
TypeScript agents, including Mastra, connect to the same URL with the token as a Bearer header. Mint the token on a backend with the Python SDK, since the Node.js SDK does not create MCP session tokens yet.
SendGrid's logs identify the key. An agent in production also needs to identify the user and the tool call behind each request. Understanding agent tool observability is essential for production deployments.
Every execute_tool call returns an execution_id. The Scalekit dashboard shows status and tool execution logs per connected account under AgentKit > Connected Accounts. For token and session events across your app, see Scalekit auth logs. That closes the gap SendGrid's Email Logs leave: SendGrid records which api_key_id sent a message, and Scalekit records which user identifier and which tool made the call.
Upstream SendGrid errors raise ScalekitToolException with tool_error_code, tool_error_message, and execution_id. A 403 from a key without Email Activity permission traces to one user and one call. Subscribe to the connected_account.status_updated webhook to act when an account leaves ACTIVE, and see Manage connected accounts for reconnect flows.
If your agent is a local experiment against your own test account, a community MCP server is fast, provided you read its source, pin its version, and give it a Restricted key. If your agent sends deterministic, single-tenant transactional email, call the v3 API from your own code and keep the key out of model context. If your agent acts for many customers with their own SendGrid accounts, or needs a scoped MCP endpoint without hosting one, use a connector that vaults each key and scopes each tool surface. Every path runs on the same long-lived key. The decision that matters is where that key lives and how narrow the surface around it is.
The patterns involved here parallel the broader challenge of credential ownership across agent tool-calling patterns — a structural question that every multi-tenant AI product must answer.
Browse the Scalekit SendGrid connector, start from the SendGrid connector docs, or compare plans on Scalekit pricing.
Building a SendGrid agent now? Talk to us for immediate help with key scoping, Virtual MCP setup, or multi-tenant rollout.