Packages
claude_code
0.5.0
0.36.5
0.36.4
0.36.3
0.36.2
0.36.1
0.36.0
0.35.0
0.34.0
0.33.1
0.32.2
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.1
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Claude Agent SDK for Elixir – Build AI agents with Claude Code
Current section
Files
Jump to
Current section
Files
lib/claude_code/message/system.ex
defmodule ClaudeCode.Message.System do
@moduledoc """
Represents a system message from the Claude CLI.
System messages are initialization messages that provide session setup information
including available tools, MCP servers, model, and permission mode.
Matches the official SDK schema:
```
{
type: "system",
subtype: "init",
apiKeySource: string,
cwd: string,
session_id: string,
tools: string[],
mcp_servers: { name: string, status: string }[],
model: string,
permissionMode: "default" | "acceptEdits" | "bypassPermissions" | "plan"
}
```
"""
alias ClaudeCode.Types
@enforce_keys [:type, :subtype, :cwd, :session_id, :tools, :mcp_servers, :model, :permission_mode, :api_key_source]
defstruct [
:type,
:subtype,
:cwd,
:session_id,
:tools,
:mcp_servers,
:model,
:permission_mode,
:api_key_source
]
@type t :: %__MODULE__{
type: :system,
subtype: :init,
cwd: String.t(),
session_id: Types.session_id(),
tools: [String.t()],
mcp_servers: [Types.mcp_server()],
model: Types.model(),
permission_mode: Types.permission_mode(),
api_key_source: String.t()
}
@doc """
Creates a new System message from JSON data.
## Examples
iex> System.new(%{"type" => "system", "subtype" => "init", ...})
{:ok, %System{...}}
iex> System.new(%{"type" => "assistant"})
{:error, :invalid_message_type}
"""
@spec new(map()) :: {:ok, t()} | {:error, :invalid_message_type | {:missing_fields, [atom()]}}
def new(%{"type" => "system"} = json) do
required_fields = ["subtype", "cwd", "session_id", "tools", "mcp_servers", "model", "permissionMode", "apiKeySource"]
missing = Enum.filter(required_fields, &(not Map.has_key?(json, &1)))
if Enum.empty?(missing) do
message = %__MODULE__{
type: :system,
subtype: String.to_atom(json["subtype"]),
cwd: json["cwd"],
session_id: json["session_id"],
tools: json["tools"],
mcp_servers: parse_mcp_servers(json["mcp_servers"]),
model: json["model"],
permission_mode: parse_permission_mode(json["permissionMode"]),
api_key_source: json["apiKeySource"]
}
{:ok, message}
else
{:error, {:missing_fields, Enum.map(missing, &String.to_atom/1)}}
end
end
def new(_), do: {:error, :invalid_message_type}
@doc """
Type guard to check if a value is a System message.
"""
@spec system_message?(any()) :: boolean()
def system_message?(%__MODULE__{type: :system}), do: true
def system_message?(_), do: false
defp parse_mcp_servers(servers) when is_list(servers) do
Enum.map(servers, fn server ->
%{
name: server["name"],
status: server["status"]
}
end)
end
defp parse_permission_mode("default"), do: :default
defp parse_permission_mode("acceptEdits"), do: :accept_edits
defp parse_permission_mode("bypassPermissions"), do: :bypass_permissions
defp parse_permission_mode("plan"), do: :plan
defp parse_permission_mode(_), do: :default
end