Architecture
Client & Server
MCP Ambassador is a two-component system. The Ambassador Server is the central hub; the Ambassador Client is the lightweight local agent.
Ambassador Server
The server is a Node.js application running in a single Docker container. It:
- Authenticates and manages users, groups, and clients
- Maintains the MCP catalog (which MCPs exist and their configurations)
- Spawns and proxies downstream MCP processes per user
- Enforces RBAC and kill switches
- Exposes two APIs:
- Client API on port
8443— Ambassador Clients connect here - Admin + User Web UI on port
9443— browser and admin API access
- Client API on port
Internal components
| Component | Role |
|---|---|
| Auth layer | Validates session tokens, rate limits login, prevents session fixation |
| Proxy engine | Routes tool calls to the right downstream MCP process |
| Credential vault | AES-256-GCM encrypted storage for user API keys |
| RBAC engine | Group membership → MCP access → per-client tool selection |
| Audit logger | Records every tool invocation with user, client, tool, args, result |
Ambassador Client
The Ambassador Client is an npm package (@mcpambassador/client) that runs as a local MCP server in the AI tool's process. It speaks the MCP protocol upstream (to Claude, VS Code, etc.) and the Ambassador Client API downstream (to the server).
Responsibilities
- Register with the server on first run using a preshared key
- Receive an ephemeral session token (
amb_st_...) - Fetch the personalized tool catalog for this user/client
- Forward tool calls from the AI tool to the server
- Return results to the AI tool
The client is intentionally minimal — no credentials, no MCP configs, no local processes. All intelligence lives on the server.
Communication flow
Registration (first run)
AI Tool Ambassador Client Ambassador Server
| | |
| spawn | |
|─────────────────> | |
| | POST /v1/clients/register
| | { preshared_key, friendly_name, host_tool }
| |─────────────────────>|
| | | validate preshared key
| | | create client record
| |<─────────────────────|
| | { session_token, ca_fingerprint }
| | |
Tool invocation
AI Tool Ambassador Client Ambassador Server Downstream MCP
| | | |
| tools/call | | |
|─────────────────> | | |
| | POST /v1/tools/call | |
| | X-Session-Token: ... | |
| |─────────────────────>| |
| | | validate session |
| | | check RBAC |
| | | check kill switch |
| | | log invocation |
| | | forward call |
| | |─────────────────> |
| | |<───────────────── |
| | | log result |
| |<─────────────────────| |
|<───────────────── | | |
Session tokens
Session tokens (amb_st_...) are ephemeral HMAC-SHA256 tokens:
- Generated at registration
- Tied to a specific client ID and user
- Validated on every tool call (no database hit — HMAC verification)
- Expire after inactivity (renewed via
/v1/session/heartbeat) - Revoked immediately when a client is deactivated
The Ambassador Client stores the session token in memory only — not on disk. If the client process restarts, it re-registers using the preshared key.
TLS and certificate pinning
All traffic between the Ambassador Client and Server is HTTPS. On registration, the server returns its CA certificate fingerprint. The client pins this fingerprint for subsequent connections — no manual certificate installation required, and no vulnerability to MITM attacks even with self-signed certificates.
Multiple clients per user
One user can have many Ambassador Clients — one per device or AI tool:
- Laptop: VS Code client
- Laptop: Claude Desktop client
- CI/CD: Automated agent client
Each client is registered separately, gets its own session token, and can have a different subset of tools enabled. An admin can deactivate individual clients without affecting others.
Downstream MCP processes
When the server receives a tool call, it routes it to the appropriate downstream MCP process:
- Shared MCPs (
per_serverisolation): one process shared across all users - Per-user MCPs (
per_userisolation): separate process per user (required when credentials differ between users)
Stdio MCPs are spawned on first call and kept alive. Credentials are injected as environment variables at spawn time and then zeroed from the server's memory.