openkrak-mcp 1.0.10 → 1.0.12
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 +66 -102
- package/dist/index.js +37 -14
- package/package.json +4 -2
- package/server.json +23 -0
package/README.md
CHANGED
|
@@ -1,26 +1,14 @@
|
|
|
1
1
|
# openkrak-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MCP server for developer tooling. Performs static analysis on a software repository via the Dorchester engine and delivers a structured context brief to the language model before any file is accessed.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## The Problem
|
|
10
|
-
|
|
11
|
-
Every time you ask your coding agent to modify code, the LLM starts blind — reading raw files, burning tokens, guessing dependencies.
|
|
12
|
-
|
|
13
|
-
**Without OpenKrak:** LLM reads 50,000+ tokens of raw files. Slow. Expensive. Blind.
|
|
14
|
-
**With OpenKrak:** LLM reads a pre-computed Mahadata brief. Precise. Cheap. Aware.
|
|
15
|
-
|
|
16
|
-
For simple tasks, OpenKrak replaces 50+ file reads with a single tool call.
|
|
17
|
-
For complex refactors, it cuts token usage 20-30% and eliminates blind exploration — the LLM knows exactly which files matter before it reads a single line.
|
|
5
|
+
**Supported:** OpenCode (TUI + Desktop). Claude Code, Codex, and Cursor support in development.
|
|
18
6
|
|
|
19
7
|
---
|
|
20
8
|
|
|
21
9
|
## How It Works
|
|
22
10
|
|
|
23
|
-
OpenKrak runs the **Dorchester engine** — a
|
|
11
|
+
OpenKrak runs the **Dorchester engine** — a six-step static analysis pipeline — on your repository before the language model executes any task.
|
|
24
12
|
|
|
25
13
|
```
|
|
26
14
|
Repository
|
|
@@ -41,21 +29,10 @@ Blast Radius — Ripple effects of any change mapped before commit
|
|
|
41
29
|
Execution Gate — Analysis validated and normalized
|
|
42
30
|
│
|
|
43
31
|
▼
|
|
44
|
-
Mahadata — Structured
|
|
32
|
+
Mahadata — Structured brief delivered to the language model
|
|
45
33
|
```
|
|
46
34
|
|
|
47
|
-
Your codebase
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Supported Agents
|
|
52
|
-
|
|
53
|
-
| Agent | Status |
|
|
54
|
-
|-------|--------|
|
|
55
|
-
| **OpenCode** | ✅ Supported |
|
|
56
|
-
| Claude Code | 🔜 Coming soon |
|
|
57
|
-
| Codex | 🔜 Coming soon |
|
|
58
|
-
| Cursor | 🔜 Coming soon |
|
|
35
|
+
All analysis runs locally. Your codebase does not leave your machine.
|
|
59
36
|
|
|
60
37
|
---
|
|
61
38
|
|
|
@@ -65,13 +42,25 @@ Your codebase never leaves your machine. All analysis runs locally.
|
|
|
65
42
|
npm install -g openkrak-mcp
|
|
66
43
|
```
|
|
67
44
|
|
|
45
|
+
Requires Node.js ≥ 18.
|
|
46
|
+
|
|
68
47
|
---
|
|
69
48
|
|
|
70
|
-
## Setup
|
|
49
|
+
## Setup
|
|
50
|
+
|
|
51
|
+
OpenKrak works with both **OpenCode TUI** and **OpenCode Desktop**. The config file and setup steps are identical for both.
|
|
52
|
+
|
|
53
|
+
### Config file location
|
|
54
|
+
|
|
55
|
+
| Platform | Path |
|
|
56
|
+
|----------|------|
|
|
57
|
+
| Windows | `C:\Users\<username>\.config\opencode\opencode.jsonc` |
|
|
58
|
+
| macOS | `~/.config/opencode/opencode.jsonc` |
|
|
59
|
+
| Linux | `~/.config/opencode/opencode.jsonc` |
|
|
71
60
|
|
|
72
|
-
### Step 1 —
|
|
61
|
+
### Step 1 — Add OpenKrak to your config
|
|
73
62
|
|
|
74
|
-
Open
|
|
63
|
+
Open the config file and add the `mcp` block:
|
|
75
64
|
|
|
76
65
|
```jsonc
|
|
77
66
|
{
|
|
@@ -80,91 +69,76 @@ Open `~/.config/opencode/opencode.jsonc` and add the `mcp` block:
|
|
|
80
69
|
"openkrak": {
|
|
81
70
|
"type": "local",
|
|
82
71
|
"enabled": true,
|
|
83
|
-
"command": ["openkrak-mcp"]
|
|
72
|
+
"command": ["npx", "openkrak-mcp"]
|
|
84
73
|
}
|
|
85
74
|
}
|
|
86
75
|
}
|
|
87
76
|
```
|
|
88
77
|
|
|
89
|
-
> **Windows path:** `C:\Users\<username>\.config\opencode\opencode.jsonc`
|
|
90
|
-
> **Mac/Linux path:** `~/.config/opencode/opencode.jsonc`
|
|
91
|
-
|
|
92
78
|
### Step 2 — Restart OpenCode
|
|
93
79
|
|
|
94
|
-
Close and reopen OpenCode
|
|
80
|
+
Close and reopen OpenCode (TUI or Desktop). Confirm **openkrak Connected** appears in the MCP panel.
|
|
95
81
|
|
|
96
|
-
|
|
82
|
+
> **OpenCode Desktop:** MCP status is shown in the bottom status bar. Green dot = connected.
|
|
83
|
+
> **OpenCode TUI:** MCP status is shown in the top-right panel.
|
|
97
84
|
|
|
98
|
-
|
|
85
|
+
### Step 3 — Run your first analysis
|
|
99
86
|
|
|
100
|
-
|
|
87
|
+
Open any repository in OpenCode and send a message:
|
|
101
88
|
|
|
102
89
|
```
|
|
103
|
-
|
|
90
|
+
analyze_repo on /absolute/path/to/your/repo
|
|
104
91
|
```
|
|
105
92
|
|
|
93
|
+
Or just start a coding task normally — OpenKrak runs automatically before the model reads any file.
|
|
94
|
+
|
|
106
95
|
---
|
|
107
96
|
|
|
108
|
-
##
|
|
97
|
+
## Tools
|
|
109
98
|
|
|
110
|
-
|
|
99
|
+
| Tool | When to use |
|
|
100
|
+
|------|-------------|
|
|
101
|
+
| `analyze_repo` | Full pipeline. Call before any coding task on a new repo. Returns dependency graph, hotspot rankings, blast radius, and threat matrix. |
|
|
102
|
+
| `get_mahadata` | Compact repo brief — structure, entry points, constraints, risk score. Use when you need repo-wide context without a full re-analysis. |
|
|
103
|
+
| `get_hotspots` | Ranked list of high-risk files by complexity, coupling, and change frequency. Use before reviewing or refactoring. |
|
|
104
|
+
| `blast_radius` | Impact map for a specific file. Which files, modules, and APIs are affected by a change. Use before modifying a critical file. |
|
|
111
105
|
|
|
112
|
-
|
|
113
|
-
// ON
|
|
114
|
-
"enabled": true
|
|
106
|
+
### Example prompts
|
|
115
107
|
|
|
116
|
-
// OFF
|
|
117
|
-
"enabled": false
|
|
118
108
|
```
|
|
119
|
-
|
|
120
|
-
Then restart OpenCode. That's it.
|
|
121
|
-
|
|
122
|
-
**Quick toggle scripts (optional):**
|
|
123
|
-
|
|
124
|
-
Save these two files anywhere on your machine.
|
|
125
|
-
|
|
126
|
-
`mcp-on.ps1` (Windows PowerShell):
|
|
127
|
-
```powershell
|
|
128
|
-
$config = Get-Content "$env:USERPROFILE\.config\opencode\opencode.jsonc" | ConvertFrom-Json -AsHashtable
|
|
129
|
-
$config.mcp.openkrak.enabled = $true
|
|
130
|
-
$config | ConvertTo-Json -Depth 10 | Set-Content "$env:USERPROFILE\.config\opencode\opencode.jsonc"
|
|
131
|
-
Write-Host "OpenKrak: ON"
|
|
109
|
+
analyze_repo on /path/to/repo with objective "refactor the auth module"
|
|
132
110
|
```
|
|
133
|
-
|
|
134
|
-
`mcp-off.ps1` (Windows PowerShell):
|
|
135
|
-
```powershell
|
|
136
|
-
$config = Get-Content "$env:USERPROFILE\.config\opencode\opencode.jsonc" | ConvertFrom-Json -AsHashtable
|
|
137
|
-
$config.mcp.openkrak.enabled = $false
|
|
138
|
-
$config | ConvertTo-Json -Depth 10 | Set-Content "$env:USERPROFILE\.config\opencode\opencode.jsonc"
|
|
139
|
-
Write-Host "OpenKrak: OFF"
|
|
140
111
|
```
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
powershell -File mcp-off.ps1
|
|
112
|
+
Run get_hotspots on /path/to/repo — which files should I avoid touching?
|
|
113
|
+
```
|
|
114
|
+
```
|
|
115
|
+
blast_radius on /path/to/repo for file src/api/routes/user.ts
|
|
146
116
|
```
|
|
147
117
|
|
|
148
118
|
---
|
|
149
119
|
|
|
150
|
-
##
|
|
120
|
+
## Enable / Disable
|
|
151
121
|
|
|
152
|
-
|
|
122
|
+
Set `"enabled"` in your config and restart OpenCode:
|
|
153
123
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
| `get_hotspots` | Which files are most dangerous to touch — ranked by complexity, coupling, change frequency |
|
|
159
|
-
| `blast_radius` | Ripple effect of modifying a specific file — which files, modules, APIs will be affected |
|
|
124
|
+
```jsonc
|
|
125
|
+
"enabled": true // on
|
|
126
|
+
"enabled": false // off
|
|
127
|
+
```
|
|
160
128
|
|
|
161
129
|
---
|
|
162
130
|
|
|
163
|
-
## Pro License
|
|
131
|
+
## Pro License
|
|
164
132
|
|
|
165
|
-
Free tier
|
|
133
|
+
Free tier is active by default — no account required.
|
|
166
134
|
|
|
167
|
-
|
|
135
|
+
| Plan | Price | Queries |
|
|
136
|
+
|------|-------|---------|
|
|
137
|
+
| Free | $0 | 15 per 24-hour rolling window |
|
|
138
|
+
| Pro Monthly | $8 / month | Unlimited |
|
|
139
|
+
| Pro Annual | $67.20 / year | Unlimited |
|
|
140
|
+
|
|
141
|
+
To activate Pro, add your key to the config:
|
|
168
142
|
|
|
169
143
|
```jsonc
|
|
170
144
|
{
|
|
@@ -173,7 +147,7 @@ For unlimited calls, get a Pro key at **[openkrak.dev](https://openkrak.dev)**:
|
|
|
173
147
|
"openkrak": {
|
|
174
148
|
"type": "local",
|
|
175
149
|
"enabled": true,
|
|
176
|
-
"command": ["openkrak-mcp"],
|
|
150
|
+
"command": ["npx", "openkrak-mcp"],
|
|
177
151
|
"env": {
|
|
178
152
|
"OPENKRAK_KEY": "your-license-key"
|
|
179
153
|
}
|
|
@@ -182,32 +156,22 @@ For unlimited calls, get a Pro key at **[openkrak.dev](https://openkrak.dev)**:
|
|
|
182
156
|
}
|
|
183
157
|
```
|
|
184
158
|
|
|
185
|
-
|
|
186
|
-
|------|-------|-------|
|
|
187
|
-
| Free | $0 | 15 calls / 24h rolling |
|
|
188
|
-
| Pro Monthly | $8/month | Unlimited |
|
|
189
|
-
| Pro Annual | $67.20/year | Unlimited |
|
|
159
|
+
License keys: [openkrak-web.vercel.app](https://openkrak-web.vercel.app). Delivered via email after purchase. No subscription, no auto-renewal.
|
|
190
160
|
|
|
191
161
|
---
|
|
192
162
|
|
|
193
|
-
##
|
|
163
|
+
## Notes
|
|
194
164
|
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
- No telemetry, no file uploads
|
|
165
|
+
- Static analysis only. No AI inference in the pipeline.
|
|
166
|
+
- Anonymous usage telemetry is collected (query count, tool name, error events). No source code or file contents are transmitted.
|
|
167
|
+
- License validation requires a network call to the license server on each tool invocation.
|
|
199
168
|
|
|
200
169
|
---
|
|
201
170
|
|
|
202
|
-
##
|
|
171
|
+
## Repository
|
|
203
172
|
|
|
204
|
-
|
|
205
|
-
- **Analysis:** Static, deterministic — not AI/probabilistic
|
|
206
|
-
- **Runtime:** Node.js ≥ 18
|
|
207
|
-
- **License:** MIT
|
|
173
|
+
[github.com/FrnzJulianBergmann/openkrak](https://github.com/FrnzJulianBergmann/openkrak)
|
|
208
174
|
|
|
209
175
|
---
|
|
210
176
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
MIT — © 2026 Faiz Hamizan
|
|
177
|
+
MIT License — © 2026 Faiz Hamizan / Challanger Absolute Advance
|
package/dist/index.js
CHANGED
|
@@ -241794,7 +241794,7 @@ function inferLanguage(filePath) {
|
|
|
241794
241794
|
if (filePath.endsWith(".js") || filePath.endsWith(".jsx")) return "javascript";
|
|
241795
241795
|
return "unknown";
|
|
241796
241796
|
}
|
|
241797
|
-
function extractRawEdges(filePath, ast, fileNodeId) {
|
|
241797
|
+
function extractRawEdges(filePath, ast, fileNodeId, tsconfigPaths2) {
|
|
241798
241798
|
const edges = [];
|
|
241799
241799
|
const symbolRanges = [];
|
|
241800
241800
|
(0, import_typescript_estree3.simpleTraverse)(ast, {
|
|
@@ -241845,8 +241845,7 @@ function extractRawEdges(filePath, ast, fileNodeId) {
|
|
|
241845
241845
|
if (node.type === "ImportDeclaration") {
|
|
241846
241846
|
const importPath = node.source.value;
|
|
241847
241847
|
const line = node.loc?.start.line ?? null;
|
|
241848
|
-
const
|
|
241849
|
-
const resolvedTarget = resolveImportTarget(filePath, importPath);
|
|
241848
|
+
const resolvedTarget = resolveImportTarget(filePath, importPath, tsconfigPaths2);
|
|
241850
241849
|
edges.push({
|
|
241851
241850
|
from: importFromNodeId,
|
|
241852
241851
|
to: resolvedTarget,
|
|
@@ -241875,7 +241874,7 @@ function extractRawEdges(filePath, ast, fileNodeId) {
|
|
|
241875
241874
|
const sourceLiteral = node.source.type === "Literal" ? node.source.value : "<dynamic>";
|
|
241876
241875
|
edges.push({
|
|
241877
241876
|
from: fileNodeId,
|
|
241878
|
-
to: resolveImportTarget(filePath, sourceLiteral),
|
|
241877
|
+
to: resolveImportTarget(filePath, sourceLiteral, tsconfigPaths2),
|
|
241879
241878
|
kind: "dynamic_import",
|
|
241880
241879
|
file: filePath,
|
|
241881
241880
|
line,
|
|
@@ -241889,7 +241888,6 @@ function extractRawEdges(filePath, ast, fileNodeId) {
|
|
|
241889
241888
|
edges.push({
|
|
241890
241889
|
from: fileNodeId,
|
|
241891
241890
|
to: superName,
|
|
241892
|
-
// resolved to node_id in assembly
|
|
241893
241891
|
kind: "extend",
|
|
241894
241892
|
file: filePath,
|
|
241895
241893
|
line: node.loc.start.line,
|
|
@@ -241954,7 +241952,7 @@ function extractRawEdges(filePath, ast, fileNodeId) {
|
|
|
241954
241952
|
});
|
|
241955
241953
|
return edges;
|
|
241956
241954
|
}
|
|
241957
|
-
function extractBarrelReExports(filePath, ast) {
|
|
241955
|
+
function extractBarrelReExports(filePath, ast, tsconfigPaths2) {
|
|
241958
241956
|
const reExports = [];
|
|
241959
241957
|
(0, import_typescript_estree3.simpleTraverse)(ast, {
|
|
241960
241958
|
enter(node) {
|
|
@@ -241962,7 +241960,7 @@ function extractBarrelReExports(filePath, ast) {
|
|
|
241962
241960
|
if (!node.source) return;
|
|
241963
241961
|
const sourcePath = node.source.value;
|
|
241964
241962
|
if (!sourcePath.startsWith(".")) return;
|
|
241965
|
-
const resolvedSource = resolveImportTarget(filePath, sourcePath);
|
|
241963
|
+
const resolvedSource = resolveImportTarget(filePath, sourcePath, tsconfigPaths2);
|
|
241966
241964
|
if (node.type === "ExportAllDeclaration") {
|
|
241967
241965
|
reExports.push({
|
|
241968
241966
|
barrelFile: filePath,
|
|
@@ -241985,7 +241983,7 @@ function extractBarrelReExports(filePath, ast) {
|
|
|
241985
241983
|
});
|
|
241986
241984
|
return reExports;
|
|
241987
241985
|
}
|
|
241988
|
-
function resolveImportTarget(fromFile, importPath) {
|
|
241986
|
+
function resolveImportTarget(fromFile, importPath, tsconfigPaths2) {
|
|
241989
241987
|
if (importPath.startsWith(".")) {
|
|
241990
241988
|
const dir = import_path3.default.dirname(fromFile);
|
|
241991
241989
|
const resolved = import_path3.default.join(dir, importPath).replace(/\\/g, "/");
|
|
@@ -241995,11 +241993,29 @@ function resolveImportTarget(fromFile, importPath) {
|
|
|
241995
241993
|
}
|
|
241996
241994
|
return normalized;
|
|
241997
241995
|
}
|
|
241996
|
+
if (tsconfigPaths2) {
|
|
241997
|
+
for (const [prefix, target] of Object.entries(tsconfigPaths2)) {
|
|
241998
|
+
if (importPath.startsWith(prefix)) {
|
|
241999
|
+
const rest = importPath.slice(prefix.length);
|
|
242000
|
+
const resolved = (target + rest).replace(/\\/g, "/");
|
|
242001
|
+
const normalized = resolved.replace(/\.js$/, ".ts");
|
|
242002
|
+
if (!import_path3.default.extname(normalized)) {
|
|
242003
|
+
return normalized + ".ts";
|
|
242004
|
+
}
|
|
242005
|
+
return normalized;
|
|
242006
|
+
}
|
|
242007
|
+
}
|
|
242008
|
+
}
|
|
242009
|
+
if (importPath.startsWith("@/")) {
|
|
242010
|
+
const stripped = importPath.slice(2);
|
|
242011
|
+
const normalized = stripped.replace(/\.js$/, ".ts");
|
|
242012
|
+
if (!import_path3.default.extname(normalized)) {
|
|
242013
|
+
return normalized + ".ts";
|
|
242014
|
+
}
|
|
242015
|
+
return normalized;
|
|
242016
|
+
}
|
|
241998
242017
|
return importPath;
|
|
241999
242018
|
}
|
|
242000
|
-
function isBarrelPath(importPath) {
|
|
242001
|
-
return importPath.endsWith("/index") || importPath.endsWith("/index.ts") || importPath.endsWith("/index.js") || importPath === "index";
|
|
242002
|
-
}
|
|
242003
242019
|
function assembleGraph(allNodes, rawEdges, barrelReExports = []) {
|
|
242004
242020
|
for (const node of allNodes) {
|
|
242005
242021
|
node.id = node.id.replace(/\\/g, "/");
|
|
@@ -242511,7 +242527,14 @@ function inferModule(filePath) {
|
|
|
242511
242527
|
return parts.length >= 2 ? parts[0] : null;
|
|
242512
242528
|
}
|
|
242513
242529
|
function isEntryPoint(filePath) {
|
|
242514
|
-
|
|
242530
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
242531
|
+
if (/\/(index|main|server|cli)\.(ts|js)x?$/.test(normalized)) return true;
|
|
242532
|
+
if (/^app\/.*page\.(ts|js)x?$/.test(normalized)) return true;
|
|
242533
|
+
if (/^app\/layout\.(ts|js)x?$/.test(normalized)) return true;
|
|
242534
|
+
if (/^app\/.*route\.(ts|js)x?$/.test(normalized)) return true;
|
|
242535
|
+
if (/^pages\//.test(normalized) && /\.(ts|js)x?$/.test(normalized)) return true;
|
|
242536
|
+
if (/^src\/(main|index|App)\.(ts|js)x?$/.test(normalized)) return true;
|
|
242537
|
+
return false;
|
|
242515
242538
|
}
|
|
242516
242539
|
function walkAst(node, onEnter, onLeave) {
|
|
242517
242540
|
if (!node || typeof node !== "object" || !("type" in node)) return;
|
|
@@ -242622,9 +242645,9 @@ async function runDeepStrike(store, opts) {
|
|
|
242622
242645
|
for (const s of symbols) s.content_hash = currentHash;
|
|
242623
242646
|
allNodes.push(...symbols);
|
|
242624
242647
|
const fileNodeId = symbols.find((n) => n.kind === "file")?.id ?? `${relPath}::file::0`;
|
|
242625
|
-
const rawEdges = extractRawEdges(relPath, ast, fileNodeId);
|
|
242648
|
+
const rawEdges = extractRawEdges(relPath, ast, fileNodeId, tsconfigPaths);
|
|
242626
242649
|
allRawEdges.push(...rawEdges);
|
|
242627
|
-
const barrelReExports = extractBarrelReExports(relPath, ast);
|
|
242650
|
+
const barrelReExports = extractBarrelReExports(relPath, ast, tsconfigPaths);
|
|
242628
242651
|
allBarrelReExports.push(...barrelReExports);
|
|
242629
242652
|
const secFindings = detectSecurityPatterns(relPath, content);
|
|
242630
242653
|
allFindings.push(...secFindings);
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openkrak-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "OpenKrak MCP Server - AI coding intelligence via Dorchester engine",
|
|
5
|
+
"mcpName": "io.github.FrnzJulianBergmann/openkrak",
|
|
5
6
|
"type": "commonjs",
|
|
6
7
|
"bin": {
|
|
7
8
|
"openkrak-mcp": "dist/index.js"
|
|
@@ -9,7 +10,8 @@
|
|
|
9
10
|
"main": "./dist/index.js",
|
|
10
11
|
"files": [
|
|
11
12
|
"dist",
|
|
12
|
-
"README.md"
|
|
13
|
+
"README.md",
|
|
14
|
+
"server.json"
|
|
13
15
|
],
|
|
14
16
|
"scripts": {
|
|
15
17
|
"build": "tsup",
|
package/server.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.FrnzJulianBergmann/openkrak",
|
|
4
|
+
"title": "OpenKrak",
|
|
5
|
+
"description": "MCP server that performs static analysis on a repository via the Dorchester engine — dependency graph construction, complexity scoring, blast radius mapping — and delivers a structured context brief to the language model before any file is read.",
|
|
6
|
+
"version": "1.0.10",
|
|
7
|
+
"repository": {
|
|
8
|
+
"url": "https://github.com/FrnzJulianBergmann/openkrak",
|
|
9
|
+
"source": "github"
|
|
10
|
+
},
|
|
11
|
+
"websiteUrl": "https://openkrak-web.vercel.app",
|
|
12
|
+
"packages": [
|
|
13
|
+
{
|
|
14
|
+
"registryType": "npm",
|
|
15
|
+
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
|
+
"identifier": "openkrak-mcp",
|
|
17
|
+
"version": "1.0.10",
|
|
18
|
+
"transport": {
|
|
19
|
+
"type": "stdio"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|