Skip to content
4 changes: 2 additions & 2 deletions src/memory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,14 @@ The server can be configured using the following environment variables:
"@modelcontextprotocol/server-memory"
],
"env": {
"MEMORY_FILE_PATH": "/path/to/custom/memory.json"
"MEMORY_FILE_PATH": "/path/to/custom/memory.jsonl"
}
}
}
}
```

- `MEMORY_FILE_PATH`: Path to the memory storage JSON file (default: `memory.json` in the server directory)
- `MEMORY_FILE_PATH`: Path to the memory storage JSONL file (default: `memory.jsonl` in the server directory)

# VS Code Installation Instructions

Expand Down
46 changes: 39 additions & 7 deletions src/memory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,43 @@ import path from 'path';
import { fileURLToPath } from 'url';

// Define memory file path using environment variable with fallback
const defaultMemoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'memory.json');
const defaultMemoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'memory.jsonl');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might this cause some weird backwards compatibility problems, e.g. if people have npx -y @modelcontextprotocol/server-memory in config, suddenly it'll seem to them like all their memories have disappeared.

Maybe we could also check before this: if no custom path is set AND memory.json exists AND memory.jsonl does not exist, move memory.json to memory.jsonl.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this change.


// If MEMORY_FILE_PATH is just a filename, put it in the same directory as the script
const MEMORY_FILE_PATH = process.env.MEMORY_FILE_PATH
? path.isAbsolute(process.env.MEMORY_FILE_PATH)
? process.env.MEMORY_FILE_PATH
: path.join(path.dirname(fileURLToPath(import.meta.url)), process.env.MEMORY_FILE_PATH)
: defaultMemoryPath;
// Handle backward compatibility: migrate memory.json to memory.jsonl if needed
async function ensureMemoryFilePath(): Promise<string> {
if (process.env.MEMORY_FILE_PATH) {
// Custom path provided, use it as-is (with absolute path resolution)
return path.isAbsolute(process.env.MEMORY_FILE_PATH)
? process.env.MEMORY_FILE_PATH
: path.join(path.dirname(fileURLToPath(import.meta.url)), process.env.MEMORY_FILE_PATH);
}

// No custom path set, check for backward compatibility migration
const oldMemoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'memory.json');
const newMemoryPath = defaultMemoryPath;

try {
// Check if old file exists and new file doesn't
await fs.access(oldMemoryPath);
try {
await fs.access(newMemoryPath);
// Both files exist, use new one (no migration needed)
return newMemoryPath;
} catch {
// Old file exists, new file doesn't - migrate
console.error('DETECTED: Found legacy memory.json file, migrating to memory.jsonl for JSONL format compatibility');
await fs.rename(oldMemoryPath, newMemoryPath);
console.error('COMPLETED: Successfully migrated memory.json to memory.jsonl');
return newMemoryPath;
}
} catch {
// Old file doesn't exist, use new path
return newMemoryPath;
}
}

// Initialize memory file path (will be set during startup)
let MEMORY_FILE_PATH: string;

// We are storing our memory using entities, relations, and observations in a graph structure
interface Entity {
Expand Down Expand Up @@ -434,6 +463,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
});

async function main() {
// Initialize memory file path with backward compatibility
MEMORY_FILE_PATH = await ensureMemoryFilePath();

const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Knowledge Graph MCP Server running on stdio");
Expand Down