Skip to content

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:

  1. --config <path>
  2. MORAINE_CONFIG
  3. ~/.moraine/config.toml, when it exists
  4. MORAINE_DEFAULT_CONFIG, when it points at an existing file
  5. config/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.rs and config/moraine.toml when 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:

[bm25]
k1 = 1.2
b = 0.75
default_min_score = 0.0
default_min_should_match = 1
max_query_terms = 32

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.