#![allow(clippy::needless_pass_by_value)]
use fastmcp_rust::TaskManager;
use fastmcp_rust::prelude::*;
#[tool]
fn echo(ctx: &McpContext, message: String) -> String {
if ctx.is_cancelled() {
return "Cancelled".to_string();
}
message
}
#[tool(description = "Calculate the sum of two numbers")]
fn add(_ctx: &McpContext, a: i64, b: i64) -> String {
format!("{}", a + b)
}
#[tool]
fn reverse(_ctx: &McpContext, text: String) -> String {
text.chars().rev().collect()
}
#[tool(name = "word_count", description = "Count the number of words in text")]
fn count_words(_ctx: &McpContext, text: String) -> String {
let count = text.split_whitespace().count();
format!("{count}")
}
#[resource(uri = "info://server")]
fn server_info(_ctx: &McpContext) -> String {
r#"{
"name": "echo-server",
"version": "1.0.0",
"description": "A simple example MCP server"
}"#
.to_string()
}
#[resource(
uri = "info://time",
name = "Current Time",
description = "Returns the current Unix timestamp"
)]
fn current_time(_ctx: &McpContext) -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
format!("{timestamp}")
}
#[prompt(description = "Generate a friendly greeting")]
fn greeting(_ctx: &McpContext, name: String) -> Vec<PromptMessage> {
vec![PromptMessage {
role: Role::User,
content: Content::Text {
text: format!("Please greet {name} in a friendly way."),
},
}]
}
#[prompt(name = "review_code")]
fn code_review_prompt(_ctx: &McpContext, code: String, language: String) -> Vec<PromptMessage> {
let lang_hint = if language.is_empty() {
String::new()
} else {
format!(" (written in {language})")
};
vec![PromptMessage {
role: Role::User,
content: Content::Text {
text: format!(
"Please review the following code{lang_hint} and provide feedback:\n\n```\n{code}\n```"
),
},
}]
}
fn main() {
Server::new("echo-server", "1.0.0")
.tool(Echo)
.tool(Add)
.tool(Reverse)
.tool(CountWords)
.resource(ServerInfoResource)
.resource(CurrentTimeResource)
.prompt(GreetingPrompt)
.prompt(CodeReviewPromptPrompt)
.request_timeout(30)
.instructions(
"A simple echo server for testing FastMCP. Try calling the 'echo' tool with a message!",
)
.with_task_manager(TaskManager::new().into_shared())
.build()
.run_stdio();
}