Skip to main content

coralstack_cmd_ipc_mcp/
lib.rs

1//! MCP server adapter that exposes a [`CommandRegistry`](coralstack_cmd_ipc::CommandRegistry)
2//! as Model Context Protocol tools.
3//!
4//! [`McpServerChannel`] implements [`CommandChannel`](coralstack_cmd_ipc::CommandChannel),
5//! so it plugs into a registry the same way any other channel does:
6//!
7//! ```no_run
8//! use std::sync::Arc;
9//! use coralstack_cmd_ipc::prelude::*;
10//! use coralstack_cmd_ipc_mcp::McpServerChannel;
11//!
12//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
13//! let registry = CommandRegistry::new(Config::default());
14//! // ... registry.register_command(...) etc ...
15//!
16//! // Register the MCP channel like any other channel.
17//! let mcp = Arc::new(McpServerChannel::new("mcp"));
18//! let driver = registry.register_channel(mcp.clone()).await?;
19//! tokio::spawn(driver);
20//!
21//! // Drive the MCP protocol over stdio. Completes when the MCP client
22//! // disconnects; the channel remains registered until explicitly closed.
23//! mcp.serve_stdio().await?;
24//! # Ok(()) }
25//! ```
26//!
27//! Every non-private command in the registry is exposed to the MCP
28//! client as a tool; private commands (id prefixed with `_`) are never
29//! surfaced. `tools/list` and `tools/call` from the MCP client generate
30//! `list.commands.request` / `execute.command.request` messages on the
31//! cmd-ipc wire, so the registry's full routing machinery (local,
32//! remote via channel, escalation to a router) applies just as for any
33//! other caller.
34
35mod server;
36mod translate;
37
38pub use server::{McpServerChannel, McpServerError};