memoclaw-mcp 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/README.md +73 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +168 -0
- package/package.json +31 -0
- package/src/index.ts +197 -0
- package/tsconfig.json +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# MemoClaw MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for MemoClaw semantic memory API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g memoclaw-mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
Set your private key:
|
|
14
|
+
```bash
|
|
15
|
+
export MEMOCLAW_PRIVATE_KEY=0x...
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Claude Desktop
|
|
19
|
+
|
|
20
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"memoclaw": {
|
|
26
|
+
"command": "memoclaw-mcp",
|
|
27
|
+
"env": {
|
|
28
|
+
"MEMOCLAW_PRIVATE_KEY": "0x..."
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Cursor
|
|
36
|
+
|
|
37
|
+
Add to MCP settings in Cursor preferences.
|
|
38
|
+
|
|
39
|
+
## Tools
|
|
40
|
+
|
|
41
|
+
| Tool | Description |
|
|
42
|
+
|------|-------------|
|
|
43
|
+
| `memoclaw_store` | Store a memory with semantic embeddings |
|
|
44
|
+
| `memoclaw_recall` | Recall memories via semantic search |
|
|
45
|
+
| `memoclaw_list` | List stored memories |
|
|
46
|
+
| `memoclaw_delete` | Delete a memory by ID |
|
|
47
|
+
|
|
48
|
+
## Example Usage
|
|
49
|
+
|
|
50
|
+
Once configured, Claude can use commands like:
|
|
51
|
+
|
|
52
|
+
- "Remember that the meeting is at 3pm tomorrow"
|
|
53
|
+
- "What did I say about the project deadline?"
|
|
54
|
+
- "List my recent memories"
|
|
55
|
+
|
|
56
|
+
## Pricing
|
|
57
|
+
|
|
58
|
+
- Store: $0.001 per memory
|
|
59
|
+
- Recall: $0.001 per query
|
|
60
|
+
- List: $0.0005
|
|
61
|
+
- Delete: $0.0001
|
|
62
|
+
|
|
63
|
+
Paid with USDC on Base via x402 protocol.
|
|
64
|
+
|
|
65
|
+
## Links
|
|
66
|
+
|
|
67
|
+
- [MemoClaw Website](https://memoclaw.dev)
|
|
68
|
+
- [MemoClaw Docs](https://docs.memoclaw.com)
|
|
69
|
+
- [MCP Specification](https://modelcontextprotocol.io)
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { x402Client } from '@x402/core/client';
|
|
6
|
+
import { x402HTTPClient } from '@x402/core/http';
|
|
7
|
+
import { ExactEvmScheme } from '@x402/evm/exact/client';
|
|
8
|
+
import { toClientEvmSigner } from '@x402/evm';
|
|
9
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
10
|
+
const API_URL = process.env.MEMOCLAW_URL || 'https://api.memoclaw.dev';
|
|
11
|
+
const PRIVATE_KEY = process.env.MEMOCLAW_PRIVATE_KEY;
|
|
12
|
+
if (!PRIVATE_KEY) {
|
|
13
|
+
console.error('MEMOCLAW_PRIVATE_KEY environment variable required');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
// x402 payment client setup
|
|
17
|
+
const account = privateKeyToAccount(PRIVATE_KEY);
|
|
18
|
+
const signer = toClientEvmSigner(account);
|
|
19
|
+
const coreClient = new x402Client().register('eip155:*', new ExactEvmScheme(signer));
|
|
20
|
+
const client = new x402HTTPClient(coreClient);
|
|
21
|
+
async function makeRequest(method, path, body) {
|
|
22
|
+
const url = `${API_URL}${path}`;
|
|
23
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
24
|
+
const options = { method, headers };
|
|
25
|
+
if (body)
|
|
26
|
+
options.body = JSON.stringify(body);
|
|
27
|
+
let res = await fetch(url, options);
|
|
28
|
+
// Handle 402 Payment Required
|
|
29
|
+
if (res.status === 402) {
|
|
30
|
+
const errorBody = await res.json();
|
|
31
|
+
const paymentRequired = client.getPaymentRequiredResponse((name) => res.headers.get(name), errorBody);
|
|
32
|
+
const paymentPayload = await client.createPaymentPayload(paymentRequired);
|
|
33
|
+
const paymentHeaders = client.encodePaymentSignatureHeader(paymentPayload);
|
|
34
|
+
res = await fetch(url, {
|
|
35
|
+
method,
|
|
36
|
+
headers: { ...headers, ...paymentHeaders },
|
|
37
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
const err = await res.text();
|
|
42
|
+
throw new Error(`HTTP ${res.status}: ${err}`);
|
|
43
|
+
}
|
|
44
|
+
return res.json();
|
|
45
|
+
}
|
|
46
|
+
const server = new Server({ name: 'memoclaw', version: '1.0.0' }, { capabilities: { tools: {} } });
|
|
47
|
+
// List available tools
|
|
48
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
49
|
+
tools: [
|
|
50
|
+
{
|
|
51
|
+
name: 'memoclaw_store',
|
|
52
|
+
description: 'Store a memory with semantic embeddings for later recall',
|
|
53
|
+
inputSchema: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
content: { type: 'string', description: 'Memory content to store' },
|
|
57
|
+
importance: { type: 'number', description: 'Importance score 0-1 (default 0.5)' },
|
|
58
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Tags for categorization' },
|
|
59
|
+
namespace: { type: 'string', description: 'Namespace for organization' },
|
|
60
|
+
},
|
|
61
|
+
required: ['content'],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'memoclaw_recall',
|
|
66
|
+
description: 'Recall memories via semantic search',
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
query: { type: 'string', description: 'Search query' },
|
|
71
|
+
limit: { type: 'number', description: 'Max results (default 5)' },
|
|
72
|
+
min_similarity: { type: 'number', description: 'Min similarity threshold 0-1' },
|
|
73
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags' },
|
|
74
|
+
namespace: { type: 'string', description: 'Filter by namespace' },
|
|
75
|
+
},
|
|
76
|
+
required: ['query'],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'memoclaw_list',
|
|
81
|
+
description: 'List stored memories',
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: 'object',
|
|
84
|
+
properties: {
|
|
85
|
+
limit: { type: 'number', description: 'Max results (default 20)' },
|
|
86
|
+
offset: { type: 'number', description: 'Pagination offset' },
|
|
87
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags' },
|
|
88
|
+
namespace: { type: 'string', description: 'Filter by namespace' },
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'memoclaw_delete',
|
|
94
|
+
description: 'Delete a memory by ID',
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: 'object',
|
|
97
|
+
properties: {
|
|
98
|
+
id: { type: 'string', description: 'Memory ID to delete' },
|
|
99
|
+
},
|
|
100
|
+
required: ['id'],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
}));
|
|
105
|
+
// Handle tool calls
|
|
106
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
107
|
+
const { name, arguments: args } = request.params;
|
|
108
|
+
try {
|
|
109
|
+
switch (name) {
|
|
110
|
+
case 'memoclaw_store': {
|
|
111
|
+
const { content, importance, tags, namespace } = args;
|
|
112
|
+
const result = await makeRequest('POST', '/v1/store', {
|
|
113
|
+
content,
|
|
114
|
+
importance,
|
|
115
|
+
metadata: tags ? { tags } : undefined,
|
|
116
|
+
namespace,
|
|
117
|
+
});
|
|
118
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
119
|
+
}
|
|
120
|
+
case 'memoclaw_recall': {
|
|
121
|
+
const { query, limit, min_similarity, tags, namespace } = args;
|
|
122
|
+
const result = await makeRequest('POST', '/v1/recall', {
|
|
123
|
+
query,
|
|
124
|
+
limit,
|
|
125
|
+
min_similarity,
|
|
126
|
+
filters: tags ? { tags } : undefined,
|
|
127
|
+
namespace,
|
|
128
|
+
});
|
|
129
|
+
// Format results nicely
|
|
130
|
+
const memories = result.memories || [];
|
|
131
|
+
const formatted = memories.map((m) => `[${m.score?.toFixed(3) || '?'}] ${m.content}\n tags: ${m.metadata?.tags?.join(', ') || 'none'}`).join('\n\n');
|
|
132
|
+
return { content: [{ type: 'text', text: formatted || 'No memories found' }] };
|
|
133
|
+
}
|
|
134
|
+
case 'memoclaw_list': {
|
|
135
|
+
const { limit, offset, tags, namespace } = args;
|
|
136
|
+
const params = new URLSearchParams();
|
|
137
|
+
if (limit)
|
|
138
|
+
params.set('limit', String(limit));
|
|
139
|
+
if (offset)
|
|
140
|
+
params.set('offset', String(offset));
|
|
141
|
+
if (namespace)
|
|
142
|
+
params.set('namespace', namespace);
|
|
143
|
+
const result = await makeRequest('GET', `/v1/memories?${params}`);
|
|
144
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
145
|
+
}
|
|
146
|
+
case 'memoclaw_delete': {
|
|
147
|
+
const { id } = args;
|
|
148
|
+
const result = await makeRequest('DELETE', `/v1/memories/${id}`);
|
|
149
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
150
|
+
}
|
|
151
|
+
default:
|
|
152
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
return {
|
|
157
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
158
|
+
isError: true,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
// Start server
|
|
163
|
+
async function main() {
|
|
164
|
+
const transport = new StdioServerTransport();
|
|
165
|
+
await server.connect(transport);
|
|
166
|
+
console.error('MemoClaw MCP server running');
|
|
167
|
+
}
|
|
168
|
+
main().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "memoclaw-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for MemoClaw semantic memory API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"memoclaw-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
16
|
+
"@x402/core": "^2.3.0",
|
|
17
|
+
"@x402/evm": "^2.3.0",
|
|
18
|
+
"viem": "^2.0.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^22.0.0",
|
|
22
|
+
"typescript": "^5.7.0"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"mcp",
|
|
26
|
+
"memory",
|
|
27
|
+
"ai-agent",
|
|
28
|
+
"semantic-search"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT"
|
|
31
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import {
|
|
5
|
+
CallToolRequestSchema,
|
|
6
|
+
ListToolsRequestSchema,
|
|
7
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
8
|
+
import { x402Client } from '@x402/core/client';
|
|
9
|
+
import { x402HTTPClient } from '@x402/core/http';
|
|
10
|
+
import { ExactEvmScheme } from '@x402/evm/exact/client';
|
|
11
|
+
import { toClientEvmSigner } from '@x402/evm';
|
|
12
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
13
|
+
|
|
14
|
+
const API_URL = process.env.MEMOCLAW_URL || 'https://api.memoclaw.dev';
|
|
15
|
+
const PRIVATE_KEY = process.env.MEMOCLAW_PRIVATE_KEY;
|
|
16
|
+
|
|
17
|
+
if (!PRIVATE_KEY) {
|
|
18
|
+
console.error('MEMOCLAW_PRIVATE_KEY environment variable required');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// x402 payment client setup
|
|
23
|
+
const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`);
|
|
24
|
+
const signer = toClientEvmSigner(account);
|
|
25
|
+
const coreClient = new x402Client().register('eip155:*', new ExactEvmScheme(signer));
|
|
26
|
+
const client = new x402HTTPClient(coreClient);
|
|
27
|
+
|
|
28
|
+
async function makeRequest(method: string, path: string, body?: any) {
|
|
29
|
+
const url = `${API_URL}${path}`;
|
|
30
|
+
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
|
|
31
|
+
const options: RequestInit = { method, headers };
|
|
32
|
+
if (body) options.body = JSON.stringify(body);
|
|
33
|
+
|
|
34
|
+
let res = await fetch(url, options);
|
|
35
|
+
|
|
36
|
+
// Handle 402 Payment Required
|
|
37
|
+
if (res.status === 402) {
|
|
38
|
+
const errorBody = await res.json();
|
|
39
|
+
const paymentRequired = client.getPaymentRequiredResponse(
|
|
40
|
+
(name: string) => res.headers.get(name),
|
|
41
|
+
errorBody
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const paymentPayload = await client.createPaymentPayload(paymentRequired);
|
|
45
|
+
const paymentHeaders = client.encodePaymentSignatureHeader(paymentPayload);
|
|
46
|
+
|
|
47
|
+
res = await fetch(url, {
|
|
48
|
+
method,
|
|
49
|
+
headers: { ...headers, ...paymentHeaders },
|
|
50
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!res.ok) {
|
|
55
|
+
const err = await res.text();
|
|
56
|
+
throw new Error(`HTTP ${res.status}: ${err}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return res.json();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const server = new Server(
|
|
63
|
+
{ name: 'memoclaw', version: '1.0.0' },
|
|
64
|
+
{ capabilities: { tools: {} } }
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// List available tools
|
|
68
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
69
|
+
tools: [
|
|
70
|
+
{
|
|
71
|
+
name: 'memoclaw_store',
|
|
72
|
+
description: 'Store a memory with semantic embeddings for later recall',
|
|
73
|
+
inputSchema: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
content: { type: 'string', description: 'Memory content to store' },
|
|
77
|
+
importance: { type: 'number', description: 'Importance score 0-1 (default 0.5)' },
|
|
78
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Tags for categorization' },
|
|
79
|
+
namespace: { type: 'string', description: 'Namespace for organization' },
|
|
80
|
+
},
|
|
81
|
+
required: ['content'],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'memoclaw_recall',
|
|
86
|
+
description: 'Recall memories via semantic search',
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: 'object',
|
|
89
|
+
properties: {
|
|
90
|
+
query: { type: 'string', description: 'Search query' },
|
|
91
|
+
limit: { type: 'number', description: 'Max results (default 5)' },
|
|
92
|
+
min_similarity: { type: 'number', description: 'Min similarity threshold 0-1' },
|
|
93
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags' },
|
|
94
|
+
namespace: { type: 'string', description: 'Filter by namespace' },
|
|
95
|
+
},
|
|
96
|
+
required: ['query'],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'memoclaw_list',
|
|
101
|
+
description: 'List stored memories',
|
|
102
|
+
inputSchema: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: {
|
|
105
|
+
limit: { type: 'number', description: 'Max results (default 20)' },
|
|
106
|
+
offset: { type: 'number', description: 'Pagination offset' },
|
|
107
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags' },
|
|
108
|
+
namespace: { type: 'string', description: 'Filter by namespace' },
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'memoclaw_delete',
|
|
114
|
+
description: 'Delete a memory by ID',
|
|
115
|
+
inputSchema: {
|
|
116
|
+
type: 'object',
|
|
117
|
+
properties: {
|
|
118
|
+
id: { type: 'string', description: 'Memory ID to delete' },
|
|
119
|
+
},
|
|
120
|
+
required: ['id'],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
}));
|
|
125
|
+
|
|
126
|
+
// Handle tool calls
|
|
127
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
128
|
+
const { name, arguments: args } = request.params;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
switch (name) {
|
|
132
|
+
case 'memoclaw_store': {
|
|
133
|
+
const { content, importance, tags, namespace } = args as any;
|
|
134
|
+
const result = await makeRequest('POST', '/v1/store', {
|
|
135
|
+
content,
|
|
136
|
+
importance,
|
|
137
|
+
metadata: tags ? { tags } : undefined,
|
|
138
|
+
namespace,
|
|
139
|
+
});
|
|
140
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case 'memoclaw_recall': {
|
|
144
|
+
const { query, limit, min_similarity, tags, namespace } = args as any;
|
|
145
|
+
const result = await makeRequest('POST', '/v1/recall', {
|
|
146
|
+
query,
|
|
147
|
+
limit,
|
|
148
|
+
min_similarity,
|
|
149
|
+
filters: tags ? { tags } : undefined,
|
|
150
|
+
namespace,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Format results nicely
|
|
154
|
+
const memories = result.memories || [];
|
|
155
|
+
const formatted = memories.map((m: any) =>
|
|
156
|
+
`[${m.score?.toFixed(3) || '?'}] ${m.content}\n tags: ${m.metadata?.tags?.join(', ') || 'none'}`
|
|
157
|
+
).join('\n\n');
|
|
158
|
+
|
|
159
|
+
return { content: [{ type: 'text', text: formatted || 'No memories found' }] };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
case 'memoclaw_list': {
|
|
163
|
+
const { limit, offset, tags, namespace } = args as any;
|
|
164
|
+
const params = new URLSearchParams();
|
|
165
|
+
if (limit) params.set('limit', String(limit));
|
|
166
|
+
if (offset) params.set('offset', String(offset));
|
|
167
|
+
if (namespace) params.set('namespace', namespace);
|
|
168
|
+
|
|
169
|
+
const result = await makeRequest('GET', `/v1/memories?${params}`);
|
|
170
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
case 'memoclaw_delete': {
|
|
174
|
+
const { id } = args as any;
|
|
175
|
+
const result = await makeRequest('DELETE', `/v1/memories/${id}`);
|
|
176
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
default:
|
|
180
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
return {
|
|
184
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
185
|
+
isError: true,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Start server
|
|
191
|
+
async function main() {
|
|
192
|
+
const transport = new StdioServerTransport();
|
|
193
|
+
await server.connect(transport);
|
|
194
|
+
console.error('MemoClaw MCP server running');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
main().catch(console.error);
|
package/tsconfig.json
ADDED