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}