OpenCode (opencode_sdk v0.1.13)

Copy Markdown View Source

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:

    TypeDescription
    "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).

Summary

Functions

close(arg1)

@spec close(map()) :: :ok

create(opts \\ [])

@spec create(keyword()) ::
  {:ok, %{client: keyword(), server: OpenCode.Server.t()}} | {:error, term()}

create_client(opts \\ [])

@spec create_client(keyword()) :: keyword()

create_server(opts \\ [])

@spec create_server(keyword()) :: {:ok, OpenCode.Server.t()} | {:error, term()}

create_tui(opts \\ [])

@spec create_tui(keyword()) :: {:ok, OpenCode.Tui.t()}