Skip to main content
Glama

monica_manage_activity

Manage CRM activities like meetings and events: list, create, update, or delete interactions with contacts using activity types and details.

Instructions

List, inspect, create, update, or delete activities (meetings, events, shared interactions). Provide either activityTypeId or activityTypeName.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYes
activityIdNo
contactIdNo
limitNo
pageNo
payloadNo

Implementation Reference

  • Registration of the 'monica_manage_activity' tool via server.registerTool, including schema and handler.
    export function registerActivityTools(context: ToolRegistrationContext): void { const { server, client, logger } = context; server.registerTool( 'monica_manage_activity', { title: 'Manage Monica activities', description: 'List, inspect, create, update, or delete activities (meetings, events, shared interactions). Provide either activityTypeId or activityTypeName.', inputSchema: { action: z.enum(['list', 'get', 'create', 'update', 'delete']), activityId: z.number().int().positive().optional(), contactId: z.number().int().positive().optional(), limit: z.number().int().min(1).max(100).optional(), page: z.number().int().min(1).optional(), payload: activityPayloadSchema.optional() } }, async ({ action, activityId, contactId, limit, page, payload }) => { if (action === 'list') { const response = await client.listActivities({ contactId, limit, page }); const activities = response.data.map(normalizeActivity); const scope = contactId ? `contact ${contactId}` : 'your account'; const summary = activities.length ? `Fetched ${activities.length} activit${activities.length === 1 ? 'y' : 'ies'} for ${scope}.` : `No activities found for ${scope}.`; return { content: [ { type: 'text' as const, text: summary } ], structuredContent: { action, contactId, activities, pagination: { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } } }; } if (action === 'get') { if (!activityId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide activityId when retrieving an activity.' } ] }; } const response = await client.getActivity(activityId); const activity = normalizeActivity(response.data); return { content: [ { type: 'text' as const, text: `Activity ${activity.summary || `#${activity.id}`} (ID ${activity.id}).` } ], structuredContent: { action, activity } }; } if (action === 'create') { if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide an activity payload when creating an activity.' } ] }; } const activityTypeId = await resolveActivityTypeId(client, { activityTypeId: payload.activityTypeId, activityTypeName: payload.activityTypeName }); const result = await client.createActivity( toActivityPayloadInput({ ...payload, activityTypeId }) ); const activity = normalizeActivity(result.data); logger.info({ activityId: activity.id }, 'Created Monica activity'); return { content: [ { type: 'text' as const, text: `Created activity ${activity.summary || `#${activity.id}`} (ID ${activity.id}).` } ], structuredContent: { action, activity } }; } if (action === 'update') { if (!activityId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide activityId when updating an activity.' } ] }; } if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide an activity payload when updating an activity.' } ] }; } const activityTypeId = await resolveActivityTypeId(client, { activityTypeId: payload.activityTypeId, activityTypeName: payload.activityTypeName }); const result = await client.updateActivity( activityId, toActivityPayloadInput({ ...payload, activityTypeId }) ); const activity = normalizeActivity(result.data); logger.info({ activityId }, 'Updated Monica activity'); return { content: [ { type: 'text' as const, text: `Updated activity ${activity.summary || `#${activity.id}`} (ID ${activity.id}).` } ], structuredContent: { action, activityId, activity } }; } if (!activityId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide activityId when deleting an activity.' } ] }; } const result = await client.deleteActivity(activityId); logger.info({ activityId }, 'Deleted Monica activity'); return { content: [ { type: 'text' as const, text: `Deleted activity ID ${activityId}.` } ], structuredContent: { action, activityId, result } }; } ); }
  • Handler function implementing list, get, create, update, delete operations for activities using MonicaClient methods.
    async ({ action, activityId, contactId, limit, page, payload }) => { if (action === 'list') { const response = await client.listActivities({ contactId, limit, page }); const activities = response.data.map(normalizeActivity); const scope = contactId ? `contact ${contactId}` : 'your account'; const summary = activities.length ? `Fetched ${activities.length} activit${activities.length === 1 ? 'y' : 'ies'} for ${scope}.` : `No activities found for ${scope}.`; return { content: [ { type: 'text' as const, text: summary } ], structuredContent: { action, contactId, activities, pagination: { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } } }; } if (action === 'get') { if (!activityId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide activityId when retrieving an activity.' } ] }; } const response = await client.getActivity(activityId); const activity = normalizeActivity(response.data); return { content: [ { type: 'text' as const, text: `Activity ${activity.summary || `#${activity.id}`} (ID ${activity.id}).` } ], structuredContent: { action, activity } }; } if (action === 'create') { if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide an activity payload when creating an activity.' } ] }; } const activityTypeId = await resolveActivityTypeId(client, { activityTypeId: payload.activityTypeId, activityTypeName: payload.activityTypeName }); const result = await client.createActivity( toActivityPayloadInput({ ...payload, activityTypeId }) ); const activity = normalizeActivity(result.data); logger.info({ activityId: activity.id }, 'Created Monica activity'); return { content: [ { type: 'text' as const, text: `Created activity ${activity.summary || `#${activity.id}`} (ID ${activity.id}).` } ], structuredContent: { action, activity } }; } if (action === 'update') { if (!activityId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide activityId when updating an activity.' } ] }; } if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide an activity payload when updating an activity.' } ] }; } const activityTypeId = await resolveActivityTypeId(client, { activityTypeId: payload.activityTypeId, activityTypeName: payload.activityTypeName }); const result = await client.updateActivity( activityId, toActivityPayloadInput({ ...payload, activityTypeId }) ); const activity = normalizeActivity(result.data); logger.info({ activityId }, 'Updated Monica activity'); return { content: [ { type: 'text' as const, text: `Updated activity ${activity.summary || `#${activity.id}`} (ID ${activity.id}).` } ], structuredContent: { action, activityId, activity } }; } if (!activityId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide activityId when deleting an activity.' } ] }; } const result = await client.deleteActivity(activityId); logger.info({ activityId }, 'Deleted Monica activity'); return { content: [ { type: 'text' as const, text: `Deleted activity ID ${activityId}.` } ], structuredContent: { action, activityId, result } }; }
  • Zod schema for activity payload used in create/update actions.
    const activityPayloadSchema = z .object({ activityTypeId: z.number().int().positive().optional(), activityTypeName: z.string().min(1).max(255).optional(), summary: z.string().min(1).max(255), description: z.string().max(1_000_000).optional().nullable(), happenedAt: z .string() .regex(/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/u, 'happenedAt must be in YYYY-MM-DD format.'), contactIds: z.array(z.number().int().positive()).min(1, 'Provide at least one contact ID.'), emotionIds: z.array(z.number().int().positive()).optional() }) .superRefine((data, ctx) => { if (typeof data.activityTypeId !== 'number' && !data.activityTypeName) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Provide activityTypeId or activityTypeName.' }); } });
  • Helper function to transform validated payload into API payload format.
    function toActivityPayloadInput( payload: ActivityPayloadForm & { activityTypeId: number } ): CreateActivityPayload & UpdateActivityPayload { return { activityTypeId: payload.activityTypeId, summary: payload.summary, description: payload.description ?? null, happenedAt: payload.happenedAt, contactIds: payload.contactIds, emotionIds: payload.emotionIds && payload.emotionIds.length ? payload.emotionIds : undefined }; }
  • Top-level call to registerActivityTools during overall tools registration.
    registerActivityTools(context);

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