How the MCP Memory Server Handles Backward Compatibility Migration

The MCP Memory server automatically migrates legacy memory.json files to the modern memory.jsonl format during startup by detecting the old file, renaming it while preserving contents, and logging the transition, requiring no manual intervention from users.

The MCP Memory server in the modelcontextprotocol/servers repository stores knowledge-graph data in a JSON Lines format for improved efficiency and append-only operations. To ensure seamless backward compatibility migration for existing deployments, the server implements an automatic migration routine in src/memory/index.ts that upgrades legacy storage files without breaking existing data or requiring user action.

Migration Architecture in src/memory/index.ts

The core migration logic resides in the ensureMemoryFilePath function. This utility determines the correct file path and handles format transitions during server initialization by detecting file presence and executing conditional rename operations.

Detecting Legacy vs. Modern Formats

The function distinguishes between two storage formats:

  • Legacy format: memory.json (plain JSON structure)
  • Modern format: memory.jsonl (JSON Lines for append-only efficiency)

According to the source code at lines 22-25, the function constructs both paths relative to the module directory. When no custom path is specified via environment variables, it checks for the existence of these files to determine if migration is necessary.

Environment Variable Override

Before checking for legacy files, the function respects the MEMORY_FILE_PATH environment variable. As implemented at lines 15-20, if this variable is set, the function resolves the specified absolute or relative path and returns it immediately, skipping all migration logic. This allows users to maintain custom storage locations outside the default migration workflow.

Automatic Migration Workflow

When the server starts, the migration routine executes automatically through the following decision tree implemented in lines 26-43:

  1. Both files exist: The server uses memory.jsonl exclusively, ignoring the legacy file without migration or console output.
  2. Only legacy file exists: The server logs a detection message, executes fs.rename() at line 36 to rename memory.json to memory.jsonl, logs completion, and proceeds with the new file.
  3. No legacy file: The server returns the default memory.jsonl path, creating the file later when data is first saved.

This approach ensures the migration is idempotent and non-destructive, preserving exact file contents during the rename operation without parsing or transforming the JSON data.

Validating Migration Behavior

The test suite in src/memory/__tests__/file-path.test.ts validates all migration scenarios to ensure reliability:

  • Environment variable precedence: Confirms MEMORY_FILE_PATH bypasses migration logic for absolute, relative, and Windows paths.
  • Clean installation: Verifies behavior when neither file exists, returning the default path.
  • Legacy-only migration: Ensures memory.json is renamed to memory.jsonl with exact content preservation and proper log output.
  • Coexistence handling: Confirms no migration occurs when both files exist, preventing accidental overwrites of existing modern format data.
  • Data integrity: Validates that file contents remain bit-for-bit identical after migration, confirming the rename operation does not modify data.

Implementation Examples

Starting the Server with Automatic Migration

When you start the Memory server, the migration runs automatically if needed:

import { ensureMemoryFilePath } from "./src/memory/index.js";

async function start() {
  // Triggers migration if memory.json exists
  const memoryPath = await ensureMemoryFilePath();
  console.log("Using memory file:", memoryPath);
  // Server initialization continues...
}
start();

Console output when migration occurs:


DETECTED: Found legacy memory.json file, migrating to memory.jsonl for JSONL format compatibility
COMPLETED: Successfully migrated memory.json to memory.jsonl
Using memory file: /path/to/memory.jsonl

Bypassing Migration with Custom Paths

To use a custom storage location and skip automatic migration:


# Unix/Linux

export MEMORY_FILE_PATH=/data/persistent-memory.jsonl
node src/memory/index.js

# Windows PowerShell

$env:MEMORY_FILE_PATH = "C:\data\persistent-memory.jsonl"
node src/memory/index.js

When MEMORY_FILE_PATH is set, the server resolves the absolute path and ignores the default migration logic entirely, as specified in the ensureMemoryFilePath implementation.

Programmatic Migration Testing

Simulate the migration in a test environment to verify behavior:

import { promises as fs } from "fs";
import path from "path";
import { ensureMemoryFilePath, defaultMemoryPath } from "./src/memory/index.js";

async function testMigration() {
  // Create legacy file with sample data
  const legacyPath = path.join(process.cwd(), "memory.json");
  await fs.writeFile(legacyPath, '{"entities":[],"relations":[]}');
  
  // Execute migration
  await ensureMemoryFilePath();
  
  // Verify migration success
  const newContent = await fs.readFile(defaultMemoryPath, "utf-8");
  console.assert(newContent === '{"entities":[],"relations":[]}');
  console.log("Migration verified successfully");
}
testMigration();

Summary

  • The MCP Memory server automatically handles backward compatibility migration by detecting legacy memory.json files and renaming them to memory.jsonl during startup.
  • The ensureMemoryFilePath function in src/memory/index.ts implements this logic at lines 26-43, specifically performing the atomic rename operation at line 36.
  • Migration only occurs when exclusively the legacy file exists; if both files exist, the server uses the modern format without modification to prevent data loss.
  • The MEMORY_FILE_PATH environment variable overrides all migration logic, allowing custom storage locations without triggering legacy file detection.
  • Comprehensive tests in src/memory/__tests__/file-path.test.ts verify idempotent behavior and data preservation across all migration scenarios.

Frequently Asked Questions

What triggers the MCP Memory server backward compatibility migration?

The migration triggers automatically when the server starts and detects a memory.json file in the module directory without an existing memory.jsonl file. The ensureMemoryFilePath function performs this check during initialization, renaming the legacy file to the new JSON Lines format while preserving all contents exactly and logging the transition to stderr.

Will I lose data during the automatic migration from memory.json to memory.jsonl?

No. The migration uses a simple file rename operation at line 36 of src/memory/index.ts, which preserves the exact byte content of the original file. The test suite confirms that data remains bit-for-bit identical after migration, and because the operation uses the filesystem's native rename, it is atomic and does not parse or transform the JSON structure.

How do I prevent automatic migration and use a custom memory file location?

Set the MEMORY_FILE_PATH environment variable to your desired absolute or relative path. When this variable is present, the server uses the specified path directly and skips all legacy file detection and migration logic, as implemented in lines 15-20 of the source code. This is the recommended approach for production deployments requiring specific storage volumes or network paths.

What happens if both memory.json and memory.jsonl exist in the directory?

If both files exist simultaneously, the server uses memory.jsonl exclusively and performs no migration. This prevents accidental overwrites of existing data and allows administrators to manually manage the transition if needed. The server produces no console output in this scenario, treating the presence of both files as a standard operational state where the modern format takes precedence.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →