Skip to main content
Glama

Memory MCP Server

by inchan
server.ts4.49 kB
#!/usr/bin/env node /** * @memory-mcp/mcp-server * MCP 서버 구현 - JSON-RPC 2.0 기반 stdin/stdout 통신 */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, type CallToolRequest, } from "@modelcontextprotocol/sdk/types.js"; import { ErrorCode, MemoryMcpError, logger } from "@memory-mcp/common"; import { DEFAULT_EXECUTION_POLICY, executeTool, listTools, } from "./tools/index.js"; import type { ToolExecutionContext } from "./tools/index.js"; import type { ExecutionPolicyOptions } from "./tools/execution-policy.js"; import type { ToolName } from "./tools/schemas.js"; export interface MemoryMcpServerOptions { vaultPath?: string; indexPath?: string; mode?: "dev" | "prod"; policy?: Partial<ExecutionPolicyOptions>; } type ResolvedServerOptions = { vaultPath: string; indexPath: string; mode: "dev" | "prod"; policy: ExecutionPolicyOptions; }; const DEFAULT_OPTIONS: ResolvedServerOptions = { vaultPath: process.cwd(), indexPath: `${process.cwd()}/.memory-index.db`, mode: "dev", policy: DEFAULT_EXECUTION_POLICY, }; /** * MCP 서버 클래스 * JSON-RPC 2.0 기반으로 stdin/stdout를 통해 통신 */ class MemoryMCPServer { private readonly server: Server; private readonly options: ResolvedServerOptions; private readonly toolContext: ToolExecutionContext; constructor(options: MemoryMcpServerOptions = {}) { const resolvedPolicy: ExecutionPolicyOptions = { ...DEFAULT_EXECUTION_POLICY, ...options.policy, }; const resolvedOptions: ResolvedServerOptions = { vaultPath: options.vaultPath ?? DEFAULT_OPTIONS.vaultPath, indexPath: options.indexPath ?? DEFAULT_OPTIONS.indexPath, mode: options.mode ?? DEFAULT_OPTIONS.mode, policy: resolvedPolicy, }; this.options = resolvedOptions; this.server = new Server( { name: "memory-mcp", version: "0.1.0", }, { capabilities: { tools: {}, }, } ); this.toolContext = { vaultPath: this.options.vaultPath, indexPath: this.options.indexPath, mode: this.options.mode, logger, policy: this.options.policy, }; this.setupToolHandlers(); } /** * 툴 핸들러 설정 */ private setupToolHandlers(): void { this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: listTools(), })); this.server.setRequestHandler( CallToolRequestSchema, async (request: CallToolRequest) => { const toolName = request.params.name as ToolName; const args = request.params.arguments ?? {}; try { return await executeTool(toolName, args, this.toolContext); } catch (error) { logger.error(`Tool execution error for ${toolName}:`, error); if (error instanceof MemoryMcpError) { throw error; } throw new MemoryMcpError( ErrorCode.MCP_TOOL_ERROR, `툴 실행 중 예기치 못한 오류가 발생했습니다: ${String(error)}`, { tool: toolName, } ); } } ); } /** * 서버 시작 */ async start(): Promise<void> { const transport = new StdioServerTransport(); logger.info("Starting Memory MCP Server...", { vaultPath: this.options.vaultPath, indexPath: this.options.indexPath, mode: this.options.mode, policy: this.options.policy, }); process.on("SIGINT", async () => { logger.info("Received SIGINT, shutting down gracefully..."); await this.server.close(); process.exit(0); }); process.on("SIGTERM", async () => { logger.info("Received SIGTERM, shutting down gracefully..."); await this.server.close(); process.exit(0); }); await this.server.connect(transport); logger.info("Memory MCP Server started successfully"); } } /** * 서버 인스턴스 생성 및 시작 */ export async function startServer( options: MemoryMcpServerOptions = {} ): Promise<void> { const server = new MemoryMCPServer(options); await server.start(); } // CLI에서 직접 실행될 때 if (require.main === module) { startServer().catch((error) => { logger.error("Failed to start server:", error); process.exit(1); }); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/inchan/memory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server