Current section

Files

Jump to
codex_sdk guides 12-operational-workflows.md
Raw

guides/12-operational-workflows.md

# Operational Workflows
This guide covers the newly synced runtime workflows that sit between local
authoring and normal thread execution:
- marketplace acquisition
- MCP inventory and thread-scoped MCP execution
- thread history injection and memory controls
- filesystem watches
## Marketplace Acquisition And Maintenance
There are two runtime entry points for adding a marketplace source:
- `Codex.CLI.marketplace_add/2`
- `Codex.AppServer.marketplace_add/3`
CLI passthrough:
```elixir
{:ok, result} =
Codex.CLI.marketplace_add(
"./source-marketplace",
cwd: "/tmp/workspace",
env: %{"CODEX_HOME" => "/tmp/codex-home"}
)
IO.puts(result.stdout)
```
App-server request:
```elixir
{:ok, conn} =
Codex.AppServer.connect(codex_opts,
cwd: "/tmp/workspace",
process_env: %{"CODEX_HOME" => "/tmp/codex-home"}
)
{:ok, response} =
Codex.AppServer.marketplace_add(
conn,
"./source-marketplace",
ref_name: "main",
sparse_paths: ["plugins/demo-plugin"]
)
IO.inspect(response)
```
The app-server surface also exposes marketplace maintenance:
```elixir
{:ok, _} = Codex.AppServer.marketplace_upgrade(conn, marketplace_name: "source-marketplace")
{:ok, _} = Codex.AppServer.marketplace_remove(conn, "source-marketplace")
```
Use isolated `CODEX_HOME` values for examples, tests, and migration flows so
you do not mutate your real installed marketplace set unintentionally.
## Thread Repair And Memory Controls
### Inject raw response items
`thread/inject_items` appends raw Responses API items to the thread's
model-visible history.
```elixir
items = [
%{
"type" => "message",
"role" => "assistant",
"content" => [%{"type" => "output_text", "text" => "Recovered checkpoint"}]
}
]
{:ok, %{}} = Codex.AppServer.thread_inject_items(conn, thread_id, items)
```
Use this when a host flow needs to reconstruct or repair thread-visible state
after an out-of-band recovery step.
### Toggle thread memory mode
`thread/memoryMode/set` is experimental and requires `experimental_api: true`
when connecting.
```elixir
{:ok, conn} = Codex.AppServer.connect(codex_opts, experimental_api: true)
{:ok, %{}} = Codex.AppServer.thread_memory_mode_set(conn, thread_id, :disabled)
```
Accepted local forms:
- `:enabled`
- `:disabled`
- `"enabled"`
- `"disabled"`
### Reset memory state
`memory/reset` is also experimental and destructive. Use it only with an
isolated `CODEX_HOME` unless you explicitly want to clear the active memory
store for that Codex home.
```elixir
{:ok, conn} = Codex.AppServer.connect(codex_opts, experimental_api: true)
{:ok, %{}} = Codex.AppServer.memory_reset(conn)
```
## MCP Inventory And Execution
The app-server MCP helper now supports:
- inventory detail filtering
- resource reads
- thread-scoped tool calls
### Inventory detail
```elixir
{:ok, %{"data" => servers}} =
Codex.AppServer.Mcp.list_servers(conn, detail: :tools_and_auth_only)
```
Accepted detail selectors:
- `:full`
- `:tools_and_auth_only`
### Resource reads
```elixir
{:ok, %{"contents" => contents}} =
Codex.AppServer.Mcp.resource_read(conn, thread_id, "codex_apps", "test://resource")
```
### Tool calls
```elixir
{:ok, response} =
Codex.AppServer.Mcp.tool_call(
conn,
thread_id,
"docs",
"search",
arguments: %{"query" => "rate limits"},
meta: %{"source" => "sdk"}
)
IO.inspect(response["structuredContent"])
```
Treat MCP tool execution as an external side-effect boundary. Do not auto-run
arbitrary tools just because they are discoverable.
## Filesystem Watches
The thin app-server filesystem wrapper now includes `fs/watch` and `fs/unwatch`.
Notifications still arrive through the normal `subscribe/2` channel as
`fs/changed`.
```elixir
:ok = Codex.AppServer.subscribe(conn, methods: ["fs/changed"])
{:ok, %{"path" => watched_path}} = Codex.AppServer.fs_watch(conn, "watch_1", "/tmp/demo.txt")
receive do
{:codex_notification, "fs/changed", params} ->
IO.inspect(params, label: "fs changed")
after
5_000 ->
IO.puts("No fs/changed notification observed")
end
{:ok, %{}} = Codex.AppServer.fs_unwatch(conn, "watch_1")
```
Use stable watch ids that your host can correlate back to the subscribed
workflow.