tools.ts•5.28 kB
/**
* MCP Tool definitions and handlers for Cozi
*/
import { CoziClient } from './cozi-client';
import type { CoziList } from './types';
export interface MCPTool {
name: string;
description: string;
inputSchema: {
type: string;
properties: Record<string, any>;
required?: string[];
};
}
export const COZI_TOOLS: MCPTool[] = [
{
name: 'cozi_get_lists',
description: 'Get all Cozi lists (shopping, to-do, etc.)',
inputSchema: {
type: 'object',
properties: {},
},
},
{
name: 'cozi_get_list_items',
description: 'Get all items from a specific Cozi list',
inputSchema: {
type: 'object',
properties: {
list_id: {
type: 'string',
description: 'The ID of the list to retrieve items from',
},
},
required: ['list_id'],
},
},
{
name: 'cozi_add_item',
description: 'Add a new item to a Cozi list',
inputSchema: {
type: 'object',
properties: {
list_id: {
type: 'string',
description: 'The ID of the list to add the item to',
},
text: {
type: 'string',
description: 'The text/name of the item to add',
},
},
required: ['list_id', 'text'],
},
},
{
name: 'cozi_remove_item',
description: 'Remove an item from a Cozi list',
inputSchema: {
type: 'object',
properties: {
list_id: {
type: 'string',
description: 'The ID of the list containing the item',
},
item_id: {
type: 'string',
description: 'The ID of the item to remove',
},
},
required: ['list_id', 'item_id'],
},
},
{
name: 'cozi_mark_item_complete',
description: 'Mark a Cozi list item as complete',
inputSchema: {
type: 'object',
properties: {
list_id: {
type: 'string',
description: 'The ID of the list containing the item',
},
item_id: {
type: 'string',
description: 'The ID of the item to mark complete',
},
},
required: ['list_id', 'item_id'],
},
},
{
name: 'cozi_mark_item_incomplete',
description: 'Mark a Cozi list item as incomplete',
inputSchema: {
type: 'object',
properties: {
list_id: {
type: 'string',
description: 'The ID of the list containing the item',
},
item_id: {
type: 'string',
description: 'The ID of the item to mark incomplete',
},
},
required: ['list_id', 'item_id'],
},
},
{
name: 'cozi_search_lists',
description: 'Search for items across all Cozi lists',
inputSchema: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'The search query to find items',
},
},
required: ['query'],
},
},
];
/**
* Execute a Cozi tool
*/
export async function executeTool(
toolName: string,
args: Record<string, any>,
client: CoziClient
): Promise<any> {
switch (toolName) {
case 'cozi_get_lists': {
const lists = await client.getLists();
return {
lists: lists.map(list => ({
id: list.listId,
title: list.title,
item_count: list.items.length,
})),
};
}
case 'cozi_get_list_items': {
const list = await client.getList(args.list_id);
return {
list_id: list.listId,
title: list.title,
items: list.items.map(item => ({
id: item.itemId,
text: item.text,
status: item.status,
notes: item.notes,
due_date: item.dueDate,
})),
};
}
case 'cozi_add_item': {
await client.addItem(args.list_id, args.text);
return {
success: true,
message: `Added "${args.text}" to list`,
};
}
case 'cozi_remove_item': {
await client.removeItem(args.list_id, args.item_id);
return {
success: true,
message: 'Item removed from list',
};
}
case 'cozi_mark_item_complete': {
await client.markItem(args.list_id, args.item_id, true);
return {
success: true,
message: 'Item marked as complete',
};
}
case 'cozi_mark_item_incomplete': {
await client.markItem(args.list_id, args.item_id, false);
return {
success: true,
message: 'Item marked as incomplete',
};
}
case 'cozi_search_lists': {
const lists = await client.getLists();
const query = args.query.toLowerCase();
const results: any[] = [];
for (const list of lists) {
const matchingItems = list.items.filter(item =>
item.text.toLowerCase().includes(query)
);
if (matchingItems.length > 0) {
results.push({
list_id: list.listId,
list_title: list.title,
items: matchingItems.map(item => ({
id: item.itemId,
text: item.text,
status: item.status,
})),
});
}
}
return { results };
}
default:
throw new Error(`Unknown tool: ${toolName}`);
}
}