# `AttestoMCP.Anubis.SessionStore.Ecto`
[🔗](https://github.com/XukuLLC/attesto_mcp/blob/v1.0.5/lib/attesto_mcp/anubis/session_store/ecto.ex#L2)

Postgres-backed `Anubis.Server.Session.Store` for the Anubis MCP transports.

## Why

Anubis keeps session state in memory and recovers it only on a live
reconnect, so a deploy (node replacement) drops every session and forces each
connected client to re-initialize. Persisting the session map lets a client
reconnect with its `Mcp-Session-Id` after a deploy and have its initialized
state (client_info + `frame`) restored, with no re-initialization.

Anubis ships only a Redis adapter; this implements the same behaviour against
an `Ecto.Repo`, for a Postgres-only deployment that does not run Redis.

## Wiring

    # config/config.exs
    config :anubis_mcp, :session_store,
      enabled: true,
      adapter: AttestoMCP.Anubis.SessionStore.Ecto,
      repo: MyApp.Repo,
      ttl: to_timeout(minute: 30)

The `:repo` may also be set as `config :attesto_mcp, repo: MyApp.Repo`. Run
`mix attesto_mcp.gen.session_migration --repo MyApp.Repo` to create the
backing `attesto_mcp_sessions` table.

## No process

The store is stateless: every callback is a direct repo query and the repo is
already supervised, so `start_link/1` returns `:ignore` instead of booting an
idle GenServer. Anubis lists the adapter as a child (the `{adapter, config}`
child-spec form when `enabled: true`); `:ignore` tells the supervisor there is
nothing to start.

Postgres has no native key TTL, so expired rows are reaped lazily on `load/2`
and by `cleanup_expired/1` (call it on a schedule from the host).

Compile-guarded on `Anubis.Server.Session.Store` and `Ecto.Schema`.

---

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