Guia do desenvolvedor do 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 a ferramenta
@apiestávelgenerate_barcode(o registro de codificadores de código de barras do core acompanha onextpdf/core, então as simbologias core sempre são resolvidas; as simbologias Pro exigem onextpdf/pro), 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 digest canônico dos argumentos relevantes para a decisão, um nonce aleatório e um tempo de vida (time-to-live, TTL) de 300 segundos. O digest é um SHA-256 estável sob normalização (ordenação recursiva de chaves, excluindo o próprio argumento _confirmation_token), de modo que um cliente que reserializa os argumentos com uma ordenação de chaves diferente na nova tentativa ainda corresponde, ao passo que um token emitido para um conjunto de argumentos não pode autorizar a mesma ferramenta com argumentos substituídos (confused-deputy / substituição de argumentos). 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