Skip to main content
Glama

monica_manage_note

Manage notes for contacts in Monica CRM by listing, viewing, creating, updating, or deleting journal entries and snippets attached to contact profiles.

Instructions

List, inspect, create, update, or delete notes attached to a contact. Use this to capture or revise journal snippets.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYes
noteIdNo
contactIdNo
limitNo
pageNo
payloadNo

Implementation Reference

  • Core handler implementing CRUD operations for Monica notes: list notes for contact, get note, create/update/delete note with validation and structured responses.
    async ({ action, noteId, contactId, limit, page, payload }) => { if (action === 'list') { if (!contactId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactId when listing notes.' } ] }; } const response = await client.fetchContactNotes(contactId, limit, page); const notes = response.data.map(normalizeNote); const summary = notes.length ? `Fetched ${notes.length} note${notes.length === 1 ? '' : 's'} for contact ${contactId}.` : `No notes found for contact ${contactId}.`; return { content: [ { type: 'text' as const, text: summary } ], structuredContent: { action, contactId, notes, pagination: { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } } }; } if (action === 'get') { if (!noteId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide noteId when retrieving a note.' } ] }; } const response = await client.getNote(noteId); const note = normalizeNote(response.data); return { content: [ { type: 'text' as const, text: `Note ${note.id} for contact ${note.contact.name}.` } ], structuredContent: { action, note } }; } if (action === 'create') { if (!payload || typeof payload.contactId !== 'number' || !payload.body) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactId and body when creating a note.' } ] }; } const result = await client.createNote(toNoteCreatePayload(payload)); const note = normalizeNote(result.data); logger.info({ noteId: note.id }, 'Created Monica note'); return { content: [ { type: 'text' as const, text: `Created note ${note.id} for contact ${note.contact.name}.` } ], structuredContent: { action, note } }; } if (action === 'update') { if (!noteId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide noteId when updating a note.' } ] }; } if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide note details when updating a note.' } ] }; } const result = await client.updateNote(noteId, toNoteUpdatePayload(payload)); const note = normalizeNote(result.data); logger.info({ noteId }, 'Updated Monica note'); return { content: [ { type: 'text' as const, text: `Updated note ${note.id} for contact ${note.contact.name}.` } ], structuredContent: { action, noteId, note } }; } if (action === 'delete') { if (!noteId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide noteId when deleting a note.' } ] }; } await client.deleteNote(noteId); logger.info({ noteId }, 'Deleted Monica note'); return { content: [ { type: 'text' as const, text: `Deleted note ID ${noteId}.` } ], structuredContent: { action, noteId, deleted: true } }; } return { isError: true as const, content: [ { type: 'text' as const, text: `Unsupported action: ${action}.` } ] }; }
  • Zod schemas defining input validation for tool parameters including action types and optional note payload.
    const notePayloadSchema = z.object({ body: z.string().max(1_000_000).optional(), contactId: z.number().int().positive().optional(), isFavorited: z.boolean().optional() }); type NotePayloadForm = z.infer<typeof notePayloadSchema>; export function registerNoteTools(context: ToolRegistrationContext): void { const { server, client, logger } = context; server.registerTool( 'monica_manage_note', { title: 'Manage Monica notes', description: 'List, inspect, create, update, or delete notes attached to a contact. Use this to capture or revise journal snippets.', inputSchema: { action: z.enum(['list', 'get', 'create', 'update', 'delete']), noteId: 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: notePayloadSchema.optional() }
  • Direct registration of the 'monica_manage_note' tool via server.registerTool within registerNoteTools function.
    server.registerTool( 'monica_manage_note', { title: 'Manage Monica notes', description: 'List, inspect, create, update, or delete notes attached to a contact. Use this to capture or revise journal snippets.', inputSchema: { action: z.enum(['list', 'get', 'create', 'update', 'delete']), noteId: 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: notePayloadSchema.optional() } }, async ({ action, noteId, contactId, limit, page, payload }) => { if (action === 'list') { if (!contactId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactId when listing notes.' } ] }; } const response = await client.fetchContactNotes(contactId, limit, page); const notes = response.data.map(normalizeNote); const summary = notes.length ? `Fetched ${notes.length} note${notes.length === 1 ? '' : 's'} for contact ${contactId}.` : `No notes found for contact ${contactId}.`; return { content: [ { type: 'text' as const, text: summary } ], structuredContent: { action, contactId, notes, pagination: { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } } }; } if (action === 'get') { if (!noteId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide noteId when retrieving a note.' } ] }; } const response = await client.getNote(noteId); const note = normalizeNote(response.data); return { content: [ { type: 'text' as const, text: `Note ${note.id} for contact ${note.contact.name}.` } ], structuredContent: { action, note } }; } if (action === 'create') { if (!payload || typeof payload.contactId !== 'number' || !payload.body) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactId and body when creating a note.' } ] }; } const result = await client.createNote(toNoteCreatePayload(payload)); const note = normalizeNote(result.data); logger.info({ noteId: note.id }, 'Created Monica note'); return { content: [ { type: 'text' as const, text: `Created note ${note.id} for contact ${note.contact.name}.` } ], structuredContent: { action, note } }; } if (action === 'update') { if (!noteId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide noteId when updating a note.' } ] }; } if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide note details when updating a note.' } ] }; } const result = await client.updateNote(noteId, toNoteUpdatePayload(payload)); const note = normalizeNote(result.data); logger.info({ noteId }, 'Updated Monica note'); return { content: [ { type: 'text' as const, text: `Updated note ${note.id} for contact ${note.contact.name}.` } ], structuredContent: { action, noteId, note } }; } if (action === 'delete') { if (!noteId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide noteId when deleting a note.' } ] }; } await client.deleteNote(noteId); logger.info({ noteId }, 'Deleted Monica note'); return { content: [ { type: 'text' as const, text: `Deleted note ID ${noteId}.` } ], structuredContent: { action, noteId, deleted: true } }; } return { isError: true as const, content: [ { type: 'text' as const, text: `Unsupported action: ${action}.` } ] }; } );
  • Invocation of registerNoteTools as part of the overall tool registration sequence in registerTools.
    registerNoteTools(context);
  • Helper function to normalize raw Monica API note data to a consistent structured format, used in handler responses.
    export function normalizeNote(note: MonicaNote) { return { id: note.id, body: note.body, isFavorited: note.is_favorited, favoritedAt: note.favorited_at ?? undefined, contactId: note.contact.id, contact: normalizeContactSummary(note.contact), createdAt: note.created_at, updatedAt: note.updated_at }; }

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