/**
* @copyright 2025 Chris Bunting <cbuntingde@gmail.com>
* @license MIT
*
* Resource handlers for the Memory MCP Server
*/
import {
ListResourcesRequestSchema,
ReadResourceRequestSchema,
McpError,
ErrorCode
} from "@modelcontextprotocol/sdk/types.js";
import { MemoryStore } from "../store/MemoryStore.js";
export function setupResourceHandlers(server: any, memoryStore: MemoryStore): void {
// List available resources
server.setRequestHandler(ListResourcesRequestSchema, async () => {
memoryStore.clearExpiredShortTermMemory();
const resources = [];
// Add long-term memory resources
for (const [userId] of memoryStore.getAllLongTermMemory().entries()) {
resources.push({
uri: `memory://long-term/${userId}`,
mimeType: "application/json",
name: `Long-term memory for ${userId}`,
description: "Demographics, contact details, and preferences"
});
}
// Add episodic memory resources
for (const [userId] of memoryStore.getAllLongTermMemory().entries()) {
resources.push({
uri: `memory://episodic/${userId}`,
mimeType: "application/json",
name: `Episodic memory for ${userId}`,
description: "Past experiences and events"
});
}
return { resources };
});
// Read resource content
server.setRequestHandler(ReadResourceRequestSchema, async (request: any) => {
const url = new URL(request.params.uri);
const [type, userId] = url.pathname.replace(/^\//, '').split('/');
if (type === 'long-term') {
const memory = memoryStore.getLongTermMemory(userId);
if (!memory) {
throw new McpError(ErrorCode.InvalidRequest, `Long-term memory not found for user: ${userId}`);
}
return {
contents: [{
uri: request.params.uri,
mimeType: "application/json",
text: JSON.stringify(memory, null, 2)
}]
};
} else if (type === 'episodic') {
const memories = memoryStore.getEpisodicMemory(userId);
return {
contents: [{
uri: request.params.uri,
mimeType: "application/json",
text: JSON.stringify(memories, null, 2)
}]
};
}
throw new McpError(ErrorCode.InvalidRequest, `Invalid memory resource type: ${type}`);
});
}