pdf-extract-mcp
pdf-extract-mcp
Ein Model Context Protocol (MCP)-Server, der strukturierte Daten aus unstrukturierten PDF-Dokumenten deterministisch extrahiert – reine Textextraktion plus Regex-/Heuristik-Feldabgleich, ohne LLM-API-Aufrufe zur Extraktionszeit.
Funktionen
Echter MCP-Server – basierend auf dem offiziellen MCP Python SDK (2.x), das das Protokoll über stdio, SSE oder streamable HTTP spricht. Verifiziert durch einen End-to-End-Test, der den tatsächlichen Server mit dem offiziellen Client steuert.
Schema-gesteuerte Extraktion – richten Sie extract_fields auf ein beliebiges JSON Schema aus und erhalten Sie strukturiertes JSON genau für die Felder, die Sie angefordert haben.
Deterministisch und überprüfbar – Regex-/Heuristik-Abgleich, keine LLM-API-Aufrufe, keine versteckten Kosten, keine Black Box. Jede Extraktion ist wiederholbar und nachvollziehbar.
Verständliche Validierungsberichte – validate_against_schema erklärt pro Feld, warum es bestanden hat, fehlgeschlagen ist oder fehlt.
Vorgefertigte Schemas – invoice, resume und purchase_order sind sofort einsatzbereit, dazu synthetische Beispiel-PDFs, sodass alles direkt demonstrierbar ist.
Saubere Fehlerbehandlung – beschädigte PDFs, fehlende Dateien und ungültige Schemas liefern strukturierte Fehler, niemals Stack-Traces.
Related MCP server: PDF RAG MCP Server
Was ist MCP und warum ist das nützlich?
Das Model Context Protocol ist ein offener Standard, der KI-Assistenten (Claude, Cursor usw.) ermöglicht, über eine persistente, bidirektionale Verbindung externe Werkzeuge aufzurufen. Anstatt PDF-Text in einen Chat einzufügen und das Modell zu bitten, ihn zu „interpretieren“, kann ein Assistent pdf-extract-mcp direkt aufrufen, strukturiertes JSON empfangen, das einem von Ihnen bereitgestellten Schema entspricht, und darauf reagieren. Da die Extraktion hier deterministisch ist (Regex + Heuristiken) – kein probabilistischer Modellaufruf – ist jedes Ergebnis überprüfbar, wiederholbar und kostengünstig. Das macht es ideal für automatisierte Dokumentpipelines (Rechnungen an die Buchhaltung, Lebensläufe an ATS, Bestellungen an den Einkauf), bei denen Sie wissen müssen, warum ein Feld auf eine bestimmte Weise extrahiert wurde.
Installation
cd pdf-extract-mcp
python3 -m venv .venv
source .venv/bin/activate
make install # pip install -e ".[dev]" (installs the console script too)oder mit einfachem pip:
pip install -e ".[dev]"Der Server verwendet das offizielle MCP Python SDK (mcp >= 2.x, die aktuelle Release-Linie, die die MCPServer-API bereitstellt). pdfplumber übernimmt die Textextraktion, jsonschema die Validierung und reportlab erzeugt die Beispiel-PDFs.
Die Installation stellt außerdem ein pdf-extract-mcp-Konsolenskript bereit, sodass Sie den Server von überall aus mit folgendem Befehl ausführen können:
pdf-extract-mcp # stdio (default)
pdf-extract-mcp --transport streamable-http --host 127.0.0.1 --port 8000Ausführen
python server.pyDies stellt MCP über stdio bereit (die Standardeinstellung und das, was Claude Code / Claude Desktop erwarten). Sie können es auch als Netzwerkdienst bereitstellen:
python server.py --transport streamable-http --host 127.0.0.1 --port 8000
python server.py --transport sse --host 127.0.0.1 --port 8001Verbindung zu Claude Code / Claude Desktop herstellen
Claude Code – fügen Sie eine .mcp.json im Projektstamm hinzu:
{
"mcpServers": {
"pdf-extract": {
"command": "python",
"args": ["/absolute/path/to/pdf-extract-mcp/server.py"],
"env": {}
}
}
}Claude Desktop – fügen Sie denselben Block zur Claude Desktop config hinzu (claude_desktop_config.json, auf macOS unter ~/Library/Application Support/Claude/ zu finden):
{
"mcpServers": {
"pdf-extract": {
"command": "python",
"args": ["/absolute/path/to/pdf-extract-mcp/server.py"]
}
}
}Starten Sie den Client nach dem Speichern neu. Sie sollten drei neue Werkzeuge sehen: extract_fields, validate_against_schema und list_supported_document_types.
Werkzeuge
Tool | Zweck |
extract_fields(pdf_path, schema) | Extrahiert strukturierte Felder aus einer PDF, die einem JSON Schema entsprechen -> {"ok": true, "data": {...}} |
validate_against_schema(data, schema) | Prüft extrahierte Daten gegen ein Schema -> Pass/fail/missing-Bericht mit verständlichen Gründen |
list_supported_document_types() | Listet Dokumenttypen auf, die mit vorgefertigten Schemas ausgeliefert werden |
Das schema-Argument von extract_fields akzeptiert ein JSON-Schema-Objekt, einen integrierten Schema-Namen (z. B. „invoice“) oder einen Pfad zu einer .json-Schemadatei. Integrierte Schemas befinden sich in schemas/:
invoice – vendor_name, invoice_number, total_amount, due_date (erforderlich) + issue_date, customer_name
resume – name, email (erforderlich) + phone, skills
purchase_order – po_number, vendor_name, total_amount (erforderlich) + issue_date, customer_name
Arbeitsbeispiel
Generieren Sie zuerst die Beispiel-PDFs (bereits im Repository vorhanden; jederzeit neu erzeugen mit):
python sample_pdfs/generate_samples.pyRufen Sie nun extract_fields für die Beispielrechnung mit dem integrierten Schema-Namen invoice auf. In Claude Code können Sie einfach sagen: „Extract the fields from sample_pdfs/invoice.pdf using the invoice schema“; im Hintergrund wird ein Tool-Aufruf ausgeführt, der Folgendem entspricht:
{
"name": "extract_fields",
"arguments": {
"pdf_path": "/absolute/path/to/pdf-extract-mcp/sample_pdfs/invoice.pdf",
"schema": "invoice"
}
}Tatsächlich erwartetes Ergebnis:
{
"ok": true,
"data": {
"vendor_name": "Acme Widgets Corp",
"invoice_number": "INV-2024-0087",
"total_amount": 1750.0,
"due_date": "April 1, 2024",
"issue_date": "March 1, 2024",
"customer_name": "Globex Industries"
},
"text_length": 372
}Wenn Sie dieselben Daten mit demselben Schema an validate_against_schema übergeben:
{
"ok": true,
"valid": true,
"passed": ["customer_name", "due_date", "invoice_number", "issue_date", "total_amount", "vendor_name"],
"failed": [],
"missing": [],
"summary": "Valid: all 6 present field(s) conform to the schema.",
"error": null
}Führen Sie diese direkt aus Python aus, um es live zu sehen:
import json
from tools.extract import extract_fields
from tools.validate import validate_against_schema
schema = json.load(open("schemas/invoice.json"))
result = extract_fields("sample_pdfs/invoice.pdf", schema)
print(result["data"])
print(validate_against_schema(result["data"], schema))So funktioniert die MCP-Toolregistrierung in server.py
Das ist der Kern des Projekts, daher lohnt es sich, genau zu verstehen, was das SDK für Sie übernimmt.
1. Das Server-Objekt erstellen.
from mcp.server.mcpserver import MCPServer
mcp = MCPServer(
"pdf-extract-mcp",
title="PDF Extract MCP",
description="Deterministic structured-data extraction from PDF documents",
version="0.2.0",
)MCPServer ist die Serverklasse des mcp SDK 2.x. Sie implementiert das MCP-Wire-Protokoll: Sie weiß, wie sie auf die JSON-RPC-Nachrichten antwortet, die ein Client während des MCP-Handshakes sendet (initialize, tools/list, tools/call usw.). Die Konstruktorargumente sind Metadaten – der Server-Name (für den Protokoll-Handshake erforderlich) plus optionale title/description/version, die Clients dem Benutzer anzeigen können.
2. Jedes Werkzeug mit einem Dekorator registrieren.
@mcp.tool()
def extract_fields(pdf_path: str, schema: dict) -> dict:
"""Extract structured fields from an unstructured PDF ..."""
return _extract_fields(pdf_path, schema)Der Dekorator übernimmt für Sie drei Aufgaben:
Namensregistrierung – der Funktionsname extract_fields wird zum Tool-Namen, mit dem ein Client es aufruft. (Sie können ihn mit @mcp.tool(name="...") überschreiben.)
Schema-Ableitung – das SDK untersucht die Typannotationen der Funktion (pdf_path: str, schema: dict) und erzeugt das JSON-Eingabeschema des Werkzeugs automatisch. Deshalb weiß der MCP-Client bereits vor dem Aufruf, dass pdf_path ein String und schema ein Objekt ist. Es ist dasselbe Muster, das FastAPI verwendet – Typen sind der Vertrag.
Beschreibung – der Docstring wird zur Beschreibung des Werkzeugs, die Claude liest, um zu entscheiden, wann das Werkzeug mit welchen Argumenten aufgerufen wird.
Wenn ein Client den Server also fragt: „Was kannst du tun?“ (tools/list), antwortet das SDK mit Name, Beschreibung und abgeleitetem Eingabeschema für jede dekorierte Funktion – keine manuelle Registrierungstabelle, die synchron gehalten werden muss.
3. Der Funktionsrumpf ist einfach Python.
Wenn ein Client das Werkzeug aufruft (tools/call mit Argumenten), deserialisiert das SDK die JSON-Argumente, ruft Ihre Funktion mit ihnen auf und serialisiert den Rückgabewert über die Leitung zurück. Der Rückgabewert ist das, was der Client sieht – deshalb geben die Werkzeuge immer einfache JSON-fähige Dictionaries zurück und werfen niemals eine Exception: Eine Ausnahme würde zu einem undurchsichtigen Protokollfehler, während ein strukturiertes {"ok": false, "error": "..."}-Dictionary etwas ist, das Claude lesen und darauf reagieren kann. Die eigentliche Extraktions-/Validierungslogik liegt in tools/extract.py und tools/validate.py, sodass sie ohne MCP-Client unit-testbar bleibt.
4. Ausführen.
if __name__ == "__main__":
main() # argparse -> mcp.run(transport="stdio")mcp.run(transport="stdio") startet die Protokollschleife: Sie liest zeilenweise begrenzte JSON-RPC-Anfragen von stdin, verteilt sie an die registrierten Werkzeuge und schreibt Antworten nach stdout. Das ist der gesamte Server – kein HTTP-Framework, keine Routen, keine manuelle Anfrageverarbeitung. (Für streamable-http / sse startet derselbe run()-Aufruf eine interne ASGI-App.)
Ein weiteres Detail, das erwähnenswert ist: extract_fields verwendet einen kleinen Helfer _load_schema, der ein Schema-Dictionary, einen integrierten Schema-Namen oder einen Dateipfad akzeptiert – sodass dasselbe Werkzeug mit „invoice“ oder einem vollständigen Schema-Objekt funktioniert. Die eigentliche Extraktionsfunktion bleibt strikt (nur Dictionary) und die Serverebene übernimmt die Komfortkonvertierungen.
So funktioniert die Extraktion (deterministisch, überprüfbar)
Textextraktion – pdfplumber öffnet die PDF und extrahiert den Klartext von jeder Seite.
Feldabgleich – für jede Eigenschaft in Ihrem Schema wird eine geordnete Liste von Regexes durchsucht; der erste Treffer gewinnt (tools/extract.py -> _FIELD_PATTERNS). Die Muster sind zuerst am spezifischsten, und unbekannte Feldnamen fallen auf einen generischen Abgleich „Feldname: Wert“ zurück, zusätzlich zu einer Synonymtabelle (_FIELD_ALIASES).
Typumwandlung – übereinstimmende Strings werden in den JSON-Schema-Typ umgewandelt (z. B. „$1.750,00“ -> 1750.0 für „type“: „number“; bei Arrays durch Komma getrennt). Schlägt die Umwandlung fehl, wird der rohe String verwendet, statt Daten zu verlieren.
Validierung – validate_against_schema prüft die extrahierten Daten erneut mit dem Paket jsonschema und meldet pro Feld, ob es bestanden hat, fehlgeschlagen ist (mit verständlicher Begründung) oder vollständig fehlt.
Da jeder Schritt einfacher Code ist, können Sie genau nachvollziehen, warum ein Feld extrahiert wurde oder nicht – keine Black Box.
Fehlerbehandlung
Alle drei Werkzeuge geben auf jedem Pfad strukturiertes JSON zurück – sie werfen niemals einen Stack-Trace über die MCP-Grenze hinweg:
Beschädigte/nicht lesbare PDF ->
{"ok": false, "error": "Could not read PDF ..."}Nicht vorhandene Datei ->
{"ok": false, "error": "PDF not found: ..."}PDF ohne extrahierbaren Text ->
{"ok": false, "error": "... contains no extractable text."}Ungültiges Schema (leer, ohne Properties oder ungültiges JSON Schema) -> strukturierter Fehlerschlüssel
Fehlende Pflichtfelder -> werden unter „missing“ aufgelistet; fehlerhafte Werte -> unter „failed“ mit Begründungen
Tests
pytest tests/ -v19 Tests, die Folgendes abdecken:
Erfolgreiche Extraktion für alle drei Dokumenttypen (invoice, resume, purchase_order)
Eine PDF mit fehlenden Pflichtfeldern (negative Extraktion)
Schema-Validierung, die einen fehlerhaften Feldtyp, fehlende Pflichtfelder und Enum/Pattern-Verstöße erkennt
Fehlerpfade: beschädigte PDF, nicht vorhandene Datei, PDF ohne Text, ungültiges Schema
Ein echter End-to-End-MCP-Test (tests/test_mcp_end_to_end.py), der server.py als Unterprozess startet, über stdio mit dem offiziellen MCP-Client verbindet und alle drei Werkzeuge über die Leitung aufruft – das beweist, dass es sich um einen echten MCP-Server handelt, nicht um eine Bibliothek, die so tut
Beispiel-PDFs werden bei Bedarf von tests/conftest.py automatisch neu erzeugt.
Repository-Struktur
pdf-extract-mcp/
server.py # MCP server: MCPServer + tool registration + transports
tools/
__init__.py
extract.py # pdfplumber text extraction + regex field matching
validate.py # jsonschema validation with structured reports
schemas/
invoice.json # pre-built schema: invoice
resume.json # pre-built schema: resume
purchase_order.json # pre-built schema: purchase_order
sample_pdfs/
generate_samples.py # reportlab generator for the 4 sample PDFs
invoice.pdf
invoice_missing_fields.pdf
resume.pdf
purchase_order.pdf
tests/
conftest.py # auto-generates sample PDFs if missing
test_tools.py # unit tests for extract/validate
test_mcp_end_to_end.py # end-to-end test over the real MCP stdio transport
README.md
requirements.txtFehlerbehebung
ModuleNotFoundError: No module named 'mcp' – Sie befinden sich nicht in der virtuellen Umgebung: source .venv/bin/activate (oder ./.venv/bin/python server.py verwenden).
FastMCP-Importfehler – server.py zielt auf die mcp-2.x-API (MCPServer). Wenn Ihre Umgebung mcp 1.x hat, installieren Sie neu mit
pip install -U "mcp>=2.0".Werkzeuge erscheinen nicht in Claude – starten Sie den Client nach dem Bearbeiten der Konfiguration neu und stellen Sie sicher, dass „args“ auf den absoluten Pfad zu server.py zeigt, wobei bei Bedarf das Python der venv als Befehl verwendet wird.
Extraktion übersieht ein Feld – fügen Sie ein Muster dafür in _FIELD_PATTERNS in tools/extract.py hinzu (oder verlassen Sie sich auf den generischen „Feldname: Wert“-Fallback und die Synonymtabelle).
Available Tools
3 toolsextract_fieldsB
Extract structured fields from an unstructured PDF using regex/heuristics.
Args: pdf_path: Path to the PDF file. schema: JSON Schema describing the fields to extract (must have a non-empty 'properties' object). A built-in schema name (e.g. "invoice") or a path to a .json schema file is also accepted.
Returns: {"ok": True, "data": {...}, "text_length": N} on success, or {"ok": False, "error": "..."} on failure (corrupt PDF, bad schema, ...).
| Name | Required | Description | Default |
|---|---|---|---|
| schema | Yes | ||
| pdf_path | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. It does disclose failure modes (corrupt PDF, bad schema), the exact return contract ({ok: True/False}), and the non-empty properties requirement. However, it omits the side-effect profile (e.g., read-only disk access) and edge behaviors such as empty extraction results, so disclosure is solid but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in a single line, followed by a clean Args/Returns structure that is scannable. Slightly padded by trailing ellipses and the '...' after the failure list, but overall efficient with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations and no output schema, the description covers the return format, failure modes, and semantic details of both parameters—enough to call the tool correctly. Gaps are minor: no sibling-routing guidance and the meaning of the returned 'text_length' field is undefined.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must supply meaning. It adds substantial context: schema may be a JSON Schema object, a built-in name like 'invoice', or a .json file path, and must have a non-empty 'properties'; pdf_path is explained as a path to the PDF. This goes well beyond the bare type declarations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb (extract), a resource (structured fields), and a source/method (unstructured PDF using regex/heuristics). This clearly distinguishes extraction behavior from list_supported_document_types, though it doesn't explicitly name the differentiation from validate_against_schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to choose this tool versus its siblings. It doesn't mention when validate_against_schema or list_supported_document_types would be the better pick, and states no preconditions or exclusions beyond the inline schema-constraint note in Args. The agent must infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_supported_document_typesB
List document types with pre-built schemas (e.g. invoice, resume, purchase_order).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It weakly implies a read-only operation (listing) but does not explicitly state side effects, authentication requirements, rate limits, or response behavior. The existence of an output schema covers return format, but not behavioral traits. A simple 'List' implies read-only, but for a complete definition more context is expected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that leads with the action and then clarifies with concrete examples. There is no filler, and every word contributes to understanding the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, an output schema exists, and the purpose is simple, the description covers the essentials. It explains what the tool does and gives representative examples. It could add a note about usage direction (e.g., that these types can be used with extract_fields or validate_against_schema), but such cross-referencing is not required for basic invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the input schema is an empty object. According to the rubric, a parameterless tool gets a baseline 4. The description adds no parameter-specific information, but none is needed; the schema is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'List' and a clear resource 'document types with pre-built schemas', including helpful examples (invoice, resume, purchase_order). It clearly conveys the tool's function, though it does not explicitly distinguish it from siblings like extract_fields or validate_against_schema, so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus the sibling tools. The description does not mention alternatives, typical usage scenarios, or any conditions that would make this tool the right choice. This is a clear gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_against_schemaA
Validate extracted data against a JSON Schema.
Args: data: The data to check (e.g. the "data" from extract_fields). schema: JSON Schema to validate against.
Returns: A structured report with passed/failed/missing field lists and a human-readable reason for each failure. Never raises: invalid schemas are reported via the "error" key instead.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | ||
| schema | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses key behavior: never raises exceptions, invalid schemas are reported via an 'error' key, and the return is a structured report with passed/failed/missing lists and human-readable reasons. This goes beyond a generic 'validates' and gives the agent a clear expectation of failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficiently formatted with an Args and Returns section, front-loaded with the purpose sentence. It is not verbose—every line contributes to the agent's understanding. It could be tightened (the Returns section is slightly redundant with the behavioral note), but it's well-structured and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given two required parameters, no output schema, and no annotations, the description covers the essential context: what the tool does, what each parameter is, how errors are handled, and what the response contains. It references the sibling workflow (extract_fields) which aids routing. The only minor gap is that it doesn't specify the expected shape of 'data' beyond being an object, but the example mitigates this.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must explain the parameters. It does: 'data' is explicitly the output of extract_fields, and 'schema' is a JSON Schema. This adds meaning beyond the bare 'object' type in the schema and gives the agent the necessary context for both arguments. It could add more detail about expected structures, but it is sufficient for a two-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource: 'Validate extracted data against a JSON Schema.' It names the specific tool and its input, and the example referencing extract_fields ties it to the workflow. It is clearly distinct from the siblings (list_supported_document_types and extract_fields) because validation is an entirely separate operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use it: after extraction, with the 'data' from extract_fields. It implies the pipeline (extract → validate) without explicitly saying 'use this when...' but the example makes the usage obvious. It does not mention when not to use it or name alternatives, so it lacks an explicit exclusion but is not misleading.
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.
3 tool updates
v0.2.0- First observed
extract_fields - First observed
list_supported_document_types - First observed
validate_against_schema
TDQS
Scored across 3 tools
Each tool serves a clearly distinct purpose: listing supported schemas, extracting fields from a PDF, and validating extracted data against a schema. There is no overlap or ambiguity in tool responsibilities.
All tool names follow a consistent verb_noun pattern in snake_case: list_supported_document_types, extract_fields, validate_against_schema. The convention is uniform and predictable.
With only 3 tools, the set is at the lower end of the well-scoped range but still appropriate for a focused PDF extraction and validation server. Each tool earns its place without redundancy.
The tool surface covers the core workflow: discovering available schemas, extracting fields, and validating results. Minor gaps exist (e.g., no tool to add custom schemas or handle batch processing), but they are not critical for the primary purpose.
Maintenance
Related MCP Connectors
High-fidelity PDF to structured Markdown conversion and document field extraction.
Deterministic PDF tools for AI agents: inspect fields, fill forms, merge PDFs, invoices.
Turn PDFs and photos into typed JSON with your own schema. Missing values come back null.
Turn any PDF into structured JSON via AI + OCR: invoices, bank statements, contracts.
Related MCP Servers
- AlicenseAqualityDmaintenanceExtracts structured JSON data from unstructured text using predefined schemas for receipts, invoices, resumes, and emails. It allows users to transform messy text into organized data through built-in or custom-defined fields.1MIT
- AlicenseAqualityDmaintenanceEnables RAG over messy PDFs — extract, chunk, embed, and search scanned, multi-column, and table-heavy documents.6MIT
- AlicenseNot gradedqualityAmaintenanceExtracts text and tables from PDFs for AI agents via MCP, enabling structured data retrieval from invoices, reports, and statements.75 PyPI1MIT
- FlicenseNot gradedqualityBmaintenanceEnables reading entire PDF documents into validated structured JSON, including tables, key-values, and markdown, with read-only extraction tools and layout reconstruction.-