Architecture
System overview
Section titled “System overview”
Agent Tier
Section titled “Agent Tier”The MCP server on port 4000. Implements the Streamable HTTP transport from the MCP SDK. Per-session McpServer instances ensure the tool registry is fresh for each connection.
Proxy Tier
Section titled “Proxy Tier”The policy engine, credential management, and audit logging. This is the core of Gatelet. It evaluates policies, applies constraints and mutations, manages encrypted OAuth tokens, and logs every operation.
Upstream Tier
Section titled “Upstream Tier”Google and Microsoft APIs. Gatelet holds the OAuth credentials and makes API calls on behalf of the agent.
Request pipeline
Section titled “Request pipeline”When the agent calls a tool:
1. Authenticate ─▸ Validate bearer token (API key)2. Resolve ─▸ Find connection + provider for this tool3. Parse policy ─▸ Load YAML policy from database4. Evaluate ─▸ Check constraints → apply mutations5. Strip params ─▸ Remove fields not in tool's input schema6. Field policy ─▸ Apply allowed_fields / denied_fields7. Execute ─▸ Call provider (upstream API)8. Filter ─▸ Apply content filters (email providers)9. Audit ─▸ Log API key, original params, mutated params, result, timing10. Respond ─▸ Return sanitized result to agentIf any step fails (auth, constraints, provider error), the pipeline short-circuits and returns a safe error message. Upstream errors are classified and sanitized — no internal details are leaked.
Session management
Section titled “Session management”The MCP server creates a new McpServer instance per session. Sessions have:
- API key binding — each session is bound to the API key that created it; requests with a different key are rejected
- 20 session cap — least-recently-used sessions are evicted when the cap is reached
- 48-hour TTL — idle sessions are automatically cleaned up after 48 hours of inactivity
- Fresh tool registry — each session rebuilds the tool list from current policies
This ensures policy changes take effect on the next agent connection without restarting the server.
Project structure
Section titled “Project structure”src/ admin/ Admin API + routes (Hono on :4001) db/ SQLite + encrypted credential storage (libsodium) doctor/ Health checks (CLI + admin API) mcp/ MCP server (raw HTTP on :4000, Streamable HTTP transport) policy/ Policy engine (pure functions, no side effects) providers/ Provider implementations google-calendar/ Google Calendar via googleapis outlook-calendar/ Outlook Calendar via Microsoft Graph gmail/ Gmail via googleapis outlook-mail/ Outlook Mail via Microsoft Graph google/ Shared Google OAuth helpers microsoft/ Shared Microsoft Graph helpers email/ Shared email types, content filters, HTML stripping config.ts Environment variable config index.ts Entry point cli.ts CLI entry point (gatelet, gatelet doctor)dashboard/ Admin dashboard (React, Vite, Tailwind)website/ Documentation site (Astro, Starlight)tests/ Test suite (vitest, 590 tests)Key modules
Section titled “Key modules”Policy engine (src/policy/)
Section titled “Policy engine (src/policy/)”Pure functional, no side effects. The engine receives a policy config, operation name, and parameters, and returns either a denial or the mutated parameters.
engine.ts— orchestrates constraints → mutations → resultconstraints.ts— evaluates the four constraint rulesmutations.ts— applies set/delete/cap mutationsparser.ts— YAML parsing with validationfield-path.ts— dot-notation field access for nested paths
MCP server (src/mcp/)
Section titled “MCP server (src/mcp/)”Raw HTTP server using the MCP SDK’s StreamableHTTPServerTransport. Handles:
- Bearer token authentication with rate limiting
- Per-session tool registration
- Request size limits (1MB)
- Error sanitization
Admin API (src/admin/)
Section titled “Admin API (src/admin/)”Hono framework with 8 route modules:
- Connections (OAuth flow, CRUD)
- Policies (YAML management)
- API keys (generate, list, revoke)
- Audit log (query with filters)
- Settings (OAuth credentials)
- Status (health + metrics)
- Providers (list all available tools)
- Doctor (health checks)
Database (src/db/)
Section titled “Database (src/db/)”SQLite with WAL mode and foreign key constraints. All credentials are encrypted with libsodium before storage. The database module handles schema migrations automatically on startup.
Token refresh
Section titled “Token refresh”If an upstream API call fails due to an expired OAuth token, Gatelet automatically refreshes the token and retries the request. Per-connection mutex prevents concurrent refresh races. No agent or user action is required.