Skip to main content

What is MCP?

Model Context Protocol (MCP) is an open standard that enables AI models to securely connect to various data sources and tools. With MCP, you can extend your agents’ capabilities without modifying the core SDK.
MCP allows agents to access databases, APIs, file systems, and custom tools through a standardized interface.

Why Use MCP?

Extensibility

Add new capabilities without changing SDK code

Security

Controlled access to sensitive resources

Modularity

Mix and match different MCP servers

Standards-Based

Industry-standard protocol

Connecting to MCP Servers

Basic Connection

Connect to an MCP server using HTTP:
use shadow_agent_sdk::mcp::MCPClient;

#[tokio::main]
async fn main() -> Result<()> {
    let mut agent = Agent::new("api-key").await?;

    // Connect to MCP server
    let mcp = MCPClient::connect("http://localhost:3000").await?;

    // Add MCP client to agent
    agent.add_mcp_client(mcp);

    Ok(())
}

Multiple MCP Servers

Connect to multiple MCP servers for different capabilities:
// Database access
let db_mcp = MCPClient::connect("http://localhost:3001").await?;
agent.add_mcp_client(db_mcp);

// File system access
let fs_mcp = MCPClient::connect("http://localhost:3002").await?;
agent.add_mcp_client(fs_mcp);

// API integration
let api_mcp = MCPClient::connect("http://localhost:3003").await?;
agent.add_mcp_client(api_mcp);

Available MCP Tools

Once connected, agents can automatically discover and use MCP tools:
// Agent will automatically use MCP tools when appropriate
let response = agent.execute(
    "Query the database for user records created today"
).await?;

Building MCP Servers

Create your own MCP server to expose custom functionality:
use shadow_agent_sdk::mcp::{MCPServer, MCPTool};

#[tokio::main]
async fn main() -> Result<()> {
    let mut server = MCPServer::new("0.0.0.0:3000");

    // Register custom tool
    server.register_tool(DatabaseTool::new());

    // Start server
    server.start().await?;

    Ok(())
}

Example: Database Tool

use shadow_agent_sdk::mcp::MCPTool;
use async_trait::async_trait;

struct DatabaseTool {
    pool: sqlx::PgPool,
}

#[async_trait]
impl MCPTool for DatabaseTool {
    fn name(&self) -> &str {
        "query_database"
    }

    fn description(&self) -> &str {
        "Execute SQL queries on the database"
    }

    async fn execute(&self, params: serde_json::Value) -> Result<String> {
        let query = params["query"].as_str().unwrap();

        // Execute query safely
        let results = sqlx::query(query)
            .fetch_all(&self.pool)
            .await?;

        Ok(serde_json::to_string(&results)?)
    }
}

MCP Configuration

Authentication

Configure authentication for secure MCP connections:
use shadow_agent_sdk::mcp::{MCPClient, MCPAuth};

let auth = MCPAuth::Bearer("your-token".to_string());

let mcp = MCPClient::connect("http://localhost:3000")
    .with_auth(auth)
    .await?;

Timeout Configuration

Set timeouts for MCP operations:
let mcp = MCPClient::connect("http://localhost:3000")
    .with_timeout(Duration::from_secs(30))
    .await?;

MCP Best Practices

Always validate inputs in your MCP tools to prevent injection attacks:
async fn execute(&self, params: Value) -> Result<String> {
    let query = params["query"].as_str()
        .ok_or("Invalid query parameter")?;

    // Validate query before execution
    if !is_safe_query(query) {
        return Err("Unsafe query detected".into());
    }

    // Execute safely
}
Reuse connections for better performance:
struct DatabaseTool {
    pool: sqlx::PgPool,  // Connection pool
}
Protect your MCP servers from abuse:
server.with_rate_limit(100, Duration::from_secs(60));
Track MCP usage for debugging and security:
agent.on_mcp_call(|tool_name, params| {
    tracing::info!(
        mcp_tool = tool_name,
        "MCP tool called"
    );
});

Common MCP Use Cases

Database Access

let response = agent.execute(
    "Find all users who signed up in the last 7 days"
).await?;

API Integration

let response = agent.execute(
    "Fetch the latest weather data for San Francisco"
).await?;

File System Operations

let response = agent.execute(
    "List all PDF files modified this week"
).await?;

Custom Business Logic

let response = agent.execute(
    "Calculate the monthly revenue report"
).await?;

Troubleshooting

Ensure the MCP server is running and accessible:
curl http://localhost:3000/health
Verify your authentication credentials:
let mcp = MCPClient::connect(url)
    .with_auth(MCPAuth::Bearer(token))
    .await?;
Check that the tool is registered on the MCP server:
let tools = mcp.list_tools().await?;
println!("Available tools: {:?}", tools);

Next Steps