@ekkos/mcp-server 1.2.2 → 1.2.3
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/CHANGELOG.md +2 -0
- package/PUBLISH.md +2 -0
- package/README.md +16 -1
- package/build/index.js +27 -9
- package/index.ts +29 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/PUBLISH.md
CHANGED
package/README.md
CHANGED
|
@@ -23,7 +23,22 @@ npm install -g @ekkos/mcp-server
|
|
|
23
23
|
|
|
24
24
|
**For Windsurf:** Add to `~/.codeium/windsurf/mcp_config.json`
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"ekkos-memory": {
|
|
30
|
+
"url": "https://mcp.ekkos.dev/api/v1/mcp/sse?api_key=your-api-key-here",
|
|
31
|
+
"transport": "sse",
|
|
32
|
+
"headers": {
|
|
33
|
+
"Authorization": "Bearer your-api-key-here",
|
|
34
|
+
"X-User-ID": "your-user-id-here"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**For Claude Code:** Add to `~/.claude/settings.json`
|
|
27
42
|
|
|
28
43
|
```json
|
|
29
44
|
{
|
package/build/index.js
CHANGED
|
@@ -14,14 +14,24 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
16
16
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
17
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
17
|
+
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
18
18
|
import { createClient } from '@supabase/supabase-js';
|
|
19
19
|
import http from 'http';
|
|
20
20
|
import https from 'https';
|
|
21
21
|
// Server configuration - USE DIRECT SUPABASE CONNECTION
|
|
22
22
|
// Bypass broken production API, query database directly
|
|
23
|
-
|
|
24
|
-
const
|
|
23
|
+
// SECURITY: Never hardcode credentials - require environment variables
|
|
24
|
+
const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
|
|
25
|
+
const SUPABASE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.MEMORY_API_TOKEN;
|
|
26
|
+
// Fail fast if credentials are missing (prevents accidental exposure)
|
|
27
|
+
if (!SUPABASE_URL) {
|
|
28
|
+
console.error('[MCP:ekkos-memory] ERROR: SUPABASE_URL or NEXT_PUBLIC_SUPABASE_URL environment variable is required');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
if (!SUPABASE_KEY) {
|
|
32
|
+
console.error('[MCP:ekkos-memory] ERROR: SUPABASE_SERVICE_ROLE_KEY or MEMORY_API_TOKEN environment variable is required');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
25
35
|
// Create Supabase client for direct database access
|
|
26
36
|
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
|
|
27
37
|
// Keep legacy Memory API config for non-pattern queries
|
|
@@ -976,10 +986,11 @@ This is essential for:
|
|
|
976
986
|
// Server implementation
|
|
977
987
|
const server = new Server({
|
|
978
988
|
name: 'ekkos-memory',
|
|
979
|
-
version: '1.
|
|
989
|
+
version: '1.2.3',
|
|
980
990
|
}, {
|
|
981
991
|
capabilities: {
|
|
982
992
|
tools: {},
|
|
993
|
+
resources: {}, // Support resources listing (even if empty)
|
|
983
994
|
},
|
|
984
995
|
});
|
|
985
996
|
// List available tools
|
|
@@ -988,6 +999,12 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
988
999
|
tools: TOOLS,
|
|
989
1000
|
};
|
|
990
1001
|
});
|
|
1002
|
+
// List available resources (ekkOS uses tools, not resources, but we support the request)
|
|
1003
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
1004
|
+
return {
|
|
1005
|
+
resources: [], // ekkOS uses tools for all operations, not resources
|
|
1006
|
+
};
|
|
1007
|
+
});
|
|
991
1008
|
// User-friendly tool names for display
|
|
992
1009
|
const toolDisplayNames = {
|
|
993
1010
|
'search_memory': '🔍 Search Memory',
|
|
@@ -1655,14 +1672,15 @@ The ingestion worker will pick this up within 1-5 minutes.`,
|
|
|
1655
1672
|
const contentHash = createHash('sha256').update(content).digest('hex');
|
|
1656
1673
|
try {
|
|
1657
1674
|
// Insert directly into patterns table via Supabase
|
|
1658
|
-
|
|
1659
|
-
const
|
|
1660
|
-
const
|
|
1675
|
+
// Use the same SUPABASE_URL and SUPABASE_KEY from top-level config
|
|
1676
|
+
const localSupabaseUrl = SUPABASE_URL;
|
|
1677
|
+
const localSupabaseKey = SUPABASE_KEY;
|
|
1678
|
+
const insertResponse = await fetch(`${localSupabaseUrl}/rest/v1/patterns`, {
|
|
1661
1679
|
method: 'POST',
|
|
1662
1680
|
headers: {
|
|
1663
1681
|
'Content-Type': 'application/json',
|
|
1664
|
-
'apikey':
|
|
1665
|
-
'Authorization': `Bearer ${
|
|
1682
|
+
'apikey': localSupabaseKey,
|
|
1683
|
+
'Authorization': `Bearer ${localSupabaseKey}`,
|
|
1666
1684
|
'Prefer': 'return=representation',
|
|
1667
1685
|
},
|
|
1668
1686
|
body: JSON.stringify({
|
package/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
17
17
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
18
18
|
import {
|
|
19
19
|
CallToolRequestSchema,
|
|
20
|
+
ListResourcesRequestSchema,
|
|
20
21
|
ListToolsRequestSchema,
|
|
21
22
|
Tool,
|
|
22
23
|
} from '@modelcontextprotocol/sdk/types.js';
|
|
@@ -26,8 +27,19 @@ import https from 'https';
|
|
|
26
27
|
|
|
27
28
|
// Server configuration - USE DIRECT SUPABASE CONNECTION
|
|
28
29
|
// Bypass broken production API, query database directly
|
|
29
|
-
|
|
30
|
-
const
|
|
30
|
+
// SECURITY: Never hardcode credentials - require environment variables
|
|
31
|
+
const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
|
|
32
|
+
const SUPABASE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.MEMORY_API_TOKEN;
|
|
33
|
+
|
|
34
|
+
// Fail fast if credentials are missing (prevents accidental exposure)
|
|
35
|
+
if (!SUPABASE_URL) {
|
|
36
|
+
console.error('[MCP:ekkos-memory] ERROR: SUPABASE_URL or NEXT_PUBLIC_SUPABASE_URL environment variable is required');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
if (!SUPABASE_KEY) {
|
|
40
|
+
console.error('[MCP:ekkos-memory] ERROR: SUPABASE_SERVICE_ROLE_KEY or MEMORY_API_TOKEN environment variable is required');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
31
43
|
|
|
32
44
|
// Create Supabase client for direct database access
|
|
33
45
|
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
|
|
@@ -1023,11 +1035,12 @@ This is essential for:
|
|
|
1023
1035
|
const server = new Server(
|
|
1024
1036
|
{
|
|
1025
1037
|
name: 'ekkos-memory',
|
|
1026
|
-
version: '1.
|
|
1038
|
+
version: '1.2.3',
|
|
1027
1039
|
},
|
|
1028
1040
|
{
|
|
1029
1041
|
capabilities: {
|
|
1030
1042
|
tools: {},
|
|
1043
|
+
resources: {}, // Support resources listing (even if empty)
|
|
1031
1044
|
},
|
|
1032
1045
|
}
|
|
1033
1046
|
);
|
|
@@ -1039,6 +1052,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
1039
1052
|
};
|
|
1040
1053
|
});
|
|
1041
1054
|
|
|
1055
|
+
// List available resources (ekkOS uses tools, not resources, but we support the request)
|
|
1056
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
1057
|
+
return {
|
|
1058
|
+
resources: [], // ekkOS uses tools for all operations, not resources
|
|
1059
|
+
};
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1042
1062
|
// User-friendly tool names for display
|
|
1043
1063
|
const toolDisplayNames: Record<string, string> = {
|
|
1044
1064
|
'search_memory': '🔍 Search Memory',
|
|
@@ -1772,15 +1792,16 @@ The ingestion worker will pick this up within 1-5 minutes.`,
|
|
|
1772
1792
|
|
|
1773
1793
|
try {
|
|
1774
1794
|
// Insert directly into patterns table via Supabase
|
|
1775
|
-
|
|
1776
|
-
const
|
|
1795
|
+
// Use the same SUPABASE_URL and SUPABASE_KEY from top-level config
|
|
1796
|
+
const localSupabaseUrl = SUPABASE_URL;
|
|
1797
|
+
const localSupabaseKey = SUPABASE_KEY;
|
|
1777
1798
|
|
|
1778
|
-
const insertResponse = await fetch(`${
|
|
1799
|
+
const insertResponse = await fetch(`${localSupabaseUrl}/rest/v1/patterns`, {
|
|
1779
1800
|
method: 'POST',
|
|
1780
1801
|
headers: {
|
|
1781
1802
|
'Content-Type': 'application/json',
|
|
1782
|
-
'apikey':
|
|
1783
|
-
'Authorization': `Bearer ${
|
|
1803
|
+
'apikey': localSupabaseKey as string,
|
|
1804
|
+
'Authorization': `Bearer ${localSupabaseKey}`,
|
|
1784
1805
|
'Prefer': 'return=representation',
|
|
1785
1806
|
},
|
|
1786
1807
|
body: JSON.stringify({
|
package/package.json
CHANGED