# 📄 PDF MCP Server

A production-ready **Model Context Protocol (MCP) server** for PDF operations. This server enables AI assistants like Claude Desktop and VS Code Copilot to interact with PDF files through a standardized interface.

---

## 🆕 What's New in v2.1

### 🎯 Advanced PDF Analysis Tools

**Two powerful new tools for precise PDF analysis:**

1. **🔍 analyze-pdf-page** - Extract page dimensions, margins, and layout information
   - Get dimensions in points, inches, and millimeters
   - Automatic margin detection for standard page sizes
   - MediaBox and CropBox information
   - Essential for layout-aware PDF operations

2. **📍 detect-text-position** - OCR-level text position detection
   - Precise bounding boxes for every text element
   - Font name and size information
   - Text search and filtering capabilities
   - Perfect for intelligent watermark placement

**Use Cases:**
- 🎯 Smart watermark positioning that avoids text
- 📐 Layout-aware content addition
- 🔍 Content analysis and structure detection
- 📊 Automated document processing

**[See advanced tools documentation →](ADVANCED_TOOLS.md)**

---

## 🎉 What's New in v2.0

### 🚀 Major Improvements

1. **🔍 Intelligent File Path Resolution**
   - Just use the filename! No need for full paths
   - Automatically searches Downloads, Documents, Desktop
   - Supports relative paths, absolute paths, and file:// URIs
   - Example: `"document.pdf"` instead of `"/Users/you/Downloads/document.pdf"`

2. **🎯 Perfect Watermark Centering**
   - Watermarks now appear exactly in the center of pages
   - Fixed rotation-aware positioning
   - All position presets (corners, center) work flawlessly

3. **📥 Automatic File Downloads**
   - Tools return downloadable PDF files
   - Works seamlessly in Claude Desktop and VS Code
   - Base64-encoded for instant access

4. **🔒 Strict PDF Validation**
   - Only accepts .pdf files (rejects .docx, .txt, etc.)
   - Clear, helpful error messages
   - Security validations

5. **📝 Enhanced Documentation**
   - Comprehensive tool descriptions
   - Clear examples in every tool
   - Better error guidance

**[See full changelog →](ENHANCEMENTS.md)**

---

## ✨ Features

This MCP server provides **10 powerful PDF tools**:

### Core PDF Tools
1. **📊 count-pdf-pages** - Count total pages in a PDF file
2. **📝 extract-pdf-text** - Extract all text content from a PDF
3. **ℹ️ extract-pdf-metadata** - Get PDF metadata (title, author, dates, etc.)
4. **🤖 summarize-pdf** - AI-powered PDF summarization using LLM sampling
5. **❓ answer-pdf-question** - Answer questions about PDF content using AI

### Content Modification Tools
6. **🏷️ add-pdf-watermark** - Add custom watermarks to PDF pages with full control
7. **📑 add-pdf-header-footer** - Add headers and footers with dynamic variables
8. **✏️ replace-text-at-position** - Replace text at specific positions with precise control

### 🆕 Advanced Analysis Tools (v2.1)
9. **🔍 analyze-pdf-page** - Extract page dimensions, margins, and layout information
10. **📍 detect-text-position** - Detect precise text positions with OCR-level accuracy

**[See advanced tools documentation →](ADVANCED_TOOLS.md)**

### New: Watermark & Header/Footer Features

#### Watermark Tool
- **Position Options**: Top-left, top-right, top-center, bottom-left, bottom-right, bottom-center, center, or custom coordinates
- **Full Customization**: Font size, color (RGB), opacity, rotation angle, margin control
- **Memory Efficient**: Optimized for large PDFs (300+ pages) with batch processing
- **Smart Defaults**: Works out-of-the-box with sensible defaults

#### Header/Footer Tool
- **Dynamic Variables**: `{page}`, `{totalPages}`, `{date}`, `{title}` automatically replaced
- **Flexible Alignment**: Left, center, or right alignment
- **Page Range Support**: Apply to specific pages or all pages
- **Customization**: Font size, color, margins
- **Memory Efficient**: Handles large PDFs (300+ pages) with batch processing

## 🚀 Quick Start

### Prerequisites

- **Node.js** 18.0.0 or higher
- **npm** or **yarn**
- An MCP client (Claude Desktop or VS Code Copilot)

### Installation

```bash
# Clone or download this repository
cd pdf-mcp-server

# Install dependencies
npm install

# Build the project
npm run build

# Test the server (optional)
npm start
```

## 🔧 Configuration

### For Claude Desktop

Add the following to your Claude Desktop configuration file:

**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`  
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "pdf-operations": {
      "command": "node",
      "args": [
        "/absolute/path/to/pdf-mcp-server/dist/index.js"
      ],
      "env": {}
    }
  }
}
```

**Important**: Replace `/absolute/path/to/pdf-mcp-server` with the actual absolute path to this project directory.

### For VS Code Copilot

Add to your VS Code `settings.json`:

```json
{
  "github.copilot.mcp.servers": {
    "pdf-operations": {
      "command": "node",
      "args": [
        "/absolute/path/to/pdf-mcp-server/dist/index.js"
      ]
    }
  }
}
```

**Important**: Replace `/absolute/path/to/pdf-mcp-server` with the actual absolute path to this project directory.

## 📖 Usage Examples

Once configured, you can use natural language to interact with PDF files:

### Count Pages

```
How many pages are in /path/to/document.pdf?
```

The server will use the `count-pdf-pages` tool to return the page count.

### Extract Text

```
Extract all text from /path/to/report.pdf
```

The server will use the `extract-pdf-text` tool to return the full text content.

### Get Metadata

```
What are the metadata details of /path/to/paper.pdf?
```

The server will use the `extract-pdf-metadata` tool to return title, author, creation date, etc.

### Summarize PDF

```
Summarize the main points of /path/to/research.pdf
```

The server will use the `summarize-pdf` tool to generate an AI-powered summary.

### Answer Questions

```
Based on /path/to/manual.pdf, how do I install the software?
```

The server will use the `answer-pdf-question` tool to provide an answer based on the PDF content.

### Add Watermark

```
Add a watermark "CONFIDENTIAL" to /path/to/document.pdf
```

The server will use the `add-pdf-watermark` tool to add a watermark to all pages.

**Advanced watermark example**:
```
Add a watermark "DRAFT" to /path/to/report.pdf with:
- Position: bottom-right corner
- Font size: 36
- Light gray color (RGB: 0.7, 0.7, 0.7)
- 50% opacity
- No rotation
```

### Add Headers and Footers

```
Add "My Document" as header and "Page {page} of {totalPages}" as footer to /path/to/file.pdf
```

The server will use the `add-pdf-header-footer` tool to add headers and footers with dynamic page numbers.

**Advanced header/footer example**:
```
Add headers and footers to /path/to/contract.pdf:
- Header: "{title} - {date}" aligned left
- Footer: "Page {page} of {totalPages}" aligned right
- Apply only to pages 2-20
- Font size: 10pt
```

## 🛠️ Available Tools

### 1. count-pdf-pages

**Description**: Count the total number of pages in a PDF file.

**Input**:
```typescript
{
  filePath: string  // Absolute or relative path to PDF file
}
```

**Output**:
```typescript
{
  pageCount: number,
  filePath: string
}
```

**Example**:
```typescript
Input: { filePath: "/docs/report.pdf" }
Output: { pageCount: 42, filePath: "/docs/report.pdf" }
```

---

### 2. extract-pdf-text

**Description**: Extract all text content from a PDF file.

**Input**:
```typescript
{
  filePath: string,         // Absolute or relative path to PDF file
  maxLength?: number        // Optional: max characters to return (default: 50000)
}
```

**Output**:
```typescript
{
  text: string,            // Extracted text content
  characterCount: number,  // Total characters extracted
  pageCount: number,       // Number of pages
  filePath: string
}
```

---

### 3. extract-pdf-metadata

**Description**: Extract metadata from a PDF file (title, author, dates, etc.).

**Input**:
```typescript
{
  filePath: string  // Absolute or relative path to PDF file
}
```

**Output**:
```typescript
{
  title: string,
  author: string,
  subject: string,
  creationDate: string,
  modificationDate: string,
  pageCount: number,
  pdfVersion: string,
  filePath: string
}
```

---

### 4. summarize-pdf

**Description**: Generate an AI-powered summary of PDF content.

**Input**:
```typescript
{
  filePath: string,      // Absolute or relative path to PDF file
  maxTokens?: number     // Optional: max tokens for summary (default: 500)
}
```

**Output**:
```typescript
{
  summary: string,        // Generated summary
  pageCount: number,
  originalLength: number, // Original text length
  summaryLength: number,  // Summary length
  filePath: string
}
```

**Note**: Requires MCP client to support LLM sampling feature.

---

### 5. answer-pdf-question

**Description**: Answer questions about PDF content using AI.

**Input**:
```typescript
{
  filePath: string,      // Absolute or relative path to PDF file
  question: string,      // Question to answer
  maxTokens?: number     // Optional: max tokens for answer (default: 500)
}
```

**Output**:
```typescript
{
  answer: string,        // Answer to the question
  question: string,      // Original question
  context: string,       // Relevant PDF context used
  filePath: string
}
```

**Note**: Requires MCP client to support LLM sampling feature.

---

### 6. add-pdf-watermark

**Description**: Add custom watermark to all pages of a PDF with full control over appearance.

**Input**:
```typescript
{
  filePath: string,         // Absolute or relative path to PDF file
  text: string,            // Watermark text
  position?: string,       // Position: 'top-left', 'top-right', 'top-center', 
                          //           'bottom-left', 'bottom-right', 'bottom-center',
                          //           'center', 'custom' (default: 'center')
  x?: number,              // X coordinate (required if position is 'custom')
  y?: number,              // Y coordinate (required if position is 'custom')
  fontSize?: number,       // Font size in points (default: 48)
  color?: {                // RGB color (0-1 range, default: gray)
    r: number,
    g: number,
    b: number
  },
  opacity?: number,        // Opacity 0-1 (default: 0.3)
  rotation?: number,       // Rotation in degrees (default: -45)
  margin?: number,         // Margin from edges in points (default: 50)
  outputPath?: string,     // Output file path (default: input_watermarked.pdf)
  useBatchProcessing?: boolean  // Use batch processing for large PDFs (default: false)
}
```

**Output**:
```typescript
{
  outputPath: string,      // Path to watermarked PDF
  pagesProcessed: number,  // Number of pages watermarked
  originalPath: string,    // Original file path
  config: WatermarkConfig  // Configuration used
}
```

**Example**:
```typescript
Input: {
  filePath: "/docs/report.pdf",
  text: "CONFIDENTIAL",
  position: "center",
  opacity: 0.3
}
Output: {
  outputPath: "/docs/report_watermarked.pdf",
  pagesProcessed: 42,
  originalPath: "/docs/report.pdf",
  config: { text: "CONFIDENTIAL", position: "center", ... }
}
```

---

### 7. add-pdf-header-footer

**Description**: Add headers and/or footers to PDF pages with dynamic variables.

**Input**:
```typescript
{
  filePath: string,         // Absolute or relative path to PDF file
  headerText?: string,      // Header text (supports variables)
  footerText?: string,      // Footer text (supports variables)
  alignment?: string,       // Text alignment: 'left', 'center', 'right' (default: 'center')
  fontSize?: number,        // Font size in points (default: 12)
  color?: {                 // RGB color (0-1 range, default: black)
    r: number,
    g: number,
    b: number
  },
  margin?: number,          // Margin from top/bottom in points (default: 30)
  pageRange?: [number, number],  // Page range [start, end] (default: all pages)
  outputPath?: string,      // Output file path (default: input_with_headers_footers.pdf)
  useBatchProcessing?: boolean   // Use batch processing for large PDFs (default: false)
}
```

**Supported Variables**:
- `{page}` - Current page number (1-based)
- `{totalPages}` - Total number of pages
- `{date}` - Current date (YYYY-MM-DD format)
- `{title}` - PDF document title

**Output**:
```typescript
{
  outputPath: string,      // Path to PDF with headers/footers
  pagesProcessed: number,  // Number of pages processed
  originalPath: string,    // Original file path
  config: HeaderFooterConfig  // Configuration used
}
```

**Example**:
```typescript
Input: {
  filePath: "/docs/manual.pdf",
  headerText: "{title}",
  footerText: "Page {page} of {totalPages}",
  alignment: "center"
}
Output: {
  outputPath: "/docs/manual_with_headers_footers.pdf",
  pagesProcessed: 42,
  originalPath: "/docs/manual.pdf",
  config: { headerText: "{title}", footerText: "Page {page} of {totalPages}", ... }
}
```

---

### 8. analyze-pdf-page

**Description**: Extract comprehensive page layout information including dimensions, margins, and page boxes. Essential for understanding page structure before adding watermarks or other elements.

**Input**:
```typescript
{
  filePath: string,      // Absolute or relative path to PDF file
  pageNumber?: number    // Page number to analyze (1-indexed, default: 1)
}
```

**Output**:
```typescript
{
  filePath: string,
  pageNumber: number,
  dimensions: {
    width: number,               // Width in points
    height: number,              // Height in points
    rotation: number,            // Rotation in degrees (0, 90, 180, 270)
    inchDimensions: {
      width: number,             // Width in inches
      height: number             // Height in inches
    },
    mmDimensions: {
      width: number,             // Width in millimeters
      height: number             // Height in millimeters
    }
  },
  margins: {
    top: number,                 // Top margin in points
    bottom: number,              // Bottom margin in points
    left: number,                // Left margin in points
    right: number,               // Right margin in points
    detected: boolean            // Whether margins were detected from content
  },
  mediaBox: {
    x: number,
    y: number,
    width: number,
    height: number
  },
  cropBox?: {                    // Optional: visible page area
    x: number,
    y: number,
    width: number,
    height: number
  }
}
```

**Example**:
```typescript
Input: {
  filePath: "document.pdf",
  pageNumber: 1
}
Output: {
  filePath: "/Users/you/Downloads/document.pdf",
  pageNumber: 1,
  dimensions: {
    width: 595.28,
    height: 841.89,
    rotation: 0,
    inchDimensions: { width: 8.27, height: 11.69 },
    mmDimensions: { width: 210.0, height: 297.0 }
  },
  margins: { top: 71.0, bottom: 71.0, left: 71.0, right: 71.0, detected: true },
  mediaBox: { x: 0, y: 0, width: 595.28, height: 841.89 }
}
```

---

### 9. detect-text-position

**Description**: Detect precise text positions in a PDF page using advanced OCR-level text extraction. Returns exact bounding boxes, font information, and coordinates for each text element.

**Input**:
```typescript
{
  filePath: string,         // Absolute or relative path to PDF file
  pageNumber?: number,      // Page number to analyze (1-indexed, default: 1)
  searchQuery?: string,     // Optional: filter text items by content
  maxResults?: number       // Optional: maximum number of results to return
}
```

**Output**:
```typescript
{
  filePath: string,
  pageNumber: number,
  textItems: Array<{
    text: string,              // The text content
    fontName: string,          // Font name used for this text
    fontSize: number,          // Font size in points
    bounds: {
      x: number,               // X coordinate of top-left corner
      y: number,               // Y coordinate of top-left corner
      width: number,           // Width of the bounding box
      height: number           // Height of the bounding box
    },
    transform: number[],       // PDF transformation matrix [a, b, c, d, e, f]
    direction: number          // Text direction in degrees (0=horizontal, 90=vertical)
  }>,
  totalTextItems: number,      // Total number of text items found
  pageDimensions: {
    width: number,
    height: number,
    rotation: number,
    inchDimensions: { width: number, height: number },
    mmDimensions: { width: number, height: number }
  },
  searchQuery?: string,        // Search query used (if filtering was applied)
  filtered: boolean            // Whether results were filtered
}
```

**Example**:
```typescript
Input: {
  filePath: "document.pdf",
  pageNumber: 1,
  searchQuery: "watermark"
}
Output: {
  filePath: "/Users/you/Downloads/document.pdf",
  pageNumber: 1,
  textItems: [
    {
      text: "WATERMARK",
      fontName: "Helvetica-Bold",
      fontSize: 48.0,
      bounds: { x: 200.0, y: 400.0, width: 195.0, height: 48.0 },
      transform: [48, 0, 0, 48, 200, 400],
      direction: 0
    }
  ],
  totalTextItems: 1,
  pageDimensions: { width: 595.28, height: 841.89, rotation: 0, ... },
  searchQuery: "watermark",
  filtered: true
}
```

**Use Cases**:
- Intelligent watermark placement (avoid text overlap)
- Content-aware PDF operations
- Text position analysis for layout understanding
- Finding optimal positions for annotations

**[See advanced tools documentation →](ADVANCED_TOOLS.md)**

---

### 10. replace-text-at-position

**Description**: Replaces text at specific positions in PDF documents. Works in conjunction with detect-text-position to find and replace text with precise control over positioning, fonts, and colors. Perfect for bulk text replacements, typo corrections, and content updates.

**Input**:
```typescript
{
  filePath: string,         // Absolute or relative path to PDF file
  replacements: Array<{
    pageNumber: number,           // Page number where text should be replaced (1-indexed)
    originalText: string,         // Original text to find and replace
    replacementText: string,      // New text to insert (can be empty to remove text)
    bounds: {
      x: number,                  // X coordinate of text position
      y: number,                  // Y coordinate of text position
      width: number,              // Width of text bounding box
      height: number              // Height of text bounding box
    },
    fontName?: string,            // Font name (defaults to Helvetica)
    fontSize?: number,            // Font size in points
    color?: {                     // Text color in RGB (0-1 range)
      r: number,
      g: number,
      b: number
    },
    rotation?: number,            // Text rotation angle in degrees
    backgroundColor?: {           // Background color to cover old text (defaults to white)
      r: number,
      g: number,
      b: number
    }
  }>,
  preserveFonts?: boolean,        // Preserve original fonts when possible (default: true)
  preserveColors?: boolean,       // Preserve original colors when possible (default: true)
  outputPath?: string,            // Output file path (default: input_with_replacements.pdf)
  createBackup?: boolean          // Create backup of original file (default: false)
}
```

**Output**:
```typescript
{
  outputPath: string,             // Path to the output PDF with replacements
  replacementCount: number,       // Number of successful replacements made
  pagesModified: number,          // Number of pages modified
  originalPath: string,           // Original file path
  replacements: Array<{
    pageNumber: number,
    originalText: string,
    replacementText: string,
    success: boolean,             // Whether the replacement was successful
    error?: string                // Error message if replacement failed
  }>
}
```

**Example Use Cases**:

1. **Replace all occurrences of "Hello" with "Hi"**:
```typescript
// Step 1: Find all "Hello" text positions
Input: {
  filePath: "document.pdf",
  searchQuery: "Hello"
}
// Use detect-text-position to get positions

// Step 2: Replace all occurrences
Input: {
  filePath: "document.pdf",
  replacements: [
    {
      pageNumber: 1,
      originalText: "Hello",
      replacementText: "Hi",
      bounds: { x: 100, y: 200, width: 50, height: 15 },
      fontSize: 12
    }
    // ... more occurrences
  ]
}
Output: {
  outputPath: "/path/to/document_with_replacements.pdf",
  replacementCount: 3,
  pagesModified: 1,
  originalPath: "/path/to/document.pdf",
  replacements: [
    { pageNumber: 1, originalText: "Hello", replacementText: "Hi", success: true }
    // ... more results
  ]
}
```

2. **Replace year "2023" with "2024" in first occurrence**:
```typescript
Input: {
  filePath: "contract.pdf",
  replacements: [
    {
      pageNumber: 1,
      originalText: "2023",
      replacementText: "2024",
      bounds: { x: 150, y: 700, width: 40, height: 12 },
      fontSize: 10
    }
  ]
}
```

3. **Replace whitespace with underscores**:
```typescript
// First detect text with spaces, then replace
Input: {
  filePath: "form.pdf",
  replacements: [
    {
      pageNumber: 1,
      originalText: "First Name",
      replacementText: "First_Name",
      bounds: { x: 50, y: 100, width: 80, height: 15 },
      fontSize: 12
    }
  ]
}
```

4. **Batch replacement with custom styling**:
```typescript
Input: {
  filePath: "report.pdf",
  replacements: [
    {
      pageNumber: 1,
      originalText: "DRAFT",
      replacementText: "FINAL",
      bounds: { x: 50, y: 50, width: 100, height: 20 },
      fontSize: 16,
      color: { r: 1, g: 0, b: 0 },  // Red text
      backgroundColor: { r: 1, g: 1, b: 0.8 }  // Light yellow background
    },
    {
      pageNumber: 2,
      originalText: "Confidential",
      replacementText: "Public",
      bounds: { x: 400, y: 50, width: 120, height: 15 },
      fontSize: 12
    }
  ],
  preserveFonts: false,
  createBackup: true
}
```

**Use Cases**:
- Replace all occurrences of specific text
- Update dates, years, or version numbers
- Correct typos at specific locations
- Replace whitespace or special characters
- Batch update product names, prices, or codes
- Content updates without recreating PDFs
- Automated document corrections

**Workflow**:
1. Use `detect-text-position` to find text locations
2. Prepare replacement specifications with new text
3. Call `replace-text-at-position` to perform replacements
4. Get detailed results with success/failure status

**[See usage examples →](EXAMPLES.md)**

---

## 🔒 Security Features

- ✅ **Path validation**: Prevents path traversal attacks
- ✅ **File size limits**: Default 50MB maximum to prevent memory exhaustion
- ✅ **File type validation**: Ensures only PDF files are processed
- ✅ **Error handling**: Comprehensive error messages for debugging
- ✅ **Input sanitization**: All inputs validated with Zod schemas

## 📁 Project Structure

```
pdf-mcp-server/
├── src/
│   ├── index.ts                        # Main server entry point
│   ├── types.ts                        # TypeScript type definitions
│   ├── utils/
│   │   ├── path-resolver.ts            # File path resolution utilities
│   │   ├── pdf-utils.ts                # PDF processing utilities
│   │   ├── watermark-utils.ts          # Watermark utilities
│   │   ├── header-footer-utils.ts      # Header/footer utilities
│   │   ├── page-analysis-utils.ts      # Page dimension & margin analysis
│   │   ├── text-position-utils.ts      # Text position detection (PDF.js)
│   │   └── text-replacement-utils.ts   # Text replacement utilities (NEW)
│   └── tools/
│       ├── count-pages.tool.ts         # Page counting tool
│       ├── extract-text.tool.ts        # Text extraction tool
│       ├── extract-metadata.tool.ts    # Metadata extraction tool
│       ├── summarize-pdf.tool.ts       # AI summarization tool
│       ├── answer-question.tool.ts     # AI Q&A tool
│       ├── add-watermark.tool.ts       # Watermark tool
│       ├── add-header-footer.tool.ts   # Header/footer tool
│       ├── analyze-pdf-page.tool.ts    # Page analysis tool (v2.1)
│       ├── detect-text-position.tool.ts # Text position detection tool (v2.1)
│       └── replace-text-at-position.tool.ts # Text replacement tool (NEW)
├── scripts/
│   ├── test-new-tools.ts               # Test suite for new tools
│   └── test-text-replacement.ts        # Test suite for text replacement (NEW)
├── dist/                               # Compiled JavaScript output
├── package.json                        # Project dependencies
├── tsconfig.json                       # TypeScript configuration
├── README.md                           # This file
├── ADVANCED_TOOLS.md                   # Advanced tools documentation (v2.1)
└── EXAMPLES.md                         # Detailed usage examples
```

## 🧪 Development

### Build

```bash
npm run build
```

### Watch Mode

```bash
npm run watch
```

### Run Server

```bash
npm start
```

The server will start and wait for MCP client connections via stdio transport.

## 🐛 Troubleshooting

### Server not appearing in Claude Desktop

1. **Check configuration path**: Ensure the path in `claude_desktop_config.json` is absolute and correct
2. **Rebuild the project**: Run `npm run build` to ensure latest code is compiled
3. **Restart Claude Desktop**: Close and reopen Claude Desktop completely
4. **Check logs**: Look for error messages in Claude Desktop's developer console

### "File not found" errors

1. **Use absolute paths**: Provide absolute paths to PDF files
2. **Check file permissions**: Ensure the PDF file is readable
3. **Verify file exists**: Double-check the file path is correct

### "PDF is password protected" errors

This server does not support password-protected PDFs. Remove the password before processing.

### Memory issues with large PDFs

The default file size limit is 50MB. For larger files, you may need to:
1. Split the PDF into smaller chunks
2. Modify the `MAX_FILE_SIZE_BYTES` constant in `src/utils/pdf-utils.ts`

## 📚 Dependencies

- **[@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk)**: Official MCP TypeScript SDK
- **[pdf-parse](https://github.com/albertcui/pdf-parse)**: Pure JavaScript PDF text extraction
- **[zod](https://github.com/colinhacks/zod)**: TypeScript-first schema validation

## 🤝 Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

## 📄 License

MIT License - feel free to use this in your own projects!

## 🙏 Acknowledgments

- Built with the [Model Context Protocol](https://modelcontextprotocol.io)
- Uses [pdf-parse](https://github.com/albertcui/pdf-parse) for PDF text extraction
- Follows MCP best practices and TypeScript strict mode

## 📞 Support

For issues or questions:
1. Check the [Troubleshooting](#-troubleshooting) section
2. Review the [MCP documentation](https://modelcontextprotocol.io)
3. Open an issue on GitHub

---

**Made with ❤️ for the MCP community**
