Guia do desenvolvedor do NextPDF Connect
Visão geral
Seção intitulada “Visão geral”O NextPDF Connect (nextpdf/server) encapsula como serviço o motor PDF 2.0 do NextPDF, que é agnóstico de framework. Ele não reimplementa a geração de PDF. Ele expõe cada capacidade do motor como uma ferramenta nomeada com um schema e, em seguida, disponibiliza esse catálogo por três transportes: Model Context Protocol (MCP) sobre entrada e saída padrão, Application Programming Interface (API) no estilo Representational State Transfer (REST) e gRPC. Use este guia ao desenvolver para o servidor, estender o conjunto de ferramentas dele ou executá-lo em produção.
Três conceitos definem o design: o registro de ferramentas, os três transportes independentes e o gate de confirmação com humano no circuito (human-in-the-loop, HITL). Esta página explica como eles se encaixam e como trabalhar com eles sem enfraquecer o modelo de segurança. Para os símbolos exatos de ferramenta, chamada de procedimento remoto (RPC) e mensagem, consulte a referência da API.
Pré-requisitos: PHP 8.4, Composer 2 e — para os transportes em rede — o binário do RoadRunner e pelo menos uma chave de API. Instale com composer require nextpdf/server.
Fronteira da arquitetura
Seção intitulada “Fronteira da arquitetura”Mantenha cada responsabilidade no lado correto da fronteira. Uma ferramenta é um wrapper fino em torno de uma chamada ao motor; ela não deve conter interpretação de layout, semântica do documento nem lógica de transformação.
| Camada | Pertence a | Responsabilidade | Não coloque aqui |
|---|---|---|---|
| Cliente ou agente | Sua integração | Escolher qual ferramenta chamar; encaminhar os desafios de confirmação a um humano. | Lógica do motor ou detecção de tier. |
| Transporte | nextpdf/server | Estruturar requisições como JSON-RPC, HTTP ou Protocol Buffers; autenticar; e rotear para o executor de ferramentas. | Semântica do documento. |
| Registro de ferramentas | nextpdf/server | Descobrir tiers, registrar ferramentas sujeitas à allowlist de segurança e localizar uma ferramenta pelo nome. | Geração de PDF. |
| Ferramenta | nextpdf/server | Validar os argumentos contra o schema de entrada e chamar o motor. | Interpretação de layout ou orquestração em várias etapas. |
| Gate de confirmação | nextpdf/server | Reter uma operação ApprovalRequired até que um humano a aprove. | Autenticação do chamador. |
| Motor | nextpdf/core (e nextpdf/premium) | Gerar, inspecionar e transformar o conteúdo de PDF. | Questões de transporte ou autenticação. |
Ciclo de vida em tempo de execução
Seção intitulada “Ciclo de vida em tempo de execução”Cada transporte tem seu próprio ponto de entrada e sua própria fábrica de inicialização. Cada um constrói explicitamente o próprio grafo de objetos. Não há um container de injeção de dependências a configurar.
- Carregue a configuração. O servidor MCP resolve a configuração a partir de variáveis de ambiente (
NEXTPDF_MCP_*), depois da seçãonextpdf_mcpdo arquivo YAML, depois dos padrões embutidos, e produz umareadonlyMcpConfig. Os servidores REST e gRPC leem aHttpConfigdas variáveis de ambienteNEXTPDF_*. Consulte Configuração. - Construa a política de segurança. A allowlist
enabled_toolsé construída antes do registro, restringindo a descoberta desde o primeiro registro. - Construa o registro e descubra as ferramentas. O
ToolRegistry::registerDefaults()registra o tier core, depois os provedores Pro e Enterprise quando suas classes são resolvidas e, em seguida, os provedores AST e de mutação empacotados, sujeitos aos seus gates de ambiente. - Construa os stores compartilhados e o gate. O document store em memória é construído a partir do TTL e da capacidade configurados; o
ConfirmationGateé montado com seu store de tokens de uso único. - Vincule o transporte. O MCP entra em um laço de leitura-tratamento-escrita sobre o stdio até o fim do arquivo. O REST e o gRPC constroem sua tabela de rotas ou serviços a partir dos tiers detectados e, então, entregam ao RoadRunner o laço de requisições.
Depois disso, uma requisição segue este caminho: autenticar (REST e gRPC), resolver a ferramenta ou operação, executar o gate de confirmação para o trabalho ApprovalRequired, executar contra o motor e retornar o resultado. Consulte Inicialização e descoberta.
Modelo de transporte
Seção intitulada “Modelo de transporte”Os três transportes compartilham os conceitos de registro, configuração e gate, mas são executados como processos independentes. Iniciar um deles não inicia os outros.
| Transporte | Ponto de entrada | Quando escolhê-lo |
|---|---|---|
| MCP | bin/nextpdf-mcp | Um cliente local de inteligência artificial (IA) que inicia o servidor como subprocesso confiável. |
| REST | bin/nextpdf-server | Clientes HTTP em rede; transporte descrito por um documento OpenAPI 3.1. |
| gRPC | bin/nextpdf-grpc | Clientes tipados e com streaming; serviço nextpdf.connect.v1.NextPDFConnect. |
Escolha os transportes pelo perfil do RoadRunner que você executa: .rr.yaml (apenas REST), .rr.grpc.yaml (apenas gRPC) ou .rr.full.yaml (ambos). O transporte MCP é um subprocesso simples e não precisa de supervisor. Para detalhes de protocolo, consulte Transporte MCP, Transporte REST e Transporte gRPC.
Estrutura de implantação recomendada
Seção intitulada “Estrutura de implantação recomendada”Execute os transportes em rede sob o RoadRunner, com stores compartilhados e chaves montadas como segredos. O perfil combinado permite que REST e gRPC compartilhem um supervisor.
| Caminho ou configuração | Finalidade |
|---|---|
.rr.full.yaml | Perfil combinado de REST e gRPC sob um único supervisor. |
NEXTPDF_API_KEYS_FILE | Caminho para um arquivo de chaves de API montado como segredo e com recarga a quente. |
NEXTPDF_REDIS_HOST | Habilita stores de limite de taxa, idempotência e documentos com suporte do Redis para pools de vários workers. |
NEXTPDF_WORKER_COUNT / NEXTPDF_GRPC_WORKER_COUNT | Dimensionamento dos pools de workers HTTP e gRPC. |
| Diretório base de saída | Volume dedicado com permissões de sistema de arquivos com privilégio mínimo para as ferramentas de saída em arquivo. |
O exemplo de shell abaixo inicializa o perfil combinado com chaves montadas como segredos e um store Redis compartilhado. Ele não contém segredos; as chaves são montadas em /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.yamlPara um pool de vários workers, configure o Redis e confirme que a ext-redis está presente na imagem em execução. Sem ela, os stores de limite de taxa, idempotência e documentos ficam isolados por worker. Consulte Implantação.
Registro de ferramentas e resolução de tier
Seção intitulada “Registro de ferramentas e resolução de tier”NextPDF\Server\ToolRegistry (src/ToolRegistry.php) constrói o catálogo na inicialização. O tier é uma invariante declarada: cada ferramenta retorna seu próprio tier() e riskLevel(). O registro nunca infere o tier a partir do namespace ou do empacotamento.
- Tier core é registrado incondicionalmente: as ferramentas de documento e de diagnóstico, mais o
generate_barcodequando o registro de codificadores de código de barras do core está presente, mais oparse_pdfapenas quandoNEXTPDF_MCP_TOOL_PARSE_PDF_ENABLEDétrueou1. - Provedores Pro e Enterprise são registrados quando suas classes de provedor são resolvidas, verificadas com
class_exists(). Um tier ausente é ignorado silenciosamente. - Provedores AST e de mutação empacotados são registrados sob o tier Pro, controlados por
NEXTPDF_AST_TOOLS_ENABLEDeNEXTPDF_MUTATION_TOOLS_ENABLED(ambos habilitados por padrão). - O filtro de política de segurança intersecta cada registro com a allowlist
enabled_tools. A allowlist subtrai; nunca adiciona. O contador por tier inclui apenas as ferramentas que a política admite.
A resposta de initialize do MCP e o endpoint REST GET /api/v1/capabilities reportam as contagens por tier resultantes e o total. Considere desatualizado qualquer total fixo escrito em prosa; consulte o servidor em execução. Consulte Catálogo de ferramentas.
Tiers de risco e o gate de confirmação
Seção intitulada “Tiers de risco e o gate de confirmação”Toda ferramenta declara um dos quatro níveis de risco do enum RiskLevel (src/Config/RiskLevel.php): Safe (0), Caution (1), Review (2) e ApprovalRequired (3). O registro de auditoria se aplica a partir de Caution. Uma sobrescrita de configuração pode elevar o risco de uma ferramenta; nunca pode rebaixar uma ferramenta que é ApprovalRequired por design. O carregador de configuração lança uma exceção durante o carregamento, e o servidor se recusa a inicializar em vez de executar com um gate enfraquecido.
Quando uma ferramenta ApprovalRequired é invocada sem um token válido, o ConfirmationGate (src/Mcp/ConfirmationGate.php) retorna um token de desafio de uso único. O token vincula o nome da ferramenta, um nonce aleatório e um tempo de vida (time-to-live, TTL) de 300 segundos, mas não os argumentos, porque os clientes podem reserializar os argumentos com uma ordenação de chaves diferente na nova tentativa. O agente encaminha o desafio a um humano e invoca novamente a mesma ferramenta com o token no argumento _confirmation_token. O token é consumido no momento do uso, liberando exatamente uma chamada controlada pelo gate.
O exemplo de PHP abaixo é um auxiliar agnóstico de transporte. Ele conduz uma chamada de ferramenta MCP e, diante de um desafio de confirmação, mostra o desafio a um aprovador humano antes de tentar novamente com o token emitido. Ele declara tipos estritos, é totalmente tipado e captura a exceção mais específica em vez de capturar todos os erros indiscriminadamente.
<?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); }}Conecte McpClientInterface, HumanApproverInterface e ApprovalDeniedException ao seu próprio transporte e canal de aprovação. A nova tentativa reutiliza os argumentos originais junto com o token emitido; nunca aprove um desafio automaticamente sem uma decisão humana. Consulte Tiers de risco HITL.
Pontos de extensão
Seção intitulada “Pontos de extensão”Estenda o servidor adicionando ferramentas e fornecendo provedores, não editando o registro.
| Ponto de extensão | Use-o para | Restrição |
|---|---|---|
Uma classe que implementa ToolInterface | Uma nova capacidade do motor exposta como ferramenta. | Declare tier(), riskLevel(), category() e um inputSchema() em JSON Schema; mantenha a classe como um wrapper fino do motor. |
Um provedor ToolProviderInterface de ferramentas | Registrar um conjunto de ferramentas para um tier. | Os provedores Pro e Enterprise são descobertos por class_exists(); não faça o servidor exigir o pacote proprietário. |
enabled_tools allowlist | Escopo de privilégio mínimo do catálogo exposto. | A allowlist apenas subtrai; ela não pode registrar uma ferramenta ausente. |
risk_level_overrides | Fortalecer uma implantação elevando o risco de uma ferramenta. | Apenas elevação; um rebaixamento de uma ferramenta ApprovalRequired falha na inicialização. |
| Pontos de injeção de transporte e worker | Testar o servidor isoladamente. | Essas fronteiras existem para testes, não para a integração da aplicação. |
Fluxo de trabalho de operações
Seção intitulada “Fluxo de trabalho de operações”- Escolha um perfil. Execute
.rr.yaml,.rr.grpc.yamlou.rr.full.yamlpara os transportes que você expõe. - Monte as chaves a partir de um segredo. Aponte
NEXTPDF_API_KEYS_FILEpara um arquivo de segredo; prefira o store de chaves em arquivo com recarga a quente, para que a rotação não exija reinicialização. - Configure os stores compartilhados. Defina
NEXTPDF_REDIS_HOSTe confirme aext-redispara qualquer pool maior que um worker; coloque o job store SQLite em um volume no qual todos os workers possam escrever. - Termine o TLS. Execute o REST atrás de um terminador de Transport Layer Security (TLS); execute o gRPC com TLS mútuo em qualquer rede não confiável, com a chave do servidor, o certificado do servidor e a autoridade certificadora do cliente fornecidos como segredos de implantação.
- Verifique a saúde. Use os endpoints anônimos
/healthze/readyz(REST) ou os RPCsHealthCheckeReadinessCheck(gRPC) para sondas do orquestrador. - Defina o escopo do catálogo. Restrinja
enabled_toolsao conjunto mínimo que uma integração necessita.
Verifique a saúde do Redis em vez de presumi-la. O servidor REST recorre a stores em memória quando uma conexão Redis configurada falha. Consulte Implantação e Segurança e operações.
Tratamento de falhas
Seção intitulada “Tratamento de falhas”| Falha | Onde se manifesta | Resposta recomendada |
|---|---|---|
Desconhecido document_id | Execução da ferramenta | Retorne um erro definido ao chamador; instrua-o a chamar create_pdf primeiro. |
| ETag desatualizada em uma mutação | Ferramenta de mutação AST | Releia o documento com get_document_ast e tente novamente com a ETag atualizada. |
| Chave de API ausente ou inválida (REST) | Middleware de autenticação | Retorne 401 com um desafio WWW-Authenticate: Bearer; não revele qual parte estava errada. |
| Tier sem direito de acesso (REST) | Autorização | Retorne 403; o tier da chave está abaixo do tier da operação. |
| Rota do tier ausente (REST) | Roteador | Retorne 404; o pacote não está instalado. Esta é uma condição esperada, não uma falha. |
| Token inválido (gRPC) | Autenticador gRPC | Faça a chamada falhar com UNAUTHENTICATED. |
| Redis inacessível | Inicialização ou tempo de execução | Recorra a stores em memória; alerte os operadores e verifique a saúde do Redis. |
| Caminho de saída fora do diretório base | Ferramenta de saída em arquivo | Falhe em modo fechado; o caminho é canonicalizado e a travessia é rejeitada. |
Exponha as falhas do motor como objetos de erro definidos, nunca como sucessos silenciosos. A referência da API detalha o modelo de erro para cada transporte.
Padrões seguros
Seção intitulada “Padrões seguros”| Questão | Padrão | Quando sobrescrever |
|---|---|---|
parse_pdf | Desabilitado (opt-in via NEXTPDF_MCP_TOOL_PARSE_PDF_ENABLED). | Habilite apenas quando uma integração precisar de inspeção estrutural. |
enabled_tools | Vazio (todas as ferramentas descobertas são permitidas). | Defina uma allowlist explícita para implantações de privilégio mínimo. |
| Sobrescritas de risco | Nenhuma. | Eleve o risco para uma implantação fortalecida; nunca tente um rebaixamento. |
document_ttl / max_documents | 1800 segundos / 50 documentos. | Reduza para implantações sensíveis à residência de dados ou com memória limitada. |
allow_file_output | Habilitado. | Defina como false para implantações sem estado e sensíveis à residência. |
| Contagem de workers | Quatro (HTTP), dois (gRPC). | Dimensione conforme a latência observada e os núcleos disponíveis. |
| Listener REST | HTTP em texto puro atrás de um terminador de TLS. | Sempre termine o TLS a montante; nunca exponha texto puro em uma rede não confiável. |
| gRPC em redes não confiáveis | TLS mútuo. | Obrigatório; nunca execute um listener gRPC em texto puro em uma rede não confiável. |
Lista de verificação de testes
Seção intitulada “Lista de verificação de testes”- Os testes de registro asseguram que um tier Pro ou Enterprise ausente é ignorado silenciosamente e que o catálogo core ainda se registra.
- Os testes de allowlist asseguram que
enabled_toolssubtrai e nunca adiciona uma ferramenta que o registro não descobriu. - Os testes do gate de confirmação asseguram que uma ferramenta
ApprovalRequiredretorna um desafio na primeira chamada, executa uma vez com um token válido de uso único e expira o token após o seu TTL. - Os testes de rebaixamento asseguram que uma entrada
risk_level_overridesque enfraquece uma ferramentaApprovalRequiredfalha na inicialização. - Os testes de autenticação cobrem chaves ausentes, malformadas, desabilitadas e expiradas no REST (
401comWWW-Authenticate) e no gRPC (UNAUTHENTICATED), e a rejeição por tier sem direito de acesso (403). - Os testes de concorrência asseguram que uma ETag desatualizada faz uma mutação falhar e que uma
idempotency_keyrepetida reproduz o resultado em cache. - Os testes de contenção de caminho asseguram que um caminho de saída em arquivo resolvido para fora do diretório base é rejeitado.
- Mantenha as fixtures pequenas e não sensíveis; nunca faça commit de uma chave de API real ou do conteúdo de um documento.
Veja também
Seção intitulada “Veja também”- Referência da API — símbolos exatos de ferramenta, RPC e mensagem
- Catálogo de ferramentas — o conjunto core verificado e a contagem em tempo de execução
- Tiers de risco HITL — o modelo de risco e o envelope de confirmação
- Configuração — a ordem de resolução e a sobrescrita apenas por elevação
- Implantação — perfis do RoadRunner, Redis e TLS mútuo
- Segurança e operações — autenticação, segurança de transporte e o modelo de ameaças