About UniOne
UniOne’s official MCP server lets AI assistants operate UniOne accounts through the public Web API, with hosted OAuth or local API-key access. It covers email delivery and account administration, with controls for read-only and no-send use.
Key features
- 01Send transactional email
- 02Manage sender domains and templates
- 03Configure webhooks and suppressions
- 04Inspect events, tags, projects and account
- 05Restrict tools to read-only or no-send
Use cases
- 01Send transactional messages from an AI assistant
- 02Review or update sender domains and templates
- 03Inspect delivery events and account projects
- 04Limit an integration to read-only operations
MCP support
Exposes 32 UniOne Web API operations as MCP tools. Clients can connect to the hosted HTTP server with OAuth or use the local stdio server with an API key.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://mcp.unione.io/mcpclaude mcp add --transport http io-unione https://mcp.unione.io/mcp{"mcpServers":{"io-unione":{"type":"http","url":"https://mcp.unione.io/mcp"}}}Open in Cursor{"servers":{"io-unione":{"type":"http","url":"https://mcp.unione.io/mcp"}}}Open in VS Code{"mcpServers":{"io-unione":{"type":"http","url":"https://mcp.unione.io/mcp"}}}{"mcpServers":{"io-unione":{"serverUrl":"https://mcp.unione.io/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
https://mcp.unione.io/mcpAuth requiredTools
Details
From the project READMEunione-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.
| Area | Tool | What it does | Class |
|---|---|---|---|
| Account | get_account | Get UniOne account | read |
| Domains | list_domains | List sender domains | read |
| Domains | get_dns_records | Add domain / get its DNS records | write |
| Domains | validate_domain | Check domain DNS records | read |
| Domains | delete_domain | Delete sender domain | dangerous |
| Domains | get_sandbox_domain | Get sandbox domain | write |
| Confirmed emails | list_confirmed_emails | List confirmed emails | read |
| Confirmed emails | add_confirmed_email | Add confirmed email | write |
| Confirmed emails | delete_confirmed_email | Delete confirmed email | dangerous |
| Sending | send_email | Send email (billed) | dangerous |
| Templates | list_templates | List templates | read |
| Templates | get_template | Get template | read |
| Templates | set_template | Create or overwrite template | dangerous |
| Templates | delete_template | Delete template | dangerous |
| Webhooks | list_webhooks | List webhooks | read |
| Webhooks | get_webhook | Get webhook | read |
| Webhooks | set_webhook | Create or overwrite webhook | dangerous |
| Webhooks | delete_webhook | Delete webhook | dangerous |
| Suppressions | get_suppression | Get suppression of an address | read |
| Suppressions | list_suppressions | List suppressions | read |
| Suppressions | set_suppression | Block an address | dangerous |
| Suppressions | delete_suppression | Unblock an address | dangerous |
| Validation | validate_email | Validate an email address (billed) | write |
| Event dumps | request_event_dump | Request event dump | write |
| Event dumps | get_event_dump | Get event dump | read |
| Event dumps | delete_event_dump | Delete event dump | dangerous |
| Tags | list_tags | List tags | read |
| Tags | delete_tag | Delete tag | dangerous |
| Projects | list_projects | List projects | read |
| Projects | create_project | Create project | write |
| Projects | update_project | Update project | dangerous |
| Projects | delete_project | Delete project | dangerous |
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:
| Variable | Effect |
|---|---|
MCP_READ_ONLY=1 | only the read tools are listed: the assistant cannot change the account |
MCP_DISABLE_SEND=1 | send_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.
| Variable | Purpose |
|---|---|
UNIONE_API_KEY | local mode: the API key every tool acts with |
UNIONE_API_URL | Web API base, default https://api.unione.io/en/transactional/api/v1 |
MCP_TRANSPORT | http (default) or stdio; unione-mcp stdio sets it too |
MCP_READ_ONLY, MCP_DISABLE_SEND | see above |
AUTH_MODE | self-hosted http mode: api_key (default) or oauth |
AUTHORIZATION_SERVER_URL, OAUTH_SCOPES, OAUTH_TOKEN_PREFIX, MCP_PUBLIC_URL | self-hosted oauth mode. OAUTH_TOKEN_PREFIX defaults to uoat_. |
LISTEN_HOST, PORT | self-hosted http mode listener (default: every interface, first free port from 3000) |
UPSTREAM_TIMEOUT, UPSTREAM_MAX_BODY_BYTES, MCP_MAX_REQUEST_BYTES | Web API call limits and the /mcp body cap |
LOG_LEVEL, LOG_FORMAT | debug, info, warn, error; text or json, always to stderr |
The API key, the Authorization header and Web API response bodies are never logged.
Documentation
- UniOne API: https://docs.unione.io
- Installing with an AI agent: llms-install.md
- Reporting a vulnerability: SECURITY.md
- Issues and pull requests: CONTRIBUTING.md
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
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.