Skip to main content
Glama
knowall-ai

Neo4j Agent Memory MCP Server

by knowall-ai

create_memory

Store and connect information in a Neo4j knowledge graph by creating new memory nodes with labels and properties, ensuring relationships between existing data.

Instructions

Create a new memory in the knowledge graph. Consider that the memory might already exist, so Search → Create → Connect (its important to try and connect memories)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
labelYesMemory label in lowercase (use list_memory_labels first to check existing labels for consistency) - common: person, place, organization, project, event, topic, object, animal, plant, food, activity, media, skill, document, meeting, task, habit, health, vehicle, tool, idea, goal
propertiesYesInformation to store about this memory (use "name" as primary identifier, e.g. {name: "John Smith", age: 30, occupation: "Engineer"})

Implementation Reference

  • Handler logic for the 'create_memory' tool. Validates input using isCreateMemoryArgs, adds created_at timestamp if missing, creates a Neo4j node with the given label and properties, and returns the result as JSON.
    case 'create_memory': {
      if (!isCreateMemoryArgs(args)) {
        throw new McpError(ErrorCode.InvalidParams, 'Invalid create_memory arguments');
      }
      
      // Add created_at timestamp if not provided
      const properties = {
        ...args.properties,
        created_at: args.properties.created_at || new Date().toISOString()
      };
      
      const result = await neo4j.createNode(args.label, properties);
      
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(result, null, 2),
          },
        ],
      };
    }
  • Tool registration and input schema definition for 'create_memory'. Specifies the name, description, and JSON schema for input validation including required label and properties.
      name: 'create_memory',
      description: 'Create a new memory in the knowledge graph. Consider that the memory might already exist, so Search → Create → Connect (its important to try and connect memories)',
      inputSchema: {
        type: 'object',
        properties: {
          label: {
            type: 'string',
            description: 'Memory label in lowercase (use list_memory_labels first to check existing labels for consistency) - common: person, place, organization, project, event, topic, object, animal, plant, food, activity, media, skill, document, meeting, task, habit, health, vehicle, tool, idea, goal',
          },
          properties: {
            type: 'object',
            description: 'Information to store about this memory (use "name" as primary identifier, e.g. {name: "John Smith", age: 30, occupation: "Engineer"})',
            additionalProperties: true,
          },
        },
        required: ['label', 'properties'],
      },
    },
  • TypeScript interface defining the shape of CreateMemoryArgs used for type checking the tool input.
    export interface CreateMemoryArgs {
      label: string;
      properties: Record<string, any>;
    }
  • Runtime type guard function isCreateMemoryArgs used in the handler to validate tool arguments before execution.
    export function isCreateMemoryArgs(args: unknown): args is CreateMemoryArgs {
      return typeof args === 'object' && args !== null && typeof (args as CreateMemoryArgs).label === 'string' && typeof (args as CreateMemoryArgs).properties === 'object';
    }
  • The tools array exports all MCP tools including create_memory, used for server registration.
    export const tools: Tool[] = [
      {
        name: 'search_memories',
        description: 'Search and retrieve memories from the knowledge graph',
        inputSchema: {
          type: 'object',
          properties: {
            query: {
              type: 'string',
              description: 'Search text to find in any property (searches for ANY word - e.g. "Ben Weeks" finds memories containing "Ben" OR "Weeks")',
            },
            label: {
              type: 'string',
              description: 'Filter by memory label',
            },
            depth: {
              type: 'number',
              description: 'Relationship depth to include, defaults to 1',
            },
            order_by: {
              type: 'string',
              description: 'Sort order such as created_at DESC, name ASC',
            },
            limit: {
              type: 'number',
              description: 'Maximum results to return, defaults to 10, max 200',
            },
            since_date: {
              type: 'string',
              description: 'ISO date string to filter memories created after this date (e.g., "2024-01-01" or "2024-01-01T00:00:00Z")',
            },
          },
          required: [],
        },
      },
      {
        name: 'create_memory',
        description: 'Create a new memory in the knowledge graph. Consider that the memory might already exist, so Search → Create → Connect (its important to try and connect memories)',
        inputSchema: {
          type: 'object',
          properties: {
            label: {
              type: 'string',
              description: 'Memory label in lowercase (use list_memory_labels first to check existing labels for consistency) - common: person, place, organization, project, event, topic, object, animal, plant, food, activity, media, skill, document, meeting, task, habit, health, vehicle, tool, idea, goal',
            },
            properties: {
              type: 'object',
              description: 'Information to store about this memory (use "name" as primary identifier, e.g. {name: "John Smith", age: 30, occupation: "Engineer"})',
              additionalProperties: true,
            },
          },
          required: ['label', 'properties'],
        },
      },
      {
        name: 'create_connection',
        description: 'Create a connection between two memories (its good to have connected memories)',
        inputSchema: {
          type: 'object',
          properties: {
            fromMemoryId: {
              type: 'number',
              description: 'ID of the source memory',
            },
            toMemoryId: {
              type: 'number',
              description: 'ID of the target memory',
            },
            type: {
              type: 'string',
              description: 'Relationship type such as KNOWS, WORKS_ON, LIVES_IN, HAS_SKILL, PARTICIPATES_IN',
            },
            properties: {
              type: 'object',
              description: 'Optional relationship metadata (e.g. {since: "2023-01", role: "Manager", status: "active"})',
              additionalProperties: true,
            },
          },
          required: ['fromMemoryId', 'toMemoryId', 'type'],
        },
      },
      {
        name: 'update_memory',
        description: 'Update properties of an existing memory such as adding more detail or make a change when you find out something new',
        inputSchema: {
          type: 'object',
          properties: {
            nodeId: {
              type: 'number',
              description: 'ID of the memory to update',
            },
            properties: {
              type: 'object',
              description: 'Properties to update/add',
              additionalProperties: true,
            },
          },
          required: ['nodeId', 'properties'],
        },
      },
      {
        name: 'update_connection',
        description: 'Update properties of an existing connection between memories',
        inputSchema: {
          type: 'object',
          properties: {
            fromMemoryId: {
              type: 'number',
              description: 'ID of the source memory',
            },
            toMemoryId: {
              type: 'number',
              description: 'ID of the target memory',
            },
            type: {
              type: 'string',
              description: 'Relationship type to identify which connection to update (e.g. WORKS_AT, KNOWS, MANAGES)',
            },
            properties: {
              type: 'object',
              description: 'Properties to update/add (e.g. {status: "completed", end_date: "2024-01"})',
              additionalProperties: true,
            },
          },
          required: ['fromMemoryId', 'toMemoryId', 'type', 'properties'],
        },
      },
      {
        name: 'delete_memory',
        description: 'Delete a memory and all its connections (use with caution - this permanently removes the memory and all its connections)',
        inputSchema: {
          type: 'object',
          properties: {
            nodeId: {
              type: 'number',
              description: 'ID of the memory to delete',
            },
          },
          required: ['nodeId'],
        },
      },
      {
        name: 'delete_connection',
        description: 'Delete a specific connection between two memories (use with caution - this permanently removes the relationship)',
        inputSchema: {
          type: 'object',
          properties: {
            fromMemoryId: {
              type: 'number',
              description: 'ID of the source memory',
            },
            toMemoryId: {
              type: 'number',
              description: 'ID of the target memory',
            },
            type: {
              type: 'string',
              description: 'Exact relationship type to delete (e.g. WORKS_AT, KNOWS, MANAGES)',
            },
          },
          required: ['fromMemoryId', 'toMemoryId', 'type'],
        },
      },
      {
        name: 'list_memory_labels',
        description: 'List all unique memory labels currently in use with their counts (useful for getting an overview of the knowledge graph)',
        inputSchema: {
          type: 'object',
          properties: {},
          required: [],
        },
      },
      guidanceTool,
    ];
Behavior3/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the 'Search → Create → Connect' workflow which adds important context about checking for existing memories, but doesn't disclose other behavioral traits like whether this is a write operation (implied by 'Create'), what permissions are needed, error handling, or what happens on duplicate creation attempts beyond the workflow advice.

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

Conciseness4/5

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

The description is appropriately sized with two sentences that each serve distinct purposes: the first states the core function, the second provides important workflow guidance. It's front-loaded with the primary purpose and avoids unnecessary elaboration, though the workflow advice could be slightly more concise.

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

Completeness3/5

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

For a creation tool with 2 parameters, 100% schema coverage, but no annotations and no output schema, the description provides adequate context about the workflow but lacks details about behavioral aspects like error conditions, response format, or creation constraints. The workflow guidance is helpful but doesn't fully compensate for the missing structured information.

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

Parameters4/5

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

With 100% schema description coverage, the baseline is 3. The description adds value by explaining the overall workflow context ('Search → Create → Connect') and the importance of checking existing labels, which provides semantic context beyond the schema's technical parameter descriptions. However, it doesn't add specific details about parameter usage beyond what's in the schema.

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

Purpose4/5

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

The description clearly states the action ('Create a new memory') and resource ('in the knowledge graph'), making the purpose immediately understandable. However, it doesn't explicitly differentiate from sibling tools like 'update_memory' or 'search_memories' beyond mentioning the Search → Create → Connect workflow, which is more about usage guidance than sibling differentiation.

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

Usage Guidelines4/5

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

The description provides clear context about when to use this tool through the Search → Create → Connect workflow, advising to check for existing memories first. It implies alternatives like 'search_memories' and 'list_memory_labels' but doesn't explicitly name them or specify when NOT to use this tool.

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

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/knowall-ai/mcp-neo4j-agent-memory'

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