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

TableJSON Schema
NameRequiredDescriptionDefault
factionYes

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
        };
    }
Behavior1/5

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

No annotations are provided, so the description carries full burden for behavioral disclosure. The description fails to indicate this is a creation/mutation tool, doesn't mention permissions needed, side effects, or what happens upon successful execution. It provides no behavioral context beyond the vague noun phrase.

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

Conciseness2/5

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

While technically concise with just one phrase, this is under-specification rather than effective conciseness. The single sentence doesn't front-load critical information about the tool's function. It wastes its limited space on defining a faction rather than explaining the tool's purpose.

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?

For a mutation tool with 1 parameter containing 5 nested properties, 0% schema description coverage, no annotations, and no output schema, the description is completely inadequate. It provides no information about what the tool does, how to use it, what it returns, or any behavioral characteristics.

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 none of the parameters have descriptions in the schema. The tool description provides no information about the single 'faction' parameter or its nested properties (name, type, description, goals, leader). The description doesn't compensate for the complete lack of schema documentation.

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

Purpose1/5

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

The description 'A faction or organization operating within the game world' is a tautology that merely restates the tool name 'add_faction' without specifying what the tool does. It describes what a faction is rather than stating that this tool creates or adds a faction. Compared to sibling tools like 'add_artifact' or 'add_npc', it fails to distinguish its function.

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

Usage Guidelines1/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites, when it's appropriate to add a faction, or how it differs from sibling tools like 'update_faction' or 'delete_faction'. There's no context for usage decisions.

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