diff --git a/src/memory/__tests__/server-info.test.ts b/src/memory/__tests__/server-info.test.ts new file mode 100644 index 0000000000..50aed4fd37 --- /dev/null +++ b/src/memory/__tests__/server-info.test.ts @@ -0,0 +1,48 @@ +import { createRequire } from 'module'; +import { describe, expect, it, vi } from 'vitest'; + +const require = createRequire(import.meta.url); +const packageJson = require('../package.json') as { version: string }; + +const { MockMcpServer, mockServer } = vi.hoisted(() => { + const mockServer = { + registerTool: vi.fn(), + registerResource: vi.fn(), + connect: vi.fn().mockResolvedValue(undefined), + server: { + sendResourceUpdated: vi.fn(), + registerCapabilities: vi.fn(), + setRequestHandler: vi.fn(), + }, + }; + + return { + MockMcpServer: vi.fn(function MockMcpServer() { + return mockServer; + }), + mockServer, + }; +}); + +vi.mock('@modelcontextprotocol/sdk/server/mcp.js', () => ({ + McpServer: MockMcpServer, +})); + +vi.mock('@modelcontextprotocol/sdk/server/stdio.js', () => ({ + StdioServerTransport: vi.fn(), +})); + +describe('memory server info', () => { + it('uses the package version for MCP server metadata', async () => { + vi.resetModules(); + + await import('../index.js'); + + expect(MockMcpServer).toHaveBeenCalledTimes(1); + expect(MockMcpServer).toHaveBeenCalledWith({ + name: 'memory-server', + version: packageJson.version, + }); + expect(mockServer.registerTool).toHaveBeenCalled(); + }); +}); diff --git a/src/memory/index.ts b/src/memory/index.ts index 9865c5318e..d11ab8d955 100644 --- a/src/memory/index.ts +++ b/src/memory/index.ts @@ -4,12 +4,19 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { SubscribeRequestSchema, UnsubscribeRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; -import { promises as fs } from 'fs'; +import { promises as fs, readFileSync } from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; +const currentDirPath = path.dirname(fileURLToPath(import.meta.url)); +const packageJsonUrl = new URL( + path.basename(currentDirPath) === 'dist' ? '../package.json' : './package.json', + import.meta.url, +); +const packageJson = JSON.parse(readFileSync(packageJsonUrl, 'utf-8')) as { version: string }; + // Define memory file path using environment variable with fallback -export const defaultMemoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'memory.jsonl'); +export const defaultMemoryPath = path.join(currentDirPath, 'memory.jsonl'); // Handle backward compatibility: migrate memory.json to memory.jsonl if needed export async function ensureMemoryFilePath(): Promise { @@ -17,11 +24,11 @@ export async function ensureMemoryFilePath(): Promise { // 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); + : path.join(currentDirPath, 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 oldMemoryPath = path.join(currentDirPath, 'memory.json'); const newMemoryPath = defaultMemoryPath; try { @@ -256,7 +263,7 @@ const RelationSchema = z.object({ // The server instance and tools exposed to Claude const server = new McpServer({ name: "memory-server", - version: "0.6.3", + version: packageJson.version, }); const RESOURCE_URI = "memory://knowledge-graph";