use std::collections::BTreeMap;
use async_trait::async_trait;
use crate::server::KhiveMcpServer;
#[derive(Debug, Default, Clone)]
pub struct ServeOptions {
pub bind: Option<String>,
}
#[async_trait]
pub trait Transport: Send + Sync {
fn name(&self) -> &'static str;
fn about(&self) -> &'static str;
async fn serve(&self, server: KhiveMcpServer, opts: &ServeOptions) -> anyhow::Result<()>;
}
pub struct StdioTransport;
#[async_trait]
impl Transport for StdioTransport {
fn name(&self) -> &'static str {
"stdio"
}
fn about(&self) -> &'static str {
"MCP over stdio (default)"
}
async fn serve(&self, server: KhiveMcpServer, _opts: &ServeOptions) -> anyhow::Result<()> {
server.serve_stdio().await
}
}
pub struct TransportRegistry {
transports: BTreeMap<&'static str, Box<dyn Transport>>,
}
impl TransportRegistry {
pub fn new() -> Self {
Self {
transports: BTreeMap::new(),
}
}
pub fn with_builtins() -> Self {
let mut registry = Self::new();
registry.register(Box::new(StdioTransport));
registry
}
pub fn register(&mut self, transport: Box<dyn Transport>) {
self.transports.insert(transport.name(), transport);
}
pub fn get(&self, name: &str) -> Option<&dyn Transport> {
self.transports.get(name).map(|t| t.as_ref())
}
pub fn names(&self) -> Vec<&'static str> {
self.transports.keys().copied().collect()
}
}
impl Default for TransportRegistry {
fn default() -> Self {
Self::with_builtins()
}
}