Skip to main content
Glama
wuyunmei
by wuyunmei
index.ts11.2 kB
#!/usr/bin/env node import { Server, StdioServerTransport } from './mcp/server.js'; import { CallToolRequestSchema, ListToolsRequestSchema, McpError, ErrorCode, } from './mcp/types.js'; import * as userTools from './tools/user.js'; import * as blobTools from './tools/blob.js'; import * as knowledgeTools from './tools/knowledge.js'; import { User, Blob, Knowledge, KnowledgeRelation, CreateBlobRequest, GetBlobRequest, DeleteBlobRequest, QueryKnowledgeRequest, AddKnowledgeRequest, UpdateKnowledgeRequest, RelateKnowledgeRequest } from './api/types.js'; class MemobaseMcpServer { private server: Server; constructor() { console.error('[INFO] Initializing MemoBase MCP server'); this.server = new Server( { name: 'memobase', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); this.setupToolHandlers(); // Error handling this.server.onerror = (error) => console.error('[MCP Error]', error); } async close() { console.error('[INFO] Closing MemoBase MCP server'); await this.server.close(); } private setupToolHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async (request) => ({ tools: [ { name: 'create_user', description: 'Create a new user', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'User name' }, }, required: ['name'], }, }, { name: 'get_user', description: 'Get user information', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, }, required: ['uid'], }, }, { name: 'update_user', description: 'Update user information', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, name: { type: 'string', description: 'New user name' }, }, required: ['uid', 'name'], }, }, { name: 'delete_user', description: 'Delete a user', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, }, required: ['uid'], }, }, { name: 'insert_blob', description: 'Insert conversation data', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, blob_type: { type: 'string', description: 'Type of blob (e.g., "chat")' }, blob_data: { type: 'object', properties: { messages: { type: 'array', items: { type: 'object', properties: { role: { type: 'string', enum: ['user', 'assistant'] }, content: { type: 'string' }, alias: { type: 'string' }, }, required: ['role', 'content'], }, }, }, required: ['messages'], }, }, required: ['uid', 'blob_type', 'blob_data'], }, }, { name: 'get_blob', description: 'Get conversation data', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, bid: { type: 'string', description: 'Blob ID' }, }, required: ['uid', 'bid'], }, }, { name: 'delete_blob', description: 'Delete conversation data', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, bid: { type: 'string', description: 'Blob ID' }, }, required: ['uid', 'bid'], }, }, { name: 'query_knowledge', description: 'Query knowledge base', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, query: { type: 'string', description: 'Search query' }, filters: { type: 'object', properties: { types: { type: 'array', items: { type: 'string' }, description: 'Knowledge types to filter' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to filter' }, sources: { type: 'array', items: { type: 'string' }, description: 'Sources to filter' }, }, }, limit: { type: 'number', description: 'Maximum number of results' }, }, required: ['uid', 'query'], }, }, { name: 'add_knowledge', description: 'Add new knowledge', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, content: { type: 'string', description: 'Knowledge content' }, metadata: { type: 'object', properties: { source: { type: 'string', description: 'Knowledge source' }, type: { type: 'string', description: 'Knowledge type' }, tags: { type: 'array', items: { type: 'string' }, description: 'Knowledge tags' }, }, required: ['source', 'type', 'tags'], }, }, required: ['uid', 'content', 'metadata'], }, }, { name: 'update_knowledge', description: 'Update existing knowledge', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, kid: { type: 'string', description: 'Knowledge ID' }, content: { type: 'string', description: 'New content' }, metadata: { type: 'object', properties: { source: { type: 'string', description: 'Knowledge source' }, type: { type: 'string', description: 'Knowledge type' }, tags: { type: 'array', items: { type: 'string' }, description: 'Knowledge tags' }, }, }, }, required: ['uid', 'kid'], }, }, { name: 'relate_knowledge', description: 'Create relation between knowledge items', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'User ID' }, source_kid: { type: 'string', description: 'Source knowledge ID' }, target_kid: { type: 'string', description: 'Target knowledge ID' }, relation_type: { type: 'string', description: 'Type of relation' }, weight: { type: 'number', description: 'Relation weight (0-1)' }, }, required: ['uid', 'source_kid', 'target_kid', 'relation_type', 'weight'], }, }, ], })); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { let result; switch (request.params.name) { case 'create_user': result = await userTools.createUser(request.params.arguments as { name: string }); break; case 'get_user': result = await userTools.getUser(request.params.arguments as { uid: string }); break; case 'update_user': result = await userTools.updateUser(request.params.arguments as { uid: string; name: string }); break; case 'delete_user': result = await userTools.deleteUser(request.params.arguments as { uid: string }); break; case 'insert_blob': result = await blobTools.insertBlob(request.params.arguments as CreateBlobRequest); break; case 'get_blob': result = await blobTools.getBlob(request.params.arguments as GetBlobRequest); break; case 'delete_blob': result = await blobTools.deleteBlob(request.params.arguments as DeleteBlobRequest); break; case 'query_knowledge': result = await knowledgeTools.queryKnowledge(request.params.arguments as QueryKnowledgeRequest); break; case 'add_knowledge': result = await knowledgeTools.addKnowledge(request.params.arguments as AddKnowledgeRequest); break; case 'update_knowledge': result = await knowledgeTools.updateKnowledge(request.params.arguments as UpdateKnowledgeRequest); break; case 'relate_knowledge': result = await knowledgeTools.relateKnowledge(request.params.arguments as RelateKnowledgeRequest); break; default: throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`); } return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Tool execution failed: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('Memobase MCP server running on stdio'); } } const server = new MemobaseMcpServer(); // 保持进程运行 const keepAlive = () => { setInterval(() => { console.error('[DEBUG] Server is alive'); }, 5000); }; // 处理进程信号 process.on('SIGINT', async () => { console.error('[INFO] Received SIGINT signal'); await server.close(); process.exit(0); }); process.on('SIGTERM', async () => { console.error('[INFO] Received SIGTERM signal'); await server.close(); process.exit(0); }); // 处理未捕获的异常 process.on('uncaughtException', (error) => { console.error('[ERROR] Uncaught exception:', error); }); process.on('unhandledRejection', (reason, promise) => { console.error('[ERROR] Unhandled rejection at:', promise, 'reason:', reason); }); // 启动服务器 server.run() .then(() => { console.error('[INFO] Server started successfully'); keepAlive(); }) .catch((error) => { console.error('[ERROR] Failed to start server:', error); process.exit(1); });

Latest Blog Posts

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/wuyunmei/momedb-mcp'

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