skill-registry-mcp 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +35 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +366 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/tools.d.ts +52 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +55 -0
- package/dist/tools.js.map +1 -0
- package/package.json +22 -0
- package/src/client.ts +463 -0
- package/src/config.ts +56 -0
- package/src/index.ts +138 -0
- package/src/tools.ts +63 -0
- package/test/tools.test.ts +1572 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +9 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillRegistryClient - handles API calls to the Skill Registry API
|
|
3
|
+
* Implements session-level deduplication for find_skill
|
|
4
|
+
* Implements LRU offline cache and health polling with exponential backoff
|
|
5
|
+
*/
|
|
6
|
+
import type { Namespace } from './config.js';
|
|
7
|
+
export interface ClientOptions {
|
|
8
|
+
apiKey: string;
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
namespace: Namespace;
|
|
11
|
+
/** Override the skills directory (defaults to ~/.claude/skills). Used in tests. */
|
|
12
|
+
skillsDir?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface FindSkillInput {
|
|
15
|
+
query: string;
|
|
16
|
+
bundle_id?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SubmitFeedbackInput {
|
|
19
|
+
match_id: string;
|
|
20
|
+
skill_id: string;
|
|
21
|
+
result: 'success' | 'failure' | 'partial';
|
|
22
|
+
score: number;
|
|
23
|
+
}
|
|
24
|
+
export interface SkillRegistryClient {
|
|
25
|
+
findSkill(input: FindSkillInput): Promise<string>;
|
|
26
|
+
listBundles(): Promise<string>;
|
|
27
|
+
submitFeedback(input: SubmitFeedbackInput): Promise<string>;
|
|
28
|
+
/** Clean up background resources (health polling timer). */
|
|
29
|
+
destroy?: () => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a new SkillRegistryClient instance with its own session dedup state.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createSkillRegistryClient(options: ClientOptions): SkillRegistryClient;
|
|
35
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAM5C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,SAAS,CAAA;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;IACzC,KAAK,EAAE,MAAM,CAAA;CACd;AA4BD,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACjD,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9B,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3D,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AA6CD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,mBAAmB,CAmVrF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillRegistryClient - handles API calls to the Skill Registry API
|
|
3
|
+
* Implements session-level deduplication for find_skill
|
|
4
|
+
* Implements LRU offline cache and health polling with exponential backoff
|
|
5
|
+
*/
|
|
6
|
+
import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
7
|
+
import { existsSync } from 'fs';
|
|
8
|
+
import { join, dirname } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
// LRU cache constants
|
|
11
|
+
const LRU_MAX_SIZE = 50;
|
|
12
|
+
const HEALTH_POLL_INITIAL_MS = 5000;
|
|
13
|
+
const HEALTH_POLL_MAX_MS = 60000;
|
|
14
|
+
/**
|
|
15
|
+
* Minimal LRU cache using a Map (insertion order + re-insertion on access).
|
|
16
|
+
* Key is query.trim().toLowerCase(). Max size is LRU_MAX_SIZE.
|
|
17
|
+
*/
|
|
18
|
+
class LRUCache {
|
|
19
|
+
map = new Map();
|
|
20
|
+
maxSize;
|
|
21
|
+
constructor(maxSize) {
|
|
22
|
+
this.maxSize = maxSize;
|
|
23
|
+
}
|
|
24
|
+
get(key) {
|
|
25
|
+
if (!this.map.has(key))
|
|
26
|
+
return undefined;
|
|
27
|
+
// Re-insert to mark as recently used
|
|
28
|
+
const value = this.map.get(key);
|
|
29
|
+
this.map.delete(key);
|
|
30
|
+
this.map.set(key, value);
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
set(key, value) {
|
|
34
|
+
if (this.map.has(key)) {
|
|
35
|
+
this.map.delete(key);
|
|
36
|
+
}
|
|
37
|
+
this.map.set(key, value);
|
|
38
|
+
// Evict oldest (first) entry if over capacity
|
|
39
|
+
if (this.map.size > this.maxSize) {
|
|
40
|
+
const firstKey = this.map.keys().next().value;
|
|
41
|
+
this.map.delete(firstKey);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
has(key) {
|
|
45
|
+
return this.map.has(key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create a new SkillRegistryClient instance with its own session dedup state.
|
|
50
|
+
*/
|
|
51
|
+
export function createSkillRegistryClient(options) {
|
|
52
|
+
const { apiKey, baseUrl, namespace } = options;
|
|
53
|
+
const skillsDir = options.skillsDir ?? join(homedir(), '.claude', 'skills');
|
|
54
|
+
// Session-level deduplication: tracks skill_ids already returned in this client instance
|
|
55
|
+
const returnedSkillIds = new Set();
|
|
56
|
+
// LRU offline cache: key = query.trim().toLowerCase(), value = AGENT.md content string
|
|
57
|
+
const offlineCache = new LRUCache(LRU_MAX_SIZE);
|
|
58
|
+
// Offline state tracking
|
|
59
|
+
let isOffline = false;
|
|
60
|
+
let healthPollTimer = null;
|
|
61
|
+
let currentPollIntervalMs = HEALTH_POLL_INITIAL_MS;
|
|
62
|
+
/**
|
|
63
|
+
* Start health polling with exponential backoff.
|
|
64
|
+
* Only starts if not already polling.
|
|
65
|
+
*/
|
|
66
|
+
function startHealthPolling() {
|
|
67
|
+
if (healthPollTimer !== null)
|
|
68
|
+
return;
|
|
69
|
+
currentPollIntervalMs = HEALTH_POLL_INITIAL_MS;
|
|
70
|
+
scheduleHealthPoll();
|
|
71
|
+
}
|
|
72
|
+
function scheduleHealthPoll() {
|
|
73
|
+
healthPollTimer = setTimeout(async () => {
|
|
74
|
+
healthPollTimer = null;
|
|
75
|
+
await pollHealth();
|
|
76
|
+
}, currentPollIntervalMs);
|
|
77
|
+
}
|
|
78
|
+
async function pollHealth() {
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(`${baseUrl}/v1/health`, {
|
|
81
|
+
method: 'GET',
|
|
82
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
83
|
+
});
|
|
84
|
+
if (response.ok) {
|
|
85
|
+
let data = {};
|
|
86
|
+
try {
|
|
87
|
+
data = (await response.json());
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// ignore parse errors
|
|
91
|
+
}
|
|
92
|
+
if (data.status === 'ok' || data.status === 'degraded') {
|
|
93
|
+
// Cloud is back
|
|
94
|
+
isOffline = false;
|
|
95
|
+
healthPollTimer = null;
|
|
96
|
+
currentPollIntervalMs = HEALTH_POLL_INITIAL_MS;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Health check failed - still offline
|
|
103
|
+
}
|
|
104
|
+
// Still offline: schedule next poll with exponential backoff
|
|
105
|
+
currentPollIntervalMs = Math.min(currentPollIntervalMs * 2, HEALTH_POLL_MAX_MS);
|
|
106
|
+
scheduleHealthPoll();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Stop health polling and clean up timer.
|
|
110
|
+
*/
|
|
111
|
+
function stopHealthPolling() {
|
|
112
|
+
if (healthPollTimer !== null) {
|
|
113
|
+
clearTimeout(healthPollTimer);
|
|
114
|
+
healthPollTimer = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async function findSkill(input) {
|
|
118
|
+
const cacheKey = input.query.trim().toLowerCase();
|
|
119
|
+
// If offline, try cache first
|
|
120
|
+
if (isOffline) {
|
|
121
|
+
const cached = offlineCache.get(cacheKey);
|
|
122
|
+
if (cached !== undefined) {
|
|
123
|
+
return cached;
|
|
124
|
+
}
|
|
125
|
+
return '当前处于离线模式,未找到缓存结果。错误码:OFFLINE_CACHE_MISS';
|
|
126
|
+
}
|
|
127
|
+
const body = {
|
|
128
|
+
query: input.query,
|
|
129
|
+
namespace,
|
|
130
|
+
};
|
|
131
|
+
if (input.bundle_id) {
|
|
132
|
+
body.bundle_id = input.bundle_id;
|
|
133
|
+
}
|
|
134
|
+
let response;
|
|
135
|
+
try {
|
|
136
|
+
response = await fetch(`${baseUrl}/v1/match`, {
|
|
137
|
+
method: 'POST',
|
|
138
|
+
headers: {
|
|
139
|
+
'Content-Type': 'application/json',
|
|
140
|
+
Authorization: `Bearer ${apiKey}`,
|
|
141
|
+
},
|
|
142
|
+
body: JSON.stringify(body),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
// Network error - switch to offline mode
|
|
147
|
+
isOffline = true;
|
|
148
|
+
startHealthPolling();
|
|
149
|
+
// Try cache
|
|
150
|
+
const cached = offlineCache.get(cacheKey);
|
|
151
|
+
if (cached !== undefined) {
|
|
152
|
+
return cached;
|
|
153
|
+
}
|
|
154
|
+
return '当前处于离线模式,未找到缓存结果。错误码:OFFLINE_CACHE_MISS';
|
|
155
|
+
}
|
|
156
|
+
if (response.status === 401) {
|
|
157
|
+
return '认证失败:API Key 无效或未授权,请检查 SKILL_REGISTRY_API_KEY 环境变量。';
|
|
158
|
+
}
|
|
159
|
+
if (response.status === 429) {
|
|
160
|
+
return '请求超限:已超过 API 调用频率限制,请稍后重试。';
|
|
161
|
+
}
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
return `API 请求失败:HTTP ${response.status}`;
|
|
164
|
+
}
|
|
165
|
+
let data;
|
|
166
|
+
try {
|
|
167
|
+
data = (await response.json());
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return 'API 返回数据格式错误';
|
|
171
|
+
}
|
|
172
|
+
if (!data.skills || data.skills.length === 0) {
|
|
173
|
+
return '未找到匹配的 skill';
|
|
174
|
+
}
|
|
175
|
+
const skill = data.skills[0];
|
|
176
|
+
// Session-level deduplication check
|
|
177
|
+
if (returnedSkillIds.has(skill.skill_id)) {
|
|
178
|
+
// Extract skill name from content (first line H1 header) or fall back to skill_id
|
|
179
|
+
const skillName = extractSkillName(skill.content, skill.skill_id);
|
|
180
|
+
return `[${skillName}] 已在当前 session 中提供,请参考之前的上下文`;
|
|
181
|
+
}
|
|
182
|
+
// Mark this skill as returned in the current session
|
|
183
|
+
returnedSkillIds.add(skill.skill_id);
|
|
184
|
+
// If this is a Script type skill, attempt to download scripts
|
|
185
|
+
if (skill.type === 'Script' && skill.name && skill.scripts && skill.scripts.length > 0) {
|
|
186
|
+
const warnings = await downloadScripts(skill);
|
|
187
|
+
const finalContent = warnings.length > 0
|
|
188
|
+
? skill.content + '\n\n' + warnings.join('\n')
|
|
189
|
+
: skill.content;
|
|
190
|
+
// Cache the content (even Script skills)
|
|
191
|
+
offlineCache.set(cacheKey, finalContent);
|
|
192
|
+
return finalContent;
|
|
193
|
+
}
|
|
194
|
+
// Cache the result (AC1)
|
|
195
|
+
offlineCache.set(cacheKey, skill.content);
|
|
196
|
+
return skill.content;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Download script files for a Script-type skill.
|
|
200
|
+
* Returns an array of warning strings (empty if all downloads succeeded).
|
|
201
|
+
*/
|
|
202
|
+
async function downloadScripts(skill) {
|
|
203
|
+
const skillName = skill.name;
|
|
204
|
+
const skillDir = join(skillsDir, skillName);
|
|
205
|
+
const versionFile = join(skillDir, '.version');
|
|
206
|
+
// Check if local version matches remote version (skip download if same)
|
|
207
|
+
if (skill.version && existsSync(versionFile)) {
|
|
208
|
+
try {
|
|
209
|
+
const localVersion = await readFile(versionFile, 'utf8');
|
|
210
|
+
if (localVersion.trim() === skill.version.trim()) {
|
|
211
|
+
// Same version, skip download
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// Cannot read version file, proceed with download
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Ensure skill directory exists
|
|
220
|
+
try {
|
|
221
|
+
await mkdir(skillDir, { recursive: true });
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
return ['[WARN] 脚本文件下载失败,请手动下载或重新调用'];
|
|
225
|
+
}
|
|
226
|
+
const warnings = [];
|
|
227
|
+
for (const filename of skill.scripts) {
|
|
228
|
+
const scriptUrl = `${baseUrl}/v1/skills/${skill.skill_id}/scripts/${filename}`;
|
|
229
|
+
let scriptResponse;
|
|
230
|
+
try {
|
|
231
|
+
scriptResponse = await fetch(scriptUrl, {
|
|
232
|
+
headers: {
|
|
233
|
+
Authorization: `Bearer ${apiKey}`,
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
// Network error
|
|
239
|
+
warnings.push('[WARN] 脚本文件下载失败,请手动下载或重新调用');
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (scriptResponse.status === 404) {
|
|
243
|
+
warnings.push('[WARN] 脚本文件不存在,请联系 skill 维护者');
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (!scriptResponse.ok) {
|
|
247
|
+
warnings.push('[WARN] 脚本文件下载失败,请手动下载或重新调用');
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
const scriptContent = await scriptResponse.arrayBuffer();
|
|
252
|
+
const scriptPath = join(skillDir, filename);
|
|
253
|
+
// Ensure subdirectory exists if filename contains path separators
|
|
254
|
+
await mkdir(dirname(scriptPath), { recursive: true });
|
|
255
|
+
await writeFile(scriptPath, Buffer.from(scriptContent));
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
warnings.push('[WARN] 脚本文件下载失败,请手动下载或重新调用');
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Write version file if all downloads succeeded (no warnings)
|
|
263
|
+
if (warnings.length === 0 && skill.version) {
|
|
264
|
+
try {
|
|
265
|
+
await writeFile(versionFile, skill.version);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Non-critical: ignore version file write failure
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return warnings;
|
|
272
|
+
}
|
|
273
|
+
async function listBundles() {
|
|
274
|
+
let response;
|
|
275
|
+
try {
|
|
276
|
+
response = await fetch(`${baseUrl}/v1/bundles`, {
|
|
277
|
+
method: 'GET',
|
|
278
|
+
headers: {
|
|
279
|
+
Authorization: `Bearer ${apiKey}`,
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
return `网络错误:无法连接到 Skill Registry API。${String(err)}`;
|
|
285
|
+
}
|
|
286
|
+
if (response.status === 401) {
|
|
287
|
+
return '认证失败:API Key 无效或未授权。';
|
|
288
|
+
}
|
|
289
|
+
if (!response.ok) {
|
|
290
|
+
return `API 请求失败:HTTP ${response.status}`;
|
|
291
|
+
}
|
|
292
|
+
let data;
|
|
293
|
+
try {
|
|
294
|
+
data = (await response.json());
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
return 'API 返回数据格式错误';
|
|
298
|
+
}
|
|
299
|
+
if (!data.bundles || data.bundles.length === 0) {
|
|
300
|
+
return '暂无可用的 bundle';
|
|
301
|
+
}
|
|
302
|
+
// Format as plain text
|
|
303
|
+
const lines = ['Bundle 列表:', ''];
|
|
304
|
+
for (const bundle of data.bundles) {
|
|
305
|
+
lines.push(`Bundle ID: ${bundle.bundle_id}`);
|
|
306
|
+
lines.push(`名称: ${bundle.name}`);
|
|
307
|
+
if (bundle.description) {
|
|
308
|
+
lines.push(`描述: ${bundle.description}`);
|
|
309
|
+
}
|
|
310
|
+
lines.push(`命名空间: ${bundle.namespace}`);
|
|
311
|
+
lines.push(`Skill 数量: ${bundle.skill_count}`);
|
|
312
|
+
lines.push('');
|
|
313
|
+
}
|
|
314
|
+
return lines.join('\n').trimEnd();
|
|
315
|
+
}
|
|
316
|
+
async function submitFeedback(input) {
|
|
317
|
+
let response;
|
|
318
|
+
try {
|
|
319
|
+
response = await fetch(`${baseUrl}/v1/feedback`, {
|
|
320
|
+
method: 'POST',
|
|
321
|
+
headers: {
|
|
322
|
+
'Content-Type': 'application/json',
|
|
323
|
+
Authorization: `Bearer ${apiKey}`,
|
|
324
|
+
},
|
|
325
|
+
body: JSON.stringify(input),
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
return `网络错误:无法连接到 Skill Registry API。${String(err)}`;
|
|
330
|
+
}
|
|
331
|
+
if (response.status === 401) {
|
|
332
|
+
return '认证失败:API Key 无效或未授权,请检查 SKILL_REGISTRY_API_KEY 环境变量。';
|
|
333
|
+
}
|
|
334
|
+
if (response.status === 400) {
|
|
335
|
+
let errorBody = {};
|
|
336
|
+
try {
|
|
337
|
+
errorBody = (await response.json());
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
// ignore JSON parse failure
|
|
341
|
+
}
|
|
342
|
+
const errorCode = String(errorBody.error ?? 'UNKNOWN_ERROR');
|
|
343
|
+
const errorMsg = String(errorBody.message ?? '');
|
|
344
|
+
return `反馈提交失败:${errorCode}${errorMsg ? ' - ' + errorMsg : ''}`;
|
|
345
|
+
}
|
|
346
|
+
if (!response.ok) {
|
|
347
|
+
return `API 请求失败:HTTP ${response.status}`;
|
|
348
|
+
}
|
|
349
|
+
return '反馈已提交';
|
|
350
|
+
}
|
|
351
|
+
function destroy() {
|
|
352
|
+
stopHealthPolling();
|
|
353
|
+
}
|
|
354
|
+
return { findSkill, listBundles, submitFeedback, destroy };
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Extract skill name from AGENT.md content (first H1 heading) or fall back to skill_id.
|
|
358
|
+
*/
|
|
359
|
+
function extractSkillName(content, skillId) {
|
|
360
|
+
const match = content.match(/^#\s+(.+)$/m);
|
|
361
|
+
if (match) {
|
|
362
|
+
return match[1].trim();
|
|
363
|
+
}
|
|
364
|
+
return skillId;
|
|
365
|
+
}
|
|
366
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration parsing and validation for MCP server
|
|
3
|
+
*/
|
|
4
|
+
export type Namespace = 'private' | 'public' | 'all';
|
|
5
|
+
export interface McpConfig {
|
|
6
|
+
namespace: Namespace;
|
|
7
|
+
}
|
|
8
|
+
export interface EnvConfig {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Parse command-line arguments for the MCP server.
|
|
13
|
+
* Supports: --namespace <private|public|all>
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseArgs(args: string[]): McpConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Validate required environment variables.
|
|
18
|
+
* Throws with descriptive error if SKILL_REGISTRY_API_KEY is not set.
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateEnv(): EnvConfig;
|
|
21
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,KAAK,CAAA;AAEpD,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;CACf;AAID;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAoBnD;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,SAAS,CASvC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration parsing and validation for MCP server
|
|
3
|
+
*/
|
|
4
|
+
const VALID_NAMESPACES = ['private', 'public', 'all'];
|
|
5
|
+
/**
|
|
6
|
+
* Parse command-line arguments for the MCP server.
|
|
7
|
+
* Supports: --namespace <private|public|all>
|
|
8
|
+
*/
|
|
9
|
+
export function parseArgs(args) {
|
|
10
|
+
let namespace = 'all';
|
|
11
|
+
for (let i = 0; i < args.length; i++) {
|
|
12
|
+
if (args[i] === '--namespace') {
|
|
13
|
+
const value = args[i + 1];
|
|
14
|
+
if (!value) {
|
|
15
|
+
throw new Error('--namespace requires a value');
|
|
16
|
+
}
|
|
17
|
+
if (!VALID_NAMESPACES.includes(value)) {
|
|
18
|
+
throw new Error(`Invalid namespace value: "${value}". Must be one of: ${VALID_NAMESPACES.join(', ')}`);
|
|
19
|
+
}
|
|
20
|
+
namespace = value;
|
|
21
|
+
i++; // skip the value
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return { namespace };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate required environment variables.
|
|
28
|
+
* Throws with descriptive error if SKILL_REGISTRY_API_KEY is not set.
|
|
29
|
+
*/
|
|
30
|
+
export function validateEnv() {
|
|
31
|
+
const apiKey = process.env.SKILL_REGISTRY_API_KEY;
|
|
32
|
+
if (!apiKey) {
|
|
33
|
+
throw new Error('SKILL_REGISTRY_API_KEY environment variable is required but not set. ' +
|
|
34
|
+
'Please set it before starting the MCP server.');
|
|
35
|
+
}
|
|
36
|
+
return { apiKey };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,gBAAgB,GAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;AAElE;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,IAAI,SAAS,GAAc,KAAK,CAAA;IAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YACzB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;YACjD,CAAC;YACD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAkB,CAAC,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CACb,6BAA6B,KAAK,sBAAsB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtF,CAAA;YACH,CAAC;YACD,SAAS,GAAG,KAAkB,CAAA;YAC9B,CAAC,EAAE,CAAA,CAAC,iBAAiB;QACvB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,CAAA;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAA;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,uEAAuE;YACvE,+CAA+C,CAChD,CAAA;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAA;AACnB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @skill-registry/mcp - MCP Server entry point
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* skill-registry-mcp --namespace <private|public|all>
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* SKILL_REGISTRY_API_KEY (required) API key for Skill Registry
|
|
10
|
+
* SKILL_REGISTRY_BASE_URL (optional) Base URL, defaults to https://api.skill-registry.dev
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @skill-registry/mcp - MCP Server entry point
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* skill-registry-mcp --namespace <private|public|all>
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* SKILL_REGISTRY_API_KEY (required) API key for Skill Registry
|
|
10
|
+
* SKILL_REGISTRY_BASE_URL (optional) Base URL, defaults to https://api.skill-registry.dev
|
|
11
|
+
*/
|
|
12
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
13
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { appendFileSync } from 'node:fs';
|
|
16
|
+
import { parseArgs, validateEnv } from './config.js';
|
|
17
|
+
import { createSkillRegistryClient } from './client.js';
|
|
18
|
+
import { FIND_SKILL_DESCRIPTION, LIST_BUNDLES_DESCRIPTION, SUBMIT_FEEDBACK_DESCRIPTION, } from './tools.js';
|
|
19
|
+
const LOG_FILE = '/tmp/skill-registry-mcp.log';
|
|
20
|
+
function log(msg) {
|
|
21
|
+
appendFileSync(LOG_FILE, `[${new Date().toISOString()}] ${msg}\n`);
|
|
22
|
+
}
|
|
23
|
+
async function main() {
|
|
24
|
+
// Validate required env vars (will throw and exit if missing)
|
|
25
|
+
let envConfig;
|
|
26
|
+
try {
|
|
27
|
+
envConfig = validateEnv();
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.error(`[skill-registry-mcp] Error: ${String(err)}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
// Parse CLI args
|
|
34
|
+
let mcpConfig;
|
|
35
|
+
try {
|
|
36
|
+
mcpConfig = parseArgs(process.argv.slice(2));
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.error(`[skill-registry-mcp] Error: ${String(err)}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const baseUrl = process.env.SKILL_REGISTRY_BASE_URL ?? 'https://api.skill-registry.dev';
|
|
43
|
+
// Create API client (with session-level dedup)
|
|
44
|
+
const client = createSkillRegistryClient({
|
|
45
|
+
apiKey: envConfig.apiKey,
|
|
46
|
+
baseUrl,
|
|
47
|
+
namespace: mcpConfig.namespace,
|
|
48
|
+
});
|
|
49
|
+
// Create MCP server
|
|
50
|
+
const server = new McpServer({
|
|
51
|
+
name: 'skill-registry',
|
|
52
|
+
version: '0.0.1',
|
|
53
|
+
}, {
|
|
54
|
+
instructions: '你是一个有技能库加持的编程助手。' +
|
|
55
|
+
'当用户要求实现功能、修复 bug、重构代码或执行编码任务时,' +
|
|
56
|
+
'先调用 find_skill 搜索是否有可复用的 skill,按返回的 AGENT.md 执行任务。' +
|
|
57
|
+
'任务完成后调用 submit_feedback 提交反馈。' +
|
|
58
|
+
'如果 find_skill 无匹配结果,正常编码即可。',
|
|
59
|
+
});
|
|
60
|
+
// Register find_skill tool
|
|
61
|
+
server.tool('find_skill', FIND_SKILL_DESCRIPTION, {
|
|
62
|
+
query: z.string().describe('搜索查询文本,描述你需要的 skill 功能(最多 1000 字符)'),
|
|
63
|
+
bundle_id: z.string().optional().describe('(可选)限定在指定 bundle 中搜索'),
|
|
64
|
+
}, async ({ query, bundle_id }) => {
|
|
65
|
+
log(`find_skill called | query="${query}" bundle_id=${bundle_id ?? 'none'}`);
|
|
66
|
+
const result = await client.findSkill({ query, bundle_id });
|
|
67
|
+
log(`find_skill result | length=${result.length}`);
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: 'text', text: result }],
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
// Register list_bundles tool
|
|
73
|
+
server.tool('list_bundles', LIST_BUNDLES_DESCRIPTION, {}, async () => {
|
|
74
|
+
log('list_bundles called');
|
|
75
|
+
const result = await client.listBundles();
|
|
76
|
+
log(`list_bundles result | length=${result.length}`);
|
|
77
|
+
return {
|
|
78
|
+
content: [{ type: 'text', text: result }],
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
// Register submit_feedback tool
|
|
82
|
+
server.tool('submit_feedback', SUBMIT_FEEDBACK_DESCRIPTION, {
|
|
83
|
+
match_id: z.string().describe('find_skill 返回的 match_id(UUID)'),
|
|
84
|
+
skill_id: z.string().describe('使用的 skill ID'),
|
|
85
|
+
result: z.enum(['success', 'failure', 'partial']).describe('执行结果:success、failure 或 partial'),
|
|
86
|
+
score: z.number().int().min(1).max(3).describe('有用程度评分:1(无帮助)、2(一般)、3(非常有帮助)'),
|
|
87
|
+
}, async ({ match_id, skill_id, result, score }) => {
|
|
88
|
+
log(`submit_feedback called | match_id=${match_id} skill_id=${skill_id} result=${result} score=${score}`);
|
|
89
|
+
const text = await client.submitFeedback({ match_id, skill_id, result, score });
|
|
90
|
+
log(`submit_feedback done`);
|
|
91
|
+
return {
|
|
92
|
+
content: [{ type: 'text', text }],
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
// Start stdio transport
|
|
96
|
+
const transport = new StdioServerTransport();
|
|
97
|
+
await server.connect(transport);
|
|
98
|
+
log('MCP server started');
|
|
99
|
+
}
|
|
100
|
+
main().catch((err) => {
|
|
101
|
+
console.error('[skill-registry-mcp] Fatal error:', err);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|