Serwer MCP dla języka Python
Serwer MCP dla języka Python
Dział zatytułowany „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:
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.
Katalog narzędzi i mapowanie na pakiet SDK
Dział zatytułowany „Katalog narzędzi i mapowanie na pakiet SDK”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 MCP | Wywołanie SDK | Uwagi |
|---|---|---|
nextpdf_extract_text | ast.extract_cited_text(pdf_data, page_index=..., headings_only=...) | Zwraca listę obiektów CitedTextBlock. |
nextpdf_extract_tables | ast.extract_cited_tables(pdf_data, page_range=...) | Zwraca ExtractCitedTablesResponse. |
nextpdf_get_ast | ast.get_document_ast(pdf_data, page_range_start=0, page_range_end=..., token_budget=...) | Zwraca AstDocument. |
nextpdf_info | ast.get_document_ast(pdf_data) | Serwer tworzy podsumowanie metadanych; brak dedykowanego punktu końcowego. |
nextpdf_health | brak | Sprawdza wyłącznie zmienne środowiskowe; nie wykonuje żadnego wywołania sieciowego. |
nextpdf_search | ast.search_ast_nodes(pdf_data, node_type=..., page_index=..., text_query=..., max_results=...) | Zwraca SearchAstNodesResponse. |
nextpdf_get_outline | ast.search_ast_nodes(pdf_data, node_type="heading", max_results=500) | Serwer przekształca węzły nagłówków w konspekt. |
nextpdf_diff | ast.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_textdeklaruje polemax_pagesw swoim schemacie wejściowym, ale moduł obsługi tekstu nie przekazuje go do pakietu SDK. Ograniczanie zakresu stron dla tekstu odbywa się poprzezpage_index(pojedynczą stronę liczoną od 0). Użyjnextpdf_get_astzmax_pages, gdy potrzebujesz ograniczyć przetwarzanie całego dokumentu.nextpdf_get_astprzekładamax_pagesna włączny zakres stron[0, max_pages - 1](domyślna wartośćmax_pagesto 50). Przekażtoken_budget, aby ograniczyć rozmiar zwracanego drzewa.nextpdf_infozwracaschema_version,source_hash,page_count,estimated_tokens,root_node_typeorazroot_children_count. Wartości te pochodzą z modeluAstDocument, w którymestimated_tokensjest właściwością obliczaną (w przybliżeniu cztery znaki na token).nextpdf_get_outlinezwraca jeden wpis na nagłówek z polamiid,page_index,textorazdepth(odczytywanym zattributes["level"]węzła, z domyślną wartością 1), a także polamiheading_count,total_matchesoraztruncated.
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.
Obsługa błędów, limity czasu i przydziały
Dział zatytułowany „Obsługa błędów, limity czasu i przydziały”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:
| Warunek | Zwracany 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ątek | Status HTTP | error_code | Kiedy |
|---|---|---|---|
NextPDFLicenseError | 402 | license/tier-required | Punkt końcowy wymaga wyższego poziomu licencji po stronie serwera do tej operacji. |
AstNoStructTreeError | 422 | ast/no-struct-tree | Plik PDF nie jest otagowany, a awaryjny tryb heurystyczny nie jest włączony na serwerze. |
QuotaExceededError | 429 | quota/exceeded | Osiągnięto limit szybkości lub przydział. Zawiera retry_after (w sekundach), gdy serwer wysyła nagłówek Retry-After. |
AstBuildTimeoutError | 504 | ast/build-timeout | Budowanie AST przekroczyło budżet czasowy serwera. Zmniejsz zakres stron. |
NextPDFAPIError | inny 4xx/5xx | dostarczany przez serwer | Dowolna 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 ładunekUnexpected errorz warstwy transportowej. Gdy zobaczyszast/build-timeout, poleć agentowi zawęzić zakres: zmniejszmax_pageswnextpdf_get_astlub ustawpage_index/page_startorazpage_endw narzędziach wyodrębniania. - Przydział i ponawianie. Przy odpowiedzi 429 narzędzie zwraca
error_typerówneQuotaExceededErrorzstatus_code429. Wartośćretry_afterznajduje się w obiekcie wyjątku. Ponieważ serwer serializuje wyłącznieerror,error_typeorazstatus_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-treeoznacza, ż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_URLna punkt końcowyhttps://. Pakiet SDK wysyła klucz jako tokenBearerw nagłówkuAuthorization, 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:
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:
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:
nextpdf versionnextpdf info /path/to/sample.pdfnextpdf extract text /path/to/sample.pdf --headings-onlynextpdf 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.
Monitorowanie i debugowanie wywołań narzędzi
Dział zatytułowany „Monitorowanie i debugowanie wywołań narzędzi”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 polamierror_typeorazstatus_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łaszasdk_version,server_url,api_key_configured(wartość logiczną, nigdy sam klucz) orazstatus. - 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”| Objaw | Prawdopodobna przyczyna | Rozwiązanie |
|---|---|---|
Serwer nie uruchamia się i zgłasza ImportError dotyczący dodatku mcp | Opcjonalna zależność mcp nie jest zainstalowana | Zainstaluj 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 pusta | Podaj 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 widzi | Przekaż ś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 serwera | Uż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łączony | Włą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 transportu | Dokument jest zbyt duży względem budżetu czasowego | Zawęź zakres za pomocą max_pages, page_index lub page_start/page_end. |
| Agent nie rejestruje żadnych narzędzi NextPDF | Agent wywołał python -m nextpdf (CLI) zamiast python -m nextpdf.mcp | Uż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.