An MCP server that gives AI agents a permanent, append-only causal history
Project description
History Graph Protocol (HGP)
An MCP server that gives AI agents a permanent, append-only causal history.
HGP records what an agent did and why — every file write, every decision, every piece of evidence behind each action. Where memory systems store what an agent knows, HGP stores what an agent did. Think of other memory systems as working memory; HGP is the audit trail.
Why HGP?
| Without HGP | With HGP |
|---|---|
| Agent writes a file — no record of why | Every file write is a traceable artifact |
| Decision rationale lives only in context | Hypotheses and evidence are permanently stored |
| Can't tell what changed or when | Full causal graph: who did what, citing what |
| Session ends, history is gone | History persists across sessions and agents |
Core Concepts
Operations (Nodes)
Every action is an immutable, append-only record. Four types:
| Type | When to use |
|---|---|
artifact |
A produced output — file written, data generated |
hypothesis |
A decision, plan, or inference |
merge |
Combining multiple prior operations |
invalidation |
Superseding or retracting a prior operation |
Operations are never deleted or mutated. The graph only grows.
Causal Graph (DAG)
Operations are connected by directed edges:
causal— A produced B (B depends on A)invalidates— A supersedes B
graph LR
A["op-1\nartifact\n(analysis)"]
B["op-2\nhypothesis\n(decision)"]
C["op-3\ninvalidation\n(revised decision)"]
A -->|causal| B
C -->|invalidates| B
A -->|causal| C
Memory Tier
Each operation has a memory tier that reflects access recency:
| Tier | Meaning |
|---|---|
short_term |
Recently active; included in all queries |
long_term |
Older but still reachable; included in all queries |
inactive |
Not accessed recently; excluded from default queries, never deleted |
Tiers update automatically and can be set manually via hgp_set_memory_tier.
Evidence Trail
Operations can cite other operations as evidence, independently of the DAG edge structure. Evidence relations carry:
- relation —
supports,refutes,context,method, orsource - scope — which aspect of the citing op this evidence applies to
- inference — free-text explanation of how the evidence was used
Given any decision, you can reconstruct exactly what evidence it was based on and how each piece was interpreted.
Installation
Prerequisites: Python ≥ 3.12
pip install history-graph-protocol
The PyPI package is
history-graph-protocol; the installed CLI command ishgp.
Verify the install before proceeding:
command -v hgp # confirms hgp is on PATH
python -c "import hgp; print(hgp.__version__)" # confirms the package is importable
If command -v hgp prints nothing, the package was installed in a Python environment whose bin/ is not on your PATH. Activate the virtual environment first, then re-run the checks.
If using a virtual environment, activate it first — all subsequent
hgpcommands must run in the same environment.
One-command setup
hgp install
This registers HGP as an MCP server, installs hooks, and injects agent instructions — all in one step. Supports Claude Code, Gemini CLI, and Codex:
hgp install # all supported clients (recommended)
hgp install --claude # Claude Code only
hgp install --gemini # Gemini CLI only
hgp install --codex # Codex only
hgp install --local # project-local scope instead of global
hgp install prints a step-by-step report. Each line starts with ✓ (success) or ✗ (skipped/failed):
Claude Code:
✓ MCP: registered
✓ hooks files: installed 3 file(s) → /Users/you/.claude/hooks
✓ hooks settings: updated
✓ instructions: injected
A ✗ line includes a reason (e.g. claude CLI not found — skipping MCP registration). All ✓ lines mean the install succeeded for that client.
Verify config files were written (no client restart needed for this check):
| Client | Hooks dir | MCP config written by |
|---|---|---|
| Claude Code | ~/.claude/hooks/ |
claude mcp add (via CLI) |
| Gemini CLI | ~/.gemini/hooks/ |
gemini mcp add (via CLI) |
| Codex | ~/.codex/hooks/ |
~/.codex/config.toml |
For local scope (--local), paths are under <repo_root>/.claude/, <repo_root>/.gemini/, or <repo_root>/.codex/ respectively.
Restart your client to load the newly registered MCP server. This requires human action — an AI agent cannot restart its own host process. After restarting, the HGP tools (hgp_write_file, hgp_create_operation, etc.) will appear in the tool list.
Manual setup
Python path: In all commands below,
pythonmust be the Python that hashistory-graph-protocolinstalled. Find the correct path withpython -c "import sys; print(sys.executable)"(after activating your venv if applicable), then substitute it forpythonthroughout.
Configure without hgp install
Claude Code:
claude mcp add --scope user hgp -- python -m hgp.server
Gemini CLI:
gemini mcp add --scope user hgp python -m hgp.server
Codex — add to .codex/config.toml:
[mcp_servers.hgp]
command = "python"
args = ["-m", "hgp.server"]
[features]
codex_hooks = true # enable lifecycle hooks (required for HGP hook support)
To also install hook files (.codex/hooks/) and hooks.json, run hgp install --codex instead. Manual config covers MCP registration and feature flag only. Currently Codex fires PreToolUse/PostToolUse hooks for Bash commands only; apply_patch (file edits) support is a known upstream issue.
Use the Python that has
history-graph-protocolinstalled. If using a virtual environment, replacepythonwith the absolute path to the venv Python (e.g./path/to/.venv/bin/python).
Quick Start
These are MCP tool calls — invoke them through your MCP client (Claude Code, Gemini CLI, or any MCP-compatible host).
# Write a file and record it as an artifact
hgp_write_file(
file_path="src/analysis.py",
content="...",
agent_id="claude-code",
metadata={"description": "Initial analysis script"},
)
# → returns op_id: "op-abc123"
# Record the decision that led to a follow-up file
decision = hgp_create_operation(
op_type="hypothesis",
agent_id="claude-code",
metadata={"description": "Refactor to use async based on profiling results"},
parent_op_ids=["op-abc123"],
)
# Write the refactored file, linked to the decision
hgp_write_file(
file_path="src/analysis.py",
content="...",
agent_id="claude-code",
parent_op_ids=[decision["op_id"]],
)
# Later: audit what happened to a file
hgp_file_history(file_path="src/analysis.py")
# → all HGP operations recorded for this file, in order
Tool Index
File tools
| Tool | Description |
|---|---|
hgp_write_file |
Write (create or overwrite) a file and record it as an artifact |
hgp_append_file |
Append content to a file and record as artifact |
hgp_edit_file |
Replace a unique string in a file and record as artifact |
hgp_delete_file |
Delete a file and record an invalidation operation |
hgp_move_file |
Move/rename a file; records invalidation of old path + new artifact |
hgp_file_history |
Return all HGP operations recorded for a given file path |
Graph tools
| Tool | Description |
|---|---|
hgp_create_operation |
Record a new operation; optionally attach payload, link parents, cite evidence |
hgp_query_operations |
Filter operations by type, agent, status, or memory tier |
hgp_query_subgraph |
Traverse ancestors or descendants from a root operation |
hgp_get_evidence |
List all operations a given op cited as evidence |
hgp_get_citing_ops |
Reverse lookup — list all ops that cited a given op as evidence |
hgp_get_artifact |
Retrieve binary payload from CAS by its object_hash |
hgp_anchor_git |
Link an operation to a Git commit SHA (requires full 40-char lowercase hex SHA) |
hgp_set_memory_tier |
Manually set an operation's memory tier (short_term, long_term, inactive) |
Lease tools
Leases provide optimistic locking for multi-step write sequences.
| Tool | Description |
|---|---|
hgp_acquire_lease |
Acquire a lock on a subgraph before multi-step writes |
hgp_validate_lease |
Check a lease is still active; extends TTL by default |
hgp_release_lease |
Release a lease explicitly after writing |
Maintenance
| Tool | Description |
|---|---|
hgp_reconcile |
Run crash-recovery reconciler (use after unexpected shutdown) |
Token-sensitive sessions: mutation tools accept
verbose=Falseto omitchain_hashandobject_hashfrom responses, reducing per-call token overhead by ~73%. Default isverbose=True.
→ Full API reference: docs/tools-reference.md
→ Usage patterns and examples: docs/usage-patterns.md
Configuration
HGP mode
Control whether HGP records operations. Mode is stored in <repo_root>/.hgp/mode. Agents are blocked from changing it via the hgp mode Bash command — the pre-Bash hook intercepts and rejects those calls.
hgp mode # show current mode (default: on)
hgp mode on # normal operation
hgp mode advisory # mutation tools return HGP_ADVISORY instead of recording
hgp mode off # all tools return HGP_DISABLED
| Mode | Mutation tools | Query tools |
|---|---|---|
on |
execute normally | execute normally |
advisory |
return {"status": "HGP_ADVISORY"} |
execute normally |
off |
return {"status": "HGP_DISABLED"} |
return {"status": "HGP_DISABLED"} |
Hook enforcement policy
Hooks warn (or block) when native file tools are used instead of HGP equivalents.
hgp hook-policy # show current policy (default: advisory)
hgp hook-policy advisory # warn only — native file tools still allowed
hgp hook-policy block # block native Write/Edit/MultiEdit/write_file/replace
If you installed hooks before this feature was added, run
hgp installagain to update them.
Storage
HGP stores its database and content-addressable blobs in <repo_root>/.hgp/ (gitignored). The server resolves the project root from the nearest .git directory at startup.
- Graph tools (
hgp_create_operation, queries, etc.): if no git repo is found, fall back to<cwd>/.hgp/with a warning. - File tools (
hgp_write_file,hgp_edit_file, etc.): always require a git repo or an explicitHGP_PROJECT_ROOT. Without one, they returnPROJECT_ROOT_NOT_FOUND.
The .hgp/ directory is reserved for HGP internals. File tools reject any path that contains a .hgp directory segment — including nested paths like sub/.hgp/file.txt — and return HGP_INTERNAL_PATH. This applies across all .hgp/ directories in a project tree, which is intentional for monorepo and nested-repo layouts.
One server process is bound to one store.
Environment variables
| Variable | Default | Description |
|---|---|---|
HGP_PROJECT_ROOT |
(auto) | Override project root (default: nearest .git from cwd, then cwd) |
HGP_HOOK_BLOCK |
0 |
Set to 1 to block native file tool calls instead of warning |
Run as MCP server
hgp
# or
python -m hgp.server
HGP uses stdio transport and is compatible with any MCP-compliant host.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file history_graph_protocol-0.4.0.tar.gz.
File metadata
- Download URL: history_graph_protocol-0.4.0.tar.gz
- Upload date:
- Size: 160.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90a3affc953effb2988cc2ef01196d7297b07c0c4d42d685b911fb29d2137463
|
|
| MD5 |
4a1f92587eace4b05ef1dd6b8aa96775
|
|
| BLAKE2b-256 |
52c9c91464a6b7c25b5cedad36be05961ce7e065aab9d49a57c5e1fd32780435
|
File details
Details for the file history_graph_protocol-0.4.0-py3-none-any.whl.
File metadata
- Download URL: history_graph_protocol-0.4.0-py3-none-any.whl
- Upload date:
- Size: 58.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9460498d543d0b654615f0595a0c904dbbfce5ddfb72b7ef2e65cbe1a90c6e86
|
|
| MD5 |
f1944866deb9134358a4a1d1d49532da
|
|
| BLAKE2b-256 |
150bcc4aed810da158cbae130dc7ffa2fb374a3c4b927391efd4c1a655e5d899
|