kogral/docs/user-guide/configuration.md
2026-01-23 16:11:07 +00:00

12 KiB

Configuration Reference

Complete reference for configuring the KOGRAL using Nickel schemas.

Configuration Files

The knowledge base uses Nickel (.ncl) for configuration with type-safe schemas:

.kogral/
└── config.ncl          # Main configuration file

Configuration is exported to JSON and loaded into Rust structs with double validation.

Quick Configuration

Minimal Configuration

# .kogral/config.ncl
{
  graph = {
    name = "My Project",
    version = "1.0.0",
  },
}
{
  graph = {
    name = "My Project",
    version = "1.0.0",
    description = "Project knowledge base",
  },

  storage = {
    primary = 'filesystem,
  },

  embeddings = {
    enabled = true,
    provider = 'fastembed,
  },

  sync = {
    auto_index = true,
  },
}

Production Configuration

{
  graph = {
    name = "Production Project",
    version = "2.1.0",
    description = "Production knowledge base with full features",
  },

  inheritance = {
    base = "/Users/Akasha/Tools/.kogral-shared",
    priority = 100,
  },

  storage = {
    primary = 'filesystem,
    secondary = {
      enabled = true,
      type = 'surrealdb,
      url = "ws://db.example.com:8000",
      namespace = "kogral",
      database = "production",
    },
  },

  embeddings = {
    enabled = true,
    provider = 'openai,
    model = "text-embedding-3-large",
    api_key_env = "OPENAI_API_KEY",
  },

  query = {
    similarity_threshold = 0.6,
    max_results = 20,
    cross_graph = true,
  },

  mcp = {
    server = {
      name = "production-kogral-mcp",
      transport = 'stdio,
    },
    tools = {
      search = true,
      add_note = true,
      export = true,
    },
  },

  sync = {
    auto_index = true,
    watch_paths = ["notes", "decisions", "guidelines", "patterns"],
    debounce_ms = 1000,
  },
}

Configuration Sections

Graph Configuration

Basic graph metadata:

graph = {
  name | String,
  version | String | default = "1.0.0",
  description | String | default = "",
}

Fields:

  • name (required): Graph name identifier
  • version (optional): Semantic version string (default: "1.0.0")
  • description (optional): Human-readable description

Example:

graph = {
  name = "vapora-knowledge",
  version = "1.2.0",
  description = "Vapora project knowledge base",
}

Inheritance Configuration

Inherit guidelines and patterns from shared knowledge bases:

inheritance = {
  base | String | default = "/Users/Akasha/Tools/.kogral-shared",
  guidelines | Array String | default = [],
  priority | Number | default = 100,
}

Fields:

  • base: Path to shared KOGRAL directory
  • guidelines: Additional guideline paths to inherit
  • priority: Override priority (higher wins)

Example:

inheritance = {
  base = "~/Tools/.kogral-shared",
  guidelines = [
    "~/Tools/.claude/guidelines/rust",
    "~/Tools/.claude/guidelines/nushell",
  ],
  priority = 150,  # Project overrides shared
}

Priority Rules:

  • 0-99: Shared guidelines (lowest priority)
  • 100-199: Project guidelines (default)
  • 200+: Critical project overrides

Storage Configuration

Configure storage backends:

storage = {
  primary | [| 'filesystem, 'memory |] | default = 'filesystem,

  secondary | {
    enabled | Bool | default = false,
    type | [| 'surrealdb, 'sqlite |] | default = 'surrealdb,
    url | String | default = "ws://localhost:8000",
    namespace | String | default = "kb",
    database | String | default = "default",
  } | default = {},
}

Fields:

  • primary: Primary storage backend (filesystem or memory)
  • secondary.enabled: Enable secondary backend for sync
  • secondary.type: Secondary backend type
  • secondary.url: Connection URL for SurrealDB
  • secondary.namespace: SurrealDB namespace
  • secondary.database: SurrealDB database name

Examples:

# Filesystem only (default)
storage = {
  primary = 'filesystem,
}

# Filesystem with SurrealDB sync
storage = {
  primary = 'filesystem,
  secondary = {
    enabled = true,
    type = 'surrealdb,
    url = "ws://localhost:8000",
    namespace = "kogral",
    database = "myproject",
  },
}

# In-memory (development/testing)
storage = {
  primary = 'memory,
}

Embeddings Configuration

Configure semantic search and embeddings:

embeddings = {
  enabled | Bool | default = true,
  provider | [| 'openai, 'claude, 'ollama, 'fastembed |] | default = 'fastembed,
  model | String | default = "BAAI/bge-small-en-v1.5",
  dimensions | Number | default = 384,
  api_key_env | String | default = "OPENAI_API_KEY",
}

Fields:

  • enabled: Enable embedding generation
  • provider: Embedding provider
  • model: Model name/identifier
  • dimensions: Embedding vector dimensions
  • api_key_env: Environment variable for API key

Provider-Specific Settings:

OpenAI:

embeddings = {
  enabled = true,
  provider = 'openai,
  model = "text-embedding-3-small",  # or text-embedding-3-large
  dimensions = 1536,
  api_key_env = "OPENAI_API_KEY",
}

Claude (Anthropic):

embeddings = {
  enabled = true,
  provider = 'claude,
  model = "claude-3-embedding",
  api_key_env = "ANTHROPIC_API_KEY",
}

Ollama (local):

embeddings = {
  enabled = true,
  provider = 'ollama,
  model = "nomic-embed-text",
  dimensions = 768,
}

fastembed (local):

embeddings = {
  enabled = true,
  provider = 'fastembed,
  model = "BAAI/bge-small-en-v1.5",  # or BAAI/bge-base-en-v1.5
  dimensions = 384,  # 384 for small, 768 for base
}

Template Configuration

Configure document templates:

templates = {
  templates_dir | String | default = "templates",

  templates | {
    note | String | default = "note.md.tera",
    decision | String | default = "decision.md.tera",
    guideline | String | default = "guideline.md.tera",
    pattern | String | default = "pattern.md.tera",
    journal | String | default = "journal.md.tera",
    execution | String | default = "execution.md.tera",
  } | default = {},

  export | {
    logseq_page | String | default = "export/logseq-page.md.tera",
    logseq_journal | String | default = "export/logseq-journal.md.tera",
    summary | String | default = "export/summary.md.tera",
    json | String | default = "export/graph.json.tera",
  } | default = {},

  custom | { _ | String } | default = {},
}

Fields:

  • templates_dir: Directory containing templates
  • templates.*: Template files for each node type
  • export.*: Export format templates
  • custom: Custom template registry

Example:

templates = {
  templates_dir = "custom-templates",

  templates = {
    note = "my-note-template.md.tera",
    journal = "daily-standup.md.tera",
  },

  custom = {
    "meeting-notes" = "meeting-notes.md.tera",
    "retrospective" = "retro.md.tera",
  },
}

Query Configuration

Configure search and query behavior:

query = {
  similarity_threshold | Number | default = 0.4,
  max_results | Number | default = 10,
  recency_weight | Number | default = 3.0,
  cross_graph | Bool | default = true,
}

Fields:

  • similarity_threshold: Minimum similarity for semantic matches (0-1)
  • max_results: Maximum results to return
  • recency_weight: Weight factor for recent documents
  • cross_graph: Enable cross-graph queries

Example:

query = {
  similarity_threshold = 0.6,  # Higher = more strict
  max_results = 20,
  recency_weight = 5.0,  # Strongly prefer recent
  cross_graph = true,  # Search shared KOGRAL too
}

Similarity Threshold Guide:

  • 0.0-0.3: Very loose (many false positives)
  • 0.4-0.6: Balanced (recommended)
  • 0.7-0.9: Strict (high precision)
  • 0.9-1.0: Exact matches only

MCP Configuration

Configure Model Context Protocol server:

mcp = {
  server | {
    name | String | default = "kogral-mcp",
    version | String | default = "1.0.0",
    transport | [| 'stdio, 'sse |] | default = 'stdio,
  },

  tools | {
    search | Bool | default = true,
    add_note | Bool | default = true,
    add_decision | Bool | default = true,
    link | Bool | default = true,
    get_guidelines | Bool | default = true,
    export | Bool | default = true,
  } | default = {},

  resources | {
    expose_project | Bool | default = true,
    expose_shared | Bool | default = true,
  } | default = {},
}

Fields:

  • server.name: MCP server identifier
  • server.transport: Communication transport
  • tools.*: Enable/disable specific tools
  • resources.*: Expose resources

Example:

mcp = {
  server = {
    name = "myproject-kogral-mcp",
    transport = 'stdio,
  },

  tools = {
    search = true,
    add_note = true,
    add_decision = false,  # Disable if not needed
    link = true,
    get_guidelines = true,
    export = true,
  },

  resources = {
    expose_project = true,
    expose_shared = false,  # Hide shared KOGRAL
  },
}

Sync Configuration

Configure filesystem synchronization:

sync = {
  auto_index | Bool | default = true,
  watch_paths | Array String | default = ["notes", "decisions", "guidelines", "patterns", "journal"],
  debounce_ms | Number | default = 500,
}

Fields:

  • auto_index: Automatically sync filesystem to storage
  • watch_paths: Directories to watch for changes
  • debounce_ms: Debounce delay for file system events

Example:

sync = {
  auto_index = true,
  watch_paths = ["notes", "decisions", "guidelines"],  # Exclude journal
  debounce_ms = 1000,  # 1 second debounce
}

Environment Variables

Some settings support environment variable expansion:

Variable Purpose Example
OPENAI_API_KEY OpenAI API authentication sk-...
ANTHROPIC_API_KEY Anthropic API authentication sk-ant-...
OLLAMA_API_BASE Ollama server URL http://localhost:11434
KOGRAL_SHARED_BASE Shared KOGRAL location ~/Tools/.kogral-shared

Usage in config:

embeddings = {
  api_key_env = "OPENAI_API_KEY",  # References environment variable
}

Configuration Validation

Validate configuration before use:

# Export and validate
nickel export --format json .kogral/config.ncl

# Test configuration
kogral config validate

# Show effective configuration
kogral config show

Configuration Inheritance

Configurations can be composed:

# base.ncl
let BaseConfig = {
  graph = { version = "1.0.0" },
  storage = { primary = 'filesystem },
}

# project-config.ncl
let base = import "base.ncl" in
base & {
  graph = {
    name = "My Project",
  },
  embeddings = {
    enabled = true,
  },
}

Migration Guide

From TOML to Nickel

Old TOML config:

[graph]
name = "my-project"
version = "1.0.0"

[embeddings]
enabled = true
provider = "fastembed"

New Nickel config:

{
  graph = {
    name = "my-project",
    version = "1.0.0",
  },

  embeddings = {
    enabled = true,
    provider = 'fastembed,
  },
}

Advanced Patterns

Conditional Configuration

let is_production = std.string.is_match "prod" (std.env.get "ENV") in
{
  embeddings = {
    provider = if is_production then 'openai else 'fastembed,
  },
}

Configuration per Environment

# config/dev.ncl
{ embeddings = { provider = 'fastembed } }

# config/prod.ncl
{ embeddings = { provider = 'openai } }

# .kogral/config.ncl
let env = std.env.get_or_default "ENV" "dev" in
import ("config/" ++ env ++ ".ncl")

Troubleshooting

Syntax Errors

# Check Nickel syntax
nickel typecheck .kogral/config.ncl

# Pretty-print to find errors
nickel export --format json .kogral/config.ncl | jq

Schema Validation Failed

Ensure all required fields are present:

# This will fail (missing name)
{ graph = { version = "1.0.0" } }

# This works
{ graph = { name = "project", version = "1.0.0" } }

Type Errors

# Wrong: string instead of enum
{ storage = { primary = "filesystem" } }  # Error!

# Correct: enum variant
{ storage = { primary = 'filesystem } }  # Success

See Also