@syke1/mcp-server 1.3.6 → 1.3.8
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 +90 -62
- package/dist/index.js +8 -1
- package/dist/web/server.d.ts +8 -2
- package/dist/web/server.js +18 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,30 +10,39 @@ Works with **Claude Code**, **Cursor**, **Windsurf**, and any MCP-compatible AI
|
|
|
10
10
|
|
|
11
11
|

|
|
12
12
|
|
|
13
|
+
## How It Works
|
|
14
|
+
|
|
15
|
+
1. **On startup**, SYKE scans your source directory and builds a complete dependency graph using static import analysis.
|
|
16
|
+
2. **Your AI agent modifies files freely** — no interruptions during normal work.
|
|
17
|
+
3. **Before build/deploy**, the AI calls `gate_build` to check if all changes are safe.
|
|
18
|
+
4. **If dependencies break**, SYKE detects cascading failures and blocks the build with a `FAIL` verdict.
|
|
19
|
+
5. **The dashboard** shows a real-time visualization of your dependency graph with risk indicators.
|
|
20
|
+
|
|
21
|
+
> **SYKE is a safety net, not a gatekeeper.** It doesn't block your AI while working — it catches what your AI missed before you ship.
|
|
22
|
+
|
|
13
23
|
## Quick Start
|
|
14
24
|
|
|
15
|
-
### 1.
|
|
25
|
+
### 1. Create config file
|
|
16
26
|
|
|
17
|
-
|
|
27
|
+
Create `~/.syke/config.json`:
|
|
18
28
|
|
|
19
29
|
```json
|
|
20
30
|
{
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
"command": "npx",
|
|
24
|
-
"args": ["@syke1/mcp-server@latest"],
|
|
25
|
-
"env": {
|
|
26
|
-
"SYKE_LICENSE_KEY": "your-key-here",
|
|
27
|
-
"SYKE_WEB_PORT": "3333",
|
|
28
|
-
"GEMINI_KEY": "your-gemini-key",
|
|
29
|
-
"OPENAI_KEY": "your-openai-key",
|
|
30
|
-
"ANTHROPIC_KEY": "your-anthropic-key"
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
31
|
+
"licenseKey": "SYKE-XXXX-XXXX-XXXX-XXXX",
|
|
32
|
+
"geminiKey": "your-gemini-api-key"
|
|
34
33
|
}
|
|
35
34
|
```
|
|
36
35
|
|
|
36
|
+
> Get your license key at [syke.cloud/dashboard](https://syke.cloud/dashboard/). You only need ONE AI key. Supported: `geminiKey`, `openaiKey`, `anthropicKey`.
|
|
37
|
+
|
|
38
|
+
### 2. Register MCP server
|
|
39
|
+
|
|
40
|
+
**Claude Code:**
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
claude mcp add syke -- npx @syke1/mcp-server@latest
|
|
44
|
+
```
|
|
45
|
+
|
|
37
46
|
**Cursor** (`.cursor/mcp.json`):
|
|
38
47
|
|
|
39
48
|
```json
|
|
@@ -41,12 +50,7 @@ Works with **Claude Code**, **Cursor**, **Windsurf**, and any MCP-compatible AI
|
|
|
41
50
|
"mcpServers": {
|
|
42
51
|
"syke": {
|
|
43
52
|
"command": "npx",
|
|
44
|
-
"args": ["@syke1/mcp-server@latest"]
|
|
45
|
-
"env": {
|
|
46
|
-
"SYKE_LICENSE_KEY": "your-key-here",
|
|
47
|
-
"SYKE_WEB_PORT": "3333",
|
|
48
|
-
"GEMINI_KEY": "your-gemini-key"
|
|
49
|
-
}
|
|
53
|
+
"args": ["@syke1/mcp-server@latest"]
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
}
|
|
@@ -59,28 +63,27 @@ Works with **Claude Code**, **Cursor**, **Windsurf**, and any MCP-compatible AI
|
|
|
59
63
|
"mcpServers": {
|
|
60
64
|
"syke": {
|
|
61
65
|
"command": "npx",
|
|
62
|
-
"args": ["@syke1/mcp-server@latest"]
|
|
63
|
-
"env": {
|
|
64
|
-
"SYKE_LICENSE_KEY": "your-key-here",
|
|
65
|
-
"SYKE_WEB_PORT": "3333",
|
|
66
|
-
"GEMINI_KEY": "your-gemini-key"
|
|
67
|
-
}
|
|
66
|
+
"args": ["@syke1/mcp-server@latest"]
|
|
68
67
|
}
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
```
|
|
72
71
|
|
|
73
|
-
> **Note:** You only need ONE AI key. SYKE auto-selects: Gemini > OpenAI > Anthropic. Set `SYKE_AI_PROVIDER` to force a specific one.
|
|
74
|
-
|
|
75
72
|
> **Windows note:** If `npx` is not found, use the full path: `"command": "C:\\Program Files\\nodejs\\npx.cmd"`
|
|
76
73
|
|
|
77
|
-
###
|
|
74
|
+
### 3. Add build gate to your project
|
|
78
75
|
|
|
79
|
-
|
|
76
|
+
Add this line to your project's `CLAUDE.md` (or equivalent AI instruction file):
|
|
80
77
|
|
|
81
|
-
|
|
78
|
+
```
|
|
79
|
+
After completing code changes, always run the gate_build MCP tool before committing or deploying.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This ensures your AI agent automatically runs SYKE's safety check after every task — no manual prompting needed.
|
|
82
83
|
|
|
83
|
-
|
|
84
|
+
### 4. Restart your AI agent
|
|
85
|
+
|
|
86
|
+
SYKE auto-detects your project language and builds the dependency graph on startup. Open `http://localhost:3333` to see your live dashboard.
|
|
84
87
|
|
|
85
88
|
## Features
|
|
86
89
|
|
|
@@ -101,14 +104,14 @@ A web dashboard opens automatically at `http://localhost:3333` (configurable via
|
|
|
101
104
|
|
|
102
105
|
SYKE supports three AI providers for semantic analysis. Bring your own key:
|
|
103
106
|
|
|
104
|
-
| Provider | Model | Env Variable |
|
|
105
|
-
|
|
106
|
-
| Google Gemini | `gemini-2.5-flash` | `GEMINI_KEY` |
|
|
107
|
-
| OpenAI | `gpt-4o-mini` | `OPENAI_KEY` |
|
|
108
|
-
| Anthropic | `claude-sonnet-4-20250514` | `ANTHROPIC_KEY` |
|
|
107
|
+
| Provider | Model | Config Key | Env Variable |
|
|
108
|
+
|----------|-------|-----------|-------------|
|
|
109
|
+
| Google Gemini | `gemini-2.5-flash` | `geminiKey` | `GEMINI_KEY` |
|
|
110
|
+
| OpenAI | `gpt-4o-mini` | `openaiKey` | `OPENAI_KEY` |
|
|
111
|
+
| Anthropic | `claude-sonnet-4-20250514` | `anthropicKey` | `ANTHROPIC_KEY` |
|
|
109
112
|
|
|
110
113
|
**Auto-selection:** SYKE uses the first available key (Gemini > OpenAI > Anthropic).
|
|
111
|
-
**Force provider:** Set `
|
|
114
|
+
**Force provider:** Set `aiProvider` in config (or `SYKE_AI_PROVIDER` env var) to override.
|
|
112
115
|
|
|
113
116
|
### Language Support
|
|
114
117
|
|
|
@@ -116,10 +119,55 @@ Auto-detected, zero-config: **Dart/Flutter**, **TypeScript/JavaScript**, **Pytho
|
|
|
116
119
|
|
|
117
120
|
### Web Dashboard
|
|
118
121
|
|
|
119
|
-
Live dependency graph visualization at `localhost:3333`
|
|
120
|
-
- Interactive node graph (click any file to see its connections)
|
|
122
|
+
Live dependency graph visualization at `localhost:3333` with:
|
|
123
|
+
- Interactive 3D node graph (click any file to see its connections)
|
|
121
124
|
- Real-time cascade monitoring
|
|
122
125
|
- Risk level indicators
|
|
126
|
+
- Server offline detection with auto-reconnect
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
SYKE reads from `~/.syke/config.json` (primary) with environment variable overrides:
|
|
131
|
+
|
|
132
|
+
| Config Key | Env Variable | Description | Required |
|
|
133
|
+
|-----------|-------------|-------------|----------|
|
|
134
|
+
| `licenseKey` | `SYKE_LICENSE_KEY` | Pro license key from dashboard | No (Free tier works without) |
|
|
135
|
+
| `geminiKey` | `GEMINI_KEY` | Google Gemini API key for `ai_analyze` | No (any one AI key) |
|
|
136
|
+
| `openaiKey` | `OPENAI_KEY` | OpenAI API key for `ai_analyze` | No (any one AI key) |
|
|
137
|
+
| `anthropicKey` | `ANTHROPIC_KEY` | Anthropic API key for `ai_analyze` | No (any one AI key) |
|
|
138
|
+
| `aiProvider` | `SYKE_AI_PROVIDER` | Force AI provider: `gemini`, `openai`, or `anthropic` | No (auto-selects) |
|
|
139
|
+
| `port` | `SYKE_WEB_PORT` | Dashboard port (default: 3333) | No |
|
|
140
|
+
|
|
141
|
+
**Full config example** (`~/.syke/config.json`):
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"licenseKey": "SYKE-XXXX-XXXX-XXXX-XXXX",
|
|
146
|
+
"geminiKey": "AIza...",
|
|
147
|
+
"openaiKey": "",
|
|
148
|
+
"anthropicKey": "",
|
|
149
|
+
"port": 3333
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Recommended Workflow
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
You (developer) AI Agent SYKE
|
|
157
|
+
| | |
|
|
158
|
+
|-- "Add feature X" -->| |
|
|
159
|
+
| |-- modifies files |
|
|
160
|
+
| |-- modifies files |
|
|
161
|
+
| |-- modifies files |
|
|
162
|
+
| | |
|
|
163
|
+
| |-- gate_build --->|
|
|
164
|
+
| | |-- scans graph
|
|
165
|
+
| | |-- checks impact
|
|
166
|
+
| |<-- PASS/FAIL ----|
|
|
167
|
+
| | |
|
|
168
|
+
|<-- "Done. Safe to | |
|
|
169
|
+
| build." ----------| |
|
|
170
|
+
```
|
|
123
171
|
|
|
124
172
|
## Pricing
|
|
125
173
|
|
|
@@ -136,27 +184,7 @@ Live dependency graph visualization at `localhost:3333` (or your custom `SYKE_WE
|
|
|
136
184
|
- AI semantic analysis (BYOK — Gemini, OpenAI, or Claude)
|
|
137
185
|
- Priority support
|
|
138
186
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
## Configuration
|
|
142
|
-
|
|
143
|
-
| Environment Variable | Description | Required |
|
|
144
|
-
|---------------------|-------------|----------|
|
|
145
|
-
| `SYKE_LICENSE_KEY` | Pro license key from dashboard | No (Free tier works without) |
|
|
146
|
-
| `GEMINI_KEY` | Google Gemini API key for `ai_analyze` | No (any one AI key) |
|
|
147
|
-
| `OPENAI_KEY` | OpenAI API key for `ai_analyze` | No (any one AI key) |
|
|
148
|
-
| `ANTHROPIC_KEY` | Anthropic API key for `ai_analyze` | No (any one AI key) |
|
|
149
|
-
| `SYKE_AI_PROVIDER` | Force AI provider: `gemini`, `openai`, or `anthropic` | No (auto-selects) |
|
|
150
|
-
| `SYKE_WEB_PORT` | Dashboard port (default: 3333) | No |
|
|
151
|
-
| `SYKE_NO_BROWSER` | Set to `1` to disable auto-open browser | No |
|
|
152
|
-
| `SYKE_currentProjectRoot` | Override auto-detected project root | No |
|
|
153
|
-
|
|
154
|
-
## How It Works
|
|
155
|
-
|
|
156
|
-
1. **On startup**, SYKE scans your source directory and builds a complete dependency graph using static import analysis.
|
|
157
|
-
2. **When your AI modifies a file**, call `gate_build` to check if the change is safe before building.
|
|
158
|
-
3. **If dependencies break**, SYKE detects cascading failures and blocks the build with a `FAIL` verdict.
|
|
159
|
-
4. **The dashboard** shows a real-time visualization of your dependency graph with risk indicators.
|
|
187
|
+
Sign up at [syke.cloud](https://syke.cloud) — 3-day free trial included.
|
|
160
188
|
|
|
161
189
|
## License
|
|
162
190
|
|
package/dist/index.js
CHANGED
|
@@ -522,6 +522,8 @@ async function main() {
|
|
|
522
522
|
fileCache.initialize();
|
|
523
523
|
fileCache.startWatching();
|
|
524
524
|
}
|
|
525
|
+
// Web server handle (set after server starts)
|
|
526
|
+
let webServerHandle = null;
|
|
525
527
|
// Switch project callback — reinitializes graph + file cache
|
|
526
528
|
function switchProject(newRoot) {
|
|
527
529
|
currentProjectRoot = newRoot;
|
|
@@ -533,6 +535,10 @@ async function main() {
|
|
|
533
535
|
fileCache = new file_cache_1.FileCache(newRoot);
|
|
534
536
|
fileCache.initialize();
|
|
535
537
|
fileCache.startWatching();
|
|
538
|
+
// Re-wire SSE events to the new FileCache
|
|
539
|
+
if (webServerHandle) {
|
|
540
|
+
webServerHandle.setFileCache(fileCache);
|
|
541
|
+
}
|
|
536
542
|
// Rebuild graph
|
|
537
543
|
const graph = (0, graph_1.refreshGraph)(newRoot, currentPackageName);
|
|
538
544
|
console.error(`[syke] Switched to project: ${newRoot}`);
|
|
@@ -552,7 +558,8 @@ async function main() {
|
|
|
552
558
|
}
|
|
553
559
|
// Start Express web server with file cache for SSE (only if project detected)
|
|
554
560
|
if (currentProjectRoot) {
|
|
555
|
-
const webApp = (0, server_1.createWebServer)(() => (0, graph_1.getGraph)(currentProjectRoot, currentPackageName), fileCache, switchProject, () => currentProjectRoot, () => currentPackageName, () => licenseStatus, () => !!(0, provider_1.getAIProvider)());
|
|
561
|
+
const { app: webApp, setFileCache: setWebFileCache } = (0, server_1.createWebServer)(() => (0, graph_1.getGraph)(currentProjectRoot, currentPackageName), fileCache, switchProject, () => currentProjectRoot, () => currentPackageName, () => licenseStatus, () => !!(0, provider_1.getAIProvider)());
|
|
562
|
+
webServerHandle = { setFileCache: setWebFileCache };
|
|
556
563
|
webApp.listen(WEB_PORT, () => {
|
|
557
564
|
const dashUrl = `http://localhost:${WEB_PORT}`;
|
|
558
565
|
console.error(`[syke] Web dashboard: ${dashUrl}`);
|
package/dist/web/server.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import express from "express";
|
|
1
2
|
import { DependencyGraph } from "../graph";
|
|
2
3
|
import { FileCache } from "../watcher/file-cache";
|
|
3
4
|
import { RealtimeAnalysis } from "../ai/realtime-analyzer";
|
|
@@ -24,9 +25,14 @@ export interface SwitchProjectResult {
|
|
|
24
25
|
fileCount: number;
|
|
25
26
|
edgeCount: number;
|
|
26
27
|
}
|
|
27
|
-
export
|
|
28
|
+
export interface WebServerHandle {
|
|
29
|
+
app: ReturnType<typeof express>;
|
|
30
|
+
/** Re-wire SSE events when FileCache is replaced (e.g. after switchProject) */
|
|
31
|
+
setFileCache(cache: FileCache): void;
|
|
32
|
+
}
|
|
33
|
+
export declare function createWebServer(getGraphFn: () => DependencyGraph, initialFileCache?: FileCache, switchProjectFn?: (newRoot: string) => SwitchProjectResult, getProjectRoot?: () => string, getPackageName?: () => string, getLicenseStatus?: () => {
|
|
28
34
|
plan: string;
|
|
29
35
|
expiresAt?: string;
|
|
30
36
|
error?: string;
|
|
31
37
|
source?: string;
|
|
32
|
-
}, hasAIKeyFn?: () => boolean):
|
|
38
|
+
}, hasAIKeyFn?: () => boolean): WebServerHandle;
|
package/dist/web/server.js
CHANGED
|
@@ -226,7 +226,7 @@ function acknowledgeWarnings() {
|
|
|
226
226
|
function getAllWarnings() {
|
|
227
227
|
return [...warningStore];
|
|
228
228
|
}
|
|
229
|
-
function createWebServer(getGraphFn,
|
|
229
|
+
function createWebServer(getGraphFn, initialFileCache, switchProjectFn, getProjectRoot, getPackageName, getLicenseStatus, hasAIKeyFn) {
|
|
230
230
|
const app = (0, express_1.default)();
|
|
231
231
|
app.use(express_1.default.json());
|
|
232
232
|
// Serve static files from public/
|
|
@@ -234,6 +234,7 @@ function createWebServer(getGraphFn, fileCache, switchProjectFn, getProjectRoot,
|
|
|
234
234
|
app.use(express_1.default.static(publicDir));
|
|
235
235
|
// ── SSE: Server-Sent Events for real-time updates ──
|
|
236
236
|
const sseClients = new Set();
|
|
237
|
+
let currentFileCache = initialFileCache || null;
|
|
237
238
|
function broadcastSSE(event, data) {
|
|
238
239
|
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
239
240
|
for (const client of sseClients) {
|
|
@@ -274,7 +275,7 @@ function createWebServer(getGraphFn, fileCache, switchProjectFn, getProjectRoot,
|
|
|
274
275
|
"Access-Control-Allow-Origin": "*",
|
|
275
276
|
});
|
|
276
277
|
// Send initial connection event
|
|
277
|
-
res.write(`event: connected\ndata: ${JSON.stringify({ clients: sseClients.size + 1, cacheSize:
|
|
278
|
+
res.write(`event: connected\ndata: ${JSON.stringify({ clients: sseClients.size + 1, cacheSize: currentFileCache?.size || 0 })}\n\n`);
|
|
278
279
|
sseClients.add(res);
|
|
279
280
|
console.error(`[syke:sse] Client connected (${sseClients.size} total)`);
|
|
280
281
|
_req.on("close", () => {
|
|
@@ -283,8 +284,8 @@ function createWebServer(getGraphFn, fileCache, switchProjectFn, getProjectRoot,
|
|
|
283
284
|
});
|
|
284
285
|
});
|
|
285
286
|
// Wire FileCache change events → SSE broadcast + AI analysis
|
|
286
|
-
|
|
287
|
-
|
|
287
|
+
function wireFileCacheEvents(cache) {
|
|
288
|
+
cache.on("change", async (change) => {
|
|
288
289
|
const graph = getGraphFn();
|
|
289
290
|
const absPath = path.normalize(path.join(graph.sourceDir, change.relativePath));
|
|
290
291
|
// Compute affected nodes for visual pulse
|
|
@@ -317,7 +318,7 @@ function createWebServer(getGraphFn, fileCache, switchProjectFn, getProjectRoot,
|
|
|
317
318
|
if (license && license.plan === "pro") {
|
|
318
319
|
broadcastSSE("analysis-start", { file: change.relativePath });
|
|
319
320
|
try {
|
|
320
|
-
const analysis = await (0, realtime_analyzer_1.analyzeChangeRealtime)(change, graph, (relPath) =>
|
|
321
|
+
const analysis = await (0, realtime_analyzer_1.analyzeChangeRealtime)(change, graph, (relPath) => currentFileCache?.getFileByRelPath(relPath) ?? null);
|
|
321
322
|
broadcastSSE("analysis-result", analysis);
|
|
322
323
|
// Store warnings for MCP check_warnings tool
|
|
323
324
|
addWarning(analysis);
|
|
@@ -341,15 +342,23 @@ function createWebServer(getGraphFn, fileCache, switchProjectFn, getProjectRoot,
|
|
|
341
342
|
}
|
|
342
343
|
});
|
|
343
344
|
}
|
|
345
|
+
if (currentFileCache)
|
|
346
|
+
wireFileCacheEvents(currentFileCache);
|
|
347
|
+
/** Replace the FileCache (called after switchProject) */
|
|
348
|
+
function setFileCache(cache) {
|
|
349
|
+
currentFileCache = cache;
|
|
350
|
+
wireFileCacheEvents(cache);
|
|
351
|
+
console.error(`[syke:sse] FileCache re-wired (${cache.size} files)`);
|
|
352
|
+
}
|
|
344
353
|
// GET /api/cache-status — Memory cache stats
|
|
345
354
|
app.get("/api/cache-status", (_req, res) => {
|
|
346
|
-
if (!
|
|
355
|
+
if (!currentFileCache) {
|
|
347
356
|
return res.json({ enabled: false });
|
|
348
357
|
}
|
|
349
358
|
res.json({
|
|
350
359
|
enabled: true,
|
|
351
|
-
fileCount:
|
|
352
|
-
totalLines:
|
|
360
|
+
fileCount: currentFileCache.size,
|
|
361
|
+
totalLines: currentFileCache.totalLines,
|
|
353
362
|
sseClients: sseClients.size,
|
|
354
363
|
});
|
|
355
364
|
});
|
|
@@ -804,5 +813,5 @@ function createWebServer(getGraphFn, fileCache, switchProjectFn, getProjectRoot,
|
|
|
804
813
|
res.status(500).json({ error: err.message || "Failed to switch project" });
|
|
805
814
|
}
|
|
806
815
|
});
|
|
807
|
-
return app;
|
|
816
|
+
return { app, setFileCache };
|
|
808
817
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syke1/mcp-server",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"mcpName": "io.github.khalomsky/syke",
|
|
5
5
|
"description": "AI code impact analysis MCP server — dependency graphs, cascade detection, and a mandatory build gate for AI coding agents",
|
|
6
6
|
"main": "dist/index.js",
|