Unofficial OpenCode SDK for Elixir.
Mirrors the JS SDK behavior. Use create/1 to start a managed server and get
a client, or create_client/1 to connect to an already-running server.
Getting started
Managed server — start an OpenCode server as a child process and obtain a connected client in one call:
{:ok, %{client: client, server: server}} = OpenCode.create()
# ... use client ...
OpenCode.close(%{server: server})Existing server — connect to a server that is already running:
client = OpenCode.create_client(base_url: "http://127.0.0.1:4096")Both approaches return a client keyword list that you pass as the :client
option to every operation in OpenCode.Generated.Operations.
Sessions and prompts
Create a session, send a prompt, and extract the assistant's text:
alias OpenCode.Generated.Operations
{:ok, session} = Operations.session_create(%{title: "My session"}, client)
{:ok, result} =
Operations.session_prompt(
session["id"],
%{parts: [%{type: "text", text: "Hello!"}]},
client
)
for %{"type" => "text", "text" => text} <- result["parts"] do
IO.puts(text)
endYou can also specify a model in the prompt body:
body = %{
model: %{providerID: "anthropic", modelID: "claude-sonnet-4-20250514"},
parts: [%{type: "text", text: "Summarize this project."}]
}Response structure
session_prompt/3 returns {:ok, result} where result is a map with:
"info"— an assistant message map with metadata (role, model, tokens, cost, timing)."parts"— a list of part maps. Each has a"type"field:Type Description "text"The assistant's text response "tool-invocation"A tool call (name, args, state, result) "reasoning"Model reasoning/thinking "step-start"Start of a multi-step sequence "step-finish"End of a multi-step sequence "file"File content reference "patch"File diff/patch
Error handling
All operations return {:ok, result} on success. Failures return
{:error, {status, body}} for HTTP errors or {:error, reason} for
connection issues:
case Operations.session_prompt(session_id, body, client) do
{:ok, result} ->
result
{:error, {404, _body}} ->
IO.puts("Session not found")
{:error, {400, body}} ->
IO.puts("Bad request: #{inspect(body)}")
{:error, %Req.TransportError{reason: :econnrefused}} ->
IO.puts("Cannot connect to server")
endConfiguration
create/1 accepts a :config map that is passed to the server as
OPENCODE_CONFIG_CONTENT. Use it to override the model or log level:
{:ok, %{client: client, server: server}} =
OpenCode.create(config: %{model: "anthropic/claude-sonnet-4-20250514"})Full API reference
See OpenCode.Generated.Operations for the complete list of endpoints
(sessions, messages, permissions, events, and more).
Summary
Functions
@spec close(map()) :: :ok
@spec create(keyword()) :: {:ok, %{client: keyword(), server: OpenCode.Server.t()}} | {:error, term()}
@spec create_server(keyword()) :: {:ok, OpenCode.Server.t()} | {:error, term()}
@spec create_tui(keyword()) :: {:ok, OpenCode.Tui.t()}