Multi-user setup
In remote-relay and remote-oauth modes, an MCP server stores credentials per JWT subject (the sub field of the bearer token your client sends). One deployed server serves N users without leaking creds across users.
How it works
Section titled “How it works”- Each user authenticates against your deployed server. They get a JWT with their
sub(typically email or GitHub username). - When the user first invokes a tool that needs credentials (e.g. Notion API key), the server detects no credentials exist for that
suband triggers the relay flow — opens a browser athttps://<server>.your-domain/authorize. - The user fills the form (paste API token, OAuth login, etc.). Server encrypts and stores under key
<server-name>:<sub>. - Subsequent tool invocations from the same user route to the same encrypted bundle.
Deployment
Section titled “Deployment”Self-hosted via Docker:
docker run -d \ -p 8080:8080 \ -e MCP_TRANSPORT=http \ -e PUBLIC_URL=https://wet-mcp.your-domain.com \ -e JWT_PUBLIC_KEY="<your-jwt-public-key>" \ ghcr.io/n24q02m/wet-mcp:latestBehind any reverse proxy that adds Authorization: Bearer <token>. Caddy + Cloudflare Tunnel is the canonical pattern.
OAuth provider (remote-oauth mode)
Section titled “OAuth provider (remote-oauth mode)”Server doubles as an OAuth Authorization Server. Clients implement standard OAuth 2.1 flow:
GET /.well-known/oauth-authorization-serverGET /authorize?client_id=...&redirect_uri=...POST /tokenServer delegates user identity to GitHub / Google / your IdP. The OAuth sub becomes the credential storage key.
What about local mode?
Section titled “What about local mode?”stdio and local-relay modes are single-user by design. No sub involved. Don’t share config.enc across machines.
Read on
Section titled “Read on”- Modes overview — pick the right mode
- Multi-user pattern — implementation details