eon-memory 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/bin/eon.js ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+
3
+ const args = process.argv.slice(2);
4
+ const command = args[0];
5
+
6
+ if (command === "init") {
7
+ require("../src/init.js");
8
+ } else if (command === "status") {
9
+ require("../src/status.js");
10
+ } else if (command === "test") {
11
+ require("../src/test-connection.js");
12
+ } else if (command === "--help" || command === "-h" || !command) {
13
+ console.log(`
14
+ eon-memory - Persistent AI Memory System
15
+
16
+ Usage:
17
+ npx eon-memory init Set up EON Memory for this project
18
+ npx eon-memory status Check connection status
19
+ npx eon-memory test Test MCP connectivity
20
+
21
+ Setup:
22
+ 1. Register at https://app.ai-developer.ch
23
+ 2. Create an API key in Settings
24
+ 3. Run: npx eon-memory init
25
+
26
+ Docs: https://app.ai-developer.ch/capabilities
27
+ `);
28
+ } else {
29
+ console.error(`Unknown command: ${command}`);
30
+ console.log("Run 'npx eon-memory --help' for usage.");
31
+ process.exit(1);
32
+ }
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "eon-memory",
3
+ "version": "1.0.0",
4
+ "description": "EON Memory - Persistent AI memory system. Connect Claude Code, Cursor, or VS Code to your memory.",
5
+ "bin": {
6
+ "eon-memory": "./bin/eon.js"
7
+ },
8
+ "keywords": ["mcp", "memory", "ai", "claude", "cursor", "context"],
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/vasic-solutions/eon-memory"
13
+ },
14
+ "engines": {
15
+ "node": ">=18"
16
+ },
17
+ "files": [
18
+ "bin/",
19
+ "src/"
20
+ ]
21
+ }
package/src/init.js ADDED
@@ -0,0 +1,215 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * eon-memory init
5
+ *
6
+ * Sets up EON Memory for the current project:
7
+ * 1. Prompts for API key
8
+ * 2. Validates against the server
9
+ * 3. Adds MCP config to Claude Code settings
10
+ * 4. Generates CLAUDE.md in the project
11
+ */
12
+
13
+ const fs = require("fs");
14
+ const path = require("path");
15
+ const readline = require("readline");
16
+ const https = require("https");
17
+ const os = require("os");
18
+
19
+ const MCP_URL = "https://mcp.ai-developer.ch/mcp";
20
+ const API_BASE = "https://app.ai-developer.ch";
21
+ const INIT_ENDPOINT = "https://app.ai-developer.ch/api/proxy/cli/init";
22
+ const CLAUDE_MD_ENDPOINT = "https://app.ai-developer.ch/api/proxy/cli/claude-md";
23
+
24
+ function ask(question) {
25
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
26
+ return new Promise((resolve) => {
27
+ rl.question(question, (answer) => {
28
+ rl.close();
29
+ resolve(answer.trim());
30
+ });
31
+ });
32
+ }
33
+
34
+ function httpPost(url, body, headers = {}) {
35
+ return new Promise((resolve, reject) => {
36
+ const parsed = new URL(url);
37
+ const data = JSON.stringify(body);
38
+ const req = https.request(
39
+ {
40
+ hostname: parsed.hostname,
41
+ port: 443,
42
+ path: parsed.pathname,
43
+ method: "POST",
44
+ headers: {
45
+ "Content-Type": "application/json",
46
+ "Content-Length": Buffer.byteLength(data),
47
+ ...headers,
48
+ },
49
+ },
50
+ (res) => {
51
+ let body = "";
52
+ res.on("data", (chunk) => (body += chunk));
53
+ res.on("end", () => {
54
+ try {
55
+ resolve({ status: res.statusCode, data: JSON.parse(body) });
56
+ } catch {
57
+ resolve({ status: res.statusCode, data: body });
58
+ }
59
+ });
60
+ }
61
+ );
62
+ req.on("error", reject);
63
+ req.write(data);
64
+ req.end();
65
+ });
66
+ }
67
+
68
+ function httpGet(url, headers = {}) {
69
+ return new Promise((resolve, reject) => {
70
+ const parsed = new URL(url);
71
+ const req = https.request(
72
+ {
73
+ hostname: parsed.hostname,
74
+ port: 443,
75
+ path: parsed.pathname,
76
+ method: "GET",
77
+ headers,
78
+ },
79
+ (res) => {
80
+ let body = "";
81
+ res.on("data", (chunk) => (body += chunk));
82
+ res.on("end", () => {
83
+ try {
84
+ resolve({ status: res.statusCode, data: JSON.parse(body) });
85
+ } catch {
86
+ resolve({ status: res.statusCode, data: body });
87
+ }
88
+ });
89
+ }
90
+ );
91
+ req.on("error", reject);
92
+ req.end();
93
+ });
94
+ }
95
+
96
+ function addToClaudeConfig(apiKey) {
97
+ // Try Claude Code's config locations
98
+ const configPaths = [
99
+ // Project-level (preferred)
100
+ path.join(process.cwd(), ".mcp.json"),
101
+ ];
102
+
103
+ const mcpEntry = {
104
+ "eon-memory": {
105
+ type: "streamable-http",
106
+ url: MCP_URL,
107
+ headers: {
108
+ Authorization: `Bearer ${apiKey}`,
109
+ },
110
+ },
111
+ };
112
+
113
+ // Write to .mcp.json in project root (Claude Code auto-discovers this)
114
+ const mcpConfigPath = configPaths[0];
115
+ let existing = {};
116
+ if (fs.existsSync(mcpConfigPath)) {
117
+ try {
118
+ existing = JSON.parse(fs.readFileSync(mcpConfigPath, "utf-8"));
119
+ } catch {
120
+ existing = {};
121
+ }
122
+ }
123
+
124
+ if (!existing.mcpServers) existing.mcpServers = {};
125
+ existing.mcpServers["eon-memory"] = mcpEntry["eon-memory"];
126
+
127
+ fs.writeFileSync(mcpConfigPath, JSON.stringify(existing, null, 2) + "\n");
128
+ return mcpConfigPath;
129
+ }
130
+
131
+ function writeClaudeMd(content) {
132
+ const claudeMdPath = path.join(process.cwd(), "CLAUDE.md");
133
+
134
+ // Don't overwrite existing CLAUDE.md, append instead
135
+ if (fs.existsSync(claudeMdPath)) {
136
+ const existing = fs.readFileSync(claudeMdPath, "utf-8");
137
+ if (existing.includes("EON Memory")) {
138
+ console.log(" CLAUDE.md already contains EON Memory config - skipping.");
139
+ return claudeMdPath;
140
+ }
141
+ fs.appendFileSync(claudeMdPath, "\n\n" + content);
142
+ console.log(" Appended EON Memory section to existing CLAUDE.md");
143
+ } else {
144
+ fs.writeFileSync(claudeMdPath, content);
145
+ console.log(" Created CLAUDE.md with EON Memory instructions");
146
+ }
147
+ return claudeMdPath;
148
+ }
149
+
150
+ async function main() {
151
+ console.log("\n EON Memory - Setup\n");
152
+ console.log(" This will configure EON Memory for your project.\n");
153
+
154
+ // Step 1: Get API key
155
+ const apiKey = await ask(" Enter your API key (from app.ai-developer.ch/settings): ");
156
+
157
+ if (!apiKey) {
158
+ console.error("\n Error: API key is required.");
159
+ console.log(" Get one at: https://app.ai-developer.ch/settings\n");
160
+ process.exit(1);
161
+ }
162
+
163
+ // Step 2: Validate API key
164
+ console.log("\n Validating API key...");
165
+ try {
166
+ const res = await httpPost(INIT_ENDPOINT, { api_key: apiKey });
167
+
168
+ if (res.status !== 200) {
169
+ console.error(" Error: Invalid API key.");
170
+ console.log(" Check your key at: https://app.ai-developer.ch/settings\n");
171
+ process.exit(1);
172
+ }
173
+
174
+ const info = res.data;
175
+ console.log(` Connected as: ${info.name || info.tenant_id} (${info.tier} plan)`);
176
+ console.log(` Projects: ${(info.projects || []).length}`);
177
+ console.log(` Tools: ${info.tools_count}`);
178
+ } catch (err) {
179
+ console.error(` Error: Could not reach server - ${err.message}`);
180
+ process.exit(1);
181
+ }
182
+
183
+ // Step 3: Write MCP config
184
+ console.log("\n Configuring MCP...");
185
+ const configPath = addToClaudeConfig(apiKey);
186
+ console.log(` Wrote: ${path.relative(process.cwd(), configPath)}`);
187
+
188
+ // Step 4: Fetch and write CLAUDE.md
189
+ console.log("\n Generating CLAUDE.md...");
190
+ try {
191
+ const res = await httpGet(CLAUDE_MD_ENDPOINT, { "X-API-Key": apiKey });
192
+ if (res.status === 200 && res.data.content) {
193
+ const claudeMdPath = writeClaudeMd(res.data.content);
194
+ console.log(` Wrote: ${path.relative(process.cwd(), claudeMdPath)}`);
195
+ } else {
196
+ console.log(" Warning: Could not fetch CLAUDE.md template (non-critical).");
197
+ }
198
+ } catch {
199
+ console.log(" Warning: Could not fetch CLAUDE.md template (non-critical).");
200
+ }
201
+
202
+ // Done
203
+ console.log("\n Setup complete!\n");
204
+ console.log(" Next steps:");
205
+ console.log(" 1. Open this project in Claude Code or Cursor");
206
+ console.log(" 2. The EON Memory tools will be available automatically");
207
+ console.log(" 3. Try: \"Search my memories for...\" or \"Create a memory about...\"\n");
208
+ console.log(` Dashboard: ${API_BASE}`);
209
+ console.log(` Run 'npx eon-memory status' to check connection.\n`);
210
+ }
211
+
212
+ main().catch((err) => {
213
+ console.error(`\n Error: ${err.message}\n`);
214
+ process.exit(1);
215
+ });
package/src/status.js ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * eon-memory status
5
+ *
6
+ * Checks if EON Memory is configured and connected.
7
+ */
8
+
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+ const https = require("https");
12
+
13
+ function checkMcpConfig() {
14
+ const mcpPath = path.join(process.cwd(), ".mcp.json");
15
+ if (!fs.existsSync(mcpPath)) return null;
16
+
17
+ try {
18
+ const config = JSON.parse(fs.readFileSync(mcpPath, "utf-8"));
19
+ return config.mcpServers?.["eon-memory"] || null;
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+
25
+ function checkHealth() {
26
+ return new Promise((resolve) => {
27
+ const req = https.get("https://mcp.ai-developer.ch/health", (res) => {
28
+ let body = "";
29
+ res.on("data", (chunk) => (body += chunk));
30
+ res.on("end", () => {
31
+ try {
32
+ resolve({ ok: res.statusCode === 200, data: JSON.parse(body) });
33
+ } catch {
34
+ resolve({ ok: false });
35
+ }
36
+ });
37
+ });
38
+ req.on("error", () => resolve({ ok: false }));
39
+ req.setTimeout(5000, () => { req.destroy(); resolve({ ok: false }); });
40
+ });
41
+ }
42
+
43
+ async function main() {
44
+ console.log("\n EON Memory - Status\n");
45
+
46
+ // Check config
47
+ const config = checkMcpConfig();
48
+ if (config) {
49
+ console.log(" MCP Config: found (.mcp.json)");
50
+ console.log(` Server URL: ${config.url || "not set"}`);
51
+ console.log(` Auth: ${config.headers?.Authorization ? "configured" : "missing"}`);
52
+ } else {
53
+ console.log(" MCP Config: not found");
54
+ console.log(" Run 'npx eon-memory init' to set up.\n");
55
+ return;
56
+ }
57
+
58
+ // Check CLAUDE.md
59
+ const claudeMd = path.join(process.cwd(), "CLAUDE.md");
60
+ console.log(` CLAUDE.md: ${fs.existsSync(claudeMd) ? "found" : "not found"}`);
61
+
62
+ // Check server health
63
+ console.log("\n Checking server...");
64
+ const health = await checkHealth();
65
+ if (health.ok) {
66
+ console.log(` Server: online`);
67
+ console.log(` Tools: ${health.data?.tools || "?"}`);
68
+ console.log(` Version: ${health.data?.version || "?"}`);
69
+ } else {
70
+ console.log(" Server: unreachable");
71
+ }
72
+
73
+ console.log("");
74
+ }
75
+
76
+ main();
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * eon-memory test
5
+ *
6
+ * Tests the MCP connection with the configured API key.
7
+ */
8
+
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+ const https = require("https");
12
+
13
+ function getApiKey() {
14
+ // Try .mcp.json
15
+ const mcpPath = path.join(process.cwd(), ".mcp.json");
16
+ if (fs.existsSync(mcpPath)) {
17
+ try {
18
+ const config = JSON.parse(fs.readFileSync(mcpPath, "utf-8"));
19
+ const auth = config.mcpServers?.["eon-memory"]?.headers?.Authorization;
20
+ if (auth) return auth.replace("Bearer ", "");
21
+ } catch {}
22
+ }
23
+
24
+ // Try env
25
+ if (process.env.EON_API_KEY) return process.env.EON_API_KEY;
26
+
27
+ return null;
28
+ }
29
+
30
+ function httpPost(url, body, headers = {}) {
31
+ return new Promise((resolve, reject) => {
32
+ const parsed = new URL(url);
33
+ const data = JSON.stringify(body);
34
+ const req = https.request(
35
+ {
36
+ hostname: parsed.hostname,
37
+ port: 443,
38
+ path: parsed.pathname,
39
+ method: "POST",
40
+ headers: {
41
+ "Content-Type": "application/json",
42
+ "Content-Length": Buffer.byteLength(data),
43
+ ...headers,
44
+ },
45
+ },
46
+ (res) => {
47
+ let body = "";
48
+ res.on("data", (chunk) => (body += chunk));
49
+ res.on("end", () => {
50
+ try {
51
+ resolve({ status: res.statusCode, data: JSON.parse(body) });
52
+ } catch {
53
+ resolve({ status: res.statusCode, data: body });
54
+ }
55
+ });
56
+ }
57
+ );
58
+ req.on("error", reject);
59
+ req.write(data);
60
+ req.end();
61
+ });
62
+ }
63
+
64
+ async function main() {
65
+ console.log("\n EON Memory - Connection Test\n");
66
+
67
+ const apiKey = getApiKey();
68
+ if (!apiKey) {
69
+ console.log(" No API key found.");
70
+ console.log(" Run 'npx eon-memory init' first.\n");
71
+ process.exit(1);
72
+ }
73
+
74
+ console.log(" Testing connection...");
75
+ const start = Date.now();
76
+
77
+ try {
78
+ const res = await httpPost("https://app.ai-developer.ch/api/proxy/cli/test", {
79
+ api_key: apiKey,
80
+ });
81
+
82
+ const latency = Date.now() - start;
83
+
84
+ if (res.status === 200) {
85
+ const d = res.data;
86
+ console.log(` Status: ${d.status}`);
87
+ console.log(` Tenant: ${d.tenant_id}`);
88
+ console.log(` Plan: ${d.tier}`);
89
+ console.log(` Memories: ${d.memory_count}`);
90
+ console.log(` Tools: ${d.tools_available}`);
91
+ console.log(` Latency: ${latency}ms`);
92
+ console.log("\n Connection successful!\n");
93
+ } else {
94
+ console.log(` Error: ${res.data?.detail || "Authentication failed"}`);
95
+ console.log(" Check your API key in .mcp.json\n");
96
+ process.exit(1);
97
+ }
98
+ } catch (err) {
99
+ console.log(` Error: ${err.message}`);
100
+ console.log(" Could not reach server.\n");
101
+ process.exit(1);
102
+ }
103
+ }
104
+
105
+ main();