@bsbofmusic/memos-memu-local-memory-tools-for-agent 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP server entry point — memos-memu-local-memory-tools-for-agent
4
+ * Receives stdio JSON-RPC from mcporter and dispatches to tools.
5
+ */
6
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
+ import {
9
+ CallToolRequestSchema,
10
+ ListToolsRequestSchema,
11
+ } from '@modelcontextprotocol/sdk/types.js';
12
+
13
+ import { install_memory_system } from '../src/tools/install.js';
14
+ import { memos_query } from '../src/tools/memos.js';
15
+ import { memuk_search } from '../src/tools/memuk.js';
16
+ import { verify_memory_system } from '../src/tools/verify.js';
17
+
18
+ const server = new Server(
19
+ { name: 'memos-memu-local-memory-tools-for-agent', version: '1.0.3' },
20
+ { capabilities: { tools: {} } }
21
+ );
22
+
23
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
24
+ tools: [
25
+ {
26
+ name: 'install_memory_system',
27
+ description: 'One-shot install of the full memos + memuK memory system.',
28
+ inputSchema: { type: 'object', properties: {} },
29
+ },
30
+ {
31
+ name: 'verify_memory_system',
32
+ description: 'Smoke-test all memory system components.',
33
+ inputSchema: { type: 'object', properties: {} },
34
+ },
35
+ {
36
+ name: 'memos_query',
37
+ description: 'Query memos PostgreSQL for conversation history.',
38
+ inputSchema: {
39
+ type: 'object',
40
+ properties: {
41
+ query: { type: 'string' },
42
+ limit: { type: 'number', default: 10 },
43
+ },
44
+ required: ['query'],
45
+ },
46
+ },
47
+ {
48
+ name: 'memuk_search',
49
+ description: 'Search memuK SQLite for memory summaries.',
50
+ inputSchema: {
51
+ type: 'object',
52
+ properties: {
53
+ query: { type: 'string' },
54
+ limit: { type: 'number', default: 5 },
55
+ },
56
+ required: ['query'],
57
+ },
58
+ },
59
+ ],
60
+ }));
61
+
62
+ server.setRequestHandler(CallToolRequestSchema, async ({ params }) => {
63
+ const { name, arguments: args = {} } = params;
64
+ try {
65
+ switch (name) {
66
+ case 'install_memory_system': return await install_memory_system(args);
67
+ case 'verify_memory_system': return await verify_memory_system(args);
68
+ case 'memos_query': return await memos_query(args);
69
+ case 'memuk_search': return await memuk_search(args);
70
+ default: return { content: [{ type: 'text', text: `Unknown tool: ${name}` }], isError: true };
71
+ }
72
+ } catch (err) {
73
+ return { content: [{ type: 'text', text: `❌ ${err.message}` }], isError: true };
74
+ }
75
+ });
76
+
77
+ async function main() {
78
+ const transport = new StdioServerTransport();
79
+ await server.connect(transport);
80
+ }
81
+
82
+ main().catch(err => {
83
+ console.error('Server fatal:', err);
84
+ process.exit(1);
85
+ });
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@bsbofmusic/memos-memu-local-memory-tools-for-agent",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "MCP server — one-shot install + query for memos (PostgreSQL) and memuK (SQLite) local memory. Designed for OpenClaw agents.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
7
7
  "bin": {
8
- "memos-memu-local-memory-tools-for-agent": "./src/index.js"
8
+ "memos-memu-local-memory-tools-for-agent": "./bin/mcp-server.js"
9
9
  },
10
10
  "scripts": {
11
11
  "start": "node src/index.js",
@@ -46,9 +46,16 @@ FROM (
46
46
  }
47
47
 
48
48
  const lines = rows.map((r, i) => {
49
- const ts = new Date(Number(r.created_ts)).toLocaleString('zh-CN', {
50
- timeZone: 'Asia/Shanghai',
51
- });
49
+ // created_ts is bigint (milliseconds) — parse safely
50
+ let ts = 'unknown';
51
+ try {
52
+ const ms = typeof r.created_ts === 'number' ? r.created_ts : parseInt(String(r.created_ts));
53
+ if (ms > 1e12) {
54
+ ts = new Date(ms).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
55
+ } else if (ms > 1e9) {
56
+ ts = new Date(ms * 1000).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
57
+ }
58
+ } catch {}
52
59
  return `─── ${i + 1}. [id:${r.id}] ${ts} (${r.visibility}) ───\n${r.content}`;
53
60
  });
54
61
 
@@ -78,21 +78,34 @@ export async function verify_memory_system() {
78
78
 
79
79
  // 6. MCPorter config
80
80
  check('MCPorter config', () => {
81
- const cfgPath = path.join(env.workspaceDir, 'mcporter.json');
82
- if (!fs.existsSync(cfgPath)) {
83
- return { component: 'MCPorter config', status: 'FAIL', detail: `${cfgPath} not found` };
81
+ // Check both possible locations
82
+ const cfgPaths = [
83
+ path.join(env.workspaceDir, 'mcporter.json'),
84
+ path.join(env.workspaceDir, 'config', 'mcporter.json'),
85
+ path.join(env.workspaceDir, 'workspace', 'config', 'mcporter.json'),
86
+ ];
87
+ let foundPath = null;
88
+ let cfg = null;
89
+ for (const p of cfgPaths) {
90
+ if (fs.existsSync(p)) {
91
+ try {
92
+ cfg = JSON.parse(fs.readFileSync(p, 'utf8'));
93
+ foundPath = p;
94
+ break;
95
+ } catch {}
96
+ }
84
97
  }
85
- try {
86
- const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
87
- const hasEntry = cfg?.servers?.['memos-memu-local-memory-tools-for-agent'];
88
- return {
89
- component: 'MCPorter config',
90
- status: hasEntry ? 'PASS' : 'FAIL',
91
- detail: hasEntry ? 'MCP server entry found' : 'MCP server entry missing',
92
- };
93
- } catch (err) {
94
- return { component: 'MCPorter config', status: 'FAIL', detail: `JSON parse error: ${err.message}` };
98
+ if (!foundPath || !cfg) {
99
+ return { component: 'MCPorter config', status: 'FAIL', detail: 'mcporter.json not found in expected paths' };
95
100
  }
101
+ const hasEntry =
102
+ cfg?.servers?.['memos-memu-local-memory-tools-for-agent'] ||
103
+ cfg?.mcpServers?.['memos-memu-local-memory-tools-for-agent'];
104
+ return {
105
+ component: 'MCPorter config',
106
+ status: hasEntry ? 'PASS' : 'FAIL',
107
+ detail: hasEntry ? `Entry found in ${foundPath}` : `No MCP entry in ${foundPath}`,
108
+ };
96
109
  });
97
110
 
98
111
  // 7. Cron