Zum Inhalt springen

Python-MCP-Server

Das NextPDF Python-SDK enthält einen Model Context Protocol-Server (MCP), der PDF-Extraktionsoperationen als native Werkzeuge für Agenten bereitstellt. Ein MCP-fähiger Agent, zum Beispiel Claude Code, registriert den Server einmal und ruft NextPDF-Werkzeuge danach genauso auf wie jedes andere Werkzeug.

Der Server ist ein schlanker Adapter. Jedes Werkzeug liest eine PDF von der lokalen Festplatte, sendet die Anfrage über den asynchronen Client an Ihren NextPDF Connect-Endpunkt und liefert das Ergebnis als JSON-String zurück. Der Server selbst enthält keine Geschäftslogik und speichert zwischen Aufrufen keine Daten.

Installieren Sie das SDK mit dem MCP-Extra:

Terminal-Fenster
pip install nextpdf[mcp]

Das mcp-Extra fügt das vorgelagerte mcp-Paket hinzu (Versionsbeschränkung mcp>=1.0,<2.0). Der Server benötigt Python 3.10 oder neuer.

Starten Sie das Servermodul aus Ihrer MCP-Client-Konfiguration heraus. Das folgende Beispiel liest beide Verbindungswerte aus der Host-Umgebung, anstatt ein Secret in die Konfigurationsdatei einzubetten (siehe Sicherheit):

{
"mcpServers": {
"nextpdf": {
"command": "python",
"args": ["-m", "nextpdf.mcp"],
"env": {
"NEXTPDF_BASE_URL": "https://connect.example.com",
"NEXTPDF_API_KEY": "${NEXTPDF_API_KEY}"
}
}
}
}

Der Einstiegspunkt python -m nextpdf.mcp führt main() aus und startet den Server über die Standardein- und -ausgabe (stdio) per asyncio.run(serve()). Verwechseln Sie dies nicht mit python -m nextpdf, das die Kommandozeilenschnittstelle (CLI) startet, nicht den MCP-Server.

NEXTPDF_BASE_URL und NEXTPDF_API_KEY sind beide erforderlich. Der Server initialisiert seinen Client erst beim ersten Werkzeugaufruf. Ist eine der beiden Variablen leer, löst er einen RuntimeError aus, der dem Agenten als Werkzeugfehler zurückgegeben wird, anstatt den Prozess abstürzen zu lassen.

Der Server registriert acht Werkzeuge. Jeder Werkzeugname beginnt mit dem Präfix nextpdf_. Jedes Werkzeug bildet eine Methode im ast-Namensraum des asynchronen Clients ab (AsyncNextPDF.ast), mit Ausnahme der beiden unten genannten zusammengesetzten Werkzeuge, die im Server aus darunterliegenden Aufrufen zusammengesetzt werden.

MCP-WerkzeugSDK-AufrufHinweise
nextpdf_extract_textast.extract_cited_text(pdf_data, page_index=..., headings_only=...)Liefert eine Liste von CitedTextBlock.
nextpdf_extract_tablesast.extract_cited_tables(pdf_data, page_range=...)Liefert ExtractCitedTablesResponse.
nextpdf_get_astast.get_document_ast(pdf_data, page_range_start=0, page_range_end=..., token_budget=...)Liefert AstDocument.
nextpdf_infoast.get_document_ast(pdf_data)Der Server projiziert eine Metadatenzusammenfassung; kein eigener Endpunkt.
nextpdf_healthkeinePrüft nur Umgebungsvariablen; führt keinen Netzwerkaufruf aus.
nextpdf_searchast.search_ast_nodes(pdf_data, node_type=..., page_index=..., text_query=..., max_results=...)Liefert SearchAstNodesResponse.
nextpdf_get_outlineast.search_ast_nodes(pdf_data, node_type="heading", max_results=500)Der Server formt Überschriftenknoten in eine Gliederung um.
nextpdf_diffast.get_ast_diff(original_pdf_data, modified_pdf_data)Liefert GetAstDiffResponse.

Einige Hinweise zu den Werkzeugeingaben, die Sie kennen sollten, bevor Sie einen Agenten anbinden:

  • Alle Pfadeingaben (pdf_path, original_pdf_path, modified_pdf_path) sind absolute Pfade zu Dateien auf der Maschine, die den Server ausführt. Der Agent übergibt einen Pfad; der Server liest die Bytes lokal. Es gibt kein Upload-Werkzeug.
  • nextpdf_extract_text deklariert ein Feld max_pages in seinem Eingabeschema, der Texthandler übergibt es jedoch nicht an das SDK. Die Seiteneingrenzung für Text erfolgt über page_index (eine einzelne 0-basierte Seite). Verwenden Sie nextpdf_get_ast mit max_pages, wenn Sie einen Durchlauf über das gesamte Dokument begrenzen müssen.
  • nextpdf_get_ast übersetzt max_pages in einen inklusiven Seitenbereich von [0, max_pages - 1] (Standardwert von max_pages ist 50). Übergeben Sie token_budget, um die Größe des zurückgegebenen Baums zu begrenzen.
  • nextpdf_info liefert schema_version, source_hash, page_count, estimated_tokens, root_node_type und root_children_count. Diese Werte stammen aus dem AstDocument-Modell, wobei estimated_tokens eine berechnete Eigenschaft ist (ungefähr vier Zeichen pro Token).
  • nextpdf_get_outline liefert einen Eintrag pro Überschrift mit id, page_index, text und depth (gelesen aus attributes["level"] des Knotens, Standardwert 1) sowie heading_count, total_matches und truncated.

Die Werkzeuge zur zitierten Extraktion fügen jedem Ergebnis einen CitationAnchor hinzu. Jeder Anker enthält node_id, page_index, eine normalisierte bbox (Koordinaten im Bereich 0.0 bis 1.0) und einen confidence-Wert (0.0 bis 1.0). Agenten, die Provenance benötigen, sollten diese Felder anzeigen statt nur den rohen Text.

Der Server lässt niemals zu, dass eine Ausnahme bis zum Agenten-Transport durchschlägt. Der Dispatcher call_tool fängt jeden Fehler ab und gibt ihn als JSON-TextContent zurück. Dadurch liefert ein fehlgeschlagener Werkzeugaufruf eine strukturierte Nutzlast, die der Agent lesen kann, anstelle einer abgebrochenen Verbindung. Die Nutzlastformen sind:

BedingungZurückgegebenes JSON
Unbekannter Werkzeugname{"error": "Unknown tool: <name>"}
Fehlende Eingabedatei{"error": "PDF file not found: <path>"}
Jede NextPDFError-Unterklasse{"error": "<message>", "error_type": "<class>", "status_code": <int?>}
Jede andere Ausnahme{"error": "Unexpected error: <message>"}

status_code wird nur dann eingeschlossen, wenn der zugrunde liegende Fehler einen solchen Wert mitführt. Das SDK bildet HTTP-Antworten auf eine typisierte Ausnahmehierarchie ab, die vollständig unter NextPDFError verankert ist:

AusnahmeHTTP-Statuserror_codeWann
NextPDFLicenseError402license/tier-requiredDer Endpunkt erfordert für die Operation eine höhere serverseitige Lizenzstufe.
AstNoStructTreeError422ast/no-struct-treeDie PDF ist nicht getaggt und der heuristische Rückfallmodus ist auf dem Server nicht aktiviert.
QuotaExceededError429quota/exceededEin Ratenlimit oder Kontingent wurde erreicht. Enthält retry_after (Sekunden), wenn der Server einen Retry-After-Header sendet.
AstBuildTimeoutError504ast/build-timeoutDer AST-Aufbau hat das Zeitbudget des Servers überschritten. Verkleinere den Seitenbereich.
NextPDFAPIErrorandere 4xx/5xxserverseitig bereitgestelltJeder andere Fehler auf API-Ebene.

Praktische Hinweise für Agenten-Integrationen:

  • Timeouts. Der HTTP-Client verwendet ein festes Standard-Timeout: 60 Sekunden insgesamt mit einem Verbindungs-Timeout von 10 Sekunden. Ein langsames oder großes Dokument äußert sich entweder als AstBuildTimeoutError (der Server hat den AST-Aufbau aufgegeben) oder, falls der Client selbst ein Timeout erreicht, als Unexpected error-Nutzlast aus der Transportschicht. Wenn Sie ast/build-timeout sehen, weisen Sie den Agenten an, den Umfang einzugrenzen: senken Sie max_pages bei nextpdf_get_ast, oder setzen Sie page_index / page_start und page_end bei den Extraktionswerkzeugen.
  • Kontingent und Backoff. Bei einem 429 liefert das Werkzeug error_type als QuotaExceededError und status_code 429. Der Wert retry_after liegt auf dem Ausnahmeobjekt. Da der Server nur error, error_type und status_code serialisiert, sollte der Agent 429 als Signal behandeln, eine Pause einzulegen und es später erneut zu versuchen, statt einen Retry-Header aus der Werkzeugausgabe zu parsen. Erzwingen Sie Kontingente am Connect-Endpunkt, nicht im Agenten.
  • Nicht getaggte PDFs. Ein 422 ast/no-struct-tree bedeutet, dass die Quell-PDF keinen Strukturbaum hat. Aktivieren Sie für diese Dokumente den heuristischen Modus auf dem Server, oder leiten Sie sie vor der Extraktion durch einen Tagging-Schritt.

Sicherheit: API-Schlüssel-Scoping und geringste Rechte

Abschnitt betitelt „Sicherheit: API-Schlüssel-Scoping und geringste Rechte“

Behandeln Sie den API-Schlüssel als Secret mit derselben Sorgfalt, die Sie einem Datenbankpasswort entgegenbringen.

  • Betten Sie den Schlüssel niemals in die MCP-Konfigurationsdatei ein. Das JSON-Beispiel oben verweist auf ${NEXTPDF_API_KEY}, sodass sich der Wert beim Start aus der Host-Umgebung oder einem Secret-Manager auflöst. Eine Konfigurationsdatei landet in der Versionskontrolle; ein Secret darf das nicht.
  • Begrenzen Sie den Schlüssel auf reine Leseextraktion. Der MCP-Server ruft nur die AST-Extraktionsoberfläche auf (extract_cited_text, extract_cited_tables, get_document_ast, search_ast_nodes, get_ast_diff). Er führt kein Rendering, keine Signierung, keine Schwärzung und keine Dokumentmutation durch. Stellen Sie dem Agenten einen Schlüssel aus, dessen serverseitiger Geltungsbereich auf diese Lesepfade begrenzt ist, damit ein kompromittierter Agent keine Schreib- oder höherstufigen Operationen erreichen kann.
  • Verwenden Sie einen eigenen Schlüssel pro Agent. Ein Schlüssel pro Agent ermöglicht es Ihnen, eine Integration zu widerrufen oder zu rotieren, ohne andere zu beeinträchtigen, und macht Endpunkt-Logs einem bestimmten Agenten zuordenbar.
  • Schränken Sie das Dateisystem ein. Da jedes Werkzeug einen absoluten Pfad von der lokalen Festplatte liest, kann der Server jede Datei lesen, die der Hostprozess lesen kann. Führen Sie ihn als unprivilegierter Benutzer aus, beschränken Sie sein Arbeitsverzeichnis auf einen Dokumentenordner und führen Sie ihn niemals als privilegiertes Konto aus.
  • Bevorzugen Sie Transport Layer Security (TLS). Richten Sie NEXTPDF_BASE_URL in jedem nicht-lokalen Deployment auf einen https://-Endpunkt aus. Das SDK sendet den Schlüssel als Bearer-Token im Authorization-Header, daher würde ein Klartext-Transport ihn während der Übertragung offenlegen.

Weitere Informationen zu den endpunktseitigen Kontrollen, die diese clientseitigen Praktiken absichern, finden Sie unter Connect-Sicherheit und -Betrieb.

Den Server lokal testen, bevor Sie einen Agenten anbinden

Abschnitt betitelt „Den Server lokal testen, bevor Sie einen Agenten anbinden“

Validieren Sie den Server isoliert, bevor Sie einen Agenten anbinden. Die schnellste Prüfung erfordert keine PDF und kein Netzwerk:

Terminal-Fenster
python -c "from nextpdf.mcp import _tool_definitions; print(len(_tool_definitions()))"

Eine korrekte Installation gibt 8 aus. Wenn Sie einen ImportError sehen, der das mcp-Extra erwähnt, fehlt die optionale Abhängigkeit. Installieren Sie in diesem Fall erneut mit pip install nextpdf[mcp].

Üben Sie als Nächstes dieselben SDK-Pfade, die die Werkzeuge nutzen, über die CLI aus. Die CLI kommuniziert mit Ihrem Endpunkt über dieselben zwei Umgebungsvariablen. Setzen Sie sie einmalig:

Terminal-Fenster
export NEXTPDF_BASE_URL="https://connect.example.com"
export NEXTPDF_API_KEY="$(cat /run/secrets/nextpdf_api_key)"

Bestätigen Sie dann Version, Konnektivität und eine echte Extraktion:

Terminal-Fenster
nextpdf version
nextpdf info /path/to/sample.pdf
nextpdf extract text /path/to/sample.pdf --headings-only

nextpdf version läuft ohne Zugangsdaten und bestätigt, dass das Paket importiert werden kann. nextpdf info führt get_document_ast aus, denselben Aufruf, der hinter nextpdf_get_ast und nextpdf_info steht. Wenn beide erfolgreich sind, sind Zugangsdaten und Endpunkt korrekt und die passenden MCP-Werkzeuge funktionieren.

Um das MCP-Protokoll direkt anzusteuern, verwenden Sie den vorgelagerten MCP Inspector, der mit dem mcp-Paket ausgeliefert wird. Richten Sie ihn auf denselben Befehl und dieselbe Umgebung aus, die Ihr Agent verwenden wird, listen Sie dann die Werkzeuge auf und rufen Sie sie von Hand auf. Prüfen Sie, dass nextpdf_health status: "ok" meldet. Es meldet misconfigured, sobald NEXTPDF_BASE_URL oder NEXTPDF_API_KEY nicht gesetzt ist. Das ist der schnellste Weg, einen fehlenden Umgebungswert zu erkennen, bevor ein Agent jemals ein echtes Werkzeug aufruft.

Der MCP-Server kommuniziert über stdio, daher trägt seine Standardausgabe den Protokollstrom und muss sauber bleiben. Der Server konfiguriert kein eigenes Anwendungslogging. Ihre primären Beobachtungskanäle sind daher die strukturierten Werkzeugfehler-Nutzlasten, die CLI und die eigenen Logs Ihres Endpunkts.

  • Werkzeugfehler-Nutzlasten sind das Signal. Jeder fehlgeschlagene Aufruf liefert ein JSON-Objekt mit error und, bei SDK-Fehlern, error_type und status_code (siehe Fehlerbehandlung). Lassen Sie den Agenten-Host diese Nutzlasten aufzeichnen; sie identifizieren das fehlgeschlagene Werkzeug und die genaue Ursache ohne zusätzliche Instrumentierung im Server.
  • Reproduzieren Sie über die CLI mit Debug-Logging. Der MCP-Server selbst gibt keine Logs aus, aber die CLI führt dieselben SDK-Aufrufe aus und loggt dabei. Reproduzieren Sie ein fehlgeschlagenes Werkzeug über den passenden CLI-Befehl mit --log-level debug. Die CLI loggt mit Zeitstempeln nach stderr und zeichnet vollständige Tracebacks für unerwartete Fehler auf. Das ist der direkteste Weg, zu sehen, was ein Handler tut, ohne einen Debugger anzuhängen.
  • Health als Sonde. Rufen Sie nextpdf_health auf, um zu bestätigen, dass der Server eine Basis-URL und einen API-Schlüssel sieht. Das Ergebnis meldet sdk_version, server_url, api_key_configured (ein boolescher Wert, niemals der Schlüssel selbst) und status.
  • Endpunktseitige Beobachtbarkeit. Da jedes Werkzeug auf eine Connect-Anfrage abbildet, korrelieren Sie Werkzeugaktivität mit den Zugriffslogs des Endpunkts über API-Schlüssel und Zeitstempel. Betreiben Sie den Endpunkt hinter denselben Authentifizierungs-, Kontingent- und Beobachtbarkeitskontrollen, die Sie für andere Service-Clients nutzen.

Häufige Probleme bei der Agentenintegration beheben

Abschnitt betitelt „Häufige Probleme bei der Agentenintegration beheben“
SymptomWahrscheinliche UrsacheLösung
Der Server startet nicht und meldet einen ImportError wegen des mcp-ExtrasDie optionale Abhängigkeit mcp ist nicht installiertInstallieren Sie mit pip install nextpdf[mcp].
Der erste Werkzeugaufruf liefert {"error": "NEXTPDF_BASE_URL environment variable is required..."}Der MCP-env-Block hat die Basis-URL nicht übergeben, oder die Shell hat ${NEXTPDF_BASE_URL} nicht expandiertSetzen Sie die Variable in der Host-Umgebung des Agenten und bestätigen Sie, dass der Launcher sie expandiert.
nextpdf_health meldet "status": "misconfigured"Eine der beiden erforderlichen Variablen ist leerGeben Sie sowohl NEXTPDF_BASE_URL als auch NEXTPDF_API_KEY an.
Jedes pfadbasierte Werkzeug liefert {"error": "PDF file not found: <path>"}Der Agent hat einen relativen oder hostseitigen Pfad übergeben, den der Serverprozess nicht sehen kannÜbergeben Sie einen absoluten Pfad, der vom Benutzer des Servers lesbar ist; bestätigen Sie mit nextpdf info <path>.
Das Werkzeug liefert error_typeNextPDFLicenseError (Status 402)Die Operation benötigt eine höhere serverseitige LizenzstufeVerwenden Sie einen Endpunkt und einen Schlüssel, die zur Operation berechtigt sind.
Das Werkzeug liefert error_typeAstNoStructTreeError (Status 422)Die PDF ist nicht getaggt und der heuristische Rückfallmodus ist deaktiviertAktivieren Sie den heuristischen Modus am Endpunkt, oder taggen Sie die PDF zuerst.
Das Werkzeug liefert error_typeQuotaExceededError (Status 429)Ein Ratenlimit oder Kontingent wurde erreichtPausieren Sie und versuchen Sie es erneut; erhöhen Sie das Endpunkt-Kontingent, falls das Limit zu niedrig ist.
Das Werkzeug liefert error_typeAstBuildTimeoutError (Status 504) oder ein Transport-TimeoutDas Dokument ist zu groß für das ZeitbudgetGrenzen Sie den Umfang mit max_pages, page_index oder page_start/page_end ein.
Der Agent registriert keine NextPDF-WerkzeugeDer Agent hat python -m nextpdf (die CLI) statt python -m nextpdf.mcp verwendetVerwenden Sie python -m nextpdf.mcp als command/args.

Für Fehler auf Endpunktebene und Deployment-Prüfungen siehe Connect-Fehlerbehebung. Für die zugrunde liegenden SDK-Operationen, die diese Werkzeuge umhüllen, siehe die CLI-Referenz und die SDK-Übersicht.