A Rust-native knowledge graph engine with pointer-based RAG (Retrieval-Augmented Generation), hybrid search, and temporal truth — designed for use as a Model Context Protocol (MCP) server in AI-assisted development workflows.
- Pointer-based RAG: Retrieve relevant code/doc nodes without pulling full content; fetch only when needed
- Hybrid search: Full-text search (FTS5), vector/embedding similarity, and literal pattern matching
- Temporal fact store: Record and query time-scoped facts (decisions, constraints, learnings, API contracts)
- Knowledge graph: File and symbol relationships built from workspace crawling and chunking
- MCP server: Exposes tools via the Model Context Protocol for use with AI coding assistants (e.g. GitHub Copilot, Claude, Cursor)
- Token accounting: Tracks token savings from pointer-based retrieval vs. full file reads
- Env-var validation: Scans source files and config files for environment variable definitions and usages; detects typos and dead config via
hermes_validate_env/hermes_check_consistency - Auto-reindex: Background thread periodically re-indexes the workspace (configurable via
HERMES_AUTO_INDEX_INTERVAL_SECS)
src/
├── bin/hermes.rs # MCP server entry point (stdio transport)
├── lib.rs # Public API surface
├── schema.rs # SQLite schema definitions
├── graph.rs # Knowledge graph core
├── graph_builders.rs # Graph construction helpers
├── graph_queries.rs # Graph traversal queries
├── pointer.rs # Pointer node types and resolution
├── accounting.rs # Token savings accounting
├── embedding.rs # (Optional) Gemini embedding client — not used by default
├── temporal.rs # Temporal fact store
├── mcp_server.rs # MCP protocol implementation
├── mcp_tools_validation.rs # hermes_validate_env / hermes_check_consistency tools
├── ingestion/
│ ├── mod.rs # Ingestion orchestration
│ ├── crawler.rs # Workspace file crawler
│ ├── chunker.rs # Code/text chunking
│ ├── hash_tracker.rs # File change detection
│ └── env_scanner.rs # Environment variable discovery (config_registry)
└── search/
├── mod.rs # Unified search interface
├── fts.rs # Full-text search (SQLite FTS5)
├── vector.rs # Vector similarity search
└── literal.rs # Literal/regex pattern search
- Rust 1.75+
- No external services required — vector search works locally out of the box
- (Optional) A Gemini API key if you want to use the higher-quality
EmbeddingGenerator(seesrc/embedding.rs)
cargo build --releaseTo keep the index fresh after branch switches and merges, use repository hooks:
git config core.hooksPath .githooks
chmod +x .githooks/reindex.sh .githooks/post-merge .githooks/post-checkoutOn Windows (PowerShell):
git config core.hooksPath .githookschmod is not required on Windows when using Git for Windows.
What this enables:
post-merge: runshermes indexafter merge/pullpost-checkout: runshermes indexafter branch checkout
You can temporarily disable hook-triggered reindex by setting:
HERMES_SKIP_HOOK_REINDEX=1PowerShell equivalent:
$env:HERMES_SKIP_HOOK_REINDEX = "1"HERMES_PROJECT_ROOT=/path/to/your/project ./target/release/Hermes --stdio| Variable | Default | Description |
|---|---|---|
HERMES_PROJECT_ROOT |
. |
Root directory to index |
HERMES_DB_PATH |
<project_root>/.hermes/hermes.db |
SQLite database path |
GEMINI_API_KEY |
(unset) | (Optional) Google AI API key for EmbeddingGenerator |
GEMINI_EMBEDDING_MODEL |
text-embedding-004 |
(Optional) Gemini embedding model name |
EMBEDDING_RPM |
60 |
(Optional) Embedding API rate limit (requests/min) |
HERMES_AUTO_INDEX_INTERVAL_SECS |
300 |
Background reindex interval in seconds; set to 0 to disable |
| Tool | Description |
|---|---|
hermes_index |
Index/re-index the project files into the knowledge graph |
hermes_search |
Search the knowledge graph; returns pointers (not full content) |
hermes_fetch |
Fetch full content for a specific node by ID |
hermes_fact |
Record a persistent fact (decision, learning, constraint, etc.) |
hermes_facts |
List active facts, optionally filtered by type |
hermes_stats |
Return cumulative token savings statistics |
hermes_validate_env |
Validate an env var name against the config registry; returns Levenshtein-closest suggestions on mismatch |
hermes_check_consistency |
Audit env vars for unknown (used but not defined) or unused (defined but never referenced) entries |
Add to .vscode/mcp.json:
{
"servers": {
"hermes": {
"type": "stdio",
"command": "/path/to/hermes/target/release/Hermes",
"args": ["--stdio"],
"env": {
"HERMES_PROJECT_ROOT": "${workspaceFolder}"
}
}
}
}See LICENSE.