
epost-mcp
by sapn95
epost-mcp
Read, download and archive your Swiss ePost digital letterbox — over the documented public API, with browser automation as a fallback.
</div>Unofficial. Not affiliated with ePost or Swiss Post. It speaks their documented public API where it can and falls back to driving the web portal where it cannot — that fallback is inherently fragile, since portal updates break selectors without warning. Use it for your own letterbox and respect the provider's terms of service.
An MCP server for the Swiss ePost digital letterbox (app.epost.ch). It lets an MCP client (Claude Code, Claude Desktop, …) list and download your scanned letters and do basic housekeeping in the ePost Storage area — folders and moving documents.
ePost does publish a public API for the Digital Letterbox, and a private tenant can use it — see Transport below. That is the preferred path: no browser, no session, and letters arrive with a real sender description. Browser automation via Playwright remains for the few things the API does not cover.
Prerequisites
- Node.js ≥ 20.19
- A Chromium managed by Playwright
- A Swiss ePost account with the Scanning-Service, reachable via SwissID
git clone https://github.com/sapn95/epost-mcp.git
cd epost-mcp
npm install
npx playwright install chromium # downloads the browser Playwright drives
Session / login model
The hard part of ePost automation is the login. This server keeps you logged in so you do not re-authenticate on every call or every restart:
- The SwissID/ePost session is cached as a Playwright storageState file at
~/.epost-mcp/state.json(49 cookies incl. the KLARA/Keycloak SSO cookies). - On startup the server loads that file, so a previously logged-in session is reused across server restarts.
- After a successful
epost_loginand after every successful tool call, the server re-savesstate.json, keeping the cached session fresh. epost_loginopens a visible (headed) browser window so you complete the SwissID login (incl. 2FA) yourself. Every other tool runs headless.- SwissID sessions are short-lived. When the session expires, tools return
login_required— just runepost_loginagain.
First-time / after-expiry flow:
- Call
epost_status. If it returnslogin_required… - …call
epost_login. A browser window opens on app.epost.ch. Complete the SwissID login until you see your dashboard / the letterbox. The session is then cached to~/.epost-mcp/state.json. - Use
epost_list_letters,epost_download_letter, etc. headlessly.
Security:
~/.epost-mcp/state.jsoncontains live session cookies for your ePost/SwissID account. Treat it like a password. It is git-ignored in this repo and must never be committed, shared, or synced to a cloud folder. Delete it to force a fresh login. Override its location withEPOST_STATE.
Transport: the public API, with the browser as fallback
ePost publishes a REST API for the Digital Letterbox, and a private tenant can use it — which is easy to miss, because the developer portal is written for business clients. The API is preferred for everything it covers; browser automation runs only
Related servers

n8n
by n8n-io
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.

@modelcontextprotocol/server-everything
OfficialMCP server that exercises all the features of the MCP protocol

@modelcontextprotocol/server-filesystem
OfficialMCP server for filesystem access