Skip to main content

ses-email-notification

Stdio MCP server exposing a single send_email tool backed by AWS SES (SESv2 API).

Credentials come from boto3's default chain: the EC2 instance role in production, AWS_PROFILE for local testing. No credential configuration in code.

Tool: send_email

Parameter Type Required Notes
to list[str] yes one or more recipients
subject str yes
body_text str no* plain-text body
body_html str no* HTML body; both → multipart/alternative
cc list[str] no
attachment_paths list[str] no local file paths inside ATTACHMENT_BASE_DIR

*At least one of body_text / body_html is required.

Returns the SES MessageId on success. SES failures surface the SES error code and message verbatim (e.g. MessageRejected: Email address is not verified).

The sender address and optional reply-to addresses are fixed by configuration; the tool has no from or reply_to parameter.

Configuration (environment variables)

Variable Required Purpose
SES_FROM_ADDRESS yes verified SES identity to send from
SES_REPLY_TO_ADDRESSES no comma-separated reply-to addresses
AWS_REGION yes region of the SES identity
ATTACHMENT_BASE_DIR no directory attachments may be read from; attachments are rejected if unset
AWS_PROFILE local only profile for local testing; omit on EC2 (instance role is used)

MCP client configuration

From PyPI (no checkout needed — uvx downloads and runs the published package):

{
  "mcpServers": {
    "ses-email-notification": {
      "command": "uvx",
      "args": ["ses-email-notification"],
      "env": {
        "AWS_REGION": "us-east-1",
        "SES_FROM_ADDRESS": "noreply@example.com",
        "SES_REPLY_TO_ADDRESSES": "support@example.com",
        "ATTACHMENT_BASE_DIR": "/path/to/agent/output"
      }
    }
  }
}

From a local checkout (testing with an AWS profile):

{
  "mcpServers": {
    "ses-email-notification": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/ses-email-notification", "ses-email-notification"],
      "env": {
        "AWS_PROFILE": "your-profile",
        "AWS_REGION": "eu-central-1",
        "SES_FROM_ADDRESS": "noreply@example.com",
        "SES_REPLY_TO_ADDRESSES": "support@example.com,owner@example.com",
        "ATTACHMENT_BASE_DIR": "/path/to/agent/output"
      }
    }
  }
}

EC2 (instance role provides credentials — no AWS_PROFILE):

{
  "mcpServers": {
    "ses-email-notification": {
      "command": "uv",
      "args": ["run", "--directory", "/opt/ses-email-notification", "ses-email-notification"],
      "env": {
        "AWS_REGION": "eu-central-1",
        "SES_FROM_ADDRESS": "noreply@example.com",
        "SES_REPLY_TO_ADDRESSES": "support@example.com",
        "ATTACHMENT_BASE_DIR": "/var/agent/output"
      }
    }
  }
}

IAM policy for the EC2 instance role

ses:SendRawEmail is required for attachments. Scope the resource to your verified identity ARN:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["ses:SendEmail", "ses:SendRawEmail"],
      "Resource": "arn:aws:ses:REGION:ACCOUNT_ID:identity/example.com"
    }
  ]
}

Limits & caveats

  • Raw messages (sends with attachments) are capped at 10 MB after base64 encoding (~7 MB of actual files); the server rejects oversized sends before calling SES.
  • SES sandbox: if the account is in sandbox mode, sends to unverified recipients fail with MessageRejected. Request production access before relying on this server.

Development

uv run pytest            # unit tests (botocore Stubber, no AWS calls)

# manual smoke send against real SES:
AWS_PROFILE=your-profile AWS_REGION=eu-central-1 \
SES_FROM_ADDRESS=noreply@example.com \
SES_REPLY_TO_ADDRESSES=support@example.com \
uv run mcp dev src/ses_email_notification/server.py

Publishing to PyPI

Bump version in pyproject.toml first — PyPI rejects re-uploads of an existing version.

uv build                                      # builds sdist + wheel into dist/
uv publish --index testpypi --token <token>   # dry run against test.pypi.org
uv publish --token <token>                    # real PyPI

Tokens come from https://pypi.org/manage/account/token/ (and the test.pypi.org equivalent). UV_PUBLISH_TOKEN works instead of --token.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ses_email_notification-0.1.2.tar.gz (5.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ses_email_notification-0.1.2-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file ses_email_notification-0.1.2.tar.gz.

File metadata

  • Download URL: ses_email_notification-0.1.2.tar.gz
  • Upload date:
  • Size: 5.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for ses_email_notification-0.1.2.tar.gz
Algorithm Hash digest
SHA256 6dd39519cfd767c205b4d1df10a3be80f3b5d34e79714781578cfb425ae20a3a
MD5 550372177e990c8eb856edd11518915d
BLAKE2b-256 20448f82c9ee3e34b0be78fcdd187e32d85db3ccae0af43507e253c7cce20f8e

See more details on using hashes here.

File details

Details for the file ses_email_notification-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for ses_email_notification-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 39106004e7ed166e4008faeb1843fdc1e7217d2dbb4450f48874351e464199b1
MD5 59571b13483c06458e2552fcd7d4e5f1
BLAKE2b-256 5e6f2156ca2101d97e86504df8b4bd7c5eca22b359ad24045501a2d168f39626

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page