Skip to main content

prism_mcp_rs/server/
mcp_server.rs

1//! MCP server implementation
2//!
3//! Module provides the main MCP server implementation that handles client connections,
4//! manages resources, tools, and prompts, and processes JSON-RPC requests according to
5//! the Model Context Protocol specification.
6//!
7//! # Plugin System Feature
8//!
9//! To use the plugin system, enable the plugin feature in `Cargo.toml`:
10//! ```toml
11//! [dependencies]
12//! prism-mcp-rs = { version = "3", features = ["plugin"] }
13//! ```
14//!
15//! This enables dynamic tool loading and plugin management capabilities.
16
17use serde_json::Value;
18use std::collections::HashMap;
19use std::sync::Arc;
20use tokio::sync::{Mutex, RwLock};
21use tracing::Instrument;
22
23use crate::core::{
24    completion::{CompletionContext, CompletionHandler},
25    error::{McpError, McpResult},
26    prompt::{Prompt, PromptHandler},
27    resource::{Resource, ResourceHandler},
28    tool::{MultiRoundToolCall, MultiRoundToolHandler, Tool, ToolHandler},
29    PromptInfo, ResourceInfo, ToolInfo,
30};
31use crate::protocol::tasks::{
32    has_tasks_extension, CancelTaskParams, CreateTaskResult, GetTaskParams, GetTaskResult,
33    TaskAcknowledgement, UpdateTaskParams, TASKS_EXTENSION_ID,
34};
35use crate::protocol::{messages::*, methods, types::*, validation::*, version::*};
36use crate::security::{RequestContext, RequestPolicy, RequestTarget};
37use crate::server::tasks::{ComposedTaskToolHandler, TaskRegistry, TaskToolHandler};
38use crate::transport::traits::ServerTransport;
39
40#[cfg(feature = "plugin")]
41use crate::plugin::PluginManager;
42#[cfg(feature = "plugin")]
43use async_trait::async_trait;
44
45// Import ClosureWrapper from tool module for closure support
46use crate::core::tool::ClosureWrapper;
47
48// Plugin tool handler wrapper
49#[cfg(feature = "plugin")]
50struct PluginToolHandler {
51    manager: Arc<RwLock<PluginManager>>,
52    tool_name: String,
53}
54
55#[cfg(feature = "plugin")]
56impl PluginToolHandler {
57    fn new(manager: Arc<RwLock<PluginManager>>, tool_name: String) -> Self {
58        Self { manager, tool_name }
59    }
60}
61
62#[cfg(feature = "plugin")]
63#[async_trait]
64impl ToolHandler for PluginToolHandler {
65    async fn call(
66        &self,
67        arguments: HashMap<String, Value>,
68    ) -> McpResult<crate::protocol::types::ToolResult> {
69        self.manager
70            .read()
71            .await
72            .execute_tool(&self.tool_name, serde_json::to_value(arguments)?)
73            .await
74    }
75}
76
77/// Configuration for the MCP server
78#[derive(Debug, Clone)]
79pub struct ServerConfig {
80    /// Maximum number of concurrent requests
81    pub max_concurrent_requests: usize,
82    /// Request timeout in milliseconds
83    pub request_timeout_ms: u64,
84    /// Whether to validate incoming requests
85    pub validate_requests: bool,
86    /// Whether to enable detailed logging
87    pub enable_logging: bool,
88}
89
90impl Default for ServerConfig {
91    fn default() -> Self {
92        Self {
93            max_concurrent_requests: 100,
94            request_timeout_ms: 30000,
95            validate_requests: true,
96            enable_logging: true,
97        }
98    }
99}
100
101/// MCP Server implementation
102///
103/// The main server struct that handles MCP protocol communication, manages
104/// resources, tools, and prompts, and processes client requests.
105///
106/// # Examples
107///
108/// ## Basic Server Creation
109/// ```
110/// use prism_mcp_rs::server::McpServer;
111///
112/// let server = McpServer::new("my-server".to_string(), "1.0.0".to_string());
113/// ```
114///
115/// ## Using ServerBuilder
116/// ```
117/// use prism_mcp_rs::server::ServerBuilder;
118///
119/// let server = ServerBuilder::new()
120///     .name("my-server")
121///     .version("1.0.0")
122///     .with_tools()
123///     .with_resources()
124///     .build();
125/// ```
126///
127/// ## Adding Tools
128/// ```no_run
129/// use prism_mcp_rs::server::McpServer;
130/// use prism_mcp_rs::core::{Tool, ToolHandler};
131/// use prism_mcp_rs::core::error::McpError;
132/// use serde_json::{json, Value};
133/// use async_trait::async_trait;
134/// use std::collections::HashMap;
135///
136/// struct MyTool;
137///
138/// #[async_trait]
139/// impl ToolHandler for MyTool {
140///     async fn call(&self, _args: HashMap<String, Value>)
141///         -> Result<prism_mcp_rs::protocol::ToolResult, McpError>
142///     {
143///         Ok(prism_mcp_rs::protocol::ToolResult {
144///             content: vec![],
145///             is_error: Some(false),
146///             structured_content: None,
147///             meta: None,
148///         })
149///     }
150/// }
151///
152/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
153/// let mut server = McpServer::new("server".to_string(), "1.0.0".to_string());
154///
155/// // Add tool using the add_tool method directly
156/// server.add_tool(
157///     "my_tool",
158///     Some("My custom tool"),
159///     json!({}),
160///     MyTool
161/// ).await?;
162/// # Ok(())
163/// # }
164/// ```
165/// Main MCP server implementation
166pub struct McpServer {
167    /// Server information
168    info: ServerInfo,
169    /// Server capabilities
170    capabilities: ServerCapabilities,
171    /// Server configuration
172    config: ServerConfig,
173    /// Registered resources
174    resources: Arc<RwLock<HashMap<String, Resource>>>,
175    /// Registered tools
176    tools: Arc<RwLock<HashMap<String, Tool>>>,
177    /// Registered MCP 2026 multi-round-trip capable tools.
178    multi_round_tools: Arc<RwLock<HashMap<String, RegisteredMultiRoundTool>>>,
179    /// Registered tools that execute through the MCP Tasks extension.
180    task_tools: Arc<RwLock<HashMap<String, RegisteredTaskTool>>>,
181    /// Caller-bound durable task state.
182    task_registry: TaskRegistry,
183    /// Registered prompts
184    prompts: Arc<RwLock<HashMap<String, Prompt>>>,
185    /// Resource templates (New in 2025-11-25)
186    resource_templates: Arc<RwLock<HashMap<String, ResourceTemplate>>>,
187    /// Completion handlers (New in 2025-11-25)
188    completion_handlers: Arc<RwLock<HashMap<String, Box<dyn CompletionHandler>>>>,
189    /// Active transport
190    transport: Arc<Mutex<Option<Box<dyn ServerTransport>>>>,
191    /// Server state
192    state: Arc<RwLock<ServerState>>,
193    /// Request ID counter
194    #[allow(dead_code)]
195    request_counter: Arc<Mutex<u64>>,
196    /// Authorization and rate-limiting policy shared by all transports.
197    request_policy: RequestPolicy,
198    /// Revisions this server accepts.
199    protocol_mode: ProtocolMode,
200    /// Plugin manager for dynamic tool loading
201    #[cfg(feature = "plugin")]
202    plugin_manager: Option<Arc<RwLock<PluginManager>>>,
203}
204
205struct RegisteredMultiRoundTool {
206    info: ToolInfo,
207    handler: Box<dyn MultiRoundToolHandler>,
208}
209
210#[derive(Clone)]
211struct RegisteredTaskTool {
212    info: ToolInfo,
213    execution: TaskExecution,
214    fallback: Option<Arc<dyn ToolHandler>>,
215}
216
217#[derive(Clone)]
218enum TaskExecution {
219    Direct(Arc<dyn TaskToolHandler>),
220    Composed {
221        preflight: Arc<dyn MultiRoundToolHandler>,
222        handler: Arc<dyn ComposedTaskToolHandler>,
223    },
224}
225
226/// Internal server state
227#[derive(Debug, Clone, PartialEq)]
228pub enum ServerState {
229    /// Server is not yet initialized
230    Uninitialized,
231    /// Server is initializing
232    Initializing,
233    /// Server is running and ready to accept requests
234    Running,
235    /// Server is shutting down
236    Stopping,
237    /// Server has stopped
238    Stopped,
239}
240
241fn request_target(request: &JsonRpcRequest) -> RequestTarget {
242    let resource = request.params.as_ref().and_then(|params| {
243        params
244            .get("name")
245            .or_else(|| params.get("uri"))
246            .and_then(Value::as_str)
247            .map(str::to_owned)
248    });
249    RequestTarget::new(request.method.clone(), resource)
250}
251
252fn validate_input_required_result(
253    result: &InputRequiredResult,
254    capabilities: &ClientCapabilities,
255) -> McpResult<()> {
256    if result.result_type != ResultType::InputRequired {
257        return Err(McpError::Validation(
258            "multi-round handler must return resultType input_required".to_string(),
259        ));
260    }
261    if result.input_requests.is_empty() && result.request_state.is_none() {
262        return Err(McpError::Validation(
263            "input_required needs inputRequests or requestState".to_string(),
264        ));
265    }
266    for input_request in result.input_requests.values() {
267        let method = input_request
268            .get("method")
269            .and_then(Value::as_str)
270            .ok_or_else(|| McpError::Validation("input request is missing method".to_string()))?;
271        let required = match method {
272            methods::SAMPLING_CREATE_MESSAGE if capabilities.sampling.is_none() => {
273                Some(serde_json::json!({"sampling": {}}))
274            }
275            methods::ROOTS_LIST if capabilities.roots.is_none() => {
276                Some(serde_json::json!({"roots": {}}))
277            }
278            methods::ELICITATION_CREATE if capabilities.elicitation.is_none() => {
279                Some(serde_json::json!({"elicitation": {}}))
280            }
281            methods::SAMPLING_CREATE_MESSAGE
282            | methods::ROOTS_LIST
283            | methods::ELICITATION_CREATE => None,
284            _ => {
285                return Err(McpError::Validation(format!(
286                    "unsupported input request method: {method}"
287                )))
288            }
289        };
290        if let Some(required) = required {
291            return Err(McpError::MissingRequiredClientCapability(required));
292        }
293    }
294    Ok(())
295}
296
297fn tasks_capability_error() -> McpError {
298    McpError::MissingRequiredClientCapability(serde_json::json!({
299        "extensions": { (TASKS_EXTENSION_ID): {} }
300    }))
301}
302
303fn parse_multi_round_tool_call(
304    raw_params: &Value,
305    arguments: HashMap<String, Value>,
306    modern_context: Option<&ModernRequestContext>,
307) -> McpResult<MultiRoundToolCall> {
308    let raw_object = raw_params.as_object().ok_or_else(|| {
309        McpError::Validation("tool call parameters must be an object".to_string())
310    })?;
311    let input_responses = raw_object
312        .get("inputResponses")
313        .map(|value| {
314            value
315                .as_object()
316                .cloned()
317                .map(|values| values.into_iter().collect())
318                .ok_or_else(|| McpError::Validation("inputResponses must be an object".to_string()))
319        })
320        .transpose()?
321        .unwrap_or_default();
322    let request_state = raw_object
323        .get("requestState")
324        .map(|value| {
325            value
326                .as_str()
327                .map(str::to_string)
328                .ok_or_else(|| McpError::Validation("requestState must be a string".to_string()))
329        })
330        .transpose()?;
331    let (client_info, client_capabilities) = modern_context
332        .map(|context| {
333            (
334                context.client_info.clone(),
335                context.client_capabilities.clone(),
336            )
337        })
338        .unwrap_or_else(|| (None, ClientCapabilities::default()));
339    Ok(MultiRoundToolCall {
340        arguments,
341        input_responses,
342        request_state,
343        client_info,
344        client_capabilities,
345    })
346}
347
348impl McpServer {
349    /// Create a new MCP server with the given name and version
350    pub fn new(name: String, version: String) -> Self {
351        Self {
352            info: ServerInfo::new(name, version),
353            capabilities: ServerCapabilities {
354                extensions: None,
355                prompts: Some(PromptsCapability {
356                    list_changed: Some(true),
357                }),
358                resources: Some(ResourcesCapability {
359                    subscribe: Some(true),
360                    list_changed: Some(true),
361                }),
362                tools: Some(ToolsCapability {
363                    list_changed: Some(true),
364                }),
365                sampling: None,
366                logging: None,
367                completions: Some(CompletionsCapability::default()),
368                experimental: None,
369            },
370            config: ServerConfig::default(),
371            resources: Arc::new(RwLock::new(HashMap::new())),
372            tools: Arc::new(RwLock::new(HashMap::new())),
373            multi_round_tools: Arc::new(RwLock::new(HashMap::new())),
374            task_tools: Arc::new(RwLock::new(HashMap::new())),
375            task_registry: TaskRegistry::default(),
376            prompts: Arc::new(RwLock::new(HashMap::new())),
377            resource_templates: Arc::new(RwLock::new(HashMap::new())),
378            completion_handlers: Arc::new(RwLock::new(HashMap::new())),
379            transport: Arc::new(Mutex::new(None)),
380            state: Arc::new(RwLock::new(ServerState::Uninitialized)),
381            request_counter: Arc::new(Mutex::new(0)),
382            request_policy: RequestPolicy::default(),
383            protocol_mode: ProtocolMode::Auto,
384            #[cfg(feature = "plugin")]
385            plugin_manager: None,
386        }
387    }
388
389    /// Create a new MCP server with ergonomic string parameters
390    pub fn create(name: impl Into<String>, version: impl Into<String>) -> Self {
391        Self::new(name.into(), version.into())
392    }
393
394    /// Create a new MCP server with custom configuration
395    pub fn with_config(name: String, version: String, config: ServerConfig) -> Self {
396        let mut server = Self::new(name, version);
397        server.config = config;
398        server
399    }
400
401    /// Attach a plugin manager to the server
402    #[cfg(feature = "plugin")]
403    pub fn with_plugin_manager(mut self, manager: PluginManager) -> Self {
404        self.plugin_manager = Some(Arc::new(RwLock::new(manager)));
405        self
406    }
407
408    /// Internal method to sync plugin tools with server
409    #[cfg(feature = "plugin")]
410    pub async fn sync_plugin_tools(&self) -> McpResult<()> {
411        if let Some(ref manager) = self.plugin_manager {
412            let plugin_tools = manager.read().await.list_tools().await;
413
414            for tool in plugin_tools {
415                // Create a plugin tool wrapper
416                let handler = PluginToolHandler::new(manager.clone(), tool.name.clone());
417
418                // Convert the tool input schema to a simpler JSON value
419                let schema = serde_json::json!({
420                    "type": tool.input_schema.schema_type,
421                    "properties": tool.input_schema.properties,
422                    "required": tool.input_schema.required,
423                });
424
425                // Convert plugin tool to server tool format
426                self.add_tool(tool.name.clone(), tool.description.clone(), schema, handler)
427                    .await?;
428            }
429        }
430        Ok(())
431    }
432
433    /// Set server capabilities
434    pub fn set_capabilities(&mut self, capabilities: ServerCapabilities) {
435        self.capabilities = capabilities;
436    }
437
438    /// Select dual-stack, modern-only, or legacy-only server behavior.
439    pub fn set_protocol_mode(&mut self, mode: ProtocolMode) {
440        self.protocol_mode = mode;
441    }
442
443    /// Return the configured protocol support policy.
444    pub fn protocol_mode(&self) -> ProtocolMode {
445        self.protocol_mode
446    }
447
448    /// Set server configuration
449    pub fn set_config(&mut self, config: ServerConfig) {
450        self.config = config;
451    }
452
453    /// Install authorization and rate-limiting controls for all requests.
454    pub fn set_request_policy(&mut self, policy: RequestPolicy) {
455        self.request_policy = policy;
456    }
457
458    /// Install authorization and rate-limiting controls using a builder style.
459    pub fn with_request_policy(mut self, policy: RequestPolicy) -> Self {
460        self.request_policy = policy;
461        self
462    }
463
464    /// Set initial resources (used by ServerBuilder)
465    pub fn set_initial_resources(&mut self, resources: HashMap<String, Resource>) {
466        // This needs to be done synchronously during server construction
467        // We'll use block_on for this initial setup
468        let resources_arc = Arc::clone(&self.resources);
469        std::thread::spawn(move || {
470            let rt = tokio::runtime::Runtime::new().unwrap();
471            rt.block_on(async {
472                let mut resources_lock = resources_arc.write().await;
473                *resources_lock = resources;
474            });
475        })
476        .join()
477        .unwrap();
478    }
479
480    /// Set initial tools (used by ServerBuilder)
481    pub fn set_initial_tools(&mut self, tools: HashMap<String, Tool>) {
482        let tools_arc = Arc::clone(&self.tools);
483        std::thread::spawn(move || {
484            let rt = tokio::runtime::Runtime::new().unwrap();
485            rt.block_on(async {
486                let mut tools_lock = tools_arc.write().await;
487                *tools_lock = tools;
488            });
489        })
490        .join()
491        .unwrap();
492    }
493
494    /// Set initial prompts (used by ServerBuilder)
495    pub fn set_initial_prompts(&mut self, prompts: HashMap<String, Prompt>) {
496        let prompts_arc = Arc::clone(&self.prompts);
497        std::thread::spawn(move || {
498            let rt = tokio::runtime::Runtime::new().unwrap();
499            rt.block_on(async {
500                let mut prompts_lock = prompts_arc.write().await;
501                *prompts_lock = prompts;
502            });
503        })
504        .join()
505        .unwrap();
506    }
507
508    /// Set initial resource templates (used by ServerBuilder)
509    pub fn set_initial_resource_templates(&mut self, templates: HashMap<String, ResourceTemplate>) {
510        let templates_arc = Arc::clone(&self.resource_templates);
511        std::thread::spawn(move || {
512            let rt = tokio::runtime::Runtime::new().unwrap();
513            rt.block_on(async {
514                let mut templates_lock = templates_arc.write().await;
515                *templates_lock = templates;
516            });
517        })
518        .join()
519        .unwrap();
520    }
521
522    /// Create a builder for constructing servers
523    pub fn builder() -> crate::server::builder::ServerBuilder {
524        crate::server::builder::ServerBuilder::new()
525    }
526
527    /// Configure this server with capabilities using a fluent API
528    pub fn with_capabilities(mut self, capabilities: ServerCapabilities) -> Self {
529        self.capabilities = capabilities;
530        self
531    }
532
533    /// Configure this server with a specific configuration (fluent API)
534    pub fn with_server_config(mut self, config: ServerConfig) -> Self {
535        self.config = config;
536        self
537    }
538
539    /// Add a tool to the server with a ToolHandler implementation
540    ///
541    /// # Examples
542    ///
543    /// ```rust,ignore
544    /// // With a ToolHandler implementation
545    /// server.add_tool("my_tool", Some("description"), json!({}), MyToolHandler).await?;
546    /// ```
547    pub async fn add_tool<H>(
548        &self,
549        name: impl Into<String>,
550        description: Option<impl Into<String>>,
551        input_schema: Value,
552        handler: H,
553    ) -> McpResult<()>
554    where
555        H: ToolHandler + 'static,
556    {
557        let name = name.into();
558        let description = description.map(|d| d.into());
559        let tool = Tool::new(name.clone(), description, input_schema, handler);
560        self.multi_round_tools.write().await.remove(&name);
561        self.task_tools.write().await.remove(&name);
562        self.tools.write().await.insert(name, tool);
563        Ok(())
564    }
565
566    /// Add a tool that may return MCP 2026 `input_required` results.
567    pub async fn add_multi_round_tool<H>(
568        &self,
569        name: impl Into<String>,
570        description: Option<impl Into<String>>,
571        input_schema: Value,
572        handler: H,
573    ) -> McpResult<()>
574    where
575        H: MultiRoundToolHandler + 'static,
576    {
577        let name = name.into();
578        let description = description.map(Into::into);
579        let schema_object = input_schema.as_object().ok_or_else(|| {
580            McpError::Validation("tool input schema must be an object".to_string())
581        })?;
582        let info = ToolInfo {
583            name: name.clone(),
584            description,
585            input_schema: ToolInputSchema {
586                schema_type: schema_object
587                    .get("type")
588                    .and_then(Value::as_str)
589                    .unwrap_or("object")
590                    .to_string(),
591                properties: schema_object
592                    .get("properties")
593                    .and_then(Value::as_object)
594                    .map(|properties| {
595                        properties
596                            .iter()
597                            .map(|(key, value)| (key.clone(), value.clone()))
598                            .collect()
599                    }),
600                required: schema_object
601                    .get("required")
602                    .and_then(Value::as_array)
603                    .map(|required| {
604                        required
605                            .iter()
606                            .filter_map(Value::as_str)
607                            .map(str::to_string)
608                            .collect()
609                    }),
610                additional_properties: schema_object
611                    .iter()
612                    .filter(|(key, _)| !matches!(key.as_str(), "type" | "properties" | "required"))
613                    .map(|(key, value)| (key.clone(), value.clone()))
614                    .collect(),
615            },
616            output_schema: None,
617            annotations: None,
618            title: None,
619            icons: None,
620            meta: None,
621        };
622        validate_tool_info(&info)?;
623
624        self.tools.write().await.remove(&name);
625        self.task_tools.write().await.remove(&name);
626        self.multi_round_tools.write().await.insert(
627            name,
628            RegisteredMultiRoundTool {
629                info,
630                handler: Box::new(handler),
631            },
632        );
633        self.emit_tools_list_changed().await
634    }
635
636    /// Add a continuation-aware tool with a fully specified tool definition.
637    pub async fn add_multi_round_tool_detailed<H>(
638        &self,
639        info: ToolInfo,
640        handler: H,
641    ) -> McpResult<()>
642    where
643        H: MultiRoundToolHandler + 'static,
644    {
645        validate_tool_info(&info)?;
646        let name = info.name.clone();
647        self.tools.write().await.remove(&name);
648        self.task_tools.write().await.remove(&name);
649        self.multi_round_tools.write().await.insert(
650            name,
651            RegisteredMultiRoundTool {
652                info,
653                handler: Box::new(handler),
654            },
655        );
656        self.emit_tools_list_changed().await
657    }
658
659    /// Add a tool using a closure
660    ///
661    /// # Examples
662    ///
663    /// ```rust,ignore
664    /// server.add_tool_with_closure("echo", Some("Echo tool"), json!({}), |args| {
665    ///     Ok(vec![ContentBlock::text("Echo!")])
666    /// }).await?;
667    /// ```
668    pub async fn add_tool_with_closure<F>(
669        &self,
670        name: impl Into<String>,
671        description: Option<impl Into<String>>,
672        input_schema: Value,
673        handler: F,
674    ) -> McpResult<()>
675    where
676        F: Fn(&HashMap<String, Value>) -> McpResult<Vec<ContentBlock>> + Send + Sync + 'static,
677    {
678        let name = name.into();
679        let description = description.map(|d| d.into());
680        self.add_tool(name, description, input_schema, ClosureWrapper(handler))
681            .await
682    }
683
684    /// Add a tool using the ToolBuilder result
685    pub async fn add_tool_built(&self, tool: Tool) -> McpResult<()> {
686        let name = tool.info.name.clone();
687        self.multi_round_tools.write().await.remove(&name);
688        self.task_tools.write().await.remove(&name);
689        self.tools.write().await.insert(name, tool);
690        Ok(())
691    }
692
693    /// Register a tool whose execution is represented by a durable SEP-2663 task.
694    pub async fn add_task_tool<H>(&self, info: ToolInfo, handler: H) -> McpResult<()>
695    where
696        H: TaskToolHandler + 'static,
697    {
698        validate_tool_info(&info)?;
699        let name = info.name.clone();
700        self.tools.write().await.remove(&name);
701        self.multi_round_tools.write().await.remove(&name);
702        self.task_tools.write().await.insert(
703            name,
704            RegisteredTaskTool {
705                info,
706                execution: TaskExecution::Direct(Arc::new(handler)),
707                fallback: None,
708            },
709        );
710        self.emit_tools_list_changed().await
711    }
712
713    /// Register a durable task tool plus the synchronous behavior used when a
714    /// client has not negotiated `io.modelcontextprotocol/tasks`.
715    pub async fn add_task_tool_with_fallback<H, F>(
716        &self,
717        info: ToolInfo,
718        handler: H,
719        fallback: F,
720    ) -> McpResult<()>
721    where
722        H: TaskToolHandler + 'static,
723        F: ToolHandler + 'static,
724    {
725        validate_tool_info(&info)?;
726        let name = info.name.clone();
727        self.tools.write().await.remove(&name);
728        self.multi_round_tools.write().await.remove(&name);
729        self.task_tools.write().await.insert(
730            name,
731            RegisteredTaskTool {
732                info,
733                execution: TaskExecution::Direct(Arc::new(handler)),
734                fallback: Some(Arc::new(fallback)),
735            },
736        );
737        self.emit_tools_list_changed().await
738    }
739
740    /// Register a required-task tool that gathers request-scoped input through
741    /// MCP multi-round results before creating its durable task.
742    ///
743    /// The preflight handler returns `InputRequired` for intermediate rounds
744    /// and `Complete` when the durable phase may begin. Its completed value is
745    /// only a readiness signal; the composed handler produces the task result
746    /// and receives the entire final [`MultiRoundToolCall`].
747    pub async fn add_composed_task_tool<P, H>(
748        &self,
749        info: ToolInfo,
750        preflight: P,
751        handler: H,
752    ) -> McpResult<()>
753    where
754        P: MultiRoundToolHandler + 'static,
755        H: ComposedTaskToolHandler + 'static,
756    {
757        validate_tool_info(&info)?;
758        let name = info.name.clone();
759        self.tools.write().await.remove(&name);
760        self.multi_round_tools.write().await.remove(&name);
761        self.task_tools.write().await.insert(
762            name,
763            RegisteredTaskTool {
764                info,
765                execution: TaskExecution::Composed {
766                    preflight: Arc::new(preflight),
767                    handler: Arc::new(handler),
768                },
769                fallback: None,
770            },
771        );
772        self.emit_tools_list_changed().await
773    }
774    /// Get server information
775    pub fn info(&self) -> &ServerInfo {
776        &self.info
777    }
778
779    /// Get server name (for compatibility with tests)
780    pub fn name(&self) -> &str {
781        &self.info.name
782    }
783
784    /// Get server version (for compatibility with tests)
785    pub fn version(&self) -> &str {
786        &self.info.version
787    }
788
789    /// Get server capabilities
790    pub fn capabilities(&self) -> &ServerCapabilities {
791        &self.capabilities
792    }
793
794    /// Get server configuration
795    pub fn config(&self) -> &ServerConfig {
796        &self.config
797    }
798
799    // ========================================================================
800    // Resource Management
801    // ========================================================================
802
803    /// Add a resource to the server
804    pub async fn add_resource<H>(&self, name: String, uri: String, handler: H) -> McpResult<()>
805    where
806        H: ResourceHandler + 'static,
807    {
808        let resource_info = ResourceInfo {
809            uri: uri.clone(),
810            name: name.clone(),
811            description: None,
812            mime_type: None,
813            annotations: None,
814            size: None,
815            icons: None,
816            title: None,
817            meta: None,
818        };
819
820        validate_resource_info(&resource_info)?;
821
822        let resource = Resource::new(resource_info, handler);
823
824        {
825            let mut resources = self.resources.write().await;
826            resources.insert(uri, resource);
827        }
828
829        // Emit list changed notification if we have an active transport
830        self.emit_resources_list_changed().await?;
831
832        Ok(())
833    }
834
835    /// Add a resource with detailed information
836    pub async fn add_resource_detailed<H>(&self, info: ResourceInfo, handler: H) -> McpResult<()>
837    where
838        H: ResourceHandler + 'static,
839    {
840        validate_resource_info(&info)?;
841
842        let uri = info.uri.clone();
843        let resource = Resource::new(info, handler);
844
845        {
846            let mut resources = self.resources.write().await;
847            resources.insert(uri, resource);
848        }
849
850        self.emit_resources_list_changed().await?;
851
852        Ok(())
853    }
854
855    /// Remove a resource from the server
856    pub async fn remove_resource(&self, uri: &str) -> McpResult<bool> {
857        let removed = {
858            let mut resources = self.resources.write().await;
859            resources.remove(uri).is_some()
860        };
861
862        if removed {
863            self.emit_resources_list_changed().await?;
864        }
865
866        Ok(removed)
867    }
868
869    /// List all registered resources
870    pub async fn list_resources(&self) -> McpResult<Vec<ResourceInfo>> {
871        let resources = self.resources.read().await;
872        let mut values: Vec<_> = resources
873            .values()
874            .map(|resource| resource.info.clone())
875            .collect();
876        values.sort_by(|left, right| left.uri.cmp(&right.uri));
877        Ok(values)
878    }
879
880    /// Read a resource
881    pub async fn read_resource(&self, uri: &str) -> McpResult<Vec<ResourceContents>> {
882        let resources = self.resources.read().await;
883
884        match resources.get(uri) {
885            Some(resource) => {
886                let params = HashMap::new(); // URL parameter extraction will be implemented in future versions
887                resource.handler.read(uri, &params).await
888            }
889            None => Err(McpError::ResourceNotFound(uri.to_string())),
890        }
891    }
892
893    // ========================================================================
894    // Tool Management
895    // ========================================================================
896
897    /// Add a tool with detailed information
898    pub async fn add_tool_detailed<H>(&self, info: ToolInfo, handler: H) -> McpResult<()>
899    where
900        H: ToolHandler + 'static,
901    {
902        validate_tool_info(&info)?;
903
904        let name = info.name.clone();
905        let tool = Tool::new(
906            name.clone(),
907            info.description.clone(),
908            serde_json::to_value(&info.input_schema)?,
909            handler,
910        );
911
912        {
913            let mut tools = self.tools.write().await;
914            self.multi_round_tools.write().await.remove(&name);
915            self.task_tools.write().await.remove(&name);
916            tools.insert(name, tool);
917        }
918
919        self.emit_tools_list_changed().await?;
920
921        Ok(())
922    }
923
924    /// Remove a tool from the server
925    pub async fn remove_tool(&self, name: &str) -> McpResult<bool> {
926        let removed_regular = {
927            let mut tools = self.tools.write().await;
928            tools.remove(name).is_some()
929        };
930        let removed_multi_round = self.multi_round_tools.write().await.remove(name).is_some();
931        let removed_task = self.task_tools.write().await.remove(name).is_some();
932        let removed = removed_regular || removed_multi_round || removed_task;
933
934        if removed {
935            self.emit_tools_list_changed().await?;
936        }
937
938        Ok(removed)
939    }
940
941    /// List all registered tools
942    pub async fn list_tools(&self) -> McpResult<Vec<ToolInfo>> {
943        let tools = self.tools.read().await;
944        let mut values: Vec<_> = tools.values().map(|tool| tool.info.clone()).collect();
945        drop(tools);
946        values.extend(
947            self.multi_round_tools
948                .read()
949                .await
950                .values()
951                .map(|tool| tool.info.clone()),
952        );
953        values.extend(
954            self.task_tools
955                .read()
956                .await
957                .values()
958                .map(|tool| tool.info.clone()),
959        );
960        values.sort_by(|left, right| left.name.cmp(&right.name));
961        Ok(values)
962    }
963
964    /// Call a tool
965    pub async fn call_tool(
966        &self,
967        name: &str,
968        arguments: Option<HashMap<String, Value>>,
969    ) -> McpResult<ToolResult> {
970        let tools = self.tools.read().await;
971
972        match tools.get(name) {
973            Some(tool) => {
974                if !tool.enabled {
975                    return Err(McpError::ToolNotFound(format!("Tool '{name}' is disabled")));
976                }
977
978                let args = arguments.unwrap_or_default();
979                tool.handler.call(args).await
980            }
981            None => Err(McpError::ToolNotFound(name.to_string())),
982        }
983    }
984
985    // ========================================================================
986    // Prompt Management
987    // ========================================================================
988
989    /// Add a prompt to the server
990    pub async fn add_prompt<H>(&self, info: PromptInfo, handler: H) -> McpResult<()>
991    where
992        H: PromptHandler + 'static,
993    {
994        validate_prompt_info(&info)?;
995
996        let name = info.name.clone();
997        let prompt = Prompt::new(info, handler);
998
999        {
1000            let mut prompts = self.prompts.write().await;
1001            prompts.insert(name, prompt);
1002        }
1003
1004        self.emit_prompts_list_changed().await?;
1005
1006        Ok(())
1007    }
1008
1009    /// Remove a prompt from the server
1010    pub async fn remove_prompt(&self, name: &str) -> McpResult<bool> {
1011        let removed = {
1012            let mut prompts = self.prompts.write().await;
1013            prompts.remove(name).is_some()
1014        };
1015
1016        if removed {
1017            self.emit_prompts_list_changed().await?;
1018        }
1019
1020        Ok(removed)
1021    }
1022
1023    /// List all registered prompts
1024    pub async fn list_prompts(&self) -> McpResult<Vec<PromptInfo>> {
1025        let prompts = self.prompts.read().await;
1026        let mut values: Vec<_> = prompts.values().map(|prompt| prompt.info.clone()).collect();
1027        values.sort_by(|left, right| left.name.cmp(&right.name));
1028        Ok(values)
1029    }
1030
1031    /// Get a prompt
1032    pub async fn get_prompt(
1033        &self,
1034        name: &str,
1035        arguments: Option<HashMap<String, Value>>,
1036    ) -> McpResult<PromptResult> {
1037        let prompts = self.prompts.read().await;
1038
1039        match prompts.get(name) {
1040            Some(prompt) => {
1041                let args = arguments.unwrap_or_default();
1042                prompt.handler.get(args).await
1043            }
1044            None => Err(McpError::PromptNotFound(name.to_string())),
1045        }
1046    }
1047
1048    // ========================================================================
1049    // Resource Template Management (New in 2025-11-25)
1050    // ========================================================================
1051
1052    /// Add a resource template to the server
1053    pub async fn add_resource_template(&self, template: ResourceTemplate) -> McpResult<()> {
1054        let name = template.name.clone();
1055        {
1056            let mut templates = self.resource_templates.write().await;
1057            templates.insert(name, template);
1058        }
1059
1060        // Emit notification if supported
1061        self.emit_resource_templates_list_changed().await?;
1062        Ok(())
1063    }
1064
1065    /// List resource templates
1066    pub async fn list_resource_templates(&self) -> McpResult<Vec<ResourceTemplate>> {
1067        let templates = self.resource_templates.read().await;
1068        let mut values: Vec<_> = templates.values().cloned().collect();
1069        values.sort_by(|left, right| left.uri_template.cmp(&right.uri_template));
1070        Ok(values)
1071    }
1072
1073    /// Remove a resource template
1074    pub async fn remove_resource_template(&self, name: &str) -> McpResult<bool> {
1075        let removed = {
1076            let mut templates = self.resource_templates.write().await;
1077            templates.remove(name).is_some()
1078        };
1079
1080        if removed {
1081            self.emit_resource_templates_list_changed().await?;
1082        }
1083
1084        Ok(removed)
1085    }
1086
1087    /// Emit resource templates list changed notification
1088    async fn emit_resource_templates_list_changed(&self) -> McpResult<()> {
1089        // In a real implementation, this would send a notification
1090        // For now, we'll just return Ok
1091        Ok(())
1092    }
1093
1094    // ========================================================================
1095    // Completion Management (New in 2025-11-25)
1096    // ========================================================================
1097
1098    /// Add completion handler for a specific reference type
1099    pub async fn add_completion_handler<H>(&self, ref_type: String, handler: H) -> McpResult<()>
1100    where
1101        H: CompletionHandler + 'static,
1102    {
1103        let mut handlers = self.completion_handlers.write().await;
1104        handlers.insert(ref_type, Box::new(handler));
1105        Ok(())
1106    }
1107
1108    /// Remove completion handler for a reference type
1109    pub async fn remove_completion_handler(&self, ref_type: &str) -> McpResult<bool> {
1110        let mut handlers = self.completion_handlers.write().await;
1111        Ok(handlers.remove(ref_type).is_some())
1112    }
1113
1114    /// Handle completion request
1115    pub async fn handle_completion(
1116        &self,
1117        reference: &CompletionReference,
1118        argument: &CompletionArgument,
1119        context: Option<&CompletionContext>,
1120    ) -> McpResult<Vec<String>> {
1121        let ref_type = match reference {
1122            CompletionReference::Prompt { .. } => "ref/prompt",
1123            CompletionReference::Resource { .. } => "ref/resource",
1124            CompletionReference::Tool { .. } => "ref/tool",
1125        };
1126
1127        let handlers = self.completion_handlers.read().await;
1128        if let Some(handler) = handlers.get(ref_type) {
1129            handler.complete(reference, argument, context).await
1130        } else {
1131            // Return empty completions if no handler is registered
1132            Ok(vec![])
1133        }
1134    }
1135
1136    // ========================================================================
1137    // Bidirectional Communication (New in 2025-11-25)
1138    // ========================================================================
1139
1140    /// Send a request to the client (server-initiated)
1141    pub async fn send_client_request(
1142        &self,
1143        _request: JsonRpcRequest,
1144    ) -> McpResult<JsonRpcResponse> {
1145        let mut transport_guard = self.transport.lock().await;
1146        if let Some(_transport) = transport_guard.as_mut() {
1147            // For now, return an error - this would need transport-specific implementation
1148            Err(McpError::MethodNotFound(
1149                "Bidirectional communication not yet fully implemented".to_string(),
1150            ))
1151        } else {
1152            Err(McpError::Transport("Not connected".to_string()))
1153        }
1154    }
1155
1156    /// Request LLM sampling from client
1157    pub async fn request_sampling(
1158        &self,
1159        params: CreateMessageParams,
1160    ) -> McpResult<CreateMessageResult> {
1161        let request = JsonRpcRequest::new(
1162            Value::from(self.next_request_id().await),
1163            methods::SAMPLING_CREATE_MESSAGE.to_string(),
1164            Some(params),
1165        )?;
1166
1167        let response = self.send_client_request(request).await?;
1168
1169        if let Some(result) = response.result {
1170            Ok(serde_json::from_value(result)?)
1171        } else {
1172            Err(McpError::Protocol("No result in response".to_string()))
1173        }
1174    }
1175
1176    /// Request root directories from client
1177    pub async fn request_roots(&self) -> McpResult<ListRootsResult> {
1178        let request = JsonRpcRequest::new(
1179            Value::from(self.next_request_id().await),
1180            methods::ROOTS_LIST.to_string(),
1181            Some(ListRootsParams { meta: None }),
1182        )?;
1183
1184        let response = self.send_client_request(request).await?;
1185
1186        if let Some(result) = response.result {
1187            Ok(serde_json::from_value(result)?)
1188        } else {
1189            Err(McpError::Protocol("No result in response".to_string()))
1190        }
1191    }
1192
1193    /// Request user input via elicitation
1194    pub async fn request_elicitation(&self, params: ElicitParams) -> McpResult<ElicitResult> {
1195        let request = JsonRpcRequest::new(
1196            Value::from(self.next_request_id().await),
1197            methods::ELICITATION_CREATE.to_string(),
1198            Some(params),
1199        )?;
1200
1201        let response = self.send_client_request(request).await?;
1202
1203        if let Some(result) = response.result {
1204            Ok(serde_json::from_value(result)?)
1205        } else {
1206            Err(McpError::Protocol("No result in response".to_string()))
1207        }
1208    }
1209
1210    /// Request list of roots from the client
1211    ///
1212    /// Method allows the server to request access to specific directories
1213    /// or files on the client's file system.
1214    pub async fn request_list_roots(&self) -> McpResult<ListRootsResult> {
1215        let request = JsonRpcRequest::new(
1216            Value::from(self.next_request_id().await),
1217            methods::ROOTS_LIST.to_string(),
1218            None::<serde_json::Value>,
1219        )?;
1220
1221        let response = self.send_client_request(request).await?;
1222
1223        if let Some(result) = response.result {
1224            Ok(serde_json::from_value(result)?)
1225        } else {
1226            Err(McpError::Protocol("No result in response".to_string()))
1227        }
1228    }
1229
1230    /// Send a notification that the roots list has changed
1231    ///
1232    /// This notification informs the client that the list of roots
1233    /// the server needs access to has changed.
1234    pub async fn notify_roots_list_changed(&self) -> McpResult<()> {
1235        let notification = JsonRpcNotification {
1236            jsonrpc: "2.0".to_string(),
1237            method: methods::ROOTS_LIST_CHANGED.to_string(),
1238            params: None,
1239        };
1240
1241        if let Some(ref mut transport) = *self.transport.lock().await {
1242            transport.send_notification(notification).await
1243        } else {
1244            Err(McpError::Connection("No transport available".to_string()))
1245        }
1246    }
1247
1248    /// Notify active MCP 2026 subscriptions that the tool catalog changed.
1249    pub async fn notify_tools_list_changed(&self) -> McpResult<()> {
1250        self.emit_tools_list_changed().await
1251    }
1252
1253    /// Notify active MCP 2026 subscriptions that the prompt catalog changed.
1254    pub async fn notify_prompts_list_changed(&self) -> McpResult<()> {
1255        self.emit_prompts_list_changed().await
1256    }
1257
1258    /// Notify active MCP 2026 subscriptions that the resource catalog changed.
1259    pub async fn notify_resources_list_changed(&self) -> McpResult<()> {
1260        self.emit_resources_list_changed().await
1261    }
1262
1263    // ========================================================================
1264    // Server Lifecycle
1265    // ========================================================================
1266
1267    /// Start the server with the given transport
1268    pub async fn start<T>(&mut self, mut transport: T) -> McpResult<()>
1269    where
1270        T: ServerTransport + 'static,
1271    {
1272        let mut state = self.state.write().await;
1273
1274        match *state {
1275            ServerState::Uninitialized => {
1276                *state = ServerState::Initializing;
1277            }
1278            _ => return Err(McpError::Protocol("Server is already started".to_string())),
1279        }
1280
1281        drop(state);
1282
1283        transport.set_server_capabilities(self.modern_capabilities().await)?;
1284        transport.set_task_notifications(self.task_registry.subscribe())?;
1285
1286        let tool_schemas = {
1287            let tools = self.tools.read().await;
1288            let mut schemas = tools
1289                .iter()
1290                .map(|(name, tool)| {
1291                    serde_json::to_value(&tool.info.input_schema)
1292                        .map(|schema| (name.clone(), schema))
1293                        .map_err(McpError::from)
1294                })
1295                .collect::<McpResult<HashMap<_, _>>>()?;
1296            drop(tools);
1297            for (name, tool) in self.multi_round_tools.read().await.iter() {
1298                schemas.insert(name.clone(), serde_json::to_value(&tool.info.input_schema)?);
1299            }
1300            for (name, tool) in self.task_tools.read().await.iter() {
1301                schemas.insert(name.clone(), serde_json::to_value(&tool.info.input_schema)?);
1302            }
1303            schemas
1304        };
1305        transport.set_tool_schemas(tool_schemas)?;
1306
1307        // Create a request handler that delegates to this server
1308        let resources = self.resources.clone();
1309        let tools = self.tools.clone();
1310        let multi_round_tools = self.multi_round_tools.clone();
1311        let task_tools = self.task_tools.clone();
1312        let task_registry = self.task_registry.clone();
1313        let prompts = self.prompts.clone();
1314        let resource_templates = self.resource_templates.clone();
1315        let completion_handlers = self.completion_handlers.clone();
1316        let info = self.info.clone();
1317        let capabilities = self.capabilities.clone();
1318        let config = self.config.clone();
1319        let request_policy = self.request_policy.clone();
1320        let protocol_mode = self.protocol_mode;
1321
1322        let request_handler: crate::transport::traits::ServerRequestHandler =
1323            Arc::new(move |request| {
1324                let resources = resources.clone();
1325                let tools = tools.clone();
1326                let multi_round_tools = multi_round_tools.clone();
1327                let task_tools = task_tools.clone();
1328                let task_registry = task_registry.clone();
1329                let prompts = prompts.clone();
1330                let resource_templates = resource_templates.clone();
1331                let completion_handlers = completion_handlers.clone();
1332                let info = info.clone();
1333                let capabilities = capabilities.clone();
1334                let config = config.clone();
1335                let request_policy = request_policy.clone();
1336                Box::pin(async move {
1337                    // Create a temporary server instance to handle the request
1338                    let temp_server = McpServer {
1339                        info,
1340                        capabilities,
1341                        config,
1342                        resources,
1343                        tools,
1344                        multi_round_tools,
1345                        task_tools,
1346                        task_registry,
1347                        prompts,
1348                        resource_templates,
1349                        completion_handlers,
1350                        transport: Arc::new(Mutex::new(None)),
1351                        state: Arc::new(RwLock::new(ServerState::Running)),
1352                        request_counter: Arc::new(Mutex::new(0)),
1353                        request_policy,
1354                        protocol_mode,
1355                        #[cfg(feature = "plugin")]
1356                        plugin_manager: None,
1357                    };
1358                    temp_server.handle_request(request).await
1359                })
1360            });
1361
1362        // Set the request handler on the transport
1363        transport.set_request_handler(request_handler);
1364
1365        // Set up the transport
1366        {
1367            let mut transport_guard = self.transport.lock().await;
1368            *transport_guard = Some(Box::new(transport));
1369        }
1370
1371        // Start the transport
1372        {
1373            let mut transport_guard = self.transport.lock().await;
1374            if let Some(transport) = transport_guard.as_mut() {
1375                transport.start().await?;
1376            }
1377        }
1378
1379        // Update state to running
1380        {
1381            let mut state = self.state.write().await;
1382            *state = ServerState::Running;
1383        }
1384
1385        Ok(())
1386    }
1387
1388    /// Stop the server
1389    pub async fn stop(&self) -> McpResult<()> {
1390        let mut state = self.state.write().await;
1391
1392        match *state {
1393            ServerState::Running => {
1394                *state = ServerState::Stopping;
1395            }
1396            ServerState::Stopped => return Ok(()),
1397            _ => return Err(McpError::Protocol("Server is not running".to_string())),
1398        }
1399
1400        drop(state);
1401
1402        // Stop the transport
1403        {
1404            let mut transport_guard = self.transport.lock().await;
1405            if let Some(transport) = transport_guard.as_mut() {
1406                transport.stop().await?;
1407            }
1408        }
1409
1410        // Update state to stopped
1411        {
1412            let mut state = self.state.write().await;
1413            *state = ServerState::Stopped;
1414        }
1415
1416        Ok(())
1417    }
1418
1419    /// Check if the server is running
1420    pub async fn is_running(&self) -> bool {
1421        let state = self.state.read().await;
1422        matches!(*state, ServerState::Running)
1423    }
1424
1425    /// Get the current server state
1426    pub async fn state(&self) -> ServerState {
1427        let state = self.state.read().await;
1428        state.clone()
1429    }
1430
1431    /// Start server with custom transport and run until interrupted
1432    ///
1433    /// This is a convenience method that:
1434    /// 1. Starts the server with the provided transport
1435    /// 2. Waits for Ctrl+C signal
1436    /// 3. smoothly shuts down the server
1437    ///
1438    /// # Arguments
1439    /// * `transport` - The transport to use for communication
1440    ///
1441    /// # Example
1442    /// ```rust,ignore
1443    /// use prism_mcp_rs::prelude::*;
1444    ///
1445    /// #[cfg(feature = "stdio")]
1446    /// use prism_mcp_rs::transport::stdio::StdioServerTransport;
1447    ///
1448    /// #[tokio::main]
1449    /// async fn main() -> McpResult<()> {
1450    ///     let mut server = McpServer::new("my-server".to_string(), "1.0.0".to_string());
1451    ///     // . add tools, resources, prompts ...
1452    ///
1453    ///     #[cfg(feature = "stdio")]
1454    ///     {
1455    ///         let transport = StdioServerTransport::new();
1456    ///         server.run_with_transport(transport).await?;
1457    ///     }
1458    ///     
1459    ///     Ok(())
1460    /// }
1461    /// ```
1462    pub async fn run_with_transport<T>(mut self, transport: T) -> McpResult<()>
1463    where
1464        T: ServerTransport + 'static,
1465    {
1466        self.start(transport).await?;
1467
1468        tracing::info!("Server started. Press Ctrl+C to stop.");
1469
1470        // Wait for shutdown signal
1471        tokio::signal::ctrl_c()
1472            .await
1473            .map_err(|e| McpError::internal(format!("Signal handling error: {e}")))?;
1474
1475        tracing::info!("Shutdown signal received, stopping server...");
1476        self.stop().await
1477    }
1478
1479    // ========================================================================
1480    // Request Handling
1481    // ========================================================================
1482    /// Handle an incoming JSON-RPC request
1483    pub async fn handle_request(&self, request: JsonRpcRequest) -> McpResult<JsonRpcResponse> {
1484        self.handle_request_with_context(request, RequestContext::anonymous())
1485            .await
1486    }
1487
1488    /// Handle a request with transport-supplied identity and correlation data.
1489    ///
1490    /// Custom transports and authentication middleware should call this method
1491    /// after validating credentials and constructing a [`RequestContext`].
1492    pub async fn handle_request_with_context(
1493        &self,
1494        request: JsonRpcRequest,
1495        context: RequestContext,
1496    ) -> McpResult<JsonRpcResponse> {
1497        let target = request_target(&request);
1498        let method = request.method.clone();
1499        let principal = context.principal.id.clone();
1500        let request_id = context.request_id.clone();
1501        let transport = context.transport.clone();
1502        let span = tracing::info_span!(
1503            "mcp.request",
1504            request.id = %request_id,
1505            rpc.method = %method,
1506            principal.id = %principal,
1507            transport = %transport,
1508            otel.kind = "server"
1509        );
1510
1511        async move {
1512            let started_at = std::time::Instant::now();
1513            if let Err(error) = self.request_policy.enforce(&context, &target).await {
1514                tracing::warn!(
1515                    event = "security.policy_denied",
1516                    error.category = error.category(),
1517                    error = %error,
1518                    "request rejected by production policy"
1519                );
1520                return Err(error);
1521            }
1522
1523            // Validate the request if configured to do so
1524            let modern_context = match modern_request_context(&request) {
1525                Err(McpError::UnsupportedProtocolVersion { requested, .. }) => {
1526                    let supported = match self.protocol_mode {
1527                        ProtocolMode::Auto => SUPPORTED_PROTOCOL_VERSIONS
1528                            .iter()
1529                            .map(|version| (*version).to_string())
1530                            .collect(),
1531                        ProtocolMode::ModernOnly => vec![MODERN_PROTOCOL_VERSION.to_string()],
1532                        ProtocolMode::LegacyOnly => vec![LEGACY_PROTOCOL_VERSION.to_string()],
1533                    };
1534                    return Err(McpError::UnsupportedProtocolVersion {
1535                        requested,
1536                        supported,
1537                    });
1538                }
1539                result => result?,
1540            };
1541            let is_modern = modern_context.is_some();
1542            if request.method == methods::SERVER_DISCOVER && !is_modern {
1543                return Err(McpError::Validation(
1544                    "server/discover requires MCP 2026 request metadata".to_string(),
1545                ));
1546            }
1547            match self.protocol_mode {
1548                ProtocolMode::ModernOnly if !is_modern => {
1549                    return Err(McpError::UnsupportedProtocolVersion {
1550                        requested: LEGACY_PROTOCOL_VERSION.to_string(),
1551                        supported: vec![MODERN_PROTOCOL_VERSION.to_string()],
1552                    });
1553                }
1554                ProtocolMode::LegacyOnly if is_modern => {
1555                    return Err(McpError::UnsupportedProtocolVersion {
1556                        requested: MODERN_PROTOCOL_VERSION.to_string(),
1557                        supported: vec![LEGACY_PROTOCOL_VERSION.to_string()],
1558                    });
1559                }
1560                _ => {}
1561            }
1562            if is_modern && is_legacy_only_method(&request.method) {
1563                return Err(McpError::MethodNotFound(format!(
1564                    "{} is unavailable in MCP {MODERN_PROTOCOL_VERSION}",
1565                    request.method
1566                )));
1567            }
1568
1569            if self.config.validate_requests {
1570                validate_jsonrpc_request(&request)?;
1571                validate_mcp_request(&request.method, request.params.as_ref())?;
1572            }
1573
1574            // Route the request to the appropriate handler
1575            let result = match request.method.as_str() {
1576                methods::INITIALIZE => self.handle_initialize(request.params).await,
1577                methods::SERVER_DISCOVER => self.handle_server_discover().await,
1578                methods::PING => self.handle_ping().await,
1579                methods::TOOLS_LIST => self.handle_tools_list(request.params).await,
1580                methods::TOOLS_CALL => {
1581                    self.handle_tools_call(request.params, modern_context.as_ref(), &context)
1582                        .await
1583                }
1584                methods::TASKS_GET => {
1585                    self.handle_tasks_get(request.params, modern_context.as_ref(), &context)
1586                        .await
1587                }
1588                methods::TASKS_UPDATE => {
1589                    self.handle_tasks_update(request.params, modern_context.as_ref(), &context)
1590                        .await
1591                }
1592                methods::TASKS_CANCEL => {
1593                    self.handle_tasks_cancel(request.params, modern_context.as_ref(), &context)
1594                        .await
1595                }
1596                methods::RESOURCES_LIST => self.handle_resources_list(request.params).await,
1597                methods::RESOURCES_READ => self.handle_resources_read(request.params).await,
1598                methods::RESOURCES_SUBSCRIBE => {
1599                    self.handle_resources_subscribe(request.params).await
1600                }
1601                methods::RESOURCES_UNSUBSCRIBE => {
1602                    self.handle_resources_unsubscribe(request.params).await
1603                }
1604                methods::PROMPTS_LIST => self.handle_prompts_list(request.params).await,
1605                methods::PROMPTS_GET => self.handle_prompts_get(request.params).await,
1606                methods::RESOURCES_TEMPLATES_LIST => {
1607                    self.handle_resource_templates_list(request.params).await
1608                }
1609                methods::COMPLETION_COMPLETE => {
1610                    self.handle_completion_complete(request.params).await
1611                }
1612                methods::LOGGING_SET_LEVEL => self.handle_logging_set_level(request.params).await,
1613                methods::RPC_DISCOVER => self.handle_rpc_discover(request.params).await,
1614                _ => {
1615                    let method = &request.method;
1616                    Err(McpError::MethodNotFound(format!(
1617                        "Unknown method: {method}"
1618                    )))
1619                }
1620            };
1621
1622            // Convert the result to a JSON-RPC response
1623            let response = match result {
1624                Ok(result_value) => {
1625                    let result_value = if is_modern {
1626                        decorate_modern_result(&request.method, result_value, &self.info)?
1627                    } else {
1628                        result_value
1629                    };
1630                    Ok(JsonRpcResponse::success(request.id, result_value)?)
1631                }
1632                Err(error @ McpError::Forbidden(_)) => Err(error),
1633                Err(error @ McpError::RateLimited { .. }) => Err(error),
1634                Err(error) => Err(error),
1635            };
1636
1637            tracing::info!(
1638                event = "security.request_audit",
1639                outcome = if response.is_ok() { "allowed" } else { "error" },
1640                duration_ms = started_at.elapsed().as_millis() as u64,
1641                "request completed"
1642            );
1643            response
1644        }
1645        .instrument(span)
1646        .await
1647    }
1648
1649    // ========================================================================
1650    // Individual Request Handlers
1651    // ========================================================================
1652
1653    async fn handle_initialize(&self, params: Option<Value>) -> McpResult<Value> {
1654        let params: InitializeParams = match params {
1655            Some(p) => serde_json::from_value(p)?,
1656            None => {
1657                return Err(McpError::Validation(
1658                    "Missing initialize parameters".to_string(),
1659                ));
1660            }
1661        };
1662
1663        validate_initialize_params(&params)?;
1664        if params.protocol_version != LEGACY_PROTOCOL_VERSION {
1665            return Err(McpError::UnsupportedProtocolVersion {
1666                requested: params.protocol_version,
1667                supported: vec![LEGACY_PROTOCOL_VERSION.to_string()],
1668            });
1669        }
1670
1671        let result = InitializeResult::new(
1672            LEGACY_PROTOCOL_VERSION.to_string(),
1673            self.capabilities.clone(),
1674            self.info.clone(),
1675        );
1676
1677        Ok(serde_json::to_value(result)?)
1678    }
1679
1680    async fn handle_server_discover(&self) -> McpResult<Value> {
1681        let supported_versions: Vec<&str> = match self.protocol_mode {
1682            ProtocolMode::Auto => SUPPORTED_PROTOCOL_VERSIONS.to_vec(),
1683            ProtocolMode::ModernOnly => vec![MODERN_PROTOCOL_VERSION],
1684            ProtocolMode::LegacyOnly => vec![LEGACY_PROTOCOL_VERSION],
1685        };
1686        Ok(serde_json::json!({
1687            "supportedVersions": supported_versions,
1688            "capabilities": self.modern_capabilities().await,
1689            "instructions": self.config.enable_logging.then_some(
1690                "Prism MCP server with stateless 2026 and legacy 2025 interoperability"
1691            )
1692        }))
1693    }
1694
1695    async fn modern_capabilities(&self) -> ServerCapabilities {
1696        let mut capabilities = self.capabilities.clone();
1697        if let Some(tools) = capabilities.tools.as_mut() {
1698            tools.list_changed = Some(true);
1699        }
1700        if let Some(prompts) = capabilities.prompts.as_mut() {
1701            prompts.list_changed = Some(true);
1702        }
1703        if let Some(resources) = capabilities.resources.as_mut() {
1704            resources.list_changed = Some(true);
1705        }
1706        if !self.task_tools.read().await.is_empty() {
1707            capabilities
1708                .extensions
1709                .get_or_insert_with(HashMap::new)
1710                .insert(TASKS_EXTENSION_ID.to_string(), serde_json::json!({}));
1711        }
1712        capabilities
1713    }
1714
1715    async fn handle_ping(&self) -> McpResult<Value> {
1716        Ok(serde_json::to_value(PingResult { meta: None })?)
1717    }
1718
1719    async fn handle_tools_list(&self, params: Option<Value>) -> McpResult<Value> {
1720        let _params: ListToolsParams = match params {
1721            Some(p) => serde_json::from_value(p)?,
1722            None => ListToolsParams::default(),
1723        };
1724
1725        let tools = self.list_tools().await?;
1726        let result = ListToolsResult {
1727            tools,
1728            next_cursor: None, // Pagination support will be added in future versions
1729            meta: None,
1730        };
1731
1732        Ok(serde_json::to_value(result)?)
1733    }
1734
1735    async fn handle_tools_call(
1736        &self,
1737        params: Option<Value>,
1738        modern_context: Option<&ModernRequestContext>,
1739        request_context: &RequestContext,
1740    ) -> McpResult<Value> {
1741        let raw_params = match params {
1742            Some(params) => params,
1743            None => {
1744                return Err(McpError::Validation(
1745                    "Missing tool call parameters".to_string(),
1746                ));
1747            }
1748        };
1749        let params: CallToolParams = serde_json::from_value(raw_params.clone())?;
1750
1751        validate_call_tool_params(&params)?;
1752
1753        let task_tool = self.task_tools.read().await.get(&params.name).cloned();
1754        if let Some(tool) = task_tool {
1755            let tasks_negotiated = modern_context
1756                .map(|context| has_tasks_extension(&context.client_capabilities))
1757                .unwrap_or(false);
1758            if !tasks_negotiated {
1759                if let Some(fallback) = &tool.fallback {
1760                    return Ok(serde_json::to_value(
1761                        fallback.call(params.arguments.unwrap_or_default()).await?,
1762                    )?);
1763                }
1764                return Err(tasks_capability_error());
1765            }
1766            let task = match tool.execution {
1767                TaskExecution::Direct(handler) => {
1768                    self.task_registry
1769                        .create(
1770                            request_context.principal.id.clone(),
1771                            params.arguments.unwrap_or_default(),
1772                            handler,
1773                        )
1774                        .await?
1775                }
1776                TaskExecution::Composed { preflight, handler } => {
1777                    let call = parse_multi_round_tool_call(
1778                        &raw_params,
1779                        params.arguments.unwrap_or_default(),
1780                        modern_context,
1781                    )?;
1782                    match preflight.call(call.clone()).await? {
1783                        OperationResult::Complete(_) => {
1784                            self.task_registry
1785                                .create_composed(
1786                                    request_context.principal.id.clone(),
1787                                    call,
1788                                    handler,
1789                                )
1790                                .await?
1791                        }
1792                        OperationResult::InputRequired(result) => {
1793                            validate_input_required_result(&result, &call.client_capabilities)?;
1794                            return Ok(serde_json::to_value(result)?);
1795                        }
1796                    }
1797                }
1798            };
1799            return Ok(serde_json::to_value(CreateTaskResult {
1800                result_type: "task".to_string(),
1801                task,
1802                meta: HashMap::new(),
1803            })?);
1804        }
1805
1806        if let Some(tool) = self.multi_round_tools.read().await.get(&params.name) {
1807            let call = parse_multi_round_tool_call(
1808                &raw_params,
1809                params.arguments.unwrap_or_default(),
1810                modern_context,
1811            )?;
1812            let client_capabilities = call.client_capabilities.clone();
1813            return match tool.handler.call(call).await? {
1814                OperationResult::Complete(result) => Ok(serde_json::to_value(result)?),
1815                OperationResult::InputRequired(result) if modern_context.is_some() => {
1816                    validate_input_required_result(&result, &client_capabilities)?;
1817                    Ok(serde_json::to_value(result)?)
1818                }
1819                OperationResult::InputRequired(_) => Err(McpError::Protocol(
1820                    "input_required is unavailable in MCP 2025-11-25".to_string(),
1821                )),
1822            };
1823        }
1824
1825        let result = self.call_tool(&params.name, params.arguments).await?;
1826        Ok(serde_json::to_value(result)?)
1827    }
1828
1829    fn require_tasks_context<'a>(
1830        &self,
1831        modern_context: Option<&'a ModernRequestContext>,
1832    ) -> McpResult<&'a ClientCapabilities> {
1833        let capabilities = modern_context
1834            .map(|context| &context.client_capabilities)
1835            .ok_or_else(tasks_capability_error)?;
1836        if !has_tasks_extension(capabilities) {
1837            return Err(tasks_capability_error());
1838        }
1839        Ok(capabilities)
1840    }
1841
1842    async fn handle_tasks_get(
1843        &self,
1844        params: Option<Value>,
1845        modern_context: Option<&ModernRequestContext>,
1846        context: &RequestContext,
1847    ) -> McpResult<Value> {
1848        self.require_tasks_context(modern_context)?;
1849        let params: GetTaskParams = serde_json::from_value(
1850            params.ok_or_else(|| McpError::InvalidParams("Missing taskId".to_string()))?,
1851        )?;
1852        let task = self
1853            .task_registry
1854            .get(&params.task_id, &context.principal.id)
1855            .await?;
1856        Ok(serde_json::to_value(GetTaskResult {
1857            result_type: "complete".to_string(),
1858            task,
1859            meta: HashMap::new(),
1860        })?)
1861    }
1862
1863    async fn handle_tasks_update(
1864        &self,
1865        params: Option<Value>,
1866        modern_context: Option<&ModernRequestContext>,
1867        context: &RequestContext,
1868    ) -> McpResult<Value> {
1869        self.require_tasks_context(modern_context)?;
1870        let params: UpdateTaskParams = serde_json::from_value(
1871            params.ok_or_else(|| McpError::InvalidParams("Missing task update".to_string()))?,
1872        )?;
1873        self.task_registry
1874            .update(
1875                &params.task_id,
1876                &context.principal.id,
1877                params.input_responses,
1878            )
1879            .await?;
1880        Ok(serde_json::to_value(TaskAcknowledgement {
1881            result_type: "complete".to_string(),
1882            meta: HashMap::new(),
1883        })?)
1884    }
1885
1886    async fn handle_tasks_cancel(
1887        &self,
1888        params: Option<Value>,
1889        modern_context: Option<&ModernRequestContext>,
1890        context: &RequestContext,
1891    ) -> McpResult<Value> {
1892        self.require_tasks_context(modern_context)?;
1893        let params: CancelTaskParams = serde_json::from_value(
1894            params.ok_or_else(|| McpError::InvalidParams("Missing taskId".to_string()))?,
1895        )?;
1896        self.task_registry
1897            .cancel(&params.task_id, &context.principal.id)
1898            .await?;
1899        Ok(serde_json::to_value(TaskAcknowledgement {
1900            result_type: "complete".to_string(),
1901            meta: HashMap::new(),
1902        })?)
1903    }
1904
1905    async fn handle_resources_list(&self, params: Option<Value>) -> McpResult<Value> {
1906        let _params: ListResourcesParams = match params {
1907            Some(p) => serde_json::from_value(p)?,
1908            None => ListResourcesParams::default(),
1909        };
1910
1911        let resources = self.list_resources().await?;
1912        let result = ListResourcesResult {
1913            resources,
1914            next_cursor: None, // Pagination support will be added in future versions
1915            meta: None,
1916        };
1917
1918        Ok(serde_json::to_value(result)?)
1919    }
1920
1921    async fn handle_resources_read(&self, params: Option<Value>) -> McpResult<Value> {
1922        let params: ReadResourceParams = match params {
1923            Some(p) => serde_json::from_value(p)?,
1924            None => {
1925                return Err(McpError::Validation(
1926                    "Missing resource read parameters".to_string(),
1927                ));
1928            }
1929        };
1930
1931        validate_read_resource_params(&params)?;
1932
1933        let contents = self.read_resource(&params.uri).await?;
1934        let result = ReadResourceResult {
1935            contents,
1936            meta: None,
1937        };
1938
1939        Ok(serde_json::to_value(result)?)
1940    }
1941
1942    async fn handle_resources_subscribe(&self, params: Option<Value>) -> McpResult<Value> {
1943        let resources = self.resources.read().await;
1944        let result =
1945            crate::server::handlers::ResourceHandler::handle_subscribe(&resources, params).await?;
1946        Ok(serde_json::to_value(result)?)
1947    }
1948
1949    async fn handle_resources_unsubscribe(&self, params: Option<Value>) -> McpResult<Value> {
1950        let resources = self.resources.read().await;
1951        let result =
1952            crate::server::handlers::ResourceHandler::handle_unsubscribe(&resources, params)
1953                .await?;
1954        Ok(serde_json::to_value(result)?)
1955    }
1956
1957    async fn handle_prompts_list(&self, params: Option<Value>) -> McpResult<Value> {
1958        let _params: ListPromptsParams = match params {
1959            Some(p) => serde_json::from_value(p)?,
1960            None => ListPromptsParams::default(),
1961        };
1962
1963        let prompts = self.list_prompts().await?;
1964        let result = ListPromptsResult {
1965            prompts,
1966            next_cursor: None, // Pagination support will be added in future versions
1967            meta: None,
1968        };
1969
1970        Ok(serde_json::to_value(result)?)
1971    }
1972
1973    async fn handle_prompts_get(&self, params: Option<Value>) -> McpResult<Value> {
1974        let params: GetPromptParams = match params {
1975            Some(p) => serde_json::from_value(p)?,
1976            None => {
1977                return Err(McpError::Validation(
1978                    "Missing prompt get parameters".to_string(),
1979                ));
1980            }
1981        };
1982
1983        validate_get_prompt_params(&params)?;
1984
1985        let arguments = params.arguments.map(|args| {
1986            args.into_iter()
1987                .map(|(k, v)| (k, serde_json::Value::String(v)))
1988                .collect()
1989        });
1990        let result = self.get_prompt(&params.name, arguments).await?;
1991        Ok(serde_json::to_value(result)?)
1992    }
1993
1994    async fn handle_logging_set_level(&self, params: Option<Value>) -> McpResult<Value> {
1995        let _params: SetLoggingLevelParams = match params {
1996            Some(p) => serde_json::from_value(p)?,
1997            None => {
1998                return Err(McpError::Validation(
1999                    "Missing logging level parameters".to_string(),
2000                ));
2001            }
2002        };
2003
2004        // Logging level management feature planned for future implementation
2005        let result = SetLoggingLevelResult { meta: None };
2006        Ok(serde_json::to_value(result)?)
2007    }
2008
2009    /// Handle resource templates list request (New in 2025-11-25)
2010    async fn handle_resource_templates_list(&self, params: Option<Value>) -> McpResult<Value> {
2011        let _params: ListResourceTemplatesParams = match params {
2012            Some(p) => serde_json::from_value(p)?,
2013            None => ListResourceTemplatesParams::default(),
2014        };
2015
2016        let templates = self.list_resource_templates().await?;
2017        let result = ListResourceTemplatesResult {
2018            resource_templates: templates,
2019            next_cursor: None, // Pagination support will be added in future versions
2020            meta: None,
2021        };
2022
2023        Ok(serde_json::to_value(result)?)
2024    }
2025
2026    /// Handle completion request (New in 2025-11-25)
2027    async fn handle_completion_complete(&self, params: Option<Value>) -> McpResult<Value> {
2028        let params: CompleteParams = match params {
2029            Some(p) => serde_json::from_value(p)?,
2030            None => {
2031                return Err(McpError::Validation(
2032                    "Missing completion parameters".to_string(),
2033                ));
2034            }
2035        };
2036
2037        let completions = self
2038            .handle_completion(
2039                &params.reference,
2040                &params.argument,
2041                None, // Context support to be added
2042            )
2043            .await?;
2044
2045        let result = CompleteResult {
2046            completion: CompletionData {
2047                values: completions,
2048                total: None,
2049                has_more: None,
2050            },
2051            meta: None,
2052        };
2053
2054        Ok(serde_json::to_value(result)?)
2055    }
2056
2057    /// Handle RPC discovery request (Optional discovery mechanism)
2058    async fn handle_rpc_discover(&self, params: Option<Value>) -> McpResult<Value> {
2059        use crate::server::discovery_handler::DiscoveryHandler;
2060
2061        let handler = DiscoveryHandler::new();
2062        let result = handler
2063            .handle(&self.info, &self.capabilities, params)
2064            .await?;
2065        Ok(serde_json::to_value(result)?)
2066    }
2067
2068    // ========================================================================
2069    // Notification Helpers
2070    // ========================================================================
2071
2072    async fn emit_resources_list_changed(&self) -> McpResult<()> {
2073        let notification = JsonRpcNotification::new(
2074            methods::RESOURCES_LIST_CHANGED.to_string(),
2075            Some(ResourceListChangedParams { meta: None }),
2076        )?;
2077
2078        self.send_notification(notification).await
2079    }
2080
2081    async fn emit_tools_list_changed(&self) -> McpResult<()> {
2082        let notification = JsonRpcNotification::new(
2083            methods::TOOLS_LIST_CHANGED.to_string(),
2084            Some(ToolListChangedParams { meta: None }),
2085        )?;
2086
2087        self.send_notification(notification).await
2088    }
2089
2090    async fn emit_prompts_list_changed(&self) -> McpResult<()> {
2091        let notification = JsonRpcNotification::new(
2092            methods::PROMPTS_LIST_CHANGED.to_string(),
2093            Some(PromptListChangedParams { meta: None }),
2094        )?;
2095
2096        self.send_notification(notification).await
2097    }
2098
2099    /// Send a notification through the transport
2100    async fn send_notification(&self, notification: JsonRpcNotification) -> McpResult<()> {
2101        let mut transport_guard = self.transport.lock().await;
2102        if let Some(transport) = transport_guard.as_mut() {
2103            transport.send_notification(notification).await?;
2104        }
2105        Ok(())
2106    }
2107
2108    // ========================================================================
2109    // Utility Methods
2110    // ========================================================================
2111
2112    async fn next_request_id(&self) -> u64 {
2113        let mut counter = self.request_counter.lock().await;
2114        *counter += 1;
2115        *counter
2116    }
2117
2118    // ========================================================================
2119    // State Management & Convenience Methods
2120    // ========================================================================
2121
2122    /// Check if the server has been initialized
2123    pub async fn is_initialized(&self) -> bool {
2124        let state = self.state.read().await;
2125        matches!(*state, ServerState::Running)
2126    }
2127
2128    /// Check if the server is stopping or stopped
2129    pub async fn is_stopped(&self) -> bool {
2130        let state = self.state.read().await;
2131        matches!(*state, ServerState::Stopping | ServerState::Stopped)
2132    }
2133
2134    /// Get the current server state (alias for existing state method)
2135    pub async fn get_state(&self) -> ServerState {
2136        self.state().await
2137    }
2138
2139    /// Check if the server has any registered tools
2140    pub async fn has_tools(&self) -> bool {
2141        let tools = self.tools.read().await;
2142        !tools.is_empty()
2143    }
2144
2145    /// Check if the server has any registered resources
2146    pub async fn has_resources(&self) -> bool {
2147        let resources = self.resources.read().await;
2148        !resources.is_empty()
2149    }
2150
2151    /// Check if the server has any registered prompts
2152    pub async fn has_prompts(&self) -> bool {
2153        let prompts = self.prompts.read().await;
2154        !prompts.is_empty()
2155    }
2156
2157    /// Get the number of registered tools
2158    pub async fn tool_count(&self) -> usize {
2159        let tools = self.tools.read().await;
2160        tools.len()
2161    }
2162
2163    /// Get the number of registered resources
2164    pub async fn resource_count(&self) -> usize {
2165        let resources = self.resources.read().await;
2166        resources.len()
2167    }
2168
2169    /// Get the number of registered prompts
2170    pub async fn prompt_count(&self) -> usize {
2171        let prompts = self.prompts.read().await;
2172        prompts.len()
2173    }
2174
2175    /// Check if a specific tool is registered
2176    pub async fn has_tool(&self, name: &str) -> bool {
2177        let tools = self.tools.read().await;
2178        tools.contains_key(name)
2179    }
2180
2181    /// Check if a specific resource is registered
2182    pub async fn has_resource(&self, uri: &str) -> bool {
2183        let resources = self.resources.read().await;
2184        resources.contains_key(uri)
2185    }
2186
2187    /// Check if a specific prompt is registered
2188    pub async fn has_prompt(&self, name: &str) -> bool {
2189        let prompts = self.prompts.read().await;
2190        prompts.contains_key(name)
2191    }
2192
2193    /// Set the server state (internal use)
2194    async fn set_state(&self, new_state: ServerState) {
2195        let mut state = self.state.write().await;
2196        *state = new_state;
2197    }
2198
2199    /// Initialize the server (sets state to Running)
2200    pub async fn initialize(&self) -> McpResult<()> {
2201        self.set_state(ServerState::Running).await;
2202        Ok(())
2203    }
2204}
2205
2206#[cfg(test)]
2207mod tests {
2208    use super::*;
2209    use serde_json::json;
2210
2211    #[tokio::test]
2212    async fn test_server_creation() {
2213        let server = McpServer::new("test-server".to_string(), "1.0.0".to_string());
2214        assert_eq!(server.info().name, "test-server");
2215        assert_eq!(server.info().version, "1.0.0");
2216        assert!(!server.is_running().await);
2217    }
2218
2219    #[tokio::test]
2220    async fn test_tool_management() {
2221        let server = McpServer::new("test-server".to_string(), "1.0.0".to_string());
2222
2223        // Add a tool
2224        let schema = json!({
2225            "type": "object",
2226            "properties": {
2227                "name": {"type": "string"}
2228            }
2229        });
2230
2231        struct TestToolHandler;
2232
2233        #[async_trait::async_trait]
2234        impl ToolHandler for TestToolHandler {
2235            async fn call(&self, _arguments: HashMap<String, Value>) -> McpResult<ToolResult> {
2236                Ok(ToolResult {
2237                    content: vec![Content::text("Hello from tool")],
2238                    is_error: None,
2239                    structured_content: None,
2240                    meta: None,
2241                })
2242            }
2243        }
2244
2245        server
2246            .add_tool(
2247                "test_tool".to_string(),
2248                Some("A test tool".to_string()),
2249                schema,
2250                TestToolHandler,
2251            )
2252            .await
2253            .unwrap();
2254
2255        // List tools
2256        let tools = server.list_tools().await.unwrap();
2257        assert_eq!(tools.len(), 1);
2258        assert_eq!(tools[0].name, "test_tool");
2259
2260        // Call tool
2261        let result = server.call_tool("test_tool", None).await.unwrap();
2262        assert_eq!(result.content.len(), 1);
2263    }
2264
2265    #[tokio::test]
2266    async fn test_initialize_request() {
2267        let server = McpServer::new("test-server".to_string(), "1.0.0".to_string());
2268
2269        let init_params = InitializeParams::new(
2270            crate::protocol::LEGACY_PROTOCOL_VERSION.to_string(),
2271            ClientCapabilities::default(),
2272            ClientInfo {
2273                name: "test-client".to_string(),
2274                version: "1.0.0".to_string(),
2275                description: None,
2276                title: Some("Test Client".to_string()),
2277                website_url: None,
2278                icons: None,
2279            },
2280        );
2281
2282        let request =
2283            JsonRpcRequest::new(json!(1), methods::INITIALIZE.to_string(), Some(init_params))
2284                .unwrap();
2285
2286        let response = server.handle_request(request).await.unwrap();
2287        assert!(response.result.is_some());
2288    }
2289}