Skip to main content
Glama

upsert_entities

Insert new entities or update existing ones in the knowledge graph, ensuring data consistency and accuracy for structured reasoning and problem-solving.

Instructions

Create new entities or update existing ones in the knowledge graph using an upsert pattern

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
entitiesYesArray of entities to create or update

Implementation Reference

  • The execute function implementing the core logic of the upsert_entities tool. It processes a list of entities, creating new ones by adding observations, updating existing ones if specified (replacing observations), with timeout protection and detailed results reporting.
    execute: async (args, context) => { const total = args.entities.length; const log = context && context.log ? context.log : { info() {}, error() {}, warn() {}, debug() {} }; const results = { created: [] as string[], updated: [] as string[], failed: [] as {name: string, reason: string}[], incomplete: false }; // Process with timeout protection const startTime = Date.now(); const timeoutMs = 25000; // 25 second timeout for (const entity of args.entities) { try { // Check if we've exceeded our time budget if (Date.now() - startTime > timeoutMs) { results.incomplete = true; break; } // Check if entity exists const existingEntity = graph.entities.get(entity.name); const doesExist = !!existingEntity; // If entity doesn't exist, create it if (!doesExist) { // Add observations for the new entity for (const observation of entity.observations) { await memoryStore.add(entity.name, observation, { version: '1.0' }); } results.created.push(entity.name); } // If entity exists and update flag is true, update it else if (entity.update) { // Update entity type existingEntity.entityType = entity.entityType; // Remove all existing observations and add new ones graph.deleteObservations(entity.name, existingEntity.observations); // Add new observations for (const observation of entity.observations) { await memoryStore.add(entity.name, observation, { version: '1.0' }); } results.updated.push(entity.name); } // Entity exists but update flag is false, skip else { results.failed.push({ name: entity.name, reason: "Entity already exists and update flag is false" }); } } catch (error) { results.failed.push({ name: entity.name, reason: `Error processing entity: ${error}` }); } } // Save final changes await memoryStore.save(); // Return detailed results return JSON.stringify({ created: results.created.length > 0 ? results.created : null, updated: results.updated.length > 0 ? results.updated : null, failed: results.failed.length > 0 ? results.failed : null, incomplete: results.incomplete, message: `Created ${results.created.length} new entities. Updated ${results.updated.length} existing entities. Failed for ${results.failed.length} entities.${ results.incomplete ? ` Operation incomplete due to timeout - ${results.created.length + results.updated.length + results.failed.length} of ${total} entities processed.` : '' }` }); }
  • Zod schema defining the input structure for upsert_entities: array of entities with name, entityType, observations, optional context and update flag.
    export const UpsertEntitiesSchema = z.object({ entities: z.array(z.object({ name: z.string().min(1).describe('Unique identifier for the entity'), entityType: z.string().min(1).describe('Type classification of the entity'), observations: z.array(z.string()).describe('Facts or observations about the entity'), context: z.string().optional().describe('Optional context or situation relevant to this entity (e.g., project, meeting, or scenario)'), update: z.boolean().optional().default(false).describe('If true, will fully replace an existing entity; if false, will only create if entity doesn\'t exist') })).describe('Array of entities to create or update') });
  • Tool registration within registerMemoryTools function using FastMCP server.addTool, specifying name, description, schema reference, and inline execute handler.
    server.addTool({ name: 'upsert_entities', description: 'Create new entities or update existing ones in the knowledge graph using an upsert pattern', parameters: Schemas.UpsertEntitiesSchema, execute: async (args, context) => { const total = args.entities.length; const log = context && context.log ? context.log : { info() {}, error() {}, warn() {}, debug() {} }; const results = { created: [] as string[], updated: [] as string[], failed: [] as {name: string, reason: string}[], incomplete: false }; // Process with timeout protection const startTime = Date.now(); const timeoutMs = 25000; // 25 second timeout for (const entity of args.entities) { try { // Check if we've exceeded our time budget if (Date.now() - startTime > timeoutMs) { results.incomplete = true; break; } // Check if entity exists const existingEntity = graph.entities.get(entity.name); const doesExist = !!existingEntity; // If entity doesn't exist, create it if (!doesExist) { // Add observations for the new entity for (const observation of entity.observations) { await memoryStore.add(entity.name, observation, { version: '1.0' }); } results.created.push(entity.name); } // If entity exists and update flag is true, update it else if (entity.update) { // Update entity type existingEntity.entityType = entity.entityType; // Remove all existing observations and add new ones graph.deleteObservations(entity.name, existingEntity.observations); // Add new observations for (const observation of entity.observations) { await memoryStore.add(entity.name, observation, { version: '1.0' }); } results.updated.push(entity.name); } // Entity exists but update flag is false, skip else { results.failed.push({ name: entity.name, reason: "Entity already exists and update flag is false" }); } } catch (error) { results.failed.push({ name: entity.name, reason: `Error processing entity: ${error}` }); } } // Save final changes await memoryStore.save(); // Return detailed results return JSON.stringify({ created: results.created.length > 0 ? results.created : null, updated: results.updated.length > 0 ? results.updated : null, failed: results.failed.length > 0 ? results.failed : null, incomplete: results.incomplete, message: `Created ${results.created.length} new entities. Updated ${results.updated.length} existing entities. Failed for ${results.failed.length} entities.${ results.incomplete ? ` Operation incomplete due to timeout - ${results.created.length + results.updated.length + results.failed.length} of ${total} entities processed.` : '' }` }); } });

Other Tools

Related Tools

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/flight505/mcp-think-tank'

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