添加Pdf读取mcp

This commit is contained in:
zqm
2025-10-22 16:24:07 +08:00
parent 0d8520123e
commit 64d1e220d4
48 changed files with 21213 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
// docs/.vitepress/config.mts
import { defineConfig } from 'vitepress';
export default defineConfig({
lang: 'en-US',
title: 'PDF Reader MCP Server',
description: 'MCP Server for reading PDF files securely within a project.',
lastUpdated: true,
themeConfig: {
logo: '/logo.svg', // Assuming logo is in docs/public
nav: [
{ text: 'Home', link: '/' },
{ text: 'Guide', link: '/guide/' },
{ text: 'API Reference', link: '/api/' },
{ text: 'Design', link: '/design/' },
{ text: 'Performance', link: '/performance/' },
{ text: 'Comparison', link: '/comparison/' },
],
sidebar: {
'/guide/': [
{
text: 'Introduction',
items: [
{ text: 'What is PDF Reader MCP?', link: '/guide/' },
{ text: 'Installation', link: '/guide/installation' },
{ text: 'Getting Started', link: '/guide/getting-started' },
],
},
// Add more guide sections later
],
'/api/': [
{
text: 'API Reference',
items: [{ text: 'Tool: read_pdf', link: '/api/read_pdf' }],
},
],
// Add sidebars for other sections
'/design/': [
{
text: 'Design',
items: [{ text: 'Philosophy', link: '/design/' }],
},
],
'/performance/': [
{
text: 'Performance',
items: [{ text: 'Benchmarks', link: '/performance/' }],
},
],
'/comparison/': [
{
text: 'Comparison',
items: [{ text: 'Other Solutions', link: '/comparison/' }],
},
],
},
socialLinks: [
{ icon: 'github', link: 'https://github.com/sylphlab/pdf-reader-mcp' },
{ icon: 'issues', link: 'https://github.com/sylphlab/pdf-reader-mcp/issues' }, // Add link to issues
],
footer: {
message: 'Released under the MIT License. Found this useful? Give us a star ⭐ on GitHub!', // Add call-to-action
copyright: `Copyright © ${new Date().getFullYear()} Sylph Lab`,
},
// Enable edit links
editLink: {
pattern: 'https://github.com/sylphlab/pdf-reader-mcp/edit/main/docs/:path',
text: 'Edit this page on GitHub',
},
},
// Enable markdown features
markdown: {
lineNumbers: true,
},
});

View File

@@ -0,0 +1,5 @@
**@sylphlab/pdf-reader-mcp**
---
# @sylphlab/pdf-reader-mcp

View File

@@ -0,0 +1,84 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Nothing yet.
## [0.3.9] - 2025-04-05
### Fixed
- Removed artifact download/extract steps from `publish-docker` job in workflow, as Docker build needs the full source context provided by checkout.
## [0.3.8] - 2025-04-05
### Fixed
- Removed duplicate `context: .` entry in `docker/build-push-action` step in `.github/workflows/publish.yml`.
## [0.3.7] - 2025-04-05
### Fixed
- Removed explicit `COPY tsconfig.json ./` from Dockerfile (rely on `COPY . .`).
- Explicitly set `context: .` in docker build-push action.
## [0.3.6] - 2025-04-05
### Fixed
- Explicitly added `COPY tsconfig.json ./` before `COPY . .` in Dockerfile to ensure it exists before build step.
## [0.3.5] - 2025-04-05
### Fixed
- Added `RUN ls -la` before build step in Dockerfile to debug `tsconfig.json` not found error.
## [0.3.4] - 2025-04-05
### Fixed
- Explicitly specify `tsconfig.json` path in Dockerfile build step (`RUN ./node_modules/.bin/tsc -p tsconfig.json`) to debug build failure.
## [0.3.3] - 2025-04-05
### Fixed
- Changed Dockerfile build step from `RUN npm run build` to `RUN ./node_modules/.bin/tsc` to debug build failure.
## [0.3.2] - 2025-04-05
### Fixed
- Simplified `build` script in `package.json` to only run `tsc` (removed `chmod`) to debug Docker build failure.
## [0.3.1] - 2025-04-05
### Fixed
- Attempted various fixes for GitHub Actions workflow artifact upload issue (`Error: Provided artifact name input during validation is empty`). Final attempt uses fixed artifact filename in upload/download steps.
## [0.3.0] - 2025-04-05
### Added
- `CHANGELOG.md` file based on Keep a Changelog format.
- `LICENSE` file (MIT License).
- Improved GitHub Actions workflow (`.github/workflows/publish.yml`):
- Triggers on push to `main` branch and version tags (`v*.*.*`).
- Conditionally archives build artifacts only on tag pushes.
- Conditionally runs `publish-npm` and `publish-docker` jobs only on tag pushes.
- Added `create-release` job to automatically create GitHub Releases from tags, using `CHANGELOG.md` for the body.
- Added version headers to Memory Bank files (`activeContext.md`, `progress.md`).
### Changed
- Bumped version from 0.2.2 to 0.3.0.

View File

@@ -0,0 +1,34 @@
# Comparison with Other Solutions
When an AI agent needs to access information within PDF files, several approaches exist. Here's how the PDF Reader MCP Server compares:
1. **Direct File Access by Agent:**
- **Feasibility:** Often impossible. PDFs are binary; LLMs typically process text. Sending raw binary data is usually not supported or useful.
- **Security:** Extremely risky if the agent has broad filesystem access.
- **Efficiency:** Impractical due to file size and format.
- **PDF Reader MCP Advantage:** Provides a secure, structured way to get _textual_ data from the binary PDF.
2. **Generic Filesystem MCP Server (like `@shtse8/filesystem-mcp`):**
- **Functionality:** Can read file _content_, but for PDFs, this would be the raw binary data, which is not directly useful to an LLM.
- **Security:** Offers similar path confinement benefits if implemented correctly.
- **Efficiency:** Inefficient for PDFs as it doesn't parse the content.
- **PDF Reader MCP Advantage:** Specializes in _parsing_ PDFs to extract meaningful text and metadata.
3. **External CLI Tools (e.g., `pdftotext`, `pdfinfo`):**
- **Functionality:** Can extract text and metadata.
- **Security:** Requires the agent host to execute arbitrary commands, potentially increasing security risks. Output might need further parsing.
- **Efficiency:** Involves process creation overhead for each command. Communication might be less streamlined than MCP.
- **Integration:** Requires the agent to know how to construct and interpret CLI commands and output, which can be brittle.
- **PDF Reader MCP Advantage:** Offers a dedicated, secure MCP interface with structured JSON input/output, better integration, and potentially lower overhead for frequent operations.
4. **Cloud-Based PDF APIs:**
- **Functionality:** Often provide rich features (OCR, conversion, etc.).
- **Security:** Requires sending potentially sensitive local files to a third-party service.
- **Efficiency:** Involves network latency and potential costs.
- **Integration:** Requires API keys and handling HTTP requests/responses.
- **PDF Reader MCP Advantage:** Operates entirely locally (for local files), enhancing security and privacy. No external network dependency for local operations.
**In summary, the PDF Reader MCP Server provides a balanced solution specifically tailored for AI agents needing secure, efficient, and structured access to PDF content within a local project context.**

View File

@@ -0,0 +1,37 @@
# Contributing to PDF Reader MCP Server
Thank you for your interest in contributing!
## How to Contribute
We welcome contributions in various forms:
- **Reporting Bugs:** If you find a bug, please open an issue on GitHub detailing the problem, steps to reproduce, and your environment.
- **Suggesting Enhancements:** Have an idea for a new feature or improvement? Open an issue to discuss it.
- **Pull Requests:** If you'd like to contribute code:
1. Fork the repository.
2. Create a new branch for your feature or bug fix (`git checkout -b feature/your-feature-name` or `bugfix/issue-number`).
3. Make your changes, ensuring they adhere to the project's coding style and principles (see `docs/principles.md`).
4. Add tests for any new functionality and ensure all tests pass (`npm test`).
5. Ensure code coverage remains high (`npm run test:cov`).
6. Make sure your code lints correctly (`npm run lint`).
7. Commit your changes using the [Conventional Commits](https://www.conventionalcommits.org/) standard (e.g., `feat: Add support for encrypted PDFs`, `fix: Correct page range parsing`).
8. Push your branch to your fork (`git push origin feature/your-feature-name`).
9. Open a Pull Request against the `main` branch of the original repository.
## Development Setup
1. Clone your fork.
2. Install dependencies: `npm install`
3. Build the project: `npm run build`
4. Run in watch mode during development: `npm run watch`
5. Run tests: `npm test` or `npm run test:watch`
## Code Style
Please ensure your code adheres to the formatting and linting rules defined in the project:
- Run `npm run format` to format your code with Prettier.
- Run `npm run lint` to check for ESLint issues.
Thank you for contributing!

View File

@@ -0,0 +1,26 @@
# Design Philosophy
The PDF Reader MCP Server is built upon several core principles:
1. **Security First:**
- **Context Confinement:** The absolute primary goal. All local file access _must_ be restricted to the directory (and its subdirectories) where the server process is launched. This prevents the AI agent from accessing unintended files on the user's system.
- **Path Validation:** Rigorous validation of all incoming paths using a dedicated `resolvePath` function ensures they are relative and resolve within the designated project root.
- **No Arbitrary Execution:** The server only performs PDF reading operations, not arbitrary file system modifications or command execution.
2. **Efficiency & Resourcefulness:**
- **Structured Data:** Instead of sending potentially huge raw PDF content (which is often impractical for LLMs), the server extracts specific, structured information (text, metadata, page count).
- **Targeted Extraction:** Allows requesting text from specific pages, minimizing the amount of data transferred and processed.
- **Asynchronous Operations:** Uses Node.js async I/O to avoid blocking the event loop during file access and PDF parsing.
3. **Simplicity & Ease of Integration:**
- **Single Tool Focus:** Consolidates functionality into a single `read_pdf` tool with clear parameters, making it easier for AI agents to learn and use.
- **Standard MCP:** Leverages the `@modelcontextprotocol/sdk` for standard communication and error handling.
- **Clear Schemas:** Uses Zod for defining and validating input, providing clear contracts for tool usage.
- **Multiple Invocation Methods:** Supports easy use via `npx` or Docker for straightforward deployment in various MCP host environments.
4. **Minimalism & Reliability:**
- **Minimal Dependencies:** Relies primarily on the robust and widely-used `pdfjs-dist` library for core PDF parsing, minimizing external failure points.
- **Clear Error Reporting:** Provides specific error messages when processing fails for a source, allowing the agent to understand the issue.

View File

@@ -0,0 +1,83 @@
# Getting Started
This guide assumes you have an MCP client or host environment capable of launching and communicating with the PDF Reader MCP Server.
## 1. Launch the Server
Ensure the server is launched with its **working directory set to the root of the project** containing the PDF files you want to access.
- **If installed via npm/pnpm:** Your MCP host might manage this automatically via `npx @sylphlab/pdf-reader-mcp`.
- **If running standalone:** `cd /path/to/your/project && node /path/to/pdf-reader-mcp/build/index.js`
- **If using Docker:** `docker run -i --rm -v \"/path/to/your/project:/app\" sylphlab/pdf-reader-mcp:latest`
## 2. Using the `read_pdf` Tool
The server provides a single primary tool: `read_pdf`.
**Tool Input Schema:**
The `read_pdf` tool accepts an object with the following properties:
- `sources` (Array<Object>, required): An array of PDF sources to process. Each source object must contain either a `path` or a `url`.
- `path` (string, optional): Relative path to the local PDF file within the project root.
- `url` (string, optional): URL of the PDF file.
- `pages` (Array<number> | string, optional): Extract text only from specific pages (1-based) or ranges (e.g., `'1-3, 5'`). If provided, `include_full_text` is ignored for this source.
- `include_full_text` (boolean, optional, default: `false`): Include the full text content of each PDF (only if `pages` is not specified for that source).
- `include_metadata` (boolean, optional, default: `true`): Include metadata and info objects for each PDF.
- `include_page_count` (boolean, optional, default: `true`): Include the total number of pages for each PDF.
_(See the [API Reference](./api/) (once generated) for the full JSON schema)_
**Example MCP Request (Get metadata and page count for one PDF):**
```json
{
"tool_name": "read_pdf",
"arguments": {
"sources": [{ "path": "./documents/report.pdf" }],
"include_metadata": true,
"include_page_count": true,
"include_full_text": false
}
}
```
**Example MCP Request (Get text from page 2 of one PDF, full text of another):**
```json
{
"tool_name": "read_pdf",
"arguments": {
"sources": [
{
"path": "./invoices/inv-001.pdf",
"pages": [2] // Get only page 2 text
},
{
"url": "https://example.com/whitepaper.pdf"
// No 'pages', so 'include_full_text' applies
}
],
"include_metadata": false,
"include_page_count": false,
"include_full_text": true // Applies only to the URL source
}
}
```
## 3. Understanding the Response
The response will be an array named `results`, with each element corresponding to a source object in the request array. Each result object contains:
- `source` (string): The original path or URL provided in the request.
- `success` (boolean): Indicates if processing this source was successful.
- `data` (Object, optional): Present if `success` is `true`. Contains the requested data:
- `num_pages` (number, optional): Total page count (if `include_page_count` was true).
- `info` (Object, optional): PDF information dictionary (if `include_metadata` was true).
- `metadata` (Object, optional): PDF metadata (if `include_metadata` was true).
- `page_texts` (Array<Object>, optional): Array of objects, each with `page` (number) and `text` (string), for pages where text was extracted (if `pages` was specified or `include_full_text` was true without `pages`).
- `error` (Object, optional): Present if `success` is `false`. Contains:
- `code` (string): An error code (e.g., `FileNotFound`, `InvalidRequest`, `PdfParsingError`, `DownloadError`, `UnknownError`).
- `message` (string): A description of the error.
_(See the [API Reference](./api/) (once generated) for detailed response structure and error codes.)_

View File

@@ -0,0 +1,22 @@
# Introduction
Welcome to the PDF Reader MCP Server documentation!
This server provides a secure and efficient way for AI agents (like Cline) using the Model Context Protocol (MCP) to interact with PDF files located within a user's project directory.
## What Problem Does It Solve?
AI agents often need information from PDFs (reports, invoices, manuals). Directly feeding PDF content is impractical due to format and size. This server offers specific tools to extract:
- Full text content
- Text from specific pages
- Metadata (author, title, etc.)
- Total page count
All interactions happen securely within the defined project boundaries.
## Core Principles
- **Security:** Confined file access.
- **Efficiency:** Structured data retrieval, avoiding large raw content transfer.
- **Simplicity:** Easy integration into MCP-enabled agent workflows.

View File

@@ -0,0 +1,58 @@
# Installation
## Prerequisites
- Node.js (>= 18.0.0 recommended)
- npm (comes with Node.js)
## Using npm (Recommended)
To use the server in your project or MCP host environment, install it as a dependency:
```bash
npm install @sylphlab/pdf-reader-mcp
```
## Running Standalone (for testing/development)
1. **Clone the repository:**
```bash
git clone https://github.com/sylphlab/pdf-reader-mcp.git
cd pdf-reader-mcp
```
2. **Install dependencies:**
```bash
npm install
```
3. **Build the project:**
```bash
npm run build
```
4. **Run the server:**
The server communicates via stdio. You'll typically run it from an MCP host.
```bash
node build/index.js
```
**Important:** Ensure you run this command from the root directory of the project containing the PDFs you want the server to access.
## Using Docker
A Docker image is available on Docker Hub.
```bash
docker pull sylphlab/pdf-reader-mcp:latest
```
To run the container, you need to mount the project directory containing your PDFs into the container's working directory (`/app`):
```bash
docker run -i --rm -v "/path/to/your/project:/app" sylphlab/pdf-reader-mcp:latest
```
Replace `/path/to/your/project` with the actual absolute path to your project folder.

View File

@@ -0,0 +1,26 @@
---
layout: home
hero:
name: 'PDF Reader MCP Server'
text: 'Securely Read PDFs via MCP.'
tagline: An MCP server enabling AI agents to read text, metadata, and page counts from PDF files within a project's context.
image:
src: /logo.svg
alt: PDF Reader MCP Logo
actions:
- theme: brand
text: Get Started
link: /guide/getting-started
- theme: alt
text: View on GitHub
link: https://github.com/sylphlab/pdf-reader-mcp
features:
- title: Secure Context
details: All operations are strictly confined to the project directory where the server is launched.
- title: Structured Data
details: Returns parsed text, metadata, and page counts in a structured format via MCP.
- title: Efficient & Focused
details: Uses pdfjs-dist for reliable parsing. Designed for integration with AI agent workflows.
---

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 [Your Name or Organization]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,41 @@
# Performance
Performance is a key consideration for the PDF Reader MCP Server, as slow responses can negatively impact the interaction flow of AI agents.
## Core Library: `pdfjs-dist`
The server relies on Mozilla's [pdf.js](https://mozilla.github.io/pdf.js/) (specifically the `pdfjs-dist` distribution) for the heavy lifting of PDF parsing. This library is widely used and generally considered performant for standard PDF documents. However, performance can vary depending on:
- **PDF Complexity:** Documents with many pages, complex graphics, large embedded fonts, or non-standard structures may take longer to parse.
- **Requested Data:** Extracting full text from a very large document will naturally take longer than just retrieving metadata or the page count. Requesting text from only a few specific pages is usually more efficient than extracting the entire text.
- **Server Resources:** The performance will also depend on the CPU and memory resources available to the Node.js process running the server.
## Asynchronous Operations
All potentially long-running operations, including file reading (for local PDFs), network requests (for URL PDFs), and PDF parsing itself, are handled asynchronously using `async/await`. This prevents the server from blocking the Node.js event loop and allows it to handle other requests or tasks concurrently (though typically an MCP server handles one request at a time from its host).
## Benchmarking (Planned)
_(Section to be added)_
Formal benchmarking is planned to quantify the performance characteristics of the `read_pdf` tool under various conditions.
**Goals:**
- Measure the time taken to extract metadata, page count, specific pages, and full text for PDFs of varying sizes and complexities.
- Compare the performance of processing local files vs. URLs (network latency will be a factor for URLs).
- Identify potential bottlenecks within the handler logic or the `pdfjs-dist` library usage.
- Establish baseline performance metrics to track potential regressions in the future.
**Tools:**
- We plan to use [Vitest's built-in benchmarking](https://vitest.dev/guide/features.html#benchmarking) (`bench` function) or a dedicated library like [`tinybench`](https://github.com/tinylibs/tinybench).
Benchmark results will be published in this section once available.
## Current Optimization Considerations
- **Lazy Loading:** The `pdfjs-dist` library loads pages on demand when `pdfDocument.getPage()` is called. This means that if only metadata or page count is requested, the entire document's page content doesn't necessarily need to be parsed immediately.
- **Selective Extraction:** The ability to request specific pages (`pages` parameter) allows agents to avoid the cost of extracting text from the entire document if only a small portion is needed.
_(This section will be updated with concrete data and findings as benchmarking is performed.)_

View File

@@ -0,0 +1,45 @@
# Performance
Performance is an important consideration for the PDF Reader MCP Server, especially when dealing with large or complex PDF documents. This page outlines the benchmarking approach and presents results from initial tests.
## Benchmarking Setup
Benchmarks are conducted using the [Vitest](https://vitest.dev/) testing framework's built-in `bench` functionality. The tests measure the number of operations per second (hz) for different scenarios using the `read_pdf` handler.
- **Environment:** Node.js (latest LTS), Windows 11 (as per user environment)
- **Test File:** A sample PDF located at `test/fixtures/sample.pdf`. The exact characteristics of this file (size, page count, complexity) will influence the results.
- **Methodology:** Each scenario is run for a fixed duration (1000ms) to determine the average operations per second. The benchmark code can be found in `test/benchmark/readPdf.bench.ts`.
## Initial Benchmark Results
The following results were obtained on 2025-04-07 using the setup described above:
| Scenario | Operations per Second (hz) | Relative Speed |
| :------------------------------- | :------------------------- | :------------- |
| Handle Non-Existent File | ~12,933 | Fastest |
| Get Full Text | ~5,575 | |
| Get Specific Page (Page 1) | ~5,329 | |
| Get Specific Pages (Pages 1 & 2) | ~5,242 | |
| Get Metadata & Page Count | ~4,912 | Slowest |
_(Higher hz indicates better performance)_
**Interpretation:**
- Handling errors for non-existent files is the fastest operation as it involves minimal I/O and no PDF parsing.
- Extracting the full text was slightly faster than extracting specific pages or just metadata/page count in this particular test run. This might be influenced by the specific structure of `sample.pdf` and potential caching mechanisms within the `pdfjs-dist` library.
- Extracting only metadata and page count was slightly slower than full text extraction for this file.
**Note:** These results are specific to the `sample.pdf` file and the testing environment used. Performance with different PDFs (varying sizes, complexities, versions, or structures) may differ significantly.
## Future Benchmarking Goals
Further benchmarks are planned to measure:
- **Parsing Time:** Time taken to load and parse PDFs of varying sizes (e.g., 1 page, 10 pages, 100 pages, 1000 pages).
- **Text Extraction Speed:** More detailed analysis across different page ranges and document structures.
- **Memory Usage:** Peak memory consumption during processing of different PDF sizes.
- **URL vs. Local File:** Performance difference between processing local files and downloading/processing from URLs.
- **Comparison:** Comparison with other PDF processing methods or libraries, if applicable.
Results will be updated here as more comprehensive testing is completed.

View File

@@ -0,0 +1,45 @@
# Development Principles
This project adheres to the following core principles, based on the provided TypeScript Project Development Guidelines:
## 1. Impact-Driven
The primary goal is to solve the real problem of AI agents needing access to PDF content securely and efficiently. Features are added to serve this core purpose.
## 2. Simplicity & Minimalism
We aim for the most direct approach:
- A single, consolidated `read_pdf` tool instead of multiple specific tools.
- Leveraging the robust `pdfjs-dist` library for core parsing.
- Avoiding unnecessary abstractions.
## 3. Functional Programming Style (Influences)
While not strictly functional, the code emphasizes:
- Pure helper functions where possible (like path resolution checks).
- Minimizing side effects within core logic (parsing doesn't alter files).
- Using standard asynchronous patterns (`async/await`) effectively.
## 4. Minimal Dependencies
- Core functionality relies on `@modelcontextprotocol/sdk` and `pdfjs-dist`.
- Development dependencies are standard tools (TypeScript, ESLint, Prettier, Vitest).
- Dependencies like `glob`, `zod`, `zod-to-json-schema` provide essential validation and utility.
- Unused dependencies inherited from the template (`diff`, `detect-indent`) have been removed.
## 5. Code Quality & Consistency
- **Strict TypeScript:** Using the strictest compiler options (`strict: true`, etc.).
- **Rigorous Linting:** Employing ESLint with recommended and strict type-checked rules.
- **Consistent Formatting:** Enforced by Prettier.
- **Comprehensive Testing:** Aiming for high test coverage (currently ~95%) using Vitest, with a 100% threshold configured.
## 6. Security Focus
- Path traversal prevention is critical. All file paths are resolved relative to the project root and validated.
## 7. No Sponsorship
This project does not accept financial contributions, and all related information has been removed.

View File

@@ -0,0 +1,5 @@
<!-- Placeholder Logo -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<rect width="100" height="100" fill="#cccccc"/>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="12" fill="#333333">LOGO</text>
</svg>

After

Width:  |  Height:  |  Size: 259 B

View File

@@ -0,0 +1,60 @@
# Testing Strategy
Robust testing is essential for ensuring the reliability, correctness, and security of the PDF Reader MCP Server. We employ a multi-faceted testing approach using Vitest.
## Framework: Vitest
We use [Vitest](https://vitest.dev/) as our primary testing framework. Its key advantages include:
- **Speed:** Fast execution powered by Vite.
- **Modern Features:** Supports ES Modules, TypeScript out-of-the-box.
- **Compatibility:** Familiar API similar to Jest.
- **Integrated Coverage:** Built-in support for code coverage analysis using `v8` or `istanbul`.
## Goals & Approach
Our testing strategy focuses on:
1. **High Code Coverage:**
- **Target:** 100% statement, branch, function, and line coverage.
- **Configuration:** Enforced via `thresholds` in `vitest.config.ts`.
- **Current Status:** ~95%. The remaining uncovered lines are primarily in error handling paths that are difficult to trigger due to Zod's upfront validation or represent extreme edge cases. This level is currently accepted.
- **Tool:** Coverage reports generated using `@vitest/coverage-v8`.
2. **Correctness & Functionality:**
- **Unit Tests:** (Currently minimal, focus is on integration) Could test utility functions like `pathUtils` in isolation.
- **Integration Tests:** The primary focus is testing the `read_pdf` handler (`test/handlers/readPdf.test.ts`) with mocked dependencies (`pdfjs-dist`, `fs`). These tests verify:
- Correct parsing of various input arguments (paths, URLs, page selections, flags).
- Successful extraction of full text, specific page text, metadata, and page counts.
- Handling of multiple sources (local and URL) within a single request.
- Correct formatting of the JSON response.
- Graceful error handling for invalid inputs (caught by Zod or handler logic).
- Correct error reporting for file-not-found errors.
- Correct error reporting for PDF loading/parsing failures (mocked).
- Proper handling of warnings (e.g., requested pages out of bounds).
- **Security:** Path resolution logic (`resolvePath`) is tested separately (`test/pathUtils.test.ts`) to ensure it prevents path traversal and correctly handles relative paths within the project root.
3. **Reliability & Consistency:**
- Tests are designed to be independent and repeatable.
- Mocking is used extensively to isolate the handler logic from external factors.
## Running Tests
Use the following npm scripts:
- **`npm test`**: Run all tests once.
- **`npm run test:watch`**: Run tests in an interactive watch mode, re-running on file changes.
- **`npm run test:cov`**: Run all tests and generate a detailed coverage report in the `./coverage/` directory (view `index.html` in that directory for an interactive report). This command will fail if coverage thresholds are not met.
## Test File Structure
- Tests reside in the `test/` directory, mirroring the `src/` structure.
- Handler tests are in `test/handlers/`.
- Utility tests are in `test/utils/`.
## Future Improvements
- Consider adding end-to-end tests using a test MCP client/host.
- Explore property-based testing for more robust input validation checks.