Skip to main content
Glama
formatters.ts13.5 kB
import type { MonicaActivity, MonicaActivityType, MonicaActivityTypeCategory, MonicaAddress, MonicaContact, MonicaContactField, MonicaContactFieldType, MonicaCountry, MonicaCurrency, MonicaDebt, MonicaGender, MonicaGift, MonicaGroup, MonicaDocument, MonicaOccupation, MonicaReminder, MonicaRelationship, MonicaRelationshipType, MonicaRelationshipTypeGroup, MonicaNote, MonicaTask, MonicaTag, MonicaConversation, MonicaConversationMessage, MonicaCall, MonicaPhoto } from '../types.js'; export function normalizeContactSummary(contact: MonicaContact) { return { id: contact.id, name: [contact.first_name, contact.last_name].filter(Boolean).join(' ').trim(), nickname: contact.nickname ?? undefined, gender: contact.gender ?? undefined, emails: contact.information?.emails?.map((email) => email.value) ?? [], phones: contact.information?.phones?.map((phone) => phone.value) ?? [], isPartial: contact.is_partial }; } export function normalizeContactDetail(contact: MonicaContact) { const rawContactFields = getContactFields(contact); return { ...normalizeContactSummary(contact), description: contact.information?.description ?? undefined, dates: contact.information?.dates ?? [], createdAt: contact.created_at, updatedAt: contact.updated_at, customFields: rawContactFields.map(normalizeContactField), tags: contact.tags ? contact.tags.map(normalizeTag) : [] }; } export function buildContactSummary(contact: MonicaContact): string { const name = [contact.first_name, contact.last_name].filter(Boolean).join(' ').trim(); const emails = contact.information?.emails?.map((email) => email.value) ?? []; const phones = contact.information?.phones?.map((phone) => phone.value) ?? []; const rawContactFields = getContactFields(contact); const parts = [name || `Contact #${contact.id}`]; if (emails.length) { parts.push(`Emails: ${emails.join(', ')}`); } if (phones.length) { parts.push(`Phones: ${phones.join(', ')}`); } // Include contact fields if available if (rawContactFields.length > 0) { const fieldLines = rawContactFields.map((field) => { const typeName = field.contact_field_type?.name || 'Unknown'; const value = field.data ?? ''; return `${typeName}: ${value}`; }); parts.push(`Contact Fields:\n ${fieldLines.join('\n ')}`); } if (contact.information?.description) { parts.push(`Notes: ${contact.information.description}`); } if (contact.tags && contact.tags.length) { const tagNames = contact.tags.map((tag) => tag.name).join(', '); parts.push(`Tags: ${tagNames}`); } return parts.join('\n'); } function getContactFields(contact: MonicaContact): MonicaContactField[] { const candidate = (contact as MonicaContact & { contactfields?: MonicaContactField[]; }).contactFields; if (candidate && Array.isArray(candidate)) { return candidate; } const legacy = (contact as { contactfields?: MonicaContactField[] }).contactfields; if (legacy && Array.isArray(legacy)) { return legacy; } return []; } export function normalizeTask(task: MonicaTask) { return { id: task.id, title: task.title, description: task.description ?? undefined, completed: task.completed, status: task.completed ? 'completed' : 'open', completedAt: task.completed_at ?? undefined, dueAt: task.due_at ?? undefined, contactId: task.contact?.id, contact: task.contact ? normalizeContactSummary(task.contact) : undefined, createdAt: task.created_at, updatedAt: task.updated_at }; } 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 }; } export function normalizeActivity(activity: MonicaActivity) { return { id: activity.id, summary: activity.summary, description: activity.description ?? undefined, happenedAt: activity.happened_at, activityType: activity.activity_type ? { id: activity.activity_type.id, name: activity.activity_type.name, locationType: activity.activity_type.location_type, category: activity.activity_type.activity_type_category?.name ?? null } : null, attendees: activity.attendees.contacts.map((contact) => normalizeContactSummary(contact)), attendeeCount: activity.attendees.total, createdAt: activity.created_at, updatedAt: activity.updated_at }; } export function normalizeAddress(address: MonicaAddress) { return { id: address.id, name: address.name, street: address.street ?? undefined, city: address.city ?? undefined, province: address.province ?? undefined, postalCode: address.postal_code ?? undefined, country: address.country ? { id: address.country.id, name: address.country.name, iso: address.country.iso } : null, contact: normalizeContactSummary(address.contact), createdAt: address.created_at ?? undefined, updatedAt: address.updated_at ?? undefined }; } export function normalizeContactFieldType(type: MonicaContactFieldType) { return { id: type.id, name: type.name, icon: type.fontawesome_icon ?? undefined, protocol: type.protocol ?? undefined, delible: typeof type.delible === 'boolean' ? type.delible : type.delible === 1, kind: type.type ?? undefined, createdAt: type.created_at ?? undefined, updatedAt: type.updated_at ?? undefined }; } export function normalizeContactField(field: MonicaContactField) { return { id: field.id, value: field.data, type: normalizeContactFieldType(field.contact_field_type), contactId: field.contact.id, createdAt: field.created_at ?? undefined, updatedAt: field.updated_at ?? undefined }; } export function normalizeActivityType(activityType: MonicaActivityType) { return { id: activityType.id, name: activityType.name, locationType: activityType.location_type ?? undefined, category: activityType.activity_type_category ? normalizeActivityTypeCategory(activityType.activity_type_category) : null, createdAt: activityType.created_at ?? undefined, updatedAt: activityType.updated_at ?? undefined }; } export function normalizeActivityTypeCategory(category: MonicaActivityTypeCategory) { return { id: category.id, name: category.name, createdAt: category.created_at ?? undefined, updatedAt: category.updated_at ?? undefined }; } export function normalizeCountry(country: MonicaCountry) { return { id: country.id, name: country.name, iso: country.iso }; } export function normalizeGender(gender: MonicaGender) { return { id: gender.id, name: gender.name, createdAt: gender.created_at ?? undefined, updatedAt: gender.updated_at ?? undefined }; } export function normalizeRelationshipType(type: MonicaRelationshipType) { return { id: type.id, name: type.name, reverseName: type.name_reverse_relationship, groupId: type.relationship_type_group_id ?? undefined, isDeletable: Boolean(type.delible), createdAt: type.created_at ?? undefined, updatedAt: type.updated_at ?? undefined }; } export function normalizeRelationship(relationship: MonicaRelationship) { return { id: relationship.id, contactId: relationship.contact_is.id, contact: normalizeContactSummary(relationship.contact_is), relatedContactId: relationship.of_contact.id, relatedContact: normalizeContactSummary(relationship.of_contact), relationshipType: normalizeRelationshipType(relationship.relationship_type), createdAt: relationship.created_at, updatedAt: relationship.updated_at }; } export function normalizeGroup(group: MonicaGroup) { return { id: group.id, name: group.name, contactCount: group.contacts.length, contacts: group.contacts.map(normalizeContactSummary), createdAt: group.created_at ?? undefined, updatedAt: group.updated_at ?? undefined }; } export function normalizeReminder(reminder: MonicaReminder) { return { id: reminder.id, title: reminder.title, description: reminder.description ?? undefined, frequencyType: reminder.frequency_type, frequencyNumber: reminder.frequency_number ?? undefined, lastTriggeredDate: reminder.last_triggered_date ?? undefined, nextExpectedDate: reminder.next_expected_date ?? undefined, contactId: reminder.contact.id, contact: normalizeContactSummary(reminder.contact), createdAt: reminder.created_at, updatedAt: reminder.updated_at }; } export function normalizeRelationshipTypeGroup(group: MonicaRelationshipTypeGroup) { return { id: group.id, name: group.name, isDeletable: Boolean(group.delible), createdAt: group.created_at ?? undefined, updatedAt: group.updated_at ?? undefined }; } export function normalizeConversationMessage(message: MonicaConversationMessage) { return { id: message.id, content: message.content, writtenAt: message.written_at ?? undefined, writtenByMe: message.written_by_me, contactId: message.contact.id, contact: normalizeContactSummary(message.contact), createdAt: message.created_at, updatedAt: message.updated_at }; } export function normalizeConversation(conversation: MonicaConversation) { return { id: conversation.id, happenedAt: conversation.happened_at ?? undefined, contactId: conversation.contact.id, contact: normalizeContactSummary(conversation.contact), channel: normalizeContactFieldType(conversation.contact_field_type), messages: conversation.messages.map(normalizeConversationMessage), createdAt: conversation.created_at, updatedAt: conversation.updated_at }; } export function normalizeCall(call: MonicaCall) { return { id: call.id, contactId: call.contact.id, contact: normalizeContactSummary(call.contact), calledAt: call.called_at ?? undefined, content: call.content ?? undefined, createdAt: call.created_at, updatedAt: call.updated_at }; } export function normalizeTag(tag: MonicaTag) { return { id: tag.id, name: tag.name, nameSlug: tag.name_slug, createdAt: tag.created_at, updatedAt: tag.updated_at }; } export function normalizeCurrency(currency: MonicaCurrency) { return { id: currency.id, iso: currency.iso, name: currency.name, symbol: currency.symbol ?? undefined }; } export function normalizeOccupation(occupation: MonicaOccupation) { return { id: occupation.id, title: occupation.title, description: occupation.description ?? undefined, salary: occupation.salary ?? undefined, salaryUnit: occupation.salary_unit ?? undefined, currentlyWorksHere: occupation.currently_works_here, startDate: occupation.start_date ?? undefined, endDate: occupation.end_date ?? undefined, company: occupation.company ? { id: occupation.company.id, name: occupation.company.name ?? undefined, website: occupation.company.website ?? undefined, numberOfEmployees: occupation.company.number_of_employees ?? undefined } : null, createdAt: occupation.created_at, updatedAt: occupation.updated_at }; } export function normalizeGift(gift: MonicaGift) { return { id: gift.id, title: gift.title, description: gift.description ?? undefined, receivedOn: gift.received_on, wasGivenByMe: gift.was_given_by_me, amount: gift.amount ?? undefined, currency: gift.currency ? normalizeCurrency(gift.currency) : null, contact: normalizeContactSummary(gift.contact), createdAt: gift.created_at, updatedAt: gift.updated_at }; } export function normalizeDebt(debt: MonicaDebt) { return { id: debt.id, description: debt.description ?? undefined, amount: debt.amount, currency: debt.currency ? normalizeCurrency(debt.currency) : null, happenedAt: debt.happened_at, settled: debt.settled, settledAt: debt.settled_at ?? undefined, contact: normalizeContactSummary(debt.contact), createdAt: debt.created_at, updatedAt: debt.updated_at }; } export function normalizeDocument(document: MonicaDocument) { return { id: document.id, originalFilename: document.original_filename, storedFilename: document.new_filename, filesize: document.filesize, type: document.type ?? undefined, mimeType: document.mime_type ?? undefined, downloadCount: document.number_of_downloads ?? undefined, downloadUrl: document.link, contact: document.contact ? normalizeContactSummary(document.contact) : undefined, createdAt: document.created_at, updatedAt: document.updated_at }; } export function normalizePhoto(photo: MonicaPhoto) { return { id: photo.id, originalFilename: photo.original_filename, storedFilename: photo.new_filename, filesize: photo.filesize, mimeType: photo.mime_type ?? undefined, downloadUrl: photo.link, contact: photo.contact ? normalizeContactSummary(photo.contact) : undefined, createdAt: photo.created_at, updatedAt: photo.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