Servidor MCP em Python
O SDK Python do NextPDF inclui um servidor Model Context Protocol (MCP) que expõe operações de extração de PDF como ferramentas nativas para agentes. Um agente compatível com MCP, como o Claude Code, registra o servidor uma única vez e depois chama as ferramentas do NextPDF da mesma forma que chamaria qualquer outra ferramenta.
O servidor é um adaptador leve. Cada ferramenta lê um PDF do disco local, usa o cliente assíncrono para chamar o endpoint do NextPDF Connect e retorna o resultado como uma string JSON. O servidor não contém lógica de negócio e não armazena dados entre chamadas.
Instale o SDK com o extra MCP:
pip install nextpdf[mcp]O extra mcp instala o pacote upstream mcp (com a restrição mcp>=1.0,<2.0). O servidor exige Python 3.10 ou mais recente.
Execute o módulo do servidor pela configuração do cliente MCP. O exemplo abaixo lê os dois valores de conexão do ambiente do host, em vez de embutir um segredo no arquivo de configuração (consulte Segurança):
{ "mcpServers": { "nextpdf": { "command": "python", "args": ["-m", "nextpdf.mcp"], "env": { "NEXTPDF_BASE_URL": "https://connect.example.com", "NEXTPDF_API_KEY": "${NEXTPDF_API_KEY}" } } }}O ponto de entrada python -m nextpdf.mcp executa main(), que inicia o servidor por meio da entrada/saída padrão (stdio) com asyncio.run(serve()). Não o confunda com python -m nextpdf, que executa a interface de linha de comando (CLI), não o servidor MCP.
NEXTPDF_BASE_URL e NEXTPDF_API_KEY são obrigatórios. O servidor cria o cliente sob demanda na primeira chamada de ferramenta. Se alguma das variáveis estiver vazia, ele lança um RuntimeError e o devolve ao agente como erro de ferramenta, em vez de encerrar o processo.
Catálogo de ferramentas e mapeamento para o SDK
Seção intitulada “Catálogo de ferramentas e mapeamento para o SDK”O servidor registra oito ferramentas. Todo nome de ferramenta usa o prefixo nextpdf_. Cada ferramenta é mapeada para um método no namespace ast do cliente assíncrono (AsyncNextPDF.ast), exceto as duas ferramentas compostas indicadas abaixo. O servidor as compõe a partir de chamadas de nível mais baixo.
| Ferramenta MCP | Chamada do SDK | Observações |
|---|---|---|
nextpdf_extract_text | ast.extract_cited_text(pdf_data, page_index=..., headings_only=...) | Retorna uma lista de CitedTextBlock. |
nextpdf_extract_tables | ast.extract_cited_tables(pdf_data, page_range=...) | Retorna ExtractCitedTablesResponse. |
nextpdf_get_ast | ast.get_document_ast(pdf_data, page_range_start=0, page_range_end=..., token_budget=...) | Retorna AstDocument. |
nextpdf_info | ast.get_document_ast(pdf_data) | O servidor deriva um resumo de metadados; não há endpoint dedicado. |
nextpdf_health | nenhuma | Inspeciona somente variáveis de ambiente; não faz chamada de rede. |
nextpdf_search | ast.search_ast_nodes(pdf_data, node_type=..., page_index=..., text_query=..., max_results=...) | Retorna SearchAstNodesResponse. |
nextpdf_get_outline | ast.search_ast_nodes(pdf_data, node_type="heading", max_results=500) | O servidor transforma os nós de cabeçalho em um sumário. |
nextpdf_diff | ast.get_ast_diff(original_pdf_data, modified_pdf_data) | Retorna GetAstDiffResponse. |
Considere estes detalhes de entrada das ferramentas antes de conectar um agente:
- Todas as entradas de caminho (
pdf_path,original_pdf_path,modified_pdf_path) devem ser caminhos absolutos para arquivos na máquina que executa o servidor. O agente passa o caminho, e o servidor lê os bytes localmente. Não há ferramenta de upload. nextpdf_extract_textdeclara um campomax_pagesno esquema de entrada, mas o manipulador de texto não o encaminha ao SDK. A seleção de páginas para texto ocorre por meio depage_index(uma única página, com índice baseado em 0). Usenextpdf_get_astcommax_pagesquando precisar limitar uma varredura no documento inteiro.nextpdf_get_astconvertemax_pagesem um intervalo de páginas inclusivo de[0, max_pages - 1](o padrão demax_pagesé 50). Passetoken_budgetpara limitar o tamanho da árvore retornada.nextpdf_inforetornaschema_version,source_hash,page_count,estimated_tokens,root_node_typeeroot_children_count. Esses valores vêm do modeloAstDocument, em queestimated_tokensé uma propriedade calculada (aproximadamente quatro caracteres por token).nextpdf_get_outlineretorna uma entrada por cabeçalho comid,page_index,textedepth(lido deattributes["level"]do nó, com valor padrão 1), além deheading_count,total_matchesetruncated.
As ferramentas de extração com citações anexam um CitationAnchor a cada resultado. Cada âncora inclui node_id, page_index, um bbox normalizado (coordenadas no intervalo de 0.0 a 1.0) e uma pontuação de confidence (de 0.0 a 1.0). Agentes que precisam de proveniência devem exibir esses campos, e não apenas o texto bruto.
Tratamento de erros, timeouts e cota
Seção intitulada “Tratamento de erros, timeouts e cota”O servidor nunca deixa uma exceção escapar para o transporte do agente. O dispatcher call_tool captura todo erro e o retorna como TextContent JSON, de modo que uma chamada de ferramenta com falha produz uma carga útil estruturada que o agente pode ler, em vez de interromper a conexão. Os formatos de carga útil são:
| Condição | JSON retornado |
|---|---|
| Nome de ferramenta desconhecido | {"error": "Unknown tool: <name>"} |
| Arquivo de entrada ausente | {"error": "PDF file not found: <path>"} |
Qualquer subclasse de NextPDFError lançada | {"error": "<message>", "error_type": "<class>", "status_code": <int?>} |
| Qualquer outra exceção | {"error": "Unexpected error: <message>"} |
status_code aparece apenas quando o erro subjacente carrega um. O SDK mapeia respostas HTTP para uma hierarquia de exceções tipadas, todas com raiz em NextPDFError:
| Exceção | Status HTTP | error_code | Quando |
|---|---|---|---|
NextPDFLicenseError | 402 | license/tier-required | O endpoint exige, no lado do servidor, um nível de licença mais alto para a operação. |
AstNoStructTreeError | 422 | ast/no-struct-tree | O PDF não está marcado e o fallback heurístico não está habilitado no servidor. |
QuotaExceededError | 429 | quota/exceeded | Um limite de taxa ou cota foi atingido. Carrega retry_after (segundos) quando o servidor envia um cabeçalho Retry-After. |
AstBuildTimeoutError | 504 | ast/build-timeout | A construção da AST excedeu o orçamento de tempo do servidor. Reduza o intervalo de páginas. |
NextPDFAPIError | outros 4xx/5xx | fornecido pelo servidor | Qualquer outra falha no nível da API. |
Siga estas orientações para integrações de agentes:
- Timeouts. O cliente HTTP usa um timeout padrão fixo: 60 segundos no total, com timeout de conexão de 10 segundos. Um documento lento ou grande se manifesta como um
AstBuildTimeoutError(o servidor desistiu de construir a AST) ou, se o timeout do próprio cliente expirar, como uma carga útil deUnexpected errorda camada de transporte. Quando você virast/build-timeout, oriente o agente a restringir o escopo: reduzamax_pagesemnextpdf_get_astou definapage_index/page_startepage_endnas ferramentas de extração. - Cota e backoff. Em caso de 429, a ferramenta retorna o
error_typeigual aQuotaExceededError, comstatus_code429. O valor deretry_afterfica no objeto da exceção. Como o servidor serializa apenaserror,error_typeestatus_code, o agente deve tratar o 429 como um sinal para pausar e tentar novamente mais tarde, em vez de analisar um cabeçalho de retry na saída da ferramenta. Aplique cotas no endpoint do Connect, não no agente. - PDFs não marcados. Um 422
ast/no-struct-treesignifica que o PDF de origem não tem árvore de estrutura. Habilite o modo heurístico no servidor para esses documentos ou encaminhe-os para uma etapa de marcação antes da extração.
Segurança: escopo da chave de API e privilégio mínimo
Seção intitulada “Segurança: escopo da chave de API e privilégio mínimo”Trate a chave de API como um segredo, com o mesmo cuidado que você dedica a uma senha de banco de dados.
- Nunca embuta a chave no arquivo de configuração do MCP. O exemplo JSON acima referencia
${NEXTPDF_API_KEY}para que o valor seja resolvido a partir do ambiente do host ou de um gerenciador de segredos no momento da inicialização. Um arquivo de configuração pode ser versionado no controle de versão; um segredo não pode. - Restrinja a chave à extração somente leitura. O servidor MCP chama apenas a interface de extração da AST (
extract_cited_text,extract_cited_tables,get_document_ast,search_ast_nodes,get_ast_diff). Ele não renderiza, assina, redige nem altera documentos. Emita uma chave para o agente com escopo do lado do servidor limitado a esses caminhos de leitura, para que um agente comprometido não consiga alcançar operações de escrita ou de nível superior. - Use uma chave dedicada por agente. Uma chave por agente permite revogar ou rotacionar uma integração sem afetar as demais, e torna os logs do endpoint atribuíveis a um agente específico.
- Restrinja o sistema de arquivos. Como toda ferramenta lê um caminho absoluto do disco local, o servidor pode ler qualquer arquivo que o processo do host consiga ler. Execute-o como um usuário sem privilégios, restrinja o diretório de trabalho a uma pasta de documentos e nunca o execute com uma conta privilegiada.
- Prefira Transport Layer Security (TLS). Aponte
NEXTPDF_BASE_URLpara um endpointhttps://em qualquer implantação não local. O SDK envia a chave como um tokenBearerno cabeçalhoAuthorization, de modo que o transporte em texto claro a exporia na rede.
Consulte Segurança e operações do Connect para conhecer os controles do lado do endpoint que dão suporte a essas práticas no lado do cliente.
Testar o servidor localmente antes de conectar um agente
Seção intitulada “Testar o servidor localmente antes de conectar um agente”Valide o servidor isoladamente antes de conectar um agente. A verificação mais rápida não exige PDF nem rede:
python -c "from nextpdf.mcp import _tool_definitions; print(len(_tool_definitions()))"Uma instalação correta imprime 8. Se você vir um ImportError mencionando o extra mcp, a dependência opcional está ausente. Reinstale com pip install nextpdf[mcp].
Em seguida, valide as mesmas chamadas do SDK que as ferramentas usam, por meio da CLI. A CLI se comunica com o endpoint usando as mesmas duas variáveis de ambiente. Defina-as uma vez:
export NEXTPDF_BASE_URL="https://connect.example.com"export NEXTPDF_API_KEY="$(cat /run/secrets/nextpdf_api_key)"Depois, confirme a versão, a conectividade e uma extração real:
nextpdf versionnextpdf info /path/to/sample.pdfnextpdf extract text /path/to/sample.pdf --headings-onlynextpdf version é executado sem credenciais e confirma que o pacote é importado. nextpdf info aciona get_document_ast, a mesma chamada usada por nextpdf_get_ast e nextpdf_info. Se ambos forem bem-sucedidos, as credenciais e o endpoint estão corretos e as ferramentas MCP correspondentes funcionarão.
Para acionar o protocolo MCP diretamente, use o MCP Inspector do upstream (incluído no pacote mcp). Aponte-o para o mesmo comando e ambiente que o agente vai usar e, em seguida, liste e invoque as ferramentas manualmente. Verifique se nextpdf_health relata status: "ok". Ele retorna misconfigured sempre que NEXTPDF_BASE_URL ou NEXTPDF_API_KEY não estiver definida, o que é a forma mais rápida de detectar um valor de ambiente ausente antes que um agente chame uma ferramenta real.
Monitorar e depurar chamadas de ferramentas
Seção intitulada “Monitorar e depurar chamadas de ferramentas”O servidor MCP se comunica pela entrada/saída padrão (stdio), portanto a saída padrão carrega o fluxo do protocolo e deve permanecer limpa. O servidor não configura logging próprio da aplicação. Os principais canais de observabilidade são as cargas úteis estruturadas de erro de ferramenta, a CLI e os logs do próprio endpoint.
- As cargas úteis de erro de ferramenta são o principal sinal. Toda chamada com falha retorna um objeto JSON com
errore, para erros do SDK,error_typeestatus_code(consulte Tratamento de erros). Configure o host do agente para registrar essas cargas úteis. Elas identificam a ferramenta que falhou e a causa exata, sem instrumentação adicional no servidor. - Reproduza por meio da CLI com log de depuração. O próprio servidor MCP não emite logs, mas a CLI exercita as mesmas chamadas do SDK e gera logs. Reproduza uma ferramenta com falha por meio do comando da CLI correspondente com
--log-level debug. A CLI grava logs em stderr com carimbos de data/hora e registra tracebacks completos para erros inesperados, o que é a forma mais direta de ver o que um manipulador está fazendo sem conectar um depurador. - Use health como sonda. Chame
nextpdf_healthpara confirmar que o servidor consegue ler uma URL base e uma chave de API. O resultado informasdk_version,server_url,api_key_configured(um booleano, nunca a própria chave) estatus. - Observabilidade do lado do endpoint. Como cada ferramenta mapeia para uma requisição do Connect, correlacione a atividade das ferramentas com os logs de acesso do endpoint por chave de API e carimbo de data/hora. Execute o endpoint atrás dos mesmos controles de autenticação, cota e observabilidade que você usa para outros clientes de serviço.
Solução de problemas comuns de integração de agentes
Seção intitulada “Solução de problemas comuns de integração de agentes”| Sintoma | Causa provável | Solução |
|---|---|---|
O servidor não inicia e mostra um ImportError sobre o extra mcp opcional | A dependência opcional mcp não está instalada | Instale com pip install nextpdf[mcp]. |
A primeira chamada de ferramenta retorna {"error": "NEXTPDF_BASE_URL environment variable is required..."} | O bloco env do MCP não forneceu a URL base, ou o shell não expandiu ${NEXTPDF_BASE_URL} | Defina a variável no ambiente do host do agente e confirme que o iniciador a expande. |
nextpdf_health reporta "status": "misconfigured" | Uma das duas variáveis obrigatórias está vazia | Forneça tanto NEXTPDF_BASE_URL quanto NEXTPDF_API_KEY. |
Toda ferramenta baseada em caminho retorna {"error": "PDF file not found: <path>"} | O agente passou um caminho relativo ou de um host que o processo do servidor não consegue ver | Passe um caminho absoluto legível pelo usuário do servidor; confirme com nextpdf info <path>. |
A ferramenta retorna error_typeNextPDFLicenseError (status 402) | A operação precisa de um nível de licença mais alto do lado do servidor | Use um endpoint e uma chave com autorização para a operação. |
A ferramenta retorna error_typeAstNoStructTreeError (status 422) | O PDF não está marcado e o fallback heurístico está desativado | Habilite o modo heurístico no endpoint ou marque o PDF primeiro. |
A ferramenta retorna error_typeQuotaExceededError (status 429) | Um limite de taxa ou cota foi atingido | Pause e tente novamente; aumente a cota do endpoint se o limite for muito baixo. |
A ferramenta retorna error_typeAstBuildTimeoutError (status 504), ou um timeout de transporte | O documento é grande demais para o orçamento de tempo | Restrinja o escopo com max_pages, page_index ou page_start/page_end. |
| O agente não registra nenhuma ferramenta do NextPDF | O agente invocou python -m nextpdf (a CLI) em vez de python -m nextpdf.mcp | Use python -m nextpdf.mcp como o command/args. |
Para falhas no nível do endpoint e verificações de implantação, consulte Solução de problemas do Connect. Para as operações do SDK encapsuladas por essas ferramentas, consulte a referência da CLI e a visão geral do SDK.