How semantic_search_nodes_tool Works: Semantic Code Search in code-review-graph
semantic_search_nodes_tool is an MCP tool that performs meaning-based search across code graph nodes by comparing natural language queries against vector embeddings using cosine similarity.
The semantic_search_nodes_tool is a core component of the tirth8205/code-review-graph project, an MCP (Model Context Protocol) implementation that builds a searchable graph representation of your codebase. This tool enables developers to locate specific functions, classes, and files using natural language descriptions rather than exact identifier matches, bridging the gap between human intent and code structure.
What Is semantic_search_nodes_tool?
At its core, semantic_search_nodes_tool is a specialized utility defined in src/mcp/tools/semanticSearchNodesTool.ts that exposes semantic search capabilities to MCP clients. Unlike traditional text search that matches substrings or regular expressions, this tool understands the semantic meaning of your query by leveraging vector embeddings generated from the source code, documentation, and metadata of each node in the graph.
How semantic_search_nodes_tool Works Internally
The tool operates through a multi-stage pipeline that transforms raw source code into searchable vector representations.
Node Indexing and Corpus Generation
When the code graph is built, the indexer traverses the repository and generates a textual corpus for every node. According to the implementation in src/mcp/indexer.ts and src/mcp/graph.ts, this corpus includes:
- The node's fully qualified identifier (e.g.,
src/utils/math.ts::add) - The complete source code or a distilled summary
- JSDoc, TypeDoc, or other documentation comments
- Associated tags such as "utility" or "test"
Embedding Generation
The textual corpus for each node is sent to an embedding model via src/mcp/embeddingsProvider.ts. By default, the tool uses the OpenAI text-embedding-3-small model to generate high-dimensional vectors that capture semantic meaning. These embeddings are stored in the graph's SQLite backing store for fast retrieval.
Query Processing and Similarity Search
When you invoke semanticSearchNodesTool(query), the tool converts your natural language query into an embedding using the same model. It then performs a nearest-neighbor search using cosine similarity against all stored node embeddings. The implementation filters results based on a configurable similarity threshold and sorts them by descending relevance score.
Result Shaping and Caching
Each matching node is wrapped in a NodeSearchResult object defined in src/mcp/types.ts, containing the node's ID, a code snippet or docstring, and the similarity score. The tool maintains an intelligent caching layer that preserves embeddings for unchanged nodes, automatically refreshing vectors only when the underlying source code is modified.
Source Code Architecture
The semantic search functionality is distributed across several key files in the tirth8205/code-review-graph repository:
-
src/mcp/tools/semanticSearchNodesTool.ts– Contains the core implementation of the semantic search algorithm, including embedding lookup, similarity computation, and caching logic. -
src/mcp/graph.ts– Defines theNodeobjects, indexing logic, and SQLite storage handling for persisting vector embeddings. -
src/mcp/indexer.ts– Traverses the codebase to extract documentation and comments, building the textual corpus used for embedding generation. -
src/mcp/embeddingsProvider.ts– Provides the wrapper around the OpenAI embedding API used by the tool to generate vectors. -
src/mcp/types.ts– Contains TypeScript definitions forNodeSearchResultand related interfaces returned by the search tool.
Usage Examples
The following examples demonstrate how to import and use the tool in TypeScript applications:
// Import the tool from the MCP entry point
import { semanticSearchNodesTool } from '@code-review-graph/mcp';
// Basic semantic search for JWT validation logic
const results = await semanticSearchNodesTool('function that validates JWT tokens');
// Display the top 3 matches with similarity scores
results.slice(0, 3).forEach(r => {
console.log(`🔎 ${r.nodeId} (score=${r.score.toFixed(2)})`);
console.log(r.snippet);
console.log('---');
});
// Advanced configuration with result limiting and threshold tuning
const results = await semanticSearchNodesTool('read the configuration file', {
maxResults: 5,
minScore: 0.45, // Only return hits with similarity >= 0.45
});
if (results.length === 0) {
console.log('⚠️ No relevant nodes found.');
}
// Integration example within a VS Code extension
import { queryGraphTool } from '@code-review-graph/mcp';
import { semanticSearchNodesTool } from '@code-review-graph/mcp';
export async function onSearchCommand(query: string) {
const matches = await semanticSearchNodesTool(query, { maxResults: 10 });
// Convert matches into VS Code locations for UI display
const locations = matches.map(m => ({
uri: queryGraphTool('uri_of_node', m.nodeId),
range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },
tooltip: `Score ${m.score.toFixed(2)}`,
}));
// Display locations in the quick-pick UI...
}
Summary
- semantic_search_nodes_tool is an MCP tool that enables natural language search over code graphs by comparing vector embeddings using cosine similarity.
- The tool processes queries through
src/mcp/tools/semanticSearchNodesTool.ts, utilizing OpenAI'stext-embedding-3-smallmodel by default viasrc/mcp/embeddingsProvider.ts. - Node embeddings are generated from combined source code, documentation, and metadata during the indexing phase handled by
src/mcp/indexer.ts. - Results are returned as
NodeSearchResultobjects containing node IDs, code snippets, and similarity scores, with intelligent caching to avoid recomputing unchanged nodes. - Configuration options include
maxResultsto limit output andminScoreto filter by relevance threshold.
Frequently Asked Questions
How does semantic_search_nodes_tool differ from traditional text search?
Traditional text search relies on substring matching or regular expressions against identifiers and file contents, requiring you to know exact function names or patterns. In contrast, semantic_search_nodes_tool uses vector embeddings to understand the conceptual meaning of your query, allowing you to find relevant code using descriptions like "function that refreshes user tokens" even when the actual function is named renewAuthSession.
What embedding model does semantic_search_nodes_tool use?
According to the source code in src/mcp/embeddingsProvider.ts, the tool defaults to the OpenAI text-embedding-3-small model for generating high-dimensional vectors. This model balances performance and accuracy for code search tasks, though the architecture supports swapping providers through the embeddings provider interface.
Can I configure the similarity threshold for search results?
Yes, the tool accepts a minScore parameter in its options object that sets the minimum cosine similarity threshold for returned results. Values range from 0 to 1, where higher values require stricter semantic matches. You can also use maxResults to limit the number of matches returned regardless of their scores.
Where are the vector embeddings stored?
The embeddings are persisted in a SQLite database managed by the graph layer defined in src/mcp/graph.ts. This backing store enables fast nearest-neighbor searches without re-embedding the entire codebase on every query, and the caching mechanism in src/mcp/tools/semanticSearchNodesTool.ts ensures only modified nodes get re-indexed.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →