Skip to main content
Glama
addy-mcp

addy-mcp

addy-mcp

PyPI CI License: MIT

An MCP server that lets Claude (and other MCP clients) manage your addy.io account: aliases, recipients, usernames, custom domains, labels, rules, the blocklist and failed deliveries. It covers the full addy.io API.

Unofficial. This project is not affiliated with or endorsed by addy.io.

It runs on your own computer with your own API key. Nothing is hosted, and your key is only ever sent to addy.io.

1. Create an API key

In addy.io go to Settings → API Keys (https://app.addy.io/settings/api) and click Create New API Key. Consider giving it a name like "Claude" and an expiry date.

Related MCP server: Gmail MCP Server

2. Install

Claude Desktop (easiest)

  1. Download the latest addy-mcp-<version>.mcpb from the Releases page.

  2. Double-click it (or drag it into Settings → Extensions in Claude Desktop) and click Install.

  3. Paste your API key when asked. Claude Desktop stores it encrypted.

Claude Desktop (manual config)

Requires uv. Open Settings → Developer → Edit Config and add:

{
  "mcpServers": {
    "addy": {
      "command": "uvx",
      "args": ["addy-mcp@latest"],
      "env": {
        "ADDY_API_KEY": "paste-your-api-key-here"
      }
    }
  }
}

Then fully quit and reopen Claude Desktop. If it can't find uvx, replace "uvx" with the full path from which uvx (macOS/Linux) or where uvx (Windows). Desktop apps don't always see your shell's PATH.

Claude Code

claude mcp add addy --scope user --env ADDY_API_KEY=paste-your-api-key-here -- uvx addy-mcp@latest

This makes the server available in Claude Code (the CLI and the desktop app's Code tab). Claude Desktop's chat uses a separate config, set up above.

Other MCP clients

Run uvx addy-mcp@latest as a stdio server with ADDY_API_KEY set in its environment.

@latest makes uvx check PyPI for a new release each time the server starts. Leave it off and uvx keeps using whichever version it first downloaded. To stay on a specific version instead, use e.g. addy-mcp==0.1.1.

Configuration

Environment variable

Required

Description

ADDY_API_KEY

Yes*

Your addy.io API key.

ADDY_API_KEY_FILE

No

Path to a file containing the key, instead of ADDY_API_KEY. Takes precedence if both are set. *One of the two is required.

ADDY_READ_ONLY

No

Set to true to hide every tool that can change your account. Claude can then only look things up.

ADDY_BASE_URL

No

For self-hosted addy.io instances, e.g. https://addy.example.com. Defaults to https://app.addy.io.

Storing your key securely

The setup above keeps the key in plain text in your MCP client's config file. That's the usual approach for local MCP servers, but you can do better:

  • Claude Desktop extension: the .mcpb install stores the key encrypted. Nothing else to do.

  • macOS Keychain (Claude Code and other clients): keep the key in the Keychain and fetch it only when the server starts, so it's never written to a config file. Add the key (you'll be prompted for it, so it doesn't end up in your shell history):

    security add-generic-password -a "$USER" -s addy-mcp -w

    Then add the server with a small wrapper instead of --env:

    claude mcp add addy --scope user -- /bin/sh -c 'ADDY_API_KEY="$(security find-generic-password -a "$USER" -s addy-mcp -w)" || exit 1; export ADDY_API_KEY; exec uvx addy-mcp@latest'

    If the server fails to start because uvx isn't found, replace uvx with its full path from which uvx.

    On Linux, the same pattern works with secret-tool store --label=addy-mcp service addy-mcp and secret-tool lookup service addy-mcp. With 1Password, use op read "op://<vault>/<item>/credential" in place of the security command.

  • Key file: set ADDY_API_KEY_FILE to a file that only you can read (chmod 600), or to a Docker or Kubernetes secret mount.

  • VS Code: let VS Code prompt for the key and keep it in its secret storage:

    {
      "inputs": [
        { "type": "promptString", "id": "addy-api-key", "description": "addy.io API key", "password": true }
      ],
      "servers": {
        "addy": {
          "type": "stdio",
          "command": "uvx",
          "args": ["addy-mcp@latest"],
          "env": { "ADDY_API_KEY": "${input:addy-api-key}" }
        }
      }
    }

Whichever you choose, use a separate addy.io key for each app or device, so you can revoke one without breaking the others, and give it an expiry date.

Updating

  • Installed with addy-mcp@latest (the commands above): restart Claude (or your MCP client) and the newest release is picked up automatically.

  • Installed with plain uvx addy-mcp: uvx keeps using the version it first downloaded. Change addy-mcp to addy-mcp@latest in your config and restart Claude.

  • Claude Desktop extension (.mcpb): download the new .mcpb from the Releases page and install it the same way. Your API key and settings are kept, so you won't be asked for them again.

To see which version is newest, run uvx addy-mcp@latest --version (available from 0.1.1). To hear about new releases, watch the repo on GitHub (Watch → Custom → Releases). Changes are listed in the changelog.

What you can ask

  • "Make me a new alias for my Netflix account."

  • "Which of my aliases have blocked the most emails? Deactivate the top 5."

  • "Find every alias I created for shopping sites and label them 'Shopping'."

  • "Block everything from marketing.example.com."

  • "Create a rule that blocks newsletters (List-Unsubscribe header) sent to my shop@ alias."

  • "Why did mail to my bank alias fail last week?"

Tools

Area

Tools

Account

get_account_details, get_api_token_details, get_account_notifications, get_domain_options, get_app_version

Aliases

list_aliases, get_alias, create_alias, update_alias, delete_alias, restore_alias, forget_alias, set_alias_option (active / pinned / attached-recipients-only), set_alias_recipients, set_alias_labels

Bulk aliases

bulk_alias_action (get / activate / deactivate / pin / unpin / delete / restore / forget), bulk_set_alias_recipients, bulk_set_alias_labels

Recipients

list_recipients, get_recipient, create_recipient, update_recipient, delete_recipient, resend_recipient_verification, add_recipient_public_key, remove_recipient_public_key, set_recipient_option (active / can reply-send / encryption / inline encryption / protected headers / strip PGP keys / strip PGP signatures)

Usernames

list_usernames, get_username, create_username, update_username, delete_username, set_username_default_recipient, set_username_option (active / catch-all / can login)

Domains

list_domains, get_domain, create_domain, update_domain, delete_domain, set_domain_default_recipient, check_domain_sending_records, set_domain_option (active / catch-all / shared with family)

Labels

list_labels, get_label, create_label, update_label, delete_label

Rules

list_rules, get_rule, create_rule, update_rule, delete_rule, reorder_rules, set_rule_active

Blocklist

list_blocklist, add_to_blocklist, remove_from_blocklist

Failed deliveries

list_failed_deliveries, get_failed_delivery, download_failed_delivery, resend_failed_delivery, delete_failed_deliveries

Every tool is labelled read-only, write, or destructive (MCP tool annotations), so clients like Claude can ask before running anything risky. Deleting an alias can be undone with restore_alias. Forgetting an alias is permanent.

Privacy and security

  • The server runs locally and talks only to addy.io (or your ADDY_BASE_URL). It has no telemetry.

  • Your API key gives full access to your addy.io account. Use a dedicated key so you can revoke it on its own, and turn on ADDY_READ_ONLY if you only want Claude to look things up.

  • Anything the tools return (alias addresses, descriptions, failed-delivery emails) is passed to your AI client, and is subject to that client's privacy policy.

Development

git clone https://github.com/Former-Stranger/addy-mcp
cd addy-mcp
uv run --no-editable python -m pytest      # unit tests (mocked HTTP, never touch a real account)
uv run ruff check && uv run ruff format --check

scripts/live_test.py exercises the server against a real account: it creates, updates, deletes, restores and finally forgets a throwaway alias and label. Run it with ADDY_API_KEY=... uv run --no-editable python scripts/live_test.py --yes.

--no-editable: on some macOS setups files in .venv get the "hidden" flag, and Python 3.13+ ignores hidden .pth files, which breaks editable installs. A regular install sidesteps that.

Releasing

  1. Bump version in pyproject.toml, run uv run python scripts/sync_metadata.py, and update CHANGELOG.md.

  2. Commit, then tag and push: git tag v0.2.0 && git push origin v0.2.0.

  3. Approve the pypi deployment when GitHub asks (the release pauses until a maintainer approves it).

The release workflow publishes to PyPI, attaches the .mcpb bundle to a GitHub release, and updates the MCP Registry listing.

A weekly workflow compares the addy.io API docs with scripts/addy_api_snapshot.txt and opens an issue when the API changes. After updating the tools, refresh the snapshot with python3 scripts/check_api_docs.py --update. Dependabot opens weekly pull requests for dependency and GitHub Actions updates.

License

MIT

Available Tools

62 tools
add_recipient_public_keyA
Idempotent

Add a public GPG key to a recipient so forwarded mail can be encrypted.

Inputs: key_data (required), recipient_id (required).

add_to_blocklistA

Block mail from sender email addresses or whole domains, across all aliases.

Inputs: type (required), values (required).

bulk_alias_actionA
Destructive

Apply one action to up to 25 aliases at once (or fetch them with action='get').

Inputs: action (required), alias_ids (required).

bulk_set_alias_labelsB
Idempotent

Replace the labels of up to 25 aliases at once.

Inputs: alias_ids (required), label_ids (required).

bulk_set_alias_recipientsB
Idempotent

Replace the recipients of up to 25 aliases at once.

Inputs: alias_ids (required), recipient_ids (required), family_member_ids, family_reply_send_ids.

check_domain_sending_recordsB
Read-only

Check a custom domain's DNS records (SPF, DKIM, DMARC, ...) for sending/replying from aliases.

Inputs: domain_id (required).

create_aliasB

Create a new alias. Use get_domain_options to see which domains are available.

Inputs: domain (required), format, label_ids, local_part, +2 more.

create_domainA

Add a custom domain. Its DNS must already have the TXT verification record addy.io shows in its dashboard.

Inputs: domain (required).

create_labelC

Create a label for organising aliases.

Inputs: name (required), colour (required).

create_recipientA

Add a new recipient. addy.io emails it a verification link; it can't be used until verified.

Inputs: email (required).

create_ruleA

Create a rule that runs actions on emails matching conditions.

Example: block newsletters to a specific alias -> conditions=[{type:'alias', match:'is exactly', values:['shop@anonaddy.me']}, {type:'header', match:'exists', values:['List-Unsubscribe']}], actions=[{type:'block'}].

Inputs: name (required), actions (required), conditions (required), sends, +3 more.

create_usernameA

Create an additional username (counts against the plan's username limit).

Inputs: username (required).

delete_aliasA
Destructive

Delete an alias. It stops receiving mail but can be brought back with restore_alias.

Inputs: alias_id (required).

delete_domainA
Destructive

Delete a custom domain. Its aliases stop working.

Inputs: domain_id (required).

delete_failed_deliveriesB
Destructive

Delete failed delivery records (and any stored email).

Inputs: failed_delivery_ids (required).

delete_labelB
Destructive

Delete a label (aliases are kept, just unlabelled).

Inputs: label_id (required).

delete_recipientA
Destructive

Delete a recipient. Aliases that used it fall back to the default recipient.

Inputs: recipient_id (required).

delete_ruleC
Destructive

Delete a rule.

Inputs: rule_id (required).

delete_usernameB
Destructive

Delete a username. Its aliases stop working.

Inputs: username_id (required).

download_failed_deliveryA
Read-only

Download the raw email (.eml source) of a failed delivery, if addy.io stored it.

Inputs: failed_delivery_id (required). Returns: result

forget_aliasA
Destructive

PERMANENTLY forget an alias: it is disassociated from the account and cannot be restored.

Inputs: alias_id (required).

get_account_detailsA
Read-only

Get account details: username, plan/subscription, bandwidth used, default alias domain/format, limits, etc.

Inputs: no named parameters.

get_account_notificationsB
Read-only

Get account notifications/announcements from addy.io.

Inputs: no named parameters.

get_aliasA
Read-only

Get a single alias, including its recipients, labels and statistics.

Inputs: alias_id (required).

get_api_token_detailsA
Read-only

Get the name, creation date and expiry of the API token this server is using.

Inputs: no named parameters.

get_app_versionA
Read-only

Get the addy.io app version (only available on self-hosted instances).

Inputs: no named parameters.

get_domainA
Read-only

Get a single custom domain and its settings/verification status.

Inputs: domain_id (required).

get_domain_optionsA
Read-only

Get the domains available for creating aliases, plus the account's default alias domain and format.

Inputs: no named parameters.

get_failed_deliveryB
Read-only

Get details of a failed delivery (sender, alias, bounce reason, ...).

Inputs: failed_delivery_id (required).

get_labelC
Read-only

Get a single label.

Inputs: label_id (required).

get_recipientB
Read-only

Get a single recipient and its settings.

Inputs: recipient_id (required), include_alias_count.

get_ruleA
Read-only

Get a single rule with its conditions and actions.

Inputs: rule_id (required).

get_usernameC
Read-only

Get a single username and its settings.

Inputs: username_id (required).

list_aliasesB
Read-only

List or search aliases. Results are paginated; the response includes meta with totals and page counts.

Inputs: page, sort, active, pinned, +9 more.

list_blocklistB
Read-only

List blocked senders/domains, with how many emails each has blocked.

Inputs: page, sort, type, search, +2 more.

list_domainsA
Read-only

List the custom domains connected to the account.

Inputs: no named parameters.

list_failed_deliveriesA
Read-only

List emails that addy.io failed to deliver (or quarantined).

Inputs: page, page_size, email_type.

list_labelsC
Read-only

List the labels used to organise aliases.

Inputs: search.

list_recipientsA
Read-only

List the account's recipients (the real mailboxes aliases forward to).

Inputs: verified, include_alias_count.

list_rulesA
Read-only

List all rules, in the order they are applied.

Inputs: no named parameters.

list_usernamesA
Read-only

List the account's usernames (each gives a subdomain like name.anonaddy.com for on-the-fly aliases).

Inputs: no named parameters.

remove_from_blocklistA
Destructive

Unblock blocklist entries by id (see list_blocklist).

Inputs: entry_ids (required).

remove_recipient_public_keyB
Destructive

Remove a recipient's public GPG key (this also turns off encryption for it).

Inputs: recipient_id (required).

reorder_rulesB
Idempotent

Set the order rules are applied in.

Inputs: rule_ids (required).

resend_failed_deliveryB

Retry delivering a failed or quarantined email.

Inputs: failed_delivery_id (required), recipient_ids.

resend_recipient_verificationA

Resend the verification email for an unverified recipient.

Inputs: recipient_id (required).

restore_aliasC

Restore a deleted alias.

Inputs: alias_id (required).

set_alias_labelsB
Idempotent

Replace the labels attached to an alias.

Inputs: alias_id (required), label_ids (required).

set_alias_optionB
Idempotent

Turn an alias option on or off (activate/deactivate, pin/unpin, limit reply/send to attached recipients).

Inputs: option (required), enabled (required), alias_id (required).

set_alias_recipientsB
Idempotent

Replace the set of recipients an alias forwards to.

Inputs: alias_id (required), recipient_ids (required), family_member_ids, family_reply_send_ids.

set_domain_default_recipientB
Idempotent

Set (or clear) the default recipient for aliases on a custom domain.

Inputs: domain_id (required), recipient_id (required).

set_domain_optionC
Idempotent

Turn a custom domain option on or off.

Inputs: option (required), enabled (required), domain_id (required).

set_recipient_optionC
Idempotent

Turn a recipient option on or off.

Inputs: option (required), enabled (required), recipient_id (required).

set_rule_activeC
Idempotent

Activate or deactivate a rule.

Inputs: active (required), rule_id (required).

set_username_default_recipientA
Idempotent

Set (or clear) the default recipient for aliases on a username.

Inputs: username_id (required), recipient_id (required).

set_username_optionC
Idempotent

Turn a username option on or off.

Inputs: option (required), enabled (required), username_id (required).

update_aliasB
Idempotent

Update an alias's description, from name, or labels. Only the fields you pass are changed.

Inputs: alias_id (required), from_name, label_ids, description.

update_domainC
Idempotent

Update a custom domain's description, from name, or auto-create regex.

Inputs: domain_id (required), from_name, description, auto_create_regex.

update_labelB
Idempotent

Rename a label or change its colour.

Inputs: label_id (required), name, colour.

update_recipientB
Idempotent

Set a recipient's description.

Inputs: description (required), recipient_id (required).

update_ruleA
Idempotent

Update a rule. Only the fields you pass change; the rest are kept from the current rule.

Inputs: rule_id (required), name, sends, actions, +4 more.

update_usernameC
Idempotent

Update a username's description, from name, or auto-create regex.

Inputs: username_id (required), from_name, description, auto_create_regex.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.1/5.0

    Scored across 62 tools

    Disambiguation4/5

    Each tool targets a distinct resource+action, and the descriptions carefully separate delete_alias / restore_alias / forget_alias and the three bulk tools. Some overlap remains: update_alias can change labels while set_alias_labels exists, and bulk_alias_action acts as a catch-all that shadows the per-alias update/delete/option tools. The generic set_*_option tools also require guessing valid option names.

    Naming Consistency4/5

    The set is dominated by a clean verb_noun snake_case pattern (get_alias, create_recipient, set_domain_option, resend_failed_delivery). A few deviations break the pattern: bulk_alias_action is vague where its siblings are bulk_set_alias_* , forget_alias uses a non-standard verb, and blocklist tools mix list_blocklist with add_to_blocklist / remove_from_blocklist.

    Tool Count2/5

    62 tools is heavy for an alias-management API; four near-identical set_*_option tools (alias, domain, username, recipient) plus four bulk variants could be consolidated. Several resources get full CRUD plus option/default-recipient/DNS sub-tools, inflating the surface well past the comfortable 3-15 range.

    Completeness4/5

    Coverage is broad and lifecycle-complete for aliases, recipients, domains, usernames, rules, labels, blocklist and failed deliveries, including soft-delete/restore and bulk paths. Minor gaps: API tokens are read-only (no create/revoke), and there is no standalone alias statistics or DNS-record-set operation beyond checking/setting options.

    Maintenance

    ActivityMaintained
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that provides Claude with access to your Gmail, featuring a full OAuth 2.1 authorization server with dynamic client registration and tools to list, read, search, send, reply, draft, archive, trash, manage labels, and download attachments.
      283 npm
      1
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      Local IMAP/SMTP MCP server that lets Claude read, search, draft, send, flag, and move mail across multiple IMAP mailboxes. Credentials stay on your machine.
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables Claude to read, search, send, draft, and organize email across multiple independently authenticated Gmail accounts through one local MCP connection. It supports account aliases, per-account default From addresses, dry-run sends, and draft-only replies for safer multi-account email management.
      101 npm
      MIT