file-indexer-mcp

file-indexer-mcp

An HTTP MCP server that indexes large documents into exact-line-numbered sections, enabling AI models to locate, read, summarize, and edit parts of a document without ingesting the whole file.

Category
Visit Server

README

file-indexer

An HTTP MCP server that breaks large documents into an exact-line-numbered section index, so a small local model can locate, read, summarize and edit one part of a document at a time — without ever ingesting the whole file.

Formats: markdown, plain text, HTML, PDF.

Why

A 207k-token document does not fit in a 32k-context model. Uploading it is not the answer; finding the right 1,600 tokens is. The index is built by plain extraction — never by the model — so it is exact and effectively free:

745,247 chars / 207k tokens / 8,079 lines  →  129 sections in 234ms, largest 1,666 tokens
find("tslib")  →  section s112, lines 6971-7034, ~1,610 tokens   (zero model tokens spent)

Retrieval is BM25 over the index and costs nothing. The model only ever sees the span it asked for.

How a model uses it

Question Tool Cost
What's in this file? outline 0 tokens
Where is X? find 0 tokens
Read just that part read_section / read_span one section
Process the whole file part by part next_unit one unit per call
Summarize the file summarize_file map-reduce, reports coverage
Add something at section X edit_section backed up, restorable

Sections carry both own and subtree sizes, so a model can tell a 32-token heading from the 11k-token chapter beneath it before committing to a read. Documents with no headings still get a navigable index: HTML falls back to <section>/<article>, then batched repeating rows, then synthetic packing — such sections are marked synthetic and shown as (auto).

summarize_file returns a coverage fraction and an explicit capped/dropped_sections list. A summary that silently skips most of a document reads exactly like a good one, so under-coverage is reported rather than hidden.

Tools

Tool Description
index_file Build or refresh one document's index; incremental, milliseconds
index_all Index every supported document under the workspace
index_status Whether a document is indexed, and whether it changed on disk since
list_documents Indexable documents with size and indexed state
outline Table of contents: section ids, depth, titles, line spans, sizes
find Locate sections by keyword — zero-token BM25, no model call
read_section Read one section's own text (or one chunk of it)
read_span Read an arbitrary line range verbatim
next_unit Walk a document sequentially, one readable unit per call
summarize_section Summarize one section or its subtree; cached
summarize_file Whole-document map-reduce summary with a coverage figure
edit_section Insert/replace/delete at a section id — 7 explicit modes
edit_replace Unique-match search/replace, with a whitespace-tolerant fallback
list_backups / restore_backup Every write is backed up first
health Model endpoint, configured model, indexed document count

edit_section modes are explicit about subsections, because picking the wrong boundary silently misplaces text: append (end of own text, before subsections), append_subtree (after all of them), prepend, replace_body, replace_subtree, replace_all, delete.

PDF

A PDF has no lines. Its text is extracted once to a sidecar under .fileindex/text/, and every line number reported for a PDF refers to that extracted text, not the PDF. Sections also carry start_page/end_page:

s2  #  Preface           (lines 47-121, ~1122 tok, p.4-5)
s7  #  List of Figures   (lines 490-662, ~2493 tok, p.15-18) [2 chunks]

Structure comes from PDF bookmarks when present, then a font-size heuristic, then page grouping. PDF is read-only — the edit tools refuse it.

Run it

cp .env.example .env      # set WORKSPACE_HOST_DIR to the directory you want indexed
./start.sh

start.sh runs the container as the owner of WORKSPACE_HOST_DIR. This matters: the editor writes atomically (temp file + rename), so a root container would rewrite an edited document as root:root and lock its owner out of their own file.

The workspace is mounted read-writeedit_section/edit_replace can create, modify or delete anything under it. Scope it to the documents you actually want editable.

Summarization uses a local model over an OpenAI-compatible endpoint (llama.cpp/llama-swap by default, Ollama optional). Point LLAMACPP_URL at an already-loaded instance rather than letting a second process load its own copy — two copies of the same model will exhaust a small GPU.

Adding a format

parsers.py is a registry mapping extension to a parser returning list[dict] sections shaped {title, depth, start_line, end_line, heading_lines}. A new line-based format is one module plus one registry entry, and inherits the heading-less fallback for free.

PDF is the exception: it has no lines, so parsers.extract_pdf() does extraction and section detection together and returns text that docindex.build() writes to a sidecar and indexes instead.

Licence

MIT — see LICENSE.

PDF extraction uses PyMuPDF, which is AGPL-3.0. That only matters if you redistribute this server; it is not a concern for local or private-network use. Everything else is the Python standard library plus the MCP SDK.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured