Configuration¶
Moraine reads TOML configuration. The default template is
config/moraine.toml, and runtime installs normally use
~/.moraine/config.toml.
Resolution Order¶
The top-level moraine command resolves config in this order:
--config <path>MORAINE_CONFIG~/.moraine/config.toml, when it existsMORAINE_DEFAULT_CONFIG, when it points at an existing fileconfig/moraine.toml, when running from a source checkout
Service-specific binaries accept the same --config <path> flag and add
service-specific environment variables:
| Service | Environment override |
|---|---|
| MCP | MORAINE_MCP_CONFIG, then MORAINE_CONFIG |
| Monitor | MORAINE_MONITOR_CONFIG, then MORAINE_CONFIG |
| Ingest | MORAINE_INGEST_CONFIG, then MORAINE_CONFIG |
Minimal Example¶
Most users only need to override paths, ports, or watched sources:
[monitor]
host = "127.0.0.1"
port = 8080
[runtime]
root_dir = "~/.moraine"
start_monitor_on_up = true
start_mcp_on_up = false
[[ingest.sources]]
name = "codex"
harness = "codex"
enabled = true
glob = "~/.codex/sessions/**/*.jsonl"
watch_root = "~/.codex/sessions"
ClickHouse¶
[clickhouse] controls database connectivity:
[clickhouse]
url = "http://127.0.0.1:8123"
database = "moraine"
username = "default"
password = ""
timeout_seconds = 30.0
async_insert = true
wait_for_async_insert = true
For a managed local install, leave these values at their defaults. For an
external ClickHouse instance, point url, credentials, and database at that
server.
Ingest Sources¶
Each [[ingest.sources]] entry describes one watched source:
[[ingest.sources]]
name = "claude"
harness = "claude-code"
enabled = true
glob = "~/.claude/projects/**/*.jsonl"
watch_root = "~/.claude/projects"
format = "jsonl"
Supported harness values are codex, claude-code, cursor, kimi-cli,
hermes, and pi-coding-agent. Each value maps to a registered ingest source
adapter; see
Ingest Sources for the adapter contract and
Harness Author Workflow for source
development steps.
glob selects files to ingest. watch_root is the directory Moraine watches
for changes. format controls the file parser:
| Format | Use for |
|---|---|
jsonl |
Append-only newline-delimited trace records. This is the default for most sources. |
session_json |
One JSON file per live session that is rewritten in place. Moraine emits only newly appended synthetic session records. |
When format is omitted, Moraine infers it. Hermes sources with a .json glob
are inferred as session_json; otherwise sources are treated as jsonl.
Source Matrix¶
The default template in config/moraine.toml enables these source families:
| Source | Harness | Default glob | Watch root | Format |
|---|---|---|---|---|
| Codex | codex |
~/.codex/sessions/**/*.jsonl |
~/.codex/sessions |
inferred jsonl |
| Claude Code | claude-code |
~/.claude/projects/**/*.jsonl |
~/.claude/projects |
inferred jsonl |
| Kimi CLI | kimi-cli |
~/.kimi/sessions/**/wire.jsonl |
~/.kimi/sessions |
inferred jsonl |
| Cursor Agent | cursor |
~/.cursor/projects/*/agent-transcripts/**/*.jsonl |
~/.cursor/projects |
inferred jsonl |
| Pi Coding Agent | pi-coding-agent |
~/.pi/agent/sessions/**/*.jsonl |
~/.pi/agent/sessions |
jsonl |
| Hermes live sessions | hermes |
~/.hermes/sessions/session_*.json |
~/.hermes/sessions |
session_json |
| Hermes trajectories | hermes |
user-provided trajectory JSONL | trajectory output directory | jsonl |
Hermes supports both live session JSON and offline trajectory JSONL because the
harness is the same but the file format differs. Use a separate
[[ingest.sources]] entry for each watched directory.
Source Examples¶
Codex:
[[ingest.sources]]
name = "codex"
harness = "codex"
enabled = true
glob = "~/.codex/sessions/**/*.jsonl"
watch_root = "~/.codex/sessions"
Claude Code:
[[ingest.sources]]
name = "claude"
harness = "claude-code"
enabled = true
glob = "~/.claude/projects/**/*.jsonl"
watch_root = "~/.claude/projects"
Kimi CLI:
[[ingest.sources]]
name = "kimi-cli"
harness = "kimi-cli"
enabled = true
glob = "~/.kimi/sessions/**/wire.jsonl"
watch_root = "~/.kimi/sessions"
format = "jsonl"
Cursor Agent JSONL:
[[ingest.sources]]
name = "cursor"
harness = "cursor"
enabled = true
glob = "~/.cursor/projects/*/agent-transcripts/**/*.jsonl"
watch_root = "~/.cursor/projects"
format = "jsonl"
Cursor support watches local Agent JSONL transcripts under
agent-transcripts/. Cursor SQLite workspace history is not ingested by this
source.
Pi Coding Agent:
[[ingest.sources]]
name = "pi"
harness = "pi-coding-agent"
enabled = true
glob = "~/.pi/agent/sessions/**/*.jsonl"
watch_root = "~/.pi/agent/sessions"
format = "jsonl"
Hermes live sessions:
[[ingest.sources]]
name = "hermes"
harness = "hermes"
enabled = true
glob = "~/.hermes/sessions/session_*.json"
watch_root = "~/.hermes/sessions"
format = "session_json"
Hermes trajectories:
[[ingest.sources]]
name = "hermes-trajectories"
harness = "hermes"
enabled = true
glob = "~/trajectories/**/*.jsonl"
watch_root = "~/trajectories"
format = "jsonl"
Adding Harnesses¶
The config crate validates harness names before ingest-core runs, but
moraine-config cannot call the ingest adapter registry without creating a
dependency cycle. Adding a harness therefore requires coordinated updates:
- Add and register the adapter under
crates/moraine-ingest-core/src/sources/. - Add the harness string to
moraine_config::KNOWN_INGEST_HARNESSES. - Update defaults in
crates/moraine-config/src/lib.rsandconfig/moraine.tomlwhen the source should ship enabled by default. - Update this page and the ingest source development docs.
- Run the registry/config sync tests and ingest fixture contract tests.
The [ingest] table controls batching and watcher behavior:
[ingest]
batch_size = 4000
max_batch_bytes = 8388608
flush_interval_seconds = 0.5
state_dir = "~/.moraine/ingestor"
backfill_on_start = true
max_file_workers = 8
max_inflight_batches = 16
MCP¶
[mcp] sets defaults for agent retrieval:
[mcp]
max_results = 25
preview_chars = 320
default_context_before = 3
default_context_after = 3
default_include_tool_events = false
default_exclude_codex_mcp = true
async_log_writes = true
protocol_version = "2024-11-05"
Raise max_results only when clients need larger result windows. Increase
context defaults when retrieval snippets are too narrow.
Search Ranking¶
[bm25] tunes search behavior:
Most installations should keep these defaults.
Runtime Paths¶
[runtime] controls where Moraine keeps state and where it finds service
binaries:
[runtime]
root_dir = "~/.moraine"
logs_dir = "logs"
pids_dir = "run"
service_bin_dir = "~/.local/bin"
managed_clickhouse_dir = "~/.local/lib/moraine/clickhouse/current"
clickhouse_auto_install = true
start_monitor_on_up = true
start_mcp_on_up = false
Relative logs_dir and pids_dir values are resolved under root_dir.
service_bin_dir must contain moraine-ingest, moraine-monitor, and
moraine-mcp, unless MORAINE_SERVICE_BIN_DIR is set or source-tree mode is
enabled.