✨ feat(kebab-mcp): handler skeleton + initialize handshake (fb-30)
KebabHandler implements rmcp::ServerHandler::get_info — returns serverInfo (name="kebab", version from CARGO_PKG_VERSION) and capabilities.tools. KebabAppState wraps Config in Arc for cheap clone into per-request task scope. serve_stdio entry builds a multi-thread tokio runtime and runs the server until client closes the stream. rmcp 1.6 API used: - rmcp::ServerHandler trait (re-exported from handler::server) - ServerInfo::new(caps).with_server_info(impl) builder (not struct-init: InitializeResult/Implementation are #[non_exhaustive]) - ServerCapabilities::builder().enable_tools().build() — builder macro generated, confirms the plan-literal pattern works - Implementation::new(name, version) — non-exhaustive constructor - rmcp::transport::stdio() returns (tokio::io::Stdin, tokio::io::Stdout) tuple; tuple impls IntoTransport via AsyncRead+AsyncWrite blanket - handler.serve(transport).await → RunningService<RoleServer, H> (ServiceExt::serve, returns Result<_, ServerInitializeError>) - service.waiting().await → Result<QuitReason, JoinError> - serve_stdio is plain fn wrapping a manually-built tokio runtime (avoids nested-runtime hazard if kebab-cli ever gains its own rt) Tools wire-up lands in subsequent tasks (one tool per task). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
19
crates/kebab-mcp/tests/initialize.rs
Normal file
19
crates/kebab-mcp/tests/initialize.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
//! Integration: KebabHandler::get_info returns correct kebab serverInfo.
|
||||
//! Doesn't exercise full transport — that lands when we have at least
|
||||
//! one tool to call (Task 4+).
|
||||
|
||||
use kebab_config::Config;
|
||||
use kebab_mcp::{KebabAppState, KebabHandler};
|
||||
use rmcp::ServerHandler;
|
||||
|
||||
#[tokio::test]
|
||||
async fn initialize_returns_kebab_server_info() {
|
||||
let cfg = Config::defaults();
|
||||
let state = KebabAppState::new(cfg);
|
||||
let handler = KebabHandler::new(state);
|
||||
|
||||
let info = handler.get_info();
|
||||
assert_eq!(info.server_info.name, "kebab");
|
||||
assert!(!info.server_info.version.is_empty());
|
||||
assert!(info.capabilities.tools.is_some());
|
||||
}
|
||||
Reference in New Issue
Block a user