MCP टूल्स
Model Context Protocol (MCP) एक ओपन स्टैंडर्ड है जो LLMs को बाहरी एप्लिकेशन्स, डेटा स्रोतों और tools के साथ संचार करने में सक्षम बनाता है। ADK-Rust McpToolset के माध्यम से पूर्ण MCP समर्थन प्रदान करता है, जिससे आप किसी भी MCP-अनुरूप server से जुड़ सकते हैं और इसके tools को अपने agents के लिए उजागर कर सकते हैं।
अवलोकन
MCP क्लाइंट-server आर्किटेक्चर का पालन करता है:
- MCP Servers tools, resources, और prompts को उजागर करते हैं
- MCP Clients (जैसे ADK agents) servers से जुड़ते हैं और उनकी क्षमताओं का उपयोग करते हैं
MCP एकीकरण के लाभ:
- सार्वभौमिक कनेक्टिविटी - किसी भी MCP-अनुरूप server से जुड़ें
- स्वचालित खोज - Tools server से गतिशील रूप से खोजे जाते हैं
- भाषा-अज्ञेयवादी - किसी भी भाषा में लिखे गए tools का उपयोग करें
- बढ़ता हुआ इकोसिस्टम - हजारों मौजूदा MCP servers तक पहुँच प्राप्त करें
पूर्व-आवश्यकताएँ
MCP servers आमतौर पर npm packages के रूप में वितरित किए जाते हैं। आपको इनकी आवश्यकता होगी:
- Node.js और npm स्थापित
- एक LLM API key (Gemini, OpenAI, आदि)
त्वरित शुरुआत
एक MCP server से कनेक्ट करें और उसके tools का उपयोग करें:
use adk_agent::LlmAgentBuilder;
use adk_core::{Content, Part, ReadonlyContext, Toolset};
use adk_model::GeminiModel;
use adk_tool::McpToolset;
use rmcp::{ServiceExt, transport::TokioChildProcess};
use tokio::process::Command;
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenvy::dotenv().ok();
let api_key = std::env::var("GOOGLE_API_KEY")?;
let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.0-flash")?);
// 1. Start MCP server and connect
let mut cmd = Command::new("npx");
cmd.arg("-y").arg("@modelcontextprotocol/server-everything");
let client = ().serve(TokioChildProcess::new(cmd)?).await?;
// 2. Create toolset from the client
let toolset = McpToolset::new(client)
.with_tools(&["echo", "add"]); // Only expose these tools
// 3. Get cancellation token for cleanup
let cancel_token = toolset.cancellation_token().await;
// 4. Discover tools and add to agent
let ctx: Arc<dyn ReadonlyContext> = Arc::new(SimpleContext);
let tools = toolset.tools(ctx).await?;
let mut builder = LlmAgentBuilder::new("mcp_agent")
.model(model)
.instruction("You have MCP tools. Use 'echo' to repeat messages, 'add' to sum numbers.");
for tool in tools {
builder = builder.tool(tool);
}
let agent = builder.build()?;
// 5. Run interactive console
adk_cli::console::run_console(
Arc::new(agent),
"mcp_demo".to_string(),
"user".to_string(),
).await?;
// 6. Cleanup: shutdown MCP server
cancel_token.cancel();
Ok(())
}
// Minimal context for tool discovery
struct SimpleContext;
#[async_trait::async_trait]
impl ReadonlyContext for SimpleContext {
fn invocation_id(&self) -> &str { "init" }
fn agent_name(&self) -> &str { "init" }
fn user_id(&self) -> &str { "user" }
fn app_name(&self) -> &str { "mcp" }
fn session_id(&self) -> &str { "init" }
fn branch(&self) -> &str { "main" }
fn user_content(&self) -> &Content {
static CONTENT: std::sync::OnceLock<Content> = std::sync::OnceLock::new();
CONTENT.get_or_init(|| Content::new("user").with_text("init"))
}
}
इसके साथ चलाएँ:
GOOGLE_API_KEY=your_key cargo run --bin basic
McpToolset API
एक टूलसेट बनाना
use adk_tool::McpToolset;
// Basic creation
let toolset = McpToolset::new(client);
// With custom name
let toolset = McpToolset::new(client)
.with_name("filesystem-tools");
टूल फ़िल्टरिंग
कौन से टूल प्रदर्शित करने हैं, उन्हें फ़िल्टर करें:
// Filter by predicate function
let toolset = McpToolset::new(client)
.with_filter(|name| {
matches!(name, "read_file" | "write_file" | "list_directory")
});
// Filter by exact names (convenience method)
let toolset = McpToolset::new(client)
.with_tools(&["echo", "add", "get_time"]);
कैंसलेशन टोकन के साथ सफाई
MCP सर्वर को ठीक से बंद करने के लिए हमेशा एक कैंसलेशन टोकन प्राप्त करें:
let toolset = McpToolset::new(client);
let cancel_token = toolset.cancellation_token().await;
// ... use the toolset ...
// Before exiting, shutdown the MCP server
cancel_token.cancel();
यह EPIPE त्रुटियों को रोकता है और स्वच्छ प्रक्रिया समाप्ति सुनिश्चित करता है।
MCP सर्वर से कनेक्ट करना
स्थानीय सर्वर (Stdio)
मानक इनपुट/आउटपुट के माध्यम से एक स्थानीय MCP सर्वर से कनेक्ट करें:
use rmcp::{ServiceExt, transport::TokioChildProcess};
use tokio::process::Command;
// NPM package server
let mut cmd = Command::new("npx");
cmd.arg("-y")
.arg("@modelcontextprotocol/server-filesystem")
.arg("/path/to/allowed/directory");
let client = ().serve(TokioChildProcess::new(cmd)?).await?;
// Local binary server
let mut cmd = Command::new("./my-mcp-server");
cmd.arg("--config").arg("config.json");
let client = ().serve(TokioChildProcess::new(cmd)?).await?;
रिमोट सर्वर (SSE)
सर्वर-सेंट इवेंट्स के माध्यम से एक रिमोट MCP सर्वर से कनेक्ट करें:
use rmcp::{ServiceExt, transport::SseClient};
let client = ().serve(
SseClient::new("http://localhost:8080/sse")?
).await?;
टूल डिस्कवरी
McpToolset स्वचालित रूप से कनेक्टेड सर्वर से टूल का पता लगाता है:
use adk_core::{ReadonlyContext, Toolset};
// Get discovered tools
let tools = toolset.tools(ctx).await?;
println!("Discovered {} tools:", tools.len());
for tool in &tools {
println!(" - {}: {}", tool.name(), tool.description());
}
प्रत्येक खोजा गया टूल:
- MCP सर्वर से इसका नाम और विवरण होता है
- LLM सटीकता के लिए पैरामीटर स्कीमा शामिल करता है
- बुलाए जाने पर MCP प्रोटोकॉल के माध्यम से निष्पादित होता है
एजेंट में टूल जोड़ना
किसी एजेंट में MCP टूल जोड़ने के लिए दो पैटर्न हैं:
पैटर्न 1: टूलसेट के रूप में जोड़ें
let toolset = McpToolset::new(client);
let agent = LlmAgentBuilder::new("agent")
.model(model)
.toolset(Arc::new(toolset))
.build()?;
पैटर्न 2: व्यक्तिगत टूल जोड़ें
यह आपको इस बात पर अधिक नियंत्रण देता है कि कौन से टूल जोड़े गए हैं:
let toolset = McpToolset::new(client)
.with_tools(&["echo", "add"]);
let tools = toolset.tools(ctx).await?;
let mut builder = LlmAgentBuilder::new("agent")
.model(model);
for tool in tools {
builder = builder.tool(tool);
}
let agent = builder.build()?;
लोकप्रिय MCP सर्वर
यहां कुछ सामान्य रूप से उपयोग किए जाने वाले MCP सर्वर दिए गए हैं जिन्हें आप एकीकृत कर सकते हैं:
एवरीथिंग सर्वर (परीक्षण)
npx -y @modelcontextprotocol/server-everything
टूल: echo, add, longRunningOperation, sampleLLM, getAlerts, printEnv
फाइलसिस्टम सर्वर
npx -y @modelcontextprotocol/server-filesystem /path/to/directory
टूल: read_file, write_file, list_directory, search_files
GitHub सर्वर
npx -y @modelcontextprotocol/server-github
टूल: search_repositories, get_file_contents, create_issue
Slack सर्वर
npx -y @modelcontextprotocol/server-slack
टूल: send_message, list_channels, search_messages
मेमोरी सर्वर
npx -y @modelcontextprotocol/server-memory
टूल: store, retrieve, search
MCP सर्वर रजिस्ट्री पर और सर्वर खोजें।
त्रुटि प्रबंधन
MCP कनेक्शन और निष्पादन त्रुटियों को संभालें:
use adk_core::AdkError;
match toolset.tools(ctx).await {
Ok(tools) => {
println!("Discovered {} tools", tools.len());
}
Err(AdkError::Tool(msg)) => {
eprintln!("MCP error: {}", msg);
}
Err(e) => {
eprintln!("Other error: {}", e);
}
}
सामान्य त्रुटियाँ:
- कनेक्शन विफल - सर्वर नहीं चल रहा है या गलत पता
- Tool निष्पादन विफल - MCP सर्वर ने एक त्रुटि लौटा दी
- अमान्य पैरामीटर - Tool को गलत आर्गुमेंट प्राप्त हुए
सर्वोत्तम अभ्यास
- Tool को फ़िल्टर करें - भ्रम को कम करने के लिए केवल उन tools को उजागर करें जिनकी Agent को आवश्यकता है
- कैंसिलेशन टोकन का उपयोग करें - cleanup के लिए बाहर निकलने से पहले हमेशा
cancel()को कॉल करें - त्रुटियों को संभालें - MCP सर्वर विफल हो सकते हैं; उचित त्रुटि प्रबंधन लागू करें
- स्थानीय सर्वर का उपयोग करें - विकास के लिए, stdio ट्रांसपोर्ट रिमोट की तुलना में सरल है
- सर्वर स्थिति जांचें - Toolset बनाने से पहले MCP सर्वर के चलने की पुष्टि करें
पूर्ण उदाहरण
यहाँ उचित cleanup के साथ एक पूर्ण कार्यशील उदाहरण दिया गया है:
use adk_agent::LlmAgentBuilder;
use adk_core::{Content, Part, ReadonlyContext, Toolset};
use adk_model::GeminiModel;
use adk_tool::McpToolset;
use rmcp::{ServiceExt, transport::TokioChildProcess};
use std::sync::Arc;
use tokio::process::Command;
struct SimpleContext;
#[async_trait::async_trait]
impl ReadonlyContext for SimpleContext {
fn invocation_id(&self) -> &str { "init" }
fn agent_name(&self) -> &str { "init" }
fn user_id(&self) -> &str { "user" }
fn app_name(&self) -> &str { "mcp" }
fn session_id(&self) -> &str { "init" }
fn branch(&self) -> &str { "main" }
fn user_content(&self) -> &Content {
static CONTENT: std::sync::OnceLock<Content> = std::sync::OnceLock::new();
CONTENT.get_or_init(|| Content::new("user").with_text("init"))
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenvy::dotenv().ok();
let api_key = std::env::var("GOOGLE_API_KEY")?;
let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.0-flash")?);
println!("Starting MCP server...");
let mut cmd = Command::new("npx");
cmd.arg("-y").arg("@modelcontextprotocol/server-everything");
let client = ().serve(TokioChildProcess::new(cmd)?).await?;
println!("MCP server connected!");
// Create filtered toolset
let toolset = McpToolset::new(client)
.with_name("everything-tools")
.with_filter(|name| matches!(name, "echo" | "add" | "printEnv"));
// Get cancellation token for cleanup
let cancel_token = toolset.cancellation_token().await;
// Discover tools
let ctx = Arc::new(SimpleContext) as Arc<dyn ReadonlyContext>;
let tools = toolset.tools(ctx).await?;
println!("Discovered {} tools:", tools.len());
for tool in &tools {
println!(" - {}: {}", tool.name(), tool.description());
}
// Build agent with tools
let mut builder = LlmAgentBuilder::new("mcp_demo")
.model(model)
.instruction(
"You have access to MCP tools:\n\
- echo: Repeat a message back\n\
- add: Add two numbers (a + b)\n\
- printEnv: Print environment variables"
);
for tool in tools {
builder = builder.tool(tool);
}
let agent = builder.build()?;
// Run interactive console
let result = adk_cli::console::run_console(
Arc::new(agent),
"mcp_demo".to_string(),
"user".to_string(),
).await;
// Cleanup
println!("\nShutting down MCP server...");
cancel_token.cancel();
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
result?;
Ok(())
}
उन्नत: अनुकूलित MCP सर्वर
आप rmcp SDK का उपयोग करके Rust में अपना स्वयं का MCP सर्वर बना सकते हैं:
use rmcp::{tool, tool_router, handler::server::tool::ToolRouter, model::*};
#[derive(Clone)]
pub struct MyServer {
tool_router: ToolRouter<Self>,
}
#[tool_router]
impl MyServer {
fn new() -> Self {
Self { tool_router: Self::tool_router() }
}
#[tool(description = "Add two numbers")]
async fn add(&self, a: i32, b: i32) -> Result<CallToolResult, ErrorData> {
Ok(CallToolResult::success(vec![Content::text((a + b).to_string())]))
}
#[tool(description = "Multiply two numbers")]
async fn multiply(&self, a: i32, b: i32) -> Result<CallToolResult, ErrorData> {
Ok(CallToolResult::success(vec![Content::text((a * b).to_string())]))
}
}
संपूर्ण सर्वर कार्यान्वयन विवरण के लिए rmcp दस्तावेज़ देखें।
संबंधित
- Function Tools - Rust में कस्टम टूल बनाना
- Built-in Tools - ADK के साथ शामिल पूर्व-निर्मित टूल
- LlmAgent - एजेंटों में टूल जोड़ना
- rmcp SDK - आधिकारिक Rust MCP SDK
- MCP Specification - प्रोटोकॉल दस्तावेज़
पिछला: ← UI Tools | अगला: Sessions →