بناء عميل MCP
تطبيق ADK-Rust يصبح عميل MCP عندما يتصل بخادم، ويقرأ الكتالوج المنشور الخاص به، ويجعل القدرات المحددة متاحةً لوكيل أو سير عمل.
التثبيت
[dependencies]
adk-tool = { version = "2.0.0", features = ["mcp"] }
لـ Streamable HTTP البعيد:
adk-tool = { version = "2.0.0", features = ["mcp", "http-transport"] }
اتصال stdio المحلي
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 shutdown = toolset.cancellation_token().await;
let agent = LlmAgentBuilder::new("support")
.model(model)
.toolset(Arc::new(toolset))
.build()?;
// Run the agent, then close the client-owned MCP session.
shutdown.cancel();
استخدم مسارًا مطلقًا للملف التنفيذي في بيئة الإنتاج. تجنب وسوم الحزم مثل latest
في إعدادات النشر لأنها تجعل عمليات البناء واستعادة الحوادث غير قابلة لإعادة الإنتاج.
اكتشاف الأدوات والتصفية
McpToolset يحول كل أداة MCP منشورة إلى ADK-Rust Tool. وهو يحتفظ بمخططات الإدخال والإخراج الخاصة بالخادم دون تغيير. يقوم مزود النموذج المحدد بتطبيع نسخة من المخطط عندما يبني طلبه.
let reviewed = McpToolset::new(client).with_filter(|name| {
matches!(name, "read_order" | "read_policy" | "request_replacement")
});
تتحكم التصفية في مدى ظهور النموذج. وهي لا تحل محل التفويض عند وقت تنفيذ الأداة.
الموارد، والمطالبات، والإكمال
use serde_json::json;
let resources = toolset.list_resources().await?;
let templates = toolset.list_resource_templates().await?;
let policy = 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?;
يستخدم إكمال قالب المورد complete_resource_argument. الخادم الذي
لا يطبق عمليات القائمة يعيد قائمة فارغة عندما يرد بـ
MCP MethodNotFound؛ أما حالات الفشل الأخرى في البروتوكول والنقل فتبقى أخطاء.
اشتراكات الموارد
use adk_tool::{AutoDeclineElicitationHandler, McpToolset, ResourceNotificationHandler};
use std::sync::Arc;
struct ResourceUpdates;
#[async_trait::async_trait]
impl ResourceNotificationHandler for ResourceUpdates {
async fn handle_resource_updated(
&self,
uri: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("Resource changed: {uri}");
Ok(())
}
async fn handle_resource_list_changed(
&self,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("The resource catalog changed");
Ok(())
}
}
let toolset = McpToolset::with_handlers(
transport,
Arc::new(AutoDeclineElicitationHandler),
Arc::new(ResourceUpdates),
).await?;
toolset.subscribe_resource("company://inventory/sku-42").await?;
toolset.unsubscribe_resource("company://inventory/sku-42").await?;
McpToolset يعيد الاشتراكات النشطة بعد تحديث الاتصال المحدود الخاص به.
McpServerManager يحتفظ أيضًا بالاشتراكات عبر عمليات إعادة تشغيل العمليات المُدارة.
تُسجل أخطاء المعالج وحالات الذعر دون إنهاء اتصال MCP.
لـ Streamable HTTP، اضبط المعالج نفسه باستخدام
McpHttpClientBuilder::with_resource_notification_handler قبل استدعاء
connect_with_elicitation.
الاستدلال
يتيح الاستدلال للخادم طلب معلومات أثناء معالجة استدعاء أداة. يقرر التطبيق كيفية عرض الطلب وما إذا كان سيقبله أو يرفضه أو يلغيْه.
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
ADK-Rust يعلن عن الاستدلال بالنماذج وURL. تصبح حالة فشل المعالج أو الذعر رفضًا، مع الحفاظ على جلسة MCP. ولا يزال على التطبيق التحقق من القيم المقبولة وتطبيق سياسة الموافقة.
راجع examples/mcp_elicitation للحصول على زوج كامل من العميل والخادم.
المهام المتفاوض عليها
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),
);
يتم اختيار وضع المهمة من حقيقتين متفاوض عليهما:
- يعلن الخادم عن
tasks.requests.tools.call؛ و - تعلن الأداة عن دعم المهام على أنه مطلوب أو اختياري.
ADK-Rust يرسل بيانات تعريف المهمة مع tools/call، ويتلقى المهمة المُنشأة، ويستعلم دوريًا عن tasks/get، ويقرأ tasks/result، ويستدعي tasks/cancel عندما يتم تجاوز الحدود المحلية.
يُعاد input_required كخطأ مُنمذج لأن استدعاء أداة ADK العادي لا يوفر بعد قناة إدخال محايدة للبروتوكول لاستئناف المهمة.
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?;
يدعم منشئ الإعدادات رموز bearer المميزة، وترويسة مفتاح API مخصصة، وبيانات اعتماد عميل OAuth 2.0 ثابتة. راجع الأمان والتفويض قبل اختيار مسار المصادقة.