Connect: guida per sviluppatori
In breve
Sezione intitolata “In breve”NextPDF Connect (nextpdf/server) incapsula in un servizio indipendente dal framework il motore PDF 2.0 di NextPDF. Non reimplementa la generazione di PDF. Espone ogni funzionalità del motore come strumento con nome e schema descrittivo e pubblica il catalogo su tre trasporti: Model Context Protocol (MCP) su standard input e output, un’API (Application Programming Interface) REST (Representational State Transfer) e gRPC. Usare questa guida quando si lavora sul server, se ne estende l’insieme di strumenti o lo si gestisce in produzione.
L’intero progetto si fonda su tre concetti: il registro degli strumenti, i tre trasporti indipendenti e il gate di conferma con intervento umano (human-in-the-loop, HITL). Questa pagina spiega come questi elementi si integrano tra loro e come utilizzarli senza indebolire il modello di sicurezza. Per i simboli esatti di strumenti, RPC e messaggi, consultare la documentazione di riferimento dell’API.
Prerequisiti: PHP 8.4, Composer 2 e, per i trasporti di rete, il binario RoadRunner e almeno una chiave API. Installare con composer require nextpdf/server.
Confine architetturale
Sezione intitolata “Confine architetturale”Mantenere ogni responsabilità dal lato corretto del rispettivo confine. Uno strumento è un wrapper sottile attorno a una chiamata al motore; non deve contenere interpretazione dell’impaginazione, semantica del documento o logica di trasformazione.
| Livello | Di competenza di | Responsabilità | Non collocare qui |
|---|---|---|---|
| Client o agente | La propria integrazione | Decidere quale strumento chiamare; inoltrare a una persona le richieste di conferma. | Logica del motore o rilevamento dei livelli. |
| Trasporto | nextpdf/server | Gestire il framing delle richieste (JSON-RPC, HTTP o Protocol Buffers), autenticare e instradare verso l’esecutore degli strumenti. | Semantica del documento. |
| Registro degli strumenti | nextpdf/server | Rilevare i livelli, registrare gli strumenti nel rispetto dell’allowlist di sicurezza, risolvere uno strumento per nome. | Generazione di PDF. |
| Strumento | nextpdf/server | Convalidare gli argomenti rispetto allo schema di input e chiamare il motore. | Interpretazione dell’impaginazione o orchestrazione in più fasi. |
| Gate di conferma | nextpdf/server | Mantenere in sospeso un’operazione ApprovalRequired finché una persona non la autorizza. | Autenticazione del chiamante. |
| Motore | nextpdf/core (e nextpdf/premium) | Generare, ispezionare e trasformare il contenuto dei PDF. | Aspetti di trasporto o autenticazione. |
Ciclo di vita di runtime
Sezione intitolata “Ciclo di vita di runtime”Ogni trasporto ha un punto di ingresso e una factory di avvio propri, e ciascuno costruisce esplicitamente il proprio grafo di oggetti. Non esiste alcun container di dependency injection da configurare.
- Caricare la configurazione. Il server MCP risolve la configurazione dando precedenza alle variabili d’ambiente (
NEXTPDF_MCP_*) sulla sezionenextpdf_mcpdel file YAML, e a quest’ultima sui valori predefiniti incorporati; il risultato è unreadonlyMcpConfig. I server REST e gRPC leggonoHttpConfigdalle variabili d’ambienteNEXTPDF_*. Vedere Configurazione. - Costruire i criteri di sicurezza. L’allowlist
enabled_toolsviene costruita prima del registro, così da vincolare l’individuazione già dalla prima registrazione. - Costruire il registro e individuare gli strumenti.
ToolRegistry::registerDefaults()registra il livello core, poi i provider Pro ed Enterprise quando le loro classi vengono risolte e infine i provider AST e di mutation in bundle, in base ai rispettivi gate d’ambiente. - Costruire gli store condivisi e il gate. Lo store dei documenti in memoria viene costruito a partire da TTL e capacità configurati; il
ConfirmationGateviene assemblato con il proprio store di token monouso. - Collegare il trasporto. MCP entra in un ciclo leggi-gestisci-scrivi su stdio fino alla fine del file. REST e gRPC costruiscono la propria tabella di route o di servizi a partire dai livelli rilevati e affidano il ciclo delle richieste a RoadRunner.
A quel punto, una richiesta segue questo flusso: autenticazione (REST e gRPC), risoluzione dello strumento o dell’operazione, esecuzione del gate di conferma per le operazioni ApprovalRequired, esecuzione sul motore e restituzione del risultato. Vedere Avvio e individuazione.
Modello di trasporto
Sezione intitolata “Modello di trasporto”A livello concettuale, i tre trasporti condividono il registro, la configurazione e il gate, ma sono processi indipendenti. Avviarne uno non avvia gli altri.
| Trasporto | Punto di ingresso | Quando sceglierlo |
|---|---|---|
| MCP | bin/nextpdf-mcp | Un client IA locale che avvia il server come sottoprocesso attendibile. |
| REST | bin/nextpdf-server | Client HTTP in rete, con interfaccia descritta da un documento OpenAPI 3.1. |
| gRPC | bin/nextpdf-grpc | Client tipizzati e in streaming, tramite il servizio nextpdf.connect.v1.NextPDFConnect. |
Scegliere i trasporti in base al profilo RoadRunner che si esegue: .rr.yaml (solo REST), .rr.grpc.yaml (solo gRPC) o .rr.full.yaml (entrambi). Il trasporto MCP è un semplice sottoprocesso e non richiede alcun supervisore. I dettagli di protocollo per ciascun trasporto sono riportati in Trasporto MCP, Trasporto REST e Trasporto gRPC.
Struttura di distribuzione consigliata
Sezione intitolata “Struttura di distribuzione consigliata”Eseguire i trasporti di rete sotto RoadRunner con store condivisi e chiavi montate come segreti. Il profilo combinato consente a REST e gRPC di condividere un unico supervisore.
| Percorso o impostazione | Scopo |
|---|---|
.rr.full.yaml | Profilo REST e gRPC combinato sotto un unico supervisore. |
NEXTPDF_API_KEYS_FILE | Percorso di un file di chiavi API montato come segreto e ricaricato a caldo. |
NEXTPDF_REDIS_HOST | Abilita gli store di rate limiting, idempotenza e documenti con backend Redis per i pool con più worker. |
NEXTPDF_WORKER_COUNT / NEXTPDF_GRPC_WORKER_COUNT | Dimensionamento del pool di worker per i pool HTTP e gRPC. |
| Directory di base per l’output | Volume dedicato con permessi del filesystem a privilegio minimo per gli strumenti che producono file. |
L’esempio shell seguente avvia il profilo combinato con chiavi montate come segreti e uno store Redis condiviso. Non contiene segreti nel file in sé; le chiavi sono montate in /run/secrets/api-keys.
export NEXTPDF_API_KEYS_FILE=/run/secrets/api-keysexport NEXTPDF_WORKER_COUNT=8export NEXTPDF_GRPC_WORKER_COUNT=4export NEXTPDF_REDIS_HOST=redis./vendor/bin/rr serve -c .rr.full.yamlPer un pool con più worker, configurare Redis e verificare che ext-redis sia presente nell’immagine in esecuzione; senza l’estensione, gli store di rate limiting, idempotenza e documenti restano per singolo worker. Vedere Distribuzione.
Registro degli strumenti e risoluzione dei livelli
Sezione intitolata “Registro degli strumenti e risoluzione dei livelli”NextPDF\Server\ToolRegistry (src/ToolRegistry.php) costruisce il catalogo all’avvio. Il livello è dichiarato come invariante: ogni strumento restituisce il proprio tier() e riskLevel(); il registro non deduce mai il livello dal namespace o dal packaging.
- Il livello core si registra incondizionatamente: gli strumenti di documento e di diagnostica, più lo strumento
@apistabilegenerate_barcode(il registro core degli encoder di codici a barre è incluso innextpdf/core, quindi le simbologie core si risolvono sempre; le simbologie Pro richiedononextpdf/pro), piùparse_pdfsoltanto quandoNEXTPDF_MCP_TOOL_PARSE_PDF_ENABLEDètrueo1. - I provider Pro ed Enterprise si registrano quando le rispettive classi provider, verificate con
class_exists(), vengono risolte. Un livello assente viene ignorato silenziosamente. - I provider AST e di mutation in bundle vengono registrati nel livello Pro e sono controllati da
NEXTPDF_AST_TOOLS_ENABLEDeNEXTPDF_MUTATION_TOOLS_ENABLED(entrambi abilitati per impostazione predefinita). - Il filtro dei criteri di sicurezza interseca ogni registrazione con l’allowlist
enabled_tools. L’allowlist sottrae; non aggiunge mai. Il conteggio per livello include solo gli strumenti ammessi dai criteri.
I conteggi per livello risultanti e il totale sono riportati nella risposta initialize di MCP e nell’endpoint REST GET /api/v1/capabilities. Qualsiasi totale fisso indicato nel testo va considerato obsoleto; interrogare il server in esecuzione. Vedere Catalogo degli strumenti.
Livelli di rischio e gate di conferma
Sezione intitolata “Livelli di rischio e gate di conferma”Ogni strumento dichiara uno dei quattro livelli di rischio dell’enum RiskLevel (src/Config/RiskLevel.php): Safe (0), Caution (1), Review (2) e ApprovalRequired (3). La registrazione di audit si applica da Caution in poi. Un override di configurazione può innalzare il rischio di uno strumento; non può mai abbassare il rischio di uno strumento che è ApprovalRequired per progettazione. Il loader della configurazione genera un’eccezione al momento del caricamento e il server rifiuta di avviarsi anziché funzionare con un gate indebolito.
Quando uno strumento ApprovalRequired viene invocato senza un token valido, il ConfirmationGate (src/Mcp/ConfirmationGate.php) restituisce un token di challenge monouso. Il token vincola il nome dello strumento, un digest canonico degli argomenti rilevanti per la decisione, un nonce casuale e un time-to-live (TTL) di 300 secondi. Il digest è uno SHA-256 stabile rispetto alla normalizzazione (ordinamento ricorsivo delle chiavi, con esclusione dell’argomento _confirmation_token stesso), così che un client che, in caso di nuovo tentativo, riserializza gli argomenti con un diverso ordinamento delle chiavi corrisponda comunque, mentre un token emesso per un determinato insieme di argomenti non può autorizzare lo stesso strumento con argomenti sostituiti (confused-deputy / sostituzione di argomenti). L’agente inoltra la challenge a una persona e reinvoca lo stesso strumento con il token nell’argomento _confirmation_token. Il token viene consumato al momento dell’uso, sbloccando esattamente una chiamata sottoposta al gate.
L’esempio PHP seguente mostra un helper indipendente dal trasporto che esegue una chiamata a uno strumento MCP e, in caso di challenge di conferma, presenta la challenge a un approvatore umano prima di riprovare con il token emesso. Dichiara i tipi stretti, è completamente tipizzato e intercetta l’eccezione più specifica anziché ignorare ogni errore.
<?php
declare(strict_types=1);
namespace App\Connect;
use JsonException;
/** * Drives one tool call and resolves an ApprovalRequired confirmation * challenge through a human approver before retrying. */final readonly class ConfirmingToolCaller{ public function __construct( private McpClientInterface $client, private HumanApproverInterface $approver, ) {}
/** * @param non-empty-string $toolName * @param array<string, mixed> $arguments * * @return array<string, mixed> The tool result content * * @throws JsonException When a response cannot be decoded * @throws ApprovalDeniedException When the human declines the challenge */ public function call(string $toolName, array $arguments): array { $response = $this->client->callTool($toolName, $arguments);
if (!isset($response['challenge'], $response['token'])) { return $response; }
$challenge = (string) $response['challenge']; $token = (string) $response['token'];
if (!$this->approver->approve($toolName, $challenge)) { throw new ApprovalDeniedException($toolName); }
$arguments['_confirmation_token'] = $token;
return $this->client->callTool($toolName, $arguments); }}Collegare McpClientInterface, HumanApproverInterface e ApprovalDeniedException al proprio trasporto e canale di approvazione. Il nuovo tentativo riutilizza gli argomenti originali più il token emesso; non approvare mai automaticamente una challenge senza una decisione umana. Vedere Livelli di rischio HITL.
Punti di estensione
Sezione intitolata “Punti di estensione”Estendere il server aggiungendo strumenti e fornendo provider, non modificando il registro.
| Punto di estensione | Da usare per | Vincolo |
|---|---|---|
Una classe che implementa ToolInterface | Una nuova funzionalità del motore esposta come strumento. | Dichiarare tier(), riskLevel(), category() e un inputSchema() come schema JSON; mantenerla come wrapper sottile del motore. |
Un provider ToolProviderInterface | Registrare un insieme di strumenti per un livello. | I provider Pro ed Enterprise vengono individuati tramite class_exists(); non imporre al server il pacchetto proprietario. |
Allowlist enabled_tools | Definire l’ambito del catalogo esposto a privilegio minimo. | L’allowlist sottrae soltanto; non può registrare uno strumento assente. |
risk_level_overrides | Rafforzare una distribuzione innalzando il rischio di uno strumento. | Solo innalzamento; un abbassamento di uno strumento ApprovalRequired fa fallire l’avvio. |
| Punti di iniezione per trasporto e worker | Testare il server in isolamento. | Questi punti di estensione esistono per i test, non per il wiring dell’applicazione. |
Flusso di lavoro operativo
Sezione intitolata “Flusso di lavoro operativo”- Scegliere un profilo. Eseguire
.rr.yaml,.rr.grpc.yamlo.rr.full.yamlin base ai trasporti da esporre. - Montare le chiavi da un segreto. Puntare
NEXTPDF_API_KEYS_FILEa un file segreto; preferire lo store di chiavi su file con ricarica a caldo, così la rotazione non richiede alcun riavvio. - Configurare gli store condivisi. Impostare
NEXTPDF_REDIS_HOSTe verificareext-redisper qualsiasi pool con più di un worker; collocare lo store dei job SQLite su un volume su cui tutti i worker possano scrivere. - Terminare il TLS. Eseguire REST dietro un terminatore TLS (Transport Layer Security); eseguire gRPC con TLS reciproco su qualsiasi rete non attendibile, fornendo la chiave del server, il certificato del server e l’autorità di certificazione del client come segreti di distribuzione.
- Sondare lo stato di salute. Usare gli endpoint anonimi
/healthze/readyz(REST) oppure le RPCHealthCheckeReadinessCheck(gRPC) per i probe dell’orchestratore. - Definire l’ambito del catalogo. Limitare
enabled_toolsall’insieme minimo di cui un’integrazione ha bisogno.
Verificare lo stato di salute di Redis anziché darlo per scontato: il server REST ripiega sugli store in memoria se la connessione Redis configurata fallisce. Vedere Distribuzione e Sicurezza e operazioni.
Gestione degli errori
Sezione intitolata “Gestione degli errori”| Errore | Dove si manifesta | Risposta consigliata |
|---|---|---|
document_id sconosciuto | Esecuzione dello strumento | Restituire un errore definito al chiamante; istruirlo a chiamare prima create_pdf. |
| ETag obsoleto su una mutation | Strumento di mutation AST | Rileggere il documento con get_document_ast e riprovare con l’ETag aggiornato. |
| Chiave API mancante o non valida (REST) | Middleware di autenticazione | Restituire 401 con una challenge WWW-Authenticate: Bearer; non rivelare quale parte era errata. |
| Livello non abilitato (REST) | Autorizzazione | Restituire 403; il livello della chiave è inferiore al livello dell’operazione. |
| Route del livello assente (REST) | Router | Restituire 404; il pacchetto non è installato. È un comportamento previsto, non un guasto. |
| Token non valido (gRPC) | Autenticatore gRPC | Far fallire la chiamata con UNAUTHENTICATED. |
| Redis irraggiungibile | Avvio o runtime | Ripiegare sugli store in memoria; avvisare gli operatori e verificare lo stato di salute di Redis. |
| Percorso di output esterno alla directory di base | Strumento che produce file | Rifiutare l’operazione in modalità fail-closed; il percorso viene canonicalizzato e il traversal viene rifiutato. |
Esporre gli errori del motore come oggetti di errore definiti, mai come successi silenziosi. Il modello degli errori per ciascun trasporto è descritto nella documentazione di riferimento dell’API.
Valori predefiniti sicuri
Sezione intitolata “Valori predefiniti sicuri”| Aspetto | Predefinito | Quando eseguire l’override |
|---|---|---|
parse_pdf | Disabilitato (attivabile tramite NEXTPDF_MCP_TOOL_PARSE_PDF_ENABLED). | Abilitare solo quando un’integrazione richiede l’ispezione strutturale. |
enabled_tools | Vuota (tutti gli strumenti individuati sono consentiti). | Impostare un’allowlist esplicita per le distribuzioni a privilegio minimo. |
| Override del rischio | Nessuno. | Innalzare il rischio per una distribuzione irrobustita; non tentare mai un abbassamento. |
document_ttl / max_documents | 1800 secondi / 50 documenti. | Abbassare per le distribuzioni sensibili alla residenza dei dati o con vincoli di memoria. |
allow_file_output | Abilitato. | Impostare su false per le distribuzioni stateless e sensibili alla residenza dei dati. |
| Numero di worker | Quattro (HTTP), due (gRPC). | Dimensionare in base alla latenza osservata e ai core disponibili. |
| Listener REST | HTTP in chiaro dietro un terminatore TLS. | Terminare sempre il TLS a monte; non esporre mai testo in chiaro su una rete non attendibile. |
| gRPC su reti non attendibili | TLS reciproco. | Obbligatorio; non eseguire mai un listener gRPC in chiaro su una rete non attendibile. |
Checklist di test
Sezione intitolata “Checklist di test”- I test del registro verificano che un livello Pro o Enterprise assente venga ignorato silenziosamente e che il catalogo core si registri comunque.
- I test dell’allowlist verificano che
enabled_toolssottragga e non aggiunga mai uno strumento che il registro non ha individuato. - I test del gate di conferma verificano che uno strumento
ApprovalRequiredrestituisca una challenge alla prima chiamata e venga eseguito una sola volta con un token monouso valido, nonché che il token scada dopo il suo TTL. - I test di abbassamento verificano che una voce
risk_level_overridesche indebolisce uno strumentoApprovalRequiredfaccia fallire l’avvio. - I test di autenticazione coprono chiavi mancanti, malformate, disabilitate e scadute su REST (
401conWWW-Authenticate) e gRPC (UNAUTHENTICATED), e il rifiuto quando il livello non è abilitato (403). - I test di concorrenza verificano che un ETag obsoleto faccia fallire una mutation e che una
idempotency_keyripetuta riproduca il risultato memorizzato nella cache. - I test di contenimento dei percorsi verificano che un percorso di output che si risolve all’esterno della directory di base venga rifiutato.
- Mantenere le fixture piccole e non sensibili; non eseguire mai il commit di una chiave API reale o del contenuto di un documento.
Vedere anche
Sezione intitolata “Vedere anche”- Documentazione di riferimento dell’API: simboli esatti di strumenti, RPC e messaggi
- Catalogo degli strumenti: l’insieme core verificato e il conteggio a runtime
- Livelli di rischio HITL: il modello di rischio e l’envelope di conferma
- Configurazione: l’ordine di risoluzione e l’override solo in innalzamento
- Distribuzione: profili RoadRunner, Redis e TLS reciproco
- Sicurezza e operazioni: autenticazione, sicurezza del trasporto e modello delle minacce