Complete reference for AgentDb's four public interfaces: the Elixir AgentDb module, the mix agent_db.* CLI, MCP tools over Streamable HTTP, and WebSocket v1.* events. Each section is written against its source of truth so it can be checked, not taken on faith:

InterfaceSource of truth
Elixir APIlib/agent_db/agent_db.ex — rendered at hexdocs.pm/agent_db
CLIlib/mix/tasks/ — each task's @switches
MCPAgentDbWeb.Mcp.tools/0 in lib/agent_db_web/mcp.ex
WebSockethandle_in clauses in lib/agent_db_web/channel.ex

The generated documentation is the API reference for the Elixir module — this guide maps entry points to it instead of copying signatures, which would go stale the moment the code moves. Generate it locally with mix docs.

1. Elixir API (AgentDb module)

Start the application once, then every call below is available: {:ok, _} = Application.ensure_all_started(:agent_db). Links go to the versioned generated docs; local mix docs output matches them.

Tree operations

Entry pointWhat it doesDocs
AgentDb.write/3Writes a document, creating missing parents; acknowledges before embedding/summarizationlink
AgentDb.read/1Reads L2 content, falling back through generated layerslink
AgentDb.abstract/1Reads the L0 abstract layerlink
AgentDb.overview/1Reads the L1 overview layerlink
AgentDb.stored_layers/1Which layers exist for a URIlink
AgentDb.layers/1Reads all three layers (L0, L1, L2) in one call, each with source and character countlink
AgentDb.list/1Direct children of a URIlink
AgentDb.tree/2Depth-limited tree projectionlink
AgentDb.rm/1Removes the subtree at a URIlink
AgentDb.find/2Literal URI-path discovery with scope:link
AgentDb.grep/2Literal L2 line matches with excerptslink
AgentDb.list_all_documents/2Paged listing of the whole treelink
Entry pointWhat it doesDocs
AgentDb.search/2Keyword, vector, or hybrid search; mode:, scope:, top_k:, hybrid_weights:, fields: optionslink

fields: selects which per-result fields are returned: :uri (always required — a result without its URI cannot be fetched), :content, :abstract, :overview, :score. Omitted returns all of them, so an existing caller sees the same result set as before. An unknown name, an empty list, or a selection without :uri is {:error, {:invalid_fields, value}} rather than a substituted answer, and the projection reaches the statement that reads the rows — a caller selecting :abstract does not pay to read document content it cannot receive.

# URIs and abstracts only, for deciding which documents to read
{:ok, results} = AgentDb.search("vector index", mode: :hybrid, fields: [:uri, :abstract, :score])

Memory

Entry pointWhat it doesDocs
AgentDb.remember/3Stores a durable fact with confidence:, importance:, candidate:, source:; document, assertion, and embedding job land as one outcomelink
AgentDb.recall/1Decay-aware recall with include_superseded:; each entry reports its own type, and a malformed URI is {:error, :invalid_uri} rather than a raiselink
AgentDb.forget/1Removes a memorylink
AgentDb.promote_memory/1Promotes a candidate to durable, carrying its value through the URI's documentlink
AgentDb.reject_memory_candidate/1Rejects a candidatelink
AgentDb.pending_memory_candidates/1Candidates awaiting promotionlink
AgentDb.memory_conflicts/1Read-only conflict surfacinglink
AgentDb.memory_types/0The valid memory typeslink
AgentDb.default_confidence/0Default confidence for new memorieslink

Sessions

Entry pointWhat it doesDocs
AgentDb.create_session/0Creates an append-only sessionlink
AgentDb.append_message/3Appends a messagelink
AgentDb.get_session/1Reads every message, in orderlink
AgentDb.commit_session/3Commits a session into the treelink

Agent Skills

Entry pointWhat it doesDocs
AgentDb.import_skills/2Imports a skill folder or tar archivelink
AgentDb.list_skills/1Lists imported skillslink
AgentDb.set_enabled/2Enables/disables one skilllink
AgentDb.set_group/2Sets one skill's grouplink
AgentDb.bulk_set_enabled/2Bulk enable/disablelink
AgentDb.bulk_set_group/2Bulk group assignmentlink
AgentDb.skill_import_limits/0Bounded import limitslink
AgentDb.skill_import_error_message/1Human message for an import refusallink

Data portability

Entry pointWhat it doesDocs
AgentDb.export_data/2Exports store data to a tar archivelink
AgentDb.import_data/2Imports an exported archivelink
AgentDb.data_transfer_limits/0Bounded transfer limitslink
AgentDb.export_data_error_message/1Human message for a transfer failurelink

Vector index

Entry pointWhat it doesDocs
AgentDb.index_coverage/0Embedding coverage of the treelink
AgentDb.backfill_vector_index/0Re-embeds stale rows in the backgroundlink
AgentDb.prune_vector_index/1Drops stale vector rowslink

Status, observability, and subscriptions

Entry pointWhat it doesDocs
AgentDb.health_check/0Aggregate readiness for orchestration probeslink
AgentDb.model_status/0Per-role model state, latency, provider healthlink
AgentDb.queue_stats/0Queue depth by statelink
AgentDb.queue_detail/1Oldest pending age + failed jobs with classified reasonslink
AgentDb.operation_stats/0Operation counters by outcomelink
AgentDb.cache_stats/0Cache sizeslink
AgentDb.storage_stats/0Storage footprint and tree compositionlink
AgentDb.recent_errors/1Bounded recent operational errorslink
AgentDb.runtime_snapshot/0Read-only BEAM runtime snapshot (bounded, redacted)link
AgentDb.subscribe/1Subscribes a process to {:context_changed, uri, kind, version}link
AgentDb.unsubscribe/1Unsubscribeslink

Full signatures, option types with defaults, and every success/error return shape live in the generated docs (hexdocs link per row, or mix docs).

2. CLI (mix agent_db.*)

Every task takes --json (machine-readable stdout) and --no-compile (skips the app start). Without --json, output is human text. Failures write to stderr and exit non-zero; exit code 0 means success.

TaskPurposeSwitches
mix agent_db.readReads a document's full content (L2)--json, --no-compile
mix agent_db.abstractReads a document's L0 abstract only--json, --no-compile
mix agent_db.overviewReads a document's L1 overview only--json, --no-compile
mix agent_db.searchSearches the context tree--mode, --scope, --top-k, --json, --no-compile
mix agent_db.findDiscovers paths by literal substring--scope, --limit, --json, --no-compile
mix agent_db.grepSearches document content by literal substring--scope, --limit, --json, --no-compile
mix agent_db.treeShows the context tree--depth, --json, --no-compile
mix agent_db.recallReads memories back--type, --term, --include-superseded, --json, --no-compile
mix agent_db.indexIndexes Elixir sources into the context tree--project, --dir, --json, --no-compile
mix agent_db.import_skillsImports Agent Skills from a folder or a tar archive--user, --json, --no-compile
mix agent_db.export_dataExports store data to a tar archive--scope, --json, --no-compile
mix agent_db.import_dataImports store data from a tar archive--json, --no-compile
mix agent_db.doctorChecks store health and configuration--json, --no-compile
mix agent_db.seedSeeds a deterministic demo dataset (dev/test only)--prefix, --force, --clean, --allow-prod, --json, --no-compile

3. MCP tools (Streamable HTTP at POST /mcp)

The tool set is AgentDbWeb.Mcp.tools/0 — 19 tools. Requests are JSON-RPC 2.0 (tools/call with {"name": ..., "arguments": {...}}).

ToolRequest arguments (required in bold)Description
context_readuriReads a document's full content (L2)
context_abstracturiReads a document's L0 abstract only
context_overviewuriReads a document's L1 overview only
context_layersuriReads L0, L1, and L2 together, each with its text, source (stored or fallback), and character count
context_writeuri, contentWrites a document, creating missing parents
context_rmuriRemoves the subtree at a URI
context_listuriLists the direct children of a URI
context_treeuri, depthDepth-limited projection of the tree
context_searchterm, mode, scope, top_k, fieldsSearches by keyword, vector, or hybrid; fields selects which per-result fields to return
context_findterm, scope, limitDiscovers paths by literal substring
context_grepterm, scope, limitInspects L2 content lines by literal substring
memory_recalluri, type, term, include_supersededReads memories back by URI, type, or term
memory_rememberuri, value, confidence, sourceRecords a durable fact as a memory
memory_forgeturiRemoves a memory and its provenance
session_create—Creates a session and returns its id
session_appendsession_id, role, contentAppends a message to a session
session_getsession_idReturns every message of a session, in order
session_commitsession_id, destination_uriCommits a session into the tree at a URI
store_health—Store health, model status, and queue depth

Success response — a JSON-RPC result whose content is the data as JSON:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"content\":\"...\"}"}]}}

Error response — a JSON-RPC error; the bounded code rides in data.reason. A model that is still loading is signalled distinctly as -32001; every other failure is -32000 with the classified code:

{"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"...","data":{"reason":"model_loading"}}}

Confirm the live tool list with tools/list (what tools/install.sh --check asserts against context_read). With Bearer auth enabled, send the token as Authorization: Bearer <token>.

3.1 Local (sidecar) invocation

When AgentDb is embedded as a sidecar in a host Elixir application, the same tool inventory is reachable in-process through AgentDb.Mcp, without JSON-RPC or HTTP:

# Discover the inventory
tools = AgentDb.Mcp.tools()

# Invoke a tool directly
{:ok, %{"uri" => uri, "content" => content}} =
  AgentDb.Mcp.call_tool("context_read", %{"uri" => uri})

# Or speak JSON-RPC locally
AgentDb.Mcp.handle_request(%{"jsonrpc" => "2.0", "id" => 1, "method" => "tools/list"}, [])

AgentDb.Mcp.call_tool/3 returns {:ok, term()} or {:error, reason}. A tool deferred only because a model is still loading returns {:error, :model_loading}. AgentDbWeb.Mcp remains available as a compatibility shim delegating to AgentDb.Mcp.

4. WebSocket events (Phoenix Channel /api)

Events are {"event": "v1.*", "payload": {...}}. The reply is {:ok, <payload>} on success and {:error, %{reason: <message>, code: <classified code>}} on failure. :ok-only operations reply {:ok, %{status: "ok"}}.

EventPayloadReply payload
v1.writeuri, content (+ opts: async, abstract, overview)write result
v1.readuricontent
v1.abstracturiabstract
v1.overviewurioverview
v1.listurinames
v1.treeuri, depth (default 2)tree
v1.rmuri:ok
v1.searchterm + mode/scope/top_k/hybrid_weights in optsresults
v1.findterm, scope, limitresults
v1.grepterm, scope, limitresults
v1.rememberuri, value (+ confidence, importance, type, source)memory result
v1.recalluri/type/term (+ include_superseded)memories
v1.forgeturi:ok
v1.create_session—session_id
v1.get_sessionsession_idmessages
v1.subscribeuri:ok
v1.unsubscribeuri:ok
v1.search_progressterm (as v1.search)results + progress events
v1.model_status—model status
v1.health—health check

Pushed events (server-to-client only): v1.append_message and v1.commit_session are responses to their matching operations, and v1.context_changed ({uri, kind, version}) is the subscription push.

Subscriptions are per-connection and do not survive a reconnect — re-subscribe after every reconnect.

Trace correlation: a traceparent is accepted as an HTTP header, at the payload's top level, or inside opts (W3C format).

5. Error code catalog

One bounded taxonomy classifies every failure on every transport. The source is AgentDb.Observability (classify_reason/1, the caller-error tags, and the http_status/1 mapping); each code also appears as the log reason and in transport error payloads.

CategoryCodesHTTP
Missingnot_found, no_memory, assertion_not_found404
Authorizationunauthorized401
Retryable unavailabilitymodel_loading, background_jobs_pending, vector_index_unavailable, storage_busy503
Size limitstoo_large, too_big, too_many_entries413
Rate limitingrate_limited429
Caller errorsinvalid_mode, invalid_uri, invalid_query, invalid_limit, invalid_document, invalid_memory, invalid_memory_type, invalid_session, invalid_user_id, invalid_scope, invalid_json, invalid_argument, invalid_payload, invalid_group, not_a_memory_uri, is_root, missing_argument, unknown_event, unknown_tool, unsafe_path, unsupported_entry, unexpected_entry, empty422
Model and inferencemodel_not_found, model_load_failed, download_failed, inference_failed, inference_timeout, hybrid_leg_timeout, hybrid_leg_failed, embeddings_unavailable, no_provider_url, background_jobs_failed500
Fallbackerror (anything unrecognised)500

Any tagged reason ({tag, detail}) classifies to its tag, so the set grows only by reusing or extending these codes — never free-form text.

Where the code appears per transport: Elixir — classify with Observability.error_code(reason); CLI — stderr message; MCP — error.data.reason (with -32001 for model_loading); WebSocket — error.code in the reply payload.

For the operational side (alerting, log interpretation, symptom-driven diagnosis) see MONITORING.md and TROUBLESHOOTING.md.