Podcast Title

Author Name

0:00
0:00
Album Art

Build a Local PDF-to-Markdown MCP Server for Your IDE in Just 10 Minutes

By 10xdev team August 17, 2025

In this article, we'll explore how to build your own WCO MCP server and connect it to Cursor, VS Code, or other MCP-compatible IDEs. Our server will leverage docklink to convert PDF files into markdown entirely on your local machine, providing a powerful way to feed custom data into your development environment.

Core Architecture

This tutorial focuses on building an MCP server that uses the standard input/output (stdio) protocol for data transfer between the server and the client. While MCP supports numerous other transfer protocols and is constantly evolving, the fundamental features remain consistent. We will utilize the Python SDK provided by Anthropic to create the server and connect it to a local instance of the Cursor IDE.

The complete source code for the MCPDF reader project discussed here is open-source and available on GitHub.

Project Dependencies

To begin, our project requires several key Python libraries. These dependencies handle everything from PDF processing to the MCP server implementation.

# requirements.txt
doclink
mcp-server
pypdfium2
# A code formatter like black or ruff is also recommended
  • doclink: The core library for converting PDF files into markdown.
  • mcp-server: The official implementation for creating the MCP server.
  • pypdfium2: The backend engine used by doclink to process PDF files.

Our MCP server's primary function is to convert PDF documents, such as a customer complaint policy with standard formatting and bullet points, into clean markdown. This markdown can then be fed as context into our IDE.

Implementing the Server

In the main server file, we begin by initializing the FastMcpServer. We then define the path to our data directory containing the PDFs and create a PDFConverter instance.

The server exposes two main tools: get_document_text and get_document_list.

# server.py (simplified)
from mcp import FastMcpServer
from pdf_converter import create_pdf_converter, convert_to_markdown

# Initialize the server
server = FastMcpServer()
DATA_DIR = "./data"
pdf_converter = create_pdf_converter()

@server.tool()
def get_document_text(fileName: str) -> str:
    """Gets the full text of a document as markdown."""
    document_path = f"{DATA_DIR}/{fileName}"
    return convert_to_markdown(document_path, pdf_converter)

@server.tool()
def get_document_list() -> list[str]:
    """Gets the list of available documents."""
    # Logic to list files in DATA_DIR
    return ["customer-complaint-policy.pdf", "nvidia-annual-report.pdf"]

# Start the server using the stdio transport protocol
server.run_stdio()
  • getdocumentlist: This tool simply enumerates the available PDF files within the data directory.
  • getdocumenttext: This tool accepts a file name, constructs the full path, and uses our helper function to perform the conversion to markdown.

Handling PDF to Markdown Conversion

The magic of PDF conversion happens within our pdf_converter.py file, where doclink is utilized. For this example, we are performing a straightforward digital-to-markdown conversion without enabling advanced features like OCR or table structure recognition. However, these can be turned on for more complex documents.

# pdf_converter.py (simplified)
from doclink import DocLink

def create_pdf_converter():
    """Creates a DocLink converter instance with specific features disabled."""
    # For a more comprehensive conversion, you can enable these features
    return DocLink(config={"use_ocr": False, "table_strategy": "disabled"})

def convert_to_markdown(pdf_path: str, converter: DocLink) -> str:
    """Uses the converter to transform a PDF file into a markdown string."""
    doc = converter.from_pdf(pdf_path)
    return doc.to_markdown()

The convert_to_markdown function takes a PDF path, processes it into a doclink document, and exports the result as a markdown string, which is returned to the MCP client.

Running and Testing the Server

To run your MCP server, activate your Python environment and execute the main server file.

python server.py

Once the server is running, you can use the MCP Inspector to connect to your local instance. In the inspector's "Tools" section, you should see get_document_text and get_document_list. Running get_document_list will return a list of your PDF files. To test the conversion, run get_document_text with one of the PDF filenames. The result will be the full markdown content of the document. You may notice that images are replaced with placeholders; this and other behaviors are highly configurable within doclink.

Integrating with Your IDE (Cursor Example)

After testing the server with the MCP Inspector, you can integrate it into your IDE. In Cursor, this is done by navigating to Settings > Tools & Integrations and opening the mcp.json configuration file.

Here, you will define the command to execute your server.

// mcp.json
{
    "servers": [
        {
            "name": "Local PDF Reader",
            "command": [
                "/path/to/your/uv/binary", // Or your python executable
                "run",
                "python",
                "server.py"
            ],
            "cwd": "/path/to/your/mcp-pdf-reader"
        }
    ]
}

This configuration tells Cursor how to start your MCP server, specifying the execution path and the working directory. Once saved, the get_document_text and get_document_list tools will become available directly within the IDE.

Note: The setup process for VS Code, Gemini CLI, or other editors is very similar. You will need to consult their respective documentation for integrating external MCP servers.

Putting It All to Use

With the integration complete, you can now interact with your local files. For instance, asking the Cursor composer, "What PDF files do I have?" will trigger the get_document_list tool and return the list of documents.

A more complex prompt could be:

"Create a beautiful and simple HTML page that contains a checklist for the customer complaint policy. Make it clean and minimalistic. Each step should be a form of swipe. When a step is complete, you should be able to go back."

This prompt will cause the AI assistant to first call get_document_text with the relevant policy file. The server will return the full markdown, which the assistant will then use as context to generate the requested HTML file with a functional checklist slider. The information in the final HTML is sourced directly from your local PDF, demonstrating the power of this local-first approach.

This MCP PDF server allows you to seamlessly use your local PDF files as context for Cursor and other IDEs, enhancing your development workflow.

Join the 10xdev Community

Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.

Recommended For You

Up Next