import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { api } from "../api/client.js";
import { formatResponse, validateDeleteOperation, createDeleteSafetyError } from "../utils/index.js";
export function registerLabelTools(server: McpServer) {
// Add a label to a task
server.tool(
"add_label",
"Add a label to a task",
{
board_id: z.number().int().positive().describe("Board ID"),
task_id: z.number().int().positive().describe("Task ID"),
label_id: z.number().int().positive().describe("Label ID"),
},
async (args) => {
const { board_id, task_id, label_id } = args;
const response = await api.post(
`/projects/${board_id}/labels/task`,
{ taskId: task_id, labelId: label_id }
);
return formatResponse(response.data);
}
);
// Remove a label from a task
server.tool(
"remove_label",
"Remove a label from a task",
{
board_id: z.number().int().positive().describe("Board ID"),
task_id: z.number().int().positive().describe("Task ID"),
label_id: z.number().int().positive().describe("Label ID"),
},
async (args) => {
const { board_id, task_id, label_id } = args;
const response = await api.delete(
`/projects/${board_id}/tasks/${task_id}/labels/${label_id}`
);
return formatResponse(response.data);
}
);
// Edit a label
server.tool(
"edit_label",
"Edit a label's title and colors",
{
board_id: z.number().int().positive().describe("Board ID"),
label_id: z.number().int().positive().describe("Label ID"),
title: z.string().min(1).describe("Label title/text"),
bg_color: z.string().optional().describe("Background color (hex)"),
color: z.string().optional().describe("Text color (hex)"),
},
async (args) => {
const { board_id, label_id, title, bg_color, color } = args;
const labelData: any = {
label: title,
};
if (bg_color) {
labelData.bg_color = bg_color;
}
if (color) {
labelData.color = color;
}
const response = await api.put(
`/projects/${board_id}/labels/${label_id}`,
labelData
);
return formatResponse(response.data);
}
);
// Create a new label
server.tool(
"create_label",
"Create a new label on a board",
{
board_id: z.number().int().positive().describe("Board ID"),
title: z.string().min(1).describe("Label title/text"),
bg_color: z.string().describe("Background color (hex) - e.g., #4bce97"),
color: z
.string()
.default("#1B2533")
.describe("Text color (hex) - defaults to #1B2533"),
},
async (args) => {
const { board_id, title, bg_color, color } = args;
const labelData: any = {
label: title,
bg_color,
color,
};
const response = await api.post(
`/projects/${board_id}/labels`,
labelData
);
return formatResponse(response.data);
}
);
// Delete a label from board
server.tool(
"delete_label",
"Delete a label from a board permanently",
{
board_id: z.number().int().positive().describe("Board ID"),
label_id: z.number().int().positive().describe("Label ID"),
confirm_delete: z.union([z.boolean(), z.string()]).optional().describe("Confirmation required: set to true, 'yes', or 'confirm' to proceed"),
},
async (args) => {
const { board_id, label_id, confirm_delete } = args;
// Validate delete operation safety
const safetyCheck = validateDeleteOperation("label", confirm_delete);
if (!safetyCheck.allowed) {
return formatResponse(createDeleteSafetyError(safetyCheck));
}
const response = await api.delete(`/projects/${board_id}/labels/${label_id}`);
return formatResponse(response.data);
}
);
}