Skip to main content

kotoba/
lib.rs

1//! Kotoba (言葉) — MCP server framework for pleme-io applications.
2//!
3//! Shared boilerplate and helpers for building MCP servers with rmcp:
4//! - `McpApp`: server builder with sensible defaults (name, version, stdio)
5//! - `json_ok` / `json_err`: consistent JSON response formatting
6//! - `StatusTool`: standardized health/status tool (name, version, uptime)
7//! - Re-exports of rmcp types used in every MCP server
8//!
9//! # Usage
10//!
11//! ```rust,ignore
12//! use kotoba::prelude::*;
13//!
14//! #[derive(Clone)]
15//! struct MyServer { tool_router: ToolRouter<Self> }
16//!
17//! #[tool_router]
18//! impl MyServer {
19//!     #[tool(description = "do something")]
20//!     async fn my_tool(&self, Parameters(input): Parameters<MyInput>) -> String {
21//!         json_ok(&result)
22//!     }
23//! }
24//!
25//! #[tool_handler]
26//! impl ServerHandler for MyServer {
27//!     fn get_info(&self) -> ServerInfo {
28//!         kotoba::server_info("my-app", "My App description")
29//!     }
30//! }
31//!
32//! #[tokio::main]
33//! async fn main() {
34//!     kotoba::run(MyServer::new()).await.unwrap();
35//! }
36//! ```
37
38pub mod error;
39pub mod response;
40pub mod status;
41
42pub use error::McpError;
43pub use response::{json_err, json_ok, json_result};
44pub use status::StatusInfo;
45
46// Re-export rmcp types that every MCP server needs
47pub mod prelude {
48    pub use rmcp::{
49        ServerHandler, ServiceExt,
50        handler::server::{router::tool::ToolRouter, wrapper::Parameters},
51        model::{ServerCapabilities, ServerInfo},
52        schemars, tool, tool_handler, tool_router,
53        transport::stdio,
54    };
55    pub use serde::Deserialize;
56    pub use crate::{json_err, json_ok, json_result};
57    pub use crate::status::StatusInfo;
58}
59
60use rmcp::ServiceExt;
61use rmcp::model::{Implementation, ServerCapabilities, ServerInfo};
62
63/// Create a `ServerInfo` with tools enabled and the given name + description.
64pub fn server_info(name: &str, description: &str) -> ServerInfo {
65    ServerInfo {
66        server_info: Implementation {
67            name: name.to_string(),
68            ..Implementation::from_build_env()
69        },
70        instructions: Some(description.into()),
71        capabilities: ServerCapabilities::builder().enable_tools().build(),
72        ..Default::default()
73    }
74}
75
76/// Run an MCP server on stdio transport. Standard entry point for all pleme-io MCP servers.
77pub async fn run<S>(server: S) -> Result<(), Box<dyn std::error::Error>>
78where
79    S: rmcp::ServerHandler,
80{
81    let service = server.serve(rmcp::transport::stdio()).await?;
82    service.waiting().await?;
83    Ok(())
84}