Skip to main content
Glama
dakshp26

PDFDashboardWithMCP

by dakshp26

PDF Dashboard With MCP

Upload PDFs, extract text with PyMuPDF or GLM-OCR (Ollama), and ask questions against the document with a local Ollama model. No API keys.

Features

  • PDF extraction: PyMuPDF for text layers; GLM-OCR when the PDF is scanned or image-only

  • Per-document RAG: each upload gets its own Chroma collection

  • Local chat: LangChain agent with inline citations; choose any installed Ollama model from the dropdown

  • Markdown viewer: read extracted text, preview chunks, download markdown

Related MCP server: RAG MCP Server

Prerequisites

Setup

1. Clone the repository

git clone https://github.com/dakshp26/PDFDashboardWithMCP.git
cd PDFDashboardWithMCP

2. Install dependencies

uv sync

3. Pull Ollama models

ollama pull qwen2.5:3b       # chat (or another chat model)
ollama pull nomic-embed-text # embeddings
ollama pull glm-ocr          # OCR for scanned PDFs

4. Run the app

uv run streamlit run app/main.py

Open http://localhost:8501 in your browser.

Usage

  1. Upload PDF: open Upload PDF, select a file, wait for extraction to finish

  2. Chat: open Chat, pick the PDF and an Ollama model, ask questions

Project Structure

app/
├── main.py                       # Entry point, page navigation
├── app_pages/
│   ├── landing.py                # Home page
│   ├── process_pdf_upload.py     # Upload + pipeline UI
│   ├── pdf_library.py            # Browse uploaded PDFs (read-only viewer)
│   └── process_pdf.py            # Viewer + chat UI
└── process_pdf/
    ├── extract.py                 # PDF → Markdown (pymupdf4llm + GLM-OCR)
    ├── pipeline.py                # Extraction pipeline with live progress
    ├── rag.py                     # Chunking, embeddings, Chroma persistence
    └── agent.py                   # LangChain agent with retriever tool
mcp_server/
└── server.py                     # MCP server (list_documents, get_document)
data/                             # Runtime data (gitignored)
├── process_pdf/                  # Saved PDFs and extracted markdown
└── process_chroma/               # Chroma vector collections (one per PDF)
NOTE

File-by-file breakdown, execution order, and data flow:APP_STRUCTURE.md.

Pages

Page

What it does

Home

Links and setup summary

Upload PDF

Run extraction (text layer, OCR fallback, chunking, embedding); download markdown

PDF Library

Open past uploads; view markdown and chunk previews without re-running extraction

Chat

Query an indexed PDF with citations

Extraction progress shows in an st.status block. After processing, the Chroma collection lives in data/process_chroma/ and loads on the next run without re-extracting.

MCP Server

Two tools for MCP clients (Claude Desktop, Cursor, Claude Code):

  • list_documents: indexed document collections

  • get_document(document, query): semantic search over a collection

Add to claude_desktop_config.json (Windows: %APPDATA%\Claude\claude_desktop_config.json) or use .mcp.json in the project root:

{
  "mcpServers": {
    "PDFDashboardWithMCP": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/PDFDashboardWithMCP", "mcp_server/server.py"]
    }
  }
}

Add to .cursor/mcp.json in the project root or global ~/.cursor/mcp.json:

{
  "mcpServers": {
    "PDFDashboardWithMCP": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/PDFDashboardWithMCP", "mcp_server/server.py"]
    }
  }
}

Project-scoped .mcp.json in the repo root keeps the server tied to this repo:

{
  "mcpServers": {
    "PDFDashboardWithMCP": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/PDFDashboardWithMCP", "mcp_server/server.py"]
    }
  }
}

Claude Code reads .mcp.json when you open the project.

Replace /absolute/path/to/PDFDashboardWithMCP with your clone path.

Ollama must be running with nomic-embed-text pulled before the MCP server can load collections.

Tech Stack

Component

Library

UI

Streamlit

PDF extraction

langchain-pymupdf4llm, PyMuPDF

OCR fallback

Ollama glm-ocr

Embeddings

Ollama nomic-embed-text

Vector store

Chroma (langchain-chroma)

LLM / agent

Ollama chat model (e.g. qwen2.5:3b), LangChain

Package manager

uv

MCP server

mcp[cli]

Available Tools

2 tools
get_documentA

Search a document collection for chunks relevant to a query.

Args: document: Collection name as returned by list_documents. query: Natural-language question or search string.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
documentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. 'Search' implies a read-only, non-destructive operation, but the description does not explicitly confirm this, nor does it mention any limitations or side effects. It adds no behavioral details beyond the basic operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences plus a two-item arg list. It front-loads the main action and provides all necessary param semantics in a compact, scannable format. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter search tool with an output schema, the description provides the core context: what it searches, what a valid 'document' is, and the format of the query. It could be more explicit about read-only behavior, but the search operation is inherently non-destructive. The reference to list_documents completes the workflow context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema offers zero description coverage for the parameters, but the description compensates by defining 'document' as the collection name returned by list_documents and 'query' as a natural-language question or search string. This fully clarifies both parameters with useful cross-tool context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Search a document collection for chunks relevant to a query' – a specific verb ('search') plus resource ('document collection') and result type ('chunks'). It also references sibling list_documents, distinguishing this as the search-within-collection tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The args section explicitly says 'Collection name as returned by list_documents,' which gives a clear prerequisite workflow. It implies when this tool should be used: after listing available documents. However, it does not explicitly state when not to use it or name alternatives beyond the implicit reference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_documentsA

List all document collections available in the vector store.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavioral disclosure. 'List all' implies a read-only, non-mutating operation, and 'available' suggests real-time availability. It does not mention pagination or limits, but the presence of an output schema reduces the need to detail return values.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence that directly states the function. It is front-loaded with the verb and resource, containing no filler or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no parameters, no annotations, and an existing output schema), the description is complete. It clearly identifies the scope and resource, and the sibling tool name provides context for differentiation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and the schema coverage is 100% (vacuously). The description adds no parameter-specific detail, but since there are no parameters, the baseline score of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List') and the resource ('document collections available in the vector store'). It distinguishes from the sibling tool 'get_document' by implying a collection-level listing rather than retrieving a single document.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is used to enumerate document collections, but it does not explicitly state when to prefer this over the sibling 'get_document' or any exclusions. For a zero-parameter listing tool, this is acceptable but not fully explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 2 tool updatesv0.1.0
    • First observedget_document
    • First observedlist_documents

TDQS

A4.1/5.0
Disambiguation5/5

The two tools have clearly distinct purposes: list_documents enumerates collections, while get_document searches within a specified collection. There is no ambiguity about which to use for a given task.

Naming Consistency4/5

Both tools follow the verb_noun pattern, but list_documents uses plural while get_document uses singular. This minor inconsistency does not hinder readability or predictability.

Tool Count3/5

With only two tools, the server feels thin for a PDF dashboard. While it covers listing and searching, the small number may not justify a dedicated server for many use cases.

Completeness2/5

The domain appears to be document retrieval, but the surface lacks essential operations like uploading, deleting, or retrieving full documents. The get_document tool only returns chunks, leaving significant gaps for common workflows.

Maintenance

ActivityInactive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Transforms PDF collections into a searchable knowledge base using TF-IDF indexing and proximity matching. It enables users to search documents, retrieve specific page content, and manage document libraries through natural language via MCP clients.
    5
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides tools for ingesting documents into a local vector database and retrieving relevant information via semantic search, enabling retrieval-augmented generation for MCP clients.
    6
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dakshp26/PDFDashboardWithMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server