MCP HubMCP Hub
evangstav

python-memory-mcp-server

by: evangstav

python memory mcp server

10created 14/12/2024
Visit
python
memory

📌Overview

Purpose: To provide a Model Context Protocol (MCP) server that facilitates knowledge graph management, ensuring data integrity through strict validation rules.

Overview: The Memory MCP Server enables users to efficiently manage entities, relationships, and observations within a structured knowledge graph. It emphasizes data consistency through comprehensive validation rules and offers powerful tools for retrieving, creating, and deleting data.

Key Features:

  • Knowledge Graph Management: Organize and manipulate entities, relations, and observations with strict adherence to validation protocols, promoting data integrity.

  • Comprehensive Validation Rules: Enforces specific naming conventions and uniqueness for entity names, types, and observations to ensure consistent and valid data representation.

  • Rich Querying and Search Capabilities: Supports natural language queries, including temporal and fuzzy matching, allowing users to easily retrieve relevant information with a weighted search mechanism.

  • Flexible API for Entity Interaction: Provides straightforward APIs for creating, retrieving, updating, and deleting entities, as well as managing relationships between them, streamlining user interactions.


Memory MCP Server

A Model Context Protocol (MCP) server that provides knowledge graph functionality for managing entities, relations, and observations in memory, with strict validation rules to maintain data consistency.

Installation

Install the server in Claude Desktop:

mcp install main.py -v MEMORY_FILE_PATH=/path/to/memory.jsonl

Data Validation Rules

Entity Names

  • Must start with a lowercase letter
  • Can contain lowercase letters, numbers, and hyphens
  • Maximum length of 100 characters
  • Must be unique within the graph
  • Examples: python-project, meeting-notes-2024, user-john

Entity Types

Supported types:

  • person: Human entities
  • concept: Abstract ideas or principles
  • project: Work initiatives or tasks
  • document: Documentation
  • tool: Software tools or utilities
  • organization: Companies or groups
  • location: Physical or virtual places
  • event: Time-bound occurrences

Observations

  • Non-empty strings
  • Maximum length of 500 characters
  • Must be unique per entity
  • Should be factual and objective statements
  • Include timestamp when relevant

Relations

Supported relation types:

  • knows: Person to person connection
  • contains: Parent/child relationship
  • uses: Entity utilizing another entity
  • created: Authorship/creation relationship
  • belongs-to: Membership/ownership
  • depends-on: Dependency relationship
  • related-to: Generic relationship

Additional rules:

  • Both source and target entities must exist
  • Self-referential relations are not allowed
  • No circular dependencies
  • Must use predefined relation types

Usage

The server provides tools for managing a knowledge graph:

Get Entity

result = await session.call_tool("get_entity", {
    "entity_name": "example"
})
if not result.success:
    if result.error_type == "NOT_FOUND":
        print(f"Entity not found: {result.error}")
    elif result.error_type == "VALIDATION_ERROR":
        print(f"Invalid input: {result.error}")
    else:
        print(f"Error: {result.error}")
else:
    entity = result.data
    print(f"Found entity: {entity}")

Get Graph

result = await session.call_tool("get_graph", {})
if result.success:
    graph = result.data
    print(f"Graph data: {graph}")
else:
    print(f"Error retrieving graph: {result.error}")

Create Entities

entities = [
    Entity(
        name="python-project",
        entityType="project",
        observations=["Started development on 2024-01-29"]
    ),
    Entity(
        name="john-doe",
        entityType="person",
        observations=["Software engineer", "Joined team in 2024"]
    )
]
result = await session.call_tool("create_entities", {
    "entities": entities
})
if not result.success:
    if result.error_type == "VALIDATION_ERROR":
        print(f"Invalid entity data: {result.error}")
    else:
        print(f"Error creating entities: {result.error}")

Add Observation

result = await session.call_tool("add_observation", {
    "entity": "python-project",
    "observation": "Completed initial prototype"
})
if not result.success:
    if result.error_type == "NOT_FOUND":
        print(f"Entity not found: {result.error}")
    elif result.error_type == "VALIDATION_ERROR":
        print(f"Invalid observation: {result.error}")
    else:
        print(f"Error adding observation: {result.error}")

Create Relation

result = await session.call_tool("create_relation", {
    "from_entity": "john-doe",
    "to_entity": "python-project",
    "relation_type": "created"
})
if not result.success:
    if result.error_type == "NOT_FOUND":
        print(f"Entity not found: {result.error}")
    elif result.error_type == "VALIDATION_ERROR":
        print(f"Invalid relation data: {result.error}")
    else:
        print(f"Error creating relation: {result.error}")

Search Memory

result = await session.call_tool("search_memory", {
    "query": "most recent workout"
})
if result.success:
    if result.error_type == "NO_RESULTS":
        print(f"No results found: {result.error}")
    else:
        results = result.data
        print(f"Search results: {results}")
else:
    print(f"Error searching memory: {result.error}")

Search supports:

  • Temporal queries (e.g., "most recent", "last", "latest")
  • Activity queries (e.g., "workout", "exercise")
  • General entity searches
  • Fuzzy matching with 80% similarity threshold
  • Weighted search across entity names (weight: 1.0), entity types (weight: 0.8), and observations (weight: 0.6)

Delete Entities

result = await session.call_tool("delete_entities", {
    "names": ["python-project", "john-doe"]
})
if not result.success:
    if result.error_type == "NOT_FOUND":
        print(f"Entity not found: {result.error}")
    else:
        print(f"Error deleting entities: {result.error}")

Delete Relation

result = await session.call_tool("delete_relation", {
    "from_entity": "john-doe",
    "to_entity": "python-project"
})
if not result.success:
    if result.error_type == "NOT_FOUND":
        print(f"Entity not found: {result.error}")
    else:
        print(f"Error deleting relation: {result.error}")

Flush Memory

result = await session.call_tool("flush_memory", {})
if not result.success:
    print(f"Error flushing memory: {result.error}")

Error Types

The server uses these error types:

  • NOT_FOUND: Entity or resource not found
  • VALIDATION_ERROR: Invalid input data
  • INTERNAL_ERROR: Server-side error
  • ALREADY_EXISTS: Resource already exists
  • INVALID_RELATION: Invalid relation between entities

Response Models

All tools return typed responses using these models:

EntityResponse

class EntityResponse(BaseModel):
    success: bool
    data: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
    error_type: Optional[str] = None

GraphResponse

class GraphResponse(BaseModel):
    success: bool
    data: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
    error_type: Optional[str] = None

OperationResponse

class OperationResponse(BaseModel):
    success: bool
    error: Optional[str] = None
    error_type: Optional[str] = None

Development

Running Tests

pytest tests/

Adding New Features

  1. Update validation rules in validation.py
  2. Add tests in tests/test_validation.py
  3. Implement changes in knowledge_graph_manager.py