/**
* Label-related MCP tools
*/
import { z } from 'zod';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import type { TodoistService } from '../services/todoist-service.js';
export function registerLabelTools(server: McpServer, todoist: TodoistService) {
// ─────────────────────────────────────────────────────────────
// list_labels
// ─────────────────────────────────────────────────────────────
server.tool(
'list_labels',
'List all labels in the Todoist account',
{},
async () => {
try {
const labels = await todoist.listLabels();
return {
content: [
{
type: 'text',
text: JSON.stringify({ labels }, null, 2),
},
],
};
} catch (error) {
return {
content: [{ type: 'text', text: `Error: ${(error as Error).message}` }],
isError: true,
};
}
}
);
// ─────────────────────────────────────────────────────────────
// create_label
// ─────────────────────────────────────────────────────────────
server.tool(
'create_label',
'Create a new label',
{
name: z.string().describe('Label name'),
color: z.string().optional().describe('Color name (e.g., "berry_red", "blue") or hex code'),
isFavorite: z.boolean().optional().describe('Mark as favorite'),
},
async (params) => {
try {
const label = await todoist.createLabel({
name: params.name,
color: params.color,
isFavorite: params.isFavorite,
});
return {
content: [
{
type: 'text',
text: JSON.stringify({ label }, null, 2),
},
],
};
} catch (error) {
return {
content: [{ type: 'text', text: `Error: ${(error as Error).message}` }],
isError: true,
};
}
}
);
// ─────────────────────────────────────────────────────────────
// update_label
// ─────────────────────────────────────────────────────────────
server.tool(
'update_label',
'Update an existing label (name, color, favorite status, order)',
{
labelId: z.string().describe('Label ID to update'),
name: z.string().optional().describe('New label name'),
color: z.string().optional().describe('New color name (e.g., "berry_red", "blue") or hex code'),
order: z.number().optional().describe('New order position'),
isFavorite: z.boolean().optional().describe('Mark/unmark as favorite'),
},
async (params) => {
try {
const { labelId, ...updateData } = params;
const label = await todoist.updateLabel(labelId, {
name: updateData.name,
color: updateData.color,
order: updateData.order,
isFavorite: updateData.isFavorite,
});
return {
content: [
{
type: 'text',
text: JSON.stringify({ label }, null, 2),
},
],
};
} catch (error) {
return {
content: [{ type: 'text', text: `Error: ${(error as Error).message}` }],
isError: true,
};
}
}
);
// ─────────────────────────────────────────────────────────────
// delete_label
// ─────────────────────────────────────────────────────────────
server.tool(
'delete_label',
'Permanently delete a label (tasks will keep their other labels)',
{
labelId: z.string().describe('Label ID to delete'),
},
async (params) => {
try {
const result = await todoist.deleteLabel(params.labelId);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
} catch (error) {
return {
content: [{ type: 'text', text: `Error: ${(error as Error).message}` }],
isError: true,
};
}
}
);
}