
epost-mcp
Updated 3d agoby sapn95
epost-mcp
Read, download and archive your Swiss ePost digital letterbox — over the documented public API, with browser automation as a fallback.
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.
How a call gets answered
Two ways in, and the server picks per call rather than per session — so the
same conversation can read a letter over the API and archive it in the browser
without you arranging anything. EPOST_TRANSPORT pins that choice if you would
rather it did not move.
flowchart TD
C["MCP client<br/>(Claude Code, Claude Desktop, …)"] -->|"stdio JSON-RPC"| S["epost-mcp"]
S --> T{"EPOST_TRANSPORT"}
T -->|"api — pinned"| A
T -->|"browser — pinned"| B
T -->|"auto (default)"| D{"Does this call<br/>reach for a page?"}
D -->|"no"| A["REST call to api.epost.ch"]
D -->|"yes — and only then<br/>is a browser launched"| B["Playwright drives<br/>app.epost.ch"]
K1["account password<br/>keychain: epost-mcp-api-password"] -->|"password grant"| KC["Keycloak token"]
KC -.->|"Authorization: Bearer"| A
K2["API key<br/>keychain: epost-mcp-api-key"] -.->|"X-API-KEY"| A
A --> E[("ePost<br/>Digital Letterbox")]
B --> E
subgraph disk["on disk — a live letterbox session, and secret"]
P["Chromium profile<br/>~/.epost-mcp/profile"]
ST["storageState<br/>~/.epost-mcp/state.json"]
end
disk -.->|"seeds the context"| B
B -.->|"state.json re-saved after<br/>every successful call"| ST
L["epost_login<br/>visible window, one Touch ID"] -.->|"fills state.json once"| ST
classDef pin fill:#fff4e5,stroke:#d9822b
classDef store fill:#fdecea,stroke:#c0392b
class T,D pin
class P,ST store
style disk fill:#fbfbfb,stroke:#999,stroke-dasharray: 4 3
A pin is enforced both ways. Pinned to api, a browser-only tool is refused
rather than quietly redirected — the point of pinning is knowing what ran.
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
Related servers

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

mcp-server-fetch
OfficialUpdated 14d agoA Model Context Protocol server providing tools to fetch and convert web content for usage by LLMs

@modelcontextprotocol/server-everything
OfficialUpdated 14d agoMCP server that exercises all the features of the MCP protocol