pub struct SharedServer { /* private fields */ }
Expand description
Thread-safe wrapper for sharing McpServer instances across async tasks
This wrapper encapsulates Arc/Mutex complexity and provides a clean API
for concurrent access to server functionality. It addresses the limitations
where server run methods consume self
but configuration and monitoring
need to be shared across multiple async tasks.
§Design Rationale
McpServer run methods consume self
because:
- They take ownership of the server to run the main event loop
- Transport binding requires exclusive access
- Graceful shutdown needs to control the entire server lifecycle
However, other operations like health checks, metrics, and configuration access need to be shared across multiple tasks for monitoring and management.
§Examples
use turbomcp_server::{McpServer, SharedServer, ServerConfig};
let config = ServerConfig::default();
let server = McpServer::new(config);
let shared = SharedServer::new(server);
// Clone for sharing across tasks
let shared1 = shared.clone();
let shared2 = shared.clone();
// Both tasks can access server state concurrently
let handle1 = tokio::spawn(async move {
shared1.health().await
});
let handle2 = tokio::spawn(async move {
let _handle = shared2.shutdown_handle();
"shutdown_ready"
});
let (health, _shutdown_ready) = tokio::try_join!(handle1, handle2).unwrap();
// Run the server (consumes the shared server)
// shared.run_stdio().await?;
Implementations§
Sourcepub fn new(server: McpServer) -> Self
pub fn new(server: McpServer) -> Self
Create a new shared server wrapper
Takes ownership of a McpServer and wraps it for thread-safe sharing. The original server can no longer be accessed directly after this call.
Sourcepub async fn config(&self) -> Option<ServerConfig>
pub async fn config(&self) -> Option<ServerConfig>
Get server configuration
Returns a clone of the server configuration.
Sourcepub async fn registry(&self) -> Option<Arc<HandlerRegistry>>
pub async fn registry(&self) -> Option<Arc<HandlerRegistry>>
Get handler registry
Returns a clone of the Arc to the handler registry.
Sourcepub async fn router(&self) -> Option<Arc<RequestRouter>>
pub async fn router(&self) -> Option<Arc<RequestRouter>>
Get request router
Returns a clone of the Arc to the request router.
Sourcepub async fn lifecycle(&self) -> Option<Arc<ServerLifecycle>>
pub async fn lifecycle(&self) -> Option<Arc<ServerLifecycle>>
Get server lifecycle
Returns a clone of the Arc to the server lifecycle.
Sourcepub async fn metrics(&self) -> Option<Arc<ServerMetrics>>
pub async fn metrics(&self) -> Option<Arc<ServerMetrics>>
Get server metrics
Returns a clone of the Arc to the server metrics.
Sourcepub async fn shutdown_handle(&self) -> Option<ShutdownHandle>
pub async fn shutdown_handle(&self) -> Option<ShutdownHandle>
Get a shutdown handle for graceful server termination
Returns a shutdown handle that can be used to gracefully terminate the server from external tasks.
Sourcepub async fn health(&self) -> Option<HealthStatus>
pub async fn health(&self) -> Option<HealthStatus>
Get health status
Returns the current health status of the server.
Sourcepub async fn run_stdio(self) -> ServerResult<()>
pub async fn run_stdio(self) -> ServerResult<()>
Run the server with STDIO transport
This consumes the SharedServer and extracts the inner server to run it. After calling this method, the SharedServer can no longer be used.
Sourcepub async fn is_available(&self) -> bool
pub async fn is_available(&self) -> bool
Check if the server is still available (hasn’t been consumed)