use rmcp::{
ErrorData as McpError,
handler::server::wrapper::Parameters,
model::*,
tool, tool_router,
};
use serde::Deserialize;
use crate::server::GDriveServer;
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct LabelsListParams {
pub file_id: String,
#[serde(default)]
pub max_results: Option<i32>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct LabelsModifyParams {
pub file_id: String,
pub modifications: serde_json::Value,
}
#[tool_router(router = labels_tool_router, vis = "pub")]
impl GDriveServer {
#[tool(name = "gdrive_labels_list")]
async fn labels_list(
&self,
Parameters(params): Parameters<LabelsListParams>,
) -> Result<CallToolResult, McpError> {
let mut req = self.client.hub().files().list_labels(¶ms.file_id);
if let Some(max) = params.max_results {
req = req.max_results(max);
}
let (_, list) = req.doit().await.map_err(drive_err)?;
let json = serde_json::to_string_pretty(&list)
.map_err(|e| McpError::internal_error(e.to_string(), None))?;
Ok(CallToolResult::success(vec![Content::text(json)]))
}
#[tool(name = "gdrive_labels_modify")]
async fn labels_modify(
&self,
Parameters(params): Parameters<LabelsModifyParams>,
) -> Result<CallToolResult, McpError> {
let modify_req: google_drive3::api::ModifyLabelsRequest =
serde_json::from_value(params.modifications)
.map_err(|e| McpError::invalid_params(format!("Invalid modifications: {e}"), None))?;
let (_, result) = self
.client
.hub()
.files()
.modify_labels(modify_req, ¶ms.file_id)
.doit()
.await
.map_err(drive_err)?;
let json = serde_json::to_string_pretty(&result)
.map_err(|e| McpError::internal_error(e.to_string(), None))?;
Ok(CallToolResult::success(vec![Content::text(format!(
"Labels modified:\n{json}"
))]))
}
}
fn drive_err(e: google_drive3::Error) -> McpError {
McpError::internal_error(format!("Google Drive API error: {e}"), None)
}