RustでMCPサーバーを作成、Claude Desktopで使用してみる
最近話題のMCPを簡単に試してみます。
MCPサーバーを実装する
RustではMCPのために sdk が用意されていました。これを使っていきます。
https://github.com/modelcontextprotocol/rust-sdk?tab=readme-ov-file
code: Cargo.toml
dependencies
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main", features = [
"server",
"client",
"transport-child-process",
"transport-async-rw",
"transport-io",
] }
...
今回は現在時刻を取得させるだけのものを作成します。論よりコード(見りゃだいたいわかる)
code: main.rs
use anyhow::Result;
use rmcp::{Error as McpError, ServerHandler, ServiceExt, model::*, tool, transport::stdio};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use tracing_subscriber::EnvFilter;
#derive(Debug, Clone)
pub struct SampleMcpServer;
#derive(Debug, Serialize, Deserialize, JsonSchema)
pub struct QueryParameters {
// 任意の受け取りたいパラメータ
// 今回は不要
}
#tool(tool_box)
impl SampleMcpServer {
pub fn new() -> Self {
Self
}
#tool(description = "現在時刻を取得する")
fn get_time(
&self,
#tool(aggr) QueryParameters {}: QueryParameters,
) -> Result<CallToolResult, McpError> {
let now = chrono::offset::Local::now();
Ok(CallToolResult::success(vec![Content::text(
now.to_string(),
)]))
}
}
#tool(tool_box)
impl ServerHandler for SampleMcpServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
protocol_version: ProtocolVersion::V_2024_11_05,
capabilities: ServerCapabilities::builder()
.enable_prompts()
.enable_resources()
.enable_tools()
.build(),
server_info: Implementation::from_build_env(),
instructions: Some("日時を取得できるサンプルのMCPサーバー".into()),
}
}
}
#tokio::main
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env().add_directive(tracing::Level::DEBUG.into()))
.with_writer(std::io::stderr)
.with_ansi(false)
.init();
tracing::info!("Starting Sample MCP server");
let service = SampleMcpServer::new()
.serve(stdio())
.await
.inspect_err(|e| {
tracing::error!("serving error: {:?}", e);
})?;
service.waiting().await?;
Ok(())
}
できたらリリースビルドしておきましょう
$ cargo build --release
これだけでサーバーは実装完了です!
ホスト側(今回はClaude側)で呼び出す
Claude Desktop では、Ctrl + , で設定を開き開発者タブから構成を編集をクリックしてください。
https://scrapbox.io/files/6830c88214ac1d7e021eaaad.png
すると claude_desktop_config.json が見えると思うので、それを以下のように編集していきます。
code: claude_desktop_config.json
{
"mcpServers": {
"time_server": {
"command": "/path/to/target/release/app_name.exe",
"args": []
}
}
}
それから、自作サーバーをClaudeに起動してもらうために、Claude Desktop を再起動します。
(筆者の場合タスクマネージャーからタスクキルしないと読み込んでくれなかった)
で、あとはシンプルに自然言語で聞く。リクエストした内容と実際にサーバーから返ってきた内容も見れますね。
https://scrapbox.io/files/6830c734420c510b75c44c8f.png
おわりに
こんなに簡単に、現在時刻を考慮したLLMのレスポンスが生成できます。
今回使ったような sdk が言語にあれば、ツール定義とか、リクエストのパースとか諸々簡単になって実装者は必要な箇所だけに集中できます。
MCPを利用した処理の流れとしては以下
1. MCPクライアントがMCPサーバーから使えるツールの一覧を取得する
2. LLMにMCPサーバーのどのツールを使用するか判断させ、リクエスト内容を生成させる
3. MCPクライアントがLLMのレスポンスをもとに、リクエストを対象のMCPサーバーに投げる
4. レスポンスの内容から、LLMにユーザーへ返答するための自然言語を生成させる
既に多くのMCPサーバーが作成されているので、調べてみると良いでしょう。
既存のMCPサーバー一覧を調べるには以下がおすすめ
https://glama.ai/mcp/servers
自然言語で実際に処理をさせることができるから、LLM(正確にはMCPホスト)にチャットするだけで特定業務は終わりって感じになる未来は、すぐそこにきてる?
「誰々に~~の件について、~~って感じでメールして」って言えばメールしてくれるし
「~~のファイル要約しておいて」って言えばローカルに書き込んどいてくれる
もし、社内システムとかにもMCPサーバーを実装しておけば、LLMが社内のシステムに介入できるようになる。
あまりに複雑なリクエストとかだと、リクエスト形式を正しく生成できなくてエラーになりそうとか、
LLMに言ったはいいけど本当にその処理を実行していいのかとか、
大量のMCPサーバーを起動してたら意図してないところに処理をしてしまうとか、
課題はまだありそうだけど......
#MCP #yuusuine #Claude #LLM #Rust