Ga naar inhoud

Python MCP-server

De NextPDF Python-SDK bevat een Model Context Protocol-server (MCP) die PDF-extractiebewerkingen als native tools beschikbaar maakt voor agents. Een MCP-compatibele agent, zoals Claude Code, registreert de server één keer en roept daarna NextPDF-tools aan zoals elke andere tool.

De server is een dunne adapter. Elke tool leest een PDF van de lokale schijf, roept de async-client van je NextPDF Connect-endpoint aan en geeft het resultaat als JSON-string terug. De server bevat geen bedrijfslogica en bewaart geen gegevens tussen aanroepen.

Installeer de SDK met de MCP-extra:

Terminal window
pip install nextpdf[mcp]

De extra mcp installeert ook het upstream-pakket mcp (beperking mcp>=1.0,<2.0). De server vereist Python 3.10 of nieuwer.

Voer de servermodule uit vanuit je MCP-clientconfiguratie. In het onderstaande voorbeeld worden beide verbindingswaarden uit de host-omgeving gelezen in plaats van een secret in het configuratiebestand op te nemen (zie Beveiliging):

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

Het entrypoint python -m nextpdf.mcp voert main() uit, dat de server via standaardinvoer/-uitvoer (stdio) start met asyncio.run(serve()). Verwar dit niet met python -m nextpdf, dat de command-line interface (CLI) uitvoert en niet de MCP-server.

NEXTPDF_BASE_URL en NEXTPDF_API_KEY zijn vereist. De server maakt de client lazy aan bij de eerste toolaanroep. Als een van beide variabelen leeg is, werpt de server een RuntimeError op en geeft deze als toolfout aan de agent terug in plaats van het proces te laten crashen.

De server registreert acht tools. Elke toolnaam heeft het voorvoegsel nextpdf_. Elke tool wordt toegewezen aan een methode in de ast-namespace van de async-client (AsyncNextPDF.ast), met uitzondering van de twee samengestelde tools die hieronder worden genoemd. De server bouwt die op uit aanroepen op een lager niveau.

MCP-toolSDK-aanroepOpmerkingen
nextpdf_extract_textast.extract_cited_text(pdf_data, page_index=..., headings_only=...)Geeft een lijst van CitedTextBlock terug.
nextpdf_extract_tablesast.extract_cited_tables(pdf_data, page_range=...)Geeft ExtractCitedTablesResponse terug.
nextpdf_get_astast.get_document_ast(pdf_data, page_range_start=0, page_range_end=..., token_budget=...)Geeft AstDocument terug.
nextpdf_infoast.get_document_ast(pdf_data)De server projecteert een metadatasamenvatting; geen specifiek endpoint.
nextpdf_healthgeenInspecteert alleen omgevingsvariabelen; doet geen netwerkaanroep.
nextpdf_searchast.search_ast_nodes(pdf_data, node_type=..., page_index=..., text_query=..., max_results=...)Geeft SearchAstNodesResponse terug.
nextpdf_get_outlineast.search_ast_nodes(pdf_data, node_type="heading", max_results=500)Server vormt kopnodes om tot een overzicht.
nextpdf_diffast.get_ast_diff(original_pdf_data, modified_pdf_data)Geeft GetAstDiffResponse terug.

Houd deze details over de toolinvoer in gedachten voordat je een agent koppelt:

  • Alle padinvoer (pdf_path, original_pdf_path, modified_pdf_path) bestaat uit absolute paden naar bestanden op de machine waarop de server draait. De agent geeft een pad door en de server leest de bytes lokaal. Er is geen uploadtool.
  • nextpdf_extract_text declareert een veld max_pages in het invoerschema, maar de teksthandler geeft dit niet door aan de SDK. Pagina’s voor tekst beperken doe je via page_index (een enkele 0-gebaseerde pagina). Gebruik nextpdf_get_ast met max_pages wanneer je een volledige documentscan wilt begrenzen.
  • nextpdf_get_ast vertaalt max_pages naar een inclusief paginabereik van [0, max_pages - 1] (standaard is max_pages 50). Geef token_budget door om de grootte van de teruggegeven boom te begrenzen.
  • nextpdf_info geeft schema_version, source_hash, page_count, estimated_tokens, root_node_type en root_children_count terug. Deze waarden zijn afkomstig uit het AstDocument-model, waarin estimated_tokens een berekende eigenschap is (ongeveer vier tekens per token).
  • nextpdf_get_outline geeft één item per kop terug met id, page_index, text en depth (gelezen uit attributes["level"] van de node, met standaardwaarde 1), plus heading_count, total_matches en truncated.

De tools voor geciteerde extractie voegen aan elk resultaat een CitationAnchor toe. Elke anchor bevat node_id, page_index, een genormaliseerde bbox (coördinaten in het bereik 0.0 tot 1.0) en een confidence-score (0.0 tot 1.0). Agents die herkomst nodig hebben, moeten deze velden weergeven, niet alleen de ruwe tekst.

De server laat nooit een exception naar het agenttransport ontsnappen. De dispatcher call_tool vangt elke fout op en geeft deze terug als JSON TextContent, zodat een mislukte toolaanroep een gestructureerde payload oplevert die de agent kan lezen in plaats van een verbroken verbinding. Dit zijn de payloadvormen:

ConditieGeretourneerde JSON
Onbekende toolnaam{"error": "Unknown tool: <name>"}
Ontbrekend invoerbestand{"error": "PDF file not found: <path>"}
Een subclass van NextPDFError{"error": "<message>", "error_type": "<class>", "status_code": <int?>}
Elke andere exception{"error": "Unexpected error: <message>"}

status_code verschijnt alleen wanneer de onderliggende fout er een bevat. De SDK wijst HTTP-responses toe aan een getypeerde exception-hiërarchie, die volledig is geworteld in NextPDFError:

ExceptionHTTP-statuserror_codeWanneer
NextPDFLicenseError402license/niveau-requiredHet endpoint vereist een hoger server-side licentieniveau voor de bewerking.
AstNoStructTreeError422ast/no-struct-treeDe PDF is ongetagd en heuristische fallback is niet ingeschakeld op de server.
QuotaExceededError429quota/exceededEr is een rate limit of quotum bereikt. Bevat retry_after (seconden) wanneer de server een Retry-After-header verstuurt.
AstBuildTimeoutError504ast/build-timeoutDe AST-build overschreed het tijdbudget van de server. Verklein het paginabereik.
NextPDFAPIErrorandere 4xx/5xxdoor server geleverdElke andere fout op API-niveau.

Gebruik deze richtlijnen voor agentintegraties:

  • Time-outs. De HTTP-client gebruikt een vaste standaard-time-out: 60 seconden totaal met een connect-time-out van 10 seconden. Een traag of groot document verschijnt als een AstBuildTimeoutError (de server heeft het bouwen van de AST opgegeven) of, als de client zelf een time-out krijgt, als een Unexpected error-payload van de transportlaag. Wanneer je ast/build-timeout ziet, vertel de agent dan om de scope te versmallen: verlaag max_pages op nextpdf_get_ast, of stel page_index / page_start en page_end in op de extractietools.
  • Quota en backoff. Bij een 429 geeft de tool error_type van QuotaExceededError terug met status_code 429. De waarde retry_after bevindt zich op het exception-object. Omdat de server alleen error, error_type en status_code serialiseert, moet de agent 429 behandelen als een signaal om te pauzeren en later opnieuw te proberen, in plaats van een retry-header uit de tooluitvoer te parsen. Handhaaf quota op het Connect-endpoint, niet in de agent.
  • Ongetagde PDF’s. Een 422 ast/no-struct-tree betekent dat de bron-PDF geen structuurboom heeft. Schakel heuristische modus in op de server voor die documenten, of stuur ze naar een tagging-stap voorafgaand aan de extractie.

Beveiliging: scoping van de API-sleutel en least privilege

Sectie met titel “Beveiliging: scoping van de API-sleutel en least privilege”

Behandel de API-sleutel als een secret, met dezelfde zorg als een databasewachtwoord.

  • Neem de sleutel nooit op in het MCP-configuratiebestand. Het bovenstaande JSON-voorbeeld verwijst naar ${NEXTPDF_API_KEY}, zodat de waarde bij het starten wordt opgelost uit de host-omgeving of een secret manager. Een configuratiebestand mag in versiebeheer worden vastgelegd; een secret niet.
  • Beperk de sleutel tot alleen-lezen extractie. De MCP-server roept alleen het AST-extractieoppervlak aan (extract_cited_text, extract_cited_tables, get_document_ast, search_ast_nodes, get_ast_diff). De server rendert, ondertekent, redigeert of muteert geen documenten. Geef de agent een sleutel waarvan de server-side scope beperkt is tot die leespaden, zodat een gecompromitteerde agent geen schrijfbewerkingen of bewerkingen van een hogere niveau kan bereiken.
  • Gebruik een specifieke sleutel per agent. Met een sleutel per agent kun je één integratie intrekken of roteren zonder andere te beïnvloeden, en kun je endpointlogs aan een specifieke agent toewijzen.
  • Beperk het bestandssysteem. Omdat elke tool een absoluut pad van de lokale schijf leest, kan de server elk bestand lezen dat het hostproces kan lezen. Voer de server uit als een niet-bevoorrechte gebruiker, beperk de werkdirectory tot een documentenmap en voer de server nooit uit als een bevoorrecht account.
  • Geef de voorkeur aan Transport Layer Security (TLS). Richt NEXTPDF_BASE_URL op een https://-endpoint voor elke niet-lokale deployment. De SDK verstuurt de sleutel als een Bearer-token in de Authorization-header, zodat transport in platte tekst de sleutel op de verbinding zou blootstellen.

Zie Connect-beveiliging en -operaties voor de endpoint-side controls die deze client-side praktijken ondersteunen.

De server lokaal testen voordat u een agent koppelt

Sectie met titel “De server lokaal testen voordat u een agent koppelt”

Valideer de server geïsoleerd voordat je een agent verbindt. De snelste controle vereist geen PDF en geen netwerk:

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

Een correcte installatie drukt 8 af. Als je een ImportError ziet die verwijst naar de extra mcp, ontbreekt de optionele afhankelijkheid. Installeer opnieuw met pip install nextpdf[mcp].

Test vervolgens via de CLI dezelfde SDK-paden die de tools gebruiken. De CLI communiceert met je endpoint via dezelfde twee omgevingsvariabelen. Stel die eenmalig in:

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

Controleer daarna de versie, connectiviteit en een echte extractie:

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

nextpdf version draait zonder credentials en bevestigt dat het pakket importeert. nextpdf info oefent get_document_ast uit, dezelfde aanroep achter nextpdf_get_ast en nextpdf_info. Als beide slagen, kloppen de credentials en het endpoint en werken de bijbehorende MCP-tools.

Om het MCP-protocol rechtstreeks aan te sturen, gebruik je de upstream MCP Inspector (meegeleverd met het mcp-pakket). Richt deze op hetzelfde commando en dezelfde omgeving die je agent zal gebruiken, en geef vervolgens handmatig tools weer en roep ze aan. Controleer of nextpdf_health status: "ok" rapporteert. De server geeft telkens misconfigured terug wanneer NEXTPDF_BASE_URL of NEXTPDF_API_KEY niet is ingesteld, wat de snelste manier is om een ontbrekende omgevingswaarde te ontdekken voordat een agent een echte tool aanroept.

De MCP-server communiceert via standaardinvoer/-uitvoer (stdio), dus de standaarduitvoer draagt de protocolstream en moet schoon blijven. De server configureert geen eigen applicatielogging. Je primaire observability-kanalen zijn de gestructureerde toolfout-payloads, de CLI en de eigen logs van je endpoint.

  • Toolfout-payloads zijn het belangrijkste signaal. Elke mislukte aanroep geeft een JSON-object terug met error en, voor SDK-fouten, error_type en status_code (zie Foutafhandeling). Laat de agenthost deze payloads vastleggen. Ze identificeren de mislukte tool en de precieze oorzaak zonder extra serverinstrumentatie.
  • Reproduceer via de CLI met debug-logging. De MCP-server zelf produceert geen logs, maar de CLI oefent dezelfde SDK-aanroepen uit en logt wel. Reproduceer een mislukte tool via het bijbehorende CLI-commando met --log-level debug. De CLI logt naar stderr met timestamps en registreert volledige tracebacks voor onverwachte fouten, wat de meest directe manier is om te zien wat een handler doet zonder een debugger te koppelen.
  • Health als probe. Roep nextpdf_health aan om te bevestigen dat de server een base-URL en een API-sleutel ziet. Het resultaat rapporteert sdk_version, server_url, api_key_configured (een boolean, nooit de sleutel zelf) en status.
  • Endpoint-side observability. Omdat elke tool wordt toegewezen aan één Connect-request, correleer je toolactiviteit met de endpoint-toegangslogs aan de hand van API-sleutel en timestamp. Voer het endpoint uit achter dezelfde authenticatie-, quota- en observability-controls die je voor andere serviceclients gebruikt.

Veelvoorkomende problemen met agentintegratie oplossen

Sectie met titel “Veelvoorkomende problemen met agentintegratie oplossen”
SymptoomWaarschijnlijke oorzaakOplossing
Server start niet en geeft een ImportError over de extra mcpDe optionele afhankelijkheid mcp is niet geïnstalleerdInstalleer met pip install nextpdf[mcp].
Eerste toolaanroep geeft {"error": "NEXTPDF_BASE_URL environment variable is required..."} terugHet MCP-blok env gaf de base-URL niet door, of de shell heeft ${NEXTPDF_BASE_URL} niet geëxpandeerdStel de variabele in de agenthost-omgeving in en bevestig dat de launcher deze expandeert.
nextpdf_health rapporteert "status": "misconfigured"Een van de twee vereiste variabelen is leegLever zowel NEXTPDF_BASE_URL als NEXTPDF_API_KEY aan.
Elke pad-gebaseerde tool geeft {"error": "PDF file not found: <path>"} terugDe agent gaf een relatief of host-side pad door dat het serverproces niet kan zienGeef een absoluut pad door dat leesbaar is voor de gebruiker van de server; bevestig met nextpdf info <path>.
Tool geeft error_typeNextPDFLicenseError terug (status 402)De bewerking vereist een hogere server-side licentieniveauGebruik een endpoint en sleutel die rechten hebben voor de bewerking.
Tool geeft error_typeAstNoStructTreeError terug (status 422)De PDF is ongetagd en heuristische fallback staat uitSchakel heuristische modus in op het endpoint, of tag eerst de PDF.
Tool geeft error_typeQuotaExceededError terug (status 429)Een rate limit of quotum is bereiktPauzeer en probeer opnieuw; verhoog het endpoint-quotum als de limiet te laag is.
Tool geeft error_typeAstBuildTimeoutError terug (status 504), of een transport-time-outHet document is te groot voor het tijdbudgetVersmal de scope met max_pages, page_index of page_start/page_end.
De agent registreert geen NextPDF-toolsDe agent riep python -m nextpdf (de CLI) aan in plaats van python -m nextpdf.mcpGebruik python -m nextpdf.mcp voor de command/args.

Voor mislukkingen op endpointniveau en deployment-controles, zie Connect troubleshooting. Voor de SDK-bewerkingen die deze tools omhullen, zie de CLI-referentie en het SDK-overzicht.