* docs/plan/11-slice-mcp-http-docker.md: slice plan with AC + test plan, mirroring the 11 existing plan docs. * docs/adr/0010-streamable-http-transport.md: captures Streamable HTTP vs legacy HTTP+SSE, Starlette vs FastAPI/mcp-lib, stateless v1 (no Mcp-Session-Id), one-shot JSON as common case, append to requirements vs split, baked graph + mount override. * CONTEXT.md: new 'Transports' section under Operations documenting the transport-agnostic dispatcher + stdio + Streamable HTTP.
4.8 KiB
Lore Engine
A reasoning substrate for a high-fantasy world. Its single product: when an LLM asks a question about the world, it gets a precise, time-bound, contradiction-checked answer traceable to the document it came from. Built on Cognee (the substrate); the Lore Engine is the domain layer on top.
Language
Entities & structure
Lineage: A blood relationship — descent from a founding ancestor. A person has at most one Lineage. Avoid: family, house (a house is a Faction, not a Lineage)
Faction: An association — a House, Order, or Guild. A person can belong to many Factions over time. Avoid: house (when meaning blood — that's Lineage)
Region:
A geographic concept — a continent, kingdom, forest, dungeon. Exists inside a Plane. PART_OF between Regions means "geographically contains."
Avoid: plane (a plane is not geographic)
Plane:
A mode of existence — Material, Shadow, Voldramir, the Feywild. Plane-relation edges (REFLECTS, LAYER_OF, ADJACENT_TO, ACCESSIBLE_VIA) are between Planes.
Avoid: region, world
Setting:
A top-level namespace — a campaign or world. Hosts one or more Planes. The v1.2 replacement for the flat world_id string.
Avoid: world, world_id (deprecated)
LoreSource:
A document ingested into the engine (prose, timeline YAML, dialogue log). Carries a reliability and is the unit of source attribution.
Confidence & conflict
extraction_confidence: Did we extract this triple correctly? A per-triple score (0.0–1.0) from the LLM extractor.
source_confidence:
How reliable is the document a triple came from? Derived from LoreSource.reliability (canonical 1.0 → fanon 0.3).
aggregate_confidence:
The floor — min(extraction_confidence × source_confidence) across every source on an edge. Not a mean or max. (ADR 0001.)
Avoid: confidence (unqualified — say which dimension)
Disputed edge:
When two sources produce the same (subject, relation, object) with conflicting time bounds. Kept as separate Relation records, both marked is_disputed: true, linked via disputed_with — not merged. (ADR 0002.)
Relation:
A reified-edge node — the representation for any edge that carries time bounds or confidence (RULED, MEMBER_OF, PARTICIPATED_IN, …). Carries valid_from/valid_until/extraction_confidence/source_confidence/is_disputed/superseded_by. Native edges (Cognee field-nesting) are used only for structural edges that never need time (is_type, template-wiring). Promoted from v1.1 to v1 (ADR 0009).
Contradiction: A first-class node flagging incompatible claims between LoreSources. Built from scratch in slice 2 — Cognee ships no contradiction machinery.
Time
at_time / as_of:
at_time scopes a query to an in-world moment. as_of scopes it to a retcon boundary — what the world-builder knew on a given date, before a retcon.
Retcon:
A declared revision that supersedes — never deletes — an old fact. Old edges are marked superseded_by; both pre- and post-retcon states stay answerable.
Operations
ConsistencyRun:
A record of one execution of the consistency engine (started_at, rules_run, violations_found). The LLM checks latest_run() before answering historical questions.
Cognee:
The substrate — the MIT-licensed framework that owns extraction, embedding, and the remember/recall/forget API. Pinned at v1.1.2 (ADR 0006). Graph backend pinned to Neo4j, overriding Cognee's Kuzu default (ADR 0008).
Transports
MCP (Model Context Protocol): The wire protocol clients use to talk to the server. We implement MCP 2024-11-05 over two transports:
- stdio (slice 2.6) — JSON-RPC 2.0 over stdin/stdout, stdlib only.
Entry:
scripts/05_mcp_server.py. Used by Claude Desktop, Continue, Cline, and any stdio-native MCP client. - Streamable HTTP (slice 11, ADR 0010) — single
POST /mcpendpoint. The response body is eitherapplication/json(one-shot, the common case) ortext/event-stream(SSE-upgraded via the client'sAcceptheader). Entry:scripts/06_mcp_http_server.py. Container:lore-engine-mcp(Dockerfile + docker-compose.yml).
The dispatcher in lore_engine_poc.mcp_server.MCPServer is
transport-agnostic — both transports are thin adapters over
handle_message(msg) -> Optional[dict]. The 36-tool registry
(TOOL_REGISTRY in mcp_tools.py) is shared verbatim between
them.
Avoid list (global)
- world_id — use
setting_id. - "inherited from GraphMCP-Example" — the prior substrate; no longer used. Cognee is the substrate. GraphMCP-Example appears only in historical comparisons ("the original design," "cheaper than the prior stack").
- confidence (unqualified) — say
extraction_confidence,source_confidence, oraggregate_confidence.