Salta ai contenuti

Server MCP Python

L’SDK Python di NextPDF include un server Model Context Protocol (MCP) che espone le operazioni di estrazione PDF come strumenti nativi per gli agenti. Un agente compatibile con MCP — ad esempio Claude Code — registra il server una sola volta e poi richiama gli strumenti NextPDF come qualsiasi altro strumento.

Il server è un adattatore leggero. Ogni strumento legge un PDF dal disco locale, richiama il client asincrono verso l’endpoint NextPDF Connect e restituisce il risultato come stringa JSON. Il server in sé non contiene logica di business e non conserva alcun dato tra una chiamata e l’altra.

Installare l’SDK con l’extra MCP:

Terminal window
pip install nextpdf[mcp]

L’extra mcp aggiunge il pacchetto mcp upstream (vincolo mcp>=1.0,<2.0). Il server richiede Python 3.10 o versione successiva.

Avviare il modulo del server dalla configurazione del client MCP. L’esempio seguente legge entrambi i valori di connessione dall’ambiente host anziché incorporare un segreto nel file di configurazione (vedere Sicurezza):

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

Il punto di ingresso python -m nextpdf.mcp esegue main(), che avvia il server tramite lo standard input/output (stdio) con asyncio.run(serve()). Non va confuso con python -m nextpdf, che esegue l’interfaccia a riga di comando (CLI) e non il server MCP.

NEXTPDF_BASE_URL e NEXTPDF_API_KEY sono entrambe obbligatorie. Il server inizializza il proprio client in modo lazy alla prima chiamata di uno strumento. Se una delle due variabili è vuota, viene generato un RuntimeError che viene restituito all’agente come errore dello strumento, anziché terminare il processo.

Il server registra otto strumenti. Ogni nome di strumento ha il prefisso nextpdf_. Ciascuno è mappato su un metodo dello spazio dei nomi ast del client asincrono (AsyncNextPDF.ast), a eccezione dei due strumenti compositi indicati di seguito, che vengono assemblati all’interno del server a partire da chiamate di livello inferiore.

Strumento MCPChiamata SDKNote
nextpdf_extract_textast.extract_cited_text(pdf_data, page_index=..., headings_only=...)Restituisce un elenco di CitedTextBlock.
nextpdf_extract_tablesast.extract_cited_tables(pdf_data, page_range=...)Restituisce ExtractCitedTablesResponse.
nextpdf_get_astast.get_document_ast(pdf_data, page_range_start=0, page_range_end=..., token_budget=...)Restituisce AstDocument.
nextpdf_infoast.get_document_ast(pdf_data)Il server proietta un riepilogo dei metadati; nessun endpoint dedicato.
nextpdf_healthnessunaEsamina solo le variabili d’ambiente; non esegue alcuna chiamata di rete.
nextpdf_searchast.search_ast_nodes(pdf_data, node_type=..., page_index=..., text_query=..., max_results=...)Restituisce SearchAstNodesResponse.
nextpdf_get_outlineast.search_ast_nodes(pdf_data, node_type="heading", max_results=500)Il server rimodella i nodi di intestazione in una struttura.
nextpdf_diffast.get_ast_diff(original_pdf_data, modified_pdf_data)Restituisce GetAstDiffResponse.

Alcune note sugli input degli strumenti prima di collegare un agente:

  • Tutti gli input di percorso (pdf_path, original_pdf_path, modified_pdf_path) sono percorsi assoluti di file sulla macchina che esegue il server. L’agente passa un percorso; il server legge i byte in locale. Non esiste alcuno strumento di caricamento.
  • nextpdf_extract_text dichiara un campo max_pages nel proprio schema di input, ma il gestore del testo non lo passa all’SDK. La delimitazione delle pagine per il testo avviene tramite page_index (una singola pagina con indice a base 0). Usare nextpdf_get_ast con max_pages quando occorre delimitare un’analisi dell’intero documento.
  • nextpdf_get_ast converte max_pages in un intervallo inclusivo di pagine [0, max_pages - 1] (il valore predefinito di max_pages è 50). Passare token_budget per limitare la dimensione dell’albero restituito.
  • nextpdf_info restituisce schema_version, source_hash, page_count, estimated_tokens, root_node_type e root_children_count. Questi valori provengono dal modello AstDocument, dove estimated_tokens è una proprietà calcolata (all’incirca quattro caratteri per token).
  • nextpdf_get_outline restituisce una voce per ogni intestazione con id, page_index, text e depth (letto dall’attributo attributes["level"] del nodo, con valore predefinito 1), oltre a heading_count, total_matches e truncated.

Gli strumenti di estrazione con citazioni allegano un CitationAnchor a ogni risultato. Ogni ancora contiene node_id, page_index, un bbox normalizzato (coordinate nell’intervallo da 0.0 a 1.0) e un punteggio di confidence (da 0.0 a 1.0). Gli agenti che necessitano della provenienza dovrebbero esporre questi campi anziché soltanto il testo grezzo.

Il server non lascia mai che un’eccezione raggiunga il trasporto dell’agente. Il dispatcher call_tool intercetta ogni errore e lo restituisce come TextContent JSON, in modo che una chiamata a uno strumento fallita produca un payload strutturato leggibile dall’agente anziché una connessione interrotta. I formati del payload sono:

CondizioneJSON restituito
Nome dello strumento sconosciuto{"error": "Unknown tool: <name>"}
File di input mancante{"error": "PDF file not found: <path>"}
Qualsiasi NextPDFError o sottoclasse{"error": "<message>", "error_type": "<class>", "status_code": <int?>}
Qualsiasi altra eccezione{"error": "Unexpected error: <message>"}

status_code è incluso solo quando l’errore sottostante lo contiene. L’SDK mappa le risposte HTTP su una gerarchia di eccezioni tipizzata, con radice in NextPDFError:

EccezioneStato HTTPerror_codeQuando
NextPDFLicenseError402license/tier-requiredL’endpoint richiede un livello di licenza lato server superiore per l’operazione.
AstNoStructTreeError422ast/no-struct-treeIl PDF non è taggato e il fallback euristico non è abilitato sul server.
QuotaExceededError429quota/exceededÈ stato raggiunto un limite di frequenza o una quota. Contiene retry_after (in secondi) quando il server invia un’intestazione Retry-After.
AstBuildTimeoutError504ast/build-timeoutLa costruzione dell’AST ha superato il budget di tempo del server. Ridurre l’intervallo di pagine.
NextPDFAPIErroraltri 4xx/5xxfornito dal serverQualsiasi altro errore a livello API.

Indicazioni pratiche per le integrazioni degli agenti:

  • Timeout. Il client HTTP usa un timeout predefinito fisso — 60 secondi complessivi con un timeout di connessione di 10 secondi. Un documento lento o di grandi dimensioni si manifesta come un AstBuildTimeoutError (il server ha rinunciato a costruire l’AST) oppure, se scade il client stesso, come un payload Unexpected error dal livello di trasporto. Quando compare ast/build-timeout, istruire l’agente a restringere l’ambito: ridurre max_pages su nextpdf_get_ast, oppure impostare page_index / page_start e page_end sugli strumenti di estrazione.
  • Quota e backoff. In caso di 429, lo strumento restituisce error_type pari a QuotaExceededError e status_code 429. Il valore retry_after risiede sull’oggetto eccezione. Poiché il server serializza solo error, error_type e status_code, l’agente dovrebbe trattare il 429 come un segnale per mettere in pausa e riprovare in seguito, anziché analizzare un’intestazione di retry dall’output dello strumento. Applicare le quote sull’endpoint Connect, non nell’agente.
  • PDF non taggati. Un 422 ast/no-struct-tree significa che il PDF di origine non ha un albero della struttura. Abilitare la modalità euristica sul server per quei documenti, oppure instradarli verso una fase di tagging prima dell’estrazione.

Sicurezza: ambito della chiave API e privilegio minimo

Sezione intitolata “Sicurezza: ambito della chiave API e privilegio minimo”

Trattare la chiave API come un segreto, con la stessa cura riservata a una password di database.

  • Non incorporare mai la chiave nel file di configurazione MCP. L’esempio JSON precedente fa riferimento a ${NEXTPDF_API_KEY} in modo che il valore venga risolto dall’ambiente host o da un gestore di segreti al momento dell’avvio. Un file di configurazione può finire nel controllo del codice sorgente; un segreto non deve finirci.
  • Limitare la chiave all’estrazione in sola lettura. Il server MCP richiama solo la superficie di estrazione AST (extract_cited_text, extract_cited_tables, get_document_ast, search_ast_nodes, get_ast_diff). Non esegue alcun rendering, firma, redazione o mutazione del documento. Rilasciare all’agente una chiave il cui ambito lato server sia limitato a tali percorsi di lettura, in modo che un agente compromesso non possa raggiungere operazioni di scrittura o di livello superiore.
  • Usare una chiave dedicata per ogni agente. Una chiave per agente consente di revocare o ruotare un’integrazione senza incidere sulle altre e rende i log dell’endpoint attribuibili a un agente specifico.
  • Limitare il file system. Poiché ogni strumento legge un percorso assoluto dal disco locale, il server può leggere qualsiasi file leggibile dal processo host. Eseguirlo come utente senza privilegi, limitarne la directory di lavoro a una cartella di documenti e non eseguirlo mai con un account privilegiato.
  • Preferire Transport Layer Security (TLS). Puntare NEXTPDF_BASE_URL a un endpoint https:// in qualsiasi distribuzione non locale. L’SDK invia la chiave come token Bearer nell’intestazione Authorization, quindi un trasporto in chiaro la esporrebbe sulla rete.

Vedere Sicurezza e operazioni di Connect per i controlli lato endpoint che supportano queste pratiche lato client.

Test del server in locale prima di collegare un agente

Sezione intitolata “Test del server in locale prima di collegare un agente”

Convalidare il server in isolamento prima di collegare un agente. Il controllo più rapido non richiede alcun PDF né alcuna rete:

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

Un’installazione corretta stampa 8. Se compare un ImportError che menziona l’extra mcp, la dipendenza opzionale è mancante — reinstallare con pip install nextpdf[mcp].

Successivamente, esercitare tramite la CLI gli stessi percorsi dell’SDK usati dagli strumenti. La CLI comunica con l’endpoint usando le stesse due variabili d’ambiente. Impostarle una volta:

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

Quindi verificare versione, connettività e una vera estrazione:

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

nextpdf version viene eseguito senza credenziali e conferma che il pacchetto sia importabile. nextpdf info esercita get_document_ast, la stessa chiamata alla base di nextpdf_get_ast e nextpdf_info. Se entrambi vanno a buon fine, le credenziali e l’endpoint sono corretti e i corrispondenti strumenti MCP funzioneranno.

Per pilotare direttamente il protocollo MCP, usare l’MCP Inspector upstream (incluso nel pacchetto mcp). Puntarlo allo stesso comando e allo stesso ambiente che userà l’agente, quindi elencare e invocare gli strumenti manualmente. Verificare che nextpdf_health riporti status: "ok". Restituisce misconfigured ogni volta che NEXTPDF_BASE_URL o NEXTPDF_API_KEY non è impostata, ed è il modo più rapido per intercettare un valore d’ambiente mancante prima ancora che un agente richiami uno strumento reale.

Monitoraggio e debug delle chiamate agli strumenti

Sezione intitolata “Monitoraggio e debug delle chiamate agli strumenti”

Il server MCP comunica tramite stdio, quindi il suo standard output trasporta il flusso del protocollo e deve rimanere pulito. Il server non configura un proprio logging applicativo; i principali canali di osservabilità sono quindi i payload strutturati di errore degli strumenti, la CLI e i log dell’endpoint in uso.

  • I payload di errore degli strumenti sono il segnale. Ogni chiamata fallita restituisce un oggetto JSON con error e, per gli errori dell’SDK, error_type e status_code (vedere Gestione degli errori). Fare in modo che l’host dell’agente registri questi payload; identificano lo strumento che fallisce e la causa precisa senza alcuna strumentazione aggiuntiva nel server.
  • Riprodurre tramite la CLI con il logging di debug. Il server MCP stesso non emette log, ma la CLI esercita le stesse chiamate dell’SDK e registra i log. Riprodurre uno strumento che fallisce tramite il comando CLI corrispondente con --log-level debug. La CLI scrive i log su stderr con timestamp e annota i traceback completi per gli errori imprevisti, il modo più diretto per vedere cosa sta facendo un gestore senza collegare un debugger.
  • Health come sonda. Richiamare nextpdf_health per verificare che il server veda un URL di base e una chiave API. Il risultato riporta sdk_version, server_url, api_key_configured (un valore booleano, mai la chiave stessa) e status.
  • Osservabilità lato endpoint. Poiché ogni strumento è mappato su una singola richiesta Connect, correlare l’attività degli strumenti con i log di accesso dell’endpoint per chiave API e timestamp. Eseguire l’endpoint dietro gli stessi controlli di autenticazione, quota e osservabilità usati per gli altri client di servizio.

Risoluzione dei problemi comuni di integrazione degli agenti

Sezione intitolata “Risoluzione dei problemi comuni di integrazione degli agenti”
SintomoCausa probabileSoluzione
Il server non si avvia con un ImportError relativo all’extra mcpLa dipendenza opzionale mcp non è installataInstallare con pip install nextpdf[mcp].
La prima chiamata a uno strumento restituisce {"error": "NEXTPDF_BASE_URL environment variable is required..."}Il blocco env MCP non ha passato l’URL di base, oppure la shell non ha espanso ${NEXTPDF_BASE_URL}Impostare la variabile nell’ambiente host dell’agente e verificare che il launcher la espanda.
nextpdf_health riporta "status": "misconfigured"Una delle due variabili obbligatorie è vuotaFornire sia NEXTPDF_BASE_URL sia NEXTPDF_API_KEY.
Ogni strumento basato su percorso restituisce {"error": "PDF file not found: <path>"}L’agente ha passato un percorso relativo o lato host a cui il processo del server non può accederePassare un percorso assoluto leggibile dall’utente del server; verificare con nextpdf info <path>.
Lo strumento restituisce error_typeNextPDFLicenseError (stato 402)L’operazione necessita di un livello di licenza lato server superioreUsare un endpoint e una chiave abilitati per l’operazione.
Lo strumento restituisce error_typeAstNoStructTreeError (stato 422)Il PDF non è taggato e il fallback euristico è disattivatoAbilitare la modalità euristica sull’endpoint, oppure taggare prima il PDF.
Lo strumento restituisce error_typeQuotaExceededError (stato 429)È stato raggiunto un limite di frequenza o una quotaMettere in pausa e riprovare; aumentare la quota dell’endpoint se il limite è troppo basso.
Lo strumento restituisce error_typeAstBuildTimeoutError (stato 504), oppure un timeout di trasportoIl documento è troppo grande per il budget di tempoRestringere l’ambito con max_pages, page_index o page_start/page_end.
L’agente non registra alcuno strumento NextPDFL’agente ha invocato python -m nextpdf (la CLI) anziché python -m nextpdf.mcpUsare python -m nextpdf.mcp come command/args.

Per gli errori a livello di endpoint e i controlli di distribuzione, vedere Risoluzione dei problemi di Connect. Per le operazioni SDK sottostanti che questi strumenti incapsulano, vedere il riferimento della CLI e la panoramica dell’SDK.