use crate::error::McpResult;
use tokio::io::{self, AsyncBufReadExt, AsyncWriteExt, BufReader};
pub struct StdioTransport {
reader: BufReader<io::Stdin>,
writer: io::Stdout,
}
impl StdioTransport {
pub fn new() -> Self {
Self {
reader: BufReader::new(io::stdin()),
writer: io::stdout(),
}
}
pub async fn read_line(&mut self) -> McpResult<Option<String>> {
loop {
let mut line = String::new();
match self.reader.read_line(&mut line).await? {
0 => return Ok(None), _ => {
let trimmed = line.trim();
if !trimmed.is_empty() {
return Ok(Some(trimmed.to_string()));
}
}
}
}
}
pub async fn write_line(&mut self, line: &str) -> McpResult<()> {
self.writer.write_all(line.as_bytes()).await?;
self.writer.write_all(b"\n").await?;
self.writer.flush().await?;
Ok(())
}
}
impl Default for StdioTransport {
fn default() -> Self {
Self::new()
}
}