Skip to main content
Glama
coopersully

SendGrid MCP Server

by coopersully
README.md
# SendGrid MCP Server

[![CI](https://github.com/coopersully/sendgrid-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/coopersully/sendgrid-mcp/actions/workflows/ci.yml)

An MCP stdio server for managing SendGrid email workflows from Codex and other MCP clients.

It supports:

- Design Library assets
- Dynamic transactional templates and versions
- Marketing contacts and contact lists
- Single Sends
- Direct email sends
- Stats, email validation, verified senders, and suppression groups

The server uses SendGrid v3 APIs only. It never hardcodes API keys; provide `SENDGRID_API_KEY` through the environment.

## Install

Requires Node.js 24 or newer.

```bash
git clone https://github.com/coopersully/sendgrid-mcp.git
cd sendgrid-mcp
npm install
npm run build
```

## Codex Configuration

Add the server to `~/.codex/config.toml`:

```toml
[mcp_servers.sendgrid]
command = "node"
args = ["/absolute/path/to/sendgrid-mcp/build/index.js"]
env = { SENDGRID_API_KEY = "SG.your-api-key" }
```

Prefer setting the key in your local environment or secret store instead of writing it into a shared file.

Recommended auto-approval policy: approve read-only tools only. Require review for tools that send email, mutate contacts, update templates/designs, or delete anything.

Read-only tools that are usually safe to auto-approve:

```json
[
  "list_contacts",
  "list_contact_lists",
  "get_contacts_by_list",
  "get_contacts_by_emails",
  "get_contact_by_id",
  "get_total_contact_count",
  "get_contact_list",
  "get_list_contact_count",
  "list_custom_fields",
  "list_segments",
  "list_templates",
  "get_template",
  "get_template_version",
  "list_designs",
  "get_design",
  "list_pre_built_designs",
  "get_pre_built_design",
  "list_single_sends",
  "get_single_send",
  "search_single_sends",
  "get_single_send_schedule",
  "list_single_send_categories",
  "list_single_send_stats",
  "get_single_send_stats",
  "list_verified_senders",
  "list_suppression_groups",
  "list_group_suppressions",
  "list_global_suppressions",
  "list_bounces",
  "list_blocks",
  "list_invalid_emails",
  "list_spam_reports",
  "list_marketing_senders",
  "get_marketing_sender",
  "get_stats",
  "validate_email"
]
```

## Tool Groups

### Design Library

| Tool                         | Purpose                                                                                                                             | Mutates |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `list_designs`               | List account designs with optional `page_size`, `page_token`, and `summary`. Returns pagination metadata when SendGrid provides it. | No      |
| `get_design`                 | Retrieve a design, including editable content fields returned by SendGrid.                                                          | No      |
| `create_design`              | Create a design from name, subject, HTML/plain content, editor, categories, and plain-text generation options.                      | Yes     |
| `update_design`              | Patch an existing design. Requires at least one editable field.                                                                     | Yes     |
| `duplicate_design`           | Copy an existing account design.                                                                                                    | Yes     |
| `delete_design`              | Permanently delete a design. Requires `confirm_delete: true`.                                                                       | Yes     |
| `list_pre_built_designs`     | List SendGrid pre-built designs.                                                                                                    | No      |
| `get_pre_built_design`       | Retrieve a pre-built design.                                                                                                        | No      |
| `duplicate_pre_built_design` | Copy a pre-built design into the account.                                                                                           | Yes     |

### Dynamic Templates

| Tool                        | Purpose                                                                       | Mutates |
| --------------------------- | ----------------------------------------------------------------------------- | ------- |
| `list_templates`            | List dynamic transactional templates.                                         | No      |
| `get_template`              | Retrieve a template and its versions.                                         | No      |
| `create_template`           | Create a dynamic template and an initial active version.                      | Yes     |
| `update_template_name`      | Rename a template.                                                            | Yes     |
| `duplicate_template`        | Copy a template using SendGrid's native duplicate endpoint.                   | Yes     |
| `delete_template`           | Permanently delete a template. Requires `confirm_delete: true`.               | Yes     |
| `get_template_version`      | Retrieve one version's content and active state.                              | No      |
| `create_template_version`   | Create a new version. Defaults to inactive with `active: 0`.                  | Yes     |
| `activate_template_version` | Activate an existing version for future sends.                                | Yes     |
| `update_template_version`   | Directly patch a version. Prefer creating a new version for reviewable edits. | Yes     |
| `delete_template_version`   | Permanently delete a version. Requires `confirm_delete: true`.                | Yes     |

Safe editing workflow:

1. Call `get_template`.
2. Call `get_template_version` for the active version.
3. Call `create_template_version` with edited content and leave `active` omitted or set to `0`.
4. Inspect the returned version.
5. Call `activate_template_version` only after approval.

### Contacts and Lists

| Tool                        | Purpose                                                                | Mutates |
| --------------------------- | ---------------------------------------------------------------------- | ------- |
| `list_contacts`             | List marketing contacts.                                               | No      |
| `add_contact`               | Upsert one contact.                                                    | Yes     |
| `delete_contacts`           | Permanently delete contacts by email. Requires `confirm_delete: true`. | Yes     |
| `get_contacts_by_emails`    | Retrieve contacts by email addresses.                                  | No      |
| `get_contact_by_id`         | Retrieve one contact by SendGrid contact ID.                           | No      |
| `get_total_contact_count`   | Retrieve total marketing contact count.                                | No      |
| `list_contact_lists`        | List contact lists.                                                    | No      |
| `get_contact_list`          | Retrieve one contact list by ID.                                       | No      |
| `create_contact_list`       | Create a list.                                                         | Yes     |
| `update_contact_list`       | Rename a contact list.                                                 | Yes     |
| `delete_list`               | Delete a list. Requires `confirm_delete: true`.                        | Yes     |
| `get_list_contact_count`    | Retrieve contact count for one list.                                   | No      |
| `get_contacts_by_list`      | List contacts in a list.                                               | No      |
| `add_contacts_to_list`      | Add emails to a list.                                                  | Yes     |
| `remove_contacts_from_list` | Remove emails from a list without deleting contacts.                   | Yes     |

### Custom Fields and Segments

| Tool                  | Purpose                                                                                           | Mutates |
| --------------------- | ------------------------------------------------------------------------------------------------- | ------- |
| `list_custom_fields`  | List marketing contact custom field definitions.                                                  | No      |
| `create_custom_field` | Create a custom field definition.                                                                 | Yes     |
| `update_custom_field` | Rename a custom field definition.                                                                 | Yes     |
| `delete_custom_field` | Delete a custom field definition. Requires `confirm_delete: true`.                                | Yes     |
| `list_segments`       | List Segments v2 segments with optional `ids`, `parent_list_ids`, or `no_parent_list_id` filters. | No      |
| `create_segment`      | Create a segment from `name` and `query_dsl`.                                                     | Yes     |
| `get_segment`         | Retrieve one segment.                                                                             | No      |
| `update_segment`      | Update a segment name or query DSL.                                                               | Yes     |
| `refresh_segment`     | Refresh a segment.                                                                                | Yes     |
| `delete_segment`      | Delete a segment. Requires `confirm_delete: true`.                                                | Yes     |

### Sending

| Tool                          | Purpose                                                                                                                                 | Mutates |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `send_email`                  | Send one email through SendGrid Mail Send.                                                                                              | Yes     |
| `send_to_list`                | Create and immediately schedule a Single Send to lists or segments. Requires either `suppression_group_id` or `custom_unsubscribe_url`. | Yes     |
| `create_single_send`          | Create a Single Send draft without scheduling it.                                                                                       | Yes     |
| `update_single_send`          | Patch a Single Send draft.                                                                                                              | Yes     |
| `delete_single_send`          | Delete a Single Send. Requires `confirm_delete: true`.                                                                                  | Yes     |
| `duplicate_single_send`       | Duplicate a Single Send.                                                                                                                | Yes     |
| `search_single_sends`         | Search Single Sends with SendGrid query syntax.                                                                                         | No      |
| `schedule_single_send`        | Schedule an existing Single Send for `now` or a future timestamp.                                                                       | Yes     |
| `get_single_send_schedule`    | Retrieve schedule information for a Single Send.                                                                                        | No      |
| `cancel_single_send_schedule` | Cancel a Single Send schedule without deleting the draft.                                                                               | Yes     |
| `list_single_send_categories` | List Single Send categories.                                                                                                            | No      |
| `list_single_send_stats`      | Retrieve Single Sends stats.                                                                                                            | No      |
| `get_single_send_stats`       | Retrieve stats for one Single Send.                                                                                                     | No      |
| `list_single_sends`           | List Single Sends as summaries with optional `page_size` and `page_token`.                                                              | No      |
| `get_single_send`             | Retrieve one Single Send summary. Use `include_details: true` for the full payload.                                                     | No      |

### Suppressions, Senders, Stats, and Validation

| Tool                                   | Purpose                                                                                                                    | Mutates |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- |
| `list_verified_senders`                | List verified sender identities.                                                                                           | No      |
| `list_suppression_groups`              | List unsubscribe groups.                                                                                                   | No      |
| `list_group_suppressions`              | List suppressed addresses in a suppression group.                                                                          | No      |
| `add_group_suppressions`               | Add addresses to a suppression group.                                                                                      | Yes     |
| `delete_group_suppression`             | Remove an address from a suppression group. Requires `confirm_delete: true`.                                               | Yes     |
| `list_global_suppressions`             | List global suppressions.                                                                                                  | No      |
| `add_global_suppressions`              | Add addresses to global suppressions.                                                                                      | Yes     |
| `delete_global_suppression`            | Remove an address from global suppressions. Requires `confirm_delete: true`.                                               | Yes     |
| `list_bounces`                         | List bounce suppressions. Defaults to `limit: 50` and redacted emails; use `include_emails: true` to reveal emails.        | No      |
| `list_blocks`                          | List block suppressions. Defaults to `limit: 50` and redacted emails; use `include_emails: true` to reveal emails.         | No      |
| `list_invalid_emails`                  | List invalid email suppressions. Defaults to `limit: 50` and redacted emails; use `include_emails: true` to reveal emails. | No      |
| `list_spam_reports`                    | List spam report suppressions. Defaults to `limit: 50` and redacted emails; use `include_emails: true` to reveal emails.   | No      |
| `list_marketing_senders`               | List Marketing sender identities.                                                                                          | No      |
| `get_marketing_sender`                 | Retrieve one Marketing sender identity.                                                                                    | No      |
| `create_marketing_sender`              | Create a Marketing sender identity.                                                                                        | Yes     |
| `update_marketing_sender`              | Update a Marketing sender identity.                                                                                        | Yes     |
| `delete_marketing_sender`              | Delete a Marketing sender identity. Requires `confirm_delete: true`.                                                       | Yes     |
| `resend_marketing_sender_verification` | Resend a sender verification email.                                                                                        | Yes     |
| `get_stats`                            | Retrieve email stats for `start_date`, optional `end_date`, and optional aggregation.                                      | No      |
| `validate_email`                       | Validate one email address.                                                                                                | No      |

## Safety Behavior

- Tool schemas are closed with `additionalProperties: false`.
- Tool arguments are validated before SendGrid is called.
- Empty strings, wrong primitive types, empty arrays, unexpected arguments, and missing required fields are rejected locally.
- Destructive delete tools require `confirm_delete: true`.
- Template content edits are safe by default through `create_template_version`, which creates inactive versions unless `active: 1` is explicitly provided.
- Server error logging avoids dumping raw error objects to stderr.

## Agent Response Conventions

- List tools use the SendGrid endpoint's real pagination model: `page_size`/`page_token`, `limit`/`offset`, or endpoint-specific filters.
- Transformed list responses use `{ "result": [], "_metadata": {} }`.
- `_metadata` carries pagination, applied limits, offsets, and redaction flags.
- Suppression list tools default to `limit: 50` and redact `email` fields unless `include_emails: true` is set.
- Content-heavy get tools may return summaries by default and expose full details through an explicit flag such as `include_details: true`.

## Development

```bash
npm ci
npm run check
```

`npm run check` runs formatting, ESLint, TypeScript type checks, Vitest coverage, build, and `npm audit`.

Tests use Vitest with mocked SendGrid clients. They do not make live API calls.

Useful commands:

```bash
npm run format
npm run lint
npm run typecheck
npm run test:coverage
npm run watch
npm run inspector
```

CI runs the same validation gates on Node.js 24 and 26.

Architecture and code standards live in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).

## Notes

- The API key must have the SendGrid permissions required for the tools you use.
- Sender addresses must be verified before sending.
- Bulk sends must include either a suppression group or custom unsubscribe URL.
- SendGrid Marketing API changes can be eventually consistent; recently changed contacts and lists may not appear immediately.
- Use least-privilege API keys when possible, especially for agents that only need template/design management.

## References

- [SendGrid v3 API](https://docs.sendgrid.com/api-reference/how-to-use-the-sendgrid-v3-api)
- [SendGrid Design Library API](https://www.twilio.com/docs/sendgrid/api-reference/designs-api)
- [SendGrid Transactional Templates API](https://www.twilio.com/docs/sendgrid/api-reference/transactional-templates)
- [SendGrid Single Sends API](https://www.twilio.com/docs/sendgrid/api-reference/single-sends)
- [SendGrid Contacts API](https://www.twilio.com/docs/sendgrid/api-reference/contacts)
- [SendGrid Segments v2 API](https://www.twilio.com/docs/sendgrid/api-reference/segmenting-contacts-v2)
- [SendGrid Suppressions API](https://www.twilio.com/docs/sendgrid/api-reference/suppressions-suppressions)
- [MCP tools specification](https://modelcontextprotocol.io/specification/draft/server/tools)

TDQS

B3.4/5.0

Scored across 80 tools

Disambiguation4/5

Although there are many tools, each targets a distinct resource and action. Similar suppression-related tools (e.g., list_blocks, list_bounces) are differentiated by the specific suppression type, and descriptions clearly delineate operations. Minor overlap exists between get_single_send and get_single_send_schedule, but overall ambiguity is low.

Naming Consistency5/5

Tool names consistently follow a verb_noun pattern in snake_case (e.g., activate_template_version, add_contact, delete_list). A few less common verbs (duplicate, refresh) are used consistently. No mixing of camelCase or inconsistent verb styles, making the naming very predictable.

Tool Count3/5

80 tools is high for a single MCP server, covering a broad range of SendGrid features. While each tool serves a specific purpose, the sheer number may overwhelm agents and suggests the server could be split into smaller, more focused servers. The count is borderline—not extreme but above the typical well-scoped range.

Completeness4/5

The toolset covers nearly all major SendGrid domains: contacts, lists, segments, templates, designs, single sends, suppressions, sending, statistics, and validation. Minor gaps exist (e.g., transactional sends, webhook management), but the core workflows for marketing and email delivery are well-represented.

Maintenance

ActivityStale
ResponsivenessNo issues