cf-memory-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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 John Lam
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # CF Memory MCP
2
+
3
+ [![npm version](https://badge.fury.io/js/cf-memory-mcp.svg)](https://badge.fury.io/js/cf-memory-mcp)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A portable **MCP (Model Context Protocol)** server for AI memory storage using **Cloudflare infrastructure**. This package allows AI coding agents to store, retrieve, and search memories using a production-ready, serverless backend.
7
+
8
+ ## 🚀 Quick Start
9
+
10
+ ```bash
11
+ # Run directly with npx (no installation required)
12
+ npx cf-memory-mcp
13
+
14
+ # Or install globally
15
+ npm install -g cf-memory-mcp
16
+ cf-memory-mcp
17
+ ```
18
+
19
+ ## ✨ Features
20
+
21
+ - **🌐 Completely Portable** - No local setup required, connects to deployed Cloudflare Worker
22
+ - **⚡ Production Ready** - Uses Cloudflare D1 database and KV storage for reliability
23
+ - **🔧 Zero Configuration** - Works out of the box with any MCP client
24
+ - **🌍 Cross Platform** - Supports Windows, macOS, and Linux
25
+ - **📦 NPX Compatible** - Run instantly without installation
26
+ - **🔒 Secure** - Built on Cloudflare's secure infrastructure
27
+ - **🚄 Fast** - Global edge deployment with KV caching
28
+
29
+ ## 🛠️ Usage
30
+
31
+ ### With MCP Clients
32
+
33
+ Add to your MCP client configuration:
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "cf-memory": {
39
+ "command": "npx",
40
+ "args": ["cf-memory-mcp"]
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ ### With Augment
47
+
48
+ Add to your `augment-config.json`:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "cf-memory": {
54
+ "command": "npx",
55
+ "args": ["cf-memory-mcp"]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### With Claude Desktop
62
+
63
+ Add to your Claude Desktop MCP configuration:
64
+
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "cf-memory": {
69
+ "command": "npx",
70
+ "args": ["cf-memory-mcp"]
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## 🔧 Available Tools
77
+
78
+ The CF Memory MCP server provides three main tools:
79
+
80
+ ### `store_memory`
81
+ Store a new memory with optional metadata and tags.
82
+
83
+ **Parameters:**
84
+ - `content` (string, required) - The memory content
85
+ - `tags` (array, optional) - Tags for categorization
86
+ - `importance_score` (number, optional) - Importance score 0-10
87
+ - `metadata` (object, optional) - Additional metadata
88
+
89
+ ### `search_memories`
90
+ Search memories by content and tags.
91
+
92
+ **Parameters:**
93
+ - `query` (string, optional) - Full-text search query
94
+ - `tags` (array, optional) - Filter by specific tags
95
+ - `limit` (number, optional) - Maximum results (default: 10)
96
+ - `offset` (number, optional) - Results offset (default: 0)
97
+ - `min_importance` (number, optional) - Minimum importance score
98
+
99
+ ### `retrieve_memory`
100
+ Retrieve a specific memory by ID.
101
+
102
+ **Parameters:**
103
+ - `id` (string, required) - The unique memory ID
104
+
105
+ ## 🌐 Architecture
106
+
107
+ ```
108
+ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
109
+ │ MCP Client │ │ cf-memory-mcp │ │ Cloudflare Worker │
110
+ │ (Augment, │◄──►│ (npm package) │◄──►│ (Production API) │
111
+ │ Claude, etc.) │ │ │ │ │
112
+ └─────────────────┘ └──────────────────┘ └─────────────────────┘
113
+
114
+
115
+ ┌─────────────────────┐
116
+ │ Cloudflare D1 DB │
117
+ │ + KV Storage │
118
+ └─────────────────────┘
119
+ ```
120
+
121
+ ## 🔧 Command Line Options
122
+
123
+ ```bash
124
+ # Start the MCP server
125
+ npx cf-memory-mcp
126
+
127
+ # Show version
128
+ npx cf-memory-mcp --version
129
+
130
+ # Show help
131
+ npx cf-memory-mcp --help
132
+
133
+ # Enable debug logging
134
+ DEBUG=1 npx cf-memory-mcp
135
+ ```
136
+
137
+ ## 🌍 Environment Variables
138
+
139
+ - `DEBUG=1` - Enable debug logging
140
+ - `MCP_DEBUG=1` - Enable MCP-specific debug logging
141
+
142
+ ## 📋 Requirements
143
+
144
+ - **Node.js** 16.0.0 or higher
145
+ - **Internet connection** (connects to Cloudflare Worker)
146
+ - **MCP client** (Augment, Claude Desktop, etc.)
147
+
148
+ ## 🚀 Why CF Memory MCP?
149
+
150
+ ### Traditional Approach ❌
151
+ - Clone repository
152
+ - Set up local database
153
+ - Configure environment variables
154
+ - Manage local server process
155
+ - Handle updates manually
156
+
157
+ ### CF Memory MCP ✅
158
+ - Run `npx cf-memory-mcp`
159
+ - That's it! 🎉
160
+
161
+ ## 🔒 Privacy & Security
162
+
163
+ - **No local data storage** - All data stored securely in Cloudflare D1
164
+ - **HTTPS encryption** - All communication encrypted in transit
165
+ - **Edge deployment** - Data replicated globally for reliability
166
+ - **No API keys required** - Public read/write access for simplicity
167
+
168
+ ## 🤝 Contributing
169
+
170
+ Contributions are welcome! Please see the [GitHub repository](https://github.com/johnlam90/cf-memory-mcp) for more information.
171
+
172
+ ## 📄 License
173
+
174
+ MIT License - see [LICENSE](LICENSE) file for details.
175
+
176
+ ## 🔗 Links
177
+
178
+ - **GitHub Repository**: https://github.com/johnlam90/cf-memory-mcp
179
+ - **npm Package**: https://www.npmjs.com/package/cf-memory-mcp
180
+ - **Issues**: https://github.com/johnlam90/cf-memory-mcp/issues
181
+ - **MCP Specification**: https://modelcontextprotocol.io/
182
+
183
+ ---
184
+
185
+ Made with ❤️ by [John Lam](https://github.com/johnlam90)
@@ -0,0 +1,297 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * CF Memory MCP - Portable MCP Server
5
+ *
6
+ * A portable MCP (Model Context Protocol) server for AI memory storage
7
+ * using Cloudflare infrastructure. This executable connects to a deployed
8
+ * Cloudflare Worker to provide memory storage capabilities for AI agents.
9
+ *
10
+ * Usage: npx cf-memory-mcp
11
+ *
12
+ * @author John Lam <johnlam90@gmail.com>
13
+ * @license MIT
14
+ */
15
+
16
+ const https = require('https');
17
+ const { URL } = require('url');
18
+ const os = require('os');
19
+ const process = require('process');
20
+
21
+ // Configuration
22
+ const SERVER_URL = 'https://cf-memory-mcp.johnlam90.workers.dev/mcp/message';
23
+ const PACKAGE_VERSION = require('../package.json').version;
24
+ const TIMEOUT_MS = 30000;
25
+ const CONNECT_TIMEOUT_MS = 10000;
26
+
27
+ /**
28
+ * Cross-platform MCP stdio bridge
29
+ * Handles communication between MCP clients and the Cloudflare Worker
30
+ */
31
+ class CFMemoryMCP {
32
+ constructor() {
33
+ this.serverUrl = SERVER_URL;
34
+ this.userAgent = `cf-memory-mcp/${PACKAGE_VERSION} (${os.platform()} ${os.arch()}; Node.js ${process.version})`;
35
+
36
+ // Handle process termination gracefully
37
+ process.on('SIGINT', () => this.shutdown('SIGINT'));
38
+ process.on('SIGTERM', () => this.shutdown('SIGTERM'));
39
+ process.on('uncaughtException', (error) => {
40
+ this.logError('Uncaught exception:', error);
41
+ this.shutdown('ERROR');
42
+ });
43
+
44
+ // Set up stdio encoding
45
+ process.stdin.setEncoding('utf8');
46
+ process.stdout.setEncoding('utf8');
47
+
48
+ this.logDebug('CF Memory MCP server starting...');
49
+ this.logDebug(`Server URL: ${this.serverUrl}`);
50
+ this.logDebug(`User Agent: ${this.userAgent}`);
51
+ }
52
+
53
+ /**
54
+ * Log debug messages to stderr (won't interfere with MCP communication)
55
+ */
56
+ logDebug(message) {
57
+ if (process.env.DEBUG || process.env.MCP_DEBUG) {
58
+ process.stderr.write(`[DEBUG] ${new Date().toISOString()} ${message}\n`);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Log error messages to stderr
64
+ */
65
+ logError(message, error = null) {
66
+ const timestamp = new Date().toISOString();
67
+ process.stderr.write(`[ERROR] ${timestamp} ${message}\n`);
68
+ if (error && error.stack) {
69
+ process.stderr.write(`[ERROR] ${timestamp} ${error.stack}\n`);
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Start listening for MCP messages on stdin
75
+ */
76
+ async start() {
77
+ try {
78
+ // Test connectivity first
79
+ await this.testConnectivity();
80
+
81
+ this.logDebug('Starting MCP message processing...');
82
+ await this.processStdio();
83
+ } catch (error) {
84
+ this.logError('Failed to start MCP server:', error);
85
+ process.exit(1);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Test connectivity to the Cloudflare Worker
91
+ */
92
+ async testConnectivity() {
93
+ this.logDebug('Testing connectivity to Cloudflare Worker...');
94
+
95
+ const testMessage = {
96
+ jsonrpc: '2.0',
97
+ id: 'connectivity-test',
98
+ method: 'initialize',
99
+ params: {
100
+ protocolVersion: '2024-11-05',
101
+ capabilities: { tools: {} },
102
+ clientInfo: {
103
+ name: 'cf-memory-mcp',
104
+ version: PACKAGE_VERSION
105
+ }
106
+ }
107
+ };
108
+
109
+ try {
110
+ const response = await this.makeRequest(testMessage);
111
+ if (response.error) {
112
+ throw new Error(`Server responded with error: ${response.error.message}`);
113
+ }
114
+ this.logDebug('Connectivity test successful');
115
+ } catch (error) {
116
+ throw new Error(`Cannot connect to CF Memory server: ${error.message}`);
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Process stdio input/output for MCP communication
122
+ */
123
+ async processStdio() {
124
+ let buffer = '';
125
+
126
+ // Handle stdin data
127
+ for await (const chunk of process.stdin) {
128
+ buffer += chunk;
129
+
130
+ // Process complete JSON-RPC messages (one per line)
131
+ let newlineIndex;
132
+ while ((newlineIndex = buffer.indexOf('\n')) !== -1) {
133
+ const line = buffer.slice(0, newlineIndex).trim();
134
+ buffer = buffer.slice(newlineIndex + 1);
135
+
136
+ if (line) {
137
+ await this.handleMessage(line);
138
+ }
139
+ }
140
+ }
141
+
142
+ // Process any remaining buffer content
143
+ if (buffer.trim()) {
144
+ await this.handleMessage(buffer.trim());
145
+ }
146
+
147
+ this.logDebug('Stdin closed, shutting down...');
148
+ }
149
+
150
+ /**
151
+ * Handle a single MCP message
152
+ */
153
+ async handleMessage(messageStr) {
154
+ try {
155
+ const message = JSON.parse(messageStr);
156
+ this.logDebug(`Processing message: ${message.method} (id: ${message.id})`);
157
+
158
+ const response = await this.makeRequest(message);
159
+
160
+ // Send response to stdout
161
+ process.stdout.write(JSON.stringify(response) + '\n');
162
+
163
+ } catch (error) {
164
+ this.logError('Error handling message:', error);
165
+
166
+ // Send error response
167
+ const errorResponse = {
168
+ jsonrpc: '2.0',
169
+ id: null,
170
+ error: {
171
+ code: -32700,
172
+ message: 'Parse error',
173
+ data: error.message
174
+ }
175
+ };
176
+ process.stdout.write(JSON.stringify(errorResponse) + '\n');
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Make HTTP request to the Cloudflare Worker
182
+ */
183
+ async makeRequest(message) {
184
+ return new Promise((resolve, reject) => {
185
+ const url = new URL(this.serverUrl);
186
+ const postData = JSON.stringify(message);
187
+
188
+ const options = {
189
+ hostname: url.hostname,
190
+ port: url.port || 443,
191
+ path: url.pathname,
192
+ method: 'POST',
193
+ headers: {
194
+ 'Content-Type': 'application/json',
195
+ 'Accept': 'application/json',
196
+ 'User-Agent': this.userAgent,
197
+ 'Content-Length': Buffer.byteLength(postData)
198
+ },
199
+ timeout: TIMEOUT_MS
200
+ };
201
+
202
+ const req = https.request(options, (res) => {
203
+ let body = '';
204
+
205
+ res.on('data', (chunk) => {
206
+ body += chunk;
207
+ });
208
+
209
+ res.on('end', () => {
210
+ try {
211
+ const response = JSON.parse(body);
212
+ resolve(response);
213
+ } catch (error) {
214
+ resolve({
215
+ jsonrpc: '2.0',
216
+ id: message.id || null,
217
+ error: {
218
+ code: -32603,
219
+ message: 'Invalid JSON response from server',
220
+ data: error.message
221
+ }
222
+ });
223
+ }
224
+ });
225
+ });
226
+
227
+ req.on('error', (error) => {
228
+ resolve({
229
+ jsonrpc: '2.0',
230
+ id: message.id || null,
231
+ error: {
232
+ code: -32603,
233
+ message: 'Network error',
234
+ data: `Failed to connect to ${this.serverUrl}: ${error.message}`
235
+ }
236
+ });
237
+ });
238
+
239
+ req.on('timeout', () => {
240
+ req.destroy();
241
+ resolve({
242
+ jsonrpc: '2.0',
243
+ id: message.id || null,
244
+ error: {
245
+ code: -32603,
246
+ message: 'Request timeout',
247
+ data: `Server did not respond within ${TIMEOUT_MS}ms`
248
+ }
249
+ });
250
+ });
251
+
252
+ req.write(postData);
253
+ req.end();
254
+ });
255
+ }
256
+
257
+ /**
258
+ * Graceful shutdown
259
+ */
260
+ shutdown(reason = 'UNKNOWN') {
261
+ this.logDebug(`Shutting down (reason: ${reason})`);
262
+ process.exit(0);
263
+ }
264
+ }
265
+
266
+ // Handle command line arguments
267
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
268
+ console.log(`cf-memory-mcp v${PACKAGE_VERSION}`);
269
+ process.exit(0);
270
+ }
271
+
272
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
273
+ console.log(`
274
+ CF Memory MCP v${PACKAGE_VERSION}
275
+
276
+ A portable MCP (Model Context Protocol) server for AI memory storage using Cloudflare infrastructure.
277
+
278
+ Usage:
279
+ npx cf-memory-mcp Start the MCP server
280
+ npx cf-memory-mcp --version Show version
281
+ npx cf-memory-mcp --help Show this help
282
+
283
+ Environment Variables:
284
+ DEBUG=1 Enable debug logging
285
+ MCP_DEBUG=1 Enable MCP debug logging
286
+
287
+ For more information, visit: https://github.com/johnlam90/cf-memory-mcp
288
+ `);
289
+ process.exit(0);
290
+ }
291
+
292
+ // Start the MCP server
293
+ const server = new CFMemoryMCP();
294
+ server.start().catch(error => {
295
+ console.error('Failed to start CF Memory MCP server:', error.message);
296
+ process.exit(1);
297
+ });
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "cf-memory-mcp",
3
+ "version": "1.0.0",
4
+ "description": "A portable MCP (Model Context Protocol) server for AI memory storage using Cloudflare infrastructure",
5
+ "main": "bin/cf-memory-mcp.js",
6
+ "bin": {
7
+ "cf-memory-mcp": "./bin/cf-memory-mcp.js"
8
+ },
9
+ "author": {
10
+ "name": "John Lam",
11
+ "email": "johnlam90@gmail.com",
12
+ "url": "https://github.com/johnlam90"
13
+ },
14
+ "license": "MIT",
15
+ "keywords": [
16
+ "mcp",
17
+ "model-context-protocol",
18
+ "memory",
19
+ "ai",
20
+ "cloudflare",
21
+ "workers",
22
+ "d1",
23
+ "portable",
24
+ "cli",
25
+ "npx"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/johnlam90/cf-memory-mcp.git"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/johnlam90/cf-memory-mcp/issues"
33
+ },
34
+ "homepage": "https://github.com/johnlam90/cf-memory-mcp#readme",
35
+ "engines": {
36
+ "node": ">=16.0.0"
37
+ },
38
+ "os": [
39
+ "darwin",
40
+ "linux",
41
+ "win32"
42
+ ],
43
+ "files": [
44
+ "bin/",
45
+ "lib/",
46
+ "README.md",
47
+ "LICENSE"
48
+ ],
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "scripts": {
53
+ "start": "node bin/cf-memory-mcp.js",
54
+ "test": "node test/test-package.js",
55
+ "test:mcp": "node test/mcp-integration.test.js",
56
+ "prepublishOnly": "npm test",
57
+ "deploy": "wrangler deploy",
58
+ "dev": "wrangler dev",
59
+ "cf-typegen": "wrangler types",
60
+ "test:performance": "node test/performance-benchmark.js",
61
+ "test:all": "npm test && npm run test:mcp",
62
+ "test:full": "npm run test:all && npm run test:performance",
63
+ "benchmark": "npm run test:performance",
64
+ "validate": "npm run cf-typegen && npm run test:all"
65
+ },
66
+ "dependencies": {},
67
+ "devDependencies": {
68
+ "@modelcontextprotocol/sdk": "^1.13.1",
69
+ "@cloudflare/workers-types": "^4.20250129.0",
70
+ "@types/node": "22.13.0",
71
+ "@types/service-worker-mock": "^2.0.4",
72
+ "@types/uuid": "^9.0.8",
73
+ "chanfana": "^2.6.3",
74
+ "hono": "^4.6.20",
75
+ "uuid": "^11.0.4",
76
+ "zod": "^3.24.1",
77
+ "wrangler": "^4.21.2"
78
+ }
79
+ }