Ga naar inhoud

NextPDF Connect-ontwikkelaarsgids

NextPDF Connect (nextpdf/server) verpakt de framework-onafhankelijke NextPDF PDF 2.0-engine als service. Het implementeert PDF-generatie niet opnieuw. Het stelt elke engine-mogelijkheid beschikbaar als een benoemde tool met een schema en biedt die catalogus vervolgens aan via drie transporten: Model Context Protocol (MCP) over standaardinvoer en -uitvoer, Representational State Transfer (REST) Application Programming Interface (API), en gRPC. Gebruik deze gids wanneer u voor de server ontwikkelt, de toolset uitbreidt of de server in productie draait.

Drie concepten bepalen het ontwerp: het toolregister, de drie onafhankelijke transporten en de human-in-the-loop (HITL) bevestigingspoort. Deze pagina legt uit hoe ze samenhangen en hoe u ermee werkt zonder het veiligheidsmodel te verzwakken. Raadpleeg de API-referentie voor de exacte tool-, remote procedure call (RPC)- en berichtsymbolen.

Vereisten: PHP 8.4, Composer 2 en — voor de via het netwerk benaderbare transporten — de RoadRunner-binary en ten minste één API-sleutel. Installeer met composer require nextpdf/server.

Houd elke verantwoordelijkheid aan de juiste kant van de grens. Een tool is een dunne wrapper rond een engine-aanroep; deze mag geen lay-outinterpretatie, documentsemantiek of transformatielogica bevatten.

LaagEigendom vanVerantwoordelijkheidPlaats hier niet
Client of agentUw integratieKies welke tool wordt aangeroepen; geef bevestigingsuitdagingen door aan een mens.Engine-logica of niveaudetectie.
Transportnextpdf/serverVerpak verzoeken als JSON-RPC, HTTP of Protocol Buffers; authenticeer; en routeer ze naar de tooluitvoerder.Documentsemantiek.
Toolregisternextpdf/serverDetecteer niveaus, registreer tools met inachtneming van de beveiligingstoelatingslijst, zoek een tool op naam op.PDF-generatie.
Toolnextpdf/serverValideer argumenten tegen het invoerschema en roep de engine aan.Lay-outinterpretatie of orkestratie in meerdere stappen.
Bevestigingspoortnextpdf/serverHoud een ApprovalRequired-bewerking vast totdat een mens deze goedkeurt.Authenticatie van de aanroeper.
Enginenextpdf/core (en nextpdf/premium)Genereer, inspecteer en transformeer PDF-inhoud.Transport- of authenticatieaspecten.

Elk transport heeft zijn eigen ingangspunt en boot-factory. Elk daarvan bouwt zijn objectgraaf expliciet op. Er is geen dependency-injection-container waarin u iets hoeft te registreren.

  1. Configuratie laden. De MCP-server leidt de configuratie af uit omgevingsvariabelen (NEXTPDF_MCP_*), daarna uit de nextpdf_mcp-sectie van het YAML-bestand, vervolgens uit de ingebouwde standaardwaarden, en produceert een readonlyMcpConfig. De REST- en gRPC-servers lezen HttpConfig uit NEXTPDF_*-omgevingsvariabelen. Zie Configuratie.
  2. Het beveiligingsbeleid opbouwen. De enabled_tools-toelatingslijst wordt vóór het register opgebouwd, zodat deze de detectie vanaf de eerste registratie begrenst.
  3. Het register opbouwen en tools detecteren. ToolRegistry::registerDefaults() registreert het core-niveau, vervolgens de Pro- en Enterprise-providers wanneer hun klassen worden gevonden, en daarna de gebundelde AST- en mutatieproviders met inachtneming van hun omgevingspoorten.
  4. De gedeelde stores en poort opbouwen. De in-memory documentstore wordt opgebouwd op basis van de geconfigureerde TTL en capaciteit; de ConfirmationGate wordt samengesteld met zijn store voor eenmalig bruikbare tokens.
  5. Het transport binden. MCP draait een lees-verwerk-schrijf-lus over stdio totdat het einde van het bestand is bereikt. REST en gRPC bouwen hun route- of servicetabel op uit de gedetecteerde niveaus en dragen de verzoeklus vervolgens over aan RoadRunner.

Een verzoek volgt daarna dit pad: authenticeren (REST en gRPC), de tool of bewerking bepalen, de bevestigingspoort uitvoeren voor ApprovalRequired-werk, de engine aanroepen en het resultaat retourneren. Zie Boot en detectie.

De drie transporten delen de concepten register, configuratie en poort, maar draaien als onafhankelijke processen. Het starten van het ene transport start de andere transporten niet.

TransportIngangspuntWanneer u het kiest
MCPbin/nextpdf-mcpEen lokale artificial intelligence (AI)-client die de server als een vertrouwd subproces start.
RESTbin/nextpdf-serverVia het netwerk bereikbare HTTP-clients; beschreven door een OpenAPI 3.1-document.
gRPCbin/nextpdf-grpcGetypeerde streaming-clients; de nextpdf.connect.v1.NextPDFConnect-service.

Kies transporten op basis van het RoadRunner-profiel dat u draait: .rr.yaml (alleen REST), .rr.grpc.yaml (alleen gRPC), of .rr.full.yaml (beide). Het MCP-transport is een eenvoudig subproces en heeft geen supervisor nodig. Zie MCP-transport, REST-transport en gRPC-transport voor details op protocolniveau.

Draai de via het netwerk bereikbare transporten onder RoadRunner met gedeelde stores en sleutels die via secrets zijn gekoppeld. Met het gecombineerde profiel kunnen REST en gRPC een supervisor delen.

Pad of instellingDoel
.rr.full.yamlGecombineerd REST- en gRPC-profiel onder één supervisor.
NEXTPDF_API_KEYS_FILEPad naar een via een secret gekoppeld API-sleutelbestand dat automatisch wordt herladen.
NEXTPDF_REDIS_HOSTSchakelt Redis-ondersteunde rate-limit-, idempotentie- en documentstores in voor pools met meerdere workers.
NEXTPDF_WORKER_COUNT / NEXTPDF_GRPC_WORKER_COUNTGrootte van de workerpool voor de HTTP- en gRPC-pools.
Basismap voor uitvoerSpecifiek volume met bestandssysteemrechten volgens het principe van minimale rechten voor tools met bestandsuitvoer.

Het volgende shell-voorbeeld start het gecombineerde profiel met sleutels die via secrets zijn gekoppeld en een gedeelde Redis-store. Het bevat geen secrets; sleutels worden gekoppeld op /run/secrets/api-keys.

Terminal window
export NEXTPDF_API_KEYS_FILE=/run/secrets/api-keys
export NEXTPDF_WORKER_COUNT=8
export NEXTPDF_GRPC_WORKER_COUNT=4
export NEXTPDF_REDIS_HOST=redis
./vendor/bin/rr serve -c .rr.full.yaml

Configureer Redis voor een pool met meerdere workers en bevestig dat ext-redis aanwezig is in de draaiende image. Zonder deze extensie zijn de rate-limit-, idempotentie- en documentstores per worker. Zie Deployment.

NextPDF\Server\ToolRegistry (src/ToolRegistry.php) bouwt de catalogus op bij het opstarten. Het niveau is een gedeclareerde invariant: elke tool retourneert zijn eigen tier() en riskLevel(). Het register leidt het niveau nooit af uit de namespace of packaging.

  1. Core-niveau registreert onvoorwaardelijk: de document- en diagnosetools, plus generate_barcode wanneer het core-barcode-encoderregister aanwezig is, plus parse_pdf alleen wanneer NEXTPDF_MCP_TOOL_PARSE_PDF_ENABLED true of 1 is.
  2. Pro- en Enterprise-providers worden geregistreerd wanneer hun providerklassen worden gevonden, gecontroleerd met class_exists(). Een ontbrekend niveau wordt stilzwijgend overgeslagen.
  3. Gebundelde AST- en mutatieproviders registreren onder het Pro-niveau, beperkt door NEXTPDF_AST_TOOLS_ENABLED en NEXTPDF_MUTATION_TOOLS_ENABLED (beide standaard ingeschakeld).
  4. Het beveiligingsbeleidsfilter snijdt elke registratie met de enabled_tools-toelatingslijst. De toelatingslijst trekt af; deze voegt nooit toe. De teller per niveau telt alleen tools die het beleid toelaat.

Het MCP-initialize-antwoord en het REST-eindpunt GET /api/v1/capabilities rapporteren de resulterende aantallen per niveau en het totaal. Beschouw elk hardcoded totaal in tekst als verouderd; raadpleeg de draaiende server. Zie Toolcatalogus.

Elke tool declareert een van vier risiconiveaus uit de RiskLevel-enum (src/Config/RiskLevel.php): Safe (0), Caution (1), Review (2) en ApprovalRequired (3). Auditlogging geldt vanaf Caution en hoger. Een configuratie-override mag het risico van een tool verhogen; deze mag een tool die door ontwerp ApprovalRequired is nooit verlagen. De configuratielader gooit een fout tijdens het laden, en de server weigert op te starten in plaats van met een verzwakte poort te draaien.

Wanneer een ApprovalRequired-tool wordt aangeroepen zonder geldig token, retourneert de ConfirmationGate (src/Mcp/ConfirmationGate.php) een eenmalig bruikbaar uitdagingstoken. Het token bindt de toolnaam, een willekeurige nonce en een time-to-live (TTL) van 300 seconden, maar niet de argumenten, omdat clients argumenten bij een nieuwe poging opnieuw kunnen serialiseren met een andere sleutelvolgorde. De agent geeft de uitdaging door aan een mens en roept dezelfde tool opnieuw aan met het token in het argument _confirmation_token. Het token wordt bij gebruik verbruikt en geeft precies één afgeschermde aanroep vrij.

Het volgende PHP-voorbeeld is een transport-onafhankelijke helper. Het stuurt een MCP-toolaanroep aan en toont, bij een bevestigingsuitdaging, de uitdaging aan een menselijke goedkeurder voordat het opnieuw probeert met het uitgegeven token. Het declareert strikte typen, is volledig voorzien van typehints en vangt de meest specifieke uitzondering af in plaats van elke fout in te slikken.

examples/connect/confirm-and-call.php
<?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);
}
}

Koppel McpClientInterface, HumanApproverInterface en ApprovalDeniedException aan uw eigen transport- en goedkeuringskanaal. De nieuwe poging hergebruikt de oorspronkelijke argumenten plus het uitgegeven token; keur een uitdaging nooit automatisch goed zonder menselijke beslissing. Zie HITL-risiconiveaus.

Breid de server uit door tools toe te voegen en providers te leveren, niet door het register zelf te bewerken.

UitbreidingspuntGebruik het voorBeperking
Een implementatieklasse van ToolInterfaceEen nieuwe engine-mogelijkheid die als tool beschikbaar wordt gesteld.Declareer tier(), riskLevel(), category() en een JSON Schema inputSchema(); houd de klasse beperkt tot een dunne engine-wrapper.
Een ToolProviderInterface-providerEen set tools voor een niveau registreren.Pro- en Enterprise-providers worden gevonden via class_exists(); vereis het propriëtaire pakket niet vanuit de server.
enabled_tools-toelatingslijstAfbakening van de beschikbaar gestelde catalogus volgens het principe van minimale rechten.De toelatingslijst trekt alleen af; deze kan geen ontbrekende tool registreren.
risk_level_overridesEen deployment harden door het risico van een tool te verhogen.Alleen verhogen; een verlaging van een ApprovalRequired-tool laat het opstarten mislukken.
Injecteerbare transport- en worker-nadenDe server in isolatie testen.Deze grenzen bestaan voor tests, niet voor het bedraden van de applicatie.
  1. Kies een profiel. Draai .rr.yaml, .rr.grpc.yaml of .rr.full.yaml voor de transporten die u beschikbaar maakt.
  2. Koppel sleutels vanuit een secret. Wijs NEXTPDF_API_KEYS_FILE aan op een secret-bestand; geef de voorkeur aan de bestandssleutelstore die automatisch herlaadt, zodat rotatie geen herstart vereist.
  3. Configureer gedeelde stores. Stel NEXTPDF_REDIS_HOST in en bevestig ext-redis voor elke pool met meer dan één worker; plaats de SQLite-jobstore op een volume waarnaar alle workers kunnen schrijven.
  4. Beëindig TLS. Draai REST achter een Transport Layer Security (TLS)-terminator; draai gRPC met wederzijdse TLS op elk niet-vertrouwd netwerk, met de serversleutel, het servercertificaat en de certificeringsautoriteit van de client geleverd als deployment-secrets.
  5. Controleer de gezondheid. Gebruik de anonieme eindpunten /healthz en /readyz (REST) of de RPC’s HealthCheck en ReadinessCheck (gRPC) voor controles door de orchestrator.
  6. Scope de catalogus. Beperk enabled_tools tot de minimale set die een integratie nodig heeft.

Verifieer de gezondheid van Redis in plaats van deze aan te nemen. De REST-server valt terug op in-memory stores wanneer een geconfigureerde Redis-verbinding mislukt. Zie Deployment en Beveiliging en operations.

FoutWaar deze zich voordoetAanbevolen reactie
Onbekende document_idTooluitvoeringRetourneer een gedefinieerde fout aan de aanroeper; instrueer deze om eerst create_pdf aan te roepen.
Verouderde ETag bij een mutatieAST-mutatietoolLees het document opnieuw met get_document_ast en probeer opnieuw met de verse ETag.
Ontbrekende of ongeldige API-sleutel (REST)Authenticatie-middlewareRetourneer 401 met een WWW-Authenticate: Bearer-uitdaging; lek niet welk deel verkeerd was.
Niveau niet gerechtigd (REST)AutorisatieRetourneer 403; het niveau van de sleutel ligt onder het niveau van de bewerking.
Niveauroute afwezig (REST)RouterRetourneer 404; het pakket is niet geïnstalleerd. Dit is verwacht gedrag, geen fout.
Ongeldig token (gRPC)gRPC-authenticatorLaat de aanroep mislukken met UNAUTHENTICATED.
Redis onbereikbaarOpstarten of runtimeVal terug op in-memory stores; waarschuw operators en verifieer de gezondheid van Redis.
Uitvoerpad buiten de basismapTool met bestandsuitvoerFaal gesloten; het pad wordt gecanonicaliseerd en traversal wordt afgewezen.

Stel engine-fouten beschikbaar als gedefinieerde foutobjecten, nooit als stille successen. De API-referentie beschrijft het foutmodel voor elk transport in detail.

AandachtspuntStandaardWanneer te overschrijven
parse_pdfUitgeschakeld (opt-in via NEXTPDF_MCP_TOOL_PARSE_PDF_ENABLED).Schakel alleen in wanneer een integratie structurele inspectie nodig heeft.
enabled_toolsLeeg (alle gedetecteerde tools toegestaan).Stel een expliciete toelatingslijst in voor deployments volgens het principe van minimale rechten.
Risico-overridesGeen.Verhoog het risico voor een geharde deployment; probeer nooit een verlaging.
document_ttl / max_documents1800 seconden / 50 documenten.Verlaag dit voor deployments met strenge eisen aan gegevensresidentie of beperkt geheugen.
allow_file_outputIngeschakeld.Stel in op false voor stateless deployments met strenge eisen aan gegevensresidentie.
Aantal workersVier (HTTP), twee (gRPC).Stem de grootte af op de waargenomen latentie en de beschikbare cores.
REST-listenerPlaintext-HTTP achter een TLS-terminator.Beëindig TLS altijd upstream; stel plaintext nooit beschikbaar op een niet-vertrouwd netwerk.
gRPC op niet-vertrouwde netwerkenWederzijdse TLS.Vereist; draai nooit een plaintext-gRPC-listener op een niet-vertrouwd netwerk.
  • Registertests bevestigen dat een ontbrekend Pro- of Enterprise-niveau stilzwijgend wordt overgeslagen en dat de core-catalogus nog steeds wordt geregistreerd.
  • Toelatingslijsttests bevestigen dat enabled_tools aftrekt en nooit een tool toevoegt die het register niet heeft gedetecteerd.
  • Bevestigingspoorttests bevestigen dat een ApprovalRequired-tool een uitdaging retourneert bij de eerste aanroep, eenmaal draait op een geldig eenmalig bruikbaar token, en het token na zijn TTL laat verlopen.
  • Verlagingstests bevestigen dat een risk_level_overrides-vermelding die een ApprovalRequired-tool verzwakt het opstarten laat mislukken.
  • Authenticatietests dekken ontbrekende, misvormde, uitgeschakelde en verlopen sleutels op REST (401 met WWW-Authenticate) en gRPC (UNAUTHENTICATED), en afwijzing wegens onvoldoende niveaugerechtigdheid (403).
  • Gelijktijdigheidstests bevestigen dat een verouderde ETag een mutatie laat mislukken en dat een herhaalde idempotency_key het in de cache opgeslagen resultaat opnieuw afspeelt.
  • Padbegrenzingstests bevestigen dat een bestandsuitvoerpad dat buiten de basismap uitkomt, wordt afgewezen.
  • Houd fixtures klein en niet-gevoelig; commit nooit een echte API-sleutel of documentinhoud.