# neosian > Async-only Python state layer for LLM agents: durable conversations, > agent-curated file-shaped memory, and context lifecycle — on storage the > product owns. Keyless to boot; Python >= 3.12. A stateless `Agent` core (tools, orchestration, streaming, fallback, guardrails, structured output) with opt-in `Conversation` and memory layers. One memory dispatcher serves five transports: the function tool, Anthropic's native declaration, an MCP stdio server, the shell, and the state process's HTTP wire. Agents share context by config: a `board` mount on a task scope, and read-only `ConversationView`s of another conversation with cross-conversation `recall_turn`. Long URLs, paths and ids in aged turns become `[link N]` handles, expanded at the tool boundary. Skills are documents under `skills/` in a mount — versioned, curated by the mount flag, loaded by `list_skills`/`load_skill`, served as MCP prompts. `McpServer` consumes any MCP server as agent tools, over stdio or HTTP. ## Learn from the shell - `neosian docs` — list the shipped topics (they travel in the wheel, so they always describe the installed version). - `neosian docs quickstart | agent | tools | memory | skills | cli | mcp | agents | topology` — one page, markdown on stdout, pipe-safe. - `neosian docs topology` — who runs neosian code x where the bytes live; one writer per FileStore root. ## Operate memory from the shell - `neosian memory view / --scope user:me` — the first command to try; renders the memory index. The store is the home, `~/.neosian` or `$NEOSIAN_HOME`, unless `--root DIR`, `--url` or the DSN names one. - Six commands: view, create, str_replace, insert, delete, rename. `--json` prints the memory tool's result envelope verbatim. - `neosian memory maintain` — the gardener: keyless dedup + empty-prune; `--model MODEL` adds the semantic pass (merge, prune stale, promote). - A skill is `create /project/skills/` with a frontmatter `description` and the instructions as the body (`neosian docs skills`); `versions` and `revert` work on it like any document. - Operator verbs, keyless: `versions PATH` (the audit trail; `--json` carries full historical content), `redact PATH [--all]` (the one eraser; audit skeleton preserved), `revert PATH --version N` (undo). - `neosian audit --scope S [--conversation C] [--actor A] [--since T] [--json]` — the ledger: what was done, by whom, when — newest first, identical on a root, Postgres, or the state process (`--url`). - `neosian export DIR` / `neosian import DIR` — a store moves whole, history included, any substrate to any other; DIR is a FileStore root. An import needs every scope and conversation empty in the target. - Exit tiers: 0 success, 1 ran-and-failed, 2 bad invocation, 130 interrupt. stdout carries the artifact; stderr carries guidance. - Postgres arrives only via the NEOSIAN_POSTGRES_DSN environment variable (never an argv flag). `python -m neosian.memory` is the PATH-free twin. ## Upgrade to MCP - `neosian mcp install --client claude-code|claude-desktop|cursor|codex|opencode` prints the exact registration; `--write` applies it (refused when the client is not installed; Codex is print-only — apply with the printed `codex mcp add` line). - `python -m neosian.mcp --root DIR --scope user:me` serves the same store over stdio: the `memory` tool, `list_skills` and `load_skill` over the mounts' skills (each skill also an MCP prompt — a slash command in Claude Code), and `recall_turn(turn, conversation)` — any recorded turn of any agent's session, verbatim. - The other direction: `async with McpServer.stdio(cmd, args) as s:` (or `.http(url, headers=)`, `.in_process(server)`) from `neosian.mcp` — the server's tools as `AgentConfig(tools=[*s.tools])`, schema verbatim, `is_error` in-band, `prefix=` for two servers that clash; the gate and hooks apply unchanged (`neosian docs mcp`). ## Record a foreign agent - `neosian record install --client claude-code|codex|opencode` prints the four hooks — no flags: the home and this directory's layout, `user:` at /user and `user:/proj:` at /project, spelled into the line; `--root DIR --scope S` override (the events: UserPromptSubmit, PostToolUse, Stop, SessionStart) — for OpenCode, a plugin file; `--write` merges them into ./.claude/settings.json or ./.codex/hooks.json, every other hook preserved, or writes ./.opencode/plugins/neosian-record.js (Codex: a trusted project, hooks reviewed in /hooks). - The hooks call `python -m neosian.record` with the payload on stdin; a prompt-to-stop span lands as one turn by `claude-code:` in the conversation the session id names, plus a sessions document at /memories/sessions/. Read it back: `neosian audit --scope S --conversation `. On SessionStart the verb prints the memory index and "where we left off" (the recent sessions, log-projected) — the client adds a hook's stdout to the model's context. - Hooks beside an MCP server are two writers: use `--url` (the state process) or Postgres. `neosian docs agents` carries the client table. ## Reach it over the network - `NEOSIAN_SERVE_TOKEN=... neosian serve` — the state process on the home (`--root DIR` another root): memory and conversations on a port, MCP over streamable HTTP at /mcp when started with mounts. Token is env-only (one token, or a per-client table `actor=token,...` — the process records who wrote); unset refuses to start; /health is unauthenticated. Shell clients: `--url URL` + NEOSIAN_CLIENT_TOKEN. - The shipped Dockerfile is the appliance: `docker run -e NEOSIAN_SERVE_TOKEN=... -p 6367:6367 -v state:/data neosian`. - Python clients: `await RemoteStore.connect(url, token=...)` — both storage ABCs over the wire, core install, drops in where FileStore does. `neosian docs topology` carries the full shape. ## Bring an OpenAI-compatible model - `register_model("acme-large", provider=OpenAICompatible(name="acme", api_key_env="ACME_API_KEY", base_url="https://llm.acme.example/v1"), ...)` — once at import; the model prices in µ$ and passes every gate like a shipped one. `neosian docs quickstart` carries the snippet. - Shipped door rows — `from neosian.catalog import GROK_4_6, GEMINI_3_7_FLASH` (xAI `XAI_API_KEY`; Gemini `GEMINI_API_KEY`): first-party, fingerprinted, no client of their own; each earned by green dispatched runs of the memory baselines. ## Install - `uv add "neosian==1.0.0rc3"` — one package: the library and its provider SDKs, the `neosian` shell, the MCP server and client, the state process and OpenTelemetry spans (about 70 MB; nothing loaded until used). On PyPI as a pre-release until v1.0.0: pin it explicitly, never a default resolve. Keyless to start — `Model.FAKE` and `FileStore` need nothing. The one extra is the Postgres driver for `PostgresStore`, `neosian[postgres]` (`[all]` its alias); the former `[cli]`, `[mcp]`, `[otel]`, `[server]` resolve for one release and add nothing. - `curl -fsS https://neosian.com/install | bash` — uv and neosian on a machine with nothing on it; the script says what it installs first. - The appliance: `docker run -d -e NEOSIAN_SERVE_TOKEN=… -p 6367:6367 -v neosian-state:/data ghcr.io/mausa-ai/neosian:1.0.0rc3` — the state process on a volume, `/health` the one open route. ## Docs - https://github.com/mausa-ai/neosian/blob/v1.0.0rc3/README.md: install and quickstart. - https://github.com/mausa-ai/neosian/blob/v1.0.0rc3/SERVICES.md: every environment key and what turning it off means. - `neosian docs baselines`: the published per-provider memory numbers.