Neotoma
A full system-of-record server for AI agents: it ingests sources and observations, resolves entities into deterministic, provenance-tracked snapshots, and exposes them over MCP for retrieval, correction, relationship graph traversal, federation, and governance.
Ingest & store structured entities and raw files (base64 or server-local path) in one call, with dry-run previews (
commit:false), idempotency keys, strict no-silent-merge mode, source priority, and interpretation provenance; parse files (PDF/CSV/Parquet/JSON/text) to readable text without storing.Retrieve snapshots of entities with per-field provenance, reconstructing historical state either by event time (
at) or ingestion time (at_ingested), in markdown or JSON.Search & list entities by type, date windows, published flags, server-side snapshot field filters (
eq,in,gt,contains,contains_word, …), lexical/semantic search, keyset cursor pagination, and optional snapshot omission for lightweight pages.Resolve identity via identifiers (name, email, domain, tax_id) or multi-signal bundles with confidence scoring, ranked candidates, and resolution bands; also answer "who do we know at company X" through live
works_atedges.Inspect history by listing observations, tracing a field's provenance chain, auditing recent changes across all core tables, and checking stale-snapshot health.
Correct data as immutable observations — single field corrections with optimistic version checks, atomic multi-entity compare-and-correct transactions with full rollback, and key-addressed array item patches with per-item version/absence guards.
Manage relationships — create one or many typed edges (including EMBEDS with caption/order), list/filter by direction and endpoints, snapshot an edge, soft-delete and restore, and discover or register relationship types (with enforced acyclicity).
Explore the graph — N-hop related-entity traversal with type filters, full neighborhood retrieval (entities, relationships, sources, events), and timeline event queries by type/date range.
Manage the entity lifecycle — merge duplicates, split over-merged entities by predicate, detect potential duplicates, soft-delete/restore, and count entities by type.
Evolve schemas — register schemas and reducer configs, incrementally add/remove fields or re-key identity rules, analyze raw fragments for promotion candidates, audit undeclared fragments, and read schema recommendations; discover and describe entity types.
Govern & attribute — read the instance's data policy (scope, lawful-basis requirements, sensitivity ceiling), resolve session identity/trust tier, and get the authenticated user.
Handle submissions & issues — accept guest submissions by entity type, thread follow-up messages, check submission status/list, file GitHub-mirrored issues (public or private) with reporter metadata, append messages, and sync issues both directions.
Federate & sync — register peers, list/status/remove them, run bounded outbound sync, resolve conflicts, and manage webhook/SSE subscriptions to entity and event changes.
Publish & share — mint guest-scoped shareable URLs for rendered HTML pages from an entity or inline content.
Operate the server — retrieve signed file URLs, record interpretation runs for existing sources, generate per-turn status lines, check npm for updates and capability deltas, and list/enable/disable feature bundles.
Provides Docker deployment options for the Neotoma server, enabling containerized installation and management of the deterministic state layer.
Offers a deterministic alternative to LangChain Memory and other retrieval/RAG systems by providing versioned entity snapshots with full provenance and replayable timelines.
Supports storing and managing Markdown files as part of the versioned record system, though noted as less suitable for casual note-taking compared to dedicated PKM tools.
Uses Mermaid diagrams in documentation to illustrate the Neotoma architecture and data flow between sources, observations, entities, and memory graph.
Provides a deterministic state layer alternative to MySQL and other databases, offering versioned history, replayable timelines, and schema constraints that prevent silent mutations.
Enables installation and operation of the Neotoma server via npm, with CLI tools for initialization, configuration, and management of the deterministic state layer.
Provides package distribution and installation of Neotoma through npm, enabling agent-driven setup and configuration of the deterministic state layer.
Positioned as an alternative for users needing deterministic state management rather than Obsidian-style personal knowledge management and note-taking.
Offers a deterministic state layer alternative to SQLite, providing versioned entity history, replayable timelines, and prevention of conflicting facts across agents.
Neotoma
A record, not recall.
Neotoma is the system of record for AI agents. Without one, an agent works from whatever it happens to recall: part of the last session, a note its tool saved, or nothing. With one, it reads what was stored, from which source, and what is current now, so the agents you connect can defer to one answer.
npm install -g neotoma
neotoma init
neotoma setup --tool claude-codeneotoma setup --tool claude-code connects Claude Code: it writes MCP entries, CLI instruction files, and an allow rule that lets Claude Code run any neotoma command; Install lists everything it writes. Human-run setup omits --yes; automated setup may add it after the operator authorizes those changes. Omission does not prevent every setup write.
After a plain npm install, CLI data commands such as neotoma store return AUTH_REQUIRED, because the CLI uses the production profile, which needs a token. Run them as neotoma dev ... or with NEOTOMA_ENV=development.
Other hosts are listed under Connect your tools.
Known limitations: docs/known_limitations.md lists behaviour you may run into, each with a workaround and its tracking issue.
Agents cannot own work they cannot verify.
You cannot delegate real work to agents you cannot hold to account. Accountability has two halves: what was true, and who was authorized. Neotoma answers what was true. Your agents can produce a value; they cannot tell you its version, its source, or whether it is still current. Neotoma keeps every fact as an observation tied to its source, so you can see where a value came from and what is current now.
What ships today is the foundation of that record: Neotoma ingests sources into observations that the write path does not edit (the database does not enforce this) and computes entity snapshots, with each current field tracing back to the observation that set it. It is exposed over an MCP server, a REST API, a CLI, and a bundled web Inspector. See Vision and execution status for exactly where the implementation stands against the vision.
It is built for developers building and operating AI agents who need a shared record that connected agents can defer to, with provenance on every field. The same engine serves two further groups: individuals keeping one record across their assistants on a single-user install, and operators running a shared, multi-user instance with agent access control. Agents store structured records (contacts, tasks, transactions, decisions, events, and any other type) once and read them back across every tool and session. The same observations and rules give the same snapshot.
neotoma.io · Install · Documentation (also served in-app at /docs)
What Neotoma is
Neotoma is a system of record, not a chat memory or a vector cache. It records observations from your sources, resolves them into entities, and computes a current snapshot for each entity by reducing its observations in a deterministic order. No observation is overwritten by a later write. Corrections and reinterpretations add new observations, and the earlier observations stay readable for that entity.
Three properties hold across every interface:
Deterministic. Entity IDs, event IDs, and reducer output are derived from the inputs by hashing. Entity IDs agree across instances unless tenant-scoped entity IDs are on (
NEOTOMA_SANDBOX_MODEorNEOTOMA_TENANT_SCOPED_ENTITY_IDS). Source and observation IDs also depend on the user and on the interpretation run, so they can differ between instances. The stdio MCP server writes as the shared local development user, but the HTTP server, and therefore the CLI, runs by default inlocal_sandboxmode with a per-install user, so the same data stored on two installs gets different source and observation IDs. Each interpretation run also gets a new observation ID. Do not rely on source or observation IDs matching across instances. The same observations and rules give the same snapshot regardless of order or timing. IDs are derived from inputs; observation timestamps are wall-clock, and the default merge rule orders by them.Immutable and auditable. The write path adds sources and observations and does not edit them; the database does not enforce this with a constraint. Each current field names the observation that set it, and a stored observation names its source. A correction observation has no source, and a write from the CLI records no writer.
Self-hosted and portable. The engine is embedded SQLite plus content-addressed file storage under a directory you control, with optional AES-256-GCM at-rest encryption. Nothing is used for training, and you can export your data as current state; observation history is not part of the export. In single-user mode the data stays entirely local; multi-user, peer-sync, and hosted modes are opt-in (see Deployment modes).
Related MCP server: midas-memory-mcp
How it works
graph LR
Sources["Sources (files, messages, API payloads)"] --> Obs[Observations]
Obs --> Res[Entity resolution]
Res --> Snap["Entity snapshots (reduced, versioned)"]
Snap --> Graph["Graph + timeline"]
Graph <--> MCP[MCP]
Graph <--> REST[REST API]
Graph <--> CLI[CLI]
Graph <--> Inspector[Inspector]Source. Raw input is stored once, deduplicated by SHA-256 content hash, with a deterministic source ID.
Interpretation. Structured fields are extracted from the source (directly for structured input, or via an LLM interpretation run whose model, temperature, and prompt are recorded).
Observation. Each extracted fact becomes an observation with a hash-derived ID, linked to its source and interpretation.
Entity resolution. A deterministic canonical name (driven by the type's schema) maps the observation to an entity, creating it if needed.
Snapshot. All observations for an entity are reduced into a current snapshot using per-field merge policies, with a stable order (
observed_at DESC, id ASC) and a field-to-observation provenance map.Timeline and relationships. Date fields emit deterministic timeline events; typed relationships connect entities into a graph.
What you can do with it
Neotoma v0.28.0 exposes 67 MCP tools and 112 REST paths in its OpenAPI spec. They cover largely the same capabilities, but the MCP server, the REST API, and the CLI are separate implementations, and some checks and attribution differ between them (see Known limitations). The capability surface includes:
Ingest and store. Store structured records or raw files in one call. File ingestion extracts text from PDF (with a first-page image fallback), CSV (with adaptive chunking for large files), Parquet, JSON, and plain text; images and audio are stored as raw sources. A committed, keyed structured store started on v0.26.0 that stops partway finishes its missing observations on a same-key retry; a store carrying an interpretation returns ERR_STORE_WRITE_INCOMPLETE, and keys left over from earlier versions behave differently over MCP and HTTP (see Known limitations). See Known limitations.
Resolve, retrieve, and search. Look up entities by identifier (name, email, and similar), resolve identity from multiple signals with confidence scoring, list observations, retrieve a field's provenance chain, traverse the relationship graph N hops, and pull a full graph neighborhood. When an embedding key is configured, semantic vector search runs over entity snapshots (stored locally in sqlite-vec); keyword filtering works without it.
Correct and evolve. Submit corrections as observations marked as corrections, never edits: a correction wins in the snapshot until a later correction for the same field replaces it, on array fields too, and the earlier observation stays readable. Schemas are inferred from your data, recommended from recurring unknown fields, and can be auto-enhanced or updated incrementally with versioning. New entity types work without any code change.
Relate and sequence. Create typed relationships (for example PART_OF, DEPENDS_ON, REFERS_TO, DUPLICATE_OF), query timeline events across types and date ranges, and read an entity's observation history in a deterministic order.
Manage the entity lifecycle. Merge duplicates, split an entity by predicate, soft-delete and restore, list potential duplicates, and run GDPR-oriented deletion. Merge and split are transactional and audited.
Control multi-agent access. Writes carry attribution when the writer signs its requests (AAuth) or reports a client name. Unless an agent signs its requests, the name is the writer's own claim, and some write paths, including the CLI, record no writer. Agent grants express least-privilege capabilities (which operations on which entity types). This is infrastructure behind the guarantees above, not a feature to evaluate on its own. The mechanics, including optional hardware-attested authentication and guest access tokens, are documented in the AAuth reference.
Federate, sync, and intake. Register peer instances and sync entities between them with configurable scope and conflict resolution (last-write-wins, source priority, or manual). Subscribe to entity or event changes over webhooks (HMAC-signed) or Server-Sent Events. Accept guest entity submissions, mirror GitHub issues into conversation threads, and mirror your data to deterministic, git-trackable canonical Markdown.
Export and own your data. Produce a bounded MEMORY.md summary, a JSON snapshot export of current entity state with a per-field provenance map (field to the observation ID that set it) and attribution metadata (the observations themselves, and so the observation history, are not exported), or a complete Markdown mirror of every entity, relationship, source, and timeline day.
Interfaces
The same record is reachable four ways. The MCP server, the REST API, and the CLI are separate implementations, so some checks and attribution differ between them (see Known limitations).
Interface | What it is | Transports |
MCP server | Model Context Protocol tools for agents to store and retrieve state | stdio, WebSocket, streamable HTTP |
REST API | Full HTTP interface for application integration | HTTP/HTTPS, OAuth or key-based auth |
CLI | The | local process |
Inspector | Bundled web app for browsing and managing the store | served by the API server |
The Inspector
The Inspector is a single-page web app bundled into the build and served by the API server (at / for browsers, no separate deployment). It is an operator console for the data store, with screens for:
Entities (browse, detail, correct fields, view history and provenance, per-entity timeline)
Observations, sources, interpretations, and recent activity
An interactive knowledge-graph explorer
Relationships and the global timeline
Schemas and entity types (browse, register, inspect merge policies)
Agents, agent grants (create, suspend, revoke, restore), peers, and subscriptions
Issues, conversations and turns (the agent audit trail), access policies, and compliance
Search, analytics and usage, settings (including dark mode), a sandbox surface, and an in-app documentation browser at
/docs
Install
npm install -g neotoma
neotoma init
neotoma setup --tool claude-codeIn the current package source, neotoma setup --tool claude-code writes the MCP entries and more. The skill count below includes source changes not yet in published v0.27.0, which contains 12 installable skills; check the package version you actually use:
Two MCP entries in the project's
.mcp.json:neotoma-dev(development profile,neotoma.db) andneotoma(production profile,neotoma.prod.db). They use separate databases, so an agent on one entry does not see what an agent on the other stored.CLI instruction files for Claude Code, Cursor, and Codex in the project:
.claude/rules/neotoma_cli.mdc,.cursor/rules/neotoma_cli.mdc, and.codex/neotoma_cli.md.When
claudeis on your PATH, it runsclaude plugin marketplace addandclaude plugin installto install the Neotoma Claude Code plugin (five hooks). Withoutclaudeon PATH, setup writes everything else and then exits with status 1.When
~/.claudeexists, it links 13 Neotoma skills into~/.claude/skills.
It also adds two allow rules, Bash(neotoma:*) and Bash(npm install -g neotoma:*), to .claude/settings.local.json (project scope, the default). The first is a wildcard: Claude Code then runs any neotoma command without asking, including destructive ones such as neotoma reset, neotoma storage merge-db, neotoma backup restore, and neotoma processes kill. --scope both also writes the rules to ~/.claude/settings.json, and --skip-permissions writes none. For Cursor the same two rules go to .cursor/allowlist.json; for Codex they go to the user-level ~/.codex/config.toml whatever the scope.
For another host, use its row in Connect your tools; neotoma setup --help lists the supported hosts. To check MCP config files later, neotoma mcp config scans for them and asks before adding a missing entry.
Prerequisites: Node.js 20.x (see .nvmrc) and npm 9+. No .env is required for local storage. The neotoma doctor command checks your environment, database, and security configuration.
The CLI also handles MCP config scanning and sync, harness configuration, lifecycle hook installation, peers and access management, plans, transcript and onboarding import, server and database management, memory export, and the canonical mirror. See the CLI reference.
Example
neotoma store --json='[{"entity_type":"task","title":"Submit expense report","status":"open"}]'
neotoma entities list --type task
neotoma upload ./invoice.pdfAgents do the same through MCP tool calls such as store, retrieve_entities, and retrieve_entity_by_identifier. The MCP server and the CLI are separate implementations, so some behaviour differs (see Known limitations). The MCP server logs the equivalent CLI command for each tool call.
Connect your tools
Neotoma works across MCP-capable hosts. Most are a single setup command; some add lifecycle hooks, which capture turns automatically when the local API is running.
Host | Modes | Install |
Cursor | MCP + hooks |
|
Claude Code | MCP + hooks |
|
Claude Desktop | MCP (local + remote) |
|
Codex CLI | MCP + hooks |
|
OpenClaw | Native plugin + MCP |
|
ChatGPT | MCP App + Custom GPT Actions | Manual HTTPS + OAuth |
Windsurf, Continue, VS Code (Copilot) | MCP | Manual MCP config; see the per-host guides in the Integrations matrix ( |
OpenCode | hooks | plugin install |
Full matrix: Integrations.
Hooks are the reliability floor (capture of each turn while the local API is running, retrieval injection, compaction awareness) and MCP is the quality ceiling (agent-driven structured writes). The Claude Code plugin's hooks post to 127.0.0.1:3080 unless NEOTOMA_BASE_URL is set, and fail quietly when nothing is listening there (see Known limitations). Per-harness packages live under packages/: claude-code-plugin, cursor-hooks, opencode-plugin, codex-hooks, claude-agent-sdk-adapter.
Client SDKs: @neotoma/client (TypeScript) and neotoma-client (Python).
OpenClaw native plugin: Neotoma ships as a native OpenClaw plugin with kind: "memory", so it can fill the dedicated memory slot with all MCP tools registered as agent tools.
Vision and execution status
As agent use expands, reality fragments across chat histories, agent memories, files, databases, tickets, and application state. The failure is not retrieval. It is that humans and agents can no longer answer: which assertion is current? which source introduced it? was it observed, inferred, or decided? who had authority to correct it? which agents relied on the previous version? is there legitimate disagreement? Neotoma's long-term role is collective epistemic coherence: not "better semantic memory," but deterministic, governed, multi-party state that humans and agents maintain together: attributed, correctable, disagreement-aware, portable, and independent of any one model or application.
Vision phase | What it means | Status |
P0: Deterministic single-writer state | Observations the write path does not edit, hash-derived entity IDs, deterministic reduction, field-level provenance, corrections as new observations, per-entity observation history | ✅ Shipped: in daily use; a correction stays authoritative on its field until a later correction replaces it |
P1: Multi-user state foundations | Human and agent identities, attributed writes, tenant isolation, access controls, shared instances | 🟡 Partially shipped: hosted multi-user mode with |
P2: Authority over state | Domain ownership, correction rights, supersession, policy ownership, temporary grants, disclosure logs | 🟡 Mechanisms exist (corrections, |
P3: Multi-principal semantics | Competing interpretations, disputed claims, official positions, consensus vs unresolved disagreement, field-level policies, historical validity | 🔜 Planned: interpretations are first-class today; dispute/official-position semantics are not |
P4: Organizational intelligence substrate | Non-developer governance UI, "why does the system believe this?" explanations, impact analysis, authority-graph views, enterprise administration | 🔭 Vision: the Inspector's provenance and audit views are the seed |
Ateles is the other half. Its repository describes it as an operating system for humans and AI agents to jointly initiate, execute, approve, and reconcile work under explicit authority. Neotoma holds the record that this work runs against. Neither is sufficient alone. A record without authority tells you what happened but not whether it was permitted; authority without a record tells you who may act but not against what state.
Skills
Skills are guided workflows that teach an agent to import, extract, and persist data. They ship with the npm package and are installed by neotoma setup.
Skill | Description |
ensure-neotoma | Install Neotoma, configure MCP, verify connectivity. Prerequisite for the rest. |
remember-email | Import email, extract contacts, tasks, events, and transactions. |
remember-conversations | Import ChatGPT/Claude/Slack exports, reconstruct a decision timeline. |
remember-meetings | Ingest transcripts, extract decisions and action items. |
remember-finances | Import statements, receipts, and invoices as structured transactions. |
remember-contacts | Consolidate contacts from email, calendar, chat, vCards. |
remember-calendar | Import events and commitments. |
remember-codebase | Repository integration: inventory, decisions, MCP wiring. |
recover-sqlite-database | Check integrity and recover a corrupted database. |
Ordinary storage and retrieval need no skill: the live MCP tool instructions delivered at session start cover store/query/recall directly.
Record types
Neotoma stores typed entities with versioned history and provenance. The schema is flexible: store any entity type with whatever fields the data implies, and the system infers and evolves the schema.
Type | Stores | Examples |
Contacts | People, companies, roles |
|
Tasks | Obligations, deadlines, goals |
|
Transactions | Payments, receipts, invoices |
|
Contracts | Agreements, clauses, amendments |
|
Decisions | Choices, rationale, reviews |
|
Events | Meetings, milestones, outcomes |
|
Storage, privacy, and security
Storage: Local SQLite (
better-sqlite3, WAL mode) plus content-addressed file storage, underNEOTOMA_DATA_DIR. Separate dev and prod profiles. Semantic search uses sqlite-vec locally.Privacy: Your data is never used for training; logs and event payloads carry IDs, not PII. No telemetry. Update checks ask the npm registry for the latest version: the interactive CLI about once a day (off with
NO_UPDATE_NOTIFIER=1, or--no-update-check, which applies to the CLI only), and the stdio MCP server when a session starts and about every 6 hours (off withNO_UPDATE_NOTIFIER=1). Each request carries only the package name, and the registry sees ordinary connection metadata such as your address. Thenpm_check_updateMCP tool can make the same request when an agent calls it, and is not turned off byNO_UPDATE_NOTIFIER. In single-user mode data stays local; MCP OAuth, peer sync, and hosted instances share data as configured (see Deployment modes).Encryption: Optional AES-256-GCM column encryption of sensitive content and metadata, keyed by a key file or BIP-39 mnemonic. Some tables (for example the event log) are not yet column-encrypted; pair with an encrypted volume for full coverage. See architecture.
Auth: Local auth for single-user installs, MCP OAuth for hosted use, optional hardware attestation for agents, and explicit per-operation access controls. Run
neotoma doctorto verify your setup. See Auth and Privacy.
Deployment modes
The same SQLite-backed engine runs in two modes:
Local single-user. Run it on your machine for your own record across assistants. Local auth (or key-based auth when encryption is enabled), data stays local, no network exposure required.
Hosted multi-user. Run a shared instance with MCP OAuth, per-agent hardware-attested identity (AAuth) and capability grants, guest submission tokens, peer federation, and a sandbox demo user. Deploy targets include Docker and Fly. Tenancy is enforced by
user_idscoping over the same local SQLite engine.
The "stays local" and privacy claims above apply to the local single-user mode. Hosted, OAuth, and peer-sync modes share data per their configuration.
Who this is for
Neotoma is primarily for developers building and operating AI agents who need a shared record that connected agents can defer to, with provenance on every field. The product ships as an MCP server and REST API with drop-in hook packages (Claude Code, Cursor, Codex, OpenCode), a Claude Agent SDK adapter, and TypeScript and Python clients. Its core value (versioned observations, deterministic snapshots, field-level provenance, idempotency) is record-keeping infrastructure for agent loops, not an end-user app.
Two further audiences follow from the same code: individuals keeping a personal record across assistants (the built-in types are personal-information shaped, and the single-user SQLite plus Inspector path serves one person across assistants), and operators of a shared or hosted instance (OAuth, peer federation, and Docker or Fly deploy targets). The agent-identity and grants machinery is infrastructure supporting attribution and provenance for every audience, not a reason a particular audience adopts Neotoma.
It is not aimed at casual note-taking, PKM/Obsidian-style human-driven knowledge bases, or users who need a fully hosted product with nothing running on their own machine. Neotoma is local-first by design, and that part is not a temporary state. Installation is: today it is npm and the CLI, and a guided installation is intended but not yet available. If today's install path is what stands between you and trying it, that is our problem to fix, not a sign you are the wrong user.
Full profile: ICP from functionality: the canonical public ICP statement. For how it relates to the other ICP documents and which is canonical for which surface, see ICP reconciliation.
Status
Version: see the latest release · License: MIT · Storage: local-first (SQLite + local files); hosted multi-user mode is opt-in.
Neotoma is used daily in real agent workflows. The project moves fast, and APIs or storage formats can change between versions. The core guarantees (deterministic reduction, per-entity observation history, per-field provenance) are stable, phase P0 of the vision roadmap, with P1 partially shipped in hosted mode. Schemas, extraction across versions, and backward compatibility are not yet guaranteed.
Known limitations: docs/known_limitations.md lists the specific ones, each with what you will observe, a workaround, and its tracking issue.
Development
git clone https://github.com/markmhendrickson/neotoma.git
cd neotoma
npm install
npm testCommon commands:
npm run dev # MCP server (stdio)
npm run dev:full # API + UI + build watch
npm run cli:dev # CLI in dev mode (tsx)
npm run type-check # TypeScript
npm run lint # ESLint
npm test # unit/contract/security tests
npm run test:integration
npm run test:e2e # Playwright (Inspector)Documentation
Documentation is stored under docs/ (start at the documentation index) and served in-app at /docs, browsable in the Inspector.
Foundations: Core identity, Philosophy, Manifest
Architecture: Architecture, Determinism
Interfaces: CLI reference, MCP instructions, REST API
Operations: Runbook, health check (
neotoma doctor)
Contributing
Neotoma is in active development. Open an issue or discussion for questions or collaboration. See CONTRIBUTING.md and SECURITY.md. License: MIT.
Available Tools
67 toolsadd_entity_messageA
Append a follow-up conversation_message to the thread for a submitted root entity (entity_id).
Inputs: message (required), entity_id (required).
add_issue_messageA
Append a message to an issue thread. Provide entity_id or issue_number (issue_number is an integer). Pass guest_access_token when the local issue snapshot does not already carry the operator token. If remote append fails after local/GitHub side effects, inspect remote_submission_error instead of retrying blindly.
Inputs: body (required), entity_id, issue_number, reporter_channel, +4 more.
add_peerC
Register a Neotoma peer (peer_config) for bidirectional sync: peer_url, entity_types allowlist, shared_secret for POST /sync/webhook verification.
Inputs: peer_id (required), peer_url (required), direction (required), peer_name (required), +7 more.
analyze_schema_candidatesB
Analyze raw_fragments to identify fields that should be promoted to schema fields. Returns recommendations with confidence scores based on frequency and type consistency.
Inputs: user_id, entity_type, min_frequency, min_confidence.
audit_undeclared_fragmentsA
Report the accumulated undeclared raw_fragments awaiting schema declaration — fields stored on observations but excluded from the entity snapshot because no active schema declares them. Read-only; declares nothing. Returns, per entity_type, the undeclared fragment_keys with occurrence and affected-entity counts and a schema_missing flag (true when the type has stranded fragments but no active schema), plus total_entity_types / total_undeclared_fields rollups, in deterministic order (occurrences desc, affected desc, key asc; types by total occurrences desc). Optional entity_type scopes the audit to one type. The aggregate counterpart to the per-store unknown_fields signal: use it to triage the backlog before drafting update_schema_incremental / register_schema work.
Inputs: user_id, entity_type.
correctA
Create a priority-1000 correction observation to override lower-priority extracted fields. Higher-priority sources remain authoritative; equal-priority ties follow configured source-kind precedence, then deterministic recency. Read back the entity snapshot and field provenance before claiming the correction took effect.
Inputs: field (required), value (required), entity_id (required), entity_type (required), +4 more.
correct_transactionADestructiveIdempotent
Atomically compare and correct declared fields on multiple entities. Supply each loaded observation count and expected fields. Any conflict, denied write or snapshot mismatch rolls back every change. Retry the identical request and key after uncertainty. This primitive does not authorize application-level approval.
Inputs: entities (required), idempotency_key (required), user_id.
create_interpretationB
Create an interpretation row for an existing source from agent-extracted flat entities. Observations produced by this tool are linked to both source_id and interpretation_id. Use store with an interpretation block when the source-derived extraction can be batched in one store call.
Inputs: entities (required), source_id (required), user_id, relationships, +2 more.
create_relationshipA
Create a typed relationship between two entities. The relationship_type vocabulary is a runtime registry, not a fixed list: call list_relationship_types to read what this instance accepts, and register_relationship_type to add to it. Use EMBEDS when a container entity (e.g. blog post, document) embeds an asset entity (e.g. image, attachment): source_entity_id = container, target_entity_id = asset. For images/files stored in Neotoma: store the file via store (get source_id), create an image/media entity with source_id, then create_relationship(EMBEDS, post_entity_id, image_entity_id). Optional metadata: caption, order. Both source_entity_id and target_entity_id must be entities you own; store the entity first (or in the same store call), then link it.
Inputs: source_entity_id (required), target_entity_id (required), relationship_type (required), user_id, +2 more.
create_relationshipsB
Create multiple typed relationships between existing entities in one batch
Inputs: relationships (required), user_id, source_id.
delete_entityB
Hide an entity from current snapshots and queries through an immutable lifecycle observation. After the explicit authority cutover, serialized action sequence controls visibility; before cutover, existing legacy behavior applies. Each accepted request is a separate action, without an idempotency key or conditional rollback baseline. Physical legal erasure is a separate operation.
Inputs: entity_id (required), entity_type (required), reason, user_id.
delete_relationshipA
Delete a relationship. Requires the exact relationship_type between the two entities; if unknown, call list_relationships with source_entity_id and target_entity_id first to discover it. Creates a deletion observation so the relationship is excluded from snapshots and queries. Immutable and reversible for audit. Returns 404 with a discovery hint when no live relationship matches the supplied triple.
Inputs: source_entity_id (required), target_entity_id (required), relationship_type (required), reason, +1 more.
describe_entity_typeA
Return the full active schema for one entity_type: field_names, per-field type/required/description (field_summary), required_fields, schema_version, and the raw schema_definition. Call this before store when you know the entity_type but not its declared field shape, so the first store lands with zero unknown_fields and zero required_fields_missing warnings. Repair workflow: when a prior store or correct returned unknown_fields_count > 0 (or unknown_field: true), call describe_entity_type to see the declared fields, then re-store or correct the value into a declared field that fits; only add a new field (update_schema_incremental / register_schema, per the response hint) when no declared field fits. Read-only; no persistence side effects. Errors with InvalidParams when the entity_type has no active schema (use list_entity_types to discover types, or register_schema to create one). Scope note: describe prefers user scope (always passes the session user id), and so does update_schema_incremental when user_specific is omitted, so a type visible here can be extended without restating scope. Only an explicit user_specific: false narrows the update to global and can return ERR_SCHEMA_SCOPE_MISMATCH; never register_schema for that code.
Inputs: entity_type (required), user_id.
describe_instance_policyA
Return this instance's data policy: what it is for (purpose), which entity types are in scope (in_scope_entity_types) or explicitly out of scope (out_of_scope_entity_types), whether person-data writes require a lawful-basis tag or provenance metadata, and the maximum field sensitivity class it will hold. Call this at the start of a session against an unfamiliar or shared instance, before your first store, so your writes comply instead of being rejected — policy discovered by trial-and-error rejection is strictly worse than reading it up front. Response shape is {"policy": <object|null>, "entity_id": <string|null>}. Returns {"policy": null, "entity_id": null} when the instance declares no policy; that means unrestricted, NOT deny-all. entity_id is an opaque identifier — pass it to correct() when authoring/updating the policy remotely rather than re-deriving or guessing it. When enforcement is "enforced", violating store/correct calls are rejected with ERR_STORE_POLICY_DENIED and nothing in the request is persisted; when "advisory", violating writes are accepted but you are still expected to comply. Takes no arguments: the policy is instance-wide, identical for every caller. Read-only; no persistence side effects.
Inputs: no named parameters.
get_authenticated_userA
Get the authenticated user ID for the current MCP session. Returns the user_id that is automatically used for all authenticated actions.
Inputs: no named parameters.
get_entity_submission_statusARead-only
JSON entity snapshot for a submitted entity_id; optional guest_access_token for token-scoped read-back.
Inputs: entity_id (required), guest_access_token.
get_entity_type_countsA
Return canonical entity counts by entity_type for the authenticated user. Uses the same dashboard stats aggregation behind GET /stats and sorts results by count descending, then entity_type ascending. Use this when the user asks for counts by type, histograms, or sorted totals. This returns row counts, unlike list_entity_types where field_count is schema field width.
Inputs: user_id.
get_issue_statusARead-only
Return issue status and thread messages. Provide entity_id or issue_number (issue_number is an integer). Pass guest_access_token when token-scoped remote read-through is needed.
Inputs: entity_id, skip_sync, issue_number, guest_access_token.
get_peer_statusB
Fetch peer_config by peer_id plus remote_health (/health probe, semver compat vs this server).
Inputs: peer_id (required).
get_relationship_snapshotC
Get the current snapshot of a specific relationship with provenance
Inputs: source_entity_id (required), target_entity_id (required), relationship_type (required).
get_schema_recommendationsB
Get schema update recommendations for an entity type from raw_fragments analysis, agent suggestions, or inference.
Inputs: entity_type (required), source, status, user_id.
get_session_identityA
Resolve the current session's attribution: trust tier, AAuth / clientInfo fields, active anonymous-write policy, and whether the session is eligible for trusted writes. Safe to call as a preflight health check; does not write any rows.
Inputs: no named parameters.
get_subscription_statusA
Return one subscription snapshot by subscription_id (webhook secret omitted).
Inputs: subscription_id (required).
health_check_snapshotsA
Check for stale entity snapshots (snapshots with observation_count=0 but observations exist). Returns health status and count of stale snapshots.
Inputs: auto_fix.
identify_entity_by_signalsA
Resolve an entity from a multi-signal bundle (name, email, company, domain, phone, and open-ended string props). Returns best_match with identity_score, resolution_band (high/medium/low/unresolved), ranked candidates, and matched_signals. Use when you have partial or combined identity information and want a single-call resolution with confidence scoring.
Inputs: signals (required), user_id, entity_type, entity_types, +2 more.
list_entity_submissionsCRead-only
List recent entities of a given entity_type for the authenticated user.
Inputs: entity_type (required), limit, offset.
list_entity_typesA
List available entity types. Without keyword: returns a short summary (entity_type, schema_version, field_count) for all types. field_count here means schema field width, not stored entity row count. With keyword: returns full schema (field_names, field_summary) for matching types; pass summary: true to get summary only. Uses hybrid search when keyword is provided: keyword matching first, then vector semantic search. Use before storing structured data to determine the correct entity_type.
Inputs: keyword, summary, user_id.
list_interpretationsC
List interpretation runs for the authenticated user, optionally filtered by source_id.
Inputs: limit, offset, user_id, source_id.
list_observationsC
List all observations for a given entity
Inputs: limit, offset, entity_id, created_since, +1 more.
list_peersA
List peer_config rows for the current user (secrets redacted).
Inputs: no named parameters.
list_potential_duplicatesA
List candidate duplicate entity pairs for an entity_type. Read-only fuzzy post-hoc detector; never auto-merges. Per-schema thresholds and fields come from the schema's duplicate_detection_threshold and duplicate_detection_fields; callers may override threshold per call. Confirm pairs with the user, then hand off to merge_entities.
Inputs: entity_type (required), limit, user_id, threshold.
list_recent_changesARead-only
List the most recently changed records across core Neotoma tables (entities, sources, observations, interpretations, relationships, timeline_events) for the authenticated user. Returns items ordered by latest activity_at.
Inputs: limit, offset.
list_relationshipsA
List relationships for an entity, or discover the relationship type(s) between two specific entities. Filter by entity_id (with direction), or by source_entity_id and/or target_entity_id, and optionally relationship_type. To discover the type before delete_relationship, pass both source_entity_id and target_entity_id: each returned relationship carries its relationship_type. Soft-deleted relationships are excluded by default, so a deleted edge will not be re-offered for deletion; pass include_deleted: true to include them for audit. Paginated via limit/offset.
Inputs: limit, offset, user_id, direction, +5 more.
list_relationship_typesA
Discover the registered relationship vocabulary visible to the authenticated user, including types with no edges. Read this before writing an unfamiliar edge. Registration metadata is advisory except acyclic, which is enforced.
Inputs: scope, keyword, include_deactivated, include_edge_counts.
list_subscriptionsA
List the current user's active subscriptions (webhook secrets omitted).
Inputs: no named parameters.
list_timeline_eventsBRead-only
Query timeline events with filters (type, date range, source). Returns chronological events derived from date fields in sources.
Inputs: limit, offset, user_id, end_date, +3 more.
manage_bundlesA
Inspect and manage Neotoma bundles (the deliverable unit shipping schemas, record-type docs, and skills). action=list returns all bundles with type/version/enabled/always_active/provides count; action=info (with bundle) returns full manifest detail; action=install/enable/disable (with bundle) toggle persisted enable state. Default-install bundles (core, infrastructure, core_workflows) are always active and cannot be disabled. Disabling a schema bundle stops its types from auto-creating under guided/locked while preserving existing data. Returns structured JSON.
Inputs: action (required), bundle.
merge_entitiesB
Merge duplicate entities. Rewrites observations from source entity to target entity and marks source as merged.
Inputs: user_id, merge_reason, to_entity_id, from_entity_id.
neotoma_turn_summaryA
FU-2026-05-002. Compute the per-turn Neotoma status line (msg N/M, stored K, retrieved L) plus an optional ui:// widget URI for ext-apps clients. Call at the end of every turn after the closing assistant store completes. Pass the assistant message's conversation_id and turn_key; the server resolves stored/retrieved/issue entities, turn ordinal, and total message count. Agents emit the returned status_line in the user-visible reply; ext-apps clients additionally render widget_uri inline when present.
Inputs: turn_key (required), conversation_id (required), user_id.
npm_check_updateA
Check if a newer npm version is available. Returns updateAvailable, message, suggestedCommand, and when include_release_notes is true optional release_url, release_notes_excerpt, breaking_changes_excerpt, enrichment_error. When include_capability_delta is true, adds new_tools (tools added since currentVersion), removed_tools (tools removed since currentVersion), capability_delta_recommendation (upgrade guidance string), and capability_delta_note (present ONLY when delta computation degraded — e.g. unparseable versions or missing manifest — its absence signals no degradation). Call at session start to encourage user to upgrade.
Inputs: packageName (required), currentVersion (required), distTag, include_release_notes, +1 more.
parse_fileA
Parse local or base64-encoded files into agent-readable text and first-page PDF images without storing anything. Use before store when you need to extract entities from a file.
Inputs: file_path, mime_type, file_content, original_filename.
patch_array_itemA
Atomically patch one item of a structured array field by a portable non-null scalar key, instead of read-modify-full-array-write. Requires the active schema to declare that array with merge_array_by_key and the same key_field; missing/mismatched policy fails closed. Loads current state and writes inside one transaction, so concurrent patches to DIFFERENT keys both survive. Pass expected_item_version to detect a same-key race or expected_item_absent for race-safe creation; a conflict returns the current item instead of overwriting.
Inputs: item (required), field (required), entity_id (required), key_field (required), +6 more.
publish_rendered_pageA
Turn a rendered_page into a ready-to-share guest URL in one call. Pass an existing rendered_page entity_id, or inline {title, html_body, custom_css} to create one. Mints a guest_access_token scoped to that page and returns the absolute …/entities//html?access_token= URL plus ttl_seconds. html_body is injected verbatim into a server template — no html/head/body wrappers. Each call mints a fresh token (tokens are hash-only at rest).
Inputs: title, user_id, entity_id, html_body, +3 more.
query_contacts_at_companyA
Answer "who do we have connected at company X": resolve company_name to the canonical company entity (exact-normalized match first, then a conservative fuzzy pass — the same resolution order used when a contact's organization field auto-links to a company at store time) and return every contact linked to it via a live works_at edge. Read-only: never creates a company entity — when no company matches, returns company: null and an empty contacts list. Optional owner_user_id scopes the search to a specific partner's network (must equal the authenticated user's id today; no cross-tenant admission yet); omit to search the authenticated user's own graph.
Inputs: company_name (required), limit, owner_user_id.
register_relationship_typeA
Register a relationship type after discovering the vocabulary with list_relationship_types. Requires an active grant with register_relationship_type and relationship_types permission; global scope additionally needs explicit global permission. Defaults to user scope. Refresh cached tool definitions after registration, then write the edge and read it back.
Inputs: relationship_type (required), scope, acyclic, inverse, +4 more.
register_schemaC
Register a new schema or schema version. Supports both global and user-specific schemas.
Inputs: entity_type (required), reducer_config (required), schema_definition (required), force, +4 more.
remove_peerC
Deactivate a peer by peer_id.
Inputs: peer_id (required).
resolve_sync_conflictD
Stub; use correct on the entity for manual resolution today.
Inputs: strategy (required), entity_id (required), sender_peer_url, guest_access_token.
restore_entityB
Restore visibility of an entity through an immutable lifecycle observation and expose its current factual reduction, including ordinary facts accepted while hidden. After the explicit authority cutover, serialized action sequence controls visibility; before cutover, existing legacy behavior applies. Each accepted request is a separate action, without an idempotency key or historical beforeimage restoration.
Inputs: entity_id (required), entity_type (required), reason, user_id.
restore_relationshipA
Restore a deleted relationship. Creates an immutable restoration observation that outranks earlier observations. Relationship becomes visible in snapshots and queries again; later explicit deletion remains possible.
Inputs: source_entity_id (required), target_entity_id (required), relationship_type (required), reason, +1 more.
retrieve_entitiesA
Use this when you need filtered entity lists (by type, pagination, and optional published/date filters) or lexical/semantic retrieval via search. Strict mode: search cannot be combined with non-default sorting or published filters. Set include_snapshots=false for lightweight responses that omit snapshot/provenance/raw_fragments. Use snapshot_filters to filter by snapshot field values server-side (e.g. { "status": { "op": "eq", "value": "active" } } for active entities). Compatibility aliases search_query and query are accepted but search is canonical. For deep pagination under the default sort (sort_by=entity_id), pass the next_cursor from a prior response back as cursor instead of a large offset; offset beyond a bounded depth is rejected and cursor is not supported with search, non-default sort_by, or a non-zero offset in the same call.
Inputs: limit, query, cursor, offset, +17 more.
retrieve_entity_by_identifierA
Retrieve entity by identifier (name, email, etc.) across entity types or specific type. Falls back to semantic search when keyword match returns no results. A literal entity_id (ent_) short-circuits to a direct primary-key lookup; if no entity has that id, the response carries a hint pointing to retrieve_entity_snapshot.
Inputs: identifier (required), by, limit, entity_type, +2 more.
retrieve_entity_snapshotB
Retrieve the current snapshot of an entity with provenance information. Supports historical snapshots via 'at' parameter.
Inputs: at, format, entity_id, at_ingested, +1 more.
retrieve_field_provenanceC
Retrieve the provenance chain for a specific field in an entity snapshot
Inputs: field, entity_id.
retrieve_file_urlC
Retrieve a signed URL for accessing a file
Inputs: file_path (required), expires_in.
retrieve_graph_neighborhoodB
Retrieve complete graph neighborhood around a node (entity or source): related entities, relationships, sources, and events.
Inputs: node_id (required), limit, offset, node_type, +4 more.
split_entityA
R5 inverse of merge_entities. Re-points a predicate-selected subset of an entity's observations onto a new or pre-existing entity to repair over-merges (typically the pre-v1.2 heuristic name_key:title collapse on session-scoped types). Schema-agnostic predicate — supply any of observed_at_gte, source_id_in, or observation_field_equals. Observation content is never modified; only entity_id FK is re-bound. Idempotent via (user_id, idempotency_key) — reuse with a different predicate returns ERR_IDEMPOTENCY_MISMATCH. Typed relationships remain bound to the source; rebuild them with create_relationship.
Inputs: predicate (required), new_entity (required), idempotency_key (required), source_entity_id (required), +2 more.
storeA
Unified storing for structured, file-backed, or combined payloads in one request. Choose path by source: file- or resource-sourced (attachment/file to preserve) → use file_content+mime_type or file_path; conversation- or tool-sourced (chat or other MCP) → use entities. You may send both entities and file input in the same call. File bytes create a content-addressed sources row (SHA-256 dedup per user); the response includes source_id / content_hash for the unstructured leg. The server does not invent structured fields from opaque blobs without an explicit interpretation block or a separate interpretation flow. Agents should parse and extract entities first when they need structured data from a readable file, then send those entities alongside the raw file. IMPORTANT FOR STRUCTURED DATA: Include ALL fields from source data. Schema fields go to observations; non-schema fields go to raw_fragments for future schema expansion. Relationships must link entities you own; a refused relationship is reported in relationships_refused rather than failing the call.
Inputs: commit, strict, user_id, entities, +14 more.
submit_entityA
Generic submission for entity types with an active submission_config. Creates the primary row plus optional conversation thread and guest_access_token; use submit_issue for GitHub-backed issues.
Inputs: fields (required), entity_type (required), initial_message.
submit_issueA
Submit an issue to the configured operator Neotoma instance; returns guest_access_token when accepted so callers can use token-scoped get_issue_status / add_issue_message read-back. No prior identity is required: a remote caller with no Bearer token, no AAuth signature and no guest token may submit whenever the operator instance's issue guest access policy permits guest writes — the token is an OUTPUT of the submit, not a precondition for it, so first contact needs no credential. Anonymity covers submission only; use the returned guest_access_token for add_issue_message and get_issue_status. Callers must provide at least one of reporter_git_sha or reporter_app_version. Deprecated alias: visibility 'advisory' is accepted as 'private' for one minor release and returns _deprecation: "visibility 'advisory' is deprecated; use 'private' instead."
Inputs: body (required), title (required), labels, visibility, +8 more.
subscribeA
Create a substrate event subscription (webhook with HMAC delivery, or SSE via GET /events/stream). Requires at least one filter among entity_types, entity_ids, or event_types. Optional sync_peer_id skips webhook delivery when the substrate event carries the same source_peer_id (cross-instance loop prevention).
Inputs: delivery_method (required), entity_ids, event_types, webhook_url, +4 more.
sync_entity_submissionsA
Sync external mirrors for submissions (issue → GitHub sync; other types may no-op until providers are added).
Inputs: entity_type.
sync_issuesA
Sync local Neotoma with a GitHub repo's issues. Pull leg: GitHub issues and their messages are pulled into local entities. Push leg: local public issues with no github_number are sanitized (PII stripped) and created on GitHub, then updated locally with the returned number/url. Target repo defaults to the server-configured repo (NEOTOMA_ISSUES_REPO); pass repo (owner/name) to mirror a different repo for one call without changing server config. The push leg is ON by default only for the configured default repo and OFF for any other repo unless push: true is passed. Pass commit: false for a dry run that reports what would be created, updated and pushed and writes nothing. Requires a GitHub token: NEOTOMA_ISSUES_GITHUB_TOKEN in the server environment (or gh auth login on the server host). Supports filtering by state, labels, and since date.
Inputs: push, repo, since, state, +2 more.
sync_peerC
Bounded outbound peer sync: POST signed /sync/webhook for observations (requires NEOTOMA_PUBLIC_BASE_URL, NEOTOMA_LOCAL_PEER_ID, peer sync_target_user_id). Optional limit.
Inputs: peer_id (required), limit.
unsubscribeC
Deactivate a subscription by subscription_id.
Inputs: subscription_id (required).
update_schema_incrementalA
Incrementally update a schema by adding fields (fields_to_add — minor version bump), removing fields (fields_to_remove — major version bump; observation data preserved, snapshot-excluded until re-added), or changing the identity rule (canonical_name_fields — major version bump). Creates a new schema version and activates it immediately, so all new data stored after this call uses the updated schema. Optionally migrates existing raw_fragments to observations for historical data backfill.
canonical_name_fields re-keys how the type derives canonical_name / identity. Rules are ordered precedence with fallback — the first rule whose fields are all present wins, e.g. [{composite:["linkedin_url"]},"email","name"] keys on linkedin_url, else email, else name. Reach for it when same-name-different-entity collisions appear (e.g. a bulk import collapses distinct people who share a name because identity resolves on name alone). The existing reducer_config is preserved automatically, so this is the safe way to re-key without a full register_schema re-supply. Applies to NEW writes only — it does not retroactively re-key existing entities, so it will not by itself merge existing duplicates. Omit to keep the current rule; pass [] to clear it (succeeds only if the schema also declares identity_opt_out). The response echoes the resolved canonical_name_fields; call describe_entity_type first to see the current rule before replacing it.
Scope: omit user_specific to write to whichever scope your schema resolves to (your user-scoped override if you have one, else global); the response's scope (and user_id when scope is user) reports what was written. Pass user_specific: true or false only to override that. migrated_existing is true only when migrate_existing actually promoted fragments; migration_result.skipped says why any did not. If entity_type is rejected by a naming guard whose message names force: true as the remedy, retry with force: true.
On ERR_SCHEMA_SCOPE_MISMATCH (only after an explicit user_specific: false, when the type has no global registry row and no code-defined baseline) an active schema exists in a different scope than the call checked (details.guard_scope vs details.found_scope). Retry without user_specific, or with user_specific matching details.found_scope. Never call register_schema for that code — a second active row for the same entity_type risks dual-active corruption (#2374/#2378).
Inputs: entity_type (required), force, user_id, activate, +6 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 67 tools
Many tools overlap in purpose: retrieval is split across retrieve_entities, retrieve_entity_by_identifier, identify_entity_by_signals, retrieve_entity_snapshot, retrieve_related_entities, and retrieve_graph_neighborhood; writing/correcting across store, correct, correct_transaction, and patch_array_item; and generic vs issue-specific submission across submit_entity, submit_issue, add_entity_message, and add_issue_message. Detailed descriptions help, but the boundaries still require careful reading and invite misselection.
Most tools follow a snake_case verb_noun pattern (list_observations, retrieve_entity_snapshot, create_relationship, delete_entity), with reasonable variety among verbs like get, list, and retrieve. Minor deviations include single-word imperative tools (store, correct, subscribe) and noun-first names (neotoma_turn_summary, npm_check_update, health_check_snapshots), but the overall convention remains readable and predictable.
With 67 tools, the surface is far beyond the typical 3-15 range and qualifies as an extreme mismatch according to the rubric. Even for a complex knowledge-graph platform, this volume creates selection overhead and makes it hard for an agent to hold the whole toolset in working memory.
The server covers a broad lifecycle: storing, correcting, deleting, and restoring entities; managing schemas, relationships, observations, provenance, submissions, subscriptions, peers, bundles, and issues. Some gaps remain, such as resolve_sync_conflict being an explicit stub and no direct update_relationship operation, but core workflows are otherwise well supported.
Maintenance
Related MCP Connectors
Persistent memory for AI agents across Claude, ChatGPT and any MCP client.
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Related MCP Servers
- AlicenseAqualityBmaintenanceA local-first shared memory layer for MCP-aware agents like Claude, Codex, and Hermes, enabling persistent memory across chats and clients via Markdown files and SQLite FTS.62MIT
- AlicenseAqualityCmaintenanceLocal-first, source-traceable memory for AI agents — no LLM at ingest, $0 per message, zero data egress. Gives Claude Code, Cursor, and any MCP client one shared persistent memory with semantic recall, belief revision, selective forgetting, and a provenance guard that blocks acting on stale or unconfirmed memories.2314MIT
- AlicenseNot gradedqualityFmaintenanceLocal-first, auditable memory for AI agents. Provides durable context for MCP hosts with SQLite storage, CLI, and MCP tools for memory management.2Apache 2.0
- AlicenseCqualityBmaintenanceLocal-first, governable long-term memory for AI agents. Provides SQLite-backed storage, cross-session recall, and traceable memory corrections through a standard MCP interface.4036 PyPI1MIT