use serde_json::Value;
use crate::client::ConfluenceClient;
use crate::mcp::{CallToolResult, ToolDefinition};
use crate::types::LabelListResponse;
use super::{schema, schema_with_array};
pub fn definitions() -> Vec<ToolDefinition> {
vec![
ToolDefinition {
name: "add_labels".to_string(),
description: "Add labels to a Confluence page".to_string(),
input_schema: schema_with_array(
&[("pageId", "string", true, "The ID of the page")],
&[("labels", "string", true, "Array of labels to add")],
),
},
ToolDefinition {
name: "get_labels".to_string(),
description: "Get labels from a Confluence page".to_string(),
input_schema: schema(&[("pageId", "string", true, "The ID of the page")]),
},
]
}
pub async fn add_labels(client: &ConfluenceClient, args: &Value) -> CallToolResult {
let page_id = match args.get("pageId").and_then(|v| v.as_str()) {
Some(id) => id,
None => return CallToolResult::text("Error: pageId is required."),
};
let labels: Vec<String> = match args.get("labels").and_then(|v| v.as_array()) {
Some(arr) => arr.iter().filter_map(|v| v.as_str().map(String::from)).collect(),
None => return CallToolResult::text("Error: labels is required."),
};
let label_data: Vec<Value> = labels
.iter()
.map(|name| serde_json::json!({ "prefix": "global", "name": name }))
.collect();
let body = Value::Array(label_data);
let endpoint = if client.config().is_cloud {
format!("/pages/{page_id}/labels")
} else {
format!("/content/{page_id}/label")
};
match client.post::<Value>(&endpoint, &body).await {
Ok(_) => CallToolResult::text(format!(
"✅ Labels added to page {page_id}: {}",
labels.join(", ")
)),
Err(e) => CallToolResult::text(format!("Error adding labels: {e}")),
}
}
pub async fn get_labels(client: &ConfluenceClient, args: &Value) -> CallToolResult {
let page_id = match args.get("pageId").and_then(|v| v.as_str()) {
Some(id) => id,
None => return CallToolResult::text("Error: pageId is required."),
};
let endpoint = if client.config().is_cloud {
format!("/pages/{page_id}/labels")
} else {
format!("/content/{page_id}/label")
};
match client.get::<LabelListResponse>(&endpoint).await {
Ok(result) => {
if result.results.is_empty() {
return CallToolResult::text("No labels found on this page.");
}
let label_list: Vec<&str> = result.results.iter().map(|l| l.name.as_str()).collect();
CallToolResult::text(format!(
"Labels on page {page_id}: {}",
label_list.join(", ")
))
}
Err(e) => CallToolResult::text(format!("Error getting labels: {e}")),
}
}