Skip to main content
Glama

monica_manage_relationship

Manage relationships between contacts in Monica CRM by listing, viewing, creating, updating, or deleting connections using relationship types.

Instructions

List, inspect, create, update, or delete relationships between contacts. Provide relationshipTypeId or relationshipTypeName to identify the connection.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYes
relationshipIdNo
contactIdNo
limitNo
pageNo
payloadNo

Implementation Reference

  • Main handler function for the 'monica_manage_relationship' tool. Implements switch statement handling actions: list, get, create, update, delete relationships using MonicaClient methods.
    async ({ action, relationshipId, contactId, limit, page, payload }) => { switch (action) { case 'list': { if (!contactId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactId when listing relationships.' } ] }; } const response = await client.listRelationships({ contactId, limit, page }); const relationships = response.data.map(normalizeRelationship); const pagination = response.meta ? { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } : undefined; const text = relationships.length ? `Found ${relationships.length} relationship${relationships.length === 1 ? '' : 's'} for contact ${contactId}.` : `No relationships found for contact ${contactId}.`; const structuredContent: { action: typeof action; contactId: number; relationships: ReturnType<typeof normalizeRelationship>[]; pagination?: { currentPage: number; lastPage: number; perPage: number; total: number; }; } = { action, contactId, relationships }; if (pagination) { structuredContent.pagination = pagination; } return { content: [ { type: 'text' as const, text } ], structuredContent }; } case 'get': { if (!relationshipId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipId when retrieving a relationship.' } ] }; } const response = await client.getRelationship(relationshipId); const relationship = normalizeRelationship(response.data); return { content: [ { type: 'text' as const, text: `Relationship ${relationship.relationshipType.name} between ${relationship.contact.name} and ${relationship.relatedContact.name}.` } ], structuredContent: { action, relationshipId, relationship } }; } case 'create': { if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactIsId, ofContactId, and relationshipTypeId or relationshipTypeName when creating a relationship.' } ] }; } const relationshipTypeId = await resolveRelationshipTypeId(client, { relationshipTypeId: payload.relationshipTypeId, relationshipTypeName: payload.relationshipTypeName }); const input = toRelationshipCreatePayload({ ...payload, relationshipTypeId }); const response = await client.createRelationship(input); const relationship = normalizeRelationship(response.data); logger.info({ relationshipId: relationship.id }, 'Created Monica relationship'); return { content: [ { type: 'text' as const, text: `Linked ${relationship.contact.name} and ${relationship.relatedContact.name} as ${relationship.relationshipType.name}.` } ], structuredContent: { action, relationship } }; } case 'update': { if (!relationshipId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipId when updating a relationship.' } ] }; } if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipTypeId or relationshipTypeName when updating a relationship.' } ] }; } const relationshipTypeId = await resolveRelationshipTypeId(client, { relationshipTypeId: payload.relationshipTypeId, relationshipTypeName: payload.relationshipTypeName }); const input = toRelationshipUpdatePayload({ ...payload, relationshipTypeId }); const response = await client.updateRelationship(relationshipId, input); const relationship = normalizeRelationship(response.data); logger.info({ relationshipId }, 'Updated Monica relationship'); return { content: [ { type: 'text' as const, text: `Updated relationship ${relationshipId} to ${relationship.relationshipType.name}.` } ], structuredContent: { action, relationshipId, relationship } }; } case 'delete': { if (!relationshipId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipId when deleting a relationship.' } ] }; } const result = await client.deleteRelationship(relationshipId); logger.info({ relationshipId }, 'Deleted Monica relationship'); return { content: [ { type: 'text' as const, text: `Deleted relationship ID ${relationshipId}.` } ], structuredContent: { action, relationshipId, result } }; } default: return { isError: true as const, content: [ { type: 'text' as const, text: `Unsupported action: ${action}.` } ] }; } } );
  • Registration of the 'monica_manage_relationship' tool via server.registerTool call within registerRelationshipTools function.
    export function registerRelationshipTools(context: ToolRegistrationContext): void { const { server, client, logger } = context; server.registerTool( 'monica_manage_relationship', { title: 'Manage Monica relationships', description: 'List, inspect, create, update, or delete relationships between contacts. Provide relationshipTypeId or relationshipTypeName to identify the connection.', inputSchema: { action: z.enum(['list', 'get', 'create', 'update', 'delete']), relationshipId: 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: relationshipPayloadSchema.optional() } }, async ({ action, relationshipId, contactId, limit, page, payload }) => { switch (action) { case 'list': { if (!contactId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactId when listing relationships.' } ] }; } const response = await client.listRelationships({ contactId, limit, page }); const relationships = response.data.map(normalizeRelationship); const pagination = response.meta ? { currentPage: response.meta.current_page, lastPage: response.meta.last_page, perPage: response.meta.per_page, total: response.meta.total } : undefined; const text = relationships.length ? `Found ${relationships.length} relationship${relationships.length === 1 ? '' : 's'} for contact ${contactId}.` : `No relationships found for contact ${contactId}.`; const structuredContent: { action: typeof action; contactId: number; relationships: ReturnType<typeof normalizeRelationship>[]; pagination?: { currentPage: number; lastPage: number; perPage: number; total: number; }; } = { action, contactId, relationships }; if (pagination) { structuredContent.pagination = pagination; } return { content: [ { type: 'text' as const, text } ], structuredContent }; } case 'get': { if (!relationshipId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipId when retrieving a relationship.' } ] }; } const response = await client.getRelationship(relationshipId); const relationship = normalizeRelationship(response.data); return { content: [ { type: 'text' as const, text: `Relationship ${relationship.relationshipType.name} between ${relationship.contact.name} and ${relationship.relatedContact.name}.` } ], structuredContent: { action, relationshipId, relationship } }; } case 'create': { if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide contactIsId, ofContactId, and relationshipTypeId or relationshipTypeName when creating a relationship.' } ] }; } const relationshipTypeId = await resolveRelationshipTypeId(client, { relationshipTypeId: payload.relationshipTypeId, relationshipTypeName: payload.relationshipTypeName }); const input = toRelationshipCreatePayload({ ...payload, relationshipTypeId }); const response = await client.createRelationship(input); const relationship = normalizeRelationship(response.data); logger.info({ relationshipId: relationship.id }, 'Created Monica relationship'); return { content: [ { type: 'text' as const, text: `Linked ${relationship.contact.name} and ${relationship.relatedContact.name} as ${relationship.relationshipType.name}.` } ], structuredContent: { action, relationship } }; } case 'update': { if (!relationshipId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipId when updating a relationship.' } ] }; } if (!payload) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipTypeId or relationshipTypeName when updating a relationship.' } ] }; } const relationshipTypeId = await resolveRelationshipTypeId(client, { relationshipTypeId: payload.relationshipTypeId, relationshipTypeName: payload.relationshipTypeName }); const input = toRelationshipUpdatePayload({ ...payload, relationshipTypeId }); const response = await client.updateRelationship(relationshipId, input); const relationship = normalizeRelationship(response.data); logger.info({ relationshipId }, 'Updated Monica relationship'); return { content: [ { type: 'text' as const, text: `Updated relationship ${relationshipId} to ${relationship.relationshipType.name}.` } ], structuredContent: { action, relationshipId, relationship } }; } case 'delete': { if (!relationshipId) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Provide relationshipId when deleting a relationship.' } ] }; } const result = await client.deleteRelationship(relationshipId); logger.info({ relationshipId }, 'Deleted Monica relationship'); return { content: [ { type: 'text' as const, text: `Deleted relationship ID ${relationshipId}.` } ], structuredContent: { action, relationshipId, result } }; } default: return { isError: true as const, content: [ { type: 'text' as const, text: `Unsupported action: ${action}.` } ] }; } } ); }
  • inputSchema defining the tool's input parameters: action, relationshipId, contactId, limit, page, payload.
    inputSchema: { action: z.enum(['list', 'get', 'create', 'update', 'delete']), relationshipId: 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: relationshipPayloadSchema.optional() }
  • relationshipPayloadSchema for the payload parameter, defining contactIsId, ofContactId, relationshipTypeId, relationshipTypeName.
    const relationshipPayloadSchema = z.object({ contactIsId: z.number().int().positive().optional(), ofContactId: z.number().int().positive().optional(), relationshipTypeId: z.number().int().positive().optional(), relationshipTypeName: z.string().min(1).max(255).optional() }); type RelationshipPayloadForm = z.infer<typeof relationshipPayloadSchema>;
  • toRelationshipCreatePayload helper function converting payload to CreateRelationshipPayload.
    function toRelationshipCreatePayload( payload: RelationshipPayloadForm & { relationshipTypeId: number } ): CreateRelationshipPayload { if ( typeof payload.contactIsId !== 'number' || typeof payload.ofContactId !== 'number' ) { throw new Error('contactIsId and ofContactId are required to create a relationship.'); } return { contactIsId: payload.contactIsId, ofContactId: payload.ofContactId, relationshipTypeId: payload.relationshipTypeId }; }

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