An unofficial native Swift client for the Codex App Server protocol.
The package launches codex app-server --stdio, completes the initialize
handshake, and exposes persistent threads, streaming turns, interruption,
dynamic tools, approval requests, diagnostics, images, skills, mentions, and
raw forward-compatible events without embedding Node.js.
- macOS 14+
- Swift 5.9+
- Codex CLI installed and authenticated
The resolver checks PATH, ~/.local/bin, common npm/bun locations,
Homebrew, and /usr/local/bin. You can also pass an explicit executable URL.
.package(url: "https://github.com/kiliczsh/codex-agents-sdk-swift.git", from: "0.1.0")Depend on the CodexAgentSDK product.
import CodexAgentSDK
let session = try CodexAgentSession.live()
try await session.connect()
let thread = try await session.startThread(options: .init(
workingDirectory: projectURL,
approvalPolicy: .onRequest,
sandbox: .workspaceWrite,
personality: .friendly
))
let eventTask = Task {
for try await event in session.events {
switch event {
case .agentMessageDelta(let text, _):
print(text, terminator: "")
case .turnCompleted(let payload):
print("\nCompleted:", payload)
case .serverRequest(let request):
// Surface approval and elicitation requests in your UI, then:
try await session.respond(to: request, result: ["decision": "allow"])
default:
break
}
}
}
try await session.startTurn("Summarize this project", threadId: thread.id)Dynamic tools are the direct path for connecting GenUI's A2UI tool definitions.
They currently require App Server's experimental API capability, which
CodexAgentSession.live() enables by default.
let render = CodexDynamicTool(
name: "a2ui_create_surface",
description: "Create and render an A2UI surface.",
inputSchema: [
"type": "object",
"properties": ["surfaceId": ["type": "string"]],
"required": ["surfaceId"],
]
) { arguments in
// Validate and apply arguments through GenUIBridge + GenUIKit.
return .text("Surface rendered.")
}
let session = try CodexAgentSession.live(tools: [render])
try await session.connect()
try await session.startThread(options: .init(
workingDirectory: projectURL,
sandbox: .workspaceWrite
))For a stable production tool boundary, configure the same tools as an MCP server instead of relying on experimental dynamic tools.
The SDK keeps unknown notifications and server requests as raw JSONValue, so
new Codex fields do not break decoding. For exact types matching an installed
Codex version, generate the official schema bundle:
codex app-server generate-json-schema --out GeneratedSchema
codex app-server generate-json-schema --experimental --out GeneratedSchemaExperimentalProtocol source: OpenAI Codex App Server.
The package is a usable foundation but does not ship a test target yet. Planned before 1.0: fixture-driven protocol tests, blocked-stdin/process lifecycle tests, approval-flow coverage, schema-version compatibility checks, and a live smoke test against a pinned Codex CLI version.