Repository avatar
AI Tools
v1.0.2
active

mcp

io.unione/mcp

Send transactional email and manage domains, templates and webhooks in UniOne from AI agents.

Documentation

unione-mcp

The official Model Context Protocol server for UniOne (https://docs.unione.io). It lets AI assistants — Claude, ChatGPT, Cursor, Windsurf, VS Code, Cline and any other MCP client — work with your UniOne account: send email, manage sender domains, templates, webhooks, suppressions, event dumps, tags and projects. 32 tools, each one a call of the public UniOne Web API.

Two ways to use it:

  • Remote — the hosted server at https://mcp.unione.io/mcp. Nothing to install: add the URL to your client and sign in to UniOne through OAuth.
  • Local — the server runs on your machine over stdio (npx, Docker or a binary) and acts with the API key you put into UNIONE_API_KEY.

Remote server (OAuth)

URL: https://mcp.unione.io/mcp

The client opens the UniOne sign-in page on first use; you approve the access and the client keeps the token. Revoke it at any time in your UniOne account.

Claude Code

claude mcp add --transport http unione https://mcp.unione.io/mcp

Claude Desktop / claude.ai — Settings → Connectors → Add custom connector, URL https://mcp.unione.io/mcp.

Cursor, Windsurf, Cline, VS Code and other clients with an mcpServers config:

{
  "mcpServers": {
    "unione": {
      "type": "http",
      "url": "https://mcp.unione.io/mcp"
    }
  }
}

A client that cannot do OAuth can send an API key instead: add the header Authorization: Bearer <UniOne API key>.

Local server (API key)

Get an API key in your UniOne account: an account key reaches the whole account, a project key only its project. The server reads it from UNIONE_API_KEY.

npx (Node.js 18+; downloads the binary for your platform on first run):

{
  "mcpServers": {
    "unione": {
      "command": "npx",
      "args": ["-y", "unione-mcp"],
      "env": { "UNIONE_API_KEY": "<your API key>" }
    }
  }
}

Docker:

{
  "mcpServers": {
    "unione": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "UNIONE_API_KEY", "ghcr.io/unione-repo/unione-mcp", "stdio"],
      "env": { "UNIONE_API_KEY": "<your API key>" }
    }
  }
}

Binary — download unione-mcp-<os>-<arch> from Releases, make it executable and put it on your PATH (or go install github.com/unione-repo/unione-mcp/cmd/unione-mcp@latest):

{
  "mcpServers": {
    "unione": {
      "command": "unione-mcp",
      "args": ["stdio"],
      "env": { "UNIONE_API_KEY": "<your API key>" }
    }
  }
}

Claude Code, in one line:

claude mcp add unione --env UNIONE_API_KEY=<your API key> -- npx -y unione-mcp

Check the connection by asking "show my UniOne account": the assistant calls get_account.

Tools

Every tool has a class, sent to the client as MCP annotations:

  • read — reads only (readOnlyHint);
  • write — creates or changes something, nothing is lost (destructiveHint: false);
  • dangerous — deletes or overwrites for good, or cannot be taken back (destructiveHint: true). Clients ask you before such a call.
AreaToolWhat it doesClass
Accountget_accountGet UniOne accountread
Domainslist_domainsList sender domainsread
Domainsget_dns_recordsAdd domain / get its DNS recordswrite
Domainsvalidate_domainCheck domain DNS recordsread
Domainsdelete_domainDelete sender domaindangerous
Domainsget_sandbox_domainGet sandbox domainwrite
Confirmed emailslist_confirmed_emailsList confirmed emailsread
Confirmed emailsadd_confirmed_emailAdd confirmed emailwrite
Confirmed emailsdelete_confirmed_emailDelete confirmed emaildangerous
Sendingsend_emailSend email (billed)dangerous
Templateslist_templatesList templatesread
Templatesget_templateGet templateread
Templatesset_templateCreate or overwrite templatedangerous
Templatesdelete_templateDelete templatedangerous
Webhookslist_webhooksList webhooksread
Webhooksget_webhookGet webhookread
Webhooksset_webhookCreate or overwrite webhookdangerous
Webhooksdelete_webhookDelete webhookdangerous
Suppressionsget_suppressionGet suppression of an addressread
Suppressionslist_suppressionsList suppressionsread
Suppressionsset_suppressionBlock an addressdangerous
Suppressionsdelete_suppressionUnblock an addressdangerous
Validationvalidate_emailValidate an email address (billed)write
Event dumpsrequest_event_dumpRequest event dumpwrite
Event dumpsget_event_dumpGet event dumpread
Event dumpsdelete_event_dumpDelete event dumpdangerous
Tagslist_tagsList tagsread
Tagsdelete_tagDelete tagdangerous
Projectslist_projectsList projectsread
Projectscreate_projectCreate projectwrite
Projectsupdate_projectUpdate projectdangerous
Projectsdelete_projectDelete projectdangerous

send_email sends real mail and cannot be recalled. validate_email is billed per address. The tools that reach beyond your account — send_email and add_confirmed_email mail an address, set_webhook points UniOne at a URL, validate_email probes a mailbox — say so with openWorldHint: true.

Read-only and no-send modes

Two switches narrow the tool list of a local server:

VariableEffect
MCP_READ_ONLY=1only the read tools are listed: the assistant cannot change the account
MCP_DISABLE_SEND=1send_email is not listed: the assistant cannot send mail
"env": { "UNIONE_API_KEY": "<your API key>", "MCP_READ_ONLY": "1" }

With Docker, env reaches only the docker process: pass the switch into the container with its own -e, before the image name.

"args": ["run", "-i", "--rm", "-e", "UNIONE_API_KEY", "-e", "MCP_READ_ONLY", "ghcr.io/unione-repo/unione-mcp", "stdio"],
"env": { "UNIONE_API_KEY": "<your API key>", "MCP_READ_ONLY": "1" }

They guard against mistakes of the model, not against the key's owner: the same key works in the Web API directly. For a hard limit use a project API key.

Configuration

Everything is an environment variable; a .env file in the working directory is read too. .env.example lists them all. Every value is validated at start-up.

VariablePurpose
UNIONE_API_KEYlocal mode: the API key every tool acts with
UNIONE_API_URLWeb API base, default https://api.unione.io/en/transactional/api/v1
MCP_TRANSPORThttp (default) or stdio; unione-mcp stdio sets it too
MCP_READ_ONLY, MCP_DISABLE_SENDsee above
AUTH_MODEself-hosted http mode: api_key (default) or oauth
AUTHORIZATION_SERVER_URL, OAUTH_SCOPES, OAUTH_TOKEN_PREFIX, MCP_PUBLIC_URLself-hosted oauth mode. OAUTH_TOKEN_PREFIX defaults to uoat_.
LISTEN_HOST, PORTself-hosted http mode listener (default: every interface, first free port from 3000)
UPSTREAM_TIMEOUT, UPSTREAM_MAX_BODY_BYTES, MCP_MAX_REQUEST_BYTESWeb API call limits and the /mcp body cap
LOG_LEVEL, LOG_FORMATdebug, info, warn, error; text or json, always to stderr

The API key, the Authorization header and Web API response bodies are never logged.

Documentation

Development

go build -o bin/unione-mcp ./cmd/unione-mcp
go test ./internal/... ./cmd/...                     # unit tests, no network

# acceptance: the real binary over HTTP and stdio against a WireMock stand-in of the API
docker run -d --rm -p 8081:8081 wiremock/wiremock:3.4.1 --local-response-templating --port 8081
E2E_WIREMOCK_URL=http://localhost:8081 go test -tags=integration ./tests/...

License

MIT

No installation packages available.

Remote