Skip to main content
Glama

add_faction

Create and define a faction or organization within the MemoryMesh game world by specifying its name, type, description, goals, and leader for immersive storytelling and gameplay.

Instructions

A faction or organization operating within the game world.

Input Schema

NameRequiredDescriptionDefault
factionYes

Input Schema (JSON Schema)

{ "properties": { "faction": { "additionalProperties": { "description": "Additional property value", "type": "string" }, "properties": { "description": { "description": "A detailed description of the faction.", "type": "string" }, "goals": { "description": "The main objectives or goals of the faction.", "items": { "description": "Item in goals array", "type": "string" }, "type": "array" }, "leader": { "description": "The entity leading this faction.", "items": { "description": "Item in leader array", "type": "string" }, "type": "array" }, "name": { "description": "The name of the faction or organization.", "type": "string" }, "type": { "description": "The type of the faction.", "type": "string" } }, "required": [ "name", "type", "description" ], "type": "object" } }, "required": [ "faction" ], "type": "object" }

Implementation Reference

  • Core handler function for all dynamic schema tools including 'add_faction'. Parses tool name to extract operation and schema, then dispatches to specific logic. For 'add', validates uniqueness, creates structured nodes/edges from input data using the schema, and persists atomically.
    public async handleToolCall( toolName: string, args: Record<string, any>, knowledgeGraphManager: ApplicationManager ): Promise<ToolResponse> { const match = toolName.match(/^(add|update|delete)_(.+)$/); if (!match) { return formatToolError({ operation: toolName, error: `Invalid tool name format: ${toolName}`, suggestions: ["Tool name must follow pattern: 'add|update|delete_<schemaName>'"] }); } const [, operation, schemaName] = match; const schemaBuilder = this.schemas.get(schemaName); if (!schemaBuilder) { return formatToolError({ operation: toolName, error: `Schema not found: ${schemaName}`, context: {availableSchemas: Array.from(this.schemas.keys())}, suggestions: ["Verify schema name exists"] }); } try { const schema = schemaBuilder.build(); switch (operation) { case 'add': { const nodeData = args[schemaName]; const existingNodes = await knowledgeGraphManager.openNodes([nodeData.name]); if (existingNodes.nodes.length > 0) { throw new Error(`Node already exists: ${nodeData.name}`); } const {nodes, edges} = await createSchemaNode(nodeData, schema, schemaName); await knowledgeGraphManager.beginTransaction(); try { await knowledgeGraphManager.addNodes(nodes); if (edges.length > 0) { await knowledgeGraphManager.addEdges(edges); } await knowledgeGraphManager.commit(); return formatToolResponse({ data: {nodes, edges}, actionTaken: `Created ${schemaName}: ${nodeData.name}` }); } catch (error) { await knowledgeGraphManager.rollback(); throw error; } } case 'update': { return handleSchemaUpdate( args[`update_${schemaName}`], schema, schemaName, knowledgeGraphManager ); } case 'delete': { const {name} = args[`delete_${schemaName}`]; if (!name) { return formatToolError({ operation: toolName, error: `Name is required to delete a ${schemaName}`, suggestions: ["Provide the 'name' parameter"] }); } return handleSchemaDelete(name, schemaName, knowledgeGraphManager); } default: return formatToolError({ operation: toolName, error: `Unknown operation: ${operation}`, suggestions: ["Use 'add', 'update', or 'delete'"] }); } } catch (error) { return formatToolError({ operation: toolName, error: error instanceof Error ? error.message : 'Unknown error occurred', context: {args}, suggestions: [ "Check input parameters against schema", "Verify entity existence for updates/deletes" ], recoverySteps: [ "Review schema requirements", "Ensure all required fields are provided" ] }); } }
  • Initializes the dynamic tool registry by loading all *.schema.json files (e.g. faction.schema.json), creating SchemaBuilder instances, generating Tool definitions (add_faction, update_faction, delete_faction), and caching them.
    public async initialize(): Promise<void> { try { const SCHEMAS_DIR = CONFIG.PATHS.SCHEMAS_DIR; const schemaFiles = await fs.readdir(SCHEMAS_DIR); // Process schema files for (const file of schemaFiles) { if (file.endsWith('.schema.json')) { const schemaName = path.basename(file, '.schema.json'); const schema = await SchemaLoader.loadSchema(schemaName); this.schemas.set(schemaName, schema); } } // Generate tools for each schema for (const [schemaName, schema] of this.schemas.entries()) { const tools = await this.generateToolsForSchema(schemaName, schema); tools.forEach(tool => this.toolsCache.set(tool.name, tool)); } console.error(`[DynamicSchemaTools] Initialized ${this.schemas.size} schemas and ${this.toolsCache.size} tools`); } catch (error) { console.error('[DynamicSchemaTools] Initialization error:', error); throw error; } }
  • Central tools registry initialization that includes dynamic schema tools (like add_faction) alongside static tools by calling into dynamicToolManager and merging into master tools Map.
    async initialize(knowledgeGraphManager: ApplicationManager): Promise<void> { if (this.initialized) { return; } try { this.knowledgeGraphManager = knowledgeGraphManager; // Register static tools allStaticTools.forEach(tool => { this.tools.set(tool.name, tool); }); // Initialize and register dynamic tools await dynamicToolManager.initialize(); dynamicToolManager.getTools().forEach(tool => { this.tools.set(tool.name, tool); }); this.initialized = true; console.error(`[ToolsRegistry] Initialized with ${this.tools.size} tools`); } catch (error) { console.error('[ToolsRegistry] Initialization error:', error); throw error; } }
  • Helper function called by add handler to transform schema input data into concrete Node(s) and Edge(s) for the graph, handling metadata formatting and relationship edge creation based on schema relationships config.
    export async function createSchemaNode( data: NodeData, schema: SchemaConfig, nodeType: string ): Promise<ProcessedNodeResult> { try { const {metadataConfig, relationships} = schema; const metadata: string[] = []; const nodes: Node[] = []; const edges: Edge[] = []; // Create excluded fields set const excludedFields = new Set<string>([ 'name', ...metadataConfig.requiredFields, ...metadataConfig.optionalFields, ...(metadataConfig.excludeFields || []), ]); if (relationships) { Object.keys(relationships).forEach(field => excludedFields.add(field)); } // Process required fields for (const field of metadataConfig.requiredFields) { if (data[field] === undefined) { throw new Error(`Required field "${field}" is missing`); } if (!relationships || !relationships[field]) { metadata.push(formatMetadataEntry(field, data[field])); } } // Process optional fields for (const field of metadataConfig.optionalFields) { if (data[field] !== undefined && (!relationships || !relationships[field])) { metadata.push(formatMetadataEntry(field, data[field])); } } // Process relationships if (relationships) { for (const [field, config] of Object.entries(relationships)) { if (data[field]) { const value = data[field]; if (Array.isArray(value)) { for (const target of value) { edges.push({ type: 'edge', from: data.name, to: target, edgeType: config.edgeType }); } } else { edges.push({ type: 'edge', from: data.name, to: value as string, edgeType: config.edgeType }); } metadata.push(formatMetadataEntry(field, value)); } } } // Process additional fields for (const [key, value] of Object.entries(data)) { if (!excludedFields.has(key) && value !== undefined) { metadata.push(formatMetadataEntry(key, value)); } } // Create the main node const node: Node = { type: 'node', name: data.name, nodeType, metadata }; nodes.push(node); return {nodes, edges}; } catch (error) { throw error; } }
  • Builds the final SchemaConfig from loaded JSON via SchemaLoader, which provides the inputSchema used as Tool.inputSchema for 'add_faction' and defines properties/relationships/metadata rules used in processing.
    build(): SchemaConfig { return { ...this.schema as SchemaConfig, relationships: Object.fromEntries(this.relationships), metadataConfig: this.metadataConfig }; }

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