Metadata-Version: 2.4
Name: mimir-ontology
Version: 0.1.0
Summary: A lightweight, local-first ontology engine for AI agents.
License-Expression: AGPL-3.0-only
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: fastmcp>=3.4.4
Requires-Dist: pydantic>=2.7
Requires-Dist: pyyaml>=6.0
Requires-Dist: typer>=0.12
Description-Content-Type: text/markdown

# Mimir

Mimir is a small, local-first ontology engine for AI agents. You describe your domain in a YAML
schema (types, properties, links), feed the engine claims from your data sources, and it
materializes a typed graph that an agent can query over MCP — with every value traceable to the
claim, and therefore the source, it came from.

The engine is event-sourced. The only source of truth is an append-only log of *claims* ("source
X asserts fact Y"); the queryable graph is a deterministic projection of that log. The same
claims always materialize into the byte-identical graph, nothing is ever mutated in place, and
conflicts between sources are resolved by explicit rules instead of overwrites — the losing
claims stay reachable.

Everything runs in one process on your machine: one SQLite file, one YAML schema, one MCP server.
There is no LLM inside the engine and no network access in the core, by design.

## Install

```
pip install mimir-ontology        # or: uv add mimir-ontology
```

The distribution is named `mimir-ontology`; the package you import and the CLI command are
`mimir`.

## Quickstart

The repository ships a demo world: a fictional plumbing business asserted by two fixture sources
that overlap, disagree and occasionally make mistakes — on purpose. The full walkthrough with
expected output and explanations is in [`examples/plumber/demo.md`](examples/plumber/demo.md);
the short version:

```console
$ uv run mimir init demo-ws
$ uv run mimir schema load examples/plumber/schema.yaml --dir demo-ws
$ uv run mimir ingest examples/plumber/claims.jsonl --dir demo-ws
Ingested claims.jsonl: 88 accepted, 0 duplicates, 0 quarantined.
$ uv run mimir materialize --dir demo-ws
Materialized 88 claims: 43 entities, 35 links, 4 extra properties, 2 quarantined.
Graph hash: grf_e03212dfede98982
```

Along the way the engine merged the customers both sources asserted (natural keys), resolved a
phone-number disagreement by observation time, kept an undeclared property in the entity's
`extra` pocket instead of dropping it, and quarantined two unprocessable claims with
machine-readable reasons. Ingest is idempotent: run it again and you get `88 duplicates`.

Inspect the graph from the shell (`--json` for machine output):

```console
$ uv run mimir search Job --filter status=done --limit 3 --dir demo-ws
$ uv run mimir show ent_6f65b3bf159ff099 --dir demo-ws
```

Serve it to an agent:

```console
$ uv run mimir serve-mcp --dir demo-ws
```

The server speaks MCP over stdio and exposes four read-only tools: `describe_schema`, `get`,
`search`, `traverse`. In a clone of this repository, `.mcp.json` already registers the server for
Claude Code — run the quickstart above, start `claude`, and ask:

> Which finished jobs have no invoice, and what is the total uninvoiced amount?

The agent reads the schema, narrows with `search`, walks `traverse`, and answers with figures
that are each traceable to a specific claim. When it guesses a link name that does not exist, the
server replies with a structured error naming the valid options.

## How it works

```
claims.jsonl ──ingest──▶  claim log            append-only, content-addressed (SQLite)
                             │
                        materialize            pure function: (schema, claims) → graph;
                             │                 same input, byte-identical output
                             ▼
                        typed graph            entities + links, every value with provenance
                             │
                        serve-mcp              read-only MCP tools for agents
```

Five primitives: **Claim** (an atomic assertion by a source), **Schema** (your ontology, loaded
from YAML — the engine hardcodes no domain type), **Entity** and **Link** (the materialized
graph), **Provenance** (who said it, based on what, when). Identity is content-derived
throughout: the same natural keys land on the same entity no matter which source asserted them,
and re-materialization can rebuild the whole graph from the log at any time.

This release is the engine core: primitives, append-only store, deterministic materialization,
schema-as-config, read-only MCP surface. Next up is a richer agent-facing query surface.

## Development

Requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).

```
uv sync                  # install dependencies
uv run pytest            # run tests
uv run ruff check .      # lint
uv run ruff format .     # format
uv run mypy .            # strict type check
uv run mimir --help      # CLI
```

## License

AGPL-3.0-only. See `LICENSE`.
