İçeriğe geç
getnextpdf.com

Bir aracı belge oturumunu MCP üzerinden yürütün

Bu, NextPDF Connect Model Context Protocol (MCP) sunucusuna karşı, mesaj mesaj, eksiksiz bir aracı oturumudur: initialize, tools/list, tek sayfalık bir proje özeti oluşturan altı tools/call çağrısı ve son dosya yazma işlemini geçitleyen insanın döngüde olduğu (HITL) gidiş-dönüşü. Aşağıdaki her JSON-RPC mesajı, canlı bir bin/nextpdf-mcp sürecinden birebir yakalanmış (yalnızca core katmanı araçları), ardından tam olarak iki şekilde arındırılmıştır: tek kullanımlık onay belirteci confirm_<single-use-hex> olarak gösterilir ve makinenin sistem geçici dizini C:\Temp olarak kısaltılır. Tanımlayıcılar, şemalar, konumlar ve bayt sayıları, sunucunun gönderdiği değerlerin tam olarak kendisidir.

Terminal window
composer require nextpdf/server

stdio taşıma katmanını MCP ana makinenizde bağlayın — Claude Desktop için (ana makineler komutu kendi dizinlerinden başlatır, bu nedenle mutlak bir yol kullanın; stdio taşıma katmanı, REST taşıma katmanının aksine API anahtarı gerektirmez):

{
"mcpServers": {
"nextpdf": {
"command": "php",
"args": ["/absolute/path/to/your/project/vendor/bin/nextpdf-mcp"]
}
}
}

Sunucu, stdin/stdout üzerinde satır sonuyla ayrılmış JSON-RPC 2.0 konuşur ve protokol çıktısını tanılama bilgilerinden kesin olarak ayrı tutar: başlangıç ve denetim satırları stdout’a değil, stderr’e gider.

Bir MCP belge oturumu durum bilgisi taşır. create_pdf, sunucunun bellek içi deposunda bir belge açar ve bir document_id döndürür; sonraki her çağrı bu tanımlayıcıyı hedefler. İçerik araçları (set_font, add_text, add_table), denetim günlüğü tutularak Dikkat risk düzeyinde hemen çalışır; preview_layout bir Güvenli okumadır; ve file_path içeren output_pdf, Onay gerekli düzeyindedir — ilk çağrıda çalışmaz. Bunun yerine sunucu, tek kullanımlık bir belirteç içeren bir sınama döndürür, aracı sınamayı insana iletir ve yalnızca _confirmation_token taşıyan yeniden çağrı yazma işlemini gerçekleştirir. Depoda bırakılan belgeler, yapılandırılan yaşam süresinin (varsayılan olarak 30 dakika) ardından sona erer.

Aynı araç çağrıları, araç motorunu REST ve gRPC üzerinden de yürütür — taşıma katmanları tek bir yürütücüyü paylaşır — bu nedenle stdio çerçeveleme dışındaki her şey aynen geçerlidir. HTTP yüzeyindeki aynı motor için Bir faturayı REST üzerinden uçtan uca işleme sayfasına bakın.

AraçBu oturumdaki rolüRisk düzeyi
create_pdfBelgeyi açın, document_id alınDikkat
set_fontBaşlık, ardından gövde yazı tipini seçinDikkat
add_textBaşlık satırı, ardından giriş paragrafıDikkat
add_tableSorumlu/son tarih kontrol listesi tablosuDikkat
preview_layoutÇıktıdan önce yerleşim durumunu okuyunGüvenli
output_pdf (dosya modu)PDF’i yazın — geçitliOnay gerekli

Burada yakalanan dağıtım 20 araç kaydetti (13 core, 6 Pro, 1 Enterprise — sayılar aşağıdaki initialize yanıtında görünür); bu oturum yalnızca core araçlarını kullanır, bu nedenle yalnızca açık kaynaklı bir kurulumda değişmeden çalışır. Resmi kayıt kataloğu, kendi sunucunuzun tools/list yanıtıdır ve risk merdiveni HITL risk katmanları başvurusunda tanımlanmıştır.

İstemci oturumu açar ve protokol sürümünü belirtir:

{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {
"name": "planning-agent",
"version": "1.0.0"
}
}
}

Sunucu, protokol sürümünü onaylar ve katman başına araç sayıları ile HITL geçitlemesinin etkin olduğu dahil olmak üzere yeteneklerini bildirir:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {
"tools": {
"listChanged": false
},
"nextpdf": {
"tiers": {
"core": 13,
"pro": 6,
"enterprise": 1
},
"tool_count": 20,
"risk_model_version": 1,
"hitl_enabled": true
}
},
"serverInfo": {
"name": "NextPDF Connect",
"version": "1.0.0"
}
}
}

İstemci bir bildirim ile onaylar (bildirimler id taşımaz ve yanıt almaz):

{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}

Tam yanıt, kayıtlı 20 aracın tamamını eksiksiz girdi şemalarıyla listeler. Burada, bu oturumu açan ve kapatan iki araca kısaltılmış olarak gösterilir — çıkarılan 18 girdi aynı şekle sahiptir:

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "create_pdf",
"description": "Create a new PDF document and return a document_id for subsequent operations",
"inputSchema": {
"type": "object",
"properties": {
"page_size": {
"type": "string",
"description": "Page size name (e.g. \"A4\", \"Letter\", \"Legal\", \"A3\")",
"default": "A4"
},
"orientation": {
"type": "string",
"enum": [
"portrait",
"landscape"
],
"description": "Page orientation",
"default": "portrait"
},
"title": {
"type": "string",
"description": "Document title metadata"
},
"author": {
"type": "string",
"description": "Document author metadata"
}
},
"required": []
},
"annotations": {
"destructiveHint": false,
"idempotentHint": false
}
},
{
"name": "output_pdf",
"description": "Finalize the PDF and output to file or return as base64",
"inputSchema": {
"type": "object",
"properties": {
"document_id": {
"type": "string",
"description": "The document_id returned by create_pdf"
},
"file_path": {
"type": "string",
"description": "Absolute file path to save the PDF. If omitted, returns base64-encoded PDF data."
},
"destroy": {
"type": "boolean",
"description": "Whether to remove the document from the store after output",
"default": true
}
},
"required": [
"document_id"
]
},
"annotations": {
"destructiveHint": false,
"openWorldHint": true
}
}
]
}
}

output_pdf’nin şemasına dikkat edin: file_path isteğe bağlıdır ve ek açıklamalar openWorldHint: true taşır — araç, oturumun dışındaki dünyaya dokunabilir; dosya modunun geçitlenmesinin tam nedeni budur.

{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "create_pdf",
"arguments": {
"page_size": "A4",
"orientation": "portrait",
"title": "Project kickoff brief",
"author": "Planning agent"
}
}
}
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\"document_id\":\"doc_3b9f435efa0f32d1da7a131d\",\"page_count\":1,\"page_size\":\"A4\",\"orientation\":\"portrait\"}"
}
],
"structuredContent": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"page_count": 1,
"page_size": "A4",
"orientation": "portrait"
}
}
}

Her araç sonucu, tek bir mesajda iki kez gelir: insanın okuyabildiği bir content metin bloğu ve makinenin okuyabildiği structuredContent. structuredContent.document_id değerini okuyun ve onu sonraki her çağrıda geçirin.

Kalın 16 punto bir yazı tipi ayarlayın, ardından başlığı yerleştirin:

{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "set_font",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"family": "helvetica",
"style": "B",
"size": 16
}
}
}
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [
{
"type": "text",
"text": "Font set to helvetica B 16pt on document doc_3b9f435efa0f32d1da7a131d."
}
]
}
}
{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "add_text",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"text": "Project kickoff brief"
}
}
}
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"content": [
{
"type": "text",
"text": "{\"document_id\":\"doc_3b9f435efa0f32d1da7a131d\",\"position\":{\"x\":10,\"y\":16,\"page\":0}}"
}
],
"structuredContent": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"position": {
"x": 10,
"y": 16,
"page": 0
}
}
}
}

Giriş metni için normal 11 punto yazı tipine dönün; width: 0, tam genişlikli çok hücreli yerleşimi seçer:

{
"jsonrpc": "2.0",
"id": 6,
"method": "tools/call",
"params": {
"name": "set_font",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"family": "helvetica",
"style": "",
"size": 11
}
}
}
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"content": [
{
"type": "text",
"text": "Font set to helvetica 11pt on document doc_3b9f435efa0f32d1da7a131d."
}
]
}
}
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "add_text",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"text": "Prepared by the planning agent for the 14 July kickoff. Scope, owners, and the first-week checklist are tabled below.",
"width": 0,
"line_height": 6
}
}
}
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"content": [
{
"type": "text",
"text": "{\"document_id\":\"doc_3b9f435efa0f32d1da7a131d\",\"position\":{\"x\":10,\"y\":29.75,\"page\":0}}"
}
],
"structuredContent": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"position": {
"x": 10,
"y": 29.75,
"page": 0
}
}
}
}
{
"jsonrpc": "2.0",
"id": 8,
"method": "tools/call",
"params": {
"name": "add_table",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"html": "<table><tr><th>Work item</th><th>Owner</th><th>Due</th></tr><tr><td>Repository bootstrap</td><td>Devon</td><td>2026-07-15</td></tr><tr><td>CI pipeline</td><td>Ana</td><td>2026-07-17</td></tr><tr><td>Staging deploy</td><td>Priya</td><td>2026-07-21</td></tr></table>"
}
}
}
{
"jsonrpc": "2.0",
"id": 8,
"result": {
"content": [
{
"type": "text",
"text": "{\"document_id\":\"doc_3b9f435efa0f32d1da7a131d\",\"position\":{\"x\":10,\"y\":84.75,\"page\":0}}"
}
],
"structuredContent": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"position": {
"x": 10,
"y": 84.75,
"page": 0
}
}
}
}

Her içerik çağrısı, güncellenmiş imleç position değerini döndürür; böylece aracı, sonraki öğenin nereye düşeceğini her zaman bilir.

preview_layout, Güvenli, salt okunur bir çağrıdır — iyi davranan bir aracı, bir insandan bir yazma işlemini onaylamasını istemeden önce ne oluşturduğunu denetler:

{
"jsonrpc": "2.0",
"id": 9,
"method": "tools/call",
"params": {
"name": "preview_layout",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d"
}
}
}
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"content": [
{
"type": "text",
"text": "{\"document_id\":\"doc_3b9f435efa0f32d1da7a131d\",\"total_pages\":1,\"current_page\":0,\"page_dimensions\":{\"width\":595.276,\"height\":841.89},\"margins\":{\"top\":10,\"right\":10,\"bottom\":10,\"left\":10},\"cursor_position\":{\"x\":10,\"y\":84.75}}"
}
],
"structuredContent": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"total_pages": 1,
"current_page": 0,
"page_dimensions": {
"width": 595.276,
"height": 841.89
},
"margins": {
"top": 10,
"right": 10,
"bottom": 10,
"left": 10
},
"cursor_position": {
"x": 10,
"y": 84.75
}
}
}
}

8. Dosya yazma işlemini isteyin — geçit önce yanıtlar

“8. Dosya yazma işlemini isteyin — geçit önce yanıtlar” başlıklı bölüm

Aracı, tamamlanmış özeti diske yazması için output_pdf’yi çağırır; insanın reddetmesi ve base64 çıktısına geri dönülmesi gerekmesi durumuna karşı belgeyi canlı tutar (destroy: false):

{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "output_pdf",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"file_path": "C:\\Temp\\nextpdf-mcp\\kickoff-brief.pdf",
"destroy": false
}
}
}

Dosya yazılmaz. Dosya modu Onay gerekli olduğundan, sunucu bunun yerine bir onay sınamasıyla yanıt verir:

{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "⚠️ CONFIRMATION REQUIRED\n\nOperation: output_pdf\nDescription: Finalize the PDF and output to file or return as base64\n\nTo proceed, call output_pdf again with parameter _confirmation_token: \"confirm_<single-use-hex>\"\nExpires in 300 seconds."
}
],
"isError": false
}
}

9. İnsan onaylar — belirteçle yeniden çağırın

“9. İnsan onaylar — belirteçle yeniden çağırın” başlıklı bölüm

Aracı, sınama metnini insana iletir. Onay verildiğinde, output_pdf’yi aynı bağımsız değişkenler artı _confirmation_token ile yeniden çağırır:

{
"jsonrpc": "2.0",
"id": 11,
"method": "tools/call",
"params": {
"name": "output_pdf",
"arguments": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"file_path": "C:\\Temp\\nextpdf-mcp\\kickoff-brief.pdf",
"destroy": false,
"_confirmation_token": "confirm_<single-use-hex>"
}
}
}

Belirteç tüketilir, yazma işlemi gerçekleşir ve sonuç yazılan dosyayı bildirir:

{
"jsonrpc": "2.0",
"id": 11,
"result": {
"content": [
{
"type": "text",
"text": "{\"document_id\":\"doc_3b9f435efa0f32d1da7a131d\",\"file_path\":\"C:\\\\Temp\\\\nextpdf-mcp\\\\kickoff-brief.pdf\",\"file_size\":3612,\"page_count\":1,\"destroyed\":false}"
}
],
"structuredContent": {
"document_id": "doc_3b9f435efa0f32d1da7a131d",
"file_path": "C:\\Temp\\nextpdf-mcp\\kickoff-brief.pdf",
"file_size": 3612,
"page_count": 1,
"destroyed": false
}
}
}

Oturum, kickoff-brief.pdf dosyasını yazdı (3.612 bayt, tek sayfa, structuredContent.file_size ve page_count ile eşleşir). Tam olarak o dosya için yakalanan qpdf --check çıktısı:

checking kickoff-brief.pdf
PDF Version: 2.0
File is not encrypted
File is not linearized
No syntax or stream encoding errors found; the file may still contain
errors that qpdf cannot detect

Bu, qpdf’nin kendi ifadesiyle yapısal bir denetimdir — bir uygunluk belirlemesi değil.

  • Yeniden çağrı aynı bağımsız değişkenleri yinelemelidir. Onay belirteci, araç adına artı verildiği bağımsız değişkenlerin kurallı bir özetine bağlıdır. Herhangi bir şey değiştirilerek yeniden çağırmak — hatta destroy değerini ters çevirmek bile — belirteci tüketmez; sunucu bunun yerine yeni bir sınamayla yanıt verir. Bağımsız değişkenleri tam olarak yineleyin ve yalnızca _confirmation_token ekleyin.
  • Belirteç tek kullanımlıktır ve sona erer. Sınama, son kullanma süresini (300 saniye) belirtir. Sona erme veya tüketimden sonra, sonraki geçitli çağrı yeni bir sınama alır; yenisini iletin.
  • Dosya çıktısı, izin listesindeki bir dizinin içine düşer. Sunucu, yapılandırılmış geçici dizininin dışındaki bir file_path’i Output path rejected by security policy ile reddeder. Varsayılan izin listesi kökü, sistem geçici dizini altındaki nextpdf-mcp’dir; operatörler bunu nextpdf-mcp.yaml içindeki temp_dir ayarıyla değiştirir.
  • base64 modu geçitlenmez. file_path olmadan output_pdf, hiçbir dosya sistemi yan etkisi olmadan İnceleme düzeyinde PDF’i base64 olarak döndürür — o sınırı ayrıntılı olarak görmek için Dosya çıktısı için insan onayı gerektirin sayfasına bakın.
  • Sınama bir hata değil, bir sonuçtur. Sınama mesajı isError: false ile gelir; bekleyen bir onay, bir iş akışı duraklamasıdır. Bir döngüde yeniden denemeyin ve asla bir belirteç uydurmayın.
  • Bildirimler yanıt almaz. notifications/initialized’dan sonra, bir yanıt satırı gelmesini bekleyerek bloke olmayın.

Oturum uçtan uca bellek içidir: yakalanan çalıştırmada içerik çağrıları milisaniyeler içinde döndü ve duvar saati süresine, geçidin amacı olan insan onayı gidiş-dönüşü egemendir. Belge deposu, bir oturumu varsayılan olarak 30 dakikalık boşta kalma süresi boyunca tutar (en fazla 50 belge); bu nedenle yavaş bir onay, oluşturulan belgeyi kaybetmez — ancak terk edilen bir belge geri alınır.

  • Onay belirtecini tek seferlik bir sır olarak ele alın. Sınama metnini insana iletin; belirteci günlüğe kaydetmeyin veya kalıcı olarak saklamayın. Bu sayfa, tam olarak bu nedenle yakalanan belirteci düzenleyerek gizler.
  • Denetim izi stderr üzerindedir. Dikkat düzeyi ve üzerindeki her yürütme, hassas parametreler gizlenerek PSR-3 aracılığıyla denetim günlüğüne kaydedilir (araç, risk, bağımsız değişkenler, sonuç). Tanılama bilgileri asla protokol akışına karışmaz.
  • Yol izin listesi, dosya sistemi sınırıdır. temp_dir’i Connect çıktısına ayrılmış bir dizine yönlendirin; onu genel amaçlı bir konuma genişletmeyin.
  • Risk düzeyleri yalnızca yukarı doğru çıkar. nextpdf-mcp.yaml içindeki bir operatör geçersiz kılması, bir aracın risk düzeyini yükseltebilir ancak output_pdf’yi asla Onay gerekli düzeyinin altına indiremez.

Bu reçete, hiçbir normatif standart iddiasında bulunmaz. MCP stdio taşıma katmanını (JSON-RPC 2.0, yakalanan initialize değişiminde uzlaşılan protokol sürümü 2025-06-18) ve sunucunun risk ve onay sözleşmesini belgeler. Yukarıdaki qpdf --check adımı yalnızca yazılan dosyanın yapısal bütünlüğünü doğrular; bir standarda uygunluk, üreten yazılım tarafından iddia edilmez, bağımsız bir doğrulayıcı tarafından belirlenir.