Metadata-Version: 2.4
Name: mcp-temporal-knowledge
Version: 0.7.1
Summary: Temporal Knowledge Substrate MCP Server — domain-scoped knowledge accumulation with tool-enforced temporal integrity
Requires-Python: >=3.10
Requires-Dist: fastmcp>=2.0.0
Requires-Dist: neo4j>=5.26.0
Requires-Dist: pydantic>=2.10.1
Requires-Dist: starlette>=0.28.0
Description-Content-Type: text/markdown

# Temporal Knowledge Substrate

An MCP server that lets LLM agents accumulate organizational knowledge across sessions, scoped by domain, backed by Neo4j. Tools enforce structural invariants so the graph can't corrupt itself — no raw Cypher writes.

**Two-layer architecture:**
- **Process layer** — Domains own Sessions. Sessions chain forward in time via `NEXT_SESSION`. The arrow of time is enforced by the tool, not by instructions.
- **Knowledge layer** (append-only) — 10 ontological types + 5 sub-labels via Neo4j multi-labeling, connected by 11 relationship types. Knowledge evolves via `EVOLVED_FROM` chains — every prior moment is preserved, never overwritten.

**The principle:** the tool may make claims about the graph but may not make claims about consciousness. Collisions error rather than silently merge. Description changes always create a new chain node — `update_knowledge` and `retype_knowledge` do not exist by design. See `HOWTO.xml` for the operator-facing teaching, and `docs/design/` for the design archive.

## Prerequisites

- Python 3.10+
- [uv](https://docs.astral.sh/uv/) package manager
- Neo4j 5.x instance (local or remote)

## Quick Start

```bash
# Install
uv sync

# Run (stdio transport, default for MCP clients)
mcp-temporal-knowledge --db-url bolt://localhost:7687
```

## Configuration

All options can be set via CLI flags or environment variables. CLI takes precedence.

| CLI Flag | Env Var | Default | Description |
|---|---|---|---|
| `--db-url` | `NEO4J_URI` or `NEO4J_URL` | `bolt://localhost:7687` | Neo4j connection URL |
| `--username` | `NEO4J_USERNAME` | `neo4j` | Neo4j username |
| `--password` | `NEO4J_PASSWORD` | `password` | Neo4j password |
| `--database` | `NEO4J_DATABASE` | `neo4j` | Neo4j database name |
| `--transport` | `NEO4J_TRANSPORT` | `stdio` | Transport: `stdio`, `sse`, or `streamable-http` |
| `--namespace` | `NEO4J_NAMESPACE` | *(none)* | Tool name prefix (e.g. `myapp` -> `myapp-begin_session`) |
| `--server-host` | `NEO4J_MCP_SERVER_HOST` | `127.0.0.1` | HTTP host (non-stdio transports) |
| `--server-port` | `NEO4J_MCP_SERVER_PORT` | `8000` | HTTP port (non-stdio transports) |
| `--server-path` | `NEO4J_MCP_SERVER_PATH` | `/mcp/` | HTTP path (non-stdio transports) |

## MCP Client Configuration

### Claude Desktop / Claude Code

Add to your MCP config:

```json
{
  "mcpServers": {
    "temporal-knowledge": {
      "command": "mcp-temporal-knowledge",
      "args": ["--db-url", "bolt://localhost:7687"]
    }
  }
}
```

### HTTP transport

```bash
mcp-temporal-knowledge \
  --db-url bolt://localhost:7687 \
  --transport streamable-http \
  --server-host 0.0.0.0 \
  --server-port 8000 \
  --allow-origins "http://localhost:3000" \
  --allowed-hosts "localhost,127.0.0.1"
```

## Tool Surface (22 tools)

### Session workflow

Every session follows: `create_domain` (once) → `begin_session` → create/evolve/confirm knowledge → `end_session`

| Tool | Description |
|---|---|
| `list_domains` | List all domains with session counts and last activity |
| `create_domain` | Create a knowledge domain (idempotent) |
| `begin_session` | Start a session — returns `session_id` needed by all knowledge tools. `purpose` is required. |
| `end_session` | Close a session with a summary of what was learned |

### Knowledge mutation

| Tool | Description |
|---|---|
| `create_knowledge` | Create entities. Refuses on collision (use evolve, confirm, or a different name) |
| `evolve_knowledge` | Create a new chain node — preserves the prior version via `EVOLVED_FROM`. Optional `sub_labels` parameter for sub-classification changes within the ontological type |
| `confirm_knowledge` | Record that entities were reviewed and found unchanged |
| `merge_knowledge` | Compact an `EVOLVED_FROM` chain into a single canonical node (destructive — for cleanup of exploratory churn) |
| `create_connections` | Link entities (`ENABLING`, `REQUIRING`, `INFORMING`, `CAUSING`, `EXTENDING`, `RECOGNITION`, `VALIDATION`, `INVALIDATING`, etc.) |

### Querying

| Tool | Description |
|---|---|
| `search_knowledge` | Fulltext search across names and descriptions (head-of-chain only) |
| `get_domain_state` | All current (head-of-chain) entities for a domain |
| `get_session_history` | Session history — who worked on what, when |
| `get_chain_history` | Walk `EVOLVED_FROM` backward — see what was previously understood about an entity |
| `read_cypher` | Read-only Cypher escape hatch (writes rejected) |

### Taxonomy & Analytics

| Tool | Description |
|---|---|
| `list_knowledge_types` | 10 ontological types + 5 sub-labels with the sub-label → ontological-type mapping |
| `list_connection_types` | 11 knowledge + 4 process edge types |
| `gds_create_projection` | Create a GDS graph projection for analytics |
| `gds_drop_projection` | Drop a GDS projection |
| `gds_pagerank` | PageRank centrality |
| `gds_betweenness` | Betweenness centrality (bridge nodes) |
| `gds_louvain` | Louvain community detection |
| `gds_wcc` | Weakly connected components |

## Type System

Every knowledge node carries:
- Exactly one ontological label (one of 10 below)
- An `ont_type` property naming that label deterministically
- Zero or more sub-labels via Neo4j multi-labeling

| Ontological type | Category | Sub-labels |
|---|---|---|
| `Actor` | Referent | `Person`, `Organization` |
| `Structure` | Referent | `System`, `Process`, `Configuration` |
| `Artifact` | Referent | *(none)* |
| `Event` | Event | *(none)* |
| `Insight`, `Pattern`, `Challenge`, `Solution`, `Lesson`, `Rationale` | Emergence | *(none)* |

API ergonomics: `create_knowledge` accepts either an ontological type (`Actor`) or a known sub-label (`Person`) as the `type` field. When a sub-label is given, the substrate auto-applies BOTH labels via multi-labeling (e.g., `(:Actor:Person)`).

## Upgrading from v0.6.x

v0.7.0 is a breaking change. Migration script:

```bash
.venv/bin/python -m mcp_temporal_knowledge._migration.v0_7_0 \
    --db-url bolt://localhost:7687 \
    --username neo4j --password ... \
    --database <name> \
    [--dry-run]
```

Eight phases, each independently reversible. `--database` is required (Neo4j Desktop 2 hosts multiple named databases on one instance). Phase 7 (Dependency reclassification) is operator-assisted — the script lists nodes for manual reclassification. See `CHANGELOG.md` for the full breaking-change inventory and `docs/design/` for the principle and design archive.

## Development

```bash
# Install with dev dependencies
uv sync --dev

# Run tests
uv run pytest

# Type checking
uv run pyright
```

See `HOWTO.xml` for the ontological commitments and tool behavior. Provide this to the LLM as invariant scaffolding.
