use server_less::{http, mcp};
#[derive(Clone)]
struct UsersService;
#[http]
#[mcp]
impl UsersService {
pub fn list_users(&self) -> Vec<String> {
vec!["alice".to_string(), "bob".to_string()]
}
pub fn get_user(&self, user_id: String) -> Option<String> {
match user_id.as_str() {
"alice" | "bob" => Some(format!("User: {}", user_id)),
_ => None,
}
}
pub fn create_user(&self, name: String) -> String {
format!("Created user: {}", name)
}
}
#[derive(Clone)]
struct ApiService {
users: UsersService,
}
impl ApiService {
fn new() -> Self {
Self {
users: UsersService,
}
}
}
#[http]
#[mcp]
impl ApiService {
pub fn get_health(&self) -> String {
"ok".to_string()
}
pub fn users(&self) -> &UsersService {
&self.users
}
}
fn main() {
let api = ApiService::new();
let tools = ApiService::mcp_tools();
let tool_names: Vec<&str> = tools
.iter()
.map(|t| t["name"].as_str().unwrap())
.collect();
println!("MCP tools in ApiService:");
for name in &tool_names {
println!(" {}", name);
}
assert!(
tool_names.contains(&"get_health"),
"Expected get_health tool, got: {:?}",
tool_names
);
assert!(
tool_names.contains(&"users_list_users"),
"Expected users_list_users tool, got: {:?}",
tool_names
);
assert!(
tool_names.contains(&"users_get_user"),
"Expected users_get_user tool, got: {:?}",
tool_names
);
assert!(
tool_names.contains(&"users_create_user"),
"Expected users_create_user tool, got: {:?}",
tool_names
);
let result = api.mcp_call("users_list_users", serde_json::json!({}));
println!("\nmcp_call(\"users_list_users\") -> {:?}", result.unwrap());
let spec = ApiService::http_openapi_spec();
let paths = spec["paths"].as_object().unwrap();
println!("\nHTTP routes in ApiService spec:");
for (path, methods) in paths {
let method_list: Vec<_> = methods.as_object().unwrap().keys().collect();
println!(
" {} [{}]",
path,
method_list
.iter()
.map(|m| m.to_uppercase())
.collect::<Vec<_>>()
.join(", ")
);
}
let path_keys: Vec<&str> = paths.keys().map(|k| k.as_str()).collect();
assert!(
path_keys.iter().any(|p| p.starts_with("/users/")),
"Expected child routes under /users/, got: {:?}",
path_keys
);
let api2 = ApiService::new();
let _router = api2.http_router();
println!("\nHTTP router created successfully (child routes nested under /users/)");
println!("\nAll assertions passed.");
}