Servidor MCP em Python
Servidor MCP em Python
Seção intitulada “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.