Nexla MCP Document Q&A Server

Nexla MCP Document Q&A Server

Enables querying PDF documents using natural language with grounded answers and source citations via a local RAG pipeline.

Category
访问服务器

README

Nexla Technical Assignment: MCP Document Q&A Server

This repository contains my implementation of a Model Context Protocol (MCP) server designed to provide document intelligence over PDF files. The server allows an AI client (such as Claude Desktop or the MCP Inspector) to query unstructured PDF documents and retrieve grounded answers with source citations.

I built the system using a local-first Python stack. All PDF parsing, vector search, and LLM inference run entirely on-device with zero external API calls.


1. System Design and Component Choices

When designing this system, I focused on creating a clean, modular pipeline with a clear separation of concerns between ingestion, retrieval, prompt orchestration, and tool exposure.

                      +-------------------+
                      |    MCP Client     |
                      | (Claude Desktop)  |
                      +---------+---------+
                                | stdio / JSON-RPC
                      +---------v---------+
                      |    MCP Server     |
                      |   (src/server.py) |
                      +----+---------+----+
                           |         |
         +-----------------+         +-----------------+
         |                                             |
+--------v---------+                         +---------v---------+
| Vector Retriever |                         | Active Metadata   |
| (ChromaDB +      |                         | Engine            |
|  MiniLM-L6-v2)   |                         | (Nexset Profile)  |
+--------+---------+                         +-------------------+
         |
         | Relevant Context
+--------v---------+
| RAG Generator    |
| (Ollama llama3.2)|
+------------------+

Component Selection Table

Layer Selection Justification
MCP Framework FastMCP Clean Python decorators for tool registration while adhering strictly to standard MCP JSON-RPC protocol
PDF Extraction PyMuPDF (fitz) High-speed C-backed page parsing. Benchmarked faster than pdfplumber and preserves page boundaries reliably
Embeddings sentence-transformers (all-MiniLM-L6-v2) Generates 384-dimensional dense vectors locally on CPU with minimal latency (~90MB model size)
Vector Store ChromaDB Persistent on-disk vector database using cosine distance metrics with zero extra server setup
Local LLM Ollama (llama3.2) Runs locally on CPU/GPU. Setting temperature to 0.1 ensures factual responses grounded strictly in context

2. Nexla Architecture Alignment

Nexla emphasizes metadata-driven integrations and virtualized data products called Nexsets. I structured this MCP server to reflect those core concepts:

Virtual Data Product Abstraction (Nexset Profiles)

Rather than treating PDFs as plain text strings, my ingestion pipeline computes a NexsetMetadataProfile for every document. It infers topic tags, extracts structural headings, counts words, and calculates estimated reading time.

Agents can inspect this schema using the get_nexset_schema tool before running queries.

Grounded Context Compounding

To prevent hallucinations, the generator constructs a strict system prompt. The LLM is instructed to answer questions using only the retrieved passages. If the context does not contain enough information, the model states that explicitly. Each source reference includes the document title, page number, and vector relevance score.


3. Tool Reference

The server exposes four MCP tools for AI agents:

Tool Name Purpose Key Inputs Expected Output
query_documents Grounded Q&A over indexed PDFs question (str), document_filter (optional str) Answer string + list of source citations (document, page, score)
get_nexset_schema Inspect auto-generated Nexset profile document_name (str) Metadata JSON with topic tags, word metrics, headings, and governance tags
list_documents List index registry & statistics None JSON summary of indexed documents, total pages, and chunk counts
get_document_summary Executive document summary document_name (str) High-level summary of main topics and referenced page numbers

4. Setup and How to Run

Requirements

  • Python 3.10 or higher
  • Ollama installed and running (ollama pull llama3.2)

Installation Steps

  1. Clone the repository and enter the directory:

    git clone https://github.com/Bhanunikhil/MCP-Server_Nexla.git
    cd MCP-Server_Nexla
    
  2. Set up a virtual environment and install dependencies:

    python -m venv venv
    source venv/bin/activate  # On Windows: .\venv\Scripts\activate
    pip install -r requirements.txt
    
  3. Place PDF documents in the data/ folder.

Running the Server

  • Standard MCP Server (for Claude Desktop or standard clients):

    python -m src.server
    
  • Interactive Command Line Tool:

    python ask.py
    
  • MCP Web Inspector:

    fastmcp dev src/server.py
    

5. Technical Challenges Addressed in My Implementation

When building this MCP server, I focused on solving common technical obstacles that arise when integrating unstructured enterprise PDF data with AI models. The table below outlines these challenges and the specific technical solutions I engineered in this codebase:

Real-World Challenge Problem Impact Technical Solution Implemented
Nested Directory Hierarchies Enterprise document drops use nested subfolders (data/dept_a/, data/0/), causing flat file parsers to miss data. Implemented recursive pattern discovery (data/**/*.pdf) in ingestion.py to traverse complex folder structures automatically.
Vector Memory Overflow on Large Files Indexing multi-hundred page PDFs in a single call causes memory spikes and payload exceptions in vector stores. Implemented batched upserts (batch_size = 100) combined with deterministic chunk hashing (doc_name::page::chunk) in retriever.py for memory-safe, idempotent indexing.
Metadata Invisibility & Token Waste Basic RAG models treat PDFs as dumb text strings, forcing LLMs to spend expensive context tokens just to discover document structure. Built the NexsetMetadataProfile engine and exposed get_nexset_schema in server.py, allowing AI agents to inspect structural headings, topic tags, and read metrics instantly.
Context Fragmentation from Naive Chunking Slicing text at rigid character limits cuts sentences in half, causing fragmented context and degraded embedding quality. Built a sentence-aware chunker in ingestion.py that finds period (. ) and newline (\n) boundaries before breaking text.

6. My Workflow and Use of AI Tooling

I used AI coding tools during development to speed up repetitive tasks while staying actively involved in architecture, debugging, and system tuning.

Engineering Decisions & AI Matrix

Task / Focus Area AI Assistance My Engineering Decisions & Overrides
Directory Discovery Generated flat data/*.pdf search Modified to recursive globbing (data/**/*.pdf) to support real enterprise nested folder datasets
Vector Indexing Generated unbatched collection.add() calls Refactored to batch upserts (batch_size = 100) with deterministic chunk IDs (doc_name::page::chunk) to prevent memory crashes
Metadata Engine Defaulted to plain text chunking Designed NexsetMetadataProfile abstraction to auto-infer topic categories, heading structures, and read metrics
Windows Console I/O Hardcoded Unicode emojis in print statements Sanitized console print statements to standard text to avoid UnicodeEncodeError on Windows cp1252 terminals

6. Project Layout

MCP-Server_Nexla/
├── README.md               # Documentation and technical overview
├── interaction_log.md      # Sample Q&A interactions with source citations
├── requirements.txt        # Python dependencies
├── pyproject.toml          # Project packaging settings
├── .env.example            # Environment configuration template
├── ask.py                  # CLI script for interactive testing
├── data/                   # Directory containing sample PDF documents
├── src/
│   ├── config.py           # Configuration loading logic
│   ├── ingestion.py        # PDF text extraction, chunking, and metadata engine
│   ├── retriever.py        # Embedding generation and ChromaDB vector search
│   ├── generator.py        # Ollama RAG prompt handling
│   ├── tools.py            # MCP tool definitions
│   └── server.py           # FastMCP entry point
└── tests/
    └── test_tools.py       # Unit tests

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选