# `ConduitMcp.Tasks.EtsStore`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.10.1/lib/conduit_mcp/tasks/ets_store.ex#L1)

ETS-backed task store. Default implementation of `ConduitMcp.Tasks.Store`.

All state lives in the named ETS table `:conduit_mcp_tasks`. The table
is owned by a long-lived `Agent` (`ConduitMcp.Tasks.EtsStore.Owner`) started
from `ConduitMcp.Application` so the table outlives short-lived request
processes — without this, a Bandit request handler that creates the
table dies with it, and the next request sees an empty table. The
table is `:public` so any process can read and write; concurrency is
safe because each task id is the row key and rows are written
atomically.

This store is in-memory only. Terminal-state rows accumulate until the
BEAM restarts; pair it with `ConduitMcp.Tasks.Janitor` to evict them on
an interval.

# `cancel`

Cancels a task by setting status to `"cancelled"`.

# `cleanup`

Removes terminal-state tasks (`completed`, `failed`, `cancelled`) older
than `ttl_ms`. Tasks in `working` or `input_required` are never evicted.
Returns the number of rows removed.

# `create`

Creates a new task with the given id and metadata. Returns the stored task,
or `{:error, :task_limit_reached}` when the configured row cap is hit.

The cap defaults to 10000 rows and is configurable via
`config :conduit_mcp, :tasks_max_rows`. Terminal-state rows are reclaimed
by `ConduitMcp.Tasks.Janitor`; `working`/`input_required` rows are not, so
the cap is the backstop against unbounded growth.

# `delete`

Deletes a task. Returns `:ok` whether or not it existed.

# `get`

Fetches a task by id.

# `list`

Lists all tasks, optionally filtered by `:status`.

# `update`

Merges `updates` into the existing task. Returns the new task or
`{:error, :not_found}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
