Skip to main content
Glama
README.md
# mcp_poc

A **PDF-to-Markdown** converter built with the **Model-View-Controller (MVC)** pattern using the **Model Context Protocol (MCP)**.

## Architecture

The project follows a clean separation of concerns across three layers, connected via MCP's stdio transport.

```mermaid
flowchart TB
    subgraph Client["Client Layer"]
        C[mcp_client.py<br/>Stdio Client Connector]
    end

    subgraph Server["Server Layer (Controller)"]
        S[mcp_server.py<br/>FastMCP Server]
        T[convert_pdf Tool]
        P[summarize_markdown Prompt]
    end

    subgraph Model["Model Layer"]
        M[PyMuPDF / fitz<br/>PDF Text Extraction]
    end

    subgraph View["View Layer"]
        V[Markdown Formatter<br/>## Page N]
    end

    C -->|stdio JSON-RPC| S
    S --> T
    T --> M
    M --> V
    V --> T
    T --> S
    S -->|Tool Result| C
```

### File Responsibilities

| File | Role | Description |
|------|------|-------------|
| `mcp_server.py` | **Controller** | Exposes `convert_pdf` as an MCP tool and `summarize_markdown` as a prompt. Orchestrates Model and View logic. |
| `mcp_client.py` | **Connector** | Manages the stdio client session used to call the server's tools from external processes or LLMs. |
| `main.py` | **Entry Point** | Can run the server in stdio mode (`--server`) or execute direct local conversions for testing. |
| `test_integration.py` | **Test** | End-to-end integration test that launches the server via stdio and verifies tool execution. |

## Quick Start

### 1. Install Dependencies

```bash
python -m venv venv
# Windows
.\venv\Scripts\pip install -r requirements.txt
# macOS / Linux
source venv/bin/activate && pip install -r requirements.txt
```

### 2. Run a Direct Conversion (Local Test)

```bash
.\venv\Scripts\python main.py data/sample.pdf
```

### 3. Run the MCP Server (for Claude / IDE integration)

```bash
.\venv\Scripts\python main.py --server
```

### 4. Run Integration Test (Client → Server)

```bash
.\venv\Scripts\python test_integration.py
```

## Project Structure

```
mcp_poc/
├── .env                      # Environment configuration
├── .gitignore                # Git ignore rules
├── README.md                 # This file
├── main.py                   # Application entry point
├── mcp_client.py             # MCP stdio client connector
├── mcp_server.py             # MCP server with tools & prompts
├── requirements.txt          # Python dependencies
├── test_integration.py       # Integration test
└── data/
    └── sample.pdf            # Test PDF
```

## How It Works

1. **Client** (`mcp_client.py`) spawns the server as a subprocess and communicates over stdio.
2. **Server** (`mcp_server.py`) receives a `convert_pdf` tool call.
3. **Model** (`fitz` / PyMuPDF) opens the PDF and extracts raw text page by page.
4. **View** formats the extracted text as Markdown with `## Page N` headers.
5. The formatted Markdown is returned to the client via the MCP protocol.

## Extending

- **OCR Support**: Swap the Model layer to use `marker-pdf` or an external OCR API for scanned documents.
- **Additional Tools**: Add more `@mcp.tool()` definitions in `mcp_server.py` for image extraction, metadata parsing, etc.
- **Alternative Transports**: Replace `stdio` with `sse` or `http` in `mcp.run(...)` for remote deployments.