Packages
opencode_sdk
0.1.54
0.1.84
0.1.83
0.1.82
0.1.81
0.1.80
0.1.79
0.1.78
0.1.77
0.1.76
0.1.75
0.1.74
0.1.73
0.1.72
0.1.71
0.1.70
0.1.69
0.1.68
0.1.67
0.1.66
0.1.65
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.59
0.1.58
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.50
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.41
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
0.1.25
0.1.24
0.1.23
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Unofficial OpenCode SDK for Elixir. A complete Elixir SDK for OpenCode, providing server creation, session management, messaging, file operations, and more. Mirrors the functionality of the official JavaScript SDK (@opencode-ai/sdk). Not affiliated with or built by the OpenCode team.
Current section
Files
Jump to
Current section
Files
lib/opencode.ex
defmodule OpenCode do
@moduledoc """
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)
end
You 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")
end
## Configuration
`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).
"""
alias OpenCode.Server
alias OpenCode.Tui
@default_base_url "http://127.0.0.1:4096"
@spec create(keyword()) :: {:ok, %{client: keyword(), server: Server.t()}} | {:error, term()}
def create(opts \\ []) do
case Server.create(opts) do
{:ok, server} ->
client = create_client(base_url: server.url)
{:ok, %{client: client, server: server}}
{:error, reason} ->
{:error, reason}
end
end
@spec create_client(keyword()) :: keyword()
def create_client(opts \\ []) do
base = Keyword.get(opts, :base_url, @default_base_url)
[client: OpenCode.Client, base_url: base]
|> put_opt(:directory, opts[:directory])
|> put_opt(:headers, opts[:headers])
|> put_opt(:timeout, opts[:timeout])
end
@spec create_server(keyword()) :: {:ok, Server.t()} | {:error, term()}
def create_server(opts \\ []), do: Server.create(opts)
@spec create_tui(keyword()) :: {:ok, Tui.t()}
def create_tui(opts \\ []), do: Tui.create(opts)
@spec close(map()) :: :ok
def close(%{server: server}), do: Server.close(server)
def close(_), do: :ok
defp put_opt(list, _key, nil), do: list
defp put_opt(list, _key, []), do: list
defp put_opt(list, key, val), do: Keyword.put(list, key, val)
end