rust-mcp-sdk 0.9.0

An asynchronous SDK and framework for building MCP-Servers and MCP-Clients, leveraging the rust-mcp-schema for type safe MCP Schema Objects.
Documentation
pub mod common;

use crate::common::{initialize_tracing, inquiry_utils::InquiryUtils, ExampleClientHandler};
use rust_mcp_sdk::schema::{
    ClientCapabilities, Implementation, InitializeRequestParams, LoggingLevel,
    SetLevelRequestParams, LATEST_PROTOCOL_VERSION,
};
use rust_mcp_sdk::{
    error::SdkResult,
    mcp_client::{client_runtime, McpClientOptions},
    mcp_icon, McpClient, StdioTransport, ToMcpClientHandler, TransportOptions,
};
use std::sync::Arc;

const MCP_SERVER_TO_LAUNCH: &str = "@modelcontextprotocol/server-everything";

#[tokio::main]
async fn main() -> SdkResult<()> {
    // Set up the tracing subscriber for logging
    initialize_tracing();

    // Step1 : Define client details and capabilities
    let client_details: InitializeRequestParams = InitializeRequestParams {
        capabilities: ClientCapabilities::default(),
        client_info: Implementation {
            name: "simple-rust-mcp-client-stdio".into(),
            version: "0.1.0".into(),
            title: Some("Simple Rust MCP Client (Stdio)".into()),
            description: Some("Simple Rust MCP Client, by Rust MCP SDK".into()),
            icons: vec![mcp_icon!(
                src = "https://raw.githubusercontent.com/rust-mcp-stack/rust-mcp-sdk/main/assets/rust-mcp-icon.png",
                mime_type = "image/png",
                sizes = ["128x128"],
                theme = "dark"
            )],
            website_url: Some("https://github.com/rust-mcp-stack/rust-mcp-sdk".into()),
        },
        protocol_version: LATEST_PROTOCOL_VERSION.into(),
        meta: None,
    };

    // Step2 : Create a transport, with options to launch/connect to a MCP Server
    // In this example we launch @modelcontextprotocol/server-everything (needs node.js and npm to be installed)
    let transport = StdioTransport::create_with_server_launch(
        "npx",
        vec!["-y".into(), MCP_SERVER_TO_LAUNCH.into()],
        None,
        TransportOptions::default(),
    )?;

    // STEP 3: instantiate our custom handler that is responsible for handling MCP messages
    let handler = ExampleClientHandler {};

    // STEP 4: create a MCP client
    let client = client_runtime::create_client(McpClientOptions {
        client_details,
        transport,
        handler: handler.to_mcp_client_handler(),
        task_store: None,
        server_task_store: None,
        message_observer: None,
    });

    // STEP 5: start the MCP client
    client.clone().start().await?;

    // You can utilize the client and its methods to interact with the MCP Server.
    // The following demonstrates how to use client methods to retrieve server information,
    // and print them in the terminal, set the log level, invoke a tool, and more.

    // Create a struct with utility functions for demonstration purpose, to utilize different client methods and display the information.
    let utils = InquiryUtils {
        client: Arc::clone(&client),
    };
    // Display server information (name and version)
    utils.print_server_info();

    // Display server capabilities
    utils.print_server_capabilities();

    // Display the list of tools available on the server
    utils.print_tool_list().await?;

    // Display the list of prompts available on the server
    utils.print_prompts_list().await?;

    // Display the list of resources available on the server
    utils.print_resource_list().await?;

    // Display the list of resource templates available on the server
    utils.print_resource_templates().await?;

    // Call get-sum tool, and print the result
    utils.call_get_sum_tool(100, 25).await?;

    // Set the log level
    utils
        .client
        .request_set_logging_level(SetLevelRequestParams {
            level: LoggingLevel::Debug,
            meta: None,
        })
        .await?;

    // Send 3 pings to the server, with a 2-second interval between each ping.
    utils.ping_n_times(3).await;

    client.shut_down().await?;

    Ok(())
}