Skip to content

Transports

Version scope: Managed startup and the embedded React UI on this page are Local Email App V2 behavior. See Version availability before using these commands with a PyPI installation.

mcp-email-server supports stdio, SSE, and Streamable HTTP transports. Use stdio for a local MCP client unless a network transport is specifically required.

CLI commands

mcp-email-server --version
mcp-email-server stdio
mcp-email-server sse [--host HOST] [--port PORT]
mcp-email-server streamable-http [--host HOST] [--port PORT]
mcp-email-server ui [--no-open] [--port PORT]
mcp-email-server reset --confirm RESET [--json]
mcp-email-server migrate-credentials [--to keyring|plaintext] [--json]
mcp-email-server config {init|status|doctor|index-health|policy|update-policy|cleanup-credentials|import-legacy|select}
mcp-email-server account {add|set-secret|list|show|update|disable|enable|remove|remove-secret|test}
mcp-email-server-plugin

mcp-email-server-plugin is the dedicated plugin entry point. It accepts no transport or management command and starts the same bounded stdio server directly. Because this entry point is introduced with the mail-only Local Email App V2 catalog, resolving mcp-email-server@latest fails closed on earlier packages instead of starting their legacy MCP surface.

Run mcp-email-server COMMAND --help or mcp-email-server config|account COMMAND --help for current options. Managed setup and mode selection are documented in Configuration. Every finite nested management command has a leaf --json option, for example mcp-email-server config status --json; see Machine-readable CLI output. --help, --version, transports, and the foreground UI remain text/protocol interfaces rather than CLI result documents. The managed CLI is the low-level agent management API and retains catalog, revision, binding-state, and restart-state terms. Its JSON documents use schema_version: 1, typed error codes with fixed safe messages, and post-operation revision/restart data; JSON never grants authority to run a command, and secret-writing commands accept secrets only from user-controlled stdin. account test remains the agent-facing provider-connectivity diagnostic. The Web UI intentionally has no corresponding connectivity control or route.

stdio

stdio is the recommended transport for Claude Desktop and other local MCP clients. The client starts the server and communicates through standard input and output.

{
  "mcpServers": {
    "mcp-email-server": {
      "command": "uvx",
      "args": ["mcp-email-server@latest", "stdio"]
    }
  }
}

Do not write unrelated output to stdout when wrapping a stdio server process, because stdout carries newline-delimited UTF-8 MCP JSON-RPC frames. Local Email App V2 rejects malformed UTF-8/JSON and frames larger than 2 MiB with bounded, redacted diagnostics, remains usable after a rejected frame, propagates MCP cancellation, and cancels in-flight work before cleanup on EOF.

The process resolves the bootstrap mode at startup. An explicitly selected managed mode loads only the exact supported catalog schema and its active secret bindings. Linux and Windows resolve those bindings from the private managed SQLite secret store; Windows first enforces local fixed NTFS security. macOS uses the system keyring. A missing, corrupt, incompatible, or insecure selected catalog fails closed and never falls back to preserved legacy TOML accounts. Restart stdio after every config select command.

The tool catalog remains static during the process. Account disablement, re-enablement, credential changes, endpoint changes, and policy changes are revalidated on each operation and do not rewrite tools/list. Normal shutdown, EOF, cancellation, or transport lifespan exit closes application runtime resources and discards the process cache.

SSE

Start the legacy SSE transport with:

mcp-email-server sse --host localhost --port 9557

With the default host and port, the FastMCP endpoints are:

SSE stream:      http://localhost:9557/sse
SSE messages:    http://localhost:9557/messages/

MCP clients normally configure the /sse URL; the stream tells the client where to send messages.

The default host is localhost and the default port is 9557. Configure the SSE bind address with command-line options; MCP_HOST and MCP_PORT are not used as defaults by this command.

Prefer Streamable HTTP for new network integrations when the MCP client supports it.

Streamable HTTP

Start the server with:

mcp-email-server streamable-http --host localhost --port 9557

Connect the MCP client to:

http://localhost:9557/mcp

The host and port can also be supplied as defaults through environment variables:

MCP_HOST=0.0.0.0 \
MCP_PORT=9557 \
mcp-email-server streamable-http

Explicit --host and --port options override those defaults.

Variable Default Description
MCP_HOST localhost Bind host for Streamable HTTP.
MCP_PORT 9557 Bind port for Streamable HTTP.
MCP_ALLOWED_HOSTS Derived safe values Comma-separated allowed HTTP Host values.
MCP_ALLOWED_ORIGINS Derived safe values Comma-separated allowed HTTP Origin values.
MCP_ENABLE_DNS_REBINDING_PROTECTION true Enable Host and Origin validation.

DNS rebinding protection

Both HTTP transports validate Host and Origin headers by default. Loopback hosts and origins are allowed for local use.

When binding to a named non-loopback host, that host is included in the derived allowlist. When binding to a wildcard address such as 0.0.0.0 or ::, the server cannot infer the public hostname. Configure the expected service names explicitly:

MCP_HOST=0.0.0.0 \
MCP_ALLOWED_HOSTS='mail-mcp.example.com,mcp-email-server' \
MCP_ALLOWED_ORIGINS='https://mail-mcp.example.com' \
mcp-email-server streamable-http

A bare host entry also permits any port on that host. For example, mcp-email-server expands to include mcp-email-server:*.

Specify IPv6 literals with brackets:

MCP_ALLOWED_HOSTS='[::1]:*,[2001:db8::10]:*'
MCP_ALLOWED_ORIGINS='http://[::1]:*,https://[2001:db8::10]:*'

Any of the following disables Host and Origin validation entirely:

MCP_ENABLE_DNS_REBINDING_PROTECTION=false
MCP_ALLOWED_HOSTS='*'
MCP_ALLOWED_ORIGINS='*'

Use these escape hatches only in an isolated development environment. Prefer explicit allowlists behind containers and reverse proxies.

Reverse proxies

Preserve the FastMCP endpoint paths through the proxy: /sse and /messages/ for SSE, or /mcp for Streamable HTTP. These are the current SDK defaults because this project does not override the path settings.

When a reverse proxy terminates TLS:

  • Bind the server to a private interface whenever possible.
  • Add the externally visible host to MCP_ALLOWED_HOSTS.
  • Add the browser or client origin, including its scheme, to MCP_ALLOWED_ORIGINS.
  • Preserve the request headers expected by the MCP transport.
  • Apply authentication and network access controls at the proxy or surrounding platform; transport exposure does not by itself authenticate arbitrary users.

Other CLI operations

Open the foreground managed management interface with:

mcp-email-server ui [--no-open] [--port PORT]

The UI always binds exactly to 127.0.0.1; port 0 is the default. It does not read MCP_HOST, MCP_PORT, HTTP transport allowlists, or framework sharing and debug settings. --no-open suppresses browser launch and prints the one-time fragment URL only to an attached stdout/stderr TTY. The same TTY-only fallback is used when automatic browser launch reports failure. Without an attached TTY, startup fails before serving instead of sending the token through a pipe or log. After authentication, empty-install account-storage preparation is a CSRF-protected browser POST to a backend-selected local path, not a startup or GET side effect; detected legacy content requires an explicit preparation action. Keep the process in the foreground and use SIGINT or SIGTERM for graceful session invalidation and shutdown.

Remove persistent legacy configuration with:

mcp-email-server reset --confirm RESET

Move credentials between the TOML file and operating system keyring with:

mcp-email-server migrate-credentials --to keyring
mcp-email-server migrate-credentials --to plaintext

Reset deletes every persistent legacy account and performs best-effort cleanup of its referenced keyring entries, so exact uppercase confirmation is mandatory. Reset and credential migration are legacy compatibility operations and are rejected while managed mode is selected. Both support one-document --json results for user-owned automation. The UI and nested config/account commands are equivalent managed management adapters; the UI can also guide an explicit import while legacy mode is selected. Credential behavior and migration caveats are covered in Security.