Sunstone Weave: Local Semantic Code Search
Sunstone Weave gives MCP clients local semantic search over code and documentation folders on your machine, using CPU embeddings and returning relevant passages with file paths and line ranges.
Index or update a folder with
weave_folder; only changed files are re-read, first run downloads a 133 MB encoder, and long runs continue in the background.Search woven folders with plain-language or code queries using
weave_search; returns nearest passages with file, line range, and centered-cosine score, with optional result count and folder filter.List indexed folders, file counts, passage counts, and running weaves with
weave_list.Delete a folder's index with
weave_forgetwithout touching its files.Run locally on macOS, Linux, and Windows with Node 20+; no network requests after the first encoder download.
Work with any MCP client, including Claude Code, VS Code, Cursor, Claude Desktop, and Windsurf.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Sunstone Weave: Local Semantic Code Searchsearch my repo for where pairing lines are parsed into url, key and name"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
blackwindow-weave-mcp
Semantic search over the folders on your machine, for any MCP client. The server cuts source code and documentation into passages, embeds them with Motherlode, a 33M-parameter code-search encoder, on your CPU, and answers questions such as "where is a pairing line parsed into url, key and name" with file paths, line ranges and the passages themselves.
The only network requests are to huggingface.co on the first run: six requests, which leave five files, 133,752,819 bytes, in the cache. With the files cached, a run makes none.
This is the weave from Black Window and the Sunstone VS Code extension, packaged for clients that speak the Model Context Protocol. It runs on macOS, Linux and Windows with Node 20 or later.
Install
Install it once from a terminal, before adding it to a client. This installs the package and ONNX Runtime and prints the version once the runtime has loaded:
npx -y blackwindow-weave-mcp@0.1.2 --versionOn GitHub's hosted runners, from an empty npm cache, this first install took 7 to 13 s on Linux and macOS and 55 to 69 s on Windows. Clients wait a limited time for a server to start (the MCP SDK's default is 60 s), and a client that stops waiting in the middle of an install can leave a broken copy in npm's cache (see Troubleshooting). Once installed, the server starts in under 3 s.
Keep the version in the client's configuration the same as here. With a version given, npx starts the copy it installed; with the bare name, npx (npm 11) looks for a newer version on every start and installs it while the client waits.
On Linux x64, ONNX Runtime also downloads 236 MB of CUDA libraries during the install. This server runs on the CPU and never loads them, so you can skip them:
ONNXRUNTIME_NODE_INSTALL=skip npx -y blackwindow-weave-mcp@0.1.2 --versionRelated MCP server: MCP Codebase RAG Server
Add it to a client
macOS and Linux
Claude Code:
claude mcp add weave -- npx -y blackwindow-weave-mcp@0.1.2 --folder /path/to/your/repoVS Code, in .vscode/mcp.json:
{
"servers": {
"weave": { "type": "stdio", "command": "npx", "args": ["-y", "blackwindow-weave-mcp@0.1.2", "--folder", "${workspaceFolder}"] }
}
}Cursor, Claude Desktop, Windsurf and most other clients:
{
"mcpServers": {
"weave": { "command": "npx", "args": ["-y", "blackwindow-weave-mcp@0.1.2", "--folder", "/path/to/your/repo"] }
}
}Windows
On Windows npx is a batch file, which a client can only start through cmd /c. Claude Code:
claude mcp add weave -- cmd /c npx -y blackwindow-weave-mcp@0.1.2 --folder C:\path\to\your\repoCursor, Claude Desktop, Windsurf and most other clients:
{
"mcpServers": {
"weave": { "command": "cmd", "args": ["/c", "npx", "-y", "blackwindow-weave-mcp@0.1.2", "--folder", "C:/path/to/your/repo"] }
}
}In VS Code the same command and args go under servers in .vscode/mcp.json, with "type": "stdio".
Installed globally
npm install -g blackwindow-weave-mcp@0.1.2 installs a blackwindow-weave-mcp command, which a client can start
directly (cmd /c blackwindow-weave-mcp on Windows). To run from this repository instead of npm, replace
blackwindow-weave-mcp@0.1.2 in the arguments with github:space-bacon/blackwindow-weave-mcp.
option | meaning |
| Weave this folder when the server starts. Repeatable. Optional: the model can call |
| Where the encoder and the indexes live. Default |
| Print the version and exit. |
Platforms
Every push runs CI on Linux (x64 and arm64), Windows (x64) and macOS (Apple silicon),
each with Node 20, 22 and 24. Each job runs the stdio smoke test below from a checkout. It then installs the packed
package through npx from an empty npm cache, starts it the way a client does and weaves a folder. On Windows it also
starts it through cmd /c. Last, it installs the package globally and starts it by its command. Other platforms,
such as Windows on Arm, Intel Macs and Alpine Linux, are not tested.
Troubleshooting
The client times out when it first starts the server, or the server stops with Cannot find module ... transformers.node.mjs. A first install was interrupted, usually by a client that stopped waiting, and npm kept the
half-installed copy. Delete npm's npx cache and install again from a terminal with the line under Install:
macOS and Linux:
rm -rf ~/.npm/_npxWindows (PowerShell):
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\npm-cache\_npx"
Updating. Install the new version from a terminal as above, then change the version in the client's configuration.
Tools
tool | what it does |
| Index a folder, or bring its index up to date. Only files whose size or modification time changed are read again. A run longer than 25 s returns at once and continues in the background. |
| The passages nearest a plain-language or code query, with file, line range and score. Searches the folders woven in this session, or every woven folder if none was, or one folder when asked. |
| The woven folders with their file and passage counts, and any weave still running. |
| Delete a folder's index. The folder's files are not touched. |
Measured
On an Apple M2 Ultra (24 CPU cores, Node 24.4.1), through the MCP SDK's own stdio client, in test/smoke.mjs:
folder | files | passages | first weave | second weave | search |
this package's | 6 | 42 | 3.8 s, with the encoder's download | 0.013 s | 5 to 6 ms |
the Sunstone repository | 57 | 1,367 | 20.2 s | 0.014 s | 6 ms |
Embedding runs at about 68 passages a second on that machine, so a repository of 10,000 passages takes about two and a half minutes the first time. Those figures are one run each on one machine. The smoke test's three questions about this package's own source each return the expected file first; they are a check that the pieces are wired together, not a measure of retrieval quality. For retrieval quality see the model card.
How it works
Files. A git work tree is listed by git, so
.gitignoreholds. Any other folder is walked, skippingnode_modules, build output, virtual environments, lock files and minified files. Files over 1 MB and files that read as binary are skipped. JSON and XML are left out: in the Sunstone repository, result files underbench/results/took ranks 2 and 3 of the question above when they were included.Passages. Code is cut at definitions into passages of about 700 characters, each labelled with the nearest definition. Prose is cut at paragraphs and sentences into passages of about 420 characters. The chunkers are Black Window's.
Encoder.
onnx/model.onnx(fp32) through transformers.js and ONNX Runtime on the CPU, CLS pooling.Centring. Every vector has the model's shipped mean (
centring/mean_shipped.json) subtracted and is brought back to unit length, so a score is a cosine after centring.Search. Exact: every passage is scored. Before answering, a folder not checked in the last 30 s is brought up to date if fewer than 200 of its files changed; otherwise the answer says the index is stale.
Index. One per folder under
<cache>/index/: a Float32 matrix and a JSONL of passages, named by a manifest that is written to a temporary file and renamed into place, so an interrupted write leaves the previous index. An index that cannot be read is moved aside rather than overwritten.
Licence
Business Source License 1.1 with an internal-use grant. You may use it for any internal purpose, including commercial development on your own or your employer's code, with no limit on seats. You may not offer it to others as a hosted search service or ship it inside a product you supply. On 15 September 2030 it becomes Apache-2.0. The encoder is downloaded under its own licence, which has the same shape. For other terms, write to burton@sunstonenorth.com.
Available Tools
4 toolsweave_folderWeave a folderAIdempotent
Index a folder on this machine (source code and docs) for semantic search, or bring its index up to date: only files that changed since the last run are read again. Call it once per project. The first run downloads the 33M-parameter encoder (133 MB) and embeds every passage on the CPU; a run longer than 25 s continues in the background and weave_list reports its progress.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path of the folder, or a path relative to the server's working directory |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: incremental re-indexing (only changed files re-read), a 133 MB / 33M-parameter model download on first run, CPU-bound embedding, and background continuation past 25 s. This is consistent with idempotentHint=true and readOnlyHint=false, and no contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the primary action before the operational caveats (download, runtime, backgrounding). Every sentence carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, no-output-schema tool, the description covers the mutation semantics, idempotent behavior, latency characteristics, and where progress is reported. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter and schema coverage is 100%, so the schema already documents the absolute-vs-relative path semantics. The description adds nothing about the path argument itself, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource ('index a folder ... for semantic search') plus the secondary mode ('bring its index up to date'), which cleanly separates it from the read-only siblings weave_search and weave_list. An agent can route to it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Call it once per project' gives an explicit usage cadence, and the reference to weave_list for progress tells the agent where to look while a run is in flight. It does not state when-not to use it or contrast directly with weave_search/weave_forget, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
weave_forgetForget a woven folderADestructiveIdempotent
Delete a folder's index from this machine. The folder's own files are not touched.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | The woven folder |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is partly covered. The description adds genuinely useful context beyond that: what is destroyed (the index) and what is explicitly preserved (the folder's files), which softens the otherwise alarming destructive hint. It does not discuss reversibility or how the index can be rebuilt.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and followed by the critical scope limitation. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, no-output tool whose annotations carry the safety profile, the description covers the essentials. The only real gap is behavior on non-woven folders and whether the index can be regenerated, which matters given the destructive hint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With a single parameter and 100% schema description coverage, the schema already documents 'path' as the woven folder. The description adds no format, path-shape, or example beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource — deleting a folder's index — and immediately disambiguates 'forget' from file deletion with 'the folder's own files are not touched.' It is clear on its own, though it does not explicitly contrast itself with siblings like weave_folder or weave_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus alternatives, no prerequisites, and no mention of the sibling tools. The intended usage (removing a folder from the index) is only inferable from the purpose sentence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
weave_listList woven foldersARead-only
List the folders this server has indexed, with their file and passage counts.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety and scope profile is covered. The description adds that results are limited to folders 'this server has indexed' and that file and passage counts are included, but says nothing about ordering, pagination, or behavior on an empty index.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with no filler, front-loaded with the action and resource, and it still conveys the returned metrics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only, parameterless listing tool with annotations covering safety and no output schema, the description adequately conveys both scope and what is returned. Only ordering/pagination detail is absent, which is minor here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless tool applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (folders) plus the scope of what is listed ('this server has indexed'). It does not differentiate itself from siblings like weave_search or weave_folder, so an agent must infer the boundary itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the purpose: enumerate indexed folders before, say, searching or forgetting within one. However, there is no explicit when-to-use, no when-not-to-use, and no sibling alternative named, so the routing guidance is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
weave_searchSearch the weaveARead-only
Search the woven folders in plain language: where something is defined, handled, configured or explained. Returns the nearest passages with their file, line range and centred-cosine score. Use it before grep when you do not know the identifier or file name.
| Name | Required | Description | Default |
|---|---|---|---|
| k | No | How many passages (default 8) | |
| query | Yes | What to find, in plain words or code | |
| folder | No | Search only this woven folder |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely new behavioral context: the search is semantic/ranked and returns the nearest passages with file, line range, and a centred-cosine score. It says nothing about indexing freshness, latency, or empty-result behavior, so it falls short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with the purpose first, return shape second, and routing advice last. No filler, no restatement of the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by describing the return payload (passages with file, line range, score). Combined with full schema coverage for parameters and safety annotations, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters (query, k, folder) are already documented in the schema with defaults and bounds. The description adds no syntax, format, or scoping guidance beyond that, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search the woven folders') and then sharpens the intent with concrete query types ('where something is defined, handled, configured or explained'), which tells an agent exactly what class of question this tool answers. It also distinguishes itself from sibling/adjacent tools by positioning against grep.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger condition ('when you do not know the identifier or file name') and names the alternative to use otherwise ('before grep'). The when-not case is implied by the same sentence, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
weave_folder - First observed
weave_forget - First observed
weave_list - First observed
weave_search
TDQS
Scored across 4 tools
Each tool maps to a distinct operation in the indexing lifecycle: index (weave_folder), query (weave_search), inspect (weave_list), and remove (weave_forget). There is no meaningful overlap, and the descriptions reinforce when to use each (e.g. search before grep).
The weave_ prefix is applied uniformly, giving a clear namespace. Suffixes are mostly verbs (search, list, forget) except weave_folder, which is a noun referring to the resource it indexes, a minor deviation but still readable and predictable.
Four tools is a tight, well-scoped set for a semantic-index server: create, query, enumerate, and delete. It is on the lean side with no configuration or content-retrieval tool, but each tool earns its place and nothing feels redundant.
The index lifecycle is fully covered: build/refresh (weave_folder), search (weave_search), list (weave_list), and delete (weave_forget), with re-indexing handled by weave_folder's incremental behavior. Minor gap: no tool to fetch a passage's or file's contents directly, so agents must fall back on other file-reading tools after a search hit.
Maintenance
Related MCP Connectors
Self-hosted AI workspace: semantic RAG document search, long-term memory, and AI chat via MCP.
1201Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Personal knowledge base MCP server with semantic search, auto-categorization, metadata extraction
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceClaude Context is an MCP plugin that adds semantic code search to Claude Code and other AI coding agents, giving them deep context from your entire codebase.12 npm12,624MIT
- FlicenseAqualityDmaintenanceProvides semantic vector search over local codebases via MCP, enabling hybrid search (dense + sparse + RRF) for any MCP client like GitHub Copilot or Claude Desktop.58-
- AlicenseNot gradedqualityDmaintenanceEnables semantic code search across indexed code folders using vector embeddings, with support for multiple embedding providers and automatic file watching. Provides an admin UI and integrates with MCP clients for natural language code queries.1MIT

cocoindex-codeofficial
AlicenseAqualityAmaintenanceembedded code search engine CLI -AST based that just works - improves speed and efficiency for coding agent110,100 PyPI2,901Apache 2.0