This guide covers the runtime control features that remain SDK-local after the CLI runtime cutover.
What The Client Owns
ClaudeAgentSDK.Client now sits above CliSubprocessCore.ProtocolSession and
keeps only Claude-specific control behavior:
- initialize handshake shaping
- runtime model switching
- hook callback execution
- permission callback execution
- SDK MCP routing
- Claude message and
stream_eventprojection
The client no longer accepts custom transport injection and it no longer owns subprocess lifecycle directly.
Runtime Model Switching
{:ok, client} =
ClaudeAgentSDK.Client.start_link(%ClaudeAgentSDK.Options{
model: "claude-sonnet-4"
})
:ok = ClaudeAgentSDK.Client.set_model(client, "opus")Execution Surface Routing
Choose local vs SSH execution with Options.execution_surface:
opts = %ClaudeAgentSDK.Options{
execution_surface: [
surface_kind: :ssh_exec,
transport_options: [
destination: "claude.example",
user: "sdk",
port: 22
]
]
}
{:ok, client} = ClaudeAgentSDK.Client.start_link(opts)Error Notes
- Local validation failures are returned before the client starts.
- Control requests preserve typed SDK errors such as
:timeoutand{:protocol_session_down, reason}. - CLI-declared control errors still come back as provider strings from the control protocol.