Directory Indexer MCP

Semantic search over your files, served to your AI assistant

Directory Indexer turns folders into a knowledge base your AI assistant can actually search. Notes, code, configs: ask about topics, patterns, or examples and get results from your real files, ranked by meaning instead of filename. Self-hosted, incremental, and local-first.

Claude Desktop · Cursor · Cline · OpenCode · GitHub Copilot

GitHub · MIT License

directory-indexer
$ npx directory-indexer@latest index ./WorkNotes
Found 1,284 files to process (checking for changes...)
Indexed 1,284 files, skipped 0, 0 failed
$ npx directory-indexer@latest search "how do tokens expire"
Found 2 results:
1. notes/auth-guide.md       Score: 0.82 (2 chunks)
2. api/session-handlers.ts   Score: 0.74 (1 chunk)

Install. Index. Ask.

  1. 1

    Install

    Node 18+ is the only requirement. Every command below also works through npx if you would rather not install.

    npm install -g directory-indexer@latest
  2. 2

    Start the services

    Qdrant stores vectors, Ollama generates embeddings on your machine. One docker command each, plus the embedding model.

    docker run -d --name qdrant -p 127.0.0.1:6333:6333 \
      -v qdrant_storage:/qdrant/storage qdrant/qdrant
    docker run -d --name ollama -p 127.0.0.1:11434:11434 \
      -v ollama:/root/.ollama ollama/ollama
    docker exec ollama ollama pull nomic-embed-text
  3. 3

    Index your directories

    Walks each tree, chunks, embeds, and stores. Searching comes after this has run once; re-runs only touch what changed.

    npx directory-indexer@latest index ./WorkNotes ./Projects
  4. 4

    Connect your assistant

    Add one entry to Claude Desktop, Cursor, Cline, OpenCode, or GitHub Copilot and restart it. From here you never touch the CLI: you just ask.

    "mcpServers": {
      "directory-indexer": {
        "command": "npx",
        "args": ["directory-indexer@latest", "serve"]
      }
    }

Ask about topics. Get the file that answers.

Filename search and grep stop at exact strings. Directory Indexer embeds every chunk of every supported file, so a question like "how do we handle retries" surfaces the doc that explains backoff, the config that tunes it, and the module that implements it, however those files are named.

Markdown, plain text, code, and config formats are indexed today; PDF and Office documents are on the roadmap.

one question, three phrasings, same file
$ npx directory-indexer@latest search "connection pooling setup"
1. infra/database.md         Score: 0.79
$ npx directory-indexer@latest search "why is pgbouncer in the stack"
1. infra/database.md         Score: 0.75
$ npx directory-indexer@latest search "db connection limits under load"
1. infra/database.md         Score: 0.71
Embeddings match intent, so phrasing stops mattering

A server your assistant knows how to drive.

Directory Indexer is an MCP server. Point Claude Desktop, Cursor, Cline, OpenCode, or GitHub Copilot at it and the tools appear, with descriptions that tell the model when to index, when to search, and when to read a matched file in full. You never touch the CLI again: you ask in plain language, the model calls the tools, and the answer comes back with the file cited.

the same question, inside your assistant
you › how do tokens expire in our api?
 ai › search("token expiry")
      1. notes/auth-guide.md       Score: 0.82
      2. api/session-handlers.ts   Score: 0.74
 ai › get_content("notes/auth-guide.md", chunk 2)
 ai › "Access tokens last 24 hours and refresh on use; the
      rotation logic lives in session-handlers.ts:112."
Your assistant searches, reads the match, and answers with the file cited
mcp config
{
  "mcpServers": {
    "directory-indexer": {
      "command": "npx",
      "args": ["directory-indexer@latest", "serve"]
    }
  }
}
One entry in your assistant's MCP configuration
search

Natural-language search across everything indexed, with optional workspace scoping.

similar_files

Find files related to a file your assistant already has in hand.

get_content

Read a whole file, or just the chunk range that matched.

get_chunk

Pull one specific indexed chunk by ID for precise citation.

server_info

Health, stats, indexed directories, and available workspaces.

index

Index or refresh directories on request. Only changed files are reprocessed.

delete_index

Remove a directory's index entirely. Gated behind a DISABLE_DESTRUCTIVE flag for cautious deployments.

Focused search areas, one index.

Group directories into named workspaces and your assistant can scope a search to a project, a team's docs, or anything else, instead of fishing through everything you have indexed.

Define them once as environment variables; server_info lists what is available so the model picks the right scope on its own.

workspaces in the same MCP config
{
  "mcpServers": {
    "directory-indexer": {
      "command": "npx",
      "args": ["directory-indexer@latest", "serve"],
      "env": {
        "WORKSPACE_NOTES": "/Users/pete/WorkNotes",
        "WORKSPACE_PROJECTS": "/Users/pete/Projects"
      }
    }
  }
}

Re-index everything once. After that, only changes.

Every file gets a content hash and a modification time. Re-running the index touches only what changed, cleans up files you deleted, and respects your .gitignore. Interrupt it mid-run and nothing corrupts; pick up where you left off.

second run, nothing to do
$ npx directory-indexer@latest index ./WorkNotes
Found 1,284 files to process (checking for changes...)
Indexed 0 files, skipped 1,284, cleaned up 0 deleted files, 0 failed
$ npx directory-indexer@latest search "retry backoff" --limit 3
Found 3 results ranked by relevance
Changed files are detected by mtime, then verified by hash

Your files stay yours.

With the default Ollama embeddings, file content never leaves your machine: embeddings are generated locally and stored in your own Qdrant instance. Prefer hosted speed? Point it at OpenAI's embedding API instead; the choice is yours per deployment. There are no accounts and no telemetry, and the whole thing is MIT-licensed source you can read.

Setup options, including native installs
Local-first embeddings Self-hosted storage Path-validated reads No accounts No telemetry Open source, MIT

Stop grepping. Start asking.

Free and open source under MIT. One npm package: a CLI for indexing and an MCP server for your assistants.