BEAM Agent SDKs

Erlang/OTP and Elixir libraries for AI coding agent wire protocols. OTP-native, fault-tolerant, and production-ready.

OTP 27+ Elixir 1.17+ 5 AI Agents MIT

Built for the BEAM

Every SDK is a proper OTP application. Supervision trees, telemetry, and fault isolation come standard — not bolted on.

OTP Supervision

Each agent session is a supervised gen_statem. Crashes are isolated and recoverable.

Telemetry

State changes, queries, buffer overflows — optionally instrumented via :telemetry (zero overhead when absent).

🔒

Fail-Closed Permissions

Permission handlers default to deny. Explicit opt-in for tool execution and file access.

🔌

MCP Servers

Define custom tools as Erlang functions. In-process MCP server registry with SDK integration.

📋

Universal API

Threads, checkpoints, session store, and control protocol — available on every adapter.

🔁

Content Blocks

Bidirectional conversion between messages and typed content blocks across all protocols.

Error Categorization

Structured error categories (rate_limit, subscription_exhausted, context_exceeded, auth_expired, server_error, unknown) on every error message — pattern match, don’t parse.

Architecture

All five backends share a three-layer design. The public API delegates to a shared session engine, which dispatches to per-backend protocol handlers.

Public API
beam_agent / BeamAgent
Session Engine (gen_statem)
lifecycle · queue · telemetry · error recovery
Claudestdio / JSONL
Codexstdio / JSON-RPC
GeminiJSON-RPC / NDJSON
OpenCodeHTTP / SSE
CopilotLSP framing

Packages

A single canonical SDK with five protocol-specific adapters, documented for both Erlang and Elixir.

BA
Canonical SDK

Shared types, JSONL parsing, JSON-RPC, hooks, MCP servers, telemetry, session store, threads, checkpoints, command execution, global registries (agents, plugins, slash commands, SDK config), reload bus, and the transport behaviour.

Types & Normalization JSONL / JSON-RPC Hooks MCP Registry Telemetry (opt-in) Session Store Threads Checkpoints Commands Control Protocol Agent Registry Plugin Registry Slash Commands SDK Config Reload Bus Transport Behaviour
C
Claude Code

Anthropic Claude Code agent SDK. Stdio transport, elicitation, session disk store, and native interrupt support.

X
OpenAI Codex

OpenAI Codex CLI agent SDK. Dual-mode sessions (interactive + exec), port-based transport, and turn management.

CP
GitHub Copilot

GitHub Copilot agent SDK. LSP-style framing, user input requests, and content-length delimited transport.

G
Google Gemini

Google Gemini CLI agent SDK. JSON-RPC over NDJSON with persistent ACP sessions.

O
OpenCode

OpenCode agent SDK. HTTP/SSE transport with REST session management and server-sent event streaming.

Capability Matrix

All capabilities are fully supported across every backend. The matrix shows how each is implemented: native backend call, universal OTP shim, or both.

Capability Claude Codex Gemini OpenCode Copilot
Session lifecycle
Session info
Model switch
Interrupt
Permission mode
Session history
Session mutation
Thread management
Metadata accessors
MCP servers
MCP management
Hooks
Checkpointing
Thinking budget
Task stop
Commands
Approval callbacks
User input callbacks
Realtime review
Config management
Provider management
Attachments
Event streaming
Native
Universal
Both

Quick Start

Add a dependency and start a session in a few lines.

# mix.exs {:beam_agent_ex, path: "beam_agent_ex"} # Start a session and stream results {:ok, session} = BeamAgent.start_session(backend: :claude, cli_path: "claude") session |> BeamAgent.stream!("Explain OTP supervision") |> Enum.each(fn msg -> case msg.type do :text -> IO.write(msg.content) :result -> IO.puts("\n--- Done ---") _ -> :ok end end)
%% rebar.config {deps, [{beam_agent, {path, "."}}]}. %% Start a session and send a query {ok, Session} = beam_agent:start_session(#{ backend => claude, cli_path => <<"claude">>, permission_mode => <<"bypassPermissions">> }), {ok, Messages} = beam_agent:query(Session, <<"Explain OTP supervision">>).

Cookie Setup

BeamAgent encrypts credentials at rest using a key derived from the BEAM node cookie. You don't need distributed Erlang — just a cookie set on the local node.

Without a cookie, erlang:get_cookie() returns nocookie — a publicly known atom. BeamAgent auto-generates a secure ephemeral cookie and logs persistence instructions. Pre-configure a cookie for production to avoid ephemeral keys.

Compatibility

Runtime Minimum Version Tested Up To
Erlang/OTP2728
Elixir1.171.19
Rebar33.xlatest