Przejdź do głównej zawartości

Serwer MCP dla języka Python

Pakiet SDK NextPDF dla języka Python zawiera serwer Model Context Protocol (MCP), który udostępnia operacje wyodrębniania danych z plików PDF jako natywne narzędzia agentom. Agent obsługujący MCP, taki jak Claude Code, rejestruje serwer raz, a następnie wywołuje narzędzia NextPDF tak samo jak każde inne narzędzie.

Serwer działa jako lekki adapter. Każde narzędzie odczytuje plik PDF z dysku lokalnego, wywołuje klienta asynchronicznego dla skonfigurowanego punktu końcowego NextPDF Connect i zwraca wynik jako ciąg znaków w formacie JSON. Serwer nie przechowuje logiki biznesowej ani nie zapisuje żadnych danych między wywołaniami.

Zainstaluj pakiet SDK z dodatkiem MCP:

Okno terminala
pip install nextpdf[mcp]

Dodatek mcp instaluje pakiet upstream mcp (ograniczenie mcp>=1.0,<2.0). Serwer wymaga języka Python 3.10 lub nowszego.

Uruchom moduł serwera z poziomu konfiguracji klienta MCP. Poniższy przykład odczytuje oba parametry połączenia ze środowiska hosta, zamiast osadzać klucz tajny w pliku konfiguracyjnym (zob. Bezpieczeństwo):

{
"mcpServers": {
"nextpdf": {
"command": "python",
"args": ["-m", "nextpdf.mcp"],
"env": {
"NEXTPDF_BASE_URL": "https://connect.example.com",
"NEXTPDF_API_KEY": "${NEXTPDF_API_KEY}"
}
}
}
}

Punkt wejścia python -m nextpdf.mcp wywołuje funkcję main(), która uruchamia serwer przez standardowe wejście/wyjście (stdio) z użyciem asyncio.run(serve()). Nie myl tego z python -m nextpdf, które uruchamia interfejs wiersza poleceń (CLI), a nie serwer MCP.

NEXTPDF_BASE_URL oraz NEXTPDF_API_KEY są wymagane. Serwer tworzy klienta leniwie przy pierwszym wywołaniu narzędzia. Jeśli którakolwiek ze zmiennych jest pusta, zgłasza wyjątek RuntimeError i zwraca go agentowi jako błąd narzędzia, zamiast powodować awarię procesu.

Serwer rejestruje osiem narzędzi. Każda nazwa narzędzia używa przedrostka nextpdf_. Każde narzędzie jest mapowane na metodę w przestrzeni nazw ast klienta asynchronicznego (AsyncNextPDF.ast), z wyjątkiem dwóch narzędzi złożonych wymienionych poniżej. Serwer składa je z wywołań niższego poziomu.

Narzędzie MCPWywołanie SDKUwagi
nextpdf_extract_textast.extract_cited_text(pdf_data, page_index=..., headings_only=...)Zwraca listę obiektów CitedTextBlock.
nextpdf_extract_tablesast.extract_cited_tables(pdf_data, page_range=...)Zwraca ExtractCitedTablesResponse.
nextpdf_get_astast.get_document_ast(pdf_data, page_range_start=0, page_range_end=..., token_budget=...)Zwraca AstDocument.
nextpdf_infoast.get_document_ast(pdf_data)Serwer tworzy podsumowanie metadanych; brak dedykowanego punktu końcowego.
nextpdf_healthbrakSprawdza wyłącznie zmienne środowiskowe; nie wykonuje żadnego wywołania sieciowego.
nextpdf_searchast.search_ast_nodes(pdf_data, node_type=..., page_index=..., text_query=..., max_results=...)Zwraca SearchAstNodesResponse.
nextpdf_get_outlineast.search_ast_nodes(pdf_data, node_type="heading", max_results=500)Serwer przekształca węzły nagłówków w konspekt.
nextpdf_diffast.get_ast_diff(original_pdf_data, modified_pdf_data)Zwraca GetAstDiffResponse.

Zanim podłączysz agenta, zwróć uwagę na następujące szczegóły danych wejściowych narzędzi:

  • Wszystkie dane wejściowe będące ścieżkami (pdf_path, original_pdf_path, modified_pdf_path) muszą być ścieżkami bezwzględnymi do plików na maszynie, na której działa serwer. Agent przekazuje ścieżkę, a serwer odczytuje bajty lokalnie. Nie ma osobnego narzędzia do przesyłania plików.
  • nextpdf_extract_text deklaruje pole max_pages w swoim schemacie wejściowym, ale moduł obsługi tekstu nie przekazuje go do pakietu SDK. Ograniczanie zakresu stron dla tekstu odbywa się poprzez page_index (pojedynczą stronę liczoną od 0). Użyj nextpdf_get_ast z max_pages, gdy potrzebujesz ograniczyć przetwarzanie całego dokumentu.
  • nextpdf_get_ast przekłada max_pages na włączny zakres stron [0, max_pages - 1] (domyślna wartość max_pages to 50). Przekaż token_budget, aby ograniczyć rozmiar zwracanego drzewa.
  • nextpdf_info zwraca schema_version, source_hash, page_count, estimated_tokens, root_node_type oraz root_children_count. Wartości te pochodzą z modelu AstDocument, w którym estimated_tokens jest właściwością obliczaną (w przybliżeniu cztery znaki na token).
  • nextpdf_get_outline zwraca jeden wpis na nagłówek z polami id, page_index, text oraz depth (odczytywanym z attributes["level"] węzła, z domyślną wartością 1), a także polami heading_count, total_matches oraz truncated.

Narzędzia wyodrębniania z cytowaniami dodają do każdego wyniku obiekt CitationAnchor. Każda kotwica zawiera node_id, page_index, znormalizowany bbox (współrzędne z zakresu od 0.0 do 1.0) oraz wartość confidence (od 0.0 do 1.0). Agenci, którzy potrzebują informacji o pochodzeniu, powinni wyświetlać te pola, zamiast ograniczać się do surowego tekstu.

Serwer nigdy nie pozwala, aby wyjątek przedostał się do warstwy transportowej agenta. Dyspozytor call_tool przechwytuje każdy błąd i zwraca go jako TextContent w formacie JSON, dzięki czemu nieudane wywołanie narzędzia tworzy ustrukturyzowany ładunek, który agent może odczytać, zamiast zerwanego połączenia. Struktury ładunków są następujące:

WarunekZwracany JSON
Nieznana nazwa narzędzia{"error": "Unknown tool: <name>"}
Brak pliku wejściowego{"error": "PDF file not found: <path>"}
Dowolna podklasa NextPDFError{"error": "<message>", "error_type": "<class>", "status_code": <int?>}
Dowolny inny wyjątek{"error": "Unexpected error: <message>"}

status_code pojawia się tylko wtedy, gdy bazowy błąd je zawiera. Pakiet SDK mapuje odpowiedzi HTTP na hierarchię typowanych wyjątków, których korzeniem jest NextPDFError:

WyjątekStatus HTTPerror_codeKiedy
NextPDFLicenseError402license/tier-requiredPunkt końcowy wymaga wyższego poziomu licencji po stronie serwera do tej operacji.
AstNoStructTreeError422ast/no-struct-treePlik PDF nie jest otagowany, a awaryjny tryb heurystyczny nie jest włączony na serwerze.
QuotaExceededError429quota/exceededOsiągnięto limit szybkości lub przydział. Zawiera retry_after (w sekundach), gdy serwer wysyła nagłówek Retry-After.
AstBuildTimeoutError504ast/build-timeoutBudowanie AST przekroczyło budżet czasowy serwera. Zmniejsz zakres stron.
NextPDFAPIErrorinny 4xx/5xxdostarczany przez serwerDowolna inna awaria na poziomie interfejsu API.

Przy integracjach z agentami kieruj się poniższymi wskazówkami:

  • Limity czasu. Klient HTTP używa stałego domyślnego limitu czasu: 60 sekund łącznie oraz 10 sekund na nawiązanie połączenia. Wolny lub duży dokument kończy się albo jako AstBuildTimeoutError (serwer zrezygnował z budowania AST), albo, jeśli limit czasu przekroczy sam klient, jako ładunek Unexpected error z warstwy transportowej. Gdy zobaczysz ast/build-timeout, poleć agentowi zawęzić zakres: zmniejsz max_pages w nextpdf_get_ast lub ustaw page_index / page_start oraz page_end w narzędziach wyodrębniania.
  • Przydział i ponawianie. Przy odpowiedzi 429 narzędzie zwraca error_type równe QuotaExceededError z status_code 429. Wartość retry_after znajduje się w obiekcie wyjątku. Ponieważ serwer serializuje wyłącznie error, error_type oraz status_code, agent powinien traktować odpowiedź 429 jako sygnał do wstrzymania i ponowienia próby później, zamiast analizować nagłówek ponowienia z danych wyjściowych narzędzia. Wymuszaj przydziały w punkcie końcowym Connect, a nie w agencie.
  • Nieotagowane pliki PDF. Odpowiedź 422 ast/no-struct-tree oznacza, że źródłowy plik PDF nie ma drzewa struktury. Włącz tryb heurystyczny na serwerze dla takich dokumentów albo skieruj je do tagowania przed wyodrębnianiem.

Bezpieczeństwo: ograniczanie zakresu kluczy API i najmniejsze uprawnienia

Dział zatytułowany „Bezpieczeństwo: ograniczanie zakresu kluczy API i najmniejsze uprawnienia”

Traktuj klucz API jak klucz tajny, z taką samą starannością, z jaką traktujesz hasło do bazy danych.

  • Nigdy nie osadzaj klucza w pliku konfiguracyjnym MCP. Powyższy przykład w formacie JSON odwołuje się do ${NEXTPDF_API_KEY}, dzięki czemu wartość jest podstawiana ze środowiska hosta lub menedżera kluczy tajnych w momencie uruchomienia. Plik konfiguracyjny może zostać zatwierdzony w systemie kontroli wersji; klucz tajny nie może.
  • Ogranicz zakres klucza do wyodrębniania tylko do odczytu. Serwer MCP wywołuje wyłącznie interfejs wyodrębniania AST (extract_cited_text, extract_cited_tables, get_document_ast, search_ast_nodes, get_ast_diff). Nie renderuje, nie podpisuje, nie redaguje ani nie modyfikuje dokumentów. Wydaj agentowi klucz, którego zakres po stronie serwera jest ograniczony do tych ścieżek odczytu, aby przejęty agent nie mógł sięgnąć po operacje zapisu ani operacje wyższego poziomu.
  • Używaj dedykowanego klucza dla każdego agenta. Klucz przypisany do agenta pozwala unieważnić lub wymienić pojedynczą integrację bez wpływu na pozostałe, a także sprawia, że dzienniki punktu końcowego można przypisać do konkretnego agenta.
  • Ogranicz dostęp do systemu plików. Ponieważ każde narzędzie odczytuje ścieżkę bezwzględną z dysku lokalnego, serwer może odczytać dowolny plik, do którego odczytu uprawniony jest proces hosta. Uruchamiaj go jako użytkownik bez uprawnień, ogranicz jego katalog roboczy do folderu z dokumentami i nigdy nie uruchamiaj go na koncie uprzywilejowanym.
  • Preferuj Transport Layer Security (TLS). Dla każdego wdrożenia innego niż lokalne ustaw NEXTPDF_BASE_URL na punkt końcowy https://. Pakiet SDK wysyła klucz jako token Bearer w nagłówku Authorization, więc transport tekstem jawnym ujawniłby go w sieci.

Zob. Bezpieczeństwo i operacje Connect, aby poznać mechanizmy kontroli po stronie punktu końcowego, które wspierają te praktyki po stronie klienta.

Lokalne testowanie serwera przed podłączeniem agenta

Dział zatytułowany „Lokalne testowanie serwera przed podłączeniem agenta”

Zweryfikuj serwer w izolacji, zanim podłączysz agenta. Najszybsze sprawdzenie nie wymaga pliku PDF ani sieci:

Okno terminala
python -c "from nextpdf.mcp import _tool_definitions; print(len(_tool_definitions()))"

Poprawna instalacja wypisuje 8. Jeśli zobaczysz ImportError dotyczący dodatku mcp, oznacza to, że opcjonalna zależność nie jest zainstalowana. Zainstaluj ponownie za pomocą pip install nextpdf[mcp].

Następnie sprawdź za pomocą interfejsu CLI te same ścieżki SDK, których używają narzędzia. Interfejs CLI komunikuje się z punktem końcowym przy użyciu tych samych dwóch zmiennych środowiskowych. Ustaw je jednorazowo:

Okno terminala
export NEXTPDF_BASE_URL="https://connect.example.com"
export NEXTPDF_API_KEY="$(cat /run/secrets/nextpdf_api_key)"

Następnie potwierdź wersję, łączność i rzeczywiste wyodrębnianie:

Okno terminala
nextpdf version
nextpdf info /path/to/sample.pdf
nextpdf extract text /path/to/sample.pdf --headings-only

nextpdf version działa bez poświadczeń i potwierdza, że pakiet daje się poprawnie zaimportować. nextpdf info sprawdza get_document_ast, czyli to samo wywołanie, na którym opierają się nextpdf_get_ast oraz nextpdf_info. Jeśli obie operacje się powiodą, poświadczenia i punkt końcowy są prawidłowe, a odpowiadające im narzędzia MCP będą działać.

Aby sterować protokołem MCP bezpośrednio, użyj upstreamowego narzędzia MCP Inspector (dostarczanego z pakietem mcp). Skieruj je na to samo polecenie i środowisko, których będzie używać agent, a następnie ręcznie wypisz i wywołaj narzędzia. Sprawdź, czy nextpdf_health zgłasza status: "ok". Zwraca misconfigured za każdym razem, gdy NEXTPDF_BASE_URL lub NEXTPDF_API_KEY nie jest ustawiona, co jest najszybszym sposobem na wychwycenie brakującej wartości środowiskowej, zanim agent wywoła rzeczywiste narzędzie.

Serwer MCP komunikuje się przez standardowe wejście/wyjście (stdio), więc jego standardowe wyjście przenosi strumień protokołu i musi pozostawać czyste. Serwer nie konfiguruje własnego rejestrowania aplikacji. Główne kanały obserwowalności to ustrukturyzowane ładunki błędów narzędzi, interfejs CLI oraz własne dzienniki punktu końcowego.

  • Ładunki błędów narzędzi są sygnałem. Każde nieudane wywołanie zwraca obiekt JSON z polem error, a w przypadku błędów SDK z polami error_type oraz status_code (zob. Obsługa błędów). Host agenta powinien rejestrować te ładunki. Identyfikują one nieudane narzędzie i dokładną przyczynę bez dodatkowego oprzyrządowania serwera.
  • Odtwórz problem za pomocą interfejsu CLI z rejestrowaniem debugowania. Sam serwer MCP nie emituje żadnych dzienników, ale interfejs CLI wykonuje te same wywołania SDK i je rejestruje. Odtwórz nieudane narzędzie za pomocą odpowiadającego mu polecenia CLI z --log-level debug. Interfejs CLI rejestruje dane na stderr ze znacznikami czasu i zapisuje pełne ślady stosu dla nieoczekiwanych błędów, co jest najbardziej bezpośrednim sposobem na zobaczenie, co robi moduł obsługi, bez podłączania debugera.
  • Kontrola kondycji jako sonda. Wywołaj nextpdf_health, aby potwierdzić, że serwer widzi bazowy adres URL i klucz API. Wynik zgłasza sdk_version, server_url, api_key_configured (wartość logiczną, nigdy sam klucz) oraz status.
  • Obserwowalność po stronie punktu końcowego. Ponieważ każde narzędzie odpowiada jednemu żądaniu Connect, koreluj aktywność narzędzi z dziennikami dostępu punktu końcowego według klucza API i znacznika czasu. Uruchamiaj punkt końcowy z tymi samymi mechanizmami kontroli uwierzytelniania, przydziałów i obserwowalności, których używasz dla innych klientów usługi.

Rozwiązywanie typowych problemów z integracją agentów

Dział zatytułowany „Rozwiązywanie typowych problemów z integracją agentów”
ObjawPrawdopodobna przyczynaRozwiązanie
Serwer nie uruchamia się i zgłasza ImportError dotyczący dodatku mcpOpcjonalna zależność mcp nie jest zainstalowanaZainstaluj za pomocą pip install nextpdf[mcp].
Pierwsze wywołanie narzędzia zwraca {"error": "NEXTPDF_BASE_URL environment variable is required..."}Blok env MCP nie przekazał bazowego adresu URL albo powłoka nie rozwinęła ${NEXTPDF_BASE_URL}Ustaw zmienną w środowisku hosta agenta i potwierdź, że program uruchamiający ją rozwija.
nextpdf_health zgłasza "status": "misconfigured"Jedna z dwóch wymaganych zmiennych jest pustaPodaj zarówno NEXTPDF_BASE_URL, jak i NEXTPDF_API_KEY.
Każde narzędzie oparte na ścieżkach zwraca {"error": "PDF file not found: <path>"}Agent przekazał ścieżkę względną lub ścieżkę po stronie hosta, której proces serwera nie widziPrzekaż ścieżkę bezwzględną możliwą do odczytania przez użytkownika serwera; potwierdź za pomocą nextpdf info <path>.
Narzędzie zwraca error_typeNextPDFLicenseError (status 402)Operacja wymaga wyższego poziomu licencji po stronie serweraUżyj punktu końcowego i klucza uprawnionego do tej operacji.
Narzędzie zwraca error_typeAstNoStructTreeError (status 422)Plik PDF nie jest otagowany, a awaryjny tryb heurystyczny jest wyłączonyWłącz tryb heurystyczny w punkcie końcowym lub najpierw otaguj plik PDF.
Narzędzie zwraca error_typeQuotaExceededError (status 429)Osiągnięto limit szybkości lub przydziałWstrzymaj i ponów próbę; zwiększ przydział punktu końcowego, jeśli limit jest zbyt niski.
Narzędzie zwraca error_typeAstBuildTimeoutError (status 504) lub upływa limit czasu transportuDokument jest zbyt duży względem budżetu czasowegoZawęź zakres za pomocą max_pages, page_index lub page_start/page_end.
Agent nie rejestruje żadnych narzędzi NextPDFAgent wywołał python -m nextpdf (CLI) zamiast python -m nextpdf.mcpUżyj python -m nextpdf.mcp jako command/args.

W przypadku awarii na poziomie punktu końcowego i kontroli wdrożeniowych zob. Rozwiązywanie problemów z Connect. Aby poznać operacje SDK, które opakowują te narzędzia, zob. Dokumentację interfejsu CLI oraz Przegląd pakietu SDK.