CocoIndex Code

io.github.cocoindex-io由 GitHub 帳號 cocoindex-io 發布v0.2.43更新於 Nov 6, 2026

Semantic code search over a local repository, with AST-based chunks and incremental re-indexing.

已驗證STDIO僅桌面知識與記憶開發者工具

概覽

AI 產生的概覽

本機 MCP 伺服器,讓助理以 AST 切塊與增量重建索引對程式碼庫做語意搜尋。

可以做什麼
  • 用自然語言查詢或程式碼片段依語意搜尋程式碼庫,回傳符合的程式碼區塊、檔案路徑、語言、行號與相似度分數
  • 依語言、路徑萬用字元、筆數上限與位移量篩選及分頁結果,並可在查詢前先更新索引
  • 透過只重建變更檔案的增量索引維持索引最新,背景守護程序會常駐載入嵌入模型
  • 也能在命令列進行專案初始化、建立索引、查看狀態、診斷與結構化樣式搜尋
適用情境
適合助理需要探索不熟悉的程式碼庫、找出實作位置,或在不知道確切名稱與關鍵字、grep 與 glob 效果不佳時依描述找程式碼。最適合在本機專案上工作的本機編碼助理。
執行需求
以 stdio 本機程序執行,可透過 uvx、pipx 或 uv 從 PyPI 安裝;full 版本自帶本機嵌入模型,slim 版本則需要雲端嵌入服務與 API 金鑰。若用戶端不在程式碼庫目錄內啟動,需設定 COCOINDEX_CODE_ROOT_PATH,否則使用工作目錄。首次使用需初始化專案並建立索引。
安裝前請注意
伺服器會讀取並索引所設定根目錄下的原始碼檔案,Docker 方式預設把家目錄以讀寫方式掛載進容器,範圍偏大。使用雲端嵌入服務需要 API 金鑰,例如 OPENAI_API_KEY 或 VOYAGE_API_KEY,存放在全域設定或環境變數中。建立索引會寫入專案設定目錄並加入 .gitignore;重設指令會刪除索引資料庫。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 CocoIndex Code,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

[cocoindex code]

AST-based semantic code search

[effect]

CocoIndex Code provides AST-based semantic search for your codebase, built on the CocoIndex Rust data transformation engine. Use it from the CLI or connect Claude, Codex, Cursor, and other coding agents through a Skill or MCP.

  • 70% token savings.
  • 1 min setup with default settings.

Get Started

Install

Using pipx:

bash
pipx install 'cocoindex-code[full]'          # batteries included (local embeddings)pipx upgrade cocoindex-code                  # upgrade

Using uv:

bash
uv tool install --upgrade 'cocoindex-code[full]'

Two install styles — they mirror the Docker image variants of the same names:

  • cocoindex-code[full] — batteries-included. Pulls in sentence-transformers so local embeddings (no API key required) work out of the box. The ccc init interactive prompt defaults to Snowflake/snowflake-arctic-embed-xs.
  • cocoindex-code (slim) — LiteLLM-only; requires a cloud embedding provider and API key. Use when you don't want the local-embedding deps (~1 GB of torch + transformers).

Next, set up your coding agent integration — or jump to Manual CLI Usage if you prefer direct control.

Coding Agent Integration

This repository is a single plugin marketplace (.claude-plugin/marketplace.json) consumed by both Claude Code and Grok — same plugin id cocoindex-code, same ccc skill. Grok optionally activates the bundled hooks and MCP server with --trust; Claude Code users can install the same marketplace and rely on the skill alone or load hooks/MCP from the plugin as needed.

Skill (Recommended)

Install the ccc skill so your coding agent automatically uses semantic search when needed:

bash
npx skills add cocoindex-io/cocoindex-code

The skill teaches the agent to handle initialization, indexing, and searching, so you don't need to run ccc init or ccc index yourself. The agent keeps the index up to date as you work.

The agent uses semantic search automatically when it would be helpful. You can also nudge it explicitly — just ask it to search the codebase, e.g. "find how user sessions are managed", or type /ccc to invoke the skill directly.

Works with Claude Code and other skill-compatible agents.

Claude Code plugin marketplace

For Claude Code users, this repository is also a plugin marketplace. Install the skill from inside Claude Code with:

text
/plugin marketplace add cocoindex-io/cocoindex-code/plugin install cocoindex-code@cocoindex-code

This bundles the same ccc skill, with version pinning and /plugin marketplace update for updates. The repository also ships hooks/hooks.json and .mcp.json for Grok (and Claude Code plugin installs that load those files); Claude users who want skill-only search can rely on the skill alone and add MCP manually in the MCP Server section below instead of using the bundled .mcp.json.

Grok plugin

For Grok users, install via Grok's plugin system. The plugin bundles three components:

ComponentPurpose
Skill (skills/ccc/)Agent runs ccc search / ccc index via the CLI (same as Claude Code above)
Hook (hooks/hooks.json)SessionStart + PostToolUse (Edit/Write/…) → incremental ccc index when .cocoindex_code/settings.yml exists (never in the directory holding ccc's user settings, ~ by default)
MCP (.mcp.json)ccc mcp stdio server — search tool with refresh_index=true by default

Grok does not import Claude's enabledPlugins or plugin cache; install separately even if you already use cocoindex in Claude Code.

Full install (skill + hook + MCP):

bash
grok plugin marketplace add cocoindex-io/cocoindex-codegrok plugin install cocoindex-io/cocoindex-code --trustgrok plugin enable cocoindex-code

Prefer the GitHub shorthand (cocoindex-io/cocoindex-code) for install — grok plugin install cocoindex-code can fail when no marketplace plugin matches that bare name.

--trust is required so Grok activates the plugin's hooks and MCP server (skills load when the plugin is enabled).

Skill-only (match Claude Code — no auto-index hook, no MCP tool):

Install and enable as above, then disable the optional components:

  1. Hooks — open /hooks, select the SessionStart / PostToolUse hooks from cocoindex-code, press Space to disable.
  2. MCP — open /mcps, select cocoindex-code, press Space to disable; or persist in ~/.grok/config.toml:
toml
[mcp_servers.cocoindex-code]enabled = false

The agent still owns indexing via the ccc skill (ccc index / ccc search --refresh when stale), same as Claude Code.

To avoid importing MCP servers from your Claude/Cursor user config (unrelated to this plugin):

toml
[compat.claude]mcps = false
[compat.cursor]mcps = false
Oh My Pi plugin

Oh My Pi reads .omp-plugin/marketplace.json (preferred) and falls back to .claude-plugin/marketplace.json.

bash
omp plugin marketplace add cocoindex-io/cocoindex-codeomp plugin install cocoindex-code@cocoindex-code --scope project

Then restart the session (/reload-plugins does not reload extensions). Requires ccc on PATH (uv tool install --upgrade 'cocoindex-code[full]').

ComponentPurpose
Skill (skills/ccc/)Agent runs ccc search / ccc index via the CLI
Hook (extensions/ccc-index.ts via package.json#omp.extensions)session_start + post-edit tool_result → incremental ccc index when .cocoindex_code/settings.yml exists (never in the directory holding ccc's user settings, ~ by default)
MCP (.mcp.json)ccc mcp stdio server

OMP does not execute Claude hooks/hooks.json command hooks. The TypeScript extension is the OMP equivalent of the Claude/Grok SessionStart + PostToolUse pair.

Skill-only (no MCP, no auto-index): install the skill via npx skills add cocoindex-io/cocoindex-code, or run ccc search / ccc index from the shell.

MCP Server

Alternatively, use ccc mcp to run as an MCP server:

Claude Code
bash
claude mcp add cocoindex-code -- ccc mcp
Codex
bash
codex mcp add cocoindex-code -- ccc mcp
OpenCode
bash
opencode mcp add

Enter MCP server name: cocoindex-code Select MCP server type: local Enter command to run: ccc mcp

Or use opencode.json:

json
{  "$schema": "https://opencode.ai/config.json",  "mcp": {    "cocoindex-code": {      "type": "local",      "command": [        "ccc", "mcp"      ]    }  }}
Kilo Code

Add a local MCP server in ~/.config/kilo/kilo.jsonc, kilo.jsonc, or .kilo/kilo.jsonc:

json
{  "mcp": {    "cocoindex-code": {      "type": "local",      "command": ["ccc", "mcp"],      "enabled": true    }  }}
Oh My Pi

Prefer the marketplace install above. Manual project MCP (.omp/mcp.json):

json
{  "mcpServers": {    "cocoindex-code": {      "command": "ccc",      "args": ["mcp"]    }  }}

Once configured, the agent can use semantic search to find code by description, explore unfamiliar codebases, and locate implementations without exact names.

Note: The cocoindex-code command (without subcommand) still works as an MCP server for backward compatibility. It auto-creates settings from environment variables on first run.

MCP Tool Reference

When running as an MCP server (ccc mcp), the following tool is exposed:

search — Search the codebase using semantic similarity.

search(    query: str,                          # Natural language query or code snippet    limit: int = 5,                      # Maximum results (1-100)    offset: int = 0,                     # Pagination offset    refresh_index: bool = True,          # Refresh index before querying    languages: list[str] | None = None,  # Filter by language (e.g. ["python", "typescript"])    paths: list[str] | None = None,      # Filter by path glob (e.g. ["src/utils/*"]))

Returns matching code chunks with file path, language, code content, line numbers, and similarity score.

Manual CLI Usage

You can also use the CLI directly — useful for manual control, running indexing after changing settings, checking status, or searching outside an agent.

bash
ccc init                                # initialize project (creates settings)ccc index                               # build the indexccc search "authentication logic"       # search!

The background daemon starts automatically on first use.

Tip: You can skip ccc init and go straight to ccc index — it auto-initializes new projects with default settings. If global settings are missing too (first use on the machine), it walks you through the same model setup as ccc init when run interactively; non-interactive runs (scripts, hooks) still require a one-time ccc init first.

Note: ccc index never auto-initializes the directory that holds ccc's user settings directory: your home directory by default (~/.cocoindex_code holds the global settings and daemon files), or the parent of $COCOINDEX_CODE_DIR when that directory is named .cocoindex_code. A project there would cover every repo below it. The editor hooks skip that directory even if it is already a project. If an older ccc made your home directory a project (~/.cocoindex_code/settings.yml exists), run ccc reset --all in your home directory: it removes that project's settings and indexes and keeps your global settings. To index your whole home directory on purpose, run ccc init there.

CLI Reference

CommandDescription
ccc initInitialize a project — creates settings files, adds .cocoindex_code/ to .gitignore
ccc indexBuild or update the index (auto-inits if needed). Shows streaming progress.
ccc search <query>Semantic search across the codebase
ccc grep <pattern> [path]Structural code search by example (no index needed)
ccc statusShow index stats (chunk count, file count, language breakdown)
ccc mcpRun as MCP server in stdio mode
ccc doctorRun diagnostics — checks settings, daemon, model, file matching, and index health
ccc resetDelete index databases. --all also removes settings. -f skips confirmation.
ccc versionPrint the CLI version
ccc daemon statusShow daemon version, uptime, and loaded projects
ccc daemon restartRestart the background daemon
ccc daemon stopStop the daemon

Search Options

bash
ccc search database schema                           # basic searchccc search --lang python --lang markdown schema      # filter by languageccc search --path 'src/utils/*' query handler        # filter by pathccc search --offset 10 --limit 5 database schema     # paginationccc search --refresh database schema                 # update index first, then search

By default, ccc search scopes results to your current working directory (relative to the project root). Use --path to override.

Structural Search (ccc grep)

ccc grep finds code by structure, not text — you write a by-example pattern and it matches the syntax tree (via cocoindex's code_match), so formatting, whitespace, and intervening tokens don't matter. It runs entirely locally: no index, daemon, or embeddings required.

bash
ccc grep 'def \NAME(\(ARGS*\)):'                      # every Python function def under the cwdccc grep 'foo(\(ARGS*\))' src/                        # calls to foo(...) anywhere under src/ccc grep 'fn \NAME(\(A*\))' --lang rust               # restrict to one languageccc grep 'class \NAME:' --path 'tests/**'            # restrict to a path globccc grep 'TODO(\(A*\))' path/to/file.py               # a single file

Metavariables use the \ sigil: \NAME captures one node, \(NAME*\) a run of siblings, \_/\* match anonymously. The pattern is matched per language, so a single invocation scans every supported source file (others are skipped). Inside an initialized project, ccc grep honors the project's include/exclude patterns and .gitignore; otherwise it scans all supported source files under the path.

Results stream to the terminal file-by-file as each match is found (in completion order, since files are matched in parallel) rather than all at once at the end. Each matching file shows its matched line range; under a TTY the path is colored, line numbers are dimmed, and the unmatched context around a match is dimmed so the match stands out.

Note: ccc grep relies on cocoindex's structural code_match feature. Until it ships in a released cocoindex, run against a local cocoindex build.

Docker

A Docker image is available for teams who want a reproducible, dependency-free setup — no Python, uv, or system dependencies required on the host.

The recommended approach is a persistent container: start it once, and use docker exec to run CLI commands or connect MCP sessions to it. The daemon inside stays warm across sessions, so the embedding model is loaded only once.

Choosing an image

Two variants are published from each release:

TagSizeEmbedding backendsWhen to pick
cocoindex/cocoindex-code:latest (slim, default)~450 MBLiteLLM (cloud: OpenAI, Voyage, Gemini, Ollama, …)Most users. Cloud-backed embeddings, smaller image, fast pulls.
cocoindex/cocoindex-code:full~5 GBsentence-transformers (local) + LiteLLMWhen you want local embeddings without an API key, or an offline-ready container. Heavier because of torch + transformers.

The rest of this section uses :latest — substitute :full in the image: / docker run commands if you want the full variant.

Mac users running the :full variant: local embedding inference is CPU-only inside Docker, because Docker on macOS can't access Apple's Metal (MPS) GPU. If you want local embeddings and fast inference, install natively instead: pipx install 'cocoindex-code[full]'. The :latest (slim) variant is unaffected — LiteLLM runs the model on the provider's side, so Docker vs. native makes no difference.

Quick start — docker compose up -d

Bring it up in one line — no clone needed (bash / zsh):

bash
# macOS / Windowsdocker compose -f <(curl -L https://raw.githubusercontent.com/cocoindex-io/cocoindex-code/refs/heads/main/docker/docker-compose.yml) up -d
# Linux (aligns file ownership on bind-mounted paths with your host user)PUID=$(id -u) PGID=$(id -g) docker compose -f <(curl -L https://raw.githubusercontent.com/cocoindex-io/cocoindex-code/refs/heads/main/docker/docker-compose.yml) up -d

Or grab docker/docker-compose.yml and run docker compose up -d next to it (works on any shell, including Windows cmd / PowerShell).

By default your home directory is mounted into the container (set COCOINDEX_HOST_WORKSPACE to narrow this to a specific code folder). Index data and the embedding model cache persist in a Docker volume across restarts. Your global settings file at $HOME/.cocoindex_code/global_settings.yml is visible and editable on the host; edits take effect on your next ccc command.

Pick a different image: set COCOINDEX_CODE_IMAGE to override the default. For example, the :full variant or GHCR:

bash
COCOINDEX_CODE_IMAGE=cocoindex/cocoindex-code:full docker compose up -dCOCOINDEX_CODE_IMAGE=ghcr.io/cocoindex-io/cocoindex-code:latest docker compose up -d

Or: docker run

Docker Desktop (macOS / Windows)
bash
docker run -d --name cocoindex-code \  --volume "$HOME:/workspace" \  --volume cocoindex-data:/var/cocoindex \  -e COCOINDEX_CODE_HOST_PATH_MAPPING="/workspace=$HOME" \  cocoindex/cocoindex-code:latest
Linux (with PUID/PGID)
bash
docker run -d --name cocoindex-code \  -e PUID=$(id -u) -e PGID=$(id -g) \  --volume "$HOME:/workspace" \  --volume cocoindex-data:/var/cocoindex \  -e COCOINDEX_CODE_HOST_PATH_MAPPING="/workspace=$HOME" \  cocoindex/cocoindex-code:latest

Shell wrapper for ccc commands

Paste this into ~/.bashrc / ~/.zshrc so ccc feels native on the host and picks up the right project based on your current directory:

bash
ccc() {  docker exec -it -e COCOINDEX_CODE_HOST_CWD="$PWD" cocoindex-code ccc "$@"}

Now cd into a project under your workspace and run ccc init, ccc index, ccc search ..., or ccc status.

Connect your coding agent

Claude Code

Register MCP from inside the target project so $PWD points there:

bash
claude mcp add cocoindex-code -- docker exec -i \  -e COCOINDEX_CODE_HOST_CWD="$PWD" cocoindex-code ccc mcp

Or via .mcp.json:

json
{  "mcpServers": {    "cocoindex-code": {      "type": "stdio",      "command": "docker",      "args": [        "exec",        "-i",        "-e",        "COCOINDEX_CODE_HOST_CWD=${PWD}",        "cocoindex-code",        "ccc",        "mcp"      ]    }  }}

Note: use -i (not -it). The -t flag allocates a terminal, which interferes with MCP's JSON messaging over stdin/stdout — only add it for interactive ccc commands like ccc init.

Codex
bash
codex mcp add cocoindex-code -- docker exec -i \  -e COCOINDEX_CODE_HOST_CWD="$PWD" cocoindex-code ccc mcp

Upgrading from an older image

Earlier images used separate cocoindex-db and cocoindex-model-cache volumes; the current image consolidates them into a single cocoindex-data volume. Before pulling the new image, drop the old container and volumes — indexes rebuild on your next ccc index, and the embedding model is re-populated automatically on first start:

bash
docker rm -f cocoindex-codedocker volume rm cocoindex-db cocoindex-model-cache

Configuration via environment variables

Pass configuration to docker run / compose with -e:

bash
# Extra extensions (e.g. Typesafe Config, SBT build files)-e COCOINDEX_CODE_EXTRA_EXTENSIONS="conf,sbt"
# Exclude build artefacts (Scala/SBT example)-e COCOINDEX_CODE_EXCLUDE_PATTERNS='["**/target/**","**/.bloop/**","**/.metals/**"]'
# Set an API key-e VOYAGE_API_KEY=your-key

Security note: mounting $HOME gives the container read/write access to everything under it. If that's too broad, bind-mount a narrower directory instead (COCOINDEX_HOST_WORKSPACE=/path/to/code).

Build the image locally

bash
docker build -t cocoindex-code:local -f docker/Dockerfile .

Features

  • Semantic Code Search: Find relevant code using natural language queries when grep doesn't work well.
  • Incremental indexing: The Rust indexing engine re-indexes only changed files.
  • Multi-Language Support: Python, JavaScript/TypeScript, Rust, Go, Java, C/C++, C#, SQL, Shell, and more.
  • Embedded storage: No database setup required.
  • Embedding providers: Local SentenceTransformers via the [full] extra, with no API key, or 100+ cloud providers via LiteLLM.

Configuration

For a detailed guide on choosing and configuring embedding models, see EMBEDDINGS.md.

Configuration lives in two YAML files, both created automatically by ccc init.

User Settings (~/.cocoindex_code/global_settings.yml)

Shared across all projects. Controls the embedding model and environment variables for the daemon.

yaml
embedding:  provider: sentence-transformers                    # or "litellm"  model: Snowflake/snowflake-arctic-embed-xs  device: mps                                        # optional: cpu, cuda, mps (auto-detected if omitted)  min_interval_ms: 300                               # optional: pace LiteLLM embedding requests to reduce 429s; defaults to 5 for LiteLLM  mps_low_watermark_ratio: 0.4                       # optional: PyTorch allocator soft limit  mps_high_watermark_ratio: 0.5                      # optional: PyTorch allocator hard limit
  # Optional extra kwargs passed to the embedder, separately for indexing vs query.  # `ccc init` auto-populates these for known models (e.g. Cohere, Voyage, Nvidia NIM,  # nomic-ai code-retrieval models, Snowflake arctic-embed).  # indexing_params:  #   input_type: search_document        # litellm: input_type  # query_params:  #   input_type: search_query           # sentence-transformers: prompt_name
envs:                                                # extra environment variables for the daemon  OPENAI_API_KEY: your-key                           # only needed if not already in your shell environment
daemon:  idle_timeout_minutes: 180                          # optional: exit the daemon after this long without client activity (default 180, 0 = never)  keep_alive_with_mcp: true                          # optional: keep the daemon warm while an MCP client is connected (default true)

Note: The daemon inherits your shell environment. If an API key (e.g. OPENAI_API_KEY) is already set as an environment variable, you don't need to duplicate it in envs. The envs field is only for values that aren't in your environment.

Apple Silicon memory safety: MPS SentenceTransformer calls use CocoIndex's isolated GPU subprocess, keeping the model loaded while isolating Metal allocations from the daemon. The low and high watermarks are ratios of PyTorch's recommended maximum working set; they default here to 0.4 and 0.5. CocoIndex retries MPS out-of-memory failures with progressively smaller batches, and cocoindex-code releases unused allocator cache after each index run. Explicit COCOINDEX_RUN_GPU_IN_SUBPROCESS, PYTORCH_MPS_LOW_WATERMARK_RATIO, and PYTORCH_MPS_HIGH_WATERMARK_RATIO environment variables take precedence over these defaults.

Indexing concurrency: Multiple projects may prepare indexes concurrently, while CocoIndex serializes their GPU calls through its single MPS subprocess. A search waits only when its own project still needs the initial index.

Idle timeout: the background daemon holds the embedding model in RAM, so it exits after daemon.idle_timeout_minutes without client activity and is restarted automatically on your next ccc command or MCP search. By default, a live MCP session sends periodic heartbeats so the daemon remains warm while your coding agent is connected. Set daemon.keep_alive_with_mcp: false to let the daemon idle-exit during long-lived MCP sessions and release the model between real requests. Set idle_timeout_minutes: 0 to keep the daemon running forever.

Custom location: set COCOINDEX_CODE_DIR to place global_settings.yml somewhere other than ~/.cocoindex_code/ — useful if you want the file to live alongside your projects (e.g. on a synced folder).

indexing_params / query_params

Some embedding models expose different modes for documents vs queries (asymmetric retrieval). For example, Cohere's v3 models want input_type: search_document when embedding corpus content and input_type: search_query when embedding a user query; several SentenceTransformers models use prompt_name: passage / prompt_name: query for the same purpose. These knobs live under indexing_params and query_params:

yaml
embedding:  provider: litellm  model: cohere/embed-english-v3.0  indexing_params:    input_type: search_document  query_params:    input_type: search_query

ccc init populates these automatically for models it recognizes — including all Cohere v3, Voyage, Nvidia NIM, Gemini embedding (gemini/gemini-embedding-*, gemini/text-embedding-*, gemini/embedding-* — LiteLLM auto-maps input_type to Gemini's task_type), nomic-ai/CodeRankEmbed, nomic-ai/nomic-embed-code, nomic-ai/nomic-embed-text-v1/v1.5, mixedbread-ai/mxbai-embed-large-v1, and the Snowflake/snowflake-arctic-embed-* family — and prints the chosen defaults. For other models, it leaves a commented-out template under embedding: so you can fill it in by hand.

OpenAI embeddings (text-embedding-3-*, text-embedding-ada-002) are intentionally not in the list: they're symmetric and have no equivalent knob.

Accepted keys: prompt_name (sentence-transformers) and input_type (litellm). Other keys are rejected at daemon startup with a clear error. Note: dimensions is intentionally not exposed here — output dimension must be identical for indexing and query, so it's a model-wide setting rather than a per-side knob.

Doctor checks both sides. ccc doctor exercises the model once with indexing_params and once with query_params, reporting each as a separate Model Check (indexing) / Model Check (query) entry — so a misconfiguration on one side is diagnosable without hiding behind the other.

Legacy-bridge warning: if you're upgrading from an earlier version and your global_settings.yml uses nomic-ai/CodeRankEmbed or nomic-ai/nomic-embed-code without indexing_params / query_params, the daemon continues to apply the previous behavior (prompt_name: query at query time) and prints a one-time warning asking you to make the setting explicit. You can silence the warning by adding an empty block such as query_params: {}.

Project Settings (<project>/.cocoindex_code/settings.yml)

Per-project. Controls which files to index.

yaml
include_patterns:  - "**/*.py"  - "**/*.js"  - "**/*.ts"  - "**/*.rs"  - "**/*.go"  # ... (sensible defaults for 28+ file types)
exclude_patterns:  - "**/.*"                # hidden directories  - "**/__pycache__"  - "**/node_modules"  - "**/dist"  # ...
max_file_size: 500KB       # skip files larger than this (default: no limit)
language_overrides:  - ext: inc               # treat .inc files as PHP    lang: php
chunkers:  - ext: toml              # use a custom chunker for .toml files    module: example_toml_chunker:toml_chunker

.cocoindex_code/ is automatically added to .gitignore during init.

max_file_size keeps bundled or generated files out of the index without having to enumerate them in exclude_patterns. It accepts a plain byte count (1048576) or a size with a binary unit suffix: B, KB, MB, GB (case-insensitive, so 500KB and 500 kb are the same). The limit is inclusive, and omitting the key indexes files of any size. It applies wherever project file matching does, so ccc grep skips the same files.

After editing include_patterns, exclude_patterns, max_file_size, or language_overrides:

  • Run ccc doctor to preview which files match.
  • Run ccc index or ccc search --refresh ... to update the existing index.
  • You do not need to delete the index or restart the daemon for these file-matching changes.
  • After any language_overrides change, the next run re-chunks all files, including files whose content did not change; the run reports them as reprocessed. Chunks whose text did not change keep their cached embeddings.

If you add or change custom chunkers, or edit a chunker module, restart the daemon (ccc daemon restart), then run ccc index. The daemon imports chunkers once at startup, so until it restarts it keeps running the old chunker code. The first run after the restart re-chunks all files, not only the ones the changed entry applies to; chunks whose text did not change keep their cached embeddings. A chunker counts as changed when its module: value changes or when the file of the module it names changes. Edits to other modules that file imports are not detected: after such an edit, also change the chunker's own module file (for example, bump a version comment in it).

Use chunkers when you want to control how a file type is split into chunks before indexing.

module: example_toml_chunker:toml_chunker means:

  • example_toml_chunker is a local Python module
  • toml_chunker is the function inside that module

In practice, this usually means:

  • you create a Python file in your project, for example example_toml_chunker.py
  • you add a function in that file
  • you point settings.yml at it with module.path:function_name

The function should use this signature:

python
from pathlib import Pathfrom cocoindex_code.chunking import Chunk
def my_chunker(path: Path, content: str) -> tuple[str | None, list[Chunk]]:    ...
  • path is the file being indexed
  • content is the full text of that file
  • return language_override as a string like "toml" if you want to override language detection
  • return None as language_override if you want to keep the detected language
  • return a list[Chunk] with the chunks you want stored in the index

See src/cocoindex_code/chunking.py for the public types and tests/example_toml_chunker.py for a complete example.

Embedding Models

With the [full] extra installed, ccc init defaults to a local SentenceTransformers model (Snowflake/snowflake-arctic-embed-xs) — no API key required. To use a different model, edit ~/.cocoindex_code/global_settings.yml.

The envs entries below are only needed if the key isn't already in your shell environment — the daemon inherits your environment automatically.

Ollama (Local)
yaml
embedding:  model: ollama/nomic-embed-text

Set OLLAMA_API_BASE in envs: if your Ollama server is not at http://localhost:11434.

OpenAI
yaml
embedding:  model: text-embedding-3-small  min_interval_ms: 300                               # optional: override the 5ms LiteLLM defaultenvs:  OPENAI_API_KEY: your-api-key
OpenAI-compatible (custom endpoint)

Many providers (vLLM, LM Studio, LocalAI, Together, Fireworks, DeepInfra, …) expose an OpenAI-compatible embedding API. Use the openai/ prefix and point OPENAI_BASE_URL at your endpoint:

yaml
embedding:  model: openai/your-model-nameenvs:  OPENAI_BASE_URL: https://your-endpoint/v1  OPENAI_API_KEY: your-api-key

Don't append /embeddings to the base URL — LiteLLM handles that.

Azure OpenAI
yaml
embedding:  model: azure/your-deployment-nameenvs:  AZURE_API_KEY: your-api-key  AZURE_API_BASE: https://your-resource.openai.azure.com  AZURE_API_VERSION: "2024-06-01"
Gemini
yaml
embedding:  model: gemini/gemini-embedding-001envs:  GEMINI_API_KEY: your-api-key
Mistral
yaml
embedding:  model: mistral/mistral-embedenvs:  MISTRAL_API_KEY: your-api-key
Voyage (Code-Optimized)
yaml
embedding:  model: voyage/voyage-code-3envs:  VOYAGE_API_KEY: your-api-key
Cohere
yaml
embedding:  model: cohere/embed-v4.0envs:  COHERE_API_KEY: your-api-key
AWS Bedrock
yaml
embedding:  model: bedrock/amazon.titan-embed-text-v2:0envs:  AWS_ACCESS_KEY_ID: your-access-key  AWS_SECRET_ACCESS_KEY: your-secret-key  AWS_REGION_NAME: us-east-1
Nebius
yaml
embedding:  model: nebius/BAAI/bge-en-iclenvs:  NEBIUS_API_KEY: your-api-key

Any LiteLLM-supported model works. When using a LiteLLM model, set provider: litellm (or omit provider — LiteLLM is the default for non-sentence-transformers models). For the full list of env vars each provider reads (API keys, base URLs, regions, …), see LiteLLM's Setting API Keys.

Local SentenceTransformers Models

Set provider: sentence-transformers and use any SentenceTransformers model (no API key required).

Example — general purpose text model:

yaml
embedding:  provider: sentence-transformers  model: nomic-ai/nomic-embed-text-v1.5

GPU-optimised code retrieval:

nomic-ai/CodeRankEmbed delivers significantly better code retrieval than the default model. It is 137M parameters, requires ~1 GB VRAM, and has an 8192-token context window.

yaml
embedding:  provider: sentence-transformers  model: nomic-ai/CodeRankEmbed

Note: Switching models requires re-indexing your codebase (ccc reset && ccc index) since the vector dimensions differ.

Supported Languages

LanguageAliasesFile Extensions
c.c
cppc++.cpp, .cc, .cxx, .h, .hpp
csharpcsharp, cs.cs
css.css, .scss
dart.dart
dtd.dtd
elixir.ex, .exs
fortranf, f90, f95, f03.f, .f90, .f95, .f03
gogolang.go
html.html, .htm
java.java
javascriptjs.js
json.json
kotlin.kt, .kts
lua.lua
markdownmd.md, .mdx
pascalpas, dpr, delphi.pas, .dpr
php.php
python.py
r.r
ruby.rb
rustrs.rs
scala.scala
solidity.sol
sql.sql
svelte.svelte
swift.swift
toml.toml
tsx.tsx
typescriptts.ts
vue.vue
xml.xml
yaml.yaml, .yml

Custom Database Location

By default, index databases (cocoindex.db and target_sqlite.db) live alongside settings in <project>/.cocoindex_code/. When running in Docker, you may want the databases on the container's native filesystem for performance (LMDB doesn't work well on mounted volumes) while keeping the source code and settings on a mounted volume.

Set COCOINDEX_CODE_DB_PATH_MAPPING to remap database locations by path prefix:

bash
COCOINDEX_CODE_DB_PATH_MAPPING=/workspace=/db-files

With this mapping, a project at /workspace/myrepo stores its databases in /db-files/myrepo/ instead of /workspace/myrepo/.cocoindex_code/. Settings files remain in the original location.

Multiple mappings are comma-separated and resolved in order (first match wins):

bash
COCOINDEX_CODE_DB_PATH_MAPPING=/workspace=/db-files,/workspace2=/db-files2

Both source and target must be absolute paths. If no mapping matches, the default location is used.

Troubleshooting

Run ccc doctor to check your settings, daemon health, embedding model, file matching, and index status.

sqlite3.Connection object has no attribute enable_load_extension

Some Python installations (e.g. the one pre-installed on macOS) ship with a SQLite library that doesn't enable extensions.

macOS fix: Install Python through Homebrew:

bash
brew install python3

Then re-install cocoindex-code (see Get Started for install options):

Using pipx:

bash
pipx install cocoindex-code       # first installpipx upgrade cocoindex-code       # upgrade

Using uv (install or upgrade):

bash
uv tool install --upgrade cocoindex-code

MDB_MAP_FULL: Environment mapsize limit reached

The index is stored in an LMDB database whose maximum size is fixed when the daemon starts. The default ceiling is 4 GiB, which codebases with tens of thousands of files can exhaust, especially with high-dimensional embedding models like nomic-ai/CodeRankEmbed.

Raise the ceiling with the COCOINDEX_LMDB_MAP_SIZE environment variable (value in bytes). LMDB only grows the file as data is written, so a high limit doesn't pre-allocate disk — it's safe to set it generously:

yaml
# ~/.cocoindex_code/global_settings.ymlenvs:  COCOINDEX_LMDB_MAP_SIZE: "34359738368"   # 32 GiB (= 32 * 1024^3)

Or, if you prefer to set it in your shell environment (the daemon inherits it):

bash
export COCOINDEX_LMDB_MAP_SIZE=$((32 * 1024 * 1024 * 1024))   # 32 GiB

The map size is read when the daemon starts, so restart it to pick up the change, then re-index:

bash
ccc daemon restartccc index

This manual step is temporary. Once cocoindex#2108 lands, the map size grows automatically when needed and COCOINDEX_LMDB_MAP_SIZE won't be necessary.

Legacy: Environment Variables

If you previously configured cocoindex-code via environment variables, the cocoindex-code MCP command still reads them and auto-migrates to YAML settings on first run. We recommend switching to the YAML settings for new setups.

Environment VariableYAML Equivalent
COCOINDEX_CODE_EMBEDDING_MODELembedding.model in global_settings.yml
COCOINDEX_CODE_DEVICEembedding.device in global_settings.yml
COCOINDEX_CODE_ROOT_PATHRun ccc init in your project root instead
COCOINDEX_CODE_EXCLUDED_PATTERNSexclude_patterns in project settings.yml
COCOINDEX_CODE_EXTRA_EXTENSIONSinclude_patterns + language_overrides in project settings.yml

Telemetry

cocoindex-code sends anonymous usage telemetry through CocoIndex so we can see how the tool is used in aggregate and prioritize improvements. The events identify themselves as application: cocoindex-code.

We do not collect your source code, file paths, queries, search results, embeddings, settings, or any other content from your codebase or environment.

To opt out, set:

bash
export COCOINDEX_DISABLE_USAGE_TRACKING=1

Large codebase / Enterprise

Teams indexing large or multiple repositories can share CocoIndex indexes across developers. Enterprise features include deduplication across branches.

If indexing fails with MDB_MAP_FULL, raise the LMDB map size. See MDB_MAP_FULL: Environment mapsize limit reached under Troubleshooting.

For help with remote setup, email [email protected].

Contributing

We welcome contributions. This project uses uv for development. CI checks lint, formatting, types, and tests for every PR. Run the same checks locally before opening a PR; failed pre-commit checks are the most common cause of red CI on incoming PRs.

1. Install the dev dependencies

After installing uv, sync the project. This installs everything the checks need — including prek, a fast pre-commit runner, plus Ruff, mypy, and pytest:

bash
uv sync

2. Run all checks before every PR

Run the full hook suite across all files — this is exactly what CI runs:

bash
uv run prek run --all-files

It runs trailing-whitespace/end-of-file fixes, Ruff lint (--fix) and format, uv.lock validation, mypy type checking, and the pytest suite. Fix anything it reports (Ruff auto-fixes most lint/format issues for you), re-run until it passes, then push.

3. (Optional) Run automatically on each commit

To have the same checks run on every git commit, install the git hook once:

bash
uv run prek install

For more details, see our contributing guide.

License

Apache-2.0

來源:README.md,提交 5676897

工具

1

版本歷史

1
  1. v0.2.43最新Nov 6, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分
  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分