Skip to main content

winx_code_agent/
server.rs

1//! Winx MCP server facade.
2//!
3//! Protocol catalog, session lifecycle, task handling, MCP dispatch, and tool
4//! adapters live in focused submodules under `server/`.
5
6mod catalog;
7mod handler;
8mod outcomes;
9mod principal;
10mod sessions;
11mod tasks;
12mod tool_dispatch;
13
14#[cfg(test)]
15mod tests;
16
17use std::sync::Arc;
18
19use rmcp::{
20    transport::{async_rw::AsyncRwTransport, stdio},
21    ServiceExt,
22};
23use tokio::sync::Mutex;
24use tracing::info;
25
26use crate::runtime::{configured_shell_runtime, ShellRuntime};
27use crate::state::task_state::TaskRegistry;
28use crate::state::BashState;
29use sessions::SessionRegistry;
30
31pub use sessions::SessionIsolation;
32
33/// Shared shell state for one logical Winx session.
34pub type SharedBashState = Arc<Mutex<Option<BashState>>>;
35
36/// Winx service shared by stdio or HTTP transports.
37#[derive(Clone)]
38pub struct WinxService {
39    sessions: Arc<Mutex<SessionRegistry>>,
40    tasks: Arc<Mutex<TaskRegistry>>,
41    root_bootstrap: Arc<Mutex<()>>,
42    shell_runtime: Arc<dyn ShellRuntime>,
43    /// Version information advertised in the MCP handshake.
44    pub version: String,
45    isolation: SessionIsolation,
46}
47
48/// Create and start the Winx MCP server.
49pub async fn start_winx_server() -> Result<(), Box<dyn std::error::Error>> {
50    start_winx_server_with_runtime(configured_shell_runtime().await?).await
51}
52
53/// Create and start the stdio MCP server with an explicit shell runtime.
54pub async fn start_winx_server_with_runtime(
55    runtime: Arc<dyn ShellRuntime>,
56) -> Result<(), Box<dyn std::error::Error>> {
57    info!("Starting Winx MCP Server");
58    let service = WinxService::with_runtime(SessionIsolation::Lenient, runtime);
59    let (stdin, stdout) = stdio();
60    let transport = AsyncRwTransport::new_server(stdin, stdout);
61    let server = service.serve(transport).await?;
62    server.waiting().await?;
63    Ok(())
64}