use litemcp::prelude::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct SearchArgs {
query: String,
#[serde(default)]
limit: Option<u32>,
}
fn main() -> std::io::Result<()> {
println!(
"litemcp {} — MCP stateless sur http://127.0.0.1:8080/mcp",
VERSION
);
ServerBuilder::new("hello", "0.1.0")
.tool("hello", "Dit bonjour à quelqu'un", |args| {
let name = args.get("name").and_then(|v| v.as_str()).unwrap_or("monde");
Ok(serde_json::json!({ "message": format!("Bonjour, {name} !") }))
})
.tool_typed(
"timestamp",
"Renvoie un horodatage fixe (démo)",
zod::object()
.opt("tz", zod::enumeration(&["UTC", "local"]))
.strict(),
|args| {
let tz = args.get("tz").and_then(|v| v.as_str()).unwrap_or("UTC");
Ok(serde_json::json!({ "tz": tz, "now": "2026-10-22T00:00:00Z" }))
},
)
.tool_parse(
"search",
"Recherche indexée (démo)",
zod::object()
.field("query", zod::string().min(2).max(64))
.opt("limit", zod::integer().min(1).max(100))
.strict(),
|args: SearchArgs| {
let limit = args.limit.unwrap_or(10);
Ok(serde_json::json!({ "query": args.query, "limit": limit }))
},
)
.annotate(
"timestamp",
ToolAnnotations::new()
.title("Horodatage")
.read_only(true)
.idempotent(true),
)
.annotate(
"search",
ToolAnnotations::new()
.title("Recherche")
.read_only(true)
.open_world(false),
)
.bind("127.0.0.1:8080")?
.serve()
}