reasonix 0.32.0 → 0.33.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/dist/cli/chat-EIFLHBZ6.js +39 -0
- package/dist/cli/chunk-2AWTGJ2C.js +110 -0
- package/dist/cli/chunk-2AWTGJ2C.js.map +1 -0
- package/dist/cli/chunk-3Q3C4W66.js +30 -0
- package/dist/cli/chunk-3Q3C4W66.js.map +1 -0
- package/dist/cli/chunk-4DCHFFEY.js +149 -0
- package/dist/cli/chunk-4DCHFFEY.js.map +1 -0
- package/dist/cli/chunk-5X7LZJDE.js +36 -0
- package/dist/cli/chunk-5X7LZJDE.js.map +1 -0
- package/dist/cli/chunk-6TMHAK5D.js +576 -0
- package/dist/cli/chunk-6TMHAK5D.js.map +1 -0
- package/dist/cli/chunk-APPB3ZPQ.js +43 -0
- package/dist/cli/chunk-APPB3ZPQ.js.map +1 -0
- package/dist/cli/chunk-BQNUJJN7.js +42 -0
- package/dist/cli/chunk-BQNUJJN7.js.map +1 -0
- package/dist/cli/chunk-CPOV2O73.js +39 -0
- package/dist/cli/chunk-CPOV2O73.js.map +1 -0
- package/dist/cli/chunk-D5DKXIP5.js +368 -0
- package/dist/cli/chunk-D5DKXIP5.js.map +1 -0
- package/dist/cli/chunk-DFP4YSVM.js +247 -0
- package/dist/cli/chunk-DFP4YSVM.js.map +1 -0
- package/dist/cli/chunk-DULSP7JH.js +410 -0
- package/dist/cli/chunk-DULSP7JH.js.map +1 -0
- package/dist/cli/chunk-FM57FNPJ.js +46 -0
- package/dist/cli/chunk-FM57FNPJ.js.map +1 -0
- package/dist/cli/chunk-FWGEHRB7.js +54 -0
- package/dist/cli/chunk-FWGEHRB7.js.map +1 -0
- package/dist/cli/chunk-FXGQ5NHE.js +513 -0
- package/dist/cli/chunk-FXGQ5NHE.js.map +1 -0
- package/dist/cli/chunk-G3XNWSFN.js +53 -0
- package/dist/cli/chunk-G3XNWSFN.js.map +1 -0
- package/dist/cli/chunk-I6YIAK6C.js +757 -0
- package/dist/cli/chunk-I6YIAK6C.js.map +1 -0
- package/dist/cli/chunk-J5VLP23S.js +94 -0
- package/dist/cli/chunk-J5VLP23S.js.map +1 -0
- package/dist/cli/chunk-KMWKGPFZ.js +303 -0
- package/dist/cli/chunk-KMWKGPFZ.js.map +1 -0
- package/dist/cli/chunk-LVQX5KGF.js +14934 -0
- package/dist/cli/chunk-LVQX5KGF.js.map +1 -0
- package/dist/cli/chunk-MHDNZXJJ.js +48 -0
- package/dist/cli/chunk-MHDNZXJJ.js.map +1 -0
- package/dist/cli/chunk-ORM6PK57.js +140 -0
- package/dist/cli/chunk-ORM6PK57.js.map +1 -0
- package/dist/cli/chunk-Q5GRLZJF.js +99 -0
- package/dist/cli/chunk-Q5GRLZJF.js.map +1 -0
- package/dist/cli/chunk-Q6YFXW7H.js +4986 -0
- package/dist/cli/chunk-Q6YFXW7H.js.map +1 -0
- package/dist/cli/chunk-QGE6AF76.js +1467 -0
- package/dist/cli/chunk-QGE6AF76.js.map +1 -0
- package/dist/cli/chunk-RFX7TYVV.js +28 -0
- package/dist/cli/chunk-RFX7TYVV.js.map +1 -0
- package/dist/cli/chunk-RZILUXUC.js +940 -0
- package/dist/cli/chunk-RZILUXUC.js.map +1 -0
- package/dist/cli/chunk-SDE5U32Z.js +535 -0
- package/dist/cli/chunk-SDE5U32Z.js.map +1 -0
- package/dist/cli/chunk-SOZE7V7V.js +340 -0
- package/dist/cli/chunk-SOZE7V7V.js.map +1 -0
- package/dist/cli/chunk-U3V2ZQ5J.js +479 -0
- package/dist/cli/chunk-U3V2ZQ5J.js.map +1 -0
- package/dist/cli/chunk-W4LDFAZ6.js +1544 -0
- package/dist/cli/chunk-W4LDFAZ6.js.map +1 -0
- package/dist/cli/chunk-WBDE4IRI.js +208 -0
- package/dist/cli/chunk-WBDE4IRI.js.map +1 -0
- package/dist/cli/chunk-XHQIK7B6.js +189 -0
- package/dist/cli/chunk-XHQIK7B6.js.map +1 -0
- package/dist/cli/chunk-XJLZ4HKU.js +307 -0
- package/dist/cli/chunk-XJLZ4HKU.js.map +1 -0
- package/dist/cli/chunk-ZPTSJGX5.js +88 -0
- package/dist/cli/chunk-ZPTSJGX5.js.map +1 -0
- package/dist/cli/chunk-ZTLZO42A.js +231 -0
- package/dist/cli/chunk-ZTLZO42A.js.map +1 -0
- package/dist/cli/code-F4KJOE3K.js +151 -0
- package/dist/cli/code-F4KJOE3K.js.map +1 -0
- package/dist/cli/commands-JWT2MWVH.js +352 -0
- package/dist/cli/commands-JWT2MWVH.js.map +1 -0
- package/dist/cli/commit-RPZBOZS2.js +288 -0
- package/dist/cli/commit-RPZBOZS2.js.map +1 -0
- package/dist/cli/diff-NTEHCSDW.js +145 -0
- package/dist/cli/diff-NTEHCSDW.js.map +1 -0
- package/dist/cli/doctor-3TGB2NZN.js +19 -0
- package/dist/cli/doctor-3TGB2NZN.js.map +1 -0
- package/dist/cli/events-P27CX7LN.js +338 -0
- package/dist/cli/events-P27CX7LN.js.map +1 -0
- package/dist/cli/index.js +80 -33693
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-ARTNQ24O.js +266 -0
- package/dist/cli/mcp-ARTNQ24O.js.map +1 -0
- package/dist/cli/mcp-browse-HLO2ENDL.js +163 -0
- package/dist/cli/mcp-browse-HLO2ENDL.js.map +1 -0
- package/dist/cli/mcp-inspect-T2HBR22P.js +103 -0
- package/dist/cli/mcp-inspect-T2HBR22P.js.map +1 -0
- package/dist/cli/{prompt-XHICFAYN.js → prompt-V47QKSAR.js} +3 -2
- package/dist/cli/prompt-V47QKSAR.js.map +1 -0
- package/dist/cli/prune-sessions-ERL6B4G5.js +42 -0
- package/dist/cli/prune-sessions-ERL6B4G5.js.map +1 -0
- package/dist/cli/replay-TMJASRC4.js +273 -0
- package/dist/cli/replay-TMJASRC4.js.map +1 -0
- package/dist/cli/run-JMEOTQCG.js +215 -0
- package/dist/cli/run-JMEOTQCG.js.map +1 -0
- package/dist/cli/server-SYC3OVOP.js +2967 -0
- package/dist/cli/server-SYC3OVOP.js.map +1 -0
- package/dist/cli/sessions-MOJAALJI.js +102 -0
- package/dist/cli/sessions-MOJAALJI.js.map +1 -0
- package/dist/cli/setup-CCJZAWTY.js +404 -0
- package/dist/cli/setup-CCJZAWTY.js.map +1 -0
- package/dist/cli/stats-5RJCATCE.js +12 -0
- package/dist/cli/stats-5RJCATCE.js.map +1 -0
- package/dist/cli/update-4TJWRUIN.js +90 -0
- package/dist/cli/update-4TJWRUIN.js.map +1 -0
- package/dist/cli/version-3MYFE4G6.js +29 -0
- package/dist/cli/version-3MYFE4G6.js.map +1 -0
- package/dist/index.d.ts +13 -2
- package/dist/index.js +493 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-VWFJNLIK.js +0 -1031
- package/dist/cli/chunk-VWFJNLIK.js.map +0 -1
- /package/dist/cli/{prompt-XHICFAYN.js.map → chat-EIFLHBZ6.js.map} +0 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
fetchSmitheryDetail,
|
|
4
|
+
handleToFetchResult,
|
|
5
|
+
loadMorePages,
|
|
6
|
+
openRegistry,
|
|
7
|
+
specStringFor
|
|
8
|
+
} from "./chunk-SOZE7V7V.js";
|
|
9
|
+
import {
|
|
10
|
+
MCP_CATALOG,
|
|
11
|
+
mcpCommandFor
|
|
12
|
+
} from "./chunk-FM57FNPJ.js";
|
|
13
|
+
import {
|
|
14
|
+
readConfig,
|
|
15
|
+
writeConfig
|
|
16
|
+
} from "./chunk-DULSP7JH.js";
|
|
17
|
+
|
|
18
|
+
// src/cli/commands/mcp.ts
|
|
19
|
+
var DEFAULT_LIST_LIMIT = 30;
|
|
20
|
+
var SEARCH_PAGE_CAP = 20;
|
|
21
|
+
var INSTALL_PAGE_CAP = 30;
|
|
22
|
+
var progressToStderr = ({ source, page, entries }) => {
|
|
23
|
+
if (page === 1 || page % 5 === 0) {
|
|
24
|
+
process.stderr.write(`\r\u25B8 fetching ${source} registry \xB7 page ${page} \xB7 ${entries} entries`);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function finishProgressLine() {
|
|
28
|
+
if (process.stderr.isTTY) process.stderr.write("\r\x1B[K");
|
|
29
|
+
else process.stderr.write("\n");
|
|
30
|
+
}
|
|
31
|
+
function rankEntries(entries) {
|
|
32
|
+
return [...entries].sort((a, b) => {
|
|
33
|
+
const ap = a.popularity ?? -1;
|
|
34
|
+
const bp = b.popularity ?? -1;
|
|
35
|
+
if (ap !== bp) return bp - ap;
|
|
36
|
+
return a.name.localeCompare(b.name);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function pad(s, width) {
|
|
40
|
+
return s.length >= width ? s : s + " ".repeat(width - s.length);
|
|
41
|
+
}
|
|
42
|
+
function fmtAge(ms) {
|
|
43
|
+
const sec = Math.floor(ms / 1e3);
|
|
44
|
+
if (sec < 60) return `${sec}s ago`;
|
|
45
|
+
if (sec < 3600) return `${Math.floor(sec / 60)}m ago`;
|
|
46
|
+
if (sec < 86400) return `${Math.floor(sec / 3600)}h ago`;
|
|
47
|
+
return `${Math.floor(sec / 86400)}d ago`;
|
|
48
|
+
}
|
|
49
|
+
function printEntry(e, indent = " ") {
|
|
50
|
+
const tag = e.source === "official" ? "[official]" : e.source === "smithery" ? "[smithery]" : "[local]";
|
|
51
|
+
const pop = e.popularity !== void 0 ? ` \xB7 ${e.popularity.toLocaleString()} uses` : "";
|
|
52
|
+
console.log(`${indent}${pad(e.name, 36)} ${tag}${pop}`);
|
|
53
|
+
if (e.description) console.log(`${indent} ${e.description}`);
|
|
54
|
+
if (e.install?.requiredEnv?.length) {
|
|
55
|
+
console.log(`${indent} needs: ${e.install.requiredEnv.join(", ")}`);
|
|
56
|
+
} else if (!e.install) {
|
|
57
|
+
console.log(`${indent} (smithery listing \u2014 install detail fetched lazily on install)`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function mcpListCommand(opts = {}) {
|
|
61
|
+
if (opts.local) {
|
|
62
|
+
if (opts.json) {
|
|
63
|
+
console.log(JSON.stringify(MCP_CATALOG, null, 2));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log("Bundled MCP servers (offline catalog):");
|
|
67
|
+
console.log("");
|
|
68
|
+
for (const entry of MCP_CATALOG) {
|
|
69
|
+
console.log(` ${pad(entry.name, 12)} ${entry.summary}`);
|
|
70
|
+
console.log(` ${mcpCommandFor(entry)}`);
|
|
71
|
+
if (entry.note) console.log(` \xB7 ${entry.note}`);
|
|
72
|
+
console.log("");
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });
|
|
77
|
+
const wantedPages = opts.all ? Number.POSITIVE_INFINITY : opts.pages ?? 1;
|
|
78
|
+
const additional = Math.max(0, wantedPages - handle.cache.pagination.pagesLoaded);
|
|
79
|
+
if (additional > 0) {
|
|
80
|
+
await loadMorePages(handle, {
|
|
81
|
+
pages: additional,
|
|
82
|
+
onProgress: progressToStderr
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
finishProgressLine();
|
|
86
|
+
const result = handleToFetchResult(handle);
|
|
87
|
+
const ranked = rankEntries(result.entries);
|
|
88
|
+
const limit = opts.limit ?? DEFAULT_LIST_LIMIT;
|
|
89
|
+
const shown = ranked.slice(0, limit);
|
|
90
|
+
if (opts.json) {
|
|
91
|
+
console.log(
|
|
92
|
+
JSON.stringify(
|
|
93
|
+
{
|
|
94
|
+
source: result.source,
|
|
95
|
+
fromCache: result.fromCache,
|
|
96
|
+
fetchedAt: result.fetchedAt,
|
|
97
|
+
loaded: result.entries.length,
|
|
98
|
+
hasMore: result.hasMore,
|
|
99
|
+
entries: shown
|
|
100
|
+
},
|
|
101
|
+
null,
|
|
102
|
+
2
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const ageStr = result.fromCache ? `cached, ${fmtAge(Date.now() - result.fetchedAt)}` : "just fetched";
|
|
108
|
+
const moreStr = result.hasMore ? "more available" : "all loaded";
|
|
109
|
+
console.log(
|
|
110
|
+
`MCP servers from ${result.source} registry (${result.entries.length} loaded, ${moreStr}, ${ageStr}):`
|
|
111
|
+
);
|
|
112
|
+
if (result.errors.length > 0) {
|
|
113
|
+
for (const e of result.errors) console.error(` warn: ${e}`);
|
|
114
|
+
}
|
|
115
|
+
console.log("");
|
|
116
|
+
for (const e of shown) printEntry(e);
|
|
117
|
+
if (ranked.length > limit) {
|
|
118
|
+
console.log(
|
|
119
|
+
` \u2026 ${ranked.length - limit} more loaded \u2014 use \`reasonix mcp search <query>\` to filter`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
if (result.hasMore) {
|
|
123
|
+
console.log(" \u25B8 more pages available \u2014 `reasonix mcp list --pages <n>` or --all");
|
|
124
|
+
}
|
|
125
|
+
console.log("");
|
|
126
|
+
console.log("Install: reasonix mcp install <name>");
|
|
127
|
+
}
|
|
128
|
+
function matchFilter(query) {
|
|
129
|
+
const q = query.toLowerCase();
|
|
130
|
+
return (e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q);
|
|
131
|
+
}
|
|
132
|
+
async function mcpSearchCommand(query, opts = {}) {
|
|
133
|
+
const q = query.trim();
|
|
134
|
+
if (!q) {
|
|
135
|
+
console.error("usage: reasonix mcp search <query>");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });
|
|
139
|
+
const filter = matchFilter(q);
|
|
140
|
+
const limit = opts.limit ?? DEFAULT_LIST_LIMIT;
|
|
141
|
+
const cap = opts.maxPages ?? SEARCH_PAGE_CAP;
|
|
142
|
+
await loadMorePages(handle, {
|
|
143
|
+
pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),
|
|
144
|
+
matchTarget: limit,
|
|
145
|
+
filter,
|
|
146
|
+
onProgress: progressToStderr
|
|
147
|
+
});
|
|
148
|
+
finishProgressLine();
|
|
149
|
+
const result = handleToFetchResult(handle);
|
|
150
|
+
const matches = rankEntries(result.entries.filter(filter));
|
|
151
|
+
const shown = matches.slice(0, limit);
|
|
152
|
+
if (opts.json) {
|
|
153
|
+
console.log(
|
|
154
|
+
JSON.stringify(
|
|
155
|
+
{
|
|
156
|
+
query: q,
|
|
157
|
+
source: result.source,
|
|
158
|
+
loaded: result.entries.length,
|
|
159
|
+
hasMore: result.hasMore,
|
|
160
|
+
matches: matches.length,
|
|
161
|
+
entries: shown
|
|
162
|
+
},
|
|
163
|
+
null,
|
|
164
|
+
2
|
|
165
|
+
)
|
|
166
|
+
);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (shown.length === 0) {
|
|
170
|
+
console.log(
|
|
171
|
+
`No matches for "${q}" across ${result.entries.length} loaded entries (${result.source}${result.hasMore ? ", more pages exist \u2014 try --refresh or `mcp list --all`" : ""}).`
|
|
172
|
+
);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
console.log(
|
|
176
|
+
`${matches.length} match(es) for "${q}" in ${result.source} registry (${result.entries.length} entries scanned):`
|
|
177
|
+
);
|
|
178
|
+
console.log("");
|
|
179
|
+
for (const e of shown) printEntry(e);
|
|
180
|
+
if (matches.length > limit) console.log(` \u2026 ${matches.length - limit} more matches`);
|
|
181
|
+
}
|
|
182
|
+
function findEntry(entries, name) {
|
|
183
|
+
const exact = entries.find((e) => e.name === name);
|
|
184
|
+
if (exact) return exact;
|
|
185
|
+
const lower = name.toLowerCase();
|
|
186
|
+
const ci = entries.find((e) => e.name.toLowerCase() === lower);
|
|
187
|
+
if (ci) return ci;
|
|
188
|
+
const tail = entries.find((e) => e.name.toLowerCase().endsWith(`/${lower}`));
|
|
189
|
+
if (tail) return tail;
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
async function mcpInstallCommand(name, opts = {}) {
|
|
193
|
+
const target = name.trim();
|
|
194
|
+
if (!target) {
|
|
195
|
+
console.error("usage: reasonix mcp install <name>");
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });
|
|
199
|
+
const lower = target.toLowerCase();
|
|
200
|
+
const filter = (e) => {
|
|
201
|
+
const n = e.name.toLowerCase();
|
|
202
|
+
return n === lower || n.endsWith(`/${lower}`) || n.includes(lower);
|
|
203
|
+
};
|
|
204
|
+
const cap = opts.maxPages ?? INSTALL_PAGE_CAP;
|
|
205
|
+
await loadMorePages(handle, {
|
|
206
|
+
pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),
|
|
207
|
+
matchTarget: 1,
|
|
208
|
+
filter,
|
|
209
|
+
onProgress: progressToStderr
|
|
210
|
+
});
|
|
211
|
+
finishProgressLine();
|
|
212
|
+
const entry = findEntry(handle.cache.entries, target);
|
|
213
|
+
if (!entry) {
|
|
214
|
+
console.error(
|
|
215
|
+
`No MCP server named "${target}" found after walking ${handle.cache.pagination.pagesLoaded} page(s) of the ${handle.source} registry.`
|
|
216
|
+
);
|
|
217
|
+
if (handle.cache.pagination.nextCursor !== null) {
|
|
218
|
+
console.error(`Try: reasonix mcp install ${target} --max-pages 100`);
|
|
219
|
+
}
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
if (!entry.install && entry.source === "smithery") {
|
|
223
|
+
process.stderr.write(`\u25B8 fetching smithery install detail for ${entry.name}\u2026
|
|
224
|
+
`);
|
|
225
|
+
const fetched = await fetchSmitheryDetail(entry.name);
|
|
226
|
+
if (fetched) entry.install = fetched;
|
|
227
|
+
}
|
|
228
|
+
if (!entry.install) {
|
|
229
|
+
console.error(
|
|
230
|
+
`Could not derive install metadata for "${entry.name}" \u2014 try \`npx -y @smithery/cli install ${entry.name}\` directly.`
|
|
231
|
+
);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
let spec;
|
|
235
|
+
try {
|
|
236
|
+
spec = specStringFor(entry.name, entry.install);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
console.error(`Cannot build install spec for ${entry.name}: ${err.message}`);
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
const cfg = readConfig();
|
|
242
|
+
const existing = cfg.mcp ?? [];
|
|
243
|
+
if (existing.includes(spec)) {
|
|
244
|
+
console.log(`Already installed: ${spec}`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const next = { ...cfg, mcp: [...existing, spec] };
|
|
248
|
+
writeConfig(next);
|
|
249
|
+
console.log(`Installed: ${entry.name}`);
|
|
250
|
+
console.log(` spec: ${spec}`);
|
|
251
|
+
if (entry.install.requiredEnv?.length) {
|
|
252
|
+
console.log(
|
|
253
|
+
` needs: ${entry.install.requiredEnv.join(", ")} (set these in your env before next chat)`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
console.log("");
|
|
257
|
+
console.log(
|
|
258
|
+
"Use it: reasonix chat (or `reasonix code`) \u2014 the server will be bridged automatically."
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
export {
|
|
262
|
+
mcpInstallCommand,
|
|
263
|
+
mcpListCommand,
|
|
264
|
+
mcpSearchCommand
|
|
265
|
+
};
|
|
266
|
+
//# sourceMappingURL=mcp-ARTNQ24O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/mcp.ts"],"sourcesContent":["import { readConfig, writeConfig } from \"../../config.js\";\nimport { MCP_CATALOG, mcpCommandFor } from \"../../mcp/catalog.js\";\nimport {\n type FetchProgress,\n fetchSmitheryDetail,\n handleToFetchResult,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\n\nconst DEFAULT_LIST_LIMIT = 30;\n/** Soft cap on how far `search` walks the registry on first run. */\nconst SEARCH_PAGE_CAP = 20;\n/** Soft cap on how far `install` walks looking for a name. */\nconst INSTALL_PAGE_CAP = 30;\n\nconst progressToStderr: FetchProgress = ({ source, page, entries }) => {\n if (page === 1 || page % 5 === 0) {\n process.stderr.write(`\\r▸ fetching ${source} registry · page ${page} · ${entries} entries`);\n }\n};\n\nfunction finishProgressLine(): void {\n if (process.stderr.isTTY) process.stderr.write(\"\\r\\x1b[K\");\n else process.stderr.write(\"\\n\");\n}\n\nexport interface McpListOptions {\n json?: boolean;\n /** Skip network — only show the bundled MCP_CATALOG entries. */\n local?: boolean;\n /** Bypass cache TTL. */\n refresh?: boolean;\n /** How many entries to show. Default 30. */\n limit?: number;\n /** Eagerly load this many pages before showing. Default 1. */\n pages?: number;\n /** Walk all pages of the registry (slow on first run). */\n all?: boolean;\n}\n\nexport interface McpSearchOptions {\n json?: boolean;\n refresh?: boolean;\n limit?: number;\n /** Cap how many pages to walk while searching. Default 20. */\n maxPages?: number;\n}\n\nexport interface McpInstallOptions {\n refresh?: boolean;\n /** Cap how many pages to walk while looking for the name. Default 30. */\n maxPages?: number;\n}\n\nfunction rankEntries(entries: RegistryEntry[]): RegistryEntry[] {\n return [...entries].sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction pad(s: string, width: number): string {\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n\nfunction fmtAge(ms: number): string {\n const sec = Math.floor(ms / 1000);\n if (sec < 60) return `${sec}s ago`;\n if (sec < 3600) return `${Math.floor(sec / 60)}m ago`;\n if (sec < 86400) return `${Math.floor(sec / 3600)}h ago`;\n return `${Math.floor(sec / 86400)}d ago`;\n}\n\nfunction printEntry(e: RegistryEntry, indent = \" \"): void {\n const tag =\n e.source === \"official\" ? \"[official]\" : e.source === \"smithery\" ? \"[smithery]\" : \"[local]\";\n const pop = e.popularity !== undefined ? ` · ${e.popularity.toLocaleString()} uses` : \"\";\n console.log(`${indent}${pad(e.name, 36)} ${tag}${pop}`);\n if (e.description) console.log(`${indent} ${e.description}`);\n if (e.install?.requiredEnv?.length) {\n console.log(`${indent} needs: ${e.install.requiredEnv.join(\", \")}`);\n } else if (!e.install) {\n console.log(`${indent} (smithery listing — install detail fetched lazily on install)`);\n }\n}\n\nexport async function mcpListCommand(opts: McpListOptions = {}): Promise<void> {\n if (opts.local) {\n if (opts.json) {\n console.log(JSON.stringify(MCP_CATALOG, null, 2));\n return;\n }\n console.log(\"Bundled MCP servers (offline catalog):\");\n console.log(\"\");\n for (const entry of MCP_CATALOG) {\n console.log(` ${pad(entry.name, 12)} ${entry.summary}`);\n console.log(` ${mcpCommandFor(entry)}`);\n if (entry.note) console.log(` · ${entry.note}`);\n console.log(\"\");\n }\n return;\n }\n\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const wantedPages = opts.all ? Number.POSITIVE_INFINITY : (opts.pages ?? 1);\n const additional = Math.max(0, wantedPages - handle.cache.pagination.pagesLoaded);\n if (additional > 0) {\n await loadMorePages(handle, {\n pages: additional,\n onProgress: progressToStderr,\n });\n }\n finishProgressLine();\n\n const result = handleToFetchResult(handle);\n const ranked = rankEntries(result.entries);\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n const shown = ranked.slice(0, limit);\n\n if (opts.json) {\n console.log(\n JSON.stringify(\n {\n source: result.source,\n fromCache: result.fromCache,\n fetchedAt: result.fetchedAt,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n entries: shown,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const ageStr = result.fromCache\n ? `cached, ${fmtAge(Date.now() - result.fetchedAt)}`\n : \"just fetched\";\n const moreStr = result.hasMore ? \"more available\" : \"all loaded\";\n console.log(\n `MCP servers from ${result.source} registry (${result.entries.length} loaded, ${moreStr}, ${ageStr}):`,\n );\n if (result.errors.length > 0) {\n for (const e of result.errors) console.error(` warn: ${e}`);\n }\n console.log(\"\");\n for (const e of shown) printEntry(e);\n if (ranked.length > limit) {\n console.log(\n ` … ${ranked.length - limit} more loaded — use \\`reasonix mcp search <query>\\` to filter`,\n );\n }\n if (result.hasMore) {\n console.log(\" ▸ more pages available — `reasonix mcp list --pages <n>` or --all\");\n }\n console.log(\"\");\n console.log(\"Install: reasonix mcp install <name>\");\n}\n\nfunction matchFilter(query: string): (e: RegistryEntry) => boolean {\n const q = query.toLowerCase();\n return (e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q);\n}\n\nexport async function mcpSearchCommand(query: string, opts: McpSearchOptions = {}): Promise<void> {\n const q = query.trim();\n if (!q) {\n console.error(\"usage: reasonix mcp search <query>\");\n process.exit(1);\n }\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const filter = matchFilter(q);\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n const cap = opts.maxPages ?? SEARCH_PAGE_CAP;\n\n await loadMorePages(handle, {\n pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),\n matchTarget: limit,\n filter,\n onProgress: progressToStderr,\n });\n finishProgressLine();\n\n const result = handleToFetchResult(handle);\n const matches = rankEntries(result.entries.filter(filter));\n const shown = matches.slice(0, limit);\n\n if (opts.json) {\n console.log(\n JSON.stringify(\n {\n query: q,\n source: result.source,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n matches: matches.length,\n entries: shown,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n if (shown.length === 0) {\n console.log(\n `No matches for \"${q}\" across ${result.entries.length} loaded entries (${result.source}${\n result.hasMore ? \", more pages exist — try --refresh or `mcp list --all`\" : \"\"\n }).`,\n );\n return;\n }\n console.log(\n `${matches.length} match(es) for \"${q}\" in ${result.source} registry (${result.entries.length} entries scanned):`,\n );\n console.log(\"\");\n for (const e of shown) printEntry(e);\n if (matches.length > limit) console.log(` … ${matches.length - limit} more matches`);\n}\n\nfunction findEntry(entries: RegistryEntry[], name: string): RegistryEntry | null {\n const exact = entries.find((e) => e.name === name);\n if (exact) return exact;\n const lower = name.toLowerCase();\n const ci = entries.find((e) => e.name.toLowerCase() === lower);\n if (ci) return ci;\n const tail = entries.find((e) => e.name.toLowerCase().endsWith(`/${lower}`));\n if (tail) return tail;\n return null;\n}\n\nexport async function mcpInstallCommand(name: string, opts: McpInstallOptions = {}): Promise<void> {\n const target = name.trim();\n if (!target) {\n console.error(\"usage: reasonix mcp install <name>\");\n process.exit(1);\n }\n\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const lower = target.toLowerCase();\n const filter = (e: RegistryEntry): boolean => {\n const n = e.name.toLowerCase();\n return n === lower || n.endsWith(`/${lower}`) || n.includes(lower);\n };\n const cap = opts.maxPages ?? INSTALL_PAGE_CAP;\n\n await loadMorePages(handle, {\n pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),\n matchTarget: 1,\n filter,\n onProgress: progressToStderr,\n });\n finishProgressLine();\n\n const entry = findEntry(handle.cache.entries, target);\n if (!entry) {\n console.error(\n `No MCP server named \"${target}\" found after walking ${handle.cache.pagination.pagesLoaded} page(s) of the ${handle.source} registry.`,\n );\n if (handle.cache.pagination.nextCursor !== null) {\n console.error(`Try: reasonix mcp install ${target} --max-pages 100`);\n }\n process.exit(1);\n }\n\n if (!entry.install && entry.source === \"smithery\") {\n process.stderr.write(`▸ fetching smithery install detail for ${entry.name}…\\n`);\n const fetched = await fetchSmitheryDetail(entry.name);\n if (fetched) entry.install = fetched;\n }\n\n if (!entry.install) {\n console.error(\n `Could not derive install metadata for \"${entry.name}\" — try \\`npx -y @smithery/cli install ${entry.name}\\` directly.`,\n );\n process.exit(1);\n }\n\n let spec: string;\n try {\n spec = specStringFor(entry.name, entry.install);\n } catch (err) {\n console.error(`Cannot build install spec for ${entry.name}: ${(err as Error).message}`);\n process.exit(1);\n }\n\n const cfg = readConfig();\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n console.log(`Already installed: ${spec}`);\n return;\n }\n const next = { ...cfg, mcp: [...existing, spec] };\n writeConfig(next);\n\n console.log(`Installed: ${entry.name}`);\n console.log(` spec: ${spec}`);\n if (entry.install.requiredEnv?.length) {\n console.log(\n ` needs: ${entry.install.requiredEnv.join(\", \")} (set these in your env before next chat)`,\n );\n }\n console.log(\"\");\n console.log(\n \"Use it: reasonix chat (or `reasonix code`) — the server will be bridged automatically.\",\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadDotenv
|
|
4
|
+
} from "./chunk-3Q3C4W66.js";
|
|
5
|
+
import {
|
|
6
|
+
loadMorePages,
|
|
7
|
+
openRegistry,
|
|
8
|
+
specStringFor
|
|
9
|
+
} from "./chunk-SOZE7V7V.js";
|
|
10
|
+
import "./chunk-FM57FNPJ.js";
|
|
11
|
+
import {
|
|
12
|
+
readConfig,
|
|
13
|
+
writeConfig
|
|
14
|
+
} from "./chunk-DULSP7JH.js";
|
|
15
|
+
|
|
16
|
+
// src/cli/commands/mcp-browse.tsx
|
|
17
|
+
import { Box, Text, render, useApp, useInput } from "ink";
|
|
18
|
+
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
19
|
+
var VISIBLE_ROWS = 12;
|
|
20
|
+
function rankAndFilter(entries, query) {
|
|
21
|
+
const q = query.trim().toLowerCase();
|
|
22
|
+
const list = q ? entries.filter((e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q)) : entries;
|
|
23
|
+
return [...list].sort((a, b) => {
|
|
24
|
+
const ap = a.popularity ?? -1;
|
|
25
|
+
const bp = b.popularity ?? -1;
|
|
26
|
+
if (ap !== bp) return bp - ap;
|
|
27
|
+
return a.name.localeCompare(b.name);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function McpBrowseApp() {
|
|
31
|
+
const app = useApp();
|
|
32
|
+
const [state, setState] = useState({
|
|
33
|
+
handle: null,
|
|
34
|
+
loading: true,
|
|
35
|
+
query: "",
|
|
36
|
+
selected: 0,
|
|
37
|
+
status: "opening registry\u2026"
|
|
38
|
+
});
|
|
39
|
+
const setStatus = useCallback((status) => {
|
|
40
|
+
setState((s) => ({ ...s, status }));
|
|
41
|
+
}, []);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
let cancelled = false;
|
|
44
|
+
(async () => {
|
|
45
|
+
try {
|
|
46
|
+
const handle = await openRegistry({});
|
|
47
|
+
if (cancelled) return;
|
|
48
|
+
const ageMs = Date.now() - handle.fetchedAt;
|
|
49
|
+
const ageStr = ageMs < 6e4 ? `${Math.floor(ageMs / 1e3)}s` : `${Math.floor(ageMs / 6e4)}m`;
|
|
50
|
+
setState((s) => ({
|
|
51
|
+
...s,
|
|
52
|
+
handle,
|
|
53
|
+
loading: false,
|
|
54
|
+
status: `${handle.source} \xB7 ${handle.cache.entries.length} entries${handle.fromCache ? ` \xB7 cached ${ageStr} ago` : ""}`
|
|
55
|
+
}));
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (cancelled) return;
|
|
58
|
+
setState((s) => ({ ...s, loading: false, status: `error: ${err.message}` }));
|
|
59
|
+
}
|
|
60
|
+
})();
|
|
61
|
+
return () => {
|
|
62
|
+
cancelled = true;
|
|
63
|
+
};
|
|
64
|
+
}, []);
|
|
65
|
+
const filtered = useMemo(() => {
|
|
66
|
+
if (!state.handle) return [];
|
|
67
|
+
return rankAndFilter(state.handle.cache.entries, state.query);
|
|
68
|
+
}, [state.handle, state.query]);
|
|
69
|
+
const selected = filtered[state.selected];
|
|
70
|
+
const fetchMore = useCallback(async () => {
|
|
71
|
+
if (!state.handle || state.loading) return;
|
|
72
|
+
if (state.handle.cache.pagination.nextCursor === null) {
|
|
73
|
+
setStatus("no more pages \u2014 registry exhausted");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
setState((s) => ({ ...s, loading: true, status: "loading more\u2026" }));
|
|
77
|
+
try {
|
|
78
|
+
const r = await loadMorePages(state.handle, { pages: 5 });
|
|
79
|
+
setState((s) => ({
|
|
80
|
+
...s,
|
|
81
|
+
loading: false,
|
|
82
|
+
status: `+${r.newEntries} entries (${state.handle?.cache.entries.length ?? 0} total)${r.exhausted ? " \xB7 exhausted" : ""}`
|
|
83
|
+
}));
|
|
84
|
+
} catch (err) {
|
|
85
|
+
setState((s) => ({ ...s, loading: false, status: `error: ${err.message}` }));
|
|
86
|
+
}
|
|
87
|
+
}, [state.handle, state.loading, setStatus]);
|
|
88
|
+
const install = useCallback(
|
|
89
|
+
(entry) => {
|
|
90
|
+
if (!entry.install) {
|
|
91
|
+
setStatus(`${entry.name} has no install info (smithery listing)`);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const spec = specStringFor(entry.name, entry.install);
|
|
96
|
+
const cfg = readConfig();
|
|
97
|
+
const existing = cfg.mcp ?? [];
|
|
98
|
+
if (existing.includes(spec)) {
|
|
99
|
+
setStatus(`already installed: ${spec}`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
writeConfig({ ...cfg, mcp: [...existing, spec] });
|
|
103
|
+
setStatus(`installed \u2192 ${spec}`);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
setStatus(`install failed: ${err.message}`);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
[setStatus]
|
|
109
|
+
);
|
|
110
|
+
useInput((input, key) => {
|
|
111
|
+
if (key.escape || key.ctrl && input === "c") {
|
|
112
|
+
app.exit();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (key.upArrow) {
|
|
116
|
+
setState((s) => ({ ...s, selected: Math.max(0, s.selected - 1) }));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (key.downArrow) {
|
|
120
|
+
setState((s) => ({ ...s, selected: Math.min(filtered.length - 1, s.selected + 1) }));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (key.return) {
|
|
124
|
+
if (selected) install(selected);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (key.tab || key.ctrl && input === "n") {
|
|
128
|
+
void fetchMore();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (key.backspace || key.delete) {
|
|
132
|
+
setState((s) => ({ ...s, query: s.query.slice(0, -1), selected: 0 }));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (input && !key.ctrl && !key.meta) {
|
|
136
|
+
setState((s) => ({ ...s, query: s.query + input, selected: 0 }));
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
const start = Math.max(
|
|
140
|
+
0,
|
|
141
|
+
Math.min(state.selected - Math.floor(VISIBLE_ROWS / 2), filtered.length - VISIBLE_ROWS)
|
|
142
|
+
);
|
|
143
|
+
const window = filtered.slice(Math.max(0, start), Math.max(0, start) + VISIBLE_ROWS);
|
|
144
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: "cyan" }, "\u25C8 MCP marketplace"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` \xB7 ${state.status}`)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "search: "), /* @__PURE__ */ React.createElement(Text, { color: "white" }, state.query || "(type to filter)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` ${filtered.length} match${filtered.length === 1 ? "" : "es"}`)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, window.length === 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, state.loading ? "loading\u2026" : "no entries") : window.map((e, i) => {
|
|
145
|
+
const idx = (start || 0) + i;
|
|
146
|
+
const active = idx === state.selected;
|
|
147
|
+
const tag = e.source === "official" ? "[off]" : e.source === "smithery" ? "[smt]" : "[loc]";
|
|
148
|
+
const pop = e.popularity !== void 0 ? ` \xB7 ${e.popularity.toLocaleString()}` : "";
|
|
149
|
+
return /* @__PURE__ */ React.createElement(Box, { key: e.name }, /* @__PURE__ */ React.createElement(Text, { color: active ? "cyan" : void 0 }, active ? "\u25B8 " : " "), /* @__PURE__ */ React.createElement(Text, { bold: active }, e.name.padEnd(40).slice(0, 40)), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` ${tag}${pop}`));
|
|
150
|
+
})), selected ? /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: "white" }, selected.title), selected.description ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, selected.description.slice(0, 160)) : null, selected.install ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, `spec: ${selected.install.runtime} ${selected.install.packageId ?? selected.install.url ?? "\u2014"} \xB7 ${selected.install.transport}`) : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "(smithery listing \u2014 install info not exposed)"), selected.install?.requiredEnv?.length ? /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, `needs: ${selected.install.requiredEnv.join(", ")}`) : null) : null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "type to filter \xB7 \u2191\u2193 pick \xB7 enter install \xB7 tab load more \xB7 esc quit")));
|
|
151
|
+
}
|
|
152
|
+
async function mcpBrowseCommand(_opts = {}) {
|
|
153
|
+
loadDotenv();
|
|
154
|
+
const { waitUntilExit } = render(/* @__PURE__ */ React.createElement(McpBrowseApp, null), {
|
|
155
|
+
exitOnCtrlC: true,
|
|
156
|
+
patchConsole: false
|
|
157
|
+
});
|
|
158
|
+
await waitUntilExit();
|
|
159
|
+
}
|
|
160
|
+
export {
|
|
161
|
+
mcpBrowseCommand
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=mcp-browse-HLO2ENDL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/mcp-browse.tsx"],"sourcesContent":["/** `reasonix mcp browse` — Ink TUI for the MCP marketplace. Lazy-loads pages on scroll. */\n\nimport { Box, Text, render, useApp, useInput } from \"ink\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { readConfig, writeConfig } from \"../../config.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport {\n type RegistryHandle,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\n\nconst VISIBLE_ROWS = 12;\n\ninterface State {\n handle: RegistryHandle | null;\n loading: boolean;\n query: string;\n selected: number;\n status: string;\n}\n\nfunction rankAndFilter(entries: RegistryEntry[], query: string): RegistryEntry[] {\n const q = query.trim().toLowerCase();\n const list = q\n ? entries.filter((e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q))\n : entries;\n return [...list].sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction McpBrowseApp() {\n const app = useApp();\n const [state, setState] = useState<State>({\n handle: null,\n loading: true,\n query: \"\",\n selected: 0,\n status: \"opening registry…\",\n });\n\n const setStatus = useCallback((status: string) => {\n setState((s) => ({ ...s, status }));\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const handle = await openRegistry({});\n if (cancelled) return;\n const ageMs = Date.now() - handle.fetchedAt;\n const ageStr =\n ageMs < 60_000 ? `${Math.floor(ageMs / 1000)}s` : `${Math.floor(ageMs / 60_000)}m`;\n setState((s) => ({\n ...s,\n handle,\n loading: false,\n status: `${handle.source} · ${handle.cache.entries.length} entries${\n handle.fromCache ? ` · cached ${ageStr} ago` : \"\"\n }`,\n }));\n } catch (err) {\n if (cancelled) return;\n setState((s) => ({ ...s, loading: false, status: `error: ${(err as Error).message}` }));\n }\n })();\n return () => {\n cancelled = true;\n };\n }, []);\n\n const filtered = useMemo(() => {\n if (!state.handle) return [];\n return rankAndFilter(state.handle.cache.entries, state.query);\n }, [state.handle, state.query]);\n\n const selected = filtered[state.selected];\n\n const fetchMore = useCallback(async () => {\n if (!state.handle || state.loading) return;\n if (state.handle.cache.pagination.nextCursor === null) {\n setStatus(\"no more pages — registry exhausted\");\n return;\n }\n setState((s) => ({ ...s, loading: true, status: \"loading more…\" }));\n try {\n const r = await loadMorePages(state.handle, { pages: 5 });\n setState((s) => ({\n ...s,\n loading: false,\n status: `+${r.newEntries} entries (${state.handle?.cache.entries.length ?? 0} total)${\n r.exhausted ? \" · exhausted\" : \"\"\n }`,\n }));\n } catch (err) {\n setState((s) => ({ ...s, loading: false, status: `error: ${(err as Error).message}` }));\n }\n }, [state.handle, state.loading, setStatus]);\n\n const install = useCallback(\n (entry: RegistryEntry) => {\n if (!entry.install) {\n setStatus(`${entry.name} has no install info (smithery listing)`);\n return;\n }\n try {\n const spec = specStringFor(entry.name, entry.install);\n const cfg = readConfig();\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n setStatus(`already installed: ${spec}`);\n return;\n }\n writeConfig({ ...cfg, mcp: [...existing, spec] });\n setStatus(`installed → ${spec}`);\n } catch (err) {\n setStatus(`install failed: ${(err as Error).message}`);\n }\n },\n [setStatus],\n );\n\n useInput((input, key) => {\n if (key.escape || (key.ctrl && input === \"c\")) {\n app.exit();\n return;\n }\n if (key.upArrow) {\n setState((s) => ({ ...s, selected: Math.max(0, s.selected - 1) }));\n return;\n }\n if (key.downArrow) {\n setState((s) => ({ ...s, selected: Math.min(filtered.length - 1, s.selected + 1) }));\n return;\n }\n if (key.return) {\n if (selected) install(selected);\n return;\n }\n if (key.tab || (key.ctrl && input === \"n\")) {\n void fetchMore();\n return;\n }\n if (key.backspace || key.delete) {\n setState((s) => ({ ...s, query: s.query.slice(0, -1), selected: 0 }));\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setState((s) => ({ ...s, query: s.query + input, selected: 0 }));\n }\n });\n\n const start = Math.max(\n 0,\n Math.min(state.selected - Math.floor(VISIBLE_ROWS / 2), filtered.length - VISIBLE_ROWS),\n );\n const window = filtered.slice(Math.max(0, start), Math.max(0, start) + VISIBLE_ROWS);\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n <Box>\n <Text bold color=\"cyan\">\n ◈ MCP marketplace\n </Text>\n <Text dimColor>{` · ${state.status}`}</Text>\n </Box>\n <Box marginTop={1}>\n <Text>search: </Text>\n <Text color=\"white\">{state.query || \"(type to filter)\"}</Text>\n <Text dimColor>{` ${filtered.length} match${filtered.length === 1 ? \"\" : \"es\"}`}</Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {window.length === 0 ? (\n <Text dimColor>{state.loading ? \"loading…\" : \"no entries\"}</Text>\n ) : (\n window.map((e, i) => {\n const idx = (start || 0) + i;\n const active = idx === state.selected;\n const tag =\n e.source === \"official\" ? \"[off]\" : e.source === \"smithery\" ? \"[smt]\" : \"[loc]\";\n const pop = e.popularity !== undefined ? ` · ${e.popularity.toLocaleString()}` : \"\";\n return (\n <Box key={e.name}>\n <Text color={active ? \"cyan\" : undefined}>{active ? \"▸ \" : \" \"}</Text>\n <Text bold={active}>{e.name.padEnd(40).slice(0, 40)}</Text>\n <Text dimColor>{` ${tag}${pop}`}</Text>\n </Box>\n );\n })\n )}\n </Box>\n {selected ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"white\">\n {selected.title}\n </Text>\n {selected.description ? <Text dimColor>{selected.description.slice(0, 160)}</Text> : null}\n {selected.install ? (\n <Text dimColor>\n {`spec: ${selected.install.runtime} ${selected.install.packageId ?? selected.install.url ?? \"—\"} · ${selected.install.transport}`}\n </Text>\n ) : (\n <Text dimColor>(smithery listing — install info not exposed)</Text>\n )}\n {selected.install?.requiredEnv?.length ? (\n <Text color=\"yellow\">{`needs: ${selected.install.requiredEnv.join(\", \")}`}</Text>\n ) : null}\n </Box>\n ) : null}\n <Box marginTop={1}>\n <Text dimColor>type to filter · ↑↓ pick · enter install · tab load more · esc quit</Text>\n </Box>\n </Box>\n );\n}\n\nexport interface McpBrowseOptions {\n /** Reserved — currently unused, kept for symmetry with other commands. */\n _unused?: never;\n}\n\nexport async function mcpBrowseCommand(_opts: McpBrowseOptions = {}): Promise<void> {\n loadDotenv();\n const { waitUntilExit } = render(<McpBrowseApp />, {\n exitOnCtrlC: true,\n patchConsole: false,\n });\n await waitUntilExit();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
preflightStdioSpec
|
|
4
|
+
} from "./chunk-RFX7TYVV.js";
|
|
5
|
+
import {
|
|
6
|
+
McpClient,
|
|
7
|
+
SseTransport,
|
|
8
|
+
StdioTransport,
|
|
9
|
+
StreamableHttpTransport,
|
|
10
|
+
inspectMcpServer,
|
|
11
|
+
parseMcpSpec
|
|
12
|
+
} from "./chunk-I6YIAK6C.js";
|
|
13
|
+
import "./chunk-2AWTGJ2C.js";
|
|
14
|
+
|
|
15
|
+
// src/cli/commands/mcp-inspect.ts
|
|
16
|
+
async function mcpInspectCommand(opts) {
|
|
17
|
+
const spec = parseMcpSpec(opts.spec);
|
|
18
|
+
if (spec.transport === "stdio") preflightStdioSpec(spec);
|
|
19
|
+
const transport = spec.transport === "sse" ? new SseTransport({ url: spec.url }) : spec.transport === "streamable-http" ? new StreamableHttpTransport({ url: spec.url }) : new StdioTransport({ command: spec.command, args: spec.args });
|
|
20
|
+
const client = new McpClient({ transport });
|
|
21
|
+
try {
|
|
22
|
+
await client.initialize();
|
|
23
|
+
const report = await inspectMcpServer(client);
|
|
24
|
+
if (opts.json) {
|
|
25
|
+
console.log(JSON.stringify(report, null, 2));
|
|
26
|
+
} else {
|
|
27
|
+
console.log(formatReport(spec.name ?? "(anon)", report));
|
|
28
|
+
}
|
|
29
|
+
} finally {
|
|
30
|
+
await client.close();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function formatMcpInspectFailure(err) {
|
|
34
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
35
|
+
const message = error.message;
|
|
36
|
+
const code = error.code;
|
|
37
|
+
if (code === "ENOENT") {
|
|
38
|
+
const command = message.match(/^spawn\s+([^\s]+)\s+ENOENT$/)?.[1] ?? "the command";
|
|
39
|
+
return `${message} \u2014 try: install or verify \`${command}\`, then check the MCP spec's command spelling`;
|
|
40
|
+
}
|
|
41
|
+
if (code === "ECONNREFUSED") {
|
|
42
|
+
const target = message.match(/\b(https?:\/\/\S+|\d+\.\d+\.\d+\.\d+:\d+|localhost:\d+)\b/i)?.[1];
|
|
43
|
+
return `${message} \u2014 try: confirm ${target ?? "the MCP server"} is running and the host/port match the spec`;
|
|
44
|
+
}
|
|
45
|
+
if (/^MCP request initialize \(id=\d+\) timed out after \d+ms$/.test(message)) {
|
|
46
|
+
return `${message} \u2014 try: confirm the target speaks MCP and completes the handshake before the request timeout`;
|
|
47
|
+
}
|
|
48
|
+
if (/^(empty MCP spec|MCP spec ".*" has name but no command)/.test(message)) {
|
|
49
|
+
return `${message} \u2014 try: pass \`name=command args\` or an http(s):// URL`;
|
|
50
|
+
}
|
|
51
|
+
return message;
|
|
52
|
+
}
|
|
53
|
+
function formatReport(nsName, r) {
|
|
54
|
+
const lines = [];
|
|
55
|
+
lines.push(`MCP server [${nsName}]`);
|
|
56
|
+
lines.push(
|
|
57
|
+
` server ${r.serverInfo.name || "(unknown)"}${r.serverInfo.version ? ` v${r.serverInfo.version}` : ""}`
|
|
58
|
+
);
|
|
59
|
+
lines.push(` protocol ${r.protocolVersion}`);
|
|
60
|
+
const capKeys = Object.keys(r.capabilities);
|
|
61
|
+
lines.push(` caps ${capKeys.length > 0 ? capKeys.join(", ") : "(none advertised)"}`);
|
|
62
|
+
if (r.instructions) {
|
|
63
|
+
lines.push(` notes ${r.instructions.trim().slice(0, 200)}`);
|
|
64
|
+
}
|
|
65
|
+
lines.push("");
|
|
66
|
+
lines.push(formatSection("Tools", r.tools, toolLine));
|
|
67
|
+
lines.push(formatSection("Resources", r.resources, resourceLine));
|
|
68
|
+
lines.push(formatSection("Prompts", r.prompts, promptLine));
|
|
69
|
+
return lines.join("\n");
|
|
70
|
+
}
|
|
71
|
+
function formatSection(title, section, render) {
|
|
72
|
+
if (!section.supported) {
|
|
73
|
+
return `${title}: (not supported \u2014 ${section.reason})`;
|
|
74
|
+
}
|
|
75
|
+
if (section.items.length === 0) {
|
|
76
|
+
return `${title}: (none)`;
|
|
77
|
+
}
|
|
78
|
+
const lines = [`${title} (${section.items.length}):`];
|
|
79
|
+
for (const item of section.items) lines.push(` ${render(item)}`);
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
function toolLine(t) {
|
|
83
|
+
const desc = t.description ? ` \u2014 ${oneLine(t.description, 80)}` : "";
|
|
84
|
+
return `\xB7 ${t.name}${desc}`;
|
|
85
|
+
}
|
|
86
|
+
function resourceLine(r) {
|
|
87
|
+
const mime = r.mimeType ? ` [${r.mimeType}]` : "";
|
|
88
|
+
return `\xB7 ${r.name}${mime} ${r.uri}`;
|
|
89
|
+
}
|
|
90
|
+
function promptLine(p) {
|
|
91
|
+
const argPart = p.arguments && p.arguments.length > 0 ? ` (${p.arguments.map((a) => a.required ? a.name : `${a.name}?`).join(", ")})` : "";
|
|
92
|
+
const desc = p.description ? ` \u2014 ${oneLine(p.description, 80)}` : "";
|
|
93
|
+
return `\xB7 ${p.name}${argPart}${desc}`;
|
|
94
|
+
}
|
|
95
|
+
function oneLine(s, max) {
|
|
96
|
+
const flat = s.replace(/\s+/g, " ").trim();
|
|
97
|
+
return flat.length <= max ? flat : `${flat.slice(0, max - 1)}\u2026`;
|
|
98
|
+
}
|
|
99
|
+
export {
|
|
100
|
+
formatMcpInspectFailure,
|
|
101
|
+
mcpInspectCommand
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=mcp-inspect-T2HBR22P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/mcp-inspect.ts"],"sourcesContent":["import { McpClient } from \"../../mcp/client.js\";\nimport { inspectMcpServer } from \"../../mcp/inspect.js\";\nimport type { InspectionReport } from \"../../mcp/inspect.js\";\nimport { preflightStdioSpec } from \"../../mcp/preflight.js\";\nimport { parseMcpSpec } from \"../../mcp/spec.js\";\nimport { SseTransport } from \"../../mcp/sse.js\";\nimport { type McpTransport, StdioTransport } from \"../../mcp/stdio.js\";\nimport { StreamableHttpTransport } from \"../../mcp/streamable-http.js\";\n\nexport interface McpInspectOptions {\n /** The raw --mcp spec string (e.g. `fs=npx -y @modelcontextprotocol/server-filesystem .`). */\n spec: string;\n /** Emit JSON on stdout instead of the human-readable table. */\n json?: boolean;\n}\n\nexport async function mcpInspectCommand(opts: McpInspectOptions): Promise<void> {\n const spec = parseMcpSpec(opts.spec);\n if (spec.transport === \"stdio\") preflightStdioSpec(spec);\n const transport: McpTransport =\n spec.transport === \"sse\"\n ? new SseTransport({ url: spec.url })\n : spec.transport === \"streamable-http\"\n ? new StreamableHttpTransport({ url: spec.url })\n : new StdioTransport({ command: spec.command, args: spec.args });\n const client = new McpClient({ transport });\n try {\n await client.initialize();\n const report = await inspectMcpServer(client);\n if (opts.json) {\n console.log(JSON.stringify(report, null, 2));\n } else {\n console.log(formatReport(spec.name ?? \"(anon)\", report));\n }\n } finally {\n await client.close();\n }\n}\n\nexport function formatMcpInspectFailure(err: unknown): string {\n const error = err instanceof Error ? err : new Error(String(err));\n const message = error.message;\n const code = (error as NodeJS.ErrnoException).code;\n\n if (code === \"ENOENT\") {\n const command = message.match(/^spawn\\s+([^\\s]+)\\s+ENOENT$/)?.[1] ?? \"the command\";\n return `${message} — try: install or verify \\`${command}\\`, then check the MCP spec's command spelling`;\n }\n\n if (code === \"ECONNREFUSED\") {\n const target = message.match(/\\b(https?:\\/\\/\\S+|\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+|localhost:\\d+)\\b/i)?.[1];\n return `${message} — try: confirm ${target ?? \"the MCP server\"} is running and the host/port match the spec`;\n }\n\n if (/^MCP request initialize \\(id=\\d+\\) timed out after \\d+ms$/.test(message)) {\n return `${message} — try: confirm the target speaks MCP and completes the handshake before the request timeout`;\n }\n\n if (/^(empty MCP spec|MCP spec \".*\" has name but no command)/.test(message)) {\n return `${message} — try: pass \\`name=command args\\` or an http(s):// URL`;\n }\n\n return message;\n}\n\nfunction formatReport(nsName: string, r: InspectionReport): string {\n const lines: string[] = [];\n lines.push(`MCP server [${nsName}]`);\n lines.push(\n ` server ${r.serverInfo.name || \"(unknown)\"}${r.serverInfo.version ? ` v${r.serverInfo.version}` : \"\"}`,\n );\n lines.push(` protocol ${r.protocolVersion}`);\n const capKeys = Object.keys(r.capabilities);\n lines.push(` caps ${capKeys.length > 0 ? capKeys.join(\", \") : \"(none advertised)\"}`);\n if (r.instructions) {\n lines.push(` notes ${r.instructions.trim().slice(0, 200)}`);\n }\n lines.push(\"\");\n lines.push(formatSection(\"Tools\", r.tools, toolLine));\n lines.push(formatSection(\"Resources\", r.resources, resourceLine));\n lines.push(formatSection(\"Prompts\", r.prompts, promptLine));\n return lines.join(\"\\n\");\n}\n\nfunction formatSection<T>(\n title: string,\n section: { supported: true; items: T[] } | { supported: false; reason: string },\n render: (item: T) => string,\n): string {\n if (!section.supported) {\n return `${title}: (not supported — ${section.reason})`;\n }\n if (section.items.length === 0) {\n return `${title}: (none)`;\n }\n const lines = [`${title} (${section.items.length}):`];\n for (const item of section.items) lines.push(` ${render(item)}`);\n return lines.join(\"\\n\");\n}\n\nfunction toolLine(t: { name: string; description?: string }): string {\n const desc = t.description ? ` — ${oneLine(t.description, 80)}` : \"\";\n return `· ${t.name}${desc}`;\n}\n\nfunction resourceLine(r: { uri: string; name: string; mimeType?: string }): string {\n const mime = r.mimeType ? ` [${r.mimeType}]` : \"\";\n return `· ${r.name}${mime} ${r.uri}`;\n}\n\nfunction promptLine(p: {\n name: string;\n description?: string;\n arguments?: Array<{ name: string; required?: boolean }>;\n}): string {\n const argPart =\n p.arguments && p.arguments.length > 0\n ? ` (${p.arguments.map((a) => (a.required ? a.name : `${a.name}?`)).join(\", \")})`\n : \"\";\n const desc = p.description ? ` — ${oneLine(p.description, 80)}` : \"\";\n return `· ${p.name}${argPart}${desc}`;\n}\n\nfunction oneLine(s: string, max: number): string {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length <= max ? flat : `${flat.slice(0, max - 1)}…`;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CODE_SYSTEM_PROMPT,
|
|
4
4
|
codeSystemPrompt
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6TMHAK5D.js";
|
|
6
|
+
import "./chunk-U3V2ZQ5J.js";
|
|
6
7
|
export {
|
|
7
8
|
CODE_SYSTEM_PROMPT,
|
|
8
9
|
codeSystemPrompt
|
|
9
10
|
};
|
|
10
|
-
//# sourceMappingURL=prompt-
|
|
11
|
+
//# sourceMappingURL=prompt-V47QKSAR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|