memtrace-mcp-server 1.0.0
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.
- package/index.js +304 -0
- package/package.json +25 -0
package/index.js
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ListToolsRequestSchema,
|
|
8
|
+
ListResourcesRequestSchema,
|
|
9
|
+
ReadResourceRequestSchema,
|
|
10
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
|
|
12
|
+
const API_URL = process.env.MEMTRACE_API_URL || 'http://localhost:3000/api/v1';
|
|
13
|
+
const TOKEN = process.env.MEMTRACE_TOKEN;
|
|
14
|
+
|
|
15
|
+
if (!TOKEN) {
|
|
16
|
+
console.error('Error: MEMTRACE_TOKEN environment variable is required');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Helper to make API calls
|
|
21
|
+
async function apiCall(endpoint, method = 'GET', body = null) {
|
|
22
|
+
const options = {
|
|
23
|
+
method,
|
|
24
|
+
headers: {
|
|
25
|
+
'Authorization': `Bearer ${TOKEN}`,
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
if (body) {
|
|
31
|
+
options.body = JSON.stringify(body);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const response = await fetch(`${API_URL}${endpoint}`, options);
|
|
35
|
+
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
const error = await response.json().catch(() => ({ error: 'Request failed' }));
|
|
38
|
+
throw new Error(error.error || `HTTP ${response.status}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return response.json();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Create MCP server
|
|
45
|
+
const server = new Server(
|
|
46
|
+
{
|
|
47
|
+
name: 'memtrace',
|
|
48
|
+
version: '1.0.0',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
capabilities: {
|
|
52
|
+
tools: {},
|
|
53
|
+
resources: {},
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// List available tools
|
|
59
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
60
|
+
return {
|
|
61
|
+
tools: [
|
|
62
|
+
{
|
|
63
|
+
name: 'search_knowledge',
|
|
64
|
+
description: 'Search for relevant knowledge items using semantic search. Use this to find information that might help with the current task.',
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
properties: {
|
|
68
|
+
query: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'The search query to find relevant knowledge',
|
|
71
|
+
},
|
|
72
|
+
limit: {
|
|
73
|
+
type: 'number',
|
|
74
|
+
description: 'Maximum number of results to return (default: 10)',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
required: ['query'],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'push_knowledge',
|
|
82
|
+
description: 'Store new knowledge items for future reference. Use this to save important information, decisions, preferences, or learnings.',
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
items: {
|
|
87
|
+
type: 'array',
|
|
88
|
+
description: 'Array of knowledge items to store',
|
|
89
|
+
items: {
|
|
90
|
+
type: 'object',
|
|
91
|
+
properties: {
|
|
92
|
+
title: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
description: 'Short descriptive title for the knowledge',
|
|
95
|
+
},
|
|
96
|
+
content: {
|
|
97
|
+
type: 'string',
|
|
98
|
+
description: 'The knowledge content to store',
|
|
99
|
+
},
|
|
100
|
+
category: {
|
|
101
|
+
type: 'string',
|
|
102
|
+
enum: ['fact', 'preference', 'procedure', 'decision', 'insight', 'other'],
|
|
103
|
+
description: 'Category of the knowledge',
|
|
104
|
+
},
|
|
105
|
+
tags: {
|
|
106
|
+
type: 'array',
|
|
107
|
+
items: { type: 'string' },
|
|
108
|
+
description: 'Tags for organizing the knowledge',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
required: ['title', 'content'],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
required: ['items'],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'pull_knowledge',
|
|
120
|
+
description: 'Retrieve recent knowledge items. Use this to get context from previous sessions.',
|
|
121
|
+
inputSchema: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
limit: {
|
|
125
|
+
type: 'number',
|
|
126
|
+
description: 'Maximum number of items to retrieve (default: 10)',
|
|
127
|
+
},
|
|
128
|
+
category: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
description: 'Filter by category',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: 'get_startup_context',
|
|
137
|
+
description: 'Get startup context including pinned knowledge and recent items. Call this at the beginning of a session.',
|
|
138
|
+
inputSchema: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
project_id: {
|
|
142
|
+
type: 'string',
|
|
143
|
+
description: 'Optional project identifier to filter context',
|
|
144
|
+
},
|
|
145
|
+
max_tokens: {
|
|
146
|
+
type: 'number',
|
|
147
|
+
description: 'Maximum tokens budget for the context (default: 4000)',
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Handle tool calls
|
|
157
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
158
|
+
const { name, arguments: args } = request.params;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
switch (name) {
|
|
162
|
+
case 'search_knowledge': {
|
|
163
|
+
const results = await apiCall('/mcp/knowledge/search', 'POST', {
|
|
164
|
+
query: args.query,
|
|
165
|
+
limit: args.limit || 10,
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
content: [
|
|
169
|
+
{
|
|
170
|
+
type: 'text',
|
|
171
|
+
text: JSON.stringify(results, null, 2),
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
case 'push_knowledge': {
|
|
178
|
+
const result = await apiCall('/mcp/knowledge/push', 'POST', {
|
|
179
|
+
items: args.items,
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
content: [
|
|
183
|
+
{
|
|
184
|
+
type: 'text',
|
|
185
|
+
text: `Successfully stored ${result.items_created} knowledge item(s).`,
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
case 'pull_knowledge': {
|
|
192
|
+
const results = await apiCall('/mcp/knowledge/pull', 'POST', {
|
|
193
|
+
limit: args.limit || 10,
|
|
194
|
+
category: args.category,
|
|
195
|
+
});
|
|
196
|
+
return {
|
|
197
|
+
content: [
|
|
198
|
+
{
|
|
199
|
+
type: 'text',
|
|
200
|
+
text: JSON.stringify(results, null, 2),
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
case 'get_startup_context': {
|
|
207
|
+
const context = await apiCall('/context/startup', 'POST', {
|
|
208
|
+
project_id: args.project_id,
|
|
209
|
+
max_tokens: args.max_tokens || 4000,
|
|
210
|
+
});
|
|
211
|
+
return {
|
|
212
|
+
content: [
|
|
213
|
+
{
|
|
214
|
+
type: 'text',
|
|
215
|
+
text: context.context || JSON.stringify(context, null, 2),
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
default:
|
|
222
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
223
|
+
}
|
|
224
|
+
} catch (error) {
|
|
225
|
+
return {
|
|
226
|
+
content: [
|
|
227
|
+
{
|
|
228
|
+
type: 'text',
|
|
229
|
+
text: `Error: ${error.message}`,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
isError: true,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// List resources
|
|
238
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
239
|
+
return {
|
|
240
|
+
resources: [
|
|
241
|
+
{
|
|
242
|
+
uri: 'memtrace://knowledge/recent',
|
|
243
|
+
name: 'Recent Knowledge',
|
|
244
|
+
description: 'Recently added or accessed knowledge items',
|
|
245
|
+
mimeType: 'application/json',
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
uri: 'memtrace://knowledge/pinned',
|
|
249
|
+
name: 'Pinned Knowledge',
|
|
250
|
+
description: 'Important pinned knowledge items',
|
|
251
|
+
mimeType: 'application/json',
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Read resources
|
|
258
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
259
|
+
const { uri } = request.params;
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
if (uri === 'memtrace://knowledge/recent') {
|
|
263
|
+
const results = await apiCall('/mcp/knowledge/pull', 'POST', { limit: 20 });
|
|
264
|
+
return {
|
|
265
|
+
contents: [
|
|
266
|
+
{
|
|
267
|
+
uri,
|
|
268
|
+
mimeType: 'application/json',
|
|
269
|
+
text: JSON.stringify(results, null, 2),
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (uri === 'memtrace://knowledge/pinned') {
|
|
276
|
+
const results = await apiCall('/knowledge?pinned=true&limit=20', 'GET');
|
|
277
|
+
return {
|
|
278
|
+
contents: [
|
|
279
|
+
{
|
|
280
|
+
uri,
|
|
281
|
+
mimeType: 'application/json',
|
|
282
|
+
text: JSON.stringify(results.data || [], null, 2),
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
289
|
+
} catch (error) {
|
|
290
|
+
throw new Error(`Failed to read resource: ${error.message}`);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Start server
|
|
295
|
+
async function main() {
|
|
296
|
+
const transport = new StdioServerTransport();
|
|
297
|
+
await server.connect(transport);
|
|
298
|
+
console.error('MemTrace MCP server running on stdio');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
main().catch((error) => {
|
|
302
|
+
console.error('Fatal error:', error);
|
|
303
|
+
process.exit(1);
|
|
304
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "memtrace-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for MemTrace - AI context memory service",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"memtrace-mcp-server": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["mcp", "memtrace", "ai", "context", "memory", "claude"],
|
|
14
|
+
"author": "MemTrace",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"registry": "https://registry.npmjs.org/"
|
|
24
|
+
}
|
|
25
|
+
}
|