Skip to content

A production-ready Model Context Protocol server implementing three-tiered memory architecture for vertical agents.

License

Notifications You must be signed in to change notification settings

cbuntingde/memory-mcp-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Copyright 2025 Chris Bunting cbuntingde@gmail.com

Memory MCP Server

MIT License

Memory MCP Server

A production-ready Model Context Protocol (MCP) server implementing a robust three-tiered memory architecture designed for vertical AI agents and applications requiring sophisticated context management.

Glama Badge License: MIT Node.js Version TypeScript

Overview

The Memory MCP Server provides a comprehensive, persistent, and session-based memory management system through three specialized and configurable memory types:

  • Short-term Memory: Volatile, session-specific context with a configurable Time-To-Live (TTL), ideal for maintaining conversational state or temporary operational data. (Default TTL: 30 minutes)
  • Long-term Memory: Persistent storage for user profiles, preferences, demographics, and other stable, long-lived data that defines user characteristics.
  • Episodic Memory: A searchable, time-stamped log of events, interactions, and experiences, enriched with sentiment analysis and tagging for advanced context retrieval and pattern recognition.

This architecture enables AI agents to maintain continuity across sessions, personalize interactions based on historical data, and reason over past events to provide more intelligent and context-aware responses.

Architecture

Project Structure

The project is organized with a clear separation of concerns, promoting maintainability, scalability, and testability.

memory-mcp-server/
├── src/
│   ├── types/              # TypeScript type definitions and interfaces
│   │   └── index.ts
│   ├── store/              # Core memory storage and retrieval logic
│   │   └── MemoryStore.ts
│   ├── handlers/           # MCP protocol handlers (Tools, Resources, Prompts)
│   │   ├── ResourceHandlers.ts
│   │   ├── ToolHandlers.ts
│   │   └── PromptHandlers.ts
│   ├── config/             # Server configuration and settings management
│   │   └── ServerConfig.ts
│   ├── utils/              # Shared utility functions (logging, validation, etc.)
│   │   ├── Logger.ts
│   │   └── Validation.ts
│   └── index.ts            # Main server entry point and MCP server setup
├── memory-data/            # Default directory for persistent data storage
│   ├── long-term.json      # Stores long-term user profiles and preferences
│   └── episodic.json       # Stores episodic event and experience logs
├── test-memory.js          # Functional test suite
├── package.json            # Project dependencies and scripts
├── tsconfig.json           # TypeScript compiler configuration
├── .gitignore              # Git ignore rules
├── LICENSE                 # MIT license file
└── README.md               # This file

Memory Tiers

Memory Type Persistence Primary Use Case TTL Storage Mechanism
Short-term In-memory only Session context, temporary state, conversational flow. Configurable (default: 30 minutes) Volatile RAM
Long-term Disk-based (JSON) User profiles, preferences, demographics, contact info. Permanent (until explicitly deleted) memory-data/long-term.json
Episodic Disk-based (JSON) Event history, experiences, interactions, sentiment tracking. Permanent (until explicitly deleted) memory-data/episodic.json

Data Flow

  1. Request: An MCP client (e.g., an AI agent) sends a request via a tool, resource, or prompt.
  2. Handler: The appropriate handler (ToolHandlers.ts, ResourceHandlers.ts, or PromptHandlers.ts) receives and parses the request.
  3. Validation: Input parameters are validated using Validation.ts.
  4. Store Interaction: The handler interacts with MemoryStore.ts to perform CRUD operations on the respective memory tier.
  5. Persistence: For long-term and episodic memories, data is atomically written to JSON files on disk.
  6. Response: The result is formatted and returned to the MCP client.
  7. Logging: All operations are logged via Logger.ts for monitoring and debugging.

Installation

Prerequisites

  • Node.js: Version 16.0 or higher.
  • npm: Version 7.0 or higher (or yarn/pnpm).
  • MCP Client: An application or environment that can connect to and utilize MCP servers (e.g., Cline, Claude Desktop).

Setup

  1. Clone the Repository

    git clone https://github.com/cbuntingde/memory-mcp-server.git
    cd memory-mcp-server
  2. Install Dependencies

    npm install
    # or
    yarn install
    # or
    pnpm install
  3. Build the Project Compile the TypeScript source code into JavaScript.

    npm run build
  4. Configure Your MCP Client You need to inform your MCP client about the Memory Server. This is typically done by adding a configuration entry to your client's settings file (e.g., cline_mcp_settings.json for Cline, or claude_desktop_config.json for Claude Desktop).

    Example MCP Configuration:

    {
      "mcpServers": {
        "memory-server": {
          "command": "node",
          "args": ["./path/to/memory-mcp-server/build/index.js"],
          "env": {
            "MEMORY_DATA_DIR": "./custom-memory-data" // Optional: override default data directory
          },
          "settings": {
            "dataDirectory": "./memory-mcp-server/memory-data", // Optional: can also be set here
            "defaultTTLMinutes": 30, // Optional: override default short-term TTL
            "logLevel": "info" // Optional: set logging level (trace, debug, info, warn, error)
          }
        }
      }
    }

    Replace ./path/to/memory-mcp-server/build/index.js with the actual path to the built index.js file.

API Reference

The server exposes its functionality through MCP Tools, Resources, and Prompts.

Tools

Tools are used for actions that modify or retrieve specific data.

Tool Name Description Required Parameters Optional Parameters
set_short_term_memory Stores a key-value pair in a session's short-term memory. sessionId (string), key (string), value (any JSON-serializable) ttlMinutes (number)
get_short_term_memory Retrieves all data for a given session from short-term memory. sessionId (string) -
set_long_term_memory Creates or updates a user's long-term memory profile. userId (string), data (object) -
get_long_term_memory Retrieves a user's long-term memory profile. userId (string) -
add_episodic_memory Adds a new event or experience to a user's episodic memory. userId (string), event (string) context (string), outcome (string), sentiment ('positive', 'negative', 'neutral'), tags (string[]), sessionId (string)
get_episodic_memory Retrieves all episodic memories for a user, optionally sorted. userId (string) sortBy ('timestamp_asc', 'timestamp_desc', 'sentiment'), limit (number)
search_episodic_memory Searches a user's episodic memory by keyword, tag, or sentiment. userId (string), query (string) searchIn ('event', 'context', 'outcome', 'tags'), limit (number)

Resources

Resources provide access to structured data, typically in JSON format.

Resource URI Description Returns
memory://long-term/{userId} Fetches the complete long-term memory profile for a specific user. JSON object representing the user's profile.
memory://episodic/{userId} Fetches all episodic memory entries for a specific user. JSON array of episodic memory objects.

Prompts

Prompts are templates that guide an AI agent to generate responses based on memory data.

Prompt Name Description Required Arguments Optional Arguments
memory_summary Generates a comprehensive summary of a user's profile and recent history. userId (string) includeEpisodicCount (number, default: 10)
personalization_insights Extracts key personalization opportunities from a user's long-term and episodic data. userId (string) -

Usage Examples

Here are practical examples demonstrating how to interact with the Memory MCP Server using its tools.

Managing a User Profile (Long-term Memory)

// Store comprehensive user preferences and demographics
await client.callTool({
  name: "set_long_term_memory",
  arguments: {
    userId: "user-abc-123",
    data: {
      demographics: {
        age: 42,
        location: "San Francisco, CA",
        occupation: "Software Engineer"
      },
      contact: {
        email: "user@example.com",
        phone: "+1-555-123-4567" // Note: Ensure compliance with privacy regulations
      },
      preferences: {
        seating: "window seat",
        temperature: "cool",
        communicationStyle: "concise",
        interests: ["technology", "hiking", "photography"]
      }
    }
  }
});

// Retrieve the user's profile
const userProfile = await client.callTool({
  name: "get_long_term_memory",
  arguments: {
    userId: "user-abc-123"
  }
});
console.log("User Profile:", userProfile);

Recording and Searching Interactions (Episodic Memory)

// Record a positive customer service interaction
await client.callTool({
  name: "add_episodic_memory",
  arguments: {
    userId: "user-abc-123",
    sessionId: "session-xyz-789",
    event: "Customer inquired about premium features.",
    context: "User was on the pricing page and initiated a support chat.",
    outcome: "Explained premium benefits, user seemed interested.",
    sentiment: "positive",
    tags: ["support", "pricing", "premium-features"]
  }
});

// Search for past interactions related to "pricing"
const pricingInteractions = await client.callTool({
  name: "search_episodic_memory",
  arguments: {
    userId: "user-abc-123",
    query: "pricing",
    searchIn: "event",
    limit: 5
  }
});
console.log("Pricing-related interactions:", pricingInteractions);

Maintaining Session Context (Short-term Memory)

// Store the current state of a user's shopping cart
await client.callTool({
  name: "set_short_term_memory",
  arguments: {
    sessionId: "session-xyz-789",
    key: "shopping_cart",
    value: {
      items: [
        { productId: "prod-001", name: "Memory MCP Server License", quantity: 1, price: 99.99 }
      ],
      total: 99.99,
      currency: "USD"
    },
    ttlMinutes: 60 // Extend TTL for this session
  }
});

// Retrieve the cart later in the session
const currentCart = await client.callTool({
  name: "get_short_term_memory",
  arguments: {
    sessionId: "session-xyz-789"
  }
});
console.log("Current Shopping Cart:", currentCart?.shopping_cart);

Generating a User Summary (Prompt)

// Ask the AI agent to generate a summary of the user
const summaryPrompt = await client.getPrompt({
  name: "memory_summary",
  arguments: {
    userId: "user-abc-123",
    includeEpisodicCount: 15
  }
});
// The 'summaryPrompt' would then be fed to the LLM to generate a textual summary.
console.log("Prompt for LLM:", summaryPrompt.messages[0].content.text);

Data Models

Long-term Memory Structure

Data stored in long-term.json follows this structure:

{
  "userId": {
    "demographics": {
      "age": "number | null",
      "location": "string | null",
      "occupation": "string | null"
    },
    "contact": {
      "email": "string | null",
      "phone": "string | null"
    },
    "preferences": {
      "seating": "string | null",
      "temperature": "string | null",
      "communicationStyle": "string | null",
      "interests": "string[] | null"
    },
    "metadata": {
      "createdAt": "timestamp (ISO 8601 string)",
      "lastUpdated": "timestamp (ISO 8601 string)"
    }
  }
}

Episodic Memory Structure

Data stored in episodic.json follows this structure:

{
  "id": "episodic_{timestamp}_{randomId}",
  "userId": "string",
  "sessionId": "string | null",
  "event": "string",
  "context": "string | null",
  "outcome": "string | null",
  "sentiment": "positive | negative | neutral | null",
  "tags": "string[]",
  "timestamp": "number (Unix epoch in ms)",
  "metadata": {
    "createdAt": "timestamp (ISO 8601 string)"
  }
}

Development

Available Scripts

# Install dependencies
npm install

# Build the project from TypeScript to JavaScript in /build
npm run build

# Build in watch mode for development (auto-recompile on changes)
npm run watch

# Run the functional test suite (requires build first)
npm run test

# Run the MCP Inspector for debugging MCP server interactions
npm run inspector

Testing

The project includes a functional test suite located in test-memory.js. These tests verify the core functionality of all memory operations.

To run the tests:

  1. Ensure the project is built: npm run build
  2. Execute the test script: npm run test or node test-memory.js

The tests will create and use a temporary data directory to avoid interfering with production data.

Code Style and Quality

  • TypeScript: All code is written in TypeScript for type safety and better developer experience.
  • ESLint & Prettier: Configured for consistent code style and quality (ensure you have editor plugins or run linting manually).
  • Logging: Comprehensive logging is implemented using Logger.ts. Log levels can be configured via environment variables or MCP settings.
  • Validation: All external inputs are rigorously validated using Validation.ts to prevent errors and ensure data integrity.

Production Considerations

Performance

  • Memory Operations (Short-term): Typically < 5ms. Operates entirely in memory.
  • Disk Operations (Long-term/Episodic): Typically < 50ms on modern SSDs. File I/O is atomic and synchronous to ensure data consistency.
  • Search Operations (Episodic): Performance scales linearly with the number of records. < 100ms for datasets up to 10,000 records. For larger datasets, consider integrating a dedicated search engine (e.g., Lunr.js, ElasticSearch).
  • Memory Usage: Primarily determined by the size of in-memory short-term data and the active working set of long-term/episodic data loaded from disk.

Security

  • Input Validation: All parameters passed to tools and resources are strictly validated for type, format, and content to prevent injection attacks and malformed data.
  • Data Sanitization: While the server itself doesn't render HTML, data is stored in a way that assumes it might be used in contexts where escaping is necessary.
  • File System Security: The server writes to a specific, configurable directory. Ensure this directory has appropriate permissions to prevent unauthorized access or modification.
  • No External Dependencies: The server has no network dependencies, reducing the attack surface.
  • Local Data Storage: All data is stored locally on the file system. You are responsible for securing the host machine and the data directory.

Reliability & Data Integrity

  • Atomic Writes: Disk writes for long-term and episodic memories are performed atomically (write to a temporary file, then rename) to prevent data corruption if the process is interrupted.
  • Graceful Degradation: If the data directory becomes unwritable, the server will log errors but continue to function for short-term memory operations.
  • Automatic Cleanup: Short-term memory entries are automatically purged when their TTL expires, preventing memory leaks.
  • Error Handling: Comprehensive error handling is implemented throughout, with clear error messages returned to the MCP client where appropriate.

Monitoring & Observability

  • Structured Logging: All operations are logged with relevant context (user ID, session ID, operation type, duration) in a structured format (JSON), making it easy to parse and analyze logs.
  • Log Levels: Configurable log levels (trace, debug, info, warn, error) allow for verbose debugging during development and minimal logging in production.
  • Health Checks: The server responds to standard MCP pings, allowing for basic health monitoring.
  • Data Integrity Checks: On startup, the server can optionally verify the basic structure of existing data files (planned for future versions).

Troubleshooting

Common Issues

Server fails to start or MCP client cannot connect.

  • Verify Node.js Version: Ensure you are using Node.js 16.0 or higher (node -v).
  • Check Build Step: Run npm run build to ensure the TypeScript code is compiled to /build/index.js.
  • Check File Path: In your MCP client configuration, double-check the path to build/index.js. It should be an absolute path or a path relative to where the MCP client is run.
  • Examine Logs: Check the console output from the MCP client or the terminal where you might be running the server directly for error messages. Enable debug logging: DEBUG=memory-server:* node build/index.js.

Data is not persisting across server restarts.

  • Data Directory Permissions: Ensure the memory-data/ directory (or your custom dataDirectory) exists and is writable by the process running the server.
  • Disk Space: Verify that there is sufficient disk space available on the volume where the data directory is located.
  • Configuration: Confirm that the dataDirectory setting in your MCP configuration is pointing to the correct and intended location.

"Memory not found" errors.

  • ID Validation: Double-check the userId or sessionId for typos or incorrect formatting.
  • TTL Expiration: For short-term memory, confirm that the session has not expired (i.e., its TTL has not been exceeded).
  • Operation Sequencing: Ensure that data was written to memory before attempting to read it. Check logs for previous write operations.

Debug Mode

For detailed debugging output, you can run the server with the DEBUG environment variable set:

# From the project directory
DEBUG=memory-server:* node build/index.js

This will enable verbose logging for all components of the memory server, providing insights into internal operations, data flow, and potential issues.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Please ensure all code adheres to the project's coding standards and includes appropriate tests for new functionality.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

  • Issues & Bug Reports: Please use the GitHub Issues page to report bugs or request features.

Production Implementation: This server is built with a focus on robustness, security, and operational reliability, making it suitable for integration into production AI systems and applications.

About

A production-ready Model Context Protocol server implementing three-tiered memory architecture for vertical agents.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •