Pular para o conteúdo

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:

Terminal window
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.

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 MCPChamada do SDKObservações
nextpdf_extract_textast.extract_cited_text(pdf_data, page_index=..., headings_only=...)Retorna uma lista de CitedTextBlock.
nextpdf_extract_tablesast.extract_cited_tables(pdf_data, page_range=...)Retorna ExtractCitedTablesResponse.
nextpdf_get_astast.get_document_ast(pdf_data, page_range_start=0, page_range_end=..., token_budget=...)Retorna AstDocument.
nextpdf_infoast.get_document_ast(pdf_data)O servidor deriva um resumo de metadados; não há endpoint dedicado.
nextpdf_healthnenhumaInspeciona somente variáveis de ambiente; não faz chamada de rede.
nextpdf_searchast.search_ast_nodes(pdf_data, node_type=..., page_index=..., text_query=..., max_results=...)Retorna SearchAstNodesResponse.
nextpdf_get_outlineast.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_diffast.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_text declara um campo max_pages no 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 de page_index (uma única página, com índice baseado em 0). Use nextpdf_get_ast com max_pages quando precisar limitar uma varredura no documento inteiro.
  • nextpdf_get_ast converte max_pages em um intervalo de páginas inclusivo de [0, max_pages - 1] (o padrão de max_pages é 50). Passe token_budget para limitar o tamanho da árvore retornada.
  • nextpdf_info retorna schema_version, source_hash, page_count, estimated_tokens, root_node_type e root_children_count. Esses valores vêm do modelo AstDocument, em que estimated_tokens é uma propriedade calculada (aproximadamente quatro caracteres por token).
  • nextpdf_get_outline retorna uma entrada por cabeçalho com id, page_index, text e depth (lido de attributes["level"] do nó, com valor padrão 1), além de heading_count, total_matches e truncated.

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.

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çãoJSON 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çãoStatus HTTPerror_codeQuando
NextPDFLicenseError402license/tier-requiredO endpoint exige, no lado do servidor, um nível de licença mais alto para a operação.
AstNoStructTreeError422ast/no-struct-treeO PDF não está marcado e o fallback heurístico não está habilitado no servidor.
QuotaExceededError429quota/exceededUm limite de taxa ou cota foi atingido. Carrega retry_after (segundos) quando o servidor envia um cabeçalho Retry-After.
AstBuildTimeoutError504ast/build-timeoutA construção da AST excedeu o orçamento de tempo do servidor. Reduza o intervalo de páginas.
NextPDFAPIErroroutros 4xx/5xxfornecido pelo servidorQualquer 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 de Unexpected error da camada de transporte. Quando você vir ast/build-timeout, oriente o agente a restringir o escopo: reduza max_pages em nextpdf_get_ast ou defina page_index / page_start e page_end nas ferramentas de extração.
  • Cota e backoff. Em caso de 429, a ferramenta retorna o error_type igual a QuotaExceededError, com status_code 429. O valor de retry_after fica no objeto da exceção. Como o servidor serializa apenas error, error_type e status_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-tree significa 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_URL para um endpoint https:// em qualquer implantação não local. O SDK envia a chave como um token Bearer no cabeçalho Authorization, 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:

Terminal window
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:

Terminal window
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:

Terminal window
nextpdf version
nextpdf info /path/to/sample.pdf
nextpdf extract text /path/to/sample.pdf --headings-only

nextpdf 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.

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 error e, para erros do SDK, error_type e status_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_health para confirmar que o servidor consegue ler uma URL base e uma chave de API. O resultado informa sdk_version, server_url, api_key_configured (um booleano, nunca a própria chave) e status.
  • 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”
SintomaCausa provávelSolução
O servidor não inicia e mostra um ImportError sobre o extra mcp opcionalA dependência opcional mcp não está instaladaInstale 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á vaziaForneç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 verPasse 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 servidorUse 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á desativadoHabilite 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 atingidoPause 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 transporteO documento é grande demais para o orçamento de tempoRestrinja o escopo com max_pages, page_index ou page_start/page_end.
O agente não registra nenhuma ferramenta do NextPDFO agente invocou python -m nextpdf (a CLI) em vez de python -m nextpdf.mcpUse 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.