The AI Agent Gateway is an Elixir/OTP server that sits between AI agents and the tools and data they act on. Agents connect to it over the Model Context Protocol (MCP). The gateway authenticates the caller, checks what that caller is allowed to touch, runs the tool, records the call, and returns the result. Each customer runs their own instance on their own server. There is no shared multi-tenant backend.
Everything below is a capability that ships in the current build.
MCP server
The core surface. The gateway exposes a set of tools to any MCP client (Claude Code, a custom agent, another service) over HTTP, Server-Sent Events, and JSON-RPC. A single dispatcher routes each tool call to the handler that owns it, either by exact tool name or by name prefix. Callers authenticate with a bearer token.
Access control and permissions
Every tool is gated. Each user carries a permission map, and the business logic (not the transport) decides whether a call proceeds. The model has three moving parts:
- Per-tool permission keys, so a grant can be as broad as a whole subsystem or as narrow as one tool.
- Sub-tokens: independently revocable bearer tokens that can be scoped to a subset of what the user can do, including a single tool. Full-access tokens are themselves stored as scoped sub-token rows.
- An admin role that can mint per-tool keys and manage grants.
Permission keys never leave the server process. They are not serialized to API responses, logs, or cookies. Keys are held in a dedicated registry, and stored data is encrypted at rest with AES-256.
Built-in tool domains
The gateway ships tool handlers grouped by domain:
- Platform: basic identity and session tools (who am I, admin check, a demo counter).
- Google Workspace: Gmail, Drive, Sheets, and Docs operations.
- WhatsApp: send and read messages through a local bridge.
- Browser: read and act on live web pages through the MCP Bridge extension.
- MCP Connections: proxy tool calls out to other MCP servers.
- Workflows: define and run multi-step orchestrations.
- Function Nodes: provision and run isolated code sandboxes.
- Blog: author and publish posts.
- DrawIO: generate diagrams.
- iTerm Tabs: drive iTerm2 terminals from a tool call.
- Schema: inspect and query structured data shapes.
- OpenAPI Bridge: turn a REST API into callable MCP tools from its spec.
- Monitor: system and process monitoring.
- Utility tools: Pushover notifications, alarms, text-to-speech, YouTube, current time, URL fetch, and file read/write.
External MCP connections
The gateway is also an MCP client. It connects out to other MCP servers over streamable HTTP, SSE, stdio, or WebSocket, discovers their tools, and re-exposes them through its own permission layer. Each external connection gets a connection-scope key plus one key per remote tool, so access to a third-party server can be granted in bulk or one tool at a time. This is how domain logic (customer CRMs, internal services, supplier tooling) stays in external servers while the gateway handles auth, audit, and routing. The client transport runs on the maintained Anubis MCP library.
MCP Bridge (browser extension)
A Chrome extension that lets the gateway operate the user’s own logged-in browser. It can read the DOM of an open tab, read a page’s local and session storage, issue a fetch from the page’s own origin (inheriting its cookies and auth), and intercept the responses of requests the page makes on its own. That last capability reaches data that lives only in JavaScript state or behind same-origin authenticated calls, without the gateway ever handling credentials directly.
Function Nodes
A control plane for sandboxed code execution. It provisions isolated runtimes on Fly.io, runs customer-supplied tooling inside them, and manages their lifecycle: async provisioning, idle-stop to release cost, persistent volumes for state that must survive a restart, and an audit log of what ran. A web page shows node status and lets an operator provision on demand.
LLM integration and chat
An integrated chat layer talks to multiple model providers (Anthropic, Google Gemini, OpenAI) behind one interface. A separate LLM Gateway maintains a connection pool for proxying agent-to-model traffic. Chat history is persisted.
Agent-to-agent (A2A)
An implementation of the A2A protocol for agent interoperability, with its own task store, so the gateway can participate in multi-agent exchanges rather than only serving a single client.
Scheduling, notifications, and messaging
- Alarm: schedules tasks to fire at a set time, with soft-deleted rows for an audit trail.
- Pushover: pushes notifications to a phone on meaningful events, such as a completed task or a question that needs an answer.
- WhatsApp orchestration: a resident process reads incoming WhatsApp messages and auto-responds to specific contacts.
Web dashboards and data modules
The gateway also serves a set of browser dashboards backed by its own SQLite tables:
- Activity: imports GPS tracks (GPX and TCX), segments each session into tacks, computes per-segment speed, and trims slow starts and stops so averages reflect actual planing.
- Garmin and HRV: import Garmin activity and daily heart-rate-variability exports into queryable tables with idempotent loads.
- TradingView: reads a live watchlist widget from an open chart page and stores rows while the market is open. Rendered as both a Highcharts and a Chart.js dashboard.
- Windguru and WindAlert: read live wind-station data and push a single alert when conditions cross a threshold.
- Equities and Portfolio: cross-sectional return forecasts and a long/short portfolio built on them.
- RSS aggregators: FT, NYT, ScienceDaily, an Nvidia news search, and Yahoo Finance, each an in-app inbox with refresh and per-article flagging.
- Todo: a task list with toggle, notes, snooze, recurrence, and edit.
- Blog: authoring and public post rendering.
Platform and developer infrastructure
Underneath the features sits the machinery that keeps the system honest:
- Sqler: each module owns its own SQLite database. IDs are millisecond timestamps, updates use optimistic locking, and deletes are soft by default for an audit trail.
- A logging pipeline that writes server logs, fans them out to subscribers, and can raise notifications on error conditions.
- Auto-compilation that hot-loads code changes in development.
- A ZeroMQ bridge to Python for work that belongs in that ecosystem.
- Tidewave, a development-time MCP connection into the running system.
The shape of it
The gateway is deliberately thin on domain logic and thick on control. It authenticates, authorizes, audits, and routes. The actual work (a CRM query, a market scrape, a code run, a model call) happens in a tool handler, an external MCP server, a browser tab, or a Fly.io sandbox. That separation is what lets one instance safely front many agents and many backends without any of them holding more access than they were granted.