//! Tool definitions and routing
//!
//! Tool registry and dispatcher for MCP protocol
use serde_json::Value;
use crate::error::Result;
use crate::outline::Client as OutlineClient;
// Submodules
mod collections;
mod comments;
mod common;
mod documents;
mod users;
/// Get list of all available tools
#[allow(clippy::too_many_lines)]
pub fn get_tools_list() -> Vec<Value> {
let mut tools = Vec::new();
// Document tools
tools.extend(documents::get_document_tools());
// Collection tools
tools.extend(collections::get_collection_tools());
// Comment tools
tools.extend(comments::get_comment_tools());
// User tools
tools.extend(users::get_user_tools());
tools
}
/// Call tool by name
pub async fn call_tool(name: &str, arguments: Value, client: &OutlineClient) -> Result<Value> {
let result = match name {
// Document tools
"create_document"
| "get_document"
| "update_document"
| "delete_document"
| "list_documents"
| "search_documents"
| "archive_document"
| "move_document"
| "create_template_from_document" => {
documents::call_document_tool(name, arguments, client).await
}
// Collection tools
"create_collection" | "get_collection" | "update_collection" | "list_collections" => {
collections::call_collection_tool(name, arguments, client).await
}
// Comment tools
"create_comment" | "update_comment" | "delete_comment" => {
comments::call_comment_tool(name, arguments, client).await
}
// User tools
"list_users" => users::call_user_tool(name, arguments, client).await,
// Unknown tool - return MCP-compliant error
_ => {
return Ok(common::create_mcp_error_response(&format!(
"Unknown tool: {name}"
)));
}
};
// Handle tool execution errors by converting them to MCP error responses
match result {
Ok(success_response) => Ok(success_response),
Err(error) => Ok(common::handle_tool_error(&error)),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_tools_list() {
let tools = get_tools_list();
assert_eq!(tools.len(), 17);
// Check first tool is a document tool
let first_tool = &tools[0];
assert_eq!(first_tool["name"], "create_document");
assert!(first_tool["description"]
.as_str()
.unwrap()
.contains("Create"));
}
}