Skip to main content
Glama

update_faction

Modify an existing faction's details in the MemoryMesh knowledge graph, including its name, type, description, goals, leader, or metadata, to reflect updated information accurately.

Instructions

Update an existing faction in the knowledge graph

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
update_factionYes

Implementation Reference

  • Main handler function for all dynamic 'update_<schema>' tools including 'update_faction'. Performs transaction-based update of node metadata and edges.
    export async function handleSchemaUpdate(
        updates: NodeData,
        schema: SchemaConfig,
        nodeType: string,
        applicationManager: ApplicationManager
    ): Promise<ToolResponse> {
        try {
            // Start a transaction to ensure atomic updates
            await applicationManager.beginTransaction();
    
            // Get the complete current state
            const fullGraph = await applicationManager.readGraph();
            const node = fullGraph.nodes.find((n: Node) => n.nodeType === nodeType && n.name === updates.name);
    
            if (!node) {
                await applicationManager.rollback();
                return formatToolError({
                    operation: 'updateSchema',
                    error: `${nodeType} "${updates.name}" not found`,
                    context: {updates, nodeType},
                    suggestions: ["Verify the node exists", "Check node type matches"]
                });
            }
    
            try {
                // Process updates
                const {metadata, edgeChanges} = await updateSchemaNode(
                    updates,
                    node,
                    schema,
                    fullGraph
                );
    
                // Update the node first
                const updatedNode: Node = {
                    ...node,
                    metadata
                };
                await applicationManager.updateNodes([updatedNode]);
    
                // Then handle edges if there are any changes
                if (edgeChanges.remove.length > 0) {
                    await applicationManager.deleteEdges(edgeChanges.remove);
                }
    
                if (edgeChanges.add.length > 0) {
                    await applicationManager.addEdges(edgeChanges.add);
                }
    
                // If everything succeeded, commit the transaction
                await applicationManager.commit();
    
                return formatToolResponse({
                    data: {
                        updatedNode,
                        edgeChanges
                    },
                    actionTaken: `Updated ${nodeType}: ${updatedNode.name}`
                });
    
            } catch (error) {
                // If anything fails, rollback all changes
                await applicationManager.rollback();
                throw error;
            }
    
        } catch (error) {
            if (applicationManager.isInTransaction()) {
                await applicationManager.rollback();
            }
    
            return formatToolError({
                operation: 'updateSchema',
                error: error instanceof Error ? error.message : 'Unknown error occurred',
                context: {updates, schema, nodeType},
                suggestions: [
                    "Check all required fields are provided",
                    "Verify relationship targets exist"
                ],
                recoverySteps: [
                    "Review schema requirements",
                    "Ensure node exists before updating"
                ]
            });
        }
    }
  • Helper function that processes update data for a schema node, computing new metadata array and edge add/remove changes.
    export async function updateSchemaNode(
        updates: NodeData,
        currentNode: Node,
        schema: SchemaConfig,
        currentGraph: Graph
    ): Promise<SchemaUpdateResult> {
        const {metadataConfig, relationships} = schema;
        const metadata = new Map<string, string>();
        const edgeChanges = {
            remove: [] as Edge[],
            add: [] as Edge[]
        };
    
        // Create a set of all schema-defined fields
        const schemaFields = new Set<string>([
            ...metadataConfig.requiredFields,
            ...metadataConfig.optionalFields,
            ...(metadataConfig.excludeFields || []),
            'name',
            'metadata'
        ]);
    
        // Add relationship fields to schema fields
        if (relationships) {
            Object.keys(relationships).forEach(field => schemaFields.add(field));
        }
    
        // Process existing metadata into the Map
        currentNode.metadata.forEach(meta => {
            const colonIndex = meta.indexOf(':');
            if (colonIndex !== -1) {
                const key = meta.substring(0, colonIndex).trim().toLowerCase();
                const value = meta.substring(colonIndex + 1).trim();
                metadata.set(key, value);
            }
        });
    
        const updateMetadataEntry = (key: string, value: unknown) => {
            const formattedValue = Array.isArray(value) ? value.join(', ') : String(value);
            metadata.set(key.toLowerCase(), formattedValue);
        };
    
        // Process standard metadata fields
        const allSchemaFields = [...metadataConfig.requiredFields, ...metadataConfig.optionalFields];
        for (const field of allSchemaFields) {
            if (updates[field] !== undefined && (!relationships || !relationships[field])) {
                updateMetadataEntry(field, updates[field]);
            }
        }
    
        // Process relationships if they exist in the schema
        if (relationships) {
            for (const [field, config] of Object.entries(relationships)) {
                // Only process relationship if it's being updated
                if (updates[field] !== undefined) {
                    // Get all existing edges for this relationship type from this node
                    const existingEdges = currentGraph.edges.filter(edge =>
                        edge.from === currentNode.name &&
                        edge.edgeType === config.edgeType
                    );
    
                    // Only mark edges for removal if they're part of this relationship type
                    edgeChanges.remove.push(...existingEdges);
    
                    // Add new edges
                    const value = updates[field];
                    if (Array.isArray(value)) {
                        value.forEach((target: string) => {
                            edgeChanges.add.push({
                                type: 'edge',
                                from: currentNode.name,
                                to: target,
                                edgeType: config.edgeType
                            });
                        });
                    } else if (value) {
                        edgeChanges.add.push({
                            type: 'edge',
                            from: currentNode.name,
                            to: value as string,
                            edgeType: config.edgeType
                        });
                    }
    
                    updateMetadataEntry(field, value);
                }
            }
        }
    
        // Process additional fields not defined in schema
        for (const [key, value] of Object.entries(updates)) {
            if (!schemaFields.has(key) && value !== undefined) {
                updateMetadataEntry(key, value);
            }
        }
    
        const updatedMetadata = Array.from(metadata).map(([key, value]) => {
            const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
            return `${capitalizedKey}: ${value}`;
        });
    
        return {
            metadata: updatedMetadata,
            edgeChanges
        };
    }
  • Generates the input schema definition and Tool object structure for 'update_<entity>' tools like update_faction.
    createUpdateSchema(excludeFields: Set<string> = new Set()): SchemaConfig {
        const schemaName = this.schema.name!.replace('add_', 'update_');
        const updateSchemaBuilder = new SchemaBuilder(
            schemaName,
            `Update an existing ${schemaName.replace('update_', '')} in the knowledge graph`
        );
    
        const baseProperties = this.schema.inputSchema!.properties[this.schema.name!.replace('add_', '')].properties;
    
        // Copy properties except excluded ones
        Object.entries(baseProperties).forEach(([propName, propValue]) => {
            if (!excludeFields.has(propName)) {
                if (propValue.type === 'array') {
                    updateSchemaBuilder.addArrayProperty(
                        propName,
                        propValue.description,
                        false,
                        propValue.items?.enum
                    );
                } else {
                    updateSchemaBuilder.addStringProperty(
                        propName,
                        propValue.description,
                        false,
                        propValue.enum
                    );
                }
            }
        });
    
        // Copy relationships
        this.relationships.forEach((config, propName) => {
            if (!excludeFields.has(propName)) {
                updateSchemaBuilder.addRelationship(
                    propName,
                    config.edgeType,
                    config.description || 'Relationship property',
                    config.nodeType || null
                );
            }
        });
    
        // Add metadata array
        updateSchemaBuilder.addArrayProperty(
            'metadata',
            'An array of metadata contents to replace the existing metadata'
        );
    
        return updateSchemaBuilder.build();
    }
  • Registers the dynamic 'update_<schemaName>' tool (e.g. update_faction) by generating its Tool definition from schema and adding to cache.
    private async generateToolsForSchema(schemaName: string, schema: SchemaBuilder): Promise<Tool[]> {
        const tools: Tool[] = [];
        const baseSchema = schema.build();
    
        // Add tool
        tools.push(baseSchema as unknown as Tool);
    
        // Update tool
        const updateSchema = schema.createUpdateSchema();
        tools.push(updateSchema as unknown as Tool);
    
        // Delete tool
        const deleteSchema: Tool = {
            name: `delete_${schemaName}`,
            description: `Delete
            an existing
            ${schemaName}
            from
            the
            knowledge
            graph`,
            inputSchema: {
                type: "object",
                properties: {
                    [`delete_${schemaName}`]: {
                        type: "object",
                        description: `Delete parameters for ${schemaName}`,
                        properties: {
                            name: {
                                type: "string",
                                description: `The name of the ${schemaName} to delete`
                            }
                        },
                        required: ["name"]
                    }
                },
                required: [`delete_${schemaName}`]
            }
        };
    
        tools.push(deleteSchema);
        return tools;
    }
  • Dynamic tool dispatcher that parses toolName 'update_faction' to schemaName='faction' and invokes the update handler.
    case 'update': {
        return handleSchemaUpdate(
            args[`update_${schemaName}`],
            schema,
            schemaName,
            knowledgeGraphManager
        );
    }
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but offers minimal behavioral insight. It states 'update' implying mutation but doesn't disclose permissions needed, whether changes are reversible, rate limits, or response format. This is inadequate for a mutation tool with zero annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no wasted words. It's front-loaded with the core action and resource, making it easy to parse quickly, though this brevity contributes to gaps in other dimensions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (mutation tool with nested objects, 1 parameter at 0% schema coverage, no output schema, and no annotations), the description is severely incomplete. It lacks details on usage, behavior, parameters, and output, making it inadequate for effective tool invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, meaning all parameters are undocumented in the schema. The description adds no information about parameters beyond the tool name, failing to compensate for the coverage gap. It doesn't explain the nested 'update_faction' object or its properties like 'name' or 'goals'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the action ('update') and resource ('existing faction in the knowledge graph'), which is clear but basic. It doesn't distinguish this tool from sibling update tools like update_artifact or update_npc, nor does it specify what aspects of a faction can be updated beyond the generic term.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing an existing faction), exclusions, or comparisons with similar tools like add_faction or delete_faction, leaving the agent without context for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

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/CheMiguel23/MemoryMesh'

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