@cybermem/mcp 0.5.1 โ†’ 0.6.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.
Files changed (68) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +187 -194
  3. package/package.json +29 -28
  4. package/requirements.txt +2 -0
  5. package/server.py +347 -0
  6. package/src/index.ts +227 -0
  7. package/test_mcp.py +111 -0
  8. package/tsconfig.json +14 -0
  9. package/dist/commands/deploy.js +0 -230
  10. package/dist/commands/init.js +0 -65
  11. package/dist/templates/ansible/inventory/hosts.ini +0 -3
  12. package/dist/templates/ansible/playbooks/deploy-cybermem.yml +0 -71
  13. package/dist/templates/ansible/playbooks/stop-cybermem.yml +0 -17
  14. package/dist/templates/charts/cybermem/Chart.yaml +0 -6
  15. package/dist/templates/charts/cybermem/templates/dashboard-deployment.yaml +0 -29
  16. package/dist/templates/charts/cybermem/templates/dashboard-service.yaml +0 -20
  17. package/dist/templates/charts/cybermem/templates/openmemory-deployment.yaml +0 -40
  18. package/dist/templates/charts/cybermem/templates/openmemory-pvc.yaml +0 -10
  19. package/dist/templates/charts/cybermem/templates/openmemory-service.yaml +0 -13
  20. package/dist/templates/charts/cybermem/values-vps.yaml +0 -18
  21. package/dist/templates/charts/cybermem/values.yaml +0 -42
  22. package/dist/templates/docker-compose.yml +0 -219
  23. package/dist/templates/envs/local.example +0 -27
  24. package/dist/templates/envs/rpi.example +0 -27
  25. package/dist/templates/envs/vps.example +0 -25
  26. package/dist/templates/monitoring/db_exporter/Dockerfile +0 -19
  27. package/dist/templates/monitoring/db_exporter/exporter.py +0 -313
  28. package/dist/templates/monitoring/db_exporter/requirements.txt +0 -2
  29. package/dist/templates/monitoring/grafana/dashboards/cybermem.json +0 -1088
  30. package/dist/templates/monitoring/grafana/provisioning/dashboards/default.yml +0 -12
  31. package/dist/templates/monitoring/grafana/provisioning/datasources/prometheus.yml +0 -9
  32. package/dist/templates/monitoring/log_exporter/Dockerfile +0 -13
  33. package/dist/templates/monitoring/log_exporter/exporter.py +0 -274
  34. package/dist/templates/monitoring/log_exporter/requirements.txt +0 -1
  35. package/dist/templates/monitoring/postgres_exporter/queries.yml +0 -22
  36. package/dist/templates/monitoring/prometheus/prometheus.yml +0 -22
  37. package/dist/templates/monitoring/traefik/traefik.yml +0 -32
  38. package/dist/templates/monitoring/vector/vector.toml/vector.yaml +0 -77
  39. package/dist/templates/monitoring/vector/vector.yaml +0 -106
  40. package/templates/ansible/inventory/hosts.ini +0 -3
  41. package/templates/ansible/playbooks/deploy-cybermem.yml +0 -71
  42. package/templates/ansible/playbooks/stop-cybermem.yml +0 -17
  43. package/templates/charts/cybermem/Chart.yaml +0 -6
  44. package/templates/charts/cybermem/templates/dashboard-deployment.yaml +0 -29
  45. package/templates/charts/cybermem/templates/dashboard-service.yaml +0 -20
  46. package/templates/charts/cybermem/templates/openmemory-deployment.yaml +0 -40
  47. package/templates/charts/cybermem/templates/openmemory-pvc.yaml +0 -10
  48. package/templates/charts/cybermem/templates/openmemory-service.yaml +0 -13
  49. package/templates/charts/cybermem/values-vps.yaml +0 -18
  50. package/templates/charts/cybermem/values.yaml +0 -42
  51. package/templates/docker-compose.yml +0 -219
  52. package/templates/envs/local.example +0 -27
  53. package/templates/envs/rpi.example +0 -27
  54. package/templates/envs/vps.example +0 -25
  55. package/templates/monitoring/db_exporter/Dockerfile +0 -19
  56. package/templates/monitoring/db_exporter/exporter.py +0 -313
  57. package/templates/monitoring/db_exporter/requirements.txt +0 -2
  58. package/templates/monitoring/grafana/dashboards/cybermem.json +0 -1088
  59. package/templates/monitoring/grafana/provisioning/dashboards/default.yml +0 -12
  60. package/templates/monitoring/grafana/provisioning/datasources/prometheus.yml +0 -9
  61. package/templates/monitoring/log_exporter/Dockerfile +0 -13
  62. package/templates/monitoring/log_exporter/exporter.py +0 -274
  63. package/templates/monitoring/log_exporter/requirements.txt +0 -1
  64. package/templates/monitoring/postgres_exporter/queries.yml +0 -22
  65. package/templates/monitoring/prometheus/prometheus.yml +0 -22
  66. package/templates/monitoring/traefik/traefik.yml +0 -32
  67. package/templates/monitoring/vector/vector.toml/vector.yaml +0 -77
  68. package/templates/monitoring/vector/vector.yaml +0 -106
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # @cybermem/mcp
2
2
 
3
- Universal Long-Term Memory for AI Agents.
3
+ CyberMem MCP Server โ€” AI Memory via Model Context Protocol.
4
4
 
5
5
  ๐ŸŒ [cybermem.dev](https://cybermem.dev) ยท ๐Ÿ“– [Docs](https://docs.cybermem.dev) ยท ๐Ÿ“ฆ [GitHub](https://github.com/mikhailkogan17/cybermem)
package/dist/index.js CHANGED
@@ -1,212 +1,205 @@
1
- #!/usr/bin/env node
2
1
  "use strict";
3
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
4
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
4
  };
6
5
  Object.defineProperty(exports, "__esModule", { value: true });
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const commander_1 = require("commander");
9
- const crypto_1 = __importDefault(require("crypto"));
10
- const execa_1 = __importDefault(require("execa"));
11
- const fs_1 = __importDefault(require("fs"));
12
- const inquirer_1 = __importDefault(require("inquirer"));
13
- const os_1 = __importDefault(require("os"));
14
- const path_1 = __importDefault(require("path"));
15
- const program = new commander_1.Command();
16
- program
17
- .name('mcp')
18
- .description('CyberMem - Deploy your AI memory server in one command')
19
- .version('1.0.0')
20
- .option('--rpi', 'Deploy to Raspberry Pi (default: local)')
21
- .option('--vps', 'Deploy to VPS/Cloud server')
22
- .option('-h, --host <host>', 'SSH Host (user@ip) for remote deployment')
23
- .option('--remote-access', 'Enable Tailscale Funnel for HTTPS remote access')
24
- .action(async (options) => {
25
- // Determine target from flags
26
- let target = 'local';
27
- if (options.rpi)
28
- target = 'rpi';
29
- if (options.vps)
30
- target = 'vps';
31
- const useTailscale = options.remoteAccess;
32
- console.log(chalk_1.default.blue(`Deploying CyberMem (${target})...`));
6
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
7
+ const sse_js_1 = require("@modelcontextprotocol/sdk/server/sse.js");
8
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
9
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const cors_1 = __importDefault(require("cors"));
12
+ const dotenv_1 = __importDefault(require("dotenv"));
13
+ const express_1 = __importDefault(require("express"));
14
+ dotenv_1.default.config();
15
+ // Parse CLI args for remote mode
16
+ const args = process.argv.slice(2);
17
+ const getArg = (name) => {
18
+ const idx = args.indexOf(name);
19
+ return idx !== -1 && args[idx + 1] ? args[idx + 1] : undefined;
20
+ };
21
+ const cliUrl = getArg('--url');
22
+ const cliApiKey = getArg('--api-key');
23
+ const cliClientName = getArg('--client-name');
24
+ // Use CLI args first, then env, then defaults
25
+ // Default to local CyberMem backend (via Traefik on port 8626)
26
+ const API_URL = cliUrl || process.env.CYBERMEM_URL || "http://localhost:8626/memory";
27
+ const API_KEY = cliApiKey || process.env.OM_API_KEY || "";
28
+ // Track client name per session
29
+ let currentClientName = cliClientName || "cybermem-mcp";
30
+ const server = new index_js_1.Server({
31
+ name: "cybermem-mcp",
32
+ version: "0.2.0",
33
+ }, {
34
+ capabilities: {
35
+ tools: {},
36
+ },
37
+ });
38
+ const tools = [
39
+ {
40
+ name: "add_memory",
41
+ description: "Store a new memory in CyberMem",
42
+ inputSchema: {
43
+ type: "object",
44
+ properties: {
45
+ content: { type: "string" },
46
+ user_id: { type: "string" },
47
+ tags: { type: "array", items: { type: "string" } },
48
+ },
49
+ required: ["content"],
50
+ },
51
+ },
52
+ {
53
+ name: "query_memory",
54
+ description: "Search for relevant memories",
55
+ inputSchema: {
56
+ type: "object",
57
+ properties: {
58
+ query: { type: "string" },
59
+ k: { type: "number", default: 5 },
60
+ },
61
+ required: ["query"],
62
+ },
63
+ },
64
+ {
65
+ name: "list_memories",
66
+ description: "List recent memories",
67
+ inputSchema: {
68
+ type: "object",
69
+ properties: {
70
+ limit: { type: "number", default: 10 },
71
+ },
72
+ },
73
+ },
74
+ {
75
+ name: "delete_memory",
76
+ description: "Delete a memory by ID",
77
+ inputSchema: {
78
+ type: "object",
79
+ properties: {
80
+ id: { type: "string" },
81
+ },
82
+ required: ["id"],
83
+ },
84
+ },
85
+ {
86
+ name: "update_memory",
87
+ description: "Update a memory by ID",
88
+ inputSchema: {
89
+ type: "object",
90
+ properties: {
91
+ id: { type: "string" },
92
+ content: { type: "string" },
93
+ tags: { type: "array", items: { type: "string" } },
94
+ metadata: { type: "object" },
95
+ },
96
+ required: ["id"],
97
+ },
98
+ }
99
+ ];
100
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
101
+ tools,
102
+ }));
103
+ // Create axios instance
104
+ const apiClient = axios_1.default.create({
105
+ baseURL: API_URL,
106
+ headers: {
107
+ "Authorization": `Bearer ${API_KEY}`,
108
+ },
109
+ });
110
+ // Helper to get client with context
111
+ function getClient(customHeaders = {}) {
112
+ // Identity is taken from currentClientName which is updated per-request in SSE mode
113
+ const clientName = customHeaders["X-Client-Name"] || currentClientName;
114
+ return {
115
+ ...apiClient,
116
+ get: (url, config) => apiClient.get(url, { ...config, headers: { "X-Client-Name": clientName, ...config?.headers } }),
117
+ post: (url, data, config) => apiClient.post(url, data, { ...config, headers: { "X-Client-Name": clientName, ...config?.headers } }),
118
+ put: (url, data, config) => apiClient.put(url, data, { ...config, headers: { "X-Client-Name": clientName, ...config?.headers } }),
119
+ patch: (url, data, config) => apiClient.patch(url, data, { ...config, headers: { "X-Client-Name": clientName, ...config?.headers } }),
120
+ delete: (url, config) => apiClient.delete(url, { ...config, headers: { "X-Client-Name": clientName, ...config?.headers } }),
121
+ };
122
+ }
123
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
124
+ const { name, arguments: args } = request.params;
33
125
  try {
34
- // Resolve Template Directory (Support both Dev and Prod)
35
- let templateDir = path_1.default.resolve(__dirname, '../templates');
36
- if (!fs_1.default.existsSync(templateDir)) {
37
- templateDir = path_1.default.resolve(__dirname, '../../templates');
38
- }
39
- if (!fs_1.default.existsSync(templateDir)) {
40
- templateDir = path_1.default.resolve(process.cwd(), 'packages/cli/templates');
41
- }
42
- if (!fs_1.default.existsSync(templateDir)) {
43
- throw new Error(`Templates not found at ${templateDir}. Please ensure package is built correctly.`);
44
- }
45
- if (target === 'local') {
46
- const composeFile = path_1.default.join(templateDir, 'docker-compose.yml');
47
- const internalEnvExample = path_1.default.join(templateDir, 'envs/local.example');
48
- if (!fs_1.default.existsSync(composeFile)) {
49
- console.error(chalk_1.default.red(`Internal Error: Template not found at ${composeFile}`));
50
- process.exit(1);
126
+ switch (name) {
127
+ case "add_memory": {
128
+ const response = await getClient().post("/add", args);
129
+ return { content: [{ type: "text", text: JSON.stringify(response.data) }] };
51
130
  }
52
- // Home Directory Config
53
- const homeDir = os_1.default.homedir();
54
- const configDir = path_1.default.join(homeDir, '.cybermem');
55
- const envFile = path_1.default.join(configDir, '.env');
56
- const dataDir = path_1.default.join(configDir, 'data');
57
- // 1. Ensure ~/.cybermem exists
58
- if (!fs_1.default.existsSync(configDir)) {
59
- fs_1.default.mkdirSync(configDir, { recursive: true });
60
- fs_1.default.mkdirSync(dataDir, { recursive: true });
131
+ case "query_memory": {
132
+ const response = await getClient().post("/query", args);
133
+ return { content: [{ type: "text", text: JSON.stringify(response.data) }] };
61
134
  }
62
- // 2. Local Mode: Simplified setup without mandatory API key
63
- if (!fs_1.default.existsSync(envFile)) {
64
- console.log(chalk_1.default.yellow(`Initializing local configuration in ${configDir}...`));
65
- const envContent = fs_1.default.readFileSync(internalEnvExample, 'utf-8');
66
- fs_1.default.writeFileSync(envFile, envContent);
67
- console.log(chalk_1.default.green(`Created .env at ${envFile}`));
135
+ case "list_memories": {
136
+ const limit = args?.limit || 10;
137
+ const response = await getClient().get(`/all?l=${limit}`);
138
+ return { content: [{ type: "text", text: JSON.stringify(response.data) }] };
68
139
  }
69
- console.log(chalk_1.default.blue('Starting CyberMem services in Local Mode...'));
70
- await (0, execa_1.default)('docker-compose', [
71
- '-f', composeFile,
72
- '--env-file', envFile,
73
- '--project-name', 'cybermem',
74
- 'up', '-d', '--remove-orphans'
75
- ], {
76
- stdio: 'inherit',
77
- env: {
78
- ...process.env,
79
- DATA_DIR: dataDir,
80
- CYBERMEM_ENV_PATH: envFile,
81
- CYBERMEM_API_KEY: ''
82
- }
83
- });
84
- console.log(chalk_1.default.green('\n๐ŸŽ‰ CyberMem Installed!'));
85
- console.log('');
86
- console.log(chalk_1.default.bold('Next Steps:'));
87
- console.log(` 1. Open ${chalk_1.default.underline('http://localhost:3000/client-connect')} to connect your MCP clients`);
88
- console.log(` 2. Default password: ${chalk_1.default.bold('admin')} (you'll be prompted to change it)`);
89
- console.log('');
90
- console.log(chalk_1.default.dim('Local mode is active: No API key required for connections from this laptop.'));
91
- }
92
- else if (target === 'rpi') {
93
- const composeFile = path_1.default.join(templateDir, 'docker-compose.yml');
94
- const internalEnvExample = path_1.default.join(templateDir, 'envs/rpi.example');
95
- let sshHost = options.host;
96
- if (!sshHost) {
97
- const answers = await inquirer_1.default.prompt([
98
- {
99
- type: 'input',
100
- name: 'host',
101
- message: 'Enter SSH Host (e.g. pi@raspberrypi.local):',
102
- validate: (input) => input.includes('@') ? true : 'Format must be user@host'
103
- }
104
- ]);
105
- sshHost = answers.host;
140
+ case "delete_memory": {
141
+ const { id } = args;
142
+ await getClient().delete(`/${id}`);
143
+ return { content: [{ type: "text", text: `Memory ${id} deleted` }] };
106
144
  }
107
- console.log(chalk_1.default.blue(`Remote deploying to ${sshHost}...`));
108
- // 1. Create remote directory
109
- await (0, execa_1.default)('ssh', [sshHost, 'mkdir -p ~/.cybermem/data']);
110
- // 2. Initial Env Setup (if missing)
111
- try {
112
- await (0, execa_1.default)('ssh', [sshHost, '[ -f ~/.cybermem/.env ]']);
113
- console.log(chalk_1.default.gray('Remote .env exists, skipping generation.'));
145
+ case "update_memory": {
146
+ const { id, ...updates } = args;
147
+ const response = await getClient().patch(`/${id}`, updates);
148
+ return { content: [{ type: "text", text: JSON.stringify(response.data) }] };
114
149
  }
115
- catch (e) {
116
- console.log(chalk_1.default.yellow('Generating remote .env...'));
117
- let envContent = fs_1.default.readFileSync(internalEnvExample, 'utf-8');
118
- const newKey = `sk-${crypto_1.default.randomBytes(16).toString('hex')}`;
119
- if (envContent.includes('CYBERMEM_API_KEY=')) {
120
- envContent = envContent.replace(/CYBERMEM_API_KEY=.*/, `CYBERMEM_API_KEY=${newKey}`);
121
- }
122
- const tempEnv = path_1.default.join(os_1.default.tmpdir(), 'cybermem-rpi.env');
123
- fs_1.default.writeFileSync(tempEnv, envContent);
124
- await (0, execa_1.default)('scp', [tempEnv, `${sshHost}:~/.cybermem/.env`]);
125
- fs_1.default.unlinkSync(tempEnv);
150
+ default:
151
+ throw new Error(`Unknown tool: ${name}`);
152
+ }
153
+ }
154
+ catch (error) {
155
+ return {
156
+ content: [{ type: "text", text: `Error: ${error.message}` }],
157
+ isError: true,
158
+ };
159
+ }
160
+ });
161
+ async function run() {
162
+ const isSse = process.argv.includes("--sse") || !!process.env.PORT;
163
+ if (isSse) {
164
+ const app = (0, express_1.default)();
165
+ app.use((0, cors_1.default)());
166
+ const port = process.env.PORT || 8627;
167
+ let transport = null;
168
+ app.get("/sse", async (req, res) => {
169
+ // Extract client name from header
170
+ const clientName = req.headers["x-client-name"];
171
+ if (clientName) {
172
+ currentClientName = clientName;
126
173
  }
127
- // 3. Copy Docker Compose
128
- console.log(chalk_1.default.blue('Uploading templates...'));
129
- await (0, execa_1.default)('scp', [composeFile, `${sshHost}:~/.cybermem/docker-compose.yml`]);
130
- // 4. Run Docker Compose Remotely
131
- console.log(chalk_1.default.blue('Starting services on RPi...'));
132
- // DOCKER_DEFAULT_PLATFORM=linux/arm64 forces arm64 images on RPi with 64-bit kernel but 32-bit Docker
133
- const remoteCmd = `
134
- export CYBERMEM_ENV_PATH=~/.cybermem/.env
135
- export DATA_DIR=~/.cybermem/data
136
- export DOCKER_DEFAULT_PLATFORM=linux/arm64
137
- docker-compose -f ~/.cybermem/docker-compose.yml up -d --remove-orphans
138
- `;
139
- await (0, execa_1.default)('ssh', [sshHost, remoteCmd], { stdio: 'inherit' });
140
- console.log(chalk_1.default.green('\nโœ… RPi deployment successful!'));
141
- const hostIp = sshHost.split('@')[1];
142
- console.log(chalk_1.default.bold('Access Points (LAN):'));
143
- console.log(` - Dashboard: ${chalk_1.default.underline(`http://${hostIp}:3000`)} (admin/admin)`);
144
- console.log(` - OpenMemory: ${chalk_1.default.underline(`http://${hostIp}:8080`)}`);
145
- // Tailscale Funnel setup
146
- if (useTailscale) {
147
- console.log(chalk_1.default.blue('\n๐Ÿ”— Setting up Remote Access (Tailscale Funnel)...'));
148
- try {
149
- try {
150
- await (0, execa_1.default)('ssh', [sshHost, 'which tailscale']);
151
- }
152
- catch (e) {
153
- console.log(chalk_1.default.yellow(' Tailscale not found. Installing...'));
154
- await (0, execa_1.default)('ssh', [sshHost, 'curl -fsSL https://tailscale.com/install.sh | sh'], { stdio: 'inherit' });
155
- }
156
- console.log(chalk_1.default.blue(' Ensuring Tailscale is up...'));
157
- try {
158
- await (0, execa_1.default)('ssh', [sshHost, 'tailscale status']);
159
- }
160
- catch (e) {
161
- console.log(chalk_1.default.yellow(' โš ๏ธ Tailscale authentication required. Please follow the prompts:'));
162
- await (0, execa_1.default)('ssh', [sshHost, 'sudo tailscale up'], { stdio: 'inherit' });
163
- }
164
- console.log(chalk_1.default.blue(' Configuring HTTPS Funnel (requires sudo access)...'));
165
- console.log(chalk_1.default.gray(' You may be prompted for your RPi password.'));
166
- await (0, execa_1.default)('ssh', ['-t', sshHost, 'sudo tailscale serve reset'], { stdio: 'inherit' }).catch(() => { });
167
- await (0, execa_1.default)('ssh', ['-t', sshHost, 'sudo tailscale serve --bg --set-path /cybermem http://127.0.0.1:8626'], { stdio: 'inherit' });
168
- await (0, execa_1.default)('ssh', ['-t', sshHost, 'sudo tailscale serve --bg http://127.0.0.1:3000'], { stdio: 'inherit' });
169
- await (0, execa_1.default)('ssh', ['-t', sshHost, 'sudo tailscale funnel --bg 443'], { stdio: 'inherit' });
170
- const { stdout } = await (0, execa_1.default)('ssh', [sshHost, "tailscale status --json | jq -r '.Self.DNSName' | sed 's/\\.$//'"]);
171
- const dnsName = stdout.trim();
172
- console.log(chalk_1.default.green('\n๐ŸŒ Remote Access Active (HTTPS):'));
173
- console.log(` - Dashboard: ${chalk_1.default.underline(`https://${dnsName}/`)}`);
174
- console.log(` - MCP API: ${chalk_1.default.underline(`https://${dnsName}/cybermem/mcp`)}`);
175
- }
176
- catch (e) {
177
- console.log(chalk_1.default.red('\nโŒ Remote Access setup failed:'));
178
- console.error(e);
179
- console.log(chalk_1.default.gray('Manual setup: curl -fsSL https://tailscale.com/install.sh | sh && sudo tailscale up'));
180
- }
174
+ transport = new sse_js_1.SSEServerTransport("/messages", res);
175
+ await server.connect(transport);
176
+ });
177
+ app.post("/messages", async (req, res) => {
178
+ // Also check headers on messages
179
+ const clientName = req.headers["x-client-name"];
180
+ if (clientName) {
181
+ currentClientName = clientName;
182
+ }
183
+ if (transport) {
184
+ await transport.handlePostMessage(req, res);
181
185
  }
182
186
  else {
183
- console.log(chalk_1.default.gray('\n๐Ÿ’ก For remote access, re-run with: npx @cybermem/mcp --rpi --remote-access'));
187
+ res.status(400).send("Session not established");
184
188
  }
185
- }
186
- else if (target === 'vps') {
187
- console.log(chalk_1.default.yellow('VPS deployment is similar to RPi.'));
188
- console.log(chalk_1.default.blue('\n๐Ÿ“‹ VPS Deployment Steps:'));
189
- console.log('1. Run: npx @cybermem/mcp --rpi --host user@your-vps-ip');
190
- console.log('2. For HTTPS, choose one of:');
191
- console.log(chalk_1.default.gray(' a) Tailscale Funnel: --remote-access flag'));
192
- console.log(chalk_1.default.gray(' b) Caddy (recommended for public VPS):'));
193
- console.log(chalk_1.default.gray(' - Install Caddy: sudo apt install caddy'));
194
- console.log(chalk_1.default.gray(' - Configure /etc/caddy/Caddyfile:'));
195
- console.log(chalk_1.default.cyan(`
196
- cybermem.yourdomain.com {
197
- reverse_proxy localhost:3000
198
- }
199
- api.cybermem.yourdomain.com {
200
- reverse_proxy localhost:8080
201
- }
202
- `));
203
- console.log(chalk_1.default.gray(' - Restart: sudo systemctl restart caddy'));
204
- console.log(chalk_1.default.green('\n๐Ÿ“š Full docs: https://cybermem.dev/docs#https'));
205
- }
189
+ });
190
+ app.listen(port, () => {
191
+ console.error(`CyberMem MCP Server running on SSE at http://localhost:${port}`);
192
+ console.error(` - SSE endpoint: http://localhost:${port}/sse`);
193
+ console.error(` - Message endpoint: http://localhost:${port}/messages`);
194
+ });
206
195
  }
207
- catch (error) {
208
- console.error(chalk_1.default.red('Deployment failed:'), error);
209
- process.exit(1);
196
+ else {
197
+ const transport = new stdio_js_1.StdioServerTransport();
198
+ await server.connect(transport);
199
+ console.error("CyberMem MCP Server running on stdio");
210
200
  }
201
+ }
202
+ run().catch((error) => {
203
+ console.error("Fatal error running server:", error);
204
+ process.exit(1);
211
205
  });
212
- program.parse(process.argv);
package/package.json CHANGED
@@ -1,48 +1,49 @@
1
1
  {
2
2
  "name": "@cybermem/mcp",
3
- "version": "0.5.1",
4
- "description": "CyberMem โ€” Universal Long-Term Memory for AI Agents",
5
- "homepage": "https://cybermem.dev",
3
+ "version": "0.6.0",
4
+ "description": "CyberMem MCP Server (TypeScript)",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "cybermem-mcp": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "start": "node dist/index.js",
12
+ "dev": "ts-node src/index.ts"
13
+ },
6
14
  "repository": {
7
15
  "type": "git",
8
16
  "url": "https://github.com/mikhailkogan17/cybermem.git",
9
- "directory": "packages/cli"
17
+ "directory": "packages/mcp"
10
18
  },
11
- "bin": {
12
- "mcp": "./dist/index.js"
13
- },
14
- "files": [
15
- "dist",
16
- "templates"
17
- ],
18
- "scripts": {
19
- "build": "tsc && cp -r templates dist/",
20
- "start": "ts-node src/index.ts",
21
- "test:e2e": "ts-node e2e/test-mcp.ts",
22
- "prepublishOnly": "npm run build"
19
+ "homepage": "https://cybermem.dev",
20
+ "bugs": {
21
+ "url": "https://github.com/mikhailkogan17/cybermem/issues"
23
22
  },
24
23
  "keywords": [
25
- "cybermem",
26
- "cli",
27
- "ai",
28
- "mcp"
24
+ "mcp",
25
+ "ai-memory",
26
+ "claude",
27
+ "cursor",
28
+ "antigravity",
29
+ "openmemory",
30
+ "llm"
29
31
  ],
30
- "author": "Mikhail Kogan",
32
+ "author": "Mikhail Kogan <mikhailkogan17@gmail.com>",
31
33
  "license": "MIT",
32
34
  "publishConfig": {
33
35
  "access": "public"
34
36
  },
35
- "type": "commonjs",
36
37
  "dependencies": {
37
- "chalk": "^4.1.2",
38
- "commander": "^9.0.0",
38
+ "@modelcontextprotocol/sdk": "^1.0.0",
39
+ "axios": "^1.13.2",
40
+ "cors": "^2.8.5",
39
41
  "dotenv": "^16.0.0",
40
- "execa": "^5.1.1",
41
- "inquirer": "^8.2.0",
42
- "ora": "^5.4.1"
42
+ "express": "^5.2.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/inquirer": "^9.0.3",
45
+ "@types/cors": "^2.8.19",
46
+ "@types/express": "^5.0.6",
46
47
  "@types/node": "^18.0.0",
47
48
  "ts-node": "^10.9.1",
48
49
  "typescript": "^5.0.0"
@@ -0,0 +1,2 @@
1
+ mcp>=0.9.0
2
+ httpx>=0.27.0