Skip to main content
Glama

monica_manage_task_reminder

Manage tasks and reminders in Monica CRM by creating, updating, deleting, listing, or viewing to-dos and stay-in-touch nudges for contacts.

Instructions

List, inspect, create, update, or delete Monica tasks and reminders. Choose itemType="task" for to-dos or itemType="reminder" for stay-in-touch nudges.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
itemTypeYes
actionYes
taskIdNo
reminderIdNo
contactIdNo
statusNo
limitNo
pageNo
taskPayloadNo
reminderPayloadNo

Implementation Reference

  • Main tool handler function: validates input and dispatches to task or reminder handler based on itemType.
    async (rawInput) => { const input = actionItemSchema.parse(rawInput); if (input.itemType === 'task') { return handleTaskAction({ input: input as TaskActionInput, client, logger }); } return handleReminderAction({ input: input as ReminderActionInput, client, logger }); }
  • Handler for task actions: list, get, create, update, delete tasks using Monica API.
    async function handleTaskAction({ input, client, logger }: { input: TaskActionInput; client: ToolRegistrationContext['client']; logger: ToolRegistrationContext['logger']; }) { switch (input.action) { case 'list': { const response = await client.listTasks({ contactId: input.contactId, status: input.status, limit: input.limit, page: input.page }); const tasks = response.data.map(normalizeTask); const scope = input.contactId ? `contact ${input.contactId}` : 'your account'; const summary = tasks.length ? `Fetched ${tasks.length} task${tasks.length === 1 ? '' : 's'} for ${scope}.` : `No tasks found for ${scope}.`; return { content: [ { type: 'text' as const, text: summary } ], structuredContent: { itemType: input.itemType, action: input.action, contactId: input.contactId, status: input.status, tasks, pagination: { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } } }; } case 'get': { const response = await client.getTask(input.taskId!); const task = normalizeTask(response.data); return { content: [ { type: 'text' as const, text: `Task ${task.title} (ID ${task.id}).` } ], structuredContent: { itemType: input.itemType, action: input.action, task } }; } case 'create': { const payload = input.taskPayload!; const result = await client.createTask(toTaskCreatePayload(payload)); const task = normalizeTask(result.data); logger.info({ taskId: task.id }, 'Created Monica task'); return { content: [ { type: 'text' as const, text: `Created task ${task.title || `#${task.id}`} (ID ${task.id}).` } ], structuredContent: { itemType: input.itemType, action: input.action, task } }; } case 'update': { const payload = input.taskPayload!; const result = await client.updateTask(input.taskId!, toTaskUpdatePayload(payload)); const task = normalizeTask(result.data); logger.info({ taskId: input.taskId }, 'Updated Monica task'); return { content: [ { type: 'text' as const, text: `Updated task ${task.title || `#${task.id}`} (ID ${task.id}).` } ], structuredContent: { itemType: input.itemType, action: input.action, taskId: input.taskId, task } }; } case 'delete': { const result = await client.deleteTask(input.taskId!); logger.info({ taskId: input.taskId }, 'Deleted Monica task'); return { content: [ { type: 'text' as const, text: `Deleted task ID ${input.taskId}.` } ], structuredContent: { itemType: input.itemType, action: input.action, taskId: input.taskId, result } }; } default: return unreachable(input.action as never); } }
  • Handler for reminder actions: list, get, create, update, delete reminders using Monica API.
    async function handleReminderAction({ input, client, logger }: { input: ReminderActionInput; client: ToolRegistrationContext['client']; logger: ToolRegistrationContext['logger']; }) { switch (input.action) { case 'list': { const response = await client.listReminders({ contactId: input.contactId, limit: input.limit, page: input.page }); const reminders = response.data.map(normalizeReminder); const scope = input.contactId ? `contact ${input.contactId}` : 'your account'; const text = reminders.length ? `Found ${reminders.length} reminder${reminders.length === 1 ? '' : 's'} for ${scope}.` : `No reminders found for ${scope}.`; return { content: [ { type: 'text' as const, text } ], structuredContent: { itemType: input.itemType, action: input.action, contactId: input.contactId, reminders, pagination: { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } } }; } case 'get': { const response = await client.getReminder(input.reminderId!); const reminder = normalizeReminder(response.data); const contactName = reminder.contact?.name || `Contact ${reminder.contactId}`; return { content: [ { type: 'text' as const, text: `Reminder "${reminder.title}" for ${contactName}. Next due ${reminder.nextExpectedDate ?? 'unknown'}.` } ], structuredContent: { itemType: input.itemType, action: input.action, reminder } }; } case 'create': { const payload = input.reminderPayload!; let createPayload: CreateReminderPayload; try { createPayload = toReminderCreatePayload(payload); } catch (error) { return { isError: true as const, content: [ { type: 'text' as const, text: (error as Error).message } ] }; } try { const response = await client.createReminder(createPayload); const reminder = normalizeReminder(response.data); logger.info({ reminderId: reminder.id, contactId: reminder.contactId }, 'Created Monica reminder'); return { content: [ { type: 'text' as const, text: `Created reminder "${reminder.title}" for contact ${reminder.contactId}.` } ], structuredContent: { itemType: input.itemType, action: input.action, reminder } }; } catch (error) { if (error instanceof MonicaApiError) { return buildErrorResponse(formatMonicaApiError(error)); } throw error; } } case 'update': { const payload = input.reminderPayload!; let updatePayload: UpdateReminderPayload; try { updatePayload = toReminderUpdatePayload(payload); } catch (error) { return { isError: true as const, content: [ { type: 'text' as const, text: (error as Error).message } ] }; } try { const response = await client.updateReminder(input.reminderId!, updatePayload); const reminder = normalizeReminder(response.data); logger.info({ reminderId: input.reminderId }, 'Updated Monica reminder'); return { content: [ { type: 'text' as const, text: `Updated reminder "${reminder.title}" (ID ${reminder.id}).` } ], structuredContent: { itemType: input.itemType, action: input.action, reminderId: input.reminderId, reminder } }; } catch (error) { if (error instanceof MonicaApiError) { return buildErrorResponse(formatMonicaApiError(error)); } throw error; } } case 'delete': { try { const result = await client.deleteReminder(input.reminderId!); logger.info({ reminderId: input.reminderId }, 'Deleted Monica reminder'); return { content: [ { type: 'text' as const, text: `Deleted reminder ID ${input.reminderId}.` } ], structuredContent: { itemType: input.itemType, action: input.action, reminderId: input.reminderId, result } }; } catch (error) { if (error instanceof MonicaApiError) { return buildErrorResponse(formatMonicaApiError(error)); } throw error; } } default: return unreachable(input.action as never); } }
  • Zod schemas for tool input validation, including sub-schemas for task and reminder payloads and superRefine for action-specific checks.
    const actionItemInputShape = { itemType: z.enum(['task', 'reminder']), action: z.enum(['list', 'get', 'create', 'update', 'delete']), taskId: z.number().int().positive().optional(), reminderId: z.number().int().positive().optional(), contactId: z.number().int().positive().optional(), status: z.enum(['open', 'completed', 'all']).optional(), limit: z.number().int().min(1).max(100).optional(), page: z.number().int().min(1).optional(), taskPayload: taskPayloadSchema.optional(), reminderPayload: reminderPayloadSchema.optional() } as const; const actionItemSchema = z.object(actionItemInputShape).superRefine((data, ctx) => { if (data.itemType === 'task') { switch (data.action) { case 'list': break; case 'get': case 'delete': if (typeof data.taskId !== 'number') { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide taskId for this action.' }); } break; case 'create': if (!data.taskPayload) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide task details when creating a task.' }); } break; case 'update': if (typeof data.taskId !== 'number') { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide taskId when updating a task.' }); } if (!data.taskPayload) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide task details when updating a task.' }); } break; default: break; } } else { switch (data.action) { case 'list': break; case 'get': case 'delete': if (typeof data.reminderId !== 'number') { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide reminderId for this action.' }); } break; case 'create': if (!data.reminderPayload) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide reminder details when creating a reminder.' }); } break; case 'update': if (typeof data.reminderId !== 'number') { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide reminderId when updating a reminder.' }); } if (!data.reminderPayload) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide reminder details when updating a reminder.' }); } break; default: break; } } });
  • Registers the 'monica_manage_task_reminder' tool with the MCP server.
    server.registerTool( 'monica_manage_task_reminder', { title: 'Manage Monica tasks and reminders', description: 'List, inspect, create, update, or delete Monica tasks and reminders. Choose itemType="task" for to-dos or itemType="reminder" for stay-in-touch nudges.', inputSchema: actionItemInputShape }, async (rawInput) => { const input = actionItemSchema.parse(rawInput); if (input.itemType === 'task') { return handleTaskAction({ input: input as TaskActionInput, client, logger }); } return handleReminderAction({ input: input as ReminderActionInput, client, logger }); } );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jacob-Stokes/monica-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server