Skip to content

Rust SDK for building Model Context Protocol servers on Internet Computer canisters.

License

Notifications You must be signed in to change notification settings

ByteSmithLabs/ic-rmcp

Repository files navigation

ic-rmcp

Internet Computer compatible MCP Version

A lightweight Rust SDK for implementing Model Context Protocol (MCP) servers on the Internet Computer.

This SDK is specifically designed for the IC canister runtime, using the Streamable HTTP transport and focusing on the core tools capability. It allows developers to quickly expose canister functions as MCP tools for AI models to interact with.

Docs for LLMs

We support the llms.txt convention for making documentation available to large language models and the applications that make use of them.

Features

  • Protocol Version: Implements the 2025-03-26 & 2025-06-18 MCP specification versions.
  • Target Runtime: Built exclusively for the Internet Computer (no tokio dependency).
  • Transport: Supports the official Streamable HTTP transport.
  • Capabilities:
    • tools (tools/list, tools/call)
  • Utilities:
    • ping

Limitations

  • No maintained sessions. Also no two-way communication between server and client. You should be aware of HTTP response size limitation on IC environment when designing and implementing tools.
  • Your API key can be seen by nodes in subnet

Usage

1. Add to Cargo.toml

[dependencies]
ic-rmcp = { git = "https://github.com/ByteSmithLabs/ic-rmcp", tag = "v0.3.0" }

2. Implement the Handler Trait

Create a struct for your server and implement the ic_rmcp::Handler trait. This is where you define your server's logic for listing and calling tools.

The SDK provides default implementations, so you only need to override the methods you want to support.

use ic_rmcp::{model::*, schema_for_type, Error, Handler, Server, Context};


struct MyServer;

impl Handler for MyServer {
   fn get_info(&self, _: Context) -> ServerInfo {
        ServerInfo {
            capabilities: ServerCapabilities::builder().enable_tools().build(),
            server_info: Implementation {
                name: "My MCP server".to_string(),
                version: "1.0.0".to_string(),
            },
            ..Default::default()
        }
    }

   async fn list_tools(&self,_: Context, _: Option<PaginatedRequestParam>) -> Result<ListToolsResult, Error> {
        Ok(ListToolsResult {
            next_cursor: None,
            tools: vec![
                Tool::new(
                    "foo",
                    "A foo tool",
                    schema_for_type::<EmptyObject>(),
                )
            ],
        })
    }

   async fn call_tool(&self,_: Context, requests: CallToolRequestParam) -> Result<CallToolResult, Error> {
        match requests.name.as_ref() {
            "foo" => {
                Ok(CallToolResult::success(
                    Content::text("Call foo tool successfully").into_contents(),
                ))
            }
            _ => Err(Error::invalid_params("not found tool", None)),
        }
    }
}

3. Expose the Server in Your Canister

Use the standard http_request and http_request_update canister endpoints. The Server trait is automatically implemented on your Handler, giving you access to the appropriate handle method. See more at HTTP Gateway on Internet Computer

use ic_cdk::{init, query, update};
use ic_http_certification::{HttpRequest, HttpResponse, StatusCode};

// A constant for a simple API key auth
const API_KEY: &str = "a-secret-api-key";

// Tool results are dynamic. Hence need subnet concensus.
#[query]
fn http_request(_: HttpRequest) -> HttpResponse {
    HttpResponse::builder()
        .with_status_code(StatusCode::OK)
        .with_upgrade(true)
        .build()
}

#[update]
async fn http_request_update(req: HttpRequest<'_>) -> HttpResponse<'_> {
    MyServer {}
        .handle(&req, |headers| -> bool {
            headers
                .iter()
                .any(|(k, v)| k == "x-api-key" && *v == API_KEY.with_borrow(|k| k.clone()))
        })
        .await
}

About OAuth: See our Clock MCP server example to learn about how to set up your MCP server with OAuth.

4. Deploy your canister

Access your MCP server after deployment at: https://<CANISTER_ID>.icp0.io/mcp

Full Canister Example

5. Learning resources

ByteSmithLabs YouTube Channel

Related Resources

About

Rust SDK for building Model Context Protocol servers on Internet Computer canisters.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages