# Add Semantic Code Search to Claude Code, Codex, and Cursor in 5 Minutes

> A step-by-step guide to wiring Octocode into your AI assistant as an MCP server: install, index, and connect Claude Code, Codex, Cursor or Windsurf.

Last week a friend sent me a screenshot. His AI assistant had just spent eleven tool calls and most of a context window hunting for a function he could have pointed it to in two seconds. "Is it always this dumb?" he asked.

It isn't. It's just navigating blind.

Out of the box, most AI coding tools navigate your project with text search — `grep`, `ripgrep`, glob patterns. That works fine on a toy repo and falls apart on a real one — not because grep can't find things, but because it finds too many. Two thousand unranked matches, and the agent burns its context reading the wrong twelve files. The fix is to let it narrow structurally before it reads anything, through a real retrieval tool over MCP — and the fastest one I know to set up is [Octocode](https://github.com/muvon/octocode). We wrote about [why semantic code search beats grep](https://octomind.run/blog/octocode-mcp-semantic-code-search) already — this post is the part where you actually plug it in.

Five minutes, start to finish. These are the steps.

## What You're Building

Octocode is an open-source (Apache 2.0) MCP server written in Rust. It parses your code with tree-sitter into real symbols — functions, classes, imports — builds a knowledge graph of how those pieces relate, and exposes four tools to any MCP-compatible client:

| Tool                | What your agent gets                                                                             |
| ------------------- | ------------------------------------------------------------------------------------------------ |
| `semantic_search`   | Find code by meaning — "where do we validate tokens?" returns the function, not 300 keyword hits |
| `view_signatures`   | The structure of a file — signatures, classes, imports — without reading the whole thing         |
| `graphrag`          | Relationship queries — "what calls this?", "what does this import?"                              |
| `structural_search` | AST pattern matching — every `.unwrap()`, every `new` instantiation, specific shapes             |

(One optional extra: start the server with `--with-lsp="rust-analyzer"` — or your language's server — and it also exposes LSP tools: go-to-definition, find-references, hover docs — compiler-grade precision alongside the search tools.)

Once it's connected, your assistant stops grepping and starts navigating. That's the whole pitch.

One honest caveat before we start: if your repo is small enough that ripgrep already finds everything in one hop, this is overkill — keep using ripgrep. The setup below pays off when searches come back with hundreds of matches and your agent starts reading the wrong ones.

## Step 1: Install Octocode

One line on macOS, Linux, or Windows:

```bash
curl -fsSL https://raw.githubusercontent.com/Muvon/octocode/master/install.sh | sh
```

On a Mac, Homebrew works too:

```bash
brew install muvon/tap/octocode
```

Prefer to build it yourself? It's Rust, so:

```bash
cargo install --git https://github.com/Muvon/octocode
```

Confirm it landed:

```bash
octocode --version
```

## Step 2: Give It an Embedding Provider

Semantic search needs an embedding model to turn code into vectors. Octocode supports several providers, and the default recommendation is Voyage AI — partly because their free tier is genuinely generous (200M free tokens a month, which is more than enough for most projects):

```bash
export VOYAGE_API_KEY="your-voyage-api-key"
```

Grab a key at [voyageai.com](https://www.voyageai.com/). Prefer a provider you already pay for? Point Octocode at it:

```bash
# OpenAI
export OPENAI_API_KEY="your-key"
octocode config --code-embedding-model "openai:text-embedding-3-small"

# Jina AI
export JINA_API_KEY="your-key"
octocode config --code-embedding-model "jina:jina-embeddings-v3"

# Google
export GOOGLE_API_KEY="your-key"
octocode config --code-embedding-model "google:text-embedding-005"
```

On default macOS ARM builds, local embedding models are available too — useful if you'd rather no metadata ever leaves the machine. (More on the privacy model below.)

One optional extra: if you want Octocode's commit-message and review features later, set an LLM key as well — `export OPENROUTER_API_KEY="your-key"`. Not needed for search.

## Step 3: Index Your Project

Move into your repository and index it once:

```bash
cd /your/project
octocode index
# → Indexed 12,847 blocks across 342 files
```

This is the step people skip before wondering why search returns nothing. To be precise about which tools need it: `semantic_search` queries the index — no index, empty results. The other three read your source live — `graphrag` builds its graph lazily with tree-sitter, and `view_signatures` and `structural_search` parse files on demand — so they work either way. But semantic search is the tool your agent will reach for most, so index first. Octocode respects your `.gitignore`, so it won't crawl `node_modules`, build artifacts, or secrets.

Sanity-check it from the CLI before you wire anything up:

```bash
octocode search "authentication middleware"
# → src/middleware/auth.rs | Similarity 0.923
```

If that returns sensible files, the index is healthy and the MCP server will be too.

## Step 4: Connect Your AI Assistant

This is where it pays off. The MCP server is one command — `octocode mcp --path /your/project` — and every client wires it slightly differently.

### Claude Code

A single command registers it:

```bash
claude mcp add octocode -- octocode mcp --path /path/to/your/project
```

Restart your session and the four tools are available. Ask "where is rate limiting handled?" and watch it call `semantic_search` instead of spraying `grep`.

### Codex

Codex has the same one-command registration:

```bash
codex mcp add octocode -- octocode mcp --path /path/to/your/project
```

Or edit `~/.codex/config.toml` directly:

```toml
[mcp_servers.octocode]
command = "octocode"
args = ["mcp", "--path", "/path/to/your/project"]
```

Two traps specific to Codex. First, its config is **TOML, not JSON** — the table is `mcp_servers` with an underscore, and writing `[mcpServers.octocode]` out of JSON habit parses fine but is silently ignored. Second, if your embedding key lives in a shell profile Codex doesn't source, pass it explicitly: `codex mcp add octocode --env VOYAGE_API_KEY=your-key -- octocode mcp --path /path/to/your/project`.

### Cursor

Edit `~/.cursor/mcp.json` (or use Settings → MCP Servers):

```json
{
	"mcpServers": {
		"octocode": {
			"command": "octocode",
			"args": ["mcp", "--path", "/path/to/your/project"]
		}
	}
}
```

### Claude Desktop and Windsurf

Same JSON shape, different file:

```json
{
	"mcpServers": {
		"octocode": {
			"command": "octocode",
			"args": ["mcp", "--path", "/path/to/your/project"]
		}
	}
}
```

- **Claude Desktop (macOS):** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windsurf:** Settings → MCP

Octocode's docs cover [15+ clients](https://github.com/muvon/octocode/blob/master/doc/MCP_CLIENTS.md) — VS Code via Cline or Continue, Zed, Replit, and more — but the pattern never changes: it's always `command: "octocode"`, `args: ["mcp", "--path", "..."]`.

Working across several repos? One server can cover them all: `octocode mcp --multi --path /parent/dir` serves every git repository one level under that path, and each tool call picks its repo with a `project` argument.

### Octomind (the zero-setup path)

If you're using [Octomind](https://octomind.run) as your agent runtime, you don't do any of this. Octocode ships as a capability in the tap system and auto-activates when your message looks like a code-search task — semantic search becomes one of [several capabilities the runtime turns on only when needed](/docs/usage/16-token-efficiency), so you're not paying for the tool surface when you don't use it. Just run a developer agent:

```bash
octomind run developer:general
```

## What It Looks Like When It Works

Same question, before and after:

**Before** — grep path: "find the API error handling" → 891 matches → the agent reads eight files → greps again → reads four more → finally answers, ~20,000 tokens spent on navigation.

**After** — MCP path:

```
You: "Where is user authentication implemented?"
AI: (uses semantic_search) "Found in src/auth/login.rs. authenticate()
    validates credentials, generates a JWT, and stores the session in Redis."

You: "What files depend on the payment module?"
AI: (uses graphrag) "src/api/handlers/payment.rs imports payment/mod.rs,
    which is also used by src/workers/refund.rs and src/cron/billing.rs."
```

The difference isn't that grep couldn't have found the answer — it's that grep hands back an unranked pile and makes the agent do the ranking with its context window. Octocode narrows structurally first: signatures to see a file's shape without reading it, the graph to follow real edges instead of guessing, semantic search to rank by meaning. The agent spends its context budget reasoning about your code instead of finding it. (And the ranking holds up: on Octocode's own retrieval benchmark — 254 hand-annotated queries — code search puts the right file in the top 10 results 99.2% of the time.)

## A Note on Privacy

The question I get most: does my code get uploaded? Let me answer it precisely, because the honest answer is better than the vague one. The index lives on your machine, and **search never touches the network** — the MCP server answers every query locally. The one step that does is indexing: computing a vector for a chunk of code means sending that chunk to your embedding provider, the same way any embedding API works. It's used to compute the vector and nothing is stored or searchable remotely. If even that is more than your threat model allows, run the local embedding model (included in default macOS ARM builds) and nothing leaves the machine at all. Octocode also respects `.gitignore`, so the files you'd never want indexed are never indexed.

## Keep the Index Fresh

The one gotcha worth knowing: the index is a snapshot. If you've just merged a big branch and search feels stale, re-run `octocode index` — it's incremental, so it only processes what changed. Make it a habit, or wire it into a post-merge git hook and forget about it. (If results are still off after reindexing, I wrote a whole [Octocode MCP troubleshooting guide](https://octomind.run/blog/octocode-mcp-troubleshooting-indexing) for exactly that.)

## That's It

Install, set one API key, `octocode index`, register one MCP server in your client. Your AI assistant goes from grepping in the dark to navigating your architecture by meaning — across files, through the dependency graph, in milliseconds.

If you want the deeper "why this matters" version — token economics, embeddings, the lost-in-the-middle problem — read [Your AI Agent Wastes Most of Its Time Just Finding Code](https://octomind.run/blog/octocode-mcp-semantic-code-search). And if you want to understand how MCP tools plug into an agent in the first place, the [MCP Tools Deep Dive](https://octomind.run/blog/mcp-tools-deep-dive) covers the protocol end to end.

**[Get Octocode](https://github.com/muvon/octocode)** — give your agent eyes.
