بروتوكول سياق النموذج (MCP)
خريطة الوثائق: نظرة عامة وبنية · العميل · المدير الديناميكي · تأليف الخادم · الأمان · الاختبار
يمنح MCP تطبيق الذكاء الاصطناعي طريقة قياسية لاكتشاف واستخدام الإمكانيات التي يمتلكها عملية أو خدمة أخرى. يمكن للخادم نشر:
- أدوات تؤدي الإجراءات؛
- موارد تُرجع سياقًا قابلاً للقراءة؛
- مطالبات توفر قوالب رسائل قابلة لإعادة الاستخدام؛ و
- اقتراحات إكمال تساعد العميل على ملء وسيطات المطالبة أو المورد.
عادةً ما يكون ADK-Rust هو العميل MCP. يحول McpToolset أدوات MCP المكتشفة
إلى قيم ADK-Rust Tool عادية، بحيث يمكن لـ LlmAgent تحديدها واستدعائها.
يعرض الإطار أيضًا الموارد والمطالبات والإكمال والاشتراكات والاستنباط ودورة حياة المهمة المتفاوض عليها. لتأليف خادم MCP وعمل البروتوكول المتقدم، يعيد ADK-Rust تصدير الإصدار الدقيق rmcp SDK الذي يستخدمه.
يستخدم ADK-Rust 2 حاليًا rmcp 2.2، وهو SDK Rust الرسمي المتوافق مع مواصفات MCP 2025-11-25.
البنية
هناك طبقتان منفصلتان:
- يمتلك
McpToolsetاتصال عميل MCP واحدًا مهيأً. يكتشف إمكانيات الخادم ويكيفها مع ADK-Rust. - يمتلك
McpServerManagerسجلًا متغيرًا لخوادم stdio المحلية. يقوم ببدء تلك الاتصالات ومراقبتها وإعادة تشغيلها وتحديثها وتمكينها وتعطيلها واستمرارها وتجميعها.
لا يمنح المدير موافقة الأداة. يحافظ على autoApprove عند قراءة التكوين المتوافق، ولكن يجب على التطبيق تطبيق سياسة التفويض والموافقة العادية ADK-Rust الخاصة به.
التثبيت
دعم stdio MCP المحلي اختياري:
[dependencies]
adk-tool = { version = "2.0.0", features = ["mcp"] }
أضف Streamable HTTP عند الاتصال بالخدمات البعيدة:
adk-tool = { version = "2.0.0", features = ["mcp", "http-transport"] }
تتطلب استدعاءات أخذ العينات القديمة ميزة mcp-sampling المنفصلة. لقد ألغى مشروع MCP أخذ العينات والجذور والتسجيل من خلال SEP-2577؛ استخدم APIs تلك فقط عند الحفاظ على نشر متوافق.
توصيل خادم محلي واحد
use adk_tool::{
McpToolset,
mcp::rmcp::{ServiceExt, transport::TokioChildProcess},
};
use std::sync::Arc;
use tokio::process::Command;
let command = Command::new("./target/release/company-mcp");
let client = ().serve(TokioChildProcess::new(command)?).await?;
let toolset = McpToolset::new(client)
.with_name("company_tools")
.with_tools(&["find_customer", "read_order", "request_refund"]);
let agent = LlmAgentBuilder::new("support")
.model(model)
.toolset(Arc::new(toolset.clone()))
.build()?;
// Keep the token when the application owns the process lifecycle.
let shutdown = toolset.cancellation_token().await;
// ... run the agent ...
shutdown.cancel();
يحافظ McpToolset على مخططات الإدخال والإخراج للخادم سليمة. يقوم كل محول نموذج بتطبيع نسخة لمزوده عند بناء طلب النموذج. يتيح ذلك لخادم MCP نفسه العمل مع Gemini و OpenAI و Anthropic ومقدمي الخدمات الآخرين دون الإضرار بالمخطط المصدر.
استخدام البروتوكول بما يتجاوز الأدوات
use serde_json::json;
let resources = toolset.list_resources().await?;
let templates = toolset.list_resource_templates().await?;
let contents = toolset.read_resource("company://policy/refunds").await?;
let prompts = toolset.list_prompts().await?;
let prompt = toolset
.get_prompt(
"investigate_order",
Some(serde_json::Map::from_iter([
("order_id".to_string(), json!("ORD-1042")),
])),
)
.await?;
let suggestions = toolset
.complete_prompt_argument("investigate_order", "order_id", "ORD-", None)
.await?;
toolset.subscribe_resource("company://inventory/sku-42").await?;
// ... receive notifications in a custom ClientHandler ...
toolset.unsubscribe_resource("company://inventory/sku-42").await?;
تُرجع طرق الراحة قائمة فارغة عندما لا يقوم خادم أقدم بتنفيذ قائمة الموارد أو المطالبات. تُرجع العمليات ضد مورد أو مطالبة معلنة خطأً عندما يفشل الاستدعاء عن بعد.
إدارة الخادم الديناميكية
استخدم McpServerManager عندما يحتاج التطبيق إلى أسطول من عمليات MCP الفرعية المحلية بدلاً من اتصال ثابت واحد.
use adk_tool::mcp::manager::{McpServerConfig, McpServerManager};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
let manager = Arc::new(McpServerManager::from_json_file("mcp.json")?
.with_name("product_mcp_servers")
.with_health_check_interval(Duration::from_secs(15))
.with_grace_period(Duration::from_secs(2)));
let outcomes = manager.start_all().await;
for (server_id, outcome) in outcomes {
if let Err(error) = outcome {
eprintln!("{server_id} did not start: {error}");
}
}
manager.start_monitoring();
let agent = LlmAgentBuilder::new("operator")
.model(model)
.toolset(manager.clone())
.build()?;
يدعم سجل وقت التشغيل ما يلي:
manager.add_server("billing".into(), billing_config).await?;
manager.start_server("billing").await?;
manager.update_server("billing", replacement_config).await?;
manager.disable_server("billing").await?;
manager.enable_server("billing").await?;
manager.save_json_file("mcp.json").await?;
manager.remove_server("billing").await?;
manager.shutdown().await?;
عندما ينشر خادمان نفس اسم الأداة، يقوم مجموعة الأدوات المجمعة بإضافة بادئة لكلا الاسمين كـ {server_id}__{tool_name}. تظل الأسماء الفريدة دون تغيير.
يكتشف مراقب الصحة اتصال MCP مغلقًا. يتحكم RestartPolicy المكون في إعادة المحاولة المحدودة مع التراجع الأسي. هذا هو إشراف الاتصال، وليس فحصًا صحيًا على مستوى التطبيق: استخدم أداة مجال أو مسبار خدمة منفصل عندما تحتاج إلى التحقق من قاعدة بيانات الخادم الخلفية أو API الخارجي.
قم بتشغيل المثال الحتمي:
cargo run --manifest-path examples/mcp_manager/Cargo.toml
يبدأ خادمًا فرعيًا حقيقيًا لـ Rust MCP ويمارس الاكتشاف، واستدعاء أداة، وإضافة/تمكين/تحديث/تعطيل/إزالة وقت التشغيل، واستمرارية التكوين، وإيقاف التشغيل. لا يقوم بتنزيل الحزم أو يتطلب مفتاح API.
Streamable HTTP عن بعد
use adk_tool::{McpAuth, McpHttpClientBuilder};
use std::time::Duration;
let toolset = McpHttpClientBuilder::new("https://mcp.example.com/mcp")
.with_auth(McpAuth::bearer(std::env::var("MCP_TOKEN")?))
.header("X-Tenant-ID", "tenant-42")
.timeout(Duration::from_secs(30))
.reinit_on_expired_session(true)
.connect()
.await?;
يطبق الباني مهلات الطلب، ورؤوسًا مخصصة، ورموز حامل، ورؤوس مفتاح API مخصصة، واستردادًا محدودًا عند انتهاء صلاحية جلسة HTTP.
ينفذ OAuth2Config طلب رمز عميل-بيانات اعتماد OAuth 2.0 ثابتًا. إنه مفيد لخادم بنقطة نهاية رمز معروفة. إنه ليس تدفق تفويض MCP الكامل: لا يقوم بإجراء اكتشاف بيانات تعريف الموارد المحمية، أو اكتشاف خادم التفويض، أو تفويض المتصفح، أو PKCE، أو التفاوض على مؤشر الموارد. استخدم تفويض APIs الخاص بـ rmcp أو مكون هوية خارجي عندما يتطلب النشر هذا التدفق.
الاستنباط
قد يحتاج خادم MCP إلى معلومات لم تتضمنها وسيطات الأداة. في هذه الحالة، يمكنه إرسال طلب استنباط مرة أخرى إلى العميل. يقرر التطبيق كيفية عرض الطلب لشخص ما وما إذا كان سيقبله أو يرفضه أو يلغيه.
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
يعلن ADK-Rust عن استنباط النموذج و URL. يتم تحويل خطأ المعالج أو الذعر إلى رفض بحيث يظل اتصال MCP قابلاً للاستخدام. تحقق من القيم المرتجعة وطبق قواعد الموافقة في التطبيق قبل قبول طلب ذي عواقب.
انظر examples/mcp_elicitation للحصول على خادم كامل وعميل تفاعلي.
مهام MCP طويلة الأمد
يمكن لـ MCP 2025-11-25 نقل استدعاء أداة إلى مهمة بروتوكول. يستخدم ADK-Rust تدفق المهام فقط عندما يتفاوض الخادم على tasks.requests.tools.call وتعلن الأداة عن دعم المهام المطلوب أو الاختياري.
use adk_tool::McpTaskConfig;
use std::time::Duration;
let toolset = McpToolset::new(client).with_task_support(
McpTaskConfig::enabled()
.poll_interval(Duration::from_secs(1))
.timeout(Duration::from_secs(120))
.max_attempts(120),
);
لوضع المهام، ADK-Rust:
- يرسل
tools/callمع بيانات تعريف المهمة الرسمية؛ - يستقبل المهمة التي تم إنشاؤها؛
- يستطلع
tasks/getباستخدام الفاصل الزمني المقترح للخادم؛ - يقرأ الحمولة النهائية من خلال
tasks/result؛ و - يستدعي
tasks/cancelعند الوصول إلى مهلته المحلية أو حد الاستطلاع.
يتم إرجاع input_required كخطأ مكتوب لأن استدعاء أداة ADK العادي لا يمتلك بعد قناة استئناف محايدة للبروتوكول لتوفير هذا الإدخال المفقود. صمم هذا التفاعل صراحةً في سير العمل المالك.
خريطة القدرات
| MCP قدرة | ADK-Rust للواجهة | ملاحظات |
|---|---|---|
| اكتشاف الأدوات واستدعاءاتها | McpToolset, Toolset | مخططات خام؛ نتائج متعددة الوسائط ومنظمة محفوظة |
| تصفية الأدوات | with_filter, with_tools | التصفية قبل عرضها على النموذج |
| الموارد والقوالب | list/read methods | يتم التعامل مع "method-not-found" للخوادم القديمة |
| المطالبات | list/get methods | خرائط الوسائط المكتوبة |
| الإكمال | prompt/resource completion methods | تُرجع الرسمية CompletionInfo |
| اشتراكات الموارد | subscribe/unsubscribe methods | تتطلب الإشعارات معالج عميل مناسبًا |
| استنباط | ElicitationHandler | صيغة و URL أنماط |
| المهام | McpTaskConfig | دورة حياة مهمة استدعاء الأداة المتفاوض عليها |
| stdio المحلي | TokioChildProcess | مباشر أو مملوك للمدير |
| HTTP قابل للتدفق | McpHttpClientBuilder | مهلات، رؤوس، حقن المصادقة، استعادة الجلسة |
| سجل محلي ديناميكي | McpServerManager | إضافة/تحديث/تمكين/تعطيل/إزالة/حفظ/مراقبة/إعادة تشغيل |
| تأليف الخادم والإضافات | adk_tool::mcp::rmcp | إعادة تصدير SDK دقيق للاستخدام المتقدم |
| أخذ العينات، الجذور، التسجيل | ميزة التوافق / rmcp | مهمل في المنبع عبر SEP-2577 |
اختيار الحدود
استخدم Rust FunctionTool عندما تنتمي الإمكانية إلى نفس العملية والإصدار. استخدم MCP عندما يمتلك برنامج آخر أو فريق أو لغة أو حدود أمان أو نشر الإمكانية ويجب أن ينشر عقده الخاص.
لعمليات النشر الإنتاجية:
- كشف أصغر مجموعة أدوات مفيدة؛
- فصل الإجراءات للقراءة فقط والإجراءات ذات النتائج؛
- إبقاء الأسرار بعيدًا عن وسائط سطر الأوامر وملفات
mcp.jsonالملتزم بها؛ - مصادقة خوادم HTTP البعيدة وتحديد نطاق بيانات الاعتماد بدقة؛
- التعامل مع أوصاف الأدوات والمحتوى الذي يتم إرجاعه من الخادم كمدخلات غير موثوق بها؛
- الاحتفاظ بترخيص ADK-Rust والموافقة حول تنفيذ الأداة؛
- تحديد مهل الاتصال والأداة والمهمة؛ و
- تسجيل استدعاءات الأدوات والموافقات والأخطاء وتغييرات دورة حياة الخادم.
الحدود الحالية
- يدير
McpServerManagerعمليات stdio الفرعية المحلية. تستخدم خدمات HTTP البعيدةMcpHttpClientBuilderوالتكوين المملوك للتطبيق. - تكتشف فحوصات سلامة المدير اتصالات MCP المغلقة؛ ولا تستدعي أداة صحة على مستوى الأعمال.
- يتم تسلسل تغييرات السجل بينما يكمل الفرع مصافحة MCP الخاصة به.
autoApproveهو توافق التكوين، وليس فرض التفويض.- المساعد المدمج OAuth هو بيانات اعتماد العميل، وليس تدفق اكتشاف MCP OAuth الكامل وتفويض المستخدم.
تم ذكر هذه الحدود لتبقى قرارات النشر واضحة.