semble README

The project's README from github.com/MinishLab/semble. As one markdown file: README.md.

semble logo
Fast and Accurate Code Search for Agents
Uses ~99% fewer tokens than grep+read

Package version Codecov License - MIT

Quickstart • CLI • MCP Server • Installation • Benchmarks

Semble is a code search library built for agents. It returns the exact code snippets they need instantly, using ~99% fewer tokens than grep+read. Indexing and searching a full codebase end-to-end takes under a second, matching the retrieval quality of a code-specialized transformer while indexing ~340x faster and querying ~17x faster (see benchmarks). Everything runs on CPU with no API keys, GPU, or external services. Use it as an MCP server, a CLI tool via AGENTS.md, or a dedicated sub-agent, and any coding agent (Claude Code, Cursor, Codex, OpenCode, etc.) gets instant access to any repo.

Quickstart

Your agent queries Semble in natural language (e.g. "How is authentication handled?") and gets back only the relevant code snippets, without grepping or reading full files.

The fastest way to get started is the interactive installer. Install uv, then run:

uv tool install semble
semble install

semble install detects installed coding agents such as Claude Code, Codex, and OpenCode, and then lets you choose which integrations to enable:

To undo the setup, run semble uninstall.

For manual setup instructions (MCP config per agent, AGENTS.md snippet, sub-agent files), see the installation docs.

Updating Semble
uv tool upgrade semble   # upgrade
uv cache clean semble    # for MCP users (restart your MCP client after)
Unattended install

For sandboxed or scripted environments, skip the prompts with --agent and, optionally, --type:

semble install --agent claude --type mcp subagent --yes

--agent accepts one or more agent ids (e.g. claude, codex, pi); --type accepts mcp, instructions, subagent, or all (default: all); --yes skips the confirmation prompt (requires --agent for a fully non-interactive run).

Main Features

CLI

Semble also ships as a standalone CLI. This is useful in scripts or anywhere you want search results without an MCP session. Indexes are built and cached on first run, and invalidated automatically when files change.

# Search a local repo (index is built and cached automatically)
semble search "authentication flow" ./my-project

# Search a remote repo (cloned on demand)
semble search "save model to disk" https://github.com/MinishLab/model2vec

# Limit results
semble search "save model to disk" ./my-project --top-k 10

# Search docs/config/everything instead of just code
semble search "deployment guide" ./my-project --content docs   # or: config, all

# Find code similar to a known location
semble find-related src/auth.py 42 ./my-project

# Show only the first N lines of each result's snippet (0 = path/line range only)
semble search "authentication flow" ./my-project --max-snippet-lines 10

--content accepts code (default), docs, config, or all. path defaults to the current directory when omitted; git URLs are accepted. If semble is not on $PATH, use uvx --from "semble[mcp]" semble in its place. semble --version (or -V) prints the installed version.

Controlling which files are indexed

Semble reads .gitignore and .sembleignore files to determine which files to index. Both files use standard gitignore syntax and their patterns are merged. .sembleignore lets you add semble-specific rules without touching .gitignore. Rules are applied recursively, so a .sembleignore in a subdirectory applies to that subtree.

Excluding files: add patterns the same way you would in .gitignore:

# .sembleignore
generated/     # exclude generated dir
*.pb.go.       # exclude Go protobuf files

Including non-default extensions: prefix the extension pattern with ! to force-include files that semble wouldn't index by default:

# .sembleignore
!*.proto       # include Protobuf files
!*.cob         # include COBOL files

Semble also always skips a set of well-known non-source directories regardless of ignore files (e.g. node_modules/, .venv/, dist/, build/, __pycache__/, and similar).

Savings

semble savings shows how many tokens semble has saved across all your searches:

semble savings
  Semble Token Savings
  ════════════════════════════════════════════════════════════════════════

  Total saved:  ~714.2M tokens  (94%)
  Total calls:  14.3k
  Efficiency:  ███████████████████████░  94%

  By Period
  ────────────────────────────────────────────────────────────────────────
  Period             Calls           Saved  Ratio
  ────────────────────────────────────────────────────────────────────────
  Today                198    ~1.4M tokens  ███████████████████████░  95%
  Last 7 days        13.1k  ~707.2M tokens  ███████████████████████░  94%
  All time           14.3k  ~714.2M tokens  ███████████████████████░  94%

  By Call Type
  ────────────────────────────────────────────────────────────────────────
  #     Call type            Calls  Share
  ────────────────────────────────────────────────────────────────────────
  1.    search               14.1k  ████████████████    99%
  2.    find_related           205  █░░░░░░░░░░░░░░░     1%
  ════════════════════════════════════════════════════════════════════════

Savings are calculated as follows: for each call, semble records the total character count of the unique files containing returned chunks and the character count of the snippets returned. Estimated tokens saved is (file chars − snippet chars) / 4 (4 chars per token). This is a conservative estimate: the baseline is reading matched files in full, which is how coding agents often explore unfamiliar code.

Storage

By default, your Semble savings statistics and any saved indexes are stored in the OS cache folder (~/Library/Caches/semble/ on macOS, ~/.cache/semble/ on Linux, %LOCALAPPDATA%\semble\Cache\ on Windows). To override this location you can supply an environment variable SEMBLE_CACHE_LOCATION which should be the full path to the target cache location e.g. ~/my-folder/my-caches/semble.

Files larger than 1 MB are skipped during indexing to keep index builds lean. Skipped files are reported as a warning at index time. If you work with large generated or ingested documents, you can raise (or lower) this limit with the SEMBLE_MAX_FILE_BYTES environment variable (in bytes).

On first use, Semble also downloads the embedding model from Hugging Face and caches it in the standard Hugging Face cache (~/.cache/huggingface/ by default, or $HF_HOME if set); this only happens once and requires network access.

Use semble clear to remove cached data: semble clear index (saved indexes), semble clear savings (usage stats), semble clear orphans (indexes for repos no longer present on disk), or semble clear all (everything).

Library usage

Semble can also be used as a Python library for programmatic access, useful when building custom tooling or integrating search directly into your own code.

from semble import ContentType, SembleIndex

# Index a local directory (code only, the default)
index = SembleIndex.from_path("./my-project")

# Index docs and prose (markdown, rst, etc.)
index = SembleIndex.from_path("./my-project", content=ContentType.DOCS)

# Index everything (code, docs, and config)
index = SembleIndex.from_path("./my-project", content=[ContentType.CODE, ContentType.DOCS, ContentType.CONFIG])

# Index code and docs together
index = SembleIndex.from_path("./my-project", content=[ContentType.CODE, ContentType.DOCS])

# Index a remote git repository
index = SembleIndex.from_git("https://github.com/MinishLab/model2vec")

# Search the index with a natural-language or code query
results = index.search("save model to disk", top_k=3)

# Find code similar to a specific result
related = index.find_related(results[0], top_k=3)

# Each result exposes the matched chunk
result = results[0]
result.chunk.file_path   # "model2vec/model.py"
result.chunk.start_line  # 127
result.chunk.end_line    # 150
result.chunk.content     # "def save_pretrained(self, path: PathLike, ..."

MCP Server

Semble runs as an MCP server so agents can search any codebase directly as a native tool call. Repos are indexed on demand and cached; local paths are re-indexed automatically on file changes.

Tool Description
search Search a codebase with a natural-language or code query. Pass repo as a local path or an https:// git URL and content as code, docs, config, or all (default: code).
find_related Given a file path and line number, return chunks semantically similar to the code at that location.

For per-agent setup instructions, see the installation docs.

Benchmarks

We benchmark quality and speed across ~1,250 queries over 63 repositories in 19 languages (left), and token efficiency against grep+read at equivalent recall levels (right).

Speed vs quality Token efficiency: recall vs. retrieved tokens

The quality benchmark (left) scores retrieval quality (NDCG@10) against total latency; semble matches the quality of the 137M-parameter CodeRankEmbed while indexing 340x faster. The token efficiency benchmark (right) measures how many tokens each method needs to reach a given recall level; semble uses 99% fewer tokens on average and hits 97% recall at only 2k tokens, while grep+read needs a full 100k context window to reach 85%. See benchmarks for per-language results, ablations, and full methodology.

How it works

Semble splits each file into code-aware chunks using tree-sitter, then scores every query against the chunks with two complementary retrievers: static Model2Vec embeddings using the code-specialized potion-code-16M-v2 model for semantic similarity, and BM25 for lexical matches on identifiers and API names. The two score lists are fused with Reciprocal Rank Fusion (RRF).

After fusing, results are reranked with a set of code-aware signals:

Ranking signals
  • Adaptive weighting. Symbol-like queries (Foo::bar, _private, getUserById) get more lexical weight, while natural-language queries stay balanced between semantic and lexical retrievers.
  • Definition boosts. A chunk that defines the queried symbol (a class, def, func, etc.) is ranked above chunks that merely reference it.
  • Identifier stems. Query tokens are stemmed and matched against identifier stems in a chunk, giving an additional weight to chunks that contain them. For example, querying parse config boosts chunks containing parseConfig, ConfigParser, or config_parser.
  • File coherence. When multiple chunks from the same file match the query, the file is boosted so the top result reflects broad file-level relevance rather than a single out-of-context chunk.
  • Noise penalties. Test files, compat//legacy/ shims, example code, and .d.ts declaration stubs are down-ranked so canonical implementations surface first.

Because the embedding model is static with no transformer forward pass at query time, all of this runs in milliseconds on CPU.

Indexes are cached to disk automatically on the first search. On subsequent runs, Semble walks the file tree and compares modification times; added, removed, or changed files are reindexed incrementally, without rebuilding the rest of the index. A full rebuild only happens if the indexing settings change (e.g., after a semble upgrade that changes the model, chunking, or cache format). In MCP mode, the index is checked and refreshed automatically as files change, so results stay current across the session.

Using a custom model

If you would like to use another model, you can set your SEMBLE_MODEL_NAME environment variable to a local path or Hugging Face repository. This path is read verbatim, and should contain a Model2Vec compatible model. This is particularly useful if you can't access Hugging Face at runtime.

Acknowledgements

Thanks to Greptile for providing free access to their AI code review platform.

License

MIT

Citing

If you use Semble in your research, please cite the following:

@software{minishlab2026semble,
  author       = {{van Dongen}, Thomas and Stephan Tulkens},
  title        = {Semble: Fast and Accurate Code Search for Agents},
  year         = {2026},
  publisher    = {Zenodo},
  doi          = {10.5281/zenodo.19785932},
  url          = {https://github.com/MinishLab/semble},
  license      = {MIT}
}

semble (MinishLab/semble)

Searching Database…

6.2K ·GitHub
这是什么?Semble 是一个为编程智能体打造的代码搜索库。它会针对查询直接返回准确相关的代码片段,不需要智能体用 grep 查找再逐个读取完整文件,相比 grep+read 大约能少用 99% 的 token。
它是命令行工具、MCP 服务器,还是两者都是?两者都是,另外还提供一个 Python 库。你可以把它作为 MCP 服务器运行,供智能体当作工具调用;也可以作为独立的命令行工具使用;还可以安装为专用子智能体,让其使用 AGENTS.md/CLAUDE.md 指令。
如何安装和设置?先安装 uv,然后运行 `semble install`。交互式安装程序会检测已安装的编程智能体(如 Claude Code、Codex、OpenCode 等),并让你选择要启用的集成项(MCP 服务器、AGENTS.md 指令、子智能体)。如需卸载,运行 `semble uninstall`。
运行它需要 API 密钥、GPU 或外部服务吗?不需要。所有运算都在 CPU 上完成,无需 API 密钥、GPU 或任何外部服务;唯一的要求是安装时需要 uv,以及首次从 Hugging Face 下载一次嵌入模型(需要联网)。
对可索引的文件有限制吗?默认会跳过大于 1 MB 的文件(可通过 SEMBLE_MAX_FILE_BYTES 配置);会遵循 .gitignore/.sembleignore 规则;并且始终跳过 node_modules、.venv、dist、build 等已知的非源码目录。
它支持哪些编程智能体?支持任何兼容 MCP 的智能体,包括 Claude Code、Cursor、Codex、OpenCode 和 VS Code。
支持哪些操作系统?支持 macOS、Linux 和 Windows,每个系统的默认缓存路径都列在文档中。
Semble 把索引和使用数据存在哪里?索引和节省量统计数据都保存在本地的操作系统缓存文件夹中(例如 Linux 上的 ~/.cache/semble/),可通过 SEMBLE_CACHE_LOCATION 环境变量进行配置。
Semble 究竟如何对搜索结果排序?它先用 tree-sitter 把文件切分成理解代码结构的片段,再分别用静态 Model2Vec 嵌入和 BM25 为片段打分,接着通过倒数排名融合把两者的结果合并,最后根据定义匹配加分、标识符词干匹配、文件内容连贯性等信号重新排序,并对测试文件和遗留文件施加噪声扣分。
它与 grep+read 相比,速度和准确性如何?Semble 为一个典型仓库建立索引约需 500 毫秒,在 CPU 上回答一次查询约需 1 毫秒。它只用 2k token 就能达到 97% 的召回率,而 grep+read 需要完整的 100k token 上下文窗口才能达到 85% 的召回率。它的检索质量(NDCG@10 为 0.854)与一个 1.37 亿参数的代码专用 Transformer 模型相当。
我能索引远程仓库,而不是本地文件夹吗?可以。命令行和 MCP 搜索工具都接受本地路径或 https:// Git 地址,作为要索引和搜索的仓库。
我能更换它使用的嵌入模型吗?可以。将 SEMBLE_MODEL_NAME 环境变量设置为包含 Model2Vec 兼容模型的本地路径或 Hugging Face 仓库即可。
Creator
MinishLab
Size
6.5 MB
Stars
6.2K
Age
6mo
Commits · 90 Days