Coraline Documentation

Coraline is a local-first code intelligence engine that builds a semantic graph of your codebase and exposes high-precision tools over CLI and MCP.

This book is published from the repository and combines practical guides with full reference docs.

What You Can Do With Coraline

  • Index and incrementally sync large codebases.
  • Query symbols, call graphs, and impact radius.
  • Build context for AI workflows.
  • Use semantic search with local embeddings.
  • Integrate with MCP clients.

Start with Getting Started, then move to the CLI Reference and MCP Tools.

Getting Started

Install

Install from crates.io:

cargo install coraline

Initialize and Index

coraline init
coraline index

Optional: Semantic Search Model

coraline model download
coraline embed

By default, embedding runs a freshness check and auto-syncs stale indexed state before generating embeddings.

Start MCP Server

coraline serve --mcp

Next Steps

CLI Reference

Coraline CLI Reference

Coraline is invoked as coraline [COMMAND] [OPTIONS] [PATH].

When [PATH] is omitted, the current working directory is used as the project root.


Commands at a Glance

CommandDescription
initInitialize a new project
indexFull reindex of the project
syncIncremental update (git-diff based)
statusShow project status and paths
statsShow index statistics
querySearch symbols by name
contextBuild AI context for a task
callersFind what calls a node
calleesFind what a node calls
impactAnalyze change impact radius
configRead or update configuration
hooksManage git hooks
serveStart the MCP server
updateCheck for available updates on crates.io
embedGenerate vector embeddings for indexed nodes
modelManage the ONNX embedding model

coraline init [PATH]

Initialize Coraline in a project directory. Creates .coraline/ with a SQLite database, default config.toml, and initial memory templates.

When stdin is a TTY, prompts to download the embedding model (~137 MB) after initialization. Decline to skip — all non-embedding tools remain fully functional and you can download later with coraline model download.

If .coraline/ already exists and --index is passed without --force, init skips the overwrite and runs indexing directly on the existing project.

Options:

FlagDescription
-i, --indexRun a full index immediately after initialization
-f, --forceOverwrite an existing .coraline/ directory without prompting
--no-hooksSkip automatic git hook installation

Examples:

coraline init                    # Initialize current directory
coraline init /path/to/my-app   # Initialize a specific path
coraline init -i                 # Initialize, prompt for model, then index
coraline init -i --no-hooks      # Initialize and index, skip git hooks
coraline init --force            # Wipe and reinitialize existing project

On success, creates:

  • .coraline/coraline.db — SQLite knowledge graph
  • .coraline/config.toml — Annotated config template
  • .coraline/memories/ — Initial memory files
  • .coraline/.gitignore — Excludes local data files from git
  • .git/hooks/post-commit — Auto-sync hook (unless --no-hooks)

coraline index [PATH]

Perform a full reindex of the project. Parses all matching source files, extracts symbols and edges, resolves cross-file references, and stores results in the knowledge graph.

Options:

FlagDescription
-f, --forceForce re-parse all files, even unchanged ones
-q, --quietSuppress progress output

Examples:

coraline index                   # Index current directory
coraline index /path/to/project  # Index a specific path
coraline index -f                # Force full re-parse
coraline index -q                # Silent (useful in scripts)

coraline sync [PATH]

Perform an incremental update using git-diff to identify changed files. Faster than a full index for routine updates.

Options:

FlagDescription
-q, --quietSuppress progress output

Examples:

coraline sync                    # Sync current directory
coraline sync -q                 # Silent sync (used by git hook)

coraline status [PATH]

Show the current project status: initialization state, paths to config and database, database size, and git hook status.

Examples:

coraline status

Sample output:

Coraline Status

Project: /home/user/my-app
Config:  /home/user/my-app/.coraline/config.toml
Database: /home/user/my-app/.coraline/coraline.db (1048576 bytes)
Git hooks: installed

coraline stats [PATH]

Show index statistics: file count, node count, edge count, and unresolved reference count.

Options:

FlagDescription
-j, --jsonOutput as JSON

Examples:

coraline stats
coraline stats --json

Sample output:

Coraline Statistics

Files:     128
Nodes:     4201
Edges:     9872
Unresolved refs: 153

coraline query <SEARCH> [PATH]

Search for symbols in the knowledge graph by name. Uses SQLite full-text search (FTS5) for fast, fuzzy matching.

Arguments:

ArgumentDescription
SEARCHSymbol name or search pattern

Options:

FlagDescription
-p, --path PATHProject root path
-l, --limit NMaximum results (default: 10)
-k, --kind KINDFilter by node kind (see below)
-j, --jsonOutput as JSON

Valid KIND values: file, module, class, struct, interface, trait, protocol, function, method, property, field, variable, constant, enum, enum_member, type_alias, namespace, parameter, import, export, route, component

Examples:

coraline query resolve_unresolved
coraline query "index" --kind function --limit 5
coraline query Auth --json

coraline context <TASK> [PATH]

Build structured context for an AI task description. Searches the graph, traverses relationships, and returns relevant code snippets.

Arguments:

ArgumentDescription
TASKNatural language task description

Options:

FlagDescription
-p, --path PATHProject root path
-n, --max-nodes NMax graph nodes (default: 50)
-c, --max-code NMax code blocks (default: 10)
--no-codeOmit source code snippets
-f, --format FMTmarkdown (default) or json

Examples:

coraline context "add authentication middleware"
coraline context "how does indexing work" --format json
coraline context "refactor database layer" --max-nodes 30 --max-code 5

coraline callers <NODE_ID> [PATH]

Find all nodes that call the specified node (incoming calls edges).

Arguments:

ArgumentDescription
NODE_IDNode ID (from query or stats --json output)

Options:

FlagDescription
-p, --path PATHProject root path
-l, --limit NMaximum results (default: 20)
-j, --jsonOutput as JSON

Examples:

coraline callers abc123
coraline callers abc123 --limit 50 --json

coraline callees <NODE_ID> [PATH]

Find all nodes that the specified node calls (outgoing calls edges).

Same flags as callers.


coraline impact <NODE_ID> [PATH]

Analyze the impact radius of a symbol — what would be affected if it changed. Performs a BFS over incoming edges up to --depth hops.

Arguments:

ArgumentDescription
NODE_IDNode ID to analyze

Options:

FlagDescription
-p, --path PATHProject root path
-d, --depth NBFS depth (default: 3)
-j, --jsonOutput as JSON

Examples:

coraline impact abc123
coraline impact abc123 --depth 5 --json

coraline config [PATH]

Read or update the project configuration at .coraline/config.toml.

Options:

FlagDescription
-p, --path PATHProject root path
-j, --jsonPrint config as JSON
-s, --section SECPrint only a section (indexing, context, sync, vectors)
--set KEY=VALUESet a value: section.key=value

Examples:

coraline config                                 # Print full config (TOML)
coraline config --section context               # Print one section
coraline config --json                          # Print as JSON
coraline config --set context.max_nodes=30      # Update a value
coraline config --set indexing.batch_size=50
coraline config --set vectors.enabled=true

coraline hooks <ACTION> [PATH]

Manage the git post-commit hook that runs coraline sync automatically after each commit.

Actions:

ActionDescription
installInstall the hook (backs up existing hook)
removeRemove the hook (restores backup if present)
statusShow whether the hook is installed

Options:

FlagDescription
-p, --path PATHProject root path

Examples:

coraline hooks install
coraline hooks status
coraline hooks remove

coraline serve [PATH]

Start the MCP server. With --mcp, communicates over stdio using the Model Context Protocol.

Options:

FlagDescription
-p, --path PATHProject root path
--mcpStart MCP stdio server (required)

Examples:

coraline serve --mcp
coraline serve --mcp --path /path/to/project

Typically invoked by an MCP client (Claude Desktop, Claude Code, etc.) rather than directly.


coraline update

Check whether a newer version of Coraline is published on crates.io. Compares the running binary version against the latest release and prints upgrade instructions when an update is available.

Options: None.

Examples:

coraline update

Output (when up to date):

✓ coraline is up to date (v0.3.0)

Output (when update available):

Update available: v0.3.0 → v0.4.0
Run `cargo install coraline` to upgrade.

Environment Variables

VariableDescription
CORALINE_LOGLog level filter (default: coraline=info). Examples: debug, coraline=trace, warn

Examples:

CORALINE_LOG=debug coraline index
CORALINE_LOG=coraline=trace coraline serve --mcp

Logs are written to .coraline/logs/coraline.log (daily rotating) and to stderr at the configured level.


coraline embed [PATH]

Generate vector embeddings for all indexed nodes using the local ONNX model. Embeddings enable the coraline_semantic_search MCP tool.

By default, embed performs a lightweight freshness check and runs incremental sync first when indexed state is stale. This keeps embeddings aligned with current source files without requiring a manual coraline sync step.

Options:

FlagDescription
--downloadDownload the model automatically before embedding
--variant FILENAMEONNX variant to download (default: model_int8.onnx)
--skip-syncSkip automatic pre-embed sync check (embeddings may be stale)
--batch-size NNodes per progress batch (default: 50)
-q, --quietSuppress progress output

Examples:

coraline embed                        # Embed using already-downloaded model
coraline embed --skip-sync            # Skip auto-sync and embed current index state
coraline embed --download             # Download model_int8.onnx then embed
coraline embed --download --variant model_fp16.onnx

Run coraline index first. Models are stored in .coraline/models/nomic-embed-text-v1.5/.


coraline model [PATH]

Manage the ONNX embedding model files.

coraline model download

Download model files from HuggingFace (nomic-ai/nomic-embed-text-v1.5).

FlagDescription
--variant FILENAMEONNX variant to download (default: model_int8.onnx)
-f, --forceRe-download even if files already exist
-q, --quietSuppress progress output

Downloads tokenizer.json, tokenizer_config.json, and the chosen ONNX weights into .coraline/models/nomic-embed-text-v1.5/.

Available variants (smallest to largest):

VariantSizeNotes
model_q4f16.onnx~111 MBQ4 + fp16 mixed (smallest)
model_int8.onnx~137 MBint8 quantized (recommended)
model_fp16.onnx~274 MBfp16
model.onnx~547 MBfull f32

coraline model status

Show which model files are present in the model directory.

coraline model status

MCP Tools

Coraline MCP Tools Reference

Coraline exposes 27 MCP tools when running as an MCP server (coraline serve --mcp). All tool names are prefixed with coraline_ to avoid collisions with other MCP servers.

Protocol notes:

  • Negotiates MCP protocol version 2025-11-25 (with compatibility fallback to 2024-11-05)
  • Expects notifications/initialized after initialize before normal requests
  • tools/list supports pagination via cursor and nextCursor

coraline_semantic_search is available by default (the embeddings feature ships enabled) but only registered when an ONNX model is present in .coraline/models/. Run coraline model download then coraline embed to activate it. The remaining 26 tools are typically available; memory-backed tools may be skipped if their initialization fails (e.g. due to filesystem or permission issues).

Background Auto-Sync

When the MCP server starts, it spawns a background thread that periodically checks index freshness and runs incremental sync when files have changed. This keeps the knowledge graph current without manual coraline_sync calls.

  • Default interval: 120 seconds (configurable via sync.auto_sync_interval_secs in config.toml)
  • Disable: Set auto_sync_interval_secs = 0 in [sync]
  • When embeddings are enabled and an ONNX model is present, newly-added nodes are automatically embedded after each background sync
  • The background thread uses SQLite WAL mode for safe concurrent access alongside the main MCP request loop

Quick Reference

CategoryToolDescription
Graphcoraline_searchFind symbols by name or pattern
coraline_callersFind what calls a symbol
coraline_calleesFind what a symbol calls
coraline_impactAnalyze change impact radius
coraline_dependenciesOutgoing dependency graph from a node
coraline_dependentsIncoming dependency graph (what depends on a node)
coraline_pathFind a path between two nodes
coraline_statsDetailed graph statistics by language/kind/edge
coraline_find_symbolFind symbols with rich metadata + optional body
coraline_get_symbols_overviewList all symbols in a file
coraline_find_referencesFind all references to a symbol
coraline_nodeGet full node details and source code
Contextcoraline_contextBuild structured context for an AI task
Filecoraline_read_fileRead file contents
coraline_list_dirList directory contents
coraline_find_fileFind files by glob pattern
coraline_get_file_nodesGet all indexed nodes in a file
coraline_statusShow project index statistics
coraline_syncTrigger incremental index sync
coraline_get_configRead project configuration
coraline_update_configUpdate a config value
coraline_semantic_searchVector similarity search (requires model download — see below)
Memorycoraline_write_memoryWrite or update a project memory
coraline_read_memoryRead a project memory
coraline_list_memoriesList all memories
coraline_delete_memoryDelete a memory
coraline_edit_memoryEdit memory via literal or regex replace

Graph Tools

Search for code symbols by name or pattern across the indexed codebase.

Input:

ParameterTypeRequiredDefaultDescription
querystringSymbol name or FTS pattern
kindstringFilter: function, method, class, struct, interface, trait, module
filestringFilter results to this file path (relative or absolute)
limitnumber10Maximum results

Output:

{
  "results": [
    {
      "node": {
        "id": "abc123",
        "kind": "function",
        "name": "resolve_unresolved",
        "qualified_name": "coraline::resolution::resolve_unresolved",
        "file_path": "/path/to/resolution/mod.rs",
        "start_line": 42,
        "end_line": 95,
        "language": "Rust",
        "signature": "fn resolve_unresolved(conn: &mut Connection, ...)"
      },
      "score": 0.92
    }
  ],
  "count": 1
}

coraline_callers

Find all functions/methods that call a given symbol (incoming calls edges).

Input:

ParameterTypeRequiredDefaultDescription
node_idstringID of the target node
namestringSymbol name (alternative to node_id)
filestringDisambiguate name by file path
limitnumber20Maximum callers to return

Either node_id or name must be provided. When name matches multiple symbols, supply file to disambiguate or the tool returns a listing of candidates.

Output:

{
  "callers": [
    {
      "id": "def456",
      "kind": "function",
      "name": "index_all",
      "qualified_name": "coraline::extraction::index_all",
      "file_path": "/path/to/extraction.rs",
      "start_line": 120,
      "line": 158
    }
  ],
  "count": 1
}

coraline_callees

Find all functions/methods that a given symbol calls (outgoing calls edges).

Input:

ParameterTypeRequiredDefaultDescription
node_idstringID of the source node
namestringSymbol name (alternative to node_id)
filestringDisambiguate name by file path
limitnumber20Maximum callees to return

Either node_id or name must be provided.

Output: Same shape as coraline_callers but field is callees.

Precision Notes:

  • Call-edge resolution prefers extractor-provided candidate IDs (better locality signal) to avoid false-positive cross-project links in mixed active/legacy workspaces.
  • When a call target is ambiguous and no scoped match exists, it is left unresolved (empty) rather than linked to a low-confidence global match.
  • Results are ordered deterministically by (line, column, target) to ensure consistency across repeated queries.

coraline_impact

Analyze the impact radius of changing a symbol — finds everything that directly or transitively depends on it, via BFS over incoming calls and references edges.

Input:

ParameterTypeRequiredDefaultDescription
node_idstringID of the node to analyze
namestringSymbol name (alternative to node_id)
filestringDisambiguate name by file path
max_depthnumber2BFS traversal depth
max_nodesnumber50Cap on returned nodes

Either node_id or name must be provided.

Output:

{
  "nodes": [ ... ],
  "edges": [ ... ],
  "stats": {
    "node_count": 12,
    "edge_count": 15,
    "file_count": 4,
    "max_depth": 2
  }
}

coraline_dependencies

Get the outgoing dependency graph from a node — what does this symbol import, call, or reference, recursively up to a configurable depth?

Input:

ParameterTypeRequiredDefaultDescription
node_idstringID of the source node
namestringSymbol name (alternative to node_id)
filestringDisambiguate name by file path
max_depthnumber2BFS traversal depth
max_nodesnumber50Cap on returned nodes
edge_kindsstring[]allEdge kinds to follow (e.g. ["calls", "imports"])

Either node_id or name must be provided.

Output:

{
  "root_id": "abc123",
  "nodes": [ ... ],
  "edges": [ ... ],
  "stats": { "node_count": 8, "edge_count": 10, "file_count": 3, "max_depth": 2 }
}

coraline_dependents

Get the incoming dependency graph — what symbols depend on (call, import, or reference) this node, recursively?

Input: Same as coraline_dependencies (supports node_id or name + file).

Output: Same shape as coraline_dependencies but traversal follows edges in reverse.


coraline_path

Find a path between two nodes in the graph, using BFS over all edge kinds.

Input:

ParameterTypeRequiredDescription
from_idstringStarting node ID
from_namestringStarting node name (alternative to from_id)
from_filestringDisambiguate from_name by file path
to_idstringTarget node ID
to_namestringTarget node name (alternative to to_id)
to_filestringDisambiguate to_name by file path

For each endpoint, either the _id or _name parameter must be provided.

Output:

{
  "from_id": "abc123",
  "to_id": "def456",
  "path_found": true,
  "path": ["abc123", "mid789", "def456"],
  "length": 3
}

Returns { "path_found": false } if no path exists.


coraline_stats

Return detailed graph statistics: total counts, per-language file breakdown, node kind breakdown, and edge kind breakdown.

Input: None.

Output:

{
  "totals": {
    "nodes": 1842,
    "edges": 4201,
    "files": 47,
    "unresolved_references": 123,
    "vectors": 0
  },
  "files_by_language": { "rust": 28, "typescript": 14, "toml": 5 },
  "nodes_by_kind":     { "function": 412, "method": 287, "import": 201, "struct": 88 },
  "edges_by_kind":     { "contains": 1842, "calls": 987, "imports": 201, "exports": 178 }
}

coraline_find_symbol

Find symbols by name pattern with richer metadata than coraline_search, including optional source code body. Good for Foo/__init__-style path patterns.

Input:

ParameterTypeRequiredDefaultDescription
name_patternstringSymbol name or substring
kindstringSame kind filter as coraline_search
filestringFilter results to this file path
include_bodybooleanfalseAttach source code body
limitnumber10Maximum results

Output: { "symbols": [...], "count": N } — each symbol includes docstring, is_exported, is_async, is_static, score, and optionally body.


coraline_get_symbols_overview

Get an overview of all symbols in a file, grouped by kind and ordered by line number.

Input:

ParameterTypeRequiredDescription
file_pathstringPath to file (relative to project root or absolute)

Output:

{
  "file_path": "src/lib.rs",
  "symbol_count": 14,
  "by_kind": {
    "function": [ ... ],
    "struct": [ ... ]
  },
  "symbols": [ ... ]
}

coraline_find_references

Find all nodes that reference (call, import, extend, implement, etc.) a given symbol.

Input:

ParameterTypeRequiredDefaultDescription
node_idstringID of the target node
namestringSymbol name (alternative to node_id)
filestringDisambiguate name by file path
edge_kindstringallFilter: calls, imports, extends, implements, references
limitnumber50Maximum references

Either node_id or name must be provided.

Output: { "node_id": "...", "references": [...], "count": N } — each reference includes its edge_kind and the line number of the edge.


coraline_node

Get complete details for a specific node by ID, including its source code body read from disk.

Input:

ParameterTypeRequiredDefaultDescription
node_idstringThe node ID
namestringSymbol name (alternative to node_id)
filestringDisambiguate name by file path
include_edgesbooleanfalseAlso return incoming/outgoing edge counts

Either node_id or name must be provided.

Output: Full node record including body (source lines), visibility, decorators, type_parameters, is_async, is_static, is_abstract, and optionally incoming_edge_count / outgoing_edge_count.


Context Tool

coraline_context

Build structured context for an AI task description. Searches the graph, traverses relationships, and returns relevant code snippets in Markdown or JSON format.

Input:

ParameterTypeRequiredDefaultDescription
taskstringNatural language task description
max_nodesnumber20Max graph nodes to include
max_code_blocksnumber5Max code block attachments
max_code_block_sizenumber1500Max chars per code block
include_codebooleantrueAttach source code snippets
traversal_depthnumber1Graph traversal depth
formatstring"markdown""markdown" or "json"

Output: A Markdown or JSON document containing relevant symbols and code, ready to paste as context for an LLM.


File Tools

coraline_read_file

Read the contents of a file within the project.

Input:

ParameterTypeRequiredDefaultDescription
pathstringFile path (relative to project root or absolute)
start_linenumber1First line to read (1-indexed, inclusive)
limitnumber200Maximum number of lines to return

coraline_list_dir

List the contents of a directory within the project.

Input:

ParameterTypeRequiredDefaultDescription
pathstring.Directory path (relative to project root or absolute). Defaults to project root.

coraline_get_file_nodes

Get all indexed symbols (nodes) for a specific file.

Input:

ParameterTypeRequiredDescription
file_pathstringFile path (relative or absolute)

Output: { "file_path": "...", "nodes": [...], "count": N }


coraline_find_file

Find files by name or glob pattern. Recursively walks the project tree, skipping .git, node_modules, target, and .coraline directories.

Input:

ParameterTypeRequiredDefaultDescription
patternstringFile name, substring, or glob pattern (*.rs, test_*, [Cc]argo.toml)
limitnumber20Maximum results

Output:

{
  "pattern": "*.rs",
  "files": ["src/lib.rs", "src/db.rs", "src/graph.rs"],
  "count": 3
}

coraline_status

Show project statistics: total files, nodes, edges, and unresolved reference counts.

Input: None.

Output:

{
  "files": 128,
  "nodes": 4201,
  "edges": 9872,
  "unresolved": 153,
  "db_size_bytes": 2097152
}

coraline_get_config

Read the current project configuration from .coraline/config.toml.

Input: None.

Output: Full CoralineConfig as JSON with all four sections (indexing, context, sync, vectors).


coraline_update_config

Update a single configuration value using dot-notation path.

Input:

ParameterTypeRequiredDescription
keystringDot-notation path, e.g. context.max_nodes
valueanyNew value (type must match the field)

coraline_sync

Trigger an incremental sync of the index. Detects files added, modified, or removed since the last index run and updates only what changed. Run after editing source files to keep the graph current.

Input: None.

Output:

{
  "files_checked": 42,
  "files_added": 1,
  "files_modified": 3,
  "files_removed": 0,
  "nodes_updated": 47,
  "duration_ms": 380
}

Search indexed nodes using natural-language vector similarity. Included in the default build; only registered as an MCP tool once an ONNX model is present in .coraline/models/. To activate:

coraline model download   # download nomic-embed-text-v1.5 (~137 MB)
coraline embed            # generate embeddings for all indexed nodes

When this tool is used, Coraline periodically performs a throttled freshness check. If indexed state is stale it runs incremental sync automatically, then refreshes stale/missing embeddings before search.

Input:

ParameterTypeRequiredDefaultDescription
querystringNatural-language description of what you're looking for
limitnumber10Max results
min_similaritynumber0.3Minimum cosine similarity threshold (0–1)

Output:

{
  "query": "how is sync staleness detected",
  "freshness": {
    "checked": true,
    "stale_files_added": 0,
    "stale_files_modified": 2,
    "stale_files_removed": 0,
    "synced": true,
    "files_added": 0,
    "files_modified": 2,
    "files_removed": 0,
    "embeddings_refreshed": true,
    "embeddings_refreshed_count": 18,
    "check_interval_seconds": 30
  },
  "results": [
    {
      "id": "abc123",
      "name": "resolve_unresolved",
      "qualified_name": "coraline::resolution::ReferenceResolver::resolve_unresolved",
      "kind": "function",
      "file_path": "src/resolution/mod.rs",
      "start_line": 42,
      "docstring": null,
      "signature": "fn resolve_unresolved(...)",
      "score": 0.87
    }
  ]
}

Memory Tools

Project memories are Markdown files stored in .coraline/memories/. They persist across sessions and help AI assistants maintain project context.

coraline_write_memory

Write or update a project memory.

Input:

ParameterTypeRequiredDescription
namestringMemory name (without .md). E.g. project_overview
contentstringMemory content in Markdown format

coraline_read_memory

Read a project memory by name.

Input:

ParameterTypeRequiredDescription
namestringMemory name (without .md)

Output: { "name": "...", "content": "..." }


coraline_list_memories

List all available memories for the project.

Input: None.

Output: { "memories": ["project_overview", "architecture_notes", ...], "count": N }


coraline_delete_memory

Delete a project memory.

Input:

ParameterTypeRequiredDescription
namestringMemory name to delete

coraline_edit_memory

Edit a memory file by replacing text — either as a literal string match or a regex pattern.

Input:

ParameterTypeRequiredDefaultDescription
namestringMemory name (without .md)
patternstringText to find
replacementstringReplacement text
modestring"literal""literal" or "regex"

MCP Client Configuration

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "coraline": {
      "command": "/path/to/coraline",
      "args": ["serve", "--mcp", "--path", "/path/to/your/project"]
    }
  }
}

Claude Code

Add to .claude/mcp.json in your project workspace:

{
  "mcpServers": {
    "coraline": {
      "command": "coraline",
      "args": ["serve", "--mcp"]
    }
  }
}

When --path is omitted, the working directory is used as the project root.

Configuration

Coraline Configuration Reference

Coraline stores its configuration in .coraline/config.toml within each project. All settings are optional — a missing or empty file uses sensible defaults.


File Locations

FilePurpose
.coraline/config.tomlMain user-editable configuration
.coraline/config.jsonInternal runtime config (auto-generated, do not edit)
.coraline/coraline.dbSQLite knowledge graph (do not edit)
.coraline/memories/Project memory files (Markdown)
.coraline/logs/Daily-rotating log files

Full Default Configuration

# Coraline project configuration
# All settings are optional — defaults are shown below.

[indexing]
max_file_size = 1048576   # 1 MB — skip files larger than this
batch_size    = 100       # Files processed per batch
include_patterns = [
  "**/*.rs", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx",
  "**/*.py", "**/*.go", "**/*.java", "**/*.cs", "**/*.cpp",
  "**/*.c", "**/*.h", "**/*.rb", "**/*.php", "**/*.swift",
  "**/*.kt", "**/*.razor",
]
exclude_patterns = [
  "**/.git/**", "**/target/**", "**/node_modules/**",
  "**/dist/**", "**/build/**", "**/.coraline/**",
]

[context]
max_nodes          = 20    # Max graph nodes in context output
max_code_blocks    = 5     # Max code snippets to attach
max_code_block_size = 1500 # Max chars per code block
traversal_depth    = 1     # Graph hops from entry nodes

[sync]
git_hooks_enabled        = true   # Auto-sync on git commit
watch_mode               = false  # Watch for file changes (not yet implemented)
debounce_ms              = 500    # Watch mode debounce delay
auto_sync_interval_secs  = 120    # MCP background sync interval (0 = disabled)

[vectors]
enabled    = false                  # Requires ONNX model (see below)
model      = "nomic-embed-text-v1.5"
dimension  = 384
batch_size = 32

[indexing] Section

Controls which files are indexed and how.

max_file_size

Files larger than this are skipped during indexing.

  • Type: integer (bytes)
  • Default: 1048576 (1 MB)
[indexing]
max_file_size = 524288   # 512 KB

batch_size

Number of files processed per indexing batch.

  • Type: integer
  • Default: 100

include_patterns

Glob patterns for files to include. Uses ** for recursive matching.

  • Type: array of strings
  • Default: Common source file extensions for 18+ languages
[indexing]
include_patterns = [
  "**/*.rs",
  "**/*.ts",
  "**/*.tsx",
  "src/**/*.js",
]

exclude_patterns

Glob patterns for paths to exclude. Matched against the full relative file path.

  • Type: array of strings
  • Default: Build artifacts, package caches, generated files, IDE directories
[indexing]
exclude_patterns = [
  "**/.git/**",
  "**/node_modules/**",
  "**/target/**",
  "**/dist/**",
  "tests/fixtures/**",  # custom exclusion
]

Tip: The default exclusion list is extensive. You typically only need to add project-specific paths.

Python virtualenvs: The defaults cover .venv/, venv/, env/, and named venvs matching *_venv/ or *-venv/ (e.g. cluster_venv/, memory_venv/). If you use a different naming convention, add it explicitly:

exclude_patterns = ["**/my_custom_env/**"]

[context] Section

Controls the output of coraline context (CLI) and coraline_context (MCP).

max_nodes

Maximum number of graph nodes to include in a context response.

  • Type: integer
  • Default: 20

max_code_blocks

Maximum number of source code snippets to attach.

  • Type: integer
  • Default: 5

max_code_block_size

Maximum characters per code block. Larger bodies are truncated.

  • Type: integer
  • Default: 1500

traversal_depth

How many graph hops to follow from the initial matching nodes.

  • Type: integer
  • Default: 1
[context]
max_nodes          = 40
max_code_blocks    = 10
max_code_block_size = 2000
traversal_depth    = 2

[sync] Section

Controls incremental sync behavior and git hook integration.

git_hooks_enabled

Whether coraline init installs a post-commit hook that automatically runs coraline sync after each commit.

  • Type: boolean
  • Default: true

Note: This only determines whether coraline init auto-installs the hook. To manage the hook manually, use coraline hooks install|remove|status.

watch_mode

Enable file-system watch mode (re-index on changes). Not yet implemented.

  • Type: boolean
  • Default: false

debounce_ms

Debounce delay for watch mode in milliseconds.

  • Type: integer
  • Default: 500

auto_sync_interval_secs

Interval in seconds for the MCP server's background auto-sync thread. The thread periodically checks whether the index is stale and performs an incremental sync when files have changed. When embeddings are enabled and an ONNX model is present, newly-added nodes are automatically embedded after each sync.

  • Type: integer (seconds)
  • Default: 120 (2 minutes)
  • Set to 0 to disable background auto-sync entirely.
[sync]
auto_sync_interval_secs = 60   # check every minute

Note: The first check is delayed by the configured interval to avoid racing with any initial indexing that may still be in progress when the MCP server starts.


[vectors] Section

Controls vector embedding generation for semantic search.

Status: Infrastructure is in place. Full semantic search with ONNX model embeddings is pending availability of a stable ort 2.0 API. Setting enabled = true currently has no effect.

enabled

Enable vector embedding generation.

  • Type: boolean
  • Default: false

model

Embedding model identifier.

  • Type: string
  • Default: "nomic-embed-text-v1.5"

dimension

Embedding vector dimension. Must match the selected model.

  • Type: integer
  • Default: 384

batch_size

Number of symbols embedded per batch.

  • Type: integer
  • Default: 32

CLI Configuration Commands

Read the full config:

coraline config

Read a specific section:

coraline config --section context
coraline config --section indexing

Output as JSON:

coraline config --json

Update a value:

coraline config --set context.max_nodes=30
coraline config --set indexing.batch_size=50
coraline config --set indexing.max_file_size=524288
coraline config --set vectors.enabled=true

The --set flag accepts section.key=value syntax. Values are parsed as JSON when possible (for booleans, numbers, and arrays), otherwise treated as strings.


MCP Configuration Tools

The same operations are available via MCP:

coraline_get_config          → returns full config as JSON
coraline_update_config       → updates a single key
  key: "context.max_nodes"
  value: 30

Example: Focused TypeScript Project

[indexing]
include_patterns = [
  "src/**/*.ts",
  "src/**/*.tsx",
  "tests/**/*.ts",
]
exclude_patterns = [
  "**/node_modules/**",
  "**/dist/**",
  "**/.next/**",
  "src/**/*.d.ts",
]

[context]
max_nodes = 30
max_code_blocks = 8
traversal_depth = 2

Example: Large Rust Workspace

[indexing]
max_file_size = 2097152   # 2 MB for generated code
batch_size = 200
include_patterns = [
  "crates/**/*.rs",
]
exclude_patterns = [
  "**/target/**",
  "**/.git/**",
]

[context]
max_nodes = 50
traversal_depth = 3

Architecture

Coraline Architecture

Coraline is a local-first code intelligence system that builds a semantic knowledge graph from any codebase. It uses tree-sitter for deterministic AST-based parsing, SQLite for storage and full-text search, and exposes its capabilities via both a CLI and an MCP server.


High-Level Overview

Coraline high-level architecture

Diagram source: docs/diagrams/high-level-overview.mmd


Source Layout

crates/coraline/src/
├── bin/coraline.rs     # CLI entry point (clap)
├── lib.rs              # Public API surface
├── types.rs            # NodeKind, EdgeKind, all shared types
├── db.rs               # SQLite layer + schema + FTS
├── extraction.rs       # Tree-sitter parsing + indexing pipeline
├── graph.rs            # Graph traversal and subgraph queries
├── resolution/         # Cross-file reference resolution
│   ├── mod.rs          # Core resolver + framework fallback
│   └── frameworks/     # Language/framework-specific resolvers
│       ├── mod.rs      # FrameworkResolver trait + registry
│       ├── rust.rs     # crate::, super::, self:: resolution
│       ├── react.rs    # ./Foo imports, @/ aliases, components
│       ├── blazor.rs   # .razor file discovery, .NET types
│       └── laravel.rs  # PSR-4, blade views, facades
├── context.rs          # Context builder (Markdown/JSON output)
├── vectors.rs          # Vector storage + cosine similarity
├── memory.rs           # Project memory CRUD
├── config.rs           # TOML + JSON configuration loading
├── sync.rs             # Incremental sync + git hook management
├── logging.rs          # Structured logging (tracing)
├── mcp.rs              # MCP server (JSON-RPC over stdio)
├── utils.rs            # Shared utilities
└── tools/
    ├── mod.rs          # Tool trait + ToolRegistry
    ├── graph_tools.rs  # search, callers, callees, impact, find_symbol, ...
    ├── context_tools.rs# coraline_context
    ├── file_tools.rs   # read_file, list_dir, status, config
    └── memory_tools.rs # write/read/list/delete/edit memory

Data Model

Nodes

Every extracted symbol is a Node:

#![allow(unused)]
fn main() {
pub struct Node {
    pub id: String,              // SHA-based deterministic ID
    pub kind: NodeKind,          // function, class, method, struct, ...
    pub name: String,            // unqualified symbol name
    pub qualified_name: Option<String>,
    pub file_path: String,       // absolute path
    pub language: String,
    pub start_line: i64,
    pub end_line: i64,
    pub start_column: i64,
    pub end_column: i64,
    pub signature: Option<String>,
    pub docstring: Option<String>,
    pub visibility: Option<String>,
    pub is_exported: bool,
    pub is_async: bool,
    pub is_static: bool,
    pub is_abstract: bool,
    pub decorators: Vec<String>,
    pub type_parameters: Vec<String>,
}
}

NodeKind values: file, module, class, struct, interface, trait, protocol, function, method, property, field, variable, constant, enum, enum_member, type_alias, namespace, parameter, import, export, route, component

Edges

Relationships between nodes are Edge records:

#![allow(unused)]
fn main() {
pub struct Edge {
    pub id: String,
    pub source: String,          // source node ID
    pub target: String,          // target node ID
    pub kind: EdgeKind,
    pub line: Option<i64>,       // line where the relationship occurs
    pub metadata: Option<String>,
}
}

EdgeKind values: contains, calls, imports, exports, extends, implements, references, type_of, returns, instantiates


Indexing Pipeline

  1. Scan — Glob the project tree using include_patterns/exclude_patterns.
  2. Parse — For each file, spawn the appropriate tree-sitter grammar and walk the AST.
  3. Extract — Emit Node and Edge records from the AST visitor.
  4. Store — Upsert nodes and edges into SQLite. A file content hash prevents re-parsing unchanged files.
  5. Resolve — Walk unresolved reference edges, attempt name-based resolution in the DB; fall back to framework-specific resolvers for zero-candidate references.

Incremental Sync

coraline sync (and the git post-commit hook) uses git diff --name-only HEAD~1 to find changed files, then re-parses only those files. Deleted files have their nodes pruned from the graph.


Reference Resolution

Resolution happens in two passes:

  1. Name-based: The resolution::resolve_unresolved function looks up reference names in the DB using ranked candidate scoring (file proximity, name similarity, kind match).

  2. Framework fallback: When no candidates score above threshold, framework_fallback is called. The registered FrameworkResolver implementations detect the active framework (by checking for Cargo.toml, package.json, artisan, .csproj, etc.) and return candidate file paths. Nodes from those files are then loaded and filtered by the referenced symbol name.

Current framework resolvers:

  • RustResolvercrate::, super::, self:: qualified paths → .rs file mapping
  • ReactResolver./Foo relative imports, @/ path aliases, PascalCase component search
  • BlazorResolver — PascalCase component → .razor file, dot-qualified .NET types
  • LaravelResolver — PSR-4 FQN → PHP file, dot-notation views → blade templates

Tool Architecture

All MCP tools implement the Tool trait:

#![allow(unused)]
fn main() {
pub trait Tool: Send + Sync {
    fn name(&self) -> &'static str;
    fn description(&self) -> &'static str;
    fn input_schema(&self) -> Value;
    fn execute(&self, params: Value) -> ToolResult;
}
}

Tools are registered in a ToolRegistry, which:

  • Dispatches tools/call MCP requests by name
  • Automatically generates tools/list responses from registered metadata
  • Can be used outside MCP (CLI, library API, tests)

Database Schema

The SQLite database (.coraline/coraline.db) has three main tables:

TablePurpose
nodesAll indexed symbols with full metadata
edgesDirected relationships between nodes
nodes_ftsFTS5 virtual table for fast name search

A files table tracks content hashes for incremental sync. An unresolved_refs table holds references that couldn't be resolved during extraction, to be retried on full resolution passes.


MCP Protocol

The MCP server (coraline serve --mcp) communicates over stdin/stdout using JSON-RPC 2.0, conforming to the Model Context Protocol specification.

Supported MCP methods:

  • initialize / notifications/initialized
  • tools/list — returns tool descriptors with cursor pagination (cursor / nextCursor)
  • tools/call — dispatches to ToolRegistry
  • ping

The server is single-threaded and synchronous; each request is fully processed before the next is read.


Logging

Structured logs use the tracing crate:

  • Console: stderr at the level set by CORALINE_LOG (default: info)
  • File: .coraline/logs/coraline.log with daily rotation (kept 7 days)
CORALINE_LOG=debug coraline index      # verbose
CORALINE_LOG=warn coraline serve --mcp # quiet

Development

Coraline Development Guide

This document covers building, testing, and contributing to Coraline.


Prerequisites

ToolVersionNotes
Rust≥ 1.85MSRV — install via rustup
GitanyRequired for sync and hooks
SQLitebundledIncluded via rusqlite — no separate install needed

Getting Started

git clone https://github.com/greysquirr3l/coraline.git
cd coraline

# Build (debug)
cargo build --all-features

# Build and install to ~/.cargo/bin
cargo install --path crates/coraline --force

# Verify
coraline --version

Common Commands

# Development build
cargo build --all-features

# Release build
cargo build --release --all-features

# Run all tests
cargo test --all-features

# Run tests with output
cargo test --all-features -- --nocapture

# Run a specific test by name
cargo test resolve_unresolved

# Run a specific integration test file
cargo test --test extraction_test

# Lint (project default clippy baseline)
cargo lint

# Format
cargo fmt

# Check formatting without modifying
cargo fmt -- --check

Project Structure

coraline/
├── Cargo.toml                     # Workspace manifest
├── deny.toml                      # cargo-deny license/audit policy
├── crates/
│   ├── coraline/                  # Main crate
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── bin/coraline.rs    # CLI binary
│   │       └── ...                # Library modules
│   └── tree-sitter-blazor/        # Custom Blazor grammar
├── docs/                          # Documentation
├── reference_projects/            # Reference implementations (not built)
└── .github/workflows/             # CI/CD pipelines

Tests

Test Overview

LocationCountType
src/tools/mod.rs3Unit: ToolRegistry
src/tools/memory_tools.rs5Unit: MCP memory tools
src/memory.rs11Unit: memory CRUD
src/vectors.rs5Unit: cosine similarity
tests/extraction_test.rs4 (1 ignored)Integration: AST parsing
tests/graph_test.rs4Integration: graph traversal
tests/context_test.rs5Integration: context building

Current status: 37/37 passing, 1 ignored (test_cross_file_references — import edge extraction not yet implemented).

Running Tests

# All tests
cargo test --all-features 2>&1 | grep "test result"

# Single integration file
cargo test --test graph_test

# Single unit test
cargo test memory::tests::test_write_read

# With output (for debugging)
cargo test test_name -- --nocapture

Test Fixtures

Integration tests use fixtures in crates/coraline/tests/fixtures/:

FixturePurpose
simple-project/Basic TypeScript + Rust extraction
blazor-app/Blazor/Razor component parsing
mixed-language/Multi-language extraction

Fixtures are small, self-contained codebases checked into the repo.


Adding a New Tree-Sitter Language

  1. Add the tree-sitter crate to crates/coraline/Cargo.toml.
  2. Add the language variant to Language enum in types.rs.
  3. Add the file extension mapping in extraction.rs (language_from_path).
  4. Add an extraction branch in extraction.rs (extract_nodes_from_ast).
  5. Add to the is_language_supported list in config.rs.
  6. Add at least one fixture file and a test case in tests/extraction_test.rs.

Adding a New MCP Tool

  1. Implement the Tool trait in the appropriate src/tools/*.rs file:

    #![allow(unused)]
    fn main() {
    pub struct MyTool { project_root: PathBuf }
    impl Tool for MyTool {
        fn name(&self) -> &'static str { "coraline_my_tool" }
        fn description(&self) -> &'static str { "..." }
        fn input_schema(&self) -> Value { json!({ ... }) }
        fn execute(&self, params: Value) -> ToolResult { ... }
    }
    }
  2. Register in src/tools/mod.rs inside create_default_registry(...):

    #![allow(unused)]
    fn main() {
    registry.register(Box::new(MyTool::new(project_root.to_path_buf())));
    }
  3. Add unit tests in the same file or src/tools/mod.rs.

  4. Document in docs/MCP_TOOLS.md.


Adding a Framework Resolver

  1. Create src/resolution/frameworks/my_lang.rs implementing FrameworkResolver:

    #![allow(unused)]
    fn main() {
    pub struct MyLangResolver;
    impl FrameworkResolver for MyLangResolver {
        fn name(&self) -> &'static str { "my_lang" }
        fn detect(&self, project_root: &Path) -> bool { ... }
        fn resolve_to_paths(&self, ctx: &ResolveContext<'_>) -> Vec<PathBuf> { ... }
    }
    }
  2. Add to default_resolvers() in src/resolution/frameworks/mod.rs.

  3. Add pub mod my_lang; in src/resolution/frameworks/mod.rs.


CI/CD

GitHub Actions workflows run on every push and pull request:

WorkflowTriggersWhat it does
ci.ymlpush, PRbuild, test, clippy, fmt, docs; multi-platform (Linux/macOS/Windows); MSRV check
release.ymlv* tagsCross-platform binary builds + GitHub release
security.ymldaily + dep changescargo-audit (vulnerabilities) + cargo-deny (licenses)
codeql.ymlweeklyCodeQL analysis

Creating a Release

# Bump version in crates/coraline/Cargo.toml and crates/tree-sitter-blazor/Cargo.toml
# Update CHANGELOG.md

git add -A
git commit -m "chore: release v0.2.0"
git tag v0.2.0
git push origin main --tags

The release.yml workflow builds binaries for Linux x86_64, macOS x86_64/ARM64, and Windows x86_64, then creates a GitHub release with the CHANGELOG content attached.


Code Style

  • #![forbid(unsafe_code)] on all modules — no unsafe code
  • cargo lint must pass before committing
  • cargo fmt for formatting (rustfmt defaults)
  • Keep functions focused; prefer extracting helpers over long function bodies
  • Prefer let Some(x) = opt else { return ...; } over .unwrap() or ? in non-Result contexts
  • Use tracing::{debug, info, warn, error} for log output — no bare println! in library code

See .coraline/memories/style_conventions.md in your project for project-specific conventions.


Useful Dev Workflows

Dogfood Coraline on itself

cd /path/to/coraline
coraline init -i   # index itself
coraline query "resolve_unresolved"
coraline context "how does reference resolution work"

Test MCP roundtrip manually

printf '%s\n%s\n%s\n' \
   '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"0.0.1"}}}' \
   '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
   '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
   | coraline serve --mcp

Check all tests pass after a change

cargo lint && cargo test --all-features 2>&1 | grep "test result"

Changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

0.8.6 - 2026-04-22

Fixed

  • Callees/callers query accuracy: coraline_callees and coraline_callers MCP tools now validate call edges against import/crate boundaries before returning results, eliminating false-positive cross-crate links from name collisions (e.g., heartbeat() in raccoon-agent falsely calling post() in raccoon-frontend). Validation checks: same-file, same-directory, or explicit import statements; queries fetch 2x limit to maintain result count after filtering.
  • CLI callees/callers filtering: coraline callees and coraline callers CLI commands now apply the same boundary validation and show "No callees/callers found" when all edges are filtered out.

Added

  • is_valid_call_edge() database function — validates whether a call edge respects module/crate boundaries before inclusion in query results.

0.8.5 - 2026-04-21

Dependencies

  • Bump indicatif 0.17 → 0.18
  • Bump tree-sitter-scala 0.25.0 → 0.26.0

CI

  • Bump actions/upload-artifact 7.0.0 → 7.0.1
  • Bump github/codeql-action 4.35.1 → 4.35.2
  • Bump actions/deploy-pages 4.0.5 → 5.0.0
  • Bump dependabot/fetch-metadata 2.3.0 → 3.1.0

[0.8.4] - 2026-04-20

Fixed

  • Call graph precision: coraline_callees no longer returns false-positive cross-project edges when multiple paths have the same symbol name. Resolver now prefers extractor-provided candidate IDs (better locality signal) and avoids low-confidence global-name fallback for call edges.
  • Graph queries (coraline_callees, coraline_callers) now return deterministic, stable result sets via explicit ORDER BY (line, col, target/source) in edge retrieval, improving user trust in output consistency across repeated queries.
  • Windows test portability: graph precision acceptance tests now normalize path separators in assertions, preventing src\\api.rs vs src/api.rs mismatches on windows-latest.

Added

  • Graph precision acceptance tests for call-edge disambiguation in mixed active/legacy workspaces, stale-file deletion edge hygiene, and fallback prevention scenarios.

CI

  • Replaced hardcoded Rust toolchain commit hashes with @stable tag to fix transient CI failures and ensure stable Rust channel alignment with MSRV policy.

0.8.3 - 2026-04-17

Changed

  • coraline index, coraline sync, and coraline embed now use a Braille spinner with the current phase/file instead of a progress bar, reducing terminal jitter during indexing and embedding
  • coraline embed now displays an explicit model-loading status indicator while ONNX Runtime and tokenizer initialization are in progress

Fixed

  • Fixed storing-phase progress accounting in index_all where mixed totals (parsed.len() vs files.len()) caused visible progress jumps
  • coraline embed now handles ONNX Runtime initialization panics gracefully and returns actionable loader error guidance instead of a panic backtrace

CI

  • Release workflow now supports auto-tag-triggered releases via workflow_run and shared tag/SHA resolution, avoiding the GITHUB_TOKEN tag-push trigger gap

0.8.2 - 2026-04-16

Changed

  • coraline index, coraline sync, and coraline embed now display an indicatif progress bar ({spinner} {phase} [{bar}] {pos}/{len}) instead of raw ANSI escape sequences; --quiet suppresses it entirely

Fixed

  • macOS tree-sitter-blazor archive warning removed — the build now avoids the unsupported BSD ar -D flag probe that previously emitted noisy warnings during local builds on macOS

CI

  • Add Dependabot auto-merge workflow — approved Dependabot PRs with passing CI now merge automatically

0.8.1 - 2026-04-15

CI

  • Bump actions/attest-build-provenance from 3.0.0 to 4.1.0
  • Bump actions/cache from 5.0.4 to 5.0.5
  • Bump actions/configure-pages from 5.0.0 to 6.0.0
  • Bump softprops/action-gh-release from 2.6.1 to 3.0.0
  • Bump actions/upload-pages-artifact from 3.0.1 to 5.0.0
  • Pin ort to =2.0.0-rc.11 in Dependabot ignore rules pending resolution of VitisAI build regression in rc.12

Security

  • Updated ureq to 3.3.0, rustls to 0.23.38, rustls-webpki to 0.103.12 — resolves RUSTSEC-2026-0098 and RUSTSEC-2026-0099 (URI name constraint validation bugs)

0.8.0 - 2026-04-15

Added

  • Symbol name disambiguation for MCP graph toolscoraline_callers, coraline_callees, coraline_impact, coraline_find_references, coraline_node, coraline_dependencies, coraline_dependents, and coraline_path now accept name (+ optional file) as an alternative to node_id, with clear disambiguation errors when multiple symbols share the same name
  • file filter on search toolscoraline_search and coraline_find_symbol accept an optional file parameter to scope results to a specific file path
  • coraline_find_file MCP tool — glob-based file search (*.rs, test_*, [Cc]argo.toml) that walks the project tree, skipping common build/hidden directories

Fixed

  • FTS5 search hardened against special-character queries — search terms are now individually double-quoted before SQLite MATCH execution, with embedded quotes escaped; blank/whitespace-only input returns empty results instead of an FTS syntax error. Queries containing / (e.g. file paths), ", or other FTS special characters now work correctly
  • MCP tool dispatch resolves prefixed tool namesToolRegistry now normalizes common client prefixes (mcp_coraline_coraline_*, mcp_coraline_*, mcp_*) before lookup, preventing Unknown tool errors when MCP clients such as VS Code Copilot automatically prefix registered tool names
  • Removed #[allow(clippy::cast_possible_truncation)] suppressions — all u64 as usize casts in MCP tool execute functions replaced with usize::try_from().ok().unwrap_or(N); f64 as f32 in SemanticSearchTool narrowed to a single line-level allow with justification comment
  • Fixed silent empty-string return in resolve_node_id — the len() == 1 branch now returns a proper internal_error instead of silently producing an empty node ID if the iterator is unexpectedly exhausted
  • Release workflow not triggered by auto-tag — tags pushed by github-actions[bot] via GITHUB_TOKEN don't fire push events on other workflows; auto-tag now explicitly triggers the release workflow via workflow_dispatch

0.7.0 - 2026-04-13

Added

  • MCP background auto-sync — the MCP server now spawns a background thread that periodically checks index freshness and performs incremental sync when files have changed, keeping the knowledge graph current without manual intervention
  • Automatic incremental embedding — after each background sync, newly-added nodes are automatically embedded when the embeddings feature is enabled and ONNX model files are present on disk
  • auto_sync_interval_secs config — new [sync] setting in config.toml controls the background check interval (default: 120 seconds, set to 0 to disable)
  • coraline update CLI command — checks crates.io for newer published versions and prints upgrade instructions
  • get_unembedded_nodes database query — efficient LEFT JOIN query to find nodes missing vector embeddings, enabling incremental embedding instead of re-embedding everything
  • Repository logo asset — added assets/img/coraline_logo.png and wired it into the README header for consistent project branding

Changed

  • ureq is now a non-optional dependency — always available for update checking (previously gated behind the embeddings feature)
  • tree-sitter-dart updated to 0.1.0 — migrated from deprecated language() function to the new LANGUAGE constant API

Dependencies

  • Consolidated Dependabot PRs (#15–#19) — CI action versions (actions/checkout@v6, codeql-action@v4, upload-artifact@v7, download-artifact@v8.0.1) were already at target versions; no changes needed
  • Skipped ort 2.0.0-rc.12 due to upstream VitisAI build regression — remains pinned at =2.0.0-rc.11

Documentation

  • README cleanup and docs-site routing — removed emoji-heavy formatting, normalized the logo image tag, and updated primary documentation links to point to the published site at https://greysquirr3l.github.io/coraline/
  • Configuration, MCP, and CLI docs updated — documented auto_sync_interval_secs, background auto-sync behavior, and the coraline update command

0.6.0 - 2026-04-09

Added

  • --skip-sync for coraline embed — allows explicitly bypassing the pre-embed sync check when you intentionally want to embed the current indexed state
  • SyncStatus preflight API (extraction::needs_sync) — lightweight sync-status check now returns detailed added/modified/removed counts for reuse by CLI and MCP flows

Changed

  • coraline embed now preflights index freshness — embed checks for stale index state and auto-runs incremental sync only when needed, with progress output that reports detected and applied changes
  • coraline_semantic_search now performs periodic freshness maintenance — MCP semantic search throttles freshness checks and, when stale, auto-syncs the graph and refreshes stale/missing node embeddings before serving results

Documentation

  • CLI, MCP, and README docs updated — documented embed --skip-sync, pre-embed auto-sync behavior, and MCP semantic-search freshness metadata
  • mdBook docs site added — introduced docs/book/ and a GitHub Pages deployment workflow (docs-pages.yml) to publish documentation on the project GitHub Pages site
  • Architecture docs visual refresh — replaced ASCII overview with GitHub-native Mermaid diagrams for cleaner rendering and maintenance

0.5.0 - 2026-04-08

Added

  • MCP protocol negotiation and compatibility fallback — server now negotiates protocol version with clients, preferring 2025-11-25 while retaining compatibility with 2024-11-05
  • tools/list pagination support — cursor-based pagination added via cursor request param and nextCursor response field

Changed

  • MCP lifecycle enforcement tightened — normal operations now require successful initialize followed by notifications/initialized
  • Tool error semantics aligned with MCP expectations — unknown tool calls return protocol errors; tool execution failures continue returning isError: true results
  • Tool capability declaration expanded — MCP initialize response now advertises tools.listChanged capability (currently false)
  • Core dependencies refreshed for 0.5.0 — upgraded key libraries including toml (1.1), rusqlite (0.39), sha2 (0.11), tokenizers (0.22), and multiple tree-sitter parser crates; validated with full workspace tests and clippy
  • Workflow supply-chain hardening — all CI and CodeQL GitHub Actions are now pinned to immutable commit SHAs to improve OSSF Scorecard Pinned-Dependencies posture
  • Strict lint command is now standardized — added tracked .cargo/config.toml alias so cargo lint consistently enforces the project clippy policy in local and CI runs

Fixed

  • Tool result schema field casing — MCP tool results now serialize as isError (camelCase) instead of is_error
  • Clippy pedantic compliance in MCP server code — removed no-effect underscore bindings and replaced potential panicking slice/index patterns with safe iterator/object mutation patterns

Documentation

  • MCP documentation refreshed across README and docs book — updated protocol/lifecycle notes, pagination behavior, and development examples to reflect current server behavior

[0.4.4] - 2026-04-08

Fixed

  • Windows cross-platform CI test failureparse_project_root_accepts_file_uri unit test now handles Windows file URI format (file:///C:/...) correctly by normalizing the leading slash when present; test is now platform-aware and uses appropriate URIs for each platform

[0.4.3] - 2026-04-07

Fixed

  • Cross-compilation builds failing on OpenSSL — switched TLS backend from native-tls (OpenSSL) to rustls for all HTTP operations; musl and ARM cross-builds no longer require OpenSSL headers or linking
  • Root cause: ort dependency had default features enabled which pulled in tls-nativeureq/native-tlsopenssl-sys; now uses default-features = false with explicit tls-rustls

Changed

  • embeddings feature now uses rustls — pure Rust TLS for model downloads, no system OpenSSL dependency
  • embeddings-dynamic no longer includes any TLS stack — users supply their own ONNX runtime, no HTTP downloads needed

Security

  • Pinned all GitHub Actions to commit SHAs — OSSF Scorecard PinnedDependenciesID compliance
  • Added Dependabot configuration — automated dependency updates for Cargo and GitHub Actions

0.4.2 - 2026-04-07

Fixed

  • MCP tools discovery without explicit --pathtools/list now lazily initializes the tool registry when clients call it before initialize, so tools are returned even when coraline serve --mcp starts without -p
  • Safer MCP project-root URI parsing — non-file:// URIs (for example, remote client scheme URIs) are no longer treated as filesystem paths during initialize; server falls back to an actual local path when needed
  • Regression coverage for MCP startup flow — added tests for pre-initialize tools/list behavior and URI parsing guards to prevent regressions

0.4.1 - 2026-04-03

Added

  • Embedding model prompt on coraline init — when stdin is a TTY, init now offers to download the embedding model (~137 MB) immediately after initialization; declined or non-interactive runs print a tip and continue normally with full graph functionality
  • embeddings is now the default featurecargo install coraline includes ONNX/semantic search support out of the box; no --features flag required for most users

Fixed

  • MCP server no longer ghost-creates .coraline/MemoryManager previously called create_dir_all(.coraline/memories/) eagerly on every MCP startup, leaving a stub directory that blocked coraline init from running cleanly; it now returns an error if .coraline/ doesn't exist, which the MCP tool registry handles gracefully
  • coraline init -i on an already-initialized project no longer prompts to overwrite — when --index is present without --force, init detects the existing directory, skips the destructive overwrite, and runs indexing directly; use --force to explicitly wipe and reinitialize
  • coraline_semantic_search MCP tool degrades gracefully without a model — when no ONNX model file is present the tool is not registered (all other tools remain available) and a warning is emitted to the project log

0.4.0 - 2026-03-20

Added

  • Full multi-language symbol extraction coverage across all supported languages, including previously missing Python internals and broad AST node-kind mappings.
  • Expanded import/export resolution across languages for stronger cross-file graph relationships and MCP traversal behavior.
  • Broader call-expression detection and callee extraction across language grammars to improve call graph completeness.

Changed

  • Cross-language resolution quality improved for callers/callees/impact tooling due to richer import/export and call mapping.

Internal

  • Strict lint compliance restored after expansion (cargo clippy --all-features -- -D warnings).
  • Release validated with build + full test suite.

0.3.1 - 2026-03-18

Added

  • embeddings-dynamic feature flag — alternative to embeddings that uses ort/load-dynamic instead of ort/download-binaries, allowing users on systems with older glibc (e.g., Rocky Linux, HPC nodes) to supply their own libonnxruntime.so built against their local glibc (#8)
  • musl static binaries in releasesx86_64-unknown-linux-musl and aarch64-unknown-linux-musl targets added to the release CI matrix, producing fully static binaries with zero glibc dependency

0.3.0 - 2026-03-07

Added

  • Vector math optimizations — cosine similarity and L2 normalization now use fused multiply-add for improved numerical stability

Changed

  • Dependencies updated — refreshed core dependencies and applied transitive updates for security and compatibility (tree-sitter, clap, tempfile, syn, and 16+ transitive deps)

Internal

  • All tests validated (37/37 passing); property tests ensure numerical accuracy

0.2.3 - 2026-03-01

Fixed

  • coraline init -i on an already-initialized project — instead of hard-failing, the CLI now prompts "Overwrite? [y/N]" when stdin is a TTY, or prints a clear error with --force guidance in non-interactive contexts; --force / -f flag added to init to skip the prompt
  • UNIQUE constraint failures on minified/single-line files — node IDs now incorporate start_column in addition to start_line, preventing hash collisions for multiple symbols on the same line
  • Garbled progress output during index/sync — progress lines now use \r\x1B[K (erase-to-end-of-line) instead of bare \r, and stdout is flushed after each update to prevent interleaving with log output

Internal

  • OSSF Scorecard CI workflow added
  • Security audit workflow now also triggers on deny.toml changes
  • cargo fmt style pass across config.rs and resolution/mod.rs

0.2.2 - 2026-02-21

Fixed

  • Release pipeline: binary builds failing on ort-sysort, tokenizers, and ndarray are now optional, gated behind an embeddings feature flag; default builds no longer require ONNX Runtime prebuilt binaries
  • Release pipeline: coraline publish failing when version already on crates.io — publish steps for both tree-sitter-blazor and coraline now skip gracefully if the version already exists
  • Release pipeline: build matrix cancelling all jobs on first failure — added fail-fast: false so platform builds run independently
  • Dropped x86_64-apple-darwin release binary — Intel Mac is not a supported target; ONNX Runtime provides no prebuilt binaries for it

0.2.1 - 2026-02-21

Fixed

  • coraline init blocked by log directorylogging::init() eagerly created .coraline/logs/ before is_initialized() ran, making every re-init attempt report "already initialized"
  • sync crash on UNIQUE constraint — incremental sync now catches per-file store errors (warn + continue) instead of aborting the entire sync, consistent with index_all
  • callers/callees CLI showing incorrect results — CLI was passing no edge-kind filter, surfacing contains edges as false callers; now filters to calls edges only, consistent with MCP tools
  • CI actions/checkout@v6 — updated all workflow steps to the current stable v4

0.2.0 - 2026-02-20

Added

  • Vector embeddings — full ONNX pipeline using ort 2.0.0-rc.11 and nomic-embed-text-v1.5 (384-dim). coraline embed CLI command and coraline_semantic_search MCP tool
  • 25 MCP tools (26 with embeddings) — complete symbol, graph, file, memory, config, stats, and sync toolset
  • coraline_stats — detailed graph statistics grouped by language, node kind, and edge kind
  • coraline_dependencies / coraline_dependents — traversal tools for outgoing/incoming dependencies
  • coraline_path — find shortest paths between any two nodes
  • coraline_sync MCP tool — trigger incremental sync from an MCP client
  • coraline_semantic_search — semantic similarity search over indexed symbols
  • coraline_find_symbol / coraline_get_symbols_overview / coraline_node / coraline_find_references — symbol-level tools matching Serena's precision
  • coraline_read_file / coraline_list_dir / coraline_get_file_nodes — file exploration tools
  • coraline_get_config / coraline_update_config — TOML config management via MCP
  • Memory toolscoraline_write_memory, coraline_read_memory, coraline_list_memories, coraline_delete_memory, coraline_edit_memory (regex + literal modes)
  • TOML configuration.coraline/config.toml with sections for indexing, context, sync, and vectors; written as a commented template on coraline init
  • Structured loggingtracing with daily-rotating file appender to .coraline/logs/coraline.log; level via CORALINE_LOG env var
  • Framework-specific resolvers — Rust, React, Blazor, Laravel
  • CLI commandscallers, callees, impact, config, stats, embed; --json flag on all query commands
  • Criterion benchmark suite — 9 benchmarks across indexing, search, graph traversal, and context building groups (cargo bench --bench indexing)
  • CI/CD — GitHub Actions for multiplatform builds (Linux x86_64/ARM64, macOS x86_64/ARM64, Windows x86_64), crates.io publishing, CodeQL scanning, daily dependency auditing
  • 28+ language support via tree-sitter: Rust, TypeScript, JavaScript, TSX, JSX, Python, Go, Java, C, C++, C#, PHP, Ruby, Swift, Kotlin, Bash, Dart, Elixir, Elm, Erlang, Fortran, Groovy, Haskell, Julia, Lua, Markdown, MATLAB, Nix, Perl, PowerShell, R, Scala, TOML, YAML, Zig, Blazor

Fixed

  • TypeScript import extraction: import_statement was wrongly mapped as import_declaration in tree-sitter AST
  • import_clause lookup: switched from child_by_field_name (always None) to child iteration
  • Cross-file import edges test: SELECT * placed integer id at column 0; changed to explicit SELECT source, target
  • FTS multi-word search: now uses OR logic so partial matches are found
  • Glob pattern matching: completely rewritten using globset crate; prior regex implementation was non-functional
  • Parallel indexing: CPU-bound parse phase separated from sequential DB writes; SQLite PRAGMA tuning (synchronous=NORMAL, 64 MB cache, 256 MB mmap)

Changed

  • Database filename: codegraph.dbcoraline.db
  • Project directory: .codegraph/.coraline/
  • Post-commit git hook updated to check .coraline/ directory

0.1.3 - 2026-02-15

Added

  • coraline_stats MCP tool — graph statistics by language, node kind, and edge kind
  • TypeScript import extraction fix

Fixed

  • Cross-file import edge detection

0.1.2 - 2026-02-13

Added

  • PHP, Swift, Kotlin, Markdown, TOML parser support
  • CI/CD infrastructure (GitHub Actions)
  • .coraline/ directory rename from .codegraph/

Fixed

  • Critical glob pattern matching bug (rewritten with globset)

0.1.1 - 2026-02-10

Added

  • Memory system with 5 MCP tools
  • Tool abstraction layer and registry
  • Integration test suite

0.1.0 - 2026-02-07

Added

  • Initial release
  • Tree-sitter based AST extraction for Rust, TypeScript, JavaScript, Python, Go, Java, C, C++, C#, Ruby
  • SQLite graph storage
  • MCP server (coraline serve --mcp)
  • Basic CLI: init, index, sync, status, query, context
  • coraline_search, coraline_callers, coraline_callees, coraline_impact, coraline_context MCP tools
  • Git post-commit hook integration