Metadata-Version: 2.4
Name: ses-email-notification
Version: 0.1.0
Summary: Stdio MCP server for sending email notifications via AWS SES
Keywords: mcp,ses,email,aws
Author: datgfg
Author-email: datgfg <dat.le@global-fashion-group.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Dist: boto3>=1.34
Requires-Dist: mcp>=1.0
Requires-Python: >=3.11
Project-URL: Repository, https://github.com/global-fashion-group/gfg-mcp-servers
Description-Content-Type: text/markdown

# 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 is fixed by configuration — the tool has no `from` parameter.

## Configuration (environment variables)

| Variable | Required | Purpose |
|---|---|---|
| `SES_FROM_ADDRESS` | yes | verified SES identity to send from |
| `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):

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

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

```json
{
  "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",
        "ATTACHMENT_BASE_DIR": "/path/to/agent/output"
      }
    }
  }
}
```

EC2 (instance role provides credentials — no `AWS_PROFILE`):

```json
{
  "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",
        "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:

```json
{
  "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

```bash
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 \
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.

```bash
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`.
