@ekkos/mcp-server 2.0.0 → 2.0.1
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 +122 -284
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +138 -0
- package/dist/index.js.map +1 -0
- package/package.json +24 -22
- package/build/index.d.ts +0 -13
- package/build/index.js +0 -181
package/README.md
CHANGED
|
@@ -1,46 +1,30 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ekkos/mcp-server
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
> Last updated: 2025-01-13 (testing all secrets)
|
|
3
|
+
Stdio-to-SSE bridge for [ekkOS](https://ekkos.dev) Memory substrate. Enables AI tools like Claude Code and Cursor to access your persistent memory via the Model Context Protocol (MCP).
|
|
6
4
|
|
|
7
5
|
## Quick Start
|
|
8
6
|
|
|
9
|
-
###
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install -g @ekkos/mcp-server
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### 2. Get Your API Key
|
|
7
|
+
### Claude Code
|
|
16
8
|
|
|
17
|
-
|
|
18
|
-
2. Sign in or create an account
|
|
19
|
-
3. Copy your API key from the dashboard
|
|
20
|
-
4. Copy your User ID from your profile
|
|
21
|
-
|
|
22
|
-
### 3. Configure Your IDE
|
|
23
|
-
|
|
24
|
-
**For Cursor:** Add to `~/.cursor/mcp.json`
|
|
25
|
-
|
|
26
|
-
**For Windsurf:** Add to `~/.codeium/windsurf/mcp_config.json`
|
|
9
|
+
Add to `~/.claude/settings.json`:
|
|
27
10
|
|
|
28
11
|
```json
|
|
29
12
|
{
|
|
30
13
|
"mcpServers": {
|
|
31
14
|
"ekkos-memory": {
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"X-User-ID": "your-user-id-here"
|
|
15
|
+
"command": "npx",
|
|
16
|
+
"args": ["-y", "@ekkos/mcp-server"],
|
|
17
|
+
"env": {
|
|
18
|
+
"EKKOS_API_KEY": "your_api_key_here"
|
|
37
19
|
}
|
|
38
20
|
}
|
|
39
21
|
}
|
|
40
22
|
}
|
|
41
23
|
```
|
|
42
24
|
|
|
43
|
-
|
|
25
|
+
### Cursor
|
|
26
|
+
|
|
27
|
+
Add to `.cursor/mcp.json` in your project:
|
|
44
28
|
|
|
45
29
|
```json
|
|
46
30
|
{
|
|
@@ -49,281 +33,135 @@ npm install -g @ekkos/mcp-server
|
|
|
49
33
|
"command": "npx",
|
|
50
34
|
"args": ["-y", "@ekkos/mcp-server"],
|
|
51
35
|
"env": {
|
|
52
|
-
"EKKOS_API_KEY": "
|
|
53
|
-
"EKKOS_USER_ID": "your-user-id-here"
|
|
36
|
+
"EKKOS_API_KEY": "your_api_key_here"
|
|
54
37
|
}
|
|
55
38
|
}
|
|
56
39
|
}
|
|
57
40
|
}
|
|
58
41
|
```
|
|
59
42
|
|
|
60
|
-
###
|
|
61
|
-
|
|
62
|
-
The MCP server will be available in all chat sessions. Your AI can now remember!
|
|
63
|
-
|
|
64
|
-
## How It Works
|
|
65
|
-
|
|
66
|
-
Your AI agent can now access a 10-layer memory system that stores:
|
|
67
|
-
|
|
68
|
-
- **Patterns** - Proven solutions that worked
|
|
69
|
-
- **Conversations** - Past discussions and problem-solving sessions
|
|
70
|
-
- **Directives** - Rules your AI must follow (MUST/NEVER/PREFER/AVOID)
|
|
71
|
-
- **Codebase** - Semantic search across your project
|
|
72
|
-
- **And more** - Episodic memory, procedural workflows, collective knowledge
|
|
73
|
-
|
|
74
|
-
When you ask a question, your AI searches this memory first, finds relevant solutions, and applies them automatically.
|
|
75
|
-
|
|
76
|
-
## Core Tools
|
|
77
|
-
|
|
78
|
-
### `search_memory` 🔍
|
|
79
|
-
|
|
80
|
-
**What it does:** Searches all your memory layers to find relevant patterns, solutions, and past conversations.
|
|
81
|
-
|
|
82
|
-
**When to use:** Your AI calls this automatically before answering technical questions. It's the primary way your AI remembers.
|
|
83
|
-
|
|
84
|
-
**Example:**
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
You: "How did we fix the auth timeout issue?"
|
|
88
|
-
|
|
89
|
-
AI: [Searches memory automatically]
|
|
90
|
-
"Found it! We used the auth-timeout-mitigation pattern
|
|
91
|
-
from last week. Here's the solution..."
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**What you get back:**
|
|
95
|
-
|
|
96
|
-
- Relevant patterns with success rates
|
|
97
|
-
- Past conversations about similar problems
|
|
98
|
-
- Code examples that worked
|
|
99
|
-
- Solutions sorted by how well they worked
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
### `forge_pattern` 🔥
|
|
104
|
-
|
|
105
|
-
**What it does:** Saves a solution that worked as a reusable pattern. Future AI agents (including yourself) will find it automatically.
|
|
106
|
-
|
|
107
|
-
**When to use:** After you solve a problem, fix a bug, or discover a better approach. Your AI should call this automatically, but you can also trigger it.
|
|
108
|
-
|
|
109
|
-
**Example:**
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
AI: [After fixing a bug]
|
|
113
|
-
"I've saved this solution as a pattern. Next time we
|
|
114
|
-
encounter this issue, I'll remember the fix instantly."
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**What happens:**
|
|
118
|
-
|
|
119
|
-
- Pattern is stored in memory
|
|
120
|
-
- Becomes searchable immediately
|
|
121
|
-
- Success rate tracked over time
|
|
122
|
-
- Automatically suggested for similar problems
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
### `forge_directive` 📜
|
|
127
|
-
|
|
128
|
-
**What it does:** Creates a rule your AI must follow. These are MUST/NEVER/PREFER/AVOID rules that guide behavior.
|
|
129
|
-
|
|
130
|
-
**When to use:** When you want to establish permanent rules for how your AI should behave.
|
|
131
|
-
|
|
132
|
-
**Example:**
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
You: "Always use TypeScript strict mode"
|
|
136
|
-
|
|
137
|
-
AI: [Creates directive]
|
|
138
|
-
"Rule saved. I'll always use strict mode going forward."
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Types of rules:**
|
|
142
|
-
|
|
143
|
-
- **MUST** - Always do this (highest priority)
|
|
144
|
-
- **NEVER** - Never do this (high priority)
|
|
145
|
-
- **PREFER** - Prefer this approach (medium priority)
|
|
146
|
-
- **AVOID** - Try to avoid this (lower priority)
|
|
147
|
-
|
|
148
|
-
**What happens:**
|
|
149
|
-
|
|
150
|
-
- Rule is enforced in all future interactions
|
|
151
|
-
- AI checks against rules before taking actions
|
|
152
|
-
- Rules can be project-specific or global
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
### `recall_conversation` 💬
|
|
157
|
-
|
|
158
|
-
**What it does:** Finds past conversations about a topic, even from days or weeks ago.
|
|
159
|
-
|
|
160
|
-
**When to use:** When you want to remember what you discussed before, or check if you've already solved a problem.
|
|
161
|
-
|
|
162
|
-
**Example:**
|
|
163
|
-
|
|
164
|
-
```
|
|
165
|
-
You: "What did we decide about the database schema?"
|
|
166
|
-
|
|
167
|
-
AI: [Searches past conversations]
|
|
168
|
-
"We discussed this 2 weeks ago. You decided to use
|
|
169
|
-
PostgreSQL with JSONB for flexible fields..."
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**What you get back:**
|
|
173
|
-
|
|
174
|
-
- Relevant excerpts from past conversations
|
|
175
|
-
- Context about decisions made
|
|
176
|
-
- Solutions you've tried before
|
|
177
|
-
- Semantic matches (finds related topics, not just keywords)
|
|
178
|
-
|
|
179
|
-
---
|
|
180
|
-
|
|
181
|
-
### `check_conflict` ⚖️
|
|
182
|
-
|
|
183
|
-
**What it does:** Validates an action against your rules and patterns before executing it. Prevents your AI from doing something that violates your preferences.
|
|
184
|
-
|
|
185
|
-
**When to use:** Before executing destructive operations, deploying changes, or modifying critical configs.
|
|
186
|
-
|
|
187
|
-
**Example:**
|
|
188
|
-
|
|
189
|
-
```
|
|
190
|
-
AI: [Before deleting files]
|
|
191
|
-
"I want to delete /tmp files. Let me check if this
|
|
192
|
-
violates any rules..."
|
|
193
|
-
|
|
194
|
-
[Checks conflicts]
|
|
195
|
-
"⚠️ CONFLICT: This violates NEVER rule: 'Never delete
|
|
196
|
-
files without user confirmation'. I'll ask first."
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
**What you get back:**
|
|
200
|
-
|
|
201
|
-
- List of violated rules (if any)
|
|
202
|
-
- Conflicting patterns
|
|
203
|
-
- Recommendations to proceed safely
|
|
204
|
-
- Clear explanation of why it conflicts
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## How to Use It Day-to-Day
|
|
209
|
-
|
|
210
|
-
### When Starting Work
|
|
211
|
-
|
|
212
|
-
Your AI automatically searches memory when you ask questions. You don't need to do anything special - just ask:
|
|
213
|
-
|
|
214
|
-
```
|
|
215
|
-
You: "Fix the authentication bug"
|
|
216
|
-
AI: [Searches memory] "Found 3 solutions from past work..."
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### When Solving Problems
|
|
220
|
-
|
|
221
|
-
After your AI solves something, it should automatically save it as a pattern:
|
|
222
|
-
|
|
223
|
-
```
|
|
224
|
-
AI: [After fixing bug]
|
|
225
|
-
"Solution saved. Future agents will find this automatically."
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
If it doesn't, you can remind it:
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
You: "Save this solution as a pattern"
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### When Setting Rules
|
|
235
|
-
|
|
236
|
-
Tell your AI what you want it to always/never do:
|
|
43
|
+
### Get Your API Key
|
|
237
44
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
45
|
+
1. Go to [platform.ekkos.dev](https://platform.ekkos.dev)
|
|
46
|
+
2. Sign up or log in
|
|
47
|
+
3. Navigate to **Settings → API Keys**
|
|
48
|
+
4. Click **"Generate New Key"**
|
|
242
49
|
|
|
243
|
-
|
|
50
|
+
## Environment Variables
|
|
244
51
|
|
|
245
|
-
|
|
52
|
+
| Variable | Required | Description |
|
|
53
|
+
|----------|----------|-------------|
|
|
54
|
+
| `EKKOS_API_KEY` | Yes | Your ekkOS API key from platform.ekkos.dev |
|
|
55
|
+
| `EKKOS_USER_ID` | No | Your user ID (optional, for better tracking) |
|
|
56
|
+
| `EKKOS_MCP_URL` | No | Custom MCP gateway URL (default: https://mcp.ekkos.dev/api/v1/mcp/sse) |
|
|
57
|
+
| `EKKOS_DEBUG` | No | Set to `true` for debug logs |
|
|
246
58
|
|
|
247
|
-
|
|
248
|
-
You: "What did we decide about the API structure?"
|
|
249
|
-
AI: [Searches conversations] "We discussed this last week..."
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## The Golden Loop
|
|
253
|
-
|
|
254
|
-
ekkOS uses a continuous learning cycle that makes your AI smarter:
|
|
255
|
-
|
|
256
|
-
1. **Retrieve** - `search_memory` finds relevant patterns
|
|
257
|
-
2. **Apply** - AI uses patterns to solve problems
|
|
258
|
-
3. **Measure** - System tracks if solutions worked
|
|
259
|
-
4. **Learn** - `forge_pattern` saves new solutions
|
|
59
|
+
## How It Works
|
|
260
60
|
|
|
261
|
-
This creates a
|
|
61
|
+
This package creates a bridge between:
|
|
62
|
+
- **Stdio transport** (used by AI tools like Claude Code)
|
|
63
|
+
- **SSE transport** (used by ekkOS cloud memory substrate)
|
|
64
|
+
|
|
65
|
+
When your AI tool starts the MCP server, this bridge:
|
|
66
|
+
1. Connects to ekkOS cloud via SSE using your API key
|
|
67
|
+
2. Exposes a stdio interface for your AI tool
|
|
68
|
+
3. Forwards all MCP messages between stdio and SSE
|
|
69
|
+
4. Handles authentication, reconnection, and error handling
|
|
70
|
+
|
|
71
|
+
## 35 MCP Tools
|
|
72
|
+
|
|
73
|
+
Your AI gets access to **35 memory tools** across 8 categories:
|
|
74
|
+
|
|
75
|
+
### Core Memory (7)
|
|
76
|
+
| Tool | Description |
|
|
77
|
+
|------|-------------|
|
|
78
|
+
| `ekkOS_Search` | Search all 11 memory layers for patterns, solutions, and context |
|
|
79
|
+
| `ekkOS_Forge` | Create a new pattern from a learned solution |
|
|
80
|
+
| `ekkOS_Directive` | Create user rules (MUST/NEVER/PREFER/AVOID) |
|
|
81
|
+
| `ekkOS_Context` | Get relevant context for a task (episodes + patterns + plan) |
|
|
82
|
+
| `ekkOS_Capture` | Capture a memory event (code change, chat, command, etc.) |
|
|
83
|
+
| `ekkOS_Codebase` | Search project codebase embeddings |
|
|
84
|
+
| `ekkOS_Recall` | Recall past conversations by time |
|
|
85
|
+
|
|
86
|
+
### Pattern Tracking (4)
|
|
87
|
+
| Tool | Description |
|
|
88
|
+
|------|-------------|
|
|
89
|
+
| `ekkOS_Track` | Track when a memory/pattern is applied |
|
|
90
|
+
| `ekkOS_Outcome` | Record success/failure of applied patterns |
|
|
91
|
+
| `ekkOS_Detect` | Auto-detect which patterns were used in a response |
|
|
92
|
+
| `ekkOS_Reflect` | Analyze a response for improvement opportunities |
|
|
93
|
+
|
|
94
|
+
### Utility (3)
|
|
95
|
+
| Tool | Description |
|
|
96
|
+
|------|-------------|
|
|
97
|
+
| `ekkOS_Stats` | Get statistics for all memory layers |
|
|
98
|
+
| `ekkOS_Summary` | Get human-readable summary of recent ekkOS activity |
|
|
99
|
+
| `ekkOS_Conflict` | Check if proposed action conflicts with directives |
|
|
100
|
+
|
|
101
|
+
### Plan Management (8)
|
|
102
|
+
| Tool | Description |
|
|
103
|
+
|------|-------------|
|
|
104
|
+
| `ekkOS_Plan` | Create a new structured plan (steps for a task) |
|
|
105
|
+
| `ekkOS_Plans` | List agent plans for the current user |
|
|
106
|
+
| `ekkOS_PlanStatus` | Update plan status (draft/in_progress/completed/archived) |
|
|
107
|
+
| `ekkOS_PlanStep` | Mark a plan step as complete or incomplete |
|
|
108
|
+
| `ekkOS_Generate` | Generate a plan using LLM based on context |
|
|
109
|
+
| `ekkOS_SaveTemplate` | Save a plan as a reusable template |
|
|
110
|
+
| `ekkOS_Templates` | List available plan templates |
|
|
111
|
+
| `ekkOS_FromTemplate` | Create a new plan from a template |
|
|
112
|
+
|
|
113
|
+
### Secrets Management (5)
|
|
114
|
+
| Tool | Description |
|
|
115
|
+
|------|-------------|
|
|
116
|
+
| `ekkOS_StoreSecret` | Securely store sensitive data (API keys, passwords, tokens) |
|
|
117
|
+
| `ekkOS_GetSecret` | Retrieve and decrypt a stored secret |
|
|
118
|
+
| `ekkOS_ListSecrets` | List all stored secrets (metadata only, no values) |
|
|
119
|
+
| `ekkOS_DeleteSecret` | Permanently delete a stored secret |
|
|
120
|
+
| `ekkOS_RotateSecret` | Update a secret with a new value |
|
|
121
|
+
|
|
122
|
+
### Schema Awareness (2)
|
|
123
|
+
| Tool | Description |
|
|
124
|
+
|------|-------------|
|
|
125
|
+
| `ekkOS_IndexSchema` | Index database/type schemas for field name awareness |
|
|
126
|
+
| `ekkOS_GetSchema` | Get indexed schema for a specific table/type |
|
|
127
|
+
|
|
128
|
+
### Portability (4)
|
|
129
|
+
| Tool | Description |
|
|
130
|
+
|------|-------------|
|
|
131
|
+
| `ekkOS_Export` | Export all memory data as portable JSON backup |
|
|
132
|
+
| `ekkOS_Import` | Import memory data from backup (auto-deduplication) |
|
|
133
|
+
| `ekkOS_Snapshot` | Create point-in-time memory snapshot |
|
|
134
|
+
| `ekkOS_Sync` | Synchronize local memory with cloud |
|
|
135
|
+
|
|
136
|
+
### Project Setup (2)
|
|
137
|
+
| Tool | Description |
|
|
138
|
+
|------|-------------|
|
|
139
|
+
| `ekkOS_ProjectInit` | Initialize ekkOS for a new project |
|
|
140
|
+
| `ekkOS_Ingest` | Bulk ingest data into memory layers |
|
|
262
141
|
|
|
263
142
|
## Troubleshooting
|
|
264
143
|
|
|
265
|
-
###
|
|
266
|
-
|
|
267
|
-
- Make sure Node.js 18+ is installed
|
|
268
|
-
- Check your API key is correct in the config file
|
|
269
|
-
- Restart your IDE after adding the config
|
|
270
|
-
- Check IDE logs for connection errors
|
|
271
|
-
|
|
272
|
-
### No Patterns Found
|
|
273
|
-
|
|
274
|
-
- You need to forge some patterns first (solve problems and save them)
|
|
275
|
-
- Check your API key has access to your memory
|
|
276
|
-
- Make sure `EKKOS_USER_ID` is set for user-scoped patterns
|
|
144
|
+
### "EKKOS_API_KEY environment variable is required"
|
|
145
|
+
You need to set your API key in the MCP config. Get one at [platform.ekkos.dev](https://platform.ekkos.dev/dashboard/settings/api-keys).
|
|
277
146
|
|
|
278
|
-
###
|
|
147
|
+
### MCP server not loading
|
|
148
|
+
1. Check Node.js version: `node --version` (must be 18+)
|
|
149
|
+
2. Verify config JSON is valid
|
|
150
|
+
3. Try running manually: `EKKOS_API_KEY=xxx npx @ekkos/mcp-server`
|
|
151
|
+
4. Enable debug mode: `EKKOS_DEBUG=true` in env
|
|
279
152
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
153
|
+
### Connection errors
|
|
154
|
+
1. Check your internet connection
|
|
155
|
+
2. Verify API key is correct and active
|
|
156
|
+
3. Check https://ekkos.dev/status for service status
|
|
283
157
|
|
|
284
|
-
##
|
|
158
|
+
## Support
|
|
285
159
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
-
|
|
289
|
-
-
|
|
290
|
-
- **Directives** - Rules your AI follows (MUST/NEVER/PREFER/AVOID)
|
|
291
|
-
- **Codebase** - Semantic search across your project files
|
|
292
|
-
- **Episodic** - Problem-solving sessions and workflows
|
|
293
|
-
- **Procedural** - Step-by-step processes that worked
|
|
294
|
-
- **Collective** - Knowledge shared across AI agents
|
|
295
|
-
- **Code** - Code embeddings for finding similar code
|
|
296
|
-
|
|
297
|
-
All of this is searchable instantly when your AI needs it.
|
|
298
|
-
|
|
299
|
-
## Example Workflow
|
|
300
|
-
|
|
301
|
-
```
|
|
302
|
-
1. You: "Fix the login bug"
|
|
303
|
-
|
|
304
|
-
2. AI: [Calls search_memory("login bug fix")]
|
|
305
|
-
"Found 2 patterns from past work. Applying the
|
|
306
|
-
highest-success solution..."
|
|
307
|
-
|
|
308
|
-
3. AI: [Fixes bug using pattern]
|
|
309
|
-
"Fixed! This solution has worked 8 times before."
|
|
310
|
-
|
|
311
|
-
4. AI: [Calls forge_pattern automatically]
|
|
312
|
-
"Saved this fix as a pattern for next time."
|
|
313
|
-
|
|
314
|
-
5. Next time: AI remembers instantly and applies the fix
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
## Related
|
|
318
|
-
|
|
319
|
-
- **Platform Dashboard**: https://platform.ekkos.dev
|
|
320
|
-
- **Documentation**: https://docs.ekkos.dev
|
|
321
|
-
- **GitHub**: https://github.com/ekkos-ai/ekkos
|
|
160
|
+
- [Documentation](https://docs.ekkos.dev)
|
|
161
|
+
- [Discord Community](https://discord.gg/w2JGepq9qZ)
|
|
162
|
+
- [Report Issues](https://github.com/ekkos-ai/ekkos/issues)
|
|
163
|
+
- [Email Support](mailto:support@ekkos.dev)
|
|
322
164
|
|
|
323
165
|
## License
|
|
324
166
|
|
|
325
|
-
MIT
|
|
326
|
-
|
|
327
|
-
---
|
|
328
|
-
|
|
329
|
-
**ekkOS™** - The memory substrate for AI agents. Making AI smarter, one pattern at a time. 🧠♾️
|
|
167
|
+
MIT License - see [LICENSE](LICENSE) for details
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @ekkos/mcp-server
|
|
4
|
+
*
|
|
5
|
+
* Simple stdio proxy to ekkOS cloud MCP gateway.
|
|
6
|
+
* This creates a local MCP server that forwards all requests to https://mcp.ekkos.dev
|
|
7
|
+
*/
|
|
8
|
+
// Sentry must be imported and initialized before other imports
|
|
9
|
+
import * as Sentry from '@sentry/node';
|
|
10
|
+
// Only initialize Sentry if DSN is provided via env var
|
|
11
|
+
if (process.env.SENTRY_DSN) {
|
|
12
|
+
Sentry.init({
|
|
13
|
+
dsn: process.env.SENTRY_DSN,
|
|
14
|
+
environment: process.env.NODE_ENV || 'production',
|
|
15
|
+
tracesSampleRate: 1.0,
|
|
16
|
+
sendDefaultPii: true,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
20
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
21
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
22
|
+
// Configuration
|
|
23
|
+
const EKKOS_API_KEY = process.env.EKKOS_API_KEY || '';
|
|
24
|
+
const EKKOS_USER_ID = process.env.EKKOS_USER_ID || '';
|
|
25
|
+
const EKKOS_MCP_URL = process.env.EKKOS_MCP_URL || 'https://mcp.ekkos.dev/api/v1/mcp';
|
|
26
|
+
const DEBUG = process.env.EKKOS_DEBUG === 'true';
|
|
27
|
+
if (!EKKOS_API_KEY) {
|
|
28
|
+
console.error('[ekkOS] ERROR: EKKOS_API_KEY environment variable is required');
|
|
29
|
+
console.error('[ekkOS] Get your API key at https://platform.ekkos.dev/dashboard/settings/api-keys');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
// Simple HTTP client for MCP gateway
|
|
33
|
+
async function callGateway(endpoint, method, params) {
|
|
34
|
+
const url = `${EKKOS_MCP_URL}/${endpoint}`;
|
|
35
|
+
const headers = {
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
'Authorization': `Bearer ${EKKOS_API_KEY}`,
|
|
38
|
+
};
|
|
39
|
+
if (EKKOS_USER_ID) {
|
|
40
|
+
headers['X-User-ID'] = EKKOS_USER_ID;
|
|
41
|
+
}
|
|
42
|
+
if (DEBUG) {
|
|
43
|
+
console.error(`[ekkOS] → ${method} ${endpoint}`);
|
|
44
|
+
}
|
|
45
|
+
const response = await fetch(url, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers,
|
|
48
|
+
body: JSON.stringify({ method, params: params || {} }),
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
52
|
+
}
|
|
53
|
+
const data = await response.json();
|
|
54
|
+
if (DEBUG) {
|
|
55
|
+
console.error(`[ekkOS] ← ${method} OK`);
|
|
56
|
+
}
|
|
57
|
+
return data;
|
|
58
|
+
}
|
|
59
|
+
// Create MCP server
|
|
60
|
+
const server = new Server({
|
|
61
|
+
name: 'ekkos-memory',
|
|
62
|
+
version: '1.0.0',
|
|
63
|
+
}, {
|
|
64
|
+
capabilities: {
|
|
65
|
+
tools: {},
|
|
66
|
+
resources: {},
|
|
67
|
+
prompts: {},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
// List tools - proxy to gateway
|
|
71
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
72
|
+
const result = await callGateway('tools/list', 'tools/list');
|
|
73
|
+
return result;
|
|
74
|
+
});
|
|
75
|
+
// Call tool - proxy to gateway
|
|
76
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
77
|
+
const result = await callGateway('tools/call', 'tools/call', {
|
|
78
|
+
name: request.params.name,
|
|
79
|
+
arguments: request.params.arguments,
|
|
80
|
+
});
|
|
81
|
+
return result;
|
|
82
|
+
});
|
|
83
|
+
// List resources - proxy to gateway
|
|
84
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
85
|
+
const result = await callGateway('resources/list', 'resources/list');
|
|
86
|
+
return result;
|
|
87
|
+
});
|
|
88
|
+
// Read resource - proxy to gateway
|
|
89
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
90
|
+
const result = await callGateway('resources/read', 'resources/read', {
|
|
91
|
+
uri: request.params.uri,
|
|
92
|
+
});
|
|
93
|
+
return result;
|
|
94
|
+
});
|
|
95
|
+
// List prompts - proxy to gateway
|
|
96
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
97
|
+
const result = await callGateway('prompts/list', 'prompts/list');
|
|
98
|
+
return result;
|
|
99
|
+
});
|
|
100
|
+
// Get prompt - proxy to gateway
|
|
101
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
102
|
+
const result = await callGateway('prompts/get', 'prompts/get', {
|
|
103
|
+
name: request.params.name,
|
|
104
|
+
arguments: request.params.arguments,
|
|
105
|
+
});
|
|
106
|
+
return result;
|
|
107
|
+
});
|
|
108
|
+
// Error handling
|
|
109
|
+
server.onerror = (error) => {
|
|
110
|
+
console.error('[ekkOS] Server error:', error);
|
|
111
|
+
Sentry.captureException(error);
|
|
112
|
+
};
|
|
113
|
+
process.on('SIGINT', async () => {
|
|
114
|
+
if (DEBUG) {
|
|
115
|
+
console.error('[ekkOS] Shutting down...');
|
|
116
|
+
}
|
|
117
|
+
await server.close();
|
|
118
|
+
process.exit(0);
|
|
119
|
+
});
|
|
120
|
+
// Start server
|
|
121
|
+
async function main() {
|
|
122
|
+
if (DEBUG) {
|
|
123
|
+
console.error('[ekkOS] Starting MCP proxy to ekkOS Memory...');
|
|
124
|
+
console.error(`[ekkOS] Gateway: ${EKKOS_MCP_URL}`);
|
|
125
|
+
console.error(`[ekkOS] User ID: ${EKKOS_USER_ID || '(not set)'}`);
|
|
126
|
+
}
|
|
127
|
+
const transport = new StdioServerTransport();
|
|
128
|
+
await server.connect(transport);
|
|
129
|
+
if (DEBUG) {
|
|
130
|
+
console.error('[ekkOS] ✓ Ready! Your AI can now access ekkOS memory.');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
main().catch((error) => {
|
|
134
|
+
console.error('[ekkOS] Fatal error:', error);
|
|
135
|
+
Sentry.captureException(error);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,40 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekkos/mcp-server",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "ekkOS Memory MCP Server -
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "ekkOS Memory MCP Server - stdio bridge to cloud memory substrate",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
6
7
|
"bin": {
|
|
7
|
-
"ekkos-mcp": "
|
|
8
|
+
"ekkos-mcp-server": "dist/index.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
|
-
"build": "tsc
|
|
11
|
-
"
|
|
12
|
-
"
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
13
14
|
},
|
|
14
|
-
"dependencies": {
|
|
15
|
-
"@modelcontextprotocol/sdk": "^0.5.0"
|
|
16
|
-
},
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@types/node": "^20.11.0",
|
|
19
|
-
"typescript": "^5.3.3"
|
|
20
|
-
},
|
|
21
|
-
"files": [
|
|
22
|
-
"build/**/*"
|
|
23
|
-
],
|
|
24
15
|
"keywords": [
|
|
25
16
|
"ekkos",
|
|
26
17
|
"mcp",
|
|
27
18
|
"memory",
|
|
28
19
|
"ai",
|
|
29
|
-
"cursor",
|
|
30
|
-
"windsurf",
|
|
31
20
|
"claude",
|
|
32
|
-
"
|
|
21
|
+
"anthropic",
|
|
22
|
+
"model-context-protocol"
|
|
33
23
|
],
|
|
24
|
+
"author": "ekkOS",
|
|
25
|
+
"license": "MIT",
|
|
34
26
|
"repository": {
|
|
35
27
|
"type": "git",
|
|
36
|
-
"url": "https://github.com/
|
|
28
|
+
"url": "https://github.com/ekkos-ai/ekkos.git",
|
|
29
|
+
"directory": "packages/ekkos-mcp-server"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
33
|
+
"@sentry/node": "^10.31.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.11.5",
|
|
37
|
+
"typescript": "^5.3.3"
|
|
37
38
|
},
|
|
38
|
-
"
|
|
39
|
-
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
}
|
|
40
42
|
}
|
package/build/index.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* ekkOS™ Memory MCP Server (API-Based)
|
|
4
|
-
*
|
|
5
|
-
* SECURE VERSION - Uses only EKKOS_API_KEY for authentication
|
|
6
|
-
* NO direct database access - all operations go through mcp.ekkos.dev API
|
|
7
|
-
*
|
|
8
|
-
* This is the portable, user-safe version that:
|
|
9
|
-
* - Only requires user's personal API key (no infrastructure secrets)
|
|
10
|
-
* - All database operations handled server-side
|
|
11
|
-
* - API keys are scoped per-user and can be revoked
|
|
12
|
-
*/
|
|
13
|
-
export {};
|
package/build/index.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* ekkOS™ Memory MCP Server (API-Based)
|
|
4
|
-
*
|
|
5
|
-
* SECURE VERSION - Uses only EKKOS_API_KEY for authentication
|
|
6
|
-
* NO direct database access - all operations go through mcp.ekkos.dev API
|
|
7
|
-
*
|
|
8
|
-
* This is the portable, user-safe version that:
|
|
9
|
-
* - Only requires user's personal API key (no infrastructure secrets)
|
|
10
|
-
* - All database operations handled server-side
|
|
11
|
-
* - API keys are scoped per-user and can be revoked
|
|
12
|
-
*/
|
|
13
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
14
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
15
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
16
|
-
import https from 'https';
|
|
17
|
-
// Configuration - ONLY requires user's API key
|
|
18
|
-
const EKKOS_API_KEY = process.env.EKKOS_API_KEY || '';
|
|
19
|
-
const EKKOS_USER_ID = process.env.EKKOS_USER_ID || '';
|
|
20
|
-
const MCP_API_URL = process.env.EKKOS_API_URL || 'https://mcp.ekkos.dev';
|
|
21
|
-
// Validate API key is present
|
|
22
|
-
if (!EKKOS_API_KEY) {
|
|
23
|
-
console.error('[MCP:ekkos-memory] ERROR: EKKOS_API_KEY environment variable is required');
|
|
24
|
-
console.error('[MCP:ekkos-memory] Get your API key from: https://platform.ekkos.dev/settings/api-keys');
|
|
25
|
-
console.error('[MCP:ekkos-memory] Or authenticate via the ekkOS Connect extension');
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
// Debug: Log configuration on startup (to stderr so it doesn't interfere with MCP protocol)
|
|
29
|
-
console.error(`[MCP:ekkos-memory] Using API-based authentication (secure mode)`);
|
|
30
|
-
console.error(`[MCP:ekkos-memory] API URL: ${MCP_API_URL}`);
|
|
31
|
-
console.error(`[MCP:ekkos-memory] API Key: ${EKKOS_API_KEY ? 'set (' + EKKOS_API_KEY.length + ' chars)' : 'NOT SET'}`);
|
|
32
|
-
console.error(`[MCP:ekkos-memory] User ID: ${EKKOS_USER_ID || 'NOT SET'}`);
|
|
33
|
-
// Helper: Make authenticated API request
|
|
34
|
-
async function apiRequest(endpoint, options = {}) {
|
|
35
|
-
const url = new URL(`${MCP_API_URL}${endpoint}`);
|
|
36
|
-
return new Promise((resolve, reject) => {
|
|
37
|
-
const reqOptions = {
|
|
38
|
-
hostname: url.hostname,
|
|
39
|
-
port: 443,
|
|
40
|
-
path: url.pathname + url.search,
|
|
41
|
-
method: options.method || 'GET',
|
|
42
|
-
headers: {
|
|
43
|
-
'Content-Type': 'application/json',
|
|
44
|
-
'Authorization': `Bearer ${EKKOS_API_KEY}`,
|
|
45
|
-
...(EKKOS_USER_ID ? { 'X-User-Id': EKKOS_USER_ID } : {}),
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
const req = https.request(reqOptions, (res) => {
|
|
49
|
-
let data = '';
|
|
50
|
-
res.on('data', (chunk) => { data += chunk; });
|
|
51
|
-
res.on('end', () => {
|
|
52
|
-
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
53
|
-
try {
|
|
54
|
-
resolve(JSON.parse(data));
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
resolve(data);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
console.error(`[MCP:api] ERROR: ${res.statusCode} ${data.substring(0, 500)}`);
|
|
62
|
-
reject(new Error(`API error: ${res.statusCode} - ${data.substring(0, 200)}`));
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
req.on('error', (error) => {
|
|
67
|
-
console.error(`[MCP:api] NETWORK ERROR: ${error.message}`);
|
|
68
|
-
reject(new Error(`Network error: ${error.message}`));
|
|
69
|
-
});
|
|
70
|
-
if (options.body) {
|
|
71
|
-
req.write(JSON.stringify(options.body));
|
|
72
|
-
}
|
|
73
|
-
req.end();
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
// Fetch available tools from API
|
|
77
|
-
async function fetchTools() {
|
|
78
|
-
try {
|
|
79
|
-
const response = await apiRequest('/api/v1/mcp/tools');
|
|
80
|
-
return response.tools || [];
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
console.error('[MCP:ekkos-memory] Failed to fetch tools:', error);
|
|
84
|
-
// Return minimal fallback tools
|
|
85
|
-
return [
|
|
86
|
-
{
|
|
87
|
-
name: 'search_memory',
|
|
88
|
-
description: 'Search ekkOS memory (API connection failed - limited functionality)',
|
|
89
|
-
inputSchema: {
|
|
90
|
-
type: 'object',
|
|
91
|
-
properties: {
|
|
92
|
-
query: { type: 'string', description: 'Search query' },
|
|
93
|
-
},
|
|
94
|
-
required: ['query'],
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// Call a tool via API
|
|
101
|
-
async function callTool(name, args) {
|
|
102
|
-
try {
|
|
103
|
-
const response = await apiRequest('/api/v1/mcp/call', {
|
|
104
|
-
method: 'POST',
|
|
105
|
-
body: {
|
|
106
|
-
tool: name,
|
|
107
|
-
arguments: args,
|
|
108
|
-
user_id: EKKOS_USER_ID,
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
return response;
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
console.error(`[MCP:ekkos-memory] Tool call failed: ${name}`, error);
|
|
115
|
-
throw error;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// Create MCP server
|
|
119
|
-
const server = new Server({
|
|
120
|
-
name: 'ekkos-memory',
|
|
121
|
-
version: '2.0.0',
|
|
122
|
-
}, {
|
|
123
|
-
capabilities: {
|
|
124
|
-
tools: {},
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
// Cache tools to avoid repeated API calls
|
|
128
|
-
let toolsCache = null;
|
|
129
|
-
let toolsCacheTime = 0;
|
|
130
|
-
const TOOLS_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
131
|
-
// Handle tool listing
|
|
132
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
133
|
-
// Use cached tools if fresh
|
|
134
|
-
if (toolsCache && Date.now() - toolsCacheTime < TOOLS_CACHE_TTL) {
|
|
135
|
-
return { tools: toolsCache };
|
|
136
|
-
}
|
|
137
|
-
// Fetch tools from API
|
|
138
|
-
const tools = await fetchTools();
|
|
139
|
-
toolsCache = tools;
|
|
140
|
-
toolsCacheTime = Date.now();
|
|
141
|
-
return { tools };
|
|
142
|
-
});
|
|
143
|
-
// Handle tool calls
|
|
144
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
145
|
-
const { name, arguments: args } = request.params;
|
|
146
|
-
console.error(`[MCP:ekkos-memory] Tool call: ${name}`);
|
|
147
|
-
try {
|
|
148
|
-
const result = await callTool(name, args);
|
|
149
|
-
// Format response for MCP
|
|
150
|
-
return {
|
|
151
|
-
content: [
|
|
152
|
-
{
|
|
153
|
-
type: 'text',
|
|
154
|
-
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
|
|
155
|
-
},
|
|
156
|
-
],
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
return {
|
|
161
|
-
content: [
|
|
162
|
-
{
|
|
163
|
-
type: 'text',
|
|
164
|
-
text: `Error: ${error.message}`,
|
|
165
|
-
},
|
|
166
|
-
],
|
|
167
|
-
isError: true,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
// Start server
|
|
172
|
-
async function main() {
|
|
173
|
-
console.error('[MCP:ekkos-memory] Starting ekkOS Memory MCP Server (API mode)...');
|
|
174
|
-
const transport = new StdioServerTransport();
|
|
175
|
-
await server.connect(transport);
|
|
176
|
-
console.error('[MCP:ekkos-memory] Server connected and ready');
|
|
177
|
-
}
|
|
178
|
-
main().catch((error) => {
|
|
179
|
-
console.error('[MCP:ekkos-memory] Fatal error:', error);
|
|
180
|
-
process.exit(1);
|
|
181
|
-
});
|