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