scim_server/mcp_integration/
protocol.rs

1//! MCP protocol layer for tool discovery and dispatch
2//!
3//! This module handles the core MCP protocol functionality including tool discovery,
4//! execution dispatch, and protocol communication. It serves as the interface between
5//! AI agents and the SCIM server operations.
6
7use super::core::{ScimMcpServer, ScimToolResult};
8use super::handlers::{system_info, user_crud, user_queries};
9use super::tools::{system_schemas, user_schemas};
10use crate::ResourceProvider;
11use log::{debug, info};
12use serde_json::{Value, json};
13
14impl<P: ResourceProvider + Send + Sync + 'static> ScimMcpServer<P> {
15    /// Get the list of available MCP tools as JSON
16    ///
17    /// Returns all tool definitions that AI agents can discover and execute.
18    /// Each tool includes its schema, parameters, and documentation.
19    ///
20    /// # Examples
21    ///
22    /// ```rust
23    /// # #[cfg(feature = "mcp")]
24    /// use scim_server::mcp_integration::ScimMcpServer;
25    /// # async fn example(mcp_server: ScimMcpServer<scim_server::providers::InMemoryProvider>) {
26    /// let tools = mcp_server.get_tools();
27    /// println!("Available tools: {}", tools.len());
28    /// # }
29    /// ```
30    pub fn get_tools(&self) -> Vec<Value> {
31        vec![
32            user_schemas::create_user_tool(),
33            user_schemas::get_user_tool(),
34            user_schemas::update_user_tool(),
35            user_schemas::delete_user_tool(),
36            user_schemas::list_users_tool(),
37            user_schemas::search_users_tool(),
38            user_schemas::user_exists_tool(),
39            system_schemas::get_schemas_tool(),
40            system_schemas::get_server_info_tool(),
41        ]
42    }
43
44    /// Execute a tool by name with arguments
45    ///
46    /// This is the main dispatch function that routes tool execution requests
47    /// to the appropriate handler based on the tool name.
48    ///
49    /// # Arguments
50    /// * `tool_name` - The name of the tool to execute
51    /// * `arguments` - JSON arguments for the tool execution
52    ///
53    /// # Returns
54    /// A `ScimToolResult` containing the execution outcome
55    pub async fn execute_tool(&self, tool_name: &str, arguments: Value) -> ScimToolResult {
56        debug!("Executing MCP tool: {} with args: {}", tool_name, arguments);
57
58        match tool_name {
59            // User CRUD operations
60            "scim_create_user" => user_crud::handle_create_user(self, arguments).await,
61            "scim_get_user" => user_crud::handle_get_user(self, arguments).await,
62            "scim_update_user" => user_crud::handle_update_user(self, arguments).await,
63            "scim_delete_user" => user_crud::handle_delete_user(self, arguments).await,
64
65            // User query operations
66            "scim_list_users" => user_queries::handle_list_users(self, arguments).await,
67            "scim_search_users" => user_queries::handle_search_users(self, arguments).await,
68            "scim_user_exists" => user_queries::handle_user_exists(self, arguments).await,
69
70            // System information operations
71            "scim_get_schemas" => system_info::handle_get_schemas(self, arguments).await,
72            "scim_server_info" => system_info::handle_server_info(self, arguments).await,
73
74            // Unknown tool
75            _ => ScimToolResult {
76                success: false,
77                content: json!({
78                    "error": "Unknown tool",
79                    "tool_name": tool_name
80                }),
81                metadata: None,
82            },
83        }
84    }
85
86    /// Run the MCP server using stdio communication
87    ///
88    /// Starts the MCP server and begins listening for tool execution requests
89    /// over standard input/output. This is the standard MCP communication method.
90    ///
91    /// # Examples
92    ///
93    /// ```rust,no_run
94    /// # #[cfg(feature = "mcp")]
95    /// use scim_server::mcp_integration::ScimMcpServer;
96    /// # async fn example(mcp_server: ScimMcpServer<scim_server::providers::InMemoryProvider>) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
97    /// // Run MCP server
98    /// mcp_server.run_stdio().await?;
99    /// # Ok(())
100    /// # }
101    /// ```
102    pub async fn run_stdio(self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
103        info!("SCIM MCP server ready for stdio communication");
104        info!(
105            "Available tools: {:?}",
106            self.get_tools()
107                .iter()
108                .map(|t| t.get("name"))
109                .collect::<Vec<_>>()
110        );
111        // In a real implementation, this would start the MCP protocol handler
112        // For now, we just indicate readiness
113        Ok(())
114    }
115}