@skillsmith/mcp-server 0.3.2 → 0.3.4
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 +5 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/__tests__/context.test.d.ts +10 -0
- package/dist/src/__tests__/context.test.d.ts.map +1 -0
- package/dist/src/__tests__/context.test.js +345 -0
- package/dist/src/__tests__/context.test.js.map +1 -0
- package/dist/src/__tests__/get-skill.test.d.ts +1 -0
- package/dist/src/__tests__/get-skill.test.d.ts.map +1 -1
- package/dist/src/__tests__/get-skill.test.js +84 -0
- package/dist/src/__tests__/get-skill.test.js.map +1 -1
- package/dist/src/__tests__/middleware/license.test.js +180 -78
- package/dist/src/__tests__/middleware/license.test.js.map +1 -1
- package/dist/src/__tests__/search.test.js +2 -1
- package/dist/src/__tests__/search.test.js.map +1 -1
- package/dist/src/__tests__/utils/validation.test.d.ts +7 -0
- package/dist/src/__tests__/utils/validation.test.d.ts.map +1 -0
- package/dist/src/__tests__/utils/validation.test.js +82 -0
- package/dist/src/__tests__/utils/validation.test.js.map +1 -0
- package/dist/src/context.d.ts +16 -0
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +57 -9
- package/dist/src/context.js.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/llm/failover.d.ts +200 -0
- package/dist/src/llm/failover.d.ts.map +1 -0
- package/dist/src/llm/failover.js +329 -0
- package/dist/src/llm/failover.js.map +1 -0
- package/dist/src/middleware/license.d.ts +5 -0
- package/dist/src/middleware/license.d.ts.map +1 -1
- package/dist/src/middleware/license.js +2 -1
- package/dist/src/middleware/license.js.map +1 -1
- package/dist/src/tools/compare.d.ts +3 -102
- package/dist/src/tools/compare.d.ts.map +1 -1
- package/dist/src/tools/compare.helpers.d.ts +36 -0
- package/dist/src/tools/compare.helpers.d.ts.map +1 -0
- package/dist/src/tools/compare.helpers.js +252 -0
- package/dist/src/tools/compare.helpers.js.map +1 -0
- package/dist/src/tools/compare.js +6 -288
- package/dist/src/tools/compare.js.map +1 -1
- package/dist/src/tools/compare.types.d.ts +133 -0
- package/dist/src/tools/compare.types.d.ts.map +1 -0
- package/dist/src/tools/compare.types.js +45 -0
- package/dist/src/tools/compare.types.js.map +1 -0
- package/dist/src/tools/get-skill.d.ts.map +1 -1
- package/dist/src/tools/get-skill.js +35 -2
- package/dist/src/tools/get-skill.js.map +1 -1
- package/dist/src/tools/install.d.ts +6 -60
- package/dist/src/tools/install.d.ts.map +1 -1
- package/dist/src/tools/install.helpers.d.ts +82 -0
- package/dist/src/tools/install.helpers.d.ts.map +1 -0
- package/dist/src/tools/install.helpers.js +324 -0
- package/dist/src/tools/install.helpers.js.map +1 -0
- package/dist/src/tools/install.js +176 -168
- package/dist/src/tools/install.js.map +1 -1
- package/dist/src/tools/install.types.d.ts +114 -0
- package/dist/src/tools/install.types.d.ts.map +1 -0
- package/dist/src/tools/install.types.js +91 -0
- package/dist/src/tools/install.types.js.map +1 -0
- package/dist/src/tools/recommend.d.ts +2 -148
- package/dist/src/tools/recommend.d.ts.map +1 -1
- package/dist/src/tools/recommend.helpers.d.ts +42 -0
- package/dist/src/tools/recommend.helpers.d.ts.map +1 -0
- package/dist/src/tools/recommend.helpers.js +155 -0
- package/dist/src/tools/recommend.helpers.js.map +1 -0
- package/dist/src/tools/recommend.js +75 -140
- package/dist/src/tools/recommend.js.map +1 -1
- package/dist/src/tools/recommend.types.d.ts +164 -0
- package/dist/src/tools/recommend.types.d.ts.map +1 -0
- package/dist/src/tools/recommend.types.js +87 -0
- package/dist/src/tools/recommend.types.js.map +1 -0
- package/dist/src/tools/search.d.ts +18 -4
- package/dist/src/tools/search.d.ts.map +1 -1
- package/dist/src/tools/search.js +64 -12
- package/dist/src/tools/search.js.map +1 -1
- package/dist/src/tools/validate.d.ts +3 -70
- package/dist/src/tools/validate.d.ts.map +1 -1
- package/dist/src/tools/validate.helpers.d.ts +22 -0
- package/dist/src/tools/validate.helpers.d.ts.map +1 -0
- package/dist/src/tools/validate.helpers.js +276 -0
- package/dist/src/tools/validate.helpers.js.map +1 -0
- package/dist/src/tools/validate.js +4 -337
- package/dist/src/tools/validate.js.map +1 -1
- package/dist/src/tools/validate.types.d.ts +96 -0
- package/dist/src/tools/validate.types.d.ts.map +1 -0
- package/dist/src/tools/validate.types.js +71 -0
- package/dist/src/tools/validate.types.js.map +1 -0
- package/dist/src/webhooks/index.d.ts +1 -0
- package/dist/src/webhooks/index.d.ts.map +1 -1
- package/dist/src/webhooks/index.js +2 -0
- package/dist/src/webhooks/index.js.map +1 -1
- package/dist/src/webhooks/stripe-webhook-endpoint.d.ts +68 -0
- package/dist/src/webhooks/stripe-webhook-endpoint.d.ts.map +1 -0
- package/dist/src/webhooks/stripe-webhook-endpoint.js +213 -0
- package/dist/src/webhooks/stripe-webhook-endpoint.js.map +1 -0
- package/dist/tests/integration/install.integration.test.js +273 -1
- package/dist/tests/integration/install.integration.test.js.map +1 -1
- package/dist/tests/integration/recommend.integration.test.js +2 -1
- package/dist/tests/integration/recommend.integration.test.js.map +1 -1
- package/dist/tests/llm/failover.test.d.ts +13 -0
- package/dist/tests/llm/failover.test.d.ts.map +1 -0
- package/dist/tests/llm/failover.test.js +250 -0
- package/dist/tests/llm/failover.test.js.map +1 -0
- package/dist/tests/recommend.test.js +133 -1
- package/dist/tests/recommend.test.js.map +1 -1
- package/dist/tests/tools.test.d.ts +1 -0
- package/dist/tests/tools.test.d.ts.map +1 -1
- package/dist/tests/tools.test.js +59 -1
- package/dist/tests/tools.test.js.map +1 -1
- package/dist/tests/unit/compare-helpers.test.d.ts +8 -0
- package/dist/tests/unit/compare-helpers.test.d.ts.map +1 -0
- package/dist/tests/unit/compare-helpers.test.js +224 -0
- package/dist/tests/unit/compare-helpers.test.js.map +1 -0
- package/dist/tests/unit/install-helpers.test.d.ts +8 -0
- package/dist/tests/unit/install-helpers.test.d.ts.map +1 -0
- package/dist/tests/unit/install-helpers.test.js +460 -0
- package/dist/tests/unit/install-helpers.test.js.map +1 -0
- package/dist/tests/unit/recommend-helpers.test.d.ts +8 -0
- package/dist/tests/unit/recommend-helpers.test.d.ts.map +1 -0
- package/dist/tests/unit/recommend-helpers.test.js +117 -0
- package/dist/tests/unit/recommend-helpers.test.js.map +1 -0
- package/dist/tests/unit/validate-helpers.test.d.ts +8 -0
- package/dist/tests/unit/validate-helpers.test.d.ts.map +1 -0
- package/dist/tests/unit/validate-helpers.test.js +243 -0
- package/dist/tests/unit/validate-helpers.test.js.map +1 -0
- package/package.json +1 -1
- package/src/assets/docs/USER_GUIDE.md +0 -192
- package/src/assets/skills/skillsmith/docs/QUOTAS.md +0 -182
- package/src/assets/skills/skillsmith/docs/SECURITY.md +0 -174
- package/src/assets/skills/skillsmith/docs/TRUST_TIERS.md +0 -142
|
@@ -54,8 +54,18 @@ export declare const searchToolSchema: {
|
|
|
54
54
|
minimum: number;
|
|
55
55
|
maximum: number;
|
|
56
56
|
};
|
|
57
|
+
safe_only: {
|
|
58
|
+
type: string;
|
|
59
|
+
description: string;
|
|
60
|
+
};
|
|
61
|
+
max_risk: {
|
|
62
|
+
type: string;
|
|
63
|
+
description: string;
|
|
64
|
+
minimum: number;
|
|
65
|
+
maximum: number;
|
|
66
|
+
};
|
|
57
67
|
};
|
|
58
|
-
required:
|
|
68
|
+
required: never[];
|
|
59
69
|
};
|
|
60
70
|
};
|
|
61
71
|
/**
|
|
@@ -63,14 +73,18 @@ export declare const searchToolSchema: {
|
|
|
63
73
|
* @interface SearchInput
|
|
64
74
|
*/
|
|
65
75
|
export interface SearchInput {
|
|
66
|
-
/** Search query string (
|
|
67
|
-
query
|
|
76
|
+
/** Search query string (optional if filters provided) */
|
|
77
|
+
query?: string;
|
|
68
78
|
/** Filter by skill category */
|
|
69
79
|
category?: string;
|
|
70
80
|
/** Filter by trust tier level */
|
|
71
81
|
trust_tier?: string;
|
|
72
82
|
/** Minimum quality score (0-100) */
|
|
73
83
|
min_score?: number;
|
|
84
|
+
/** SMI-825: Only show skills that passed security scan */
|
|
85
|
+
safe_only?: boolean;
|
|
86
|
+
/** SMI-825: Maximum risk score (0-100, lower is safer) */
|
|
87
|
+
max_risk?: number;
|
|
74
88
|
}
|
|
75
89
|
/**
|
|
76
90
|
* Execute a search for Claude Code skills with optional filters.
|
|
@@ -82,7 +96,7 @@ export interface SearchInput {
|
|
|
82
96
|
* @param input - Search parameters including query and optional filters
|
|
83
97
|
* @param context - Tool context with API client and local services
|
|
84
98
|
* @returns Promise resolving to search response with results and timing
|
|
85
|
-
* @throws {SkillsmithError} When query
|
|
99
|
+
* @throws {SkillsmithError} When no query and no filters are provided
|
|
86
100
|
* @throws {SkillsmithError} When min_score is outside 0-100 range
|
|
87
101
|
*
|
|
88
102
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAGL,KAAK,iBAAiB,IAAI,cAAc,EAMzC,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAQhD;;GAEG;AACH,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAGL,KAAK,iBAAiB,IAAI,cAAc,EAMzC,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAQhD;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmD5B,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAkNzB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAgCpE"}
|
package/dist/src/tools/search.js
CHANGED
|
@@ -65,8 +65,19 @@ export const searchToolSchema = {
|
|
|
65
65
|
minimum: 0,
|
|
66
66
|
maximum: 100,
|
|
67
67
|
},
|
|
68
|
+
// SMI-825: Security filters
|
|
69
|
+
safe_only: {
|
|
70
|
+
type: 'boolean',
|
|
71
|
+
description: 'Only show skills that passed security scan',
|
|
72
|
+
},
|
|
73
|
+
max_risk: {
|
|
74
|
+
type: 'number',
|
|
75
|
+
description: 'Maximum risk score (0-100, lower is safer)',
|
|
76
|
+
minimum: 0,
|
|
77
|
+
maximum: 100,
|
|
78
|
+
},
|
|
68
79
|
},
|
|
69
|
-
required: [
|
|
80
|
+
required: [], // Query is optional if filters are provided
|
|
70
81
|
},
|
|
71
82
|
};
|
|
72
83
|
/**
|
|
@@ -79,7 +90,7 @@ export const searchToolSchema = {
|
|
|
79
90
|
* @param input - Search parameters including query and optional filters
|
|
80
91
|
* @param context - Tool context with API client and local services
|
|
81
92
|
* @returns Promise resolving to search response with results and timing
|
|
82
|
-
* @throws {SkillsmithError} When query
|
|
93
|
+
* @throws {SkillsmithError} When no query and no filters are provided
|
|
83
94
|
* @throws {SkillsmithError} When min_score is outside 0-100 range
|
|
84
95
|
*
|
|
85
96
|
* @example
|
|
@@ -89,17 +100,31 @@ export const searchToolSchema = {
|
|
|
89
100
|
*/
|
|
90
101
|
export async function executeSearch(input, context) {
|
|
91
102
|
const startTime = performance.now();
|
|
92
|
-
// Validate query
|
|
93
|
-
|
|
94
|
-
|
|
103
|
+
// Validate: require query OR at least one filter
|
|
104
|
+
const hasQuery = input.query && input.query.trim().length > 0;
|
|
105
|
+
const hasFilters = input.category ||
|
|
106
|
+
input.trust_tier ||
|
|
107
|
+
input.min_score !== undefined ||
|
|
108
|
+
input.safe_only !== undefined ||
|
|
109
|
+
input.max_risk !== undefined;
|
|
110
|
+
if (!hasQuery && !hasFilters) {
|
|
111
|
+
throw new SkillsmithError(ErrorCodes.SEARCH_QUERY_EMPTY, 'Provide a search query or at least one filter (category, trust_tier, min_score, safe_only, max_risk)');
|
|
112
|
+
}
|
|
113
|
+
// SMI-1613: Anti-scraping - require minimum 3 chars when query IS provided
|
|
114
|
+
if (hasQuery && input.query.trim().length < 3) {
|
|
115
|
+
throw new SkillsmithError(ErrorCodes.SEARCH_QUERY_EMPTY, 'Query must be at least 3 characters. Use specific search terms like "testing", "git", or "docker".');
|
|
95
116
|
}
|
|
96
117
|
const filters = {};
|
|
97
118
|
// Apply category filter
|
|
98
119
|
if (input.category) {
|
|
99
120
|
filters.category = input.category;
|
|
100
121
|
}
|
|
101
|
-
// Apply trust tier filter
|
|
122
|
+
// Apply trust tier filter with runtime validation
|
|
123
|
+
const VALID_TRUST_TIERS = ['verified', 'community', 'experimental', 'unknown'];
|
|
102
124
|
if (input.trust_tier) {
|
|
125
|
+
if (!VALID_TRUST_TIERS.includes(input.trust_tier)) {
|
|
126
|
+
throw new SkillsmithError(ErrorCodes.VALIDATION_INVALID_TYPE, `Invalid trust_tier: ${input.trust_tier}. Must be one of: ${VALID_TRUST_TIERS.join(', ')}`, { details: { trust_tier: input.trust_tier, allowed: VALID_TRUST_TIERS } });
|
|
127
|
+
}
|
|
103
128
|
filters.trustTier = input.trust_tier;
|
|
104
129
|
}
|
|
105
130
|
// Apply minimum score filter (convert 0-100 to 0-1 for database)
|
|
@@ -109,12 +134,22 @@ export async function executeSearch(input, context) {
|
|
|
109
134
|
}
|
|
110
135
|
filters.minScore = input.min_score / 100; // Convert to 0-1 scale for DB
|
|
111
136
|
}
|
|
137
|
+
// SMI-825: Apply security filters
|
|
138
|
+
if (input.safe_only !== undefined) {
|
|
139
|
+
filters.safeOnly = input.safe_only;
|
|
140
|
+
}
|
|
141
|
+
if (input.max_risk !== undefined) {
|
|
142
|
+
if (input.max_risk < 0 || input.max_risk > 100) {
|
|
143
|
+
throw new SkillsmithError(ErrorCodes.VALIDATION_OUT_OF_RANGE, 'max_risk must be between 0 and 100', { details: { max_risk: input.max_risk } });
|
|
144
|
+
}
|
|
145
|
+
filters.maxRiskScore = input.max_risk;
|
|
146
|
+
}
|
|
112
147
|
const searchStart = performance.now();
|
|
113
148
|
// SMI-1183: Try API first, fall back to local DB
|
|
114
149
|
if (!context.apiClient.isOffline()) {
|
|
115
150
|
try {
|
|
116
151
|
const apiResponse = await context.apiClient.search({
|
|
117
|
-
query: input.query.trim(),
|
|
152
|
+
query: hasQuery ? input.query.trim() : '',
|
|
118
153
|
limit: 10,
|
|
119
154
|
offset: 0,
|
|
120
155
|
trustTier: filters.trustTier ? mapTrustTierToDb(filters.trustTier) : undefined,
|
|
@@ -123,6 +158,7 @@ export async function executeSearch(input, context) {
|
|
|
123
158
|
});
|
|
124
159
|
const searchEnd = performance.now();
|
|
125
160
|
// Convert API results to SkillSearchResult format
|
|
161
|
+
// SMI-1491: Added repository field for transparency
|
|
126
162
|
const results = apiResponse.data.map((item) => ({
|
|
127
163
|
id: item.id,
|
|
128
164
|
name: item.name,
|
|
@@ -131,12 +167,13 @@ export async function executeSearch(input, context) {
|
|
|
131
167
|
category: extractCategoryFromTags(item.tags),
|
|
132
168
|
trustTier: mapTrustTierFromDb(item.trust_tier),
|
|
133
169
|
score: Math.round((item.quality_score ?? 0) * 100),
|
|
170
|
+
repository: item.repo_url || undefined,
|
|
134
171
|
}));
|
|
135
172
|
const endTime = performance.now();
|
|
136
173
|
const response = {
|
|
137
174
|
results,
|
|
138
175
|
total: apiResponse.meta?.total ?? results.length,
|
|
139
|
-
query: input.query,
|
|
176
|
+
query: input.query || '', // May be empty for filter-only searches
|
|
140
177
|
filters,
|
|
141
178
|
timing: {
|
|
142
179
|
searchMs: Math.round(searchEnd - searchStart),
|
|
@@ -145,7 +182,7 @@ export async function executeSearch(input, context) {
|
|
|
145
182
|
};
|
|
146
183
|
// SMI-1184: Track search event (silent on failure)
|
|
147
184
|
if (context.distinctId) {
|
|
148
|
-
trackSkillSearch(context.distinctId, input.query, response.total, response.timing.totalMs, {
|
|
185
|
+
trackSkillSearch(context.distinctId, input.query || '', response.total, response.timing.totalMs, {
|
|
149
186
|
trustTier: filters.trustTier,
|
|
150
187
|
category: filters.category,
|
|
151
188
|
});
|
|
@@ -159,16 +196,23 @@ export async function executeSearch(input, context) {
|
|
|
159
196
|
}
|
|
160
197
|
// Fallback: Use local SearchService for FTS5 search with BM25 ranking
|
|
161
198
|
const dbTrustTier = filters.trustTier ? mapTrustTierToDb(filters.trustTier) : undefined;
|
|
199
|
+
// Local search fallback - pass empty string if no query
|
|
200
|
+
const searchQuery = hasQuery ? input.query.trim() : '';
|
|
162
201
|
const searchResults = context.searchService.search({
|
|
163
|
-
query:
|
|
202
|
+
query: searchQuery,
|
|
164
203
|
limit: 10,
|
|
165
204
|
offset: 0,
|
|
166
205
|
trustTier: dbTrustTier,
|
|
167
206
|
minQualityScore: filters.minScore,
|
|
168
207
|
category: filters.category,
|
|
208
|
+
// SMI-825: Security filters
|
|
209
|
+
safeOnly: filters.safeOnly,
|
|
210
|
+
maxRiskScore: filters.maxRiskScore,
|
|
169
211
|
});
|
|
170
212
|
const searchEnd = performance.now();
|
|
171
213
|
// Convert SearchResult to SkillSearchResult format
|
|
214
|
+
// SMI-1491: Added repository field for transparency
|
|
215
|
+
// SMI-825: Added security summary
|
|
172
216
|
const results = searchResults.items.map((item) => ({
|
|
173
217
|
id: item.skill.id,
|
|
174
218
|
name: item.skill.name,
|
|
@@ -177,12 +221,20 @@ export async function executeSearch(input, context) {
|
|
|
177
221
|
category: extractCategoryFromTags(item.skill.tags),
|
|
178
222
|
trustTier: mapTrustTierFromDb(item.skill.trustTier),
|
|
179
223
|
score: Math.round((item.skill.qualityScore ?? 0) * 100), // Convert 0-1 to 0-100
|
|
224
|
+
repository: item.skill.repoUrl || undefined,
|
|
225
|
+
// SMI-825: Security summary
|
|
226
|
+
security: {
|
|
227
|
+
passed: item.skill.securityPassed,
|
|
228
|
+
riskScore: item.skill.riskScore,
|
|
229
|
+
findingsCount: item.skill.securityFindingsCount,
|
|
230
|
+
scannedAt: item.skill.securityScannedAt,
|
|
231
|
+
},
|
|
180
232
|
}));
|
|
181
233
|
const endTime = performance.now();
|
|
182
234
|
const response = {
|
|
183
235
|
results,
|
|
184
236
|
total: searchResults.total,
|
|
185
|
-
query: input.query,
|
|
237
|
+
query: input.query || '', // May be empty for filter-only searches
|
|
186
238
|
filters,
|
|
187
239
|
timing: {
|
|
188
240
|
searchMs: Math.round(searchEnd - searchStart),
|
|
@@ -191,7 +243,7 @@ export async function executeSearch(input, context) {
|
|
|
191
243
|
};
|
|
192
244
|
// SMI-1184: Track search event (silent on failure)
|
|
193
245
|
if (context.distinctId) {
|
|
194
|
-
trackSkillSearch(context.distinctId, input.query, response.total, response.timing.totalMs, {
|
|
246
|
+
trackSkillSearch(context.distinctId, input.query || '', response.total, response.timing.totalMs, {
|
|
195
247
|
trustTier: filters.trustTier,
|
|
196
248
|
category: filters.category,
|
|
197
249
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAML,eAAe,EACf,UAAU,EACV,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,GACd,MAAM,wBAAwB,CAAA;AAE/B;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,8DAA8D;IAC3E,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,iCAAiC;aAC/C;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0BAA0B;gBACvC,IAAI,EAAE;oBACJ,aAAa;oBACb,SAAS;oBACT,eAAe;oBACf,QAAQ;oBACR,UAAU;oBACV,UAAU;oBACV,cAAc;oBACd,aAAa;oBACb,OAAO;oBACP,OAAO;iBACR;aACF;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,4BAA4B;gBACzC,IAAI,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,CAAC;aAC3D;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,+BAA+B;gBAC5C,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,GAAG;aACb;
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,77 +22,10 @@
|
|
|
22
22
|
* strict: true
|
|
23
23
|
* });
|
|
24
24
|
*/
|
|
25
|
-
import { z } from 'zod';
|
|
26
25
|
import type { ToolContext } from '../context.js';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export declare const validateInputSchema: z.ZodObject<{
|
|
31
|
-
/** Path to SKILL.md file or skill directory */
|
|
32
|
-
skill_path: z.ZodString;
|
|
33
|
-
/** Enable strict validation (default false) */
|
|
34
|
-
strict: z.ZodDefault<z.ZodBoolean>;
|
|
35
|
-
}, "strip", z.ZodTypeAny, {
|
|
36
|
-
skill_path: string;
|
|
37
|
-
strict: boolean;
|
|
38
|
-
}, {
|
|
39
|
-
skill_path: string;
|
|
40
|
-
strict?: boolean | undefined;
|
|
41
|
-
}>;
|
|
42
|
-
/**
|
|
43
|
-
* Input type (before parsing, allows optional fields)
|
|
44
|
-
*/
|
|
45
|
-
export type ValidateInput = z.input<typeof validateInputSchema>;
|
|
46
|
-
/**
|
|
47
|
-
* Validation error with severity
|
|
48
|
-
*/
|
|
49
|
-
export interface ValidationError {
|
|
50
|
-
/** Field that has the error */
|
|
51
|
-
field: string;
|
|
52
|
-
/** Error message */
|
|
53
|
-
message: string;
|
|
54
|
-
/** Severity level */
|
|
55
|
-
severity: 'error' | 'warning';
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Validation response
|
|
59
|
-
*/
|
|
60
|
-
export interface ValidateResponse {
|
|
61
|
-
/** Whether the skill is valid */
|
|
62
|
-
valid: boolean;
|
|
63
|
-
/** List of validation errors/warnings */
|
|
64
|
-
errors: ValidationError[];
|
|
65
|
-
/** Parsed metadata if valid */
|
|
66
|
-
metadata: Record<string, unknown> | null;
|
|
67
|
-
/** File path validated */
|
|
68
|
-
path: string;
|
|
69
|
-
/** Performance timing */
|
|
70
|
-
timing: {
|
|
71
|
-
totalMs: number;
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* MCP tool schema definition for skill_validate
|
|
76
|
-
*/
|
|
77
|
-
export declare const validateToolSchema: {
|
|
78
|
-
name: string;
|
|
79
|
-
description: string;
|
|
80
|
-
inputSchema: {
|
|
81
|
-
type: "object";
|
|
82
|
-
properties: {
|
|
83
|
-
skill_path: {
|
|
84
|
-
type: string;
|
|
85
|
-
description: string;
|
|
86
|
-
};
|
|
87
|
-
strict: {
|
|
88
|
-
type: string;
|
|
89
|
-
description: string;
|
|
90
|
-
default: boolean;
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
required: string[];
|
|
94
|
-
};
|
|
95
|
-
};
|
|
26
|
+
import type { ValidateInput, ValidateResponse } from './validate.types.js';
|
|
27
|
+
export type { ValidateInput, ValidateResponse, ValidationError } from './validate.types.js';
|
|
28
|
+
export { validateInputSchema, validateToolSchema } from './validate.types.js';
|
|
96
29
|
/**
|
|
97
30
|
* Execute skill validation.
|
|
98
31
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/tools/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/tools/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAGhD,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAmB,MAAM,qBAAqB,CAAA;AAO3F,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC3F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE7E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAyE3B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAqD1E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate Tool Helper Functions
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/validate.helpers
|
|
4
|
+
*/
|
|
5
|
+
import type { ValidationError } from './validate.types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Parse YAML frontmatter from markdown content
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseYamlFrontmatter(content: string): Record<string, unknown> | null;
|
|
10
|
+
/**
|
|
11
|
+
* Check for SSRF patterns in a URL
|
|
12
|
+
*/
|
|
13
|
+
export declare function hasSsrfPattern(url: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check for path traversal patterns
|
|
16
|
+
*/
|
|
17
|
+
export declare function hasPathTraversal(path: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Validate skill metadata
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateMetadata(metadata: Record<string, unknown>, strict: boolean): ValidationError[];
|
|
22
|
+
//# sourceMappingURL=validate.helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.helpers.d.ts","sourceRoot":"","sources":["../../../src/tools/validate.helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAG1D;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAqFpF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,MAAM,EAAE,OAAO,GACd,eAAe,EAAE,CA4KnB"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate Tool Helper Functions
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/validate.helpers
|
|
4
|
+
*/
|
|
5
|
+
import { FIELD_LIMITS, SSRF_PATTERNS, PATH_TRAVERSAL_PATTERNS } from './validate.types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Parse YAML frontmatter from markdown content
|
|
8
|
+
*/
|
|
9
|
+
export function parseYamlFrontmatter(content) {
|
|
10
|
+
const trimmed = content.trim();
|
|
11
|
+
if (!trimmed.startsWith('---')) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const endIndex = trimmed.indexOf('---', 3);
|
|
15
|
+
if (endIndex === -1) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const yamlContent = trimmed.slice(3, endIndex).trim();
|
|
19
|
+
const result = {};
|
|
20
|
+
const lines = yamlContent.split('\n');
|
|
21
|
+
let currentKey = null;
|
|
22
|
+
let arrayBuffer = [];
|
|
23
|
+
let inArray = false;
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
const trimmedLine = line.trim();
|
|
26
|
+
if (!trimmedLine || trimmedLine.startsWith('#')) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (trimmedLine.startsWith('- ')) {
|
|
30
|
+
if (currentKey && inArray) {
|
|
31
|
+
const value = trimmedLine
|
|
32
|
+
.slice(2)
|
|
33
|
+
.trim()
|
|
34
|
+
.replace(/^["']|["']$/g, '');
|
|
35
|
+
arrayBuffer.push(value);
|
|
36
|
+
}
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const colonIndex = trimmedLine.indexOf(':');
|
|
40
|
+
if (colonIndex > 0) {
|
|
41
|
+
if (currentKey && inArray && arrayBuffer.length > 0) {
|
|
42
|
+
result[currentKey] = arrayBuffer;
|
|
43
|
+
arrayBuffer = [];
|
|
44
|
+
}
|
|
45
|
+
const key = trimmedLine.slice(0, colonIndex).trim();
|
|
46
|
+
const value = trimmedLine.slice(colonIndex + 1).trim();
|
|
47
|
+
if (value === '' || value === '|' || value === '>') {
|
|
48
|
+
currentKey = key;
|
|
49
|
+
inArray = true;
|
|
50
|
+
arrayBuffer = [];
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
currentKey = null;
|
|
54
|
+
inArray = false;
|
|
55
|
+
let parsedValue = value;
|
|
56
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
57
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
58
|
+
parsedValue = value.slice(1, -1);
|
|
59
|
+
}
|
|
60
|
+
else if (value === 'true') {
|
|
61
|
+
parsedValue = true;
|
|
62
|
+
}
|
|
63
|
+
else if (value === 'false') {
|
|
64
|
+
parsedValue = false;
|
|
65
|
+
}
|
|
66
|
+
else if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
67
|
+
parsedValue = parseFloat(value);
|
|
68
|
+
}
|
|
69
|
+
else if (value.startsWith('[') && value.endsWith(']')) {
|
|
70
|
+
parsedValue = value
|
|
71
|
+
.slice(1, -1)
|
|
72
|
+
.split(',')
|
|
73
|
+
.map((item) => item.trim().replace(/^["']|["']$/g, ''))
|
|
74
|
+
.filter((item) => item.length > 0);
|
|
75
|
+
}
|
|
76
|
+
result[key] = parsedValue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (currentKey && inArray && arrayBuffer.length > 0) {
|
|
81
|
+
result[currentKey] = arrayBuffer;
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check for SSRF patterns in a URL
|
|
87
|
+
*/
|
|
88
|
+
export function hasSsrfPattern(url) {
|
|
89
|
+
return SSRF_PATTERNS.some((pattern) => pattern.test(url));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check for path traversal patterns
|
|
93
|
+
*/
|
|
94
|
+
export function hasPathTraversal(path) {
|
|
95
|
+
return PATH_TRAVERSAL_PATTERNS.some((pattern) => pattern.test(path));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Validate skill metadata
|
|
99
|
+
*/
|
|
100
|
+
export function validateMetadata(metadata, strict) {
|
|
101
|
+
const errors = [];
|
|
102
|
+
// Required fields - name
|
|
103
|
+
if (!metadata.name) {
|
|
104
|
+
errors.push({
|
|
105
|
+
field: 'name',
|
|
106
|
+
message: 'Required field "name" is missing',
|
|
107
|
+
severity: 'error',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else if (typeof metadata.name !== 'string') {
|
|
111
|
+
errors.push({
|
|
112
|
+
field: 'name',
|
|
113
|
+
message: 'Field "name" must be a string',
|
|
114
|
+
severity: 'error',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
else if (metadata.name.length > FIELD_LIMITS.name) {
|
|
118
|
+
errors.push({
|
|
119
|
+
field: 'name',
|
|
120
|
+
message: `Field "name" exceeds maximum length of ${FIELD_LIMITS.name} characters`,
|
|
121
|
+
severity: 'error',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// Description validation
|
|
125
|
+
if (!metadata.description) {
|
|
126
|
+
errors.push({
|
|
127
|
+
field: 'description',
|
|
128
|
+
message: 'Required field "description" is missing',
|
|
129
|
+
severity: strict ? 'error' : 'warning',
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
else if (typeof metadata.description !== 'string') {
|
|
133
|
+
errors.push({
|
|
134
|
+
field: 'description',
|
|
135
|
+
message: 'Field "description" must be a string',
|
|
136
|
+
severity: 'error',
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else if (metadata.description.length > FIELD_LIMITS.description) {
|
|
140
|
+
errors.push({
|
|
141
|
+
field: 'description',
|
|
142
|
+
message: `Field "description" exceeds maximum length of ${FIELD_LIMITS.description} characters`,
|
|
143
|
+
severity: 'error',
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// Author validation
|
|
147
|
+
if (metadata.author !== undefined) {
|
|
148
|
+
if (typeof metadata.author !== 'string') {
|
|
149
|
+
errors.push({
|
|
150
|
+
field: 'author',
|
|
151
|
+
message: 'Field "author" must be a string',
|
|
152
|
+
severity: 'error',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else if (metadata.author.length > FIELD_LIMITS.author) {
|
|
156
|
+
errors.push({
|
|
157
|
+
field: 'author',
|
|
158
|
+
message: `Field "author" exceeds maximum length of ${FIELD_LIMITS.author} characters`,
|
|
159
|
+
severity: 'error',
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Version validation
|
|
164
|
+
if (metadata.version !== undefined) {
|
|
165
|
+
if (typeof metadata.version !== 'string') {
|
|
166
|
+
errors.push({
|
|
167
|
+
field: 'version',
|
|
168
|
+
message: 'Field "version" must be a string',
|
|
169
|
+
severity: 'error',
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
else if (metadata.version.length > FIELD_LIMITS.version) {
|
|
173
|
+
errors.push({
|
|
174
|
+
field: 'version',
|
|
175
|
+
message: `Field "version" exceeds maximum length of ${FIELD_LIMITS.version} characters`,
|
|
176
|
+
severity: 'error',
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else if (strict) {
|
|
181
|
+
errors.push({
|
|
182
|
+
field: 'version',
|
|
183
|
+
message: 'Field "version" is recommended',
|
|
184
|
+
severity: 'warning',
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// Tags validation
|
|
188
|
+
if (metadata.tags !== undefined) {
|
|
189
|
+
if (!Array.isArray(metadata.tags)) {
|
|
190
|
+
errors.push({
|
|
191
|
+
field: 'tags',
|
|
192
|
+
message: 'Field "tags" must be an array',
|
|
193
|
+
severity: 'error',
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
if (metadata.tags.length > FIELD_LIMITS.maxTags) {
|
|
198
|
+
errors.push({
|
|
199
|
+
field: 'tags',
|
|
200
|
+
message: `Field "tags" exceeds maximum count of ${FIELD_LIMITS.maxTags}`,
|
|
201
|
+
severity: 'error',
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
for (let i = 0; i < metadata.tags.length; i++) {
|
|
205
|
+
const tag = metadata.tags[i];
|
|
206
|
+
if (typeof tag !== 'string') {
|
|
207
|
+
errors.push({
|
|
208
|
+
field: `tags[${i}]`,
|
|
209
|
+
message: 'Tag must be a string',
|
|
210
|
+
severity: 'error',
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
else if (tag.length > FIELD_LIMITS.tagLength) {
|
|
214
|
+
errors.push({
|
|
215
|
+
field: `tags[${i}]`,
|
|
216
|
+
message: `Tag exceeds maximum length of ${FIELD_LIMITS.tagLength} characters`,
|
|
217
|
+
severity: 'error',
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (strict) {
|
|
224
|
+
errors.push({
|
|
225
|
+
field: 'tags',
|
|
226
|
+
message: 'Field "tags" is recommended for discoverability',
|
|
227
|
+
severity: 'warning',
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// Security: Check repository URL for SSRF
|
|
231
|
+
if (metadata.repository !== undefined) {
|
|
232
|
+
if (typeof metadata.repository !== 'string') {
|
|
233
|
+
errors.push({
|
|
234
|
+
field: 'repository',
|
|
235
|
+
message: 'Field "repository" must be a string',
|
|
236
|
+
severity: 'error',
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
else if (hasSsrfPattern(metadata.repository)) {
|
|
240
|
+
errors.push({
|
|
241
|
+
field: 'repository',
|
|
242
|
+
message: 'Field "repository" contains potentially dangerous URL pattern',
|
|
243
|
+
severity: 'error',
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Security: Check homepage URL for SSRF
|
|
248
|
+
if (metadata.homepage !== undefined) {
|
|
249
|
+
if (typeof metadata.homepage !== 'string') {
|
|
250
|
+
errors.push({
|
|
251
|
+
field: 'homepage',
|
|
252
|
+
message: 'Field "homepage" must be a string',
|
|
253
|
+
severity: 'error',
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
else if (hasSsrfPattern(metadata.homepage)) {
|
|
257
|
+
errors.push({
|
|
258
|
+
field: 'homepage',
|
|
259
|
+
message: 'Field "homepage" contains potentially dangerous URL pattern',
|
|
260
|
+
severity: 'error',
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Security: Check for path traversal in any string fields
|
|
265
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
266
|
+
if (typeof value === 'string' && hasPathTraversal(value)) {
|
|
267
|
+
errors.push({
|
|
268
|
+
field: key,
|
|
269
|
+
message: `Field "${key}" contains path traversal pattern`,
|
|
270
|
+
severity: 'error',
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return errors;
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=validate.helpers.js.map
|