@skillsmith/mcp-server 0.3.3 → 0.3.5
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__/LocalIndexer.test.d.ts +5 -0
- package/dist/src/__tests__/LocalIndexer.test.d.ts.map +1 -0
- package/dist/src/__tests__/LocalIndexer.test.js +396 -0
- package/dist/src/__tests__/LocalIndexer.test.js.map +1 -0
- 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 +279 -0
- package/dist/src/__tests__/get-skill.test.js.map +1 -1
- package/dist/src/__tests__/index-local.test.d.ts +5 -0
- package/dist/src/__tests__/index-local.test.d.ts.map +1 -0
- package/dist/src/__tests__/index-local.test.js +203 -0
- package/dist/src/__tests__/index-local.test.js.map +1 -0
- 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__/recommend.test.d.ts +7 -0
- package/dist/src/__tests__/recommend.test.d.ts.map +1 -0
- package/dist/src/__tests__/recommend.test.js +277 -0
- package/dist/src/__tests__/recommend.test.js.map +1 -0
- package/dist/src/__tests__/search.test.js +140 -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 +22 -0
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +63 -9
- package/dist/src/context.js.map +1 -1
- package/dist/src/index.js +15 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexer/FrontmatterParser.d.ts +30 -0
- package/dist/src/indexer/FrontmatterParser.d.ts.map +1 -0
- package/dist/src/indexer/FrontmatterParser.js +109 -0
- package/dist/src/indexer/FrontmatterParser.js.map +1 -0
- package/dist/src/indexer/LocalIndexer.d.ts +136 -0
- package/dist/src/indexer/LocalIndexer.d.ts.map +1 -0
- package/dist/src/indexer/LocalIndexer.js +271 -0
- package/dist/src/indexer/LocalIndexer.js.map +1 -0
- package/dist/src/indexer/index.d.ts +8 -0
- package/dist/src/indexer/index.d.ts.map +1 -0
- package/dist/src/indexer/index.js +8 -0
- package/dist/src/indexer/index.js.map +1 -0
- package/dist/src/llm/failover.d.ts +210 -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/errorFormatter.d.ts +27 -0
- package/dist/src/middleware/errorFormatter.d.ts.map +1 -1
- package/dist/src/middleware/errorFormatter.js +95 -0
- package/dist/src/middleware/errorFormatter.js.map +1 -1
- package/dist/src/middleware/index.d.ts +1 -1
- package/dist/src/middleware/index.d.ts.map +1 -1
- package/dist/src/middleware/index.js.map +1 -1
- 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/middleware/quota-helpers.d.ts +40 -0
- package/dist/src/middleware/quota-helpers.d.ts.map +1 -0
- package/dist/src/middleware/quota-helpers.js +90 -0
- package/dist/src/middleware/quota-helpers.js.map +1 -0
- package/dist/src/middleware/quota-types.d.ts +105 -0
- package/dist/src/middleware/quota-types.d.ts.map +1 -0
- package/dist/src/middleware/quota-types.js +4 -0
- package/dist/src/middleware/quota-types.js.map +1 -0
- package/dist/src/middleware/quota.d.ts +3 -97
- package/dist/src/middleware/quota.d.ts.map +1 -1
- package/dist/src/middleware/quota.js +2 -87
- package/dist/src/middleware/quota.js.map +1 -1
- package/dist/src/tools/LocalSkillSearch.d.ts +32 -0
- package/dist/src/tools/LocalSkillSearch.d.ts.map +1 -0
- package/dist/src/tools/LocalSkillSearch.js +74 -0
- package/dist/src/tools/LocalSkillSearch.js.map +1 -0
- 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 +134 -0
- package/dist/src/tools/compare.types.d.ts.map +1 -0
- package/dist/src/tools/compare.types.js +47 -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 +38 -2
- package/dist/src/tools/get-skill.js.map +1 -1
- package/dist/src/tools/index-local.d.ts +117 -0
- package/dist/src/tools/index-local.d.ts.map +1 -0
- package/dist/src/tools/index-local.js +126 -0
- package/dist/src/tools/index-local.js.map +1 -0
- package/dist/src/tools/index.d.ts +2 -0
- package/dist/src/tools/index.d.ts.map +1 -1
- package/dist/src/tools/index.js +2 -0
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/install.conflict-helpers.d.ts +64 -0
- package/dist/src/tools/install.conflict-helpers.d.ts.map +1 -0
- package/dist/src/tools/install.conflict-helpers.js +165 -0
- package/dist/src/tools/install.conflict-helpers.js.map +1 -0
- package/dist/src/tools/install.conflict-helpers.test.d.ts +15 -0
- package/dist/src/tools/install.conflict-helpers.test.d.ts.map +1 -0
- package/dist/src/tools/install.conflict-helpers.test.js +243 -0
- package/dist/src/tools/install.conflict-helpers.test.js.map +1 -0
- package/dist/src/tools/install.conflict.d.ts +58 -0
- package/dist/src/tools/install.conflict.d.ts.map +1 -0
- package/dist/src/tools/install.conflict.js +160 -0
- package/dist/src/tools/install.conflict.js.map +1 -0
- package/dist/src/tools/install.conflict.test.d.ts +15 -0
- package/dist/src/tools/install.conflict.test.d.ts.map +1 -0
- package/dist/src/tools/install.conflict.test.js +354 -0
- package/dist/src/tools/install.conflict.test.js.map +1 -0
- package/dist/src/tools/install.d.ts +11 -60
- package/dist/src/tools/install.d.ts.map +1 -1
- package/dist/src/tools/install.helpers.d.ts +83 -0
- package/dist/src/tools/install.helpers.d.ts.map +1 -0
- package/dist/src/tools/install.helpers.js +333 -0
- package/dist/src/tools/install.helpers.js.map +1 -0
- package/dist/src/tools/install.js +199 -255
- package/dist/src/tools/install.js.map +1 -1
- package/dist/src/tools/install.types.d.ts +178 -0
- package/dist/src/tools/install.types.d.ts.map +1 -0
- package/dist/src/tools/install.types.js +105 -0
- package/dist/src/tools/install.types.js.map +1 -0
- package/dist/src/tools/merge.d.ts +53 -0
- package/dist/src/tools/merge.d.ts.map +1 -0
- package/dist/src/tools/merge.js +276 -0
- package/dist/src/tools/merge.js.map +1 -0
- package/dist/src/tools/merge.test.d.ts +11 -0
- package/dist/src/tools/merge.test.d.ts.map +1 -0
- package/dist/src/tools/merge.test.js +224 -0
- package/dist/src/tools/merge.test.js.map +1 -0
- package/dist/src/tools/recommend.d.ts +3 -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 +216 -154
- 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 +91 -16
- 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/utils/validation.d.ts +6 -2
- package/dist/src/utils/validation.d.ts.map +1 -1
- package/dist/src/utils/validation.js +11 -2
- package/dist/src/utils/validation.js.map +1 -1
- 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/src/webhooks/webhook-endpoint.d.ts +4 -49
- package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -1
- package/dist/src/webhooks/webhook-endpoint.js +3 -125
- package/dist/src/webhooks/webhook-endpoint.js.map +1 -1
- package/dist/src/webhooks/webhook-helpers.d.ts +69 -0
- package/dist/src/webhooks/webhook-helpers.d.ts.map +1 -0
- package/dist/src/webhooks/webhook-helpers.js +146 -0
- package/dist/src/webhooks/webhook-helpers.js.map +1 -0
- package/dist/tests/e2e/conflict-resolution.e2e.test.d.ts +12 -0
- package/dist/tests/e2e/conflict-resolution.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/conflict-resolution.e2e.test.js +343 -0
- package/dist/tests/e2e/conflict-resolution.e2e.test.js.map +1 -0
- package/dist/tests/integration/fixtures/development-skills.d.ts +22 -0
- package/dist/tests/integration/fixtures/development-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/development-skills.js +165 -0
- package/dist/tests/integration/fixtures/development-skills.js.map +1 -0
- package/dist/tests/integration/fixtures/devops-skills.d.ts +10 -0
- package/dist/tests/integration/fixtures/devops-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/devops-skills.js +70 -0
- package/dist/tests/integration/fixtures/devops-skills.js.map +1 -0
- package/dist/tests/integration/fixtures/experimental-skills.d.ts +14 -0
- package/dist/tests/integration/fixtures/experimental-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/experimental-skills.js +255 -0
- package/dist/tests/integration/fixtures/experimental-skills.js.map +1 -0
- package/dist/tests/integration/fixtures/skill-types.d.ts +18 -0
- package/dist/tests/integration/fixtures/skill-types.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/skill-types.js +6 -0
- package/dist/tests/integration/fixtures/skill-types.js.map +1 -0
- package/dist/tests/integration/fixtures/test-skills.d.ts +10 -14
- package/dist/tests/integration/fixtures/test-skills.d.ts.map +1 -1
- package/dist/tests/integration/fixtures/test-skills.js +23 -590
- package/dist/tests/integration/fixtures/test-skills.js.map +1 -1
- package/dist/tests/integration/fixtures/testing-skills.d.ts +10 -0
- package/dist/tests/integration/fixtures/testing-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/testing-skills.js +70 -0
- package/dist/tests/integration/fixtures/testing-skills.js.map +1 -0
- package/dist/tests/integration/fixtures/verified-skills.d.ts +11 -0
- package/dist/tests/integration/fixtures/verified-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/verified-skills.js +91 -0
- package/dist/tests/integration/fixtures/verified-skills.js.map +1 -0
- package/dist/tests/integration/install-conflict.integration.test.d.ts +8 -0
- package/dist/tests/integration/install-conflict.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/install-conflict.integration.test.js +384 -0
- package/dist/tests/integration/install-conflict.integration.test.js.map +1 -0
- package/dist/tests/integration/install-trust-parsing.integration.test.d.ts +13 -0
- package/dist/tests/integration/install-trust-parsing.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/install-trust-parsing.integration.test.js +290 -0
- package/dist/tests/integration/install-trust-parsing.integration.test.js.map +1 -0
- package/dist/tests/integration/install.integration.test.js +151 -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 +7 -6
- package/src/assets/docs/USER_GUIDE.md +0 -220
- 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
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for validate.helpers.ts
|
|
3
|
+
* @module @skillsmith/mcp-server/tests/unit/validate-helpers
|
|
4
|
+
*
|
|
5
|
+
* SMI-1719: Unit tests for extracted helper functions from Wave 3 refactor
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import { parseYamlFrontmatter, hasSsrfPattern, hasPathTraversal, validateMetadata, } from '../../src/tools/validate.helpers.js';
|
|
9
|
+
describe('validate.helpers', () => {
|
|
10
|
+
describe('parseYamlFrontmatter', () => {
|
|
11
|
+
it('parses simple key-value pairs', () => {
|
|
12
|
+
const content = `---
|
|
13
|
+
name: my-skill
|
|
14
|
+
description: A test skill
|
|
15
|
+
version: 1.0.0
|
|
16
|
+
---
|
|
17
|
+
# Content`;
|
|
18
|
+
const result = parseYamlFrontmatter(content);
|
|
19
|
+
expect(result).toEqual({
|
|
20
|
+
name: 'my-skill',
|
|
21
|
+
description: 'A test skill',
|
|
22
|
+
version: '1.0.0',
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
it('parses quoted strings', () => {
|
|
26
|
+
const content = `---
|
|
27
|
+
name: "my-skill"
|
|
28
|
+
description: 'A test skill'
|
|
29
|
+
---`;
|
|
30
|
+
const result = parseYamlFrontmatter(content);
|
|
31
|
+
expect(result?.name).toBe('my-skill');
|
|
32
|
+
expect(result?.description).toBe('A test skill');
|
|
33
|
+
});
|
|
34
|
+
it('parses boolean values', () => {
|
|
35
|
+
const content = `---
|
|
36
|
+
enabled: true
|
|
37
|
+
disabled: false
|
|
38
|
+
---`;
|
|
39
|
+
const result = parseYamlFrontmatter(content);
|
|
40
|
+
expect(result?.enabled).toBe(true);
|
|
41
|
+
expect(result?.disabled).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
it('parses numeric values', () => {
|
|
44
|
+
const content = `---
|
|
45
|
+
count: 42
|
|
46
|
+
score: 3.14
|
|
47
|
+
negative: -10
|
|
48
|
+
---`;
|
|
49
|
+
const result = parseYamlFrontmatter(content);
|
|
50
|
+
expect(result?.count).toBe(42);
|
|
51
|
+
expect(result?.score).toBe(3.14);
|
|
52
|
+
expect(result?.negative).toBe(-10);
|
|
53
|
+
});
|
|
54
|
+
it('parses inline arrays', () => {
|
|
55
|
+
const content = `---
|
|
56
|
+
tags: [typescript, testing, cli]
|
|
57
|
+
---`;
|
|
58
|
+
const result = parseYamlFrontmatter(content);
|
|
59
|
+
expect(result?.tags).toEqual(['typescript', 'testing', 'cli']);
|
|
60
|
+
});
|
|
61
|
+
it('parses multiline arrays', () => {
|
|
62
|
+
const content = `---
|
|
63
|
+
tags:
|
|
64
|
+
- typescript
|
|
65
|
+
- testing
|
|
66
|
+
- cli
|
|
67
|
+
---`;
|
|
68
|
+
const result = parseYamlFrontmatter(content);
|
|
69
|
+
expect(result?.tags).toEqual(['typescript', 'testing', 'cli']);
|
|
70
|
+
});
|
|
71
|
+
it('ignores comments', () => {
|
|
72
|
+
const content = `---
|
|
73
|
+
# This is a comment
|
|
74
|
+
name: my-skill
|
|
75
|
+
# Another comment
|
|
76
|
+
description: Test
|
|
77
|
+
---`;
|
|
78
|
+
const result = parseYamlFrontmatter(content);
|
|
79
|
+
expect(result).toEqual({
|
|
80
|
+
name: 'my-skill',
|
|
81
|
+
description: 'Test',
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
it('returns null for content without frontmatter', () => {
|
|
85
|
+
const content = '# Just markdown\n\nNo frontmatter here';
|
|
86
|
+
expect(parseYamlFrontmatter(content)).toBeNull();
|
|
87
|
+
});
|
|
88
|
+
it('returns null for truly unclosed frontmatter', () => {
|
|
89
|
+
// Note: The parser uses indexOf('---', 3) so any occurrence of --- will close it
|
|
90
|
+
// This test verifies truly unclosed frontmatter (no --- anywhere after the opening)
|
|
91
|
+
const content = `---
|
|
92
|
+
name: my-skill
|
|
93
|
+
description: Test
|
|
94
|
+
author: someone`;
|
|
95
|
+
expect(parseYamlFrontmatter(content)).toBeNull();
|
|
96
|
+
});
|
|
97
|
+
it('handles empty values', () => {
|
|
98
|
+
const content = `---
|
|
99
|
+
name: my-skill
|
|
100
|
+
tags:
|
|
101
|
+
---`;
|
|
102
|
+
const result = parseYamlFrontmatter(content);
|
|
103
|
+
expect(result?.name).toBe('my-skill');
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('hasSsrfPattern', () => {
|
|
107
|
+
it('detects file:// protocol', () => {
|
|
108
|
+
expect(hasSsrfPattern('file:///etc/passwd')).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
it('detects gopher:// protocol', () => {
|
|
111
|
+
expect(hasSsrfPattern('gopher://localhost')).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
it('detects localhost', () => {
|
|
114
|
+
expect(hasSsrfPattern('http://localhost/admin')).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
it('detects 127.0.0.x', () => {
|
|
117
|
+
expect(hasSsrfPattern('http://127.0.0.1/admin')).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
it('detects private IP 10.x.x.x', () => {
|
|
120
|
+
expect(hasSsrfPattern('http://10.0.0.1/internal')).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
// SMI-1723: Additional private IP ranges
|
|
123
|
+
it('detects private IP 192.168.x.x', () => {
|
|
124
|
+
expect(hasSsrfPattern('http://192.168.1.1/admin')).toBe(true);
|
|
125
|
+
expect(hasSsrfPattern('http://192.168.0.100/config')).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
it('detects cloud metadata service 169.254.x.x', () => {
|
|
128
|
+
// AWS/Azure/GCP metadata endpoints
|
|
129
|
+
expect(hasSsrfPattern('http://169.254.169.254/latest/meta-data/')).toBe(true);
|
|
130
|
+
expect(hasSsrfPattern('http://169.254.170.2/v2/credentials')).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
it('allows safe URLs', () => {
|
|
133
|
+
expect(hasSsrfPattern('https://github.com/user/repo')).toBe(false);
|
|
134
|
+
expect(hasSsrfPattern('https://example.com')).toBe(false);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
describe('hasPathTraversal', () => {
|
|
138
|
+
it('detects ../', () => {
|
|
139
|
+
expect(hasPathTraversal('../etc/passwd')).toBe(true);
|
|
140
|
+
});
|
|
141
|
+
it('detects encoded path traversal', () => {
|
|
142
|
+
expect(hasPathTraversal('%2e%2e/etc/passwd')).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
it('detects windows-style traversal', () => {
|
|
145
|
+
expect(hasPathTraversal('..\\windows\\system32')).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it('allows safe paths', () => {
|
|
148
|
+
expect(hasPathTraversal('/home/user/file.txt')).toBe(false);
|
|
149
|
+
expect(hasPathTraversal('src/index.ts')).toBe(false);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe('validateMetadata', () => {
|
|
153
|
+
it('validates valid metadata', () => {
|
|
154
|
+
const metadata = {
|
|
155
|
+
name: 'my-skill',
|
|
156
|
+
description: 'A test skill',
|
|
157
|
+
author: 'test-author',
|
|
158
|
+
version: '1.0.0',
|
|
159
|
+
tags: ['testing'],
|
|
160
|
+
};
|
|
161
|
+
const errors = validateMetadata(metadata, false);
|
|
162
|
+
expect(errors).toEqual([]);
|
|
163
|
+
});
|
|
164
|
+
it('requires name field', () => {
|
|
165
|
+
const metadata = { description: 'Test' };
|
|
166
|
+
const errors = validateMetadata(metadata, false);
|
|
167
|
+
expect(errors.some((e) => e.field === 'name' && e.severity === 'error')).toBe(true);
|
|
168
|
+
});
|
|
169
|
+
it('requires description in strict mode', () => {
|
|
170
|
+
const metadata = { name: 'my-skill' };
|
|
171
|
+
const strictErrors = validateMetadata(metadata, true);
|
|
172
|
+
const normalErrors = validateMetadata(metadata, false);
|
|
173
|
+
expect(strictErrors.some((e) => e.field === 'description' && e.severity === 'error')).toBe(true);
|
|
174
|
+
expect(normalErrors.some((e) => e.field === 'description' && e.severity === 'warning')).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
it('validates name type', () => {
|
|
177
|
+
const metadata = { name: 123, description: 'Test' };
|
|
178
|
+
const errors = validateMetadata(metadata, false);
|
|
179
|
+
expect(errors.some((e) => e.field === 'name' && e.message.includes('must be a string'))).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
it('validates name length', () => {
|
|
182
|
+
const metadata = { name: 'a'.repeat(100), description: 'Test' };
|
|
183
|
+
const errors = validateMetadata(metadata, false);
|
|
184
|
+
expect(errors.some((e) => e.field === 'name' && e.message.includes('exceeds maximum'))).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
it('validates tags array', () => {
|
|
187
|
+
const metadata = { name: 'test', description: 'Test', tags: 'not-an-array' };
|
|
188
|
+
const errors = validateMetadata(metadata, false);
|
|
189
|
+
expect(errors.some((e) => e.field === 'tags' && e.message.includes('must be an array'))).toBe(true);
|
|
190
|
+
});
|
|
191
|
+
it('validates tag count', () => {
|
|
192
|
+
const metadata = {
|
|
193
|
+
name: 'test',
|
|
194
|
+
description: 'Test',
|
|
195
|
+
tags: Array(25).fill('tag'),
|
|
196
|
+
};
|
|
197
|
+
const errors = validateMetadata(metadata, false);
|
|
198
|
+
expect(errors.some((e) => e.field === 'tags' && e.message.includes('exceeds maximum count'))).toBe(true);
|
|
199
|
+
});
|
|
200
|
+
it('validates individual tag type', () => {
|
|
201
|
+
const metadata = { name: 'test', description: 'Test', tags: [123, 'valid'] };
|
|
202
|
+
const errors = validateMetadata(metadata, false);
|
|
203
|
+
expect(errors.some((e) => e.field === 'tags[0]' && e.message.includes('must be a string'))).toBe(true);
|
|
204
|
+
});
|
|
205
|
+
it('detects SSRF in repository URL', () => {
|
|
206
|
+
const metadata = {
|
|
207
|
+
name: 'test',
|
|
208
|
+
description: 'Test',
|
|
209
|
+
repository: 'http://localhost/admin',
|
|
210
|
+
};
|
|
211
|
+
const errors = validateMetadata(metadata, false);
|
|
212
|
+
expect(errors.some((e) => e.field === 'repository' && e.message.includes('dangerous URL'))).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
it('detects SSRF in homepage URL', () => {
|
|
215
|
+
const metadata = {
|
|
216
|
+
name: 'test',
|
|
217
|
+
description: 'Test',
|
|
218
|
+
homepage: 'file:///etc/passwd',
|
|
219
|
+
};
|
|
220
|
+
const errors = validateMetadata(metadata, false);
|
|
221
|
+
expect(errors.some((e) => e.field === 'homepage' && e.message.includes('dangerous URL'))).toBe(true);
|
|
222
|
+
});
|
|
223
|
+
it('detects path traversal in any field', () => {
|
|
224
|
+
const metadata = {
|
|
225
|
+
name: 'test',
|
|
226
|
+
description: '../../../etc/passwd',
|
|
227
|
+
};
|
|
228
|
+
const errors = validateMetadata(metadata, false);
|
|
229
|
+
expect(errors.some((e) => e.field === 'description' && e.message.includes('path traversal'))).toBe(true);
|
|
230
|
+
});
|
|
231
|
+
it('recommends version in strict mode', () => {
|
|
232
|
+
const metadata = { name: 'test', description: 'Test' };
|
|
233
|
+
const errors = validateMetadata(metadata, true);
|
|
234
|
+
expect(errors.some((e) => e.field === 'version' && e.severity === 'warning')).toBe(true);
|
|
235
|
+
});
|
|
236
|
+
it('recommends tags in strict mode', () => {
|
|
237
|
+
const metadata = { name: 'test', description: 'Test' };
|
|
238
|
+
const errors = validateMetadata(metadata, true);
|
|
239
|
+
expect(errors.some((e) => e.field === 'tags' && e.message.includes('recommended'))).toBe(true);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
//# sourceMappingURL=validate-helpers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-helpers.test.js","sourceRoot":"","sources":["../../../tests/unit/validate-helpers.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillsmith/mcp-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "MCP server for Skillsmith skill discovery",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -9,21 +9,22 @@
|
|
|
9
9
|
"skillsmith-mcp": "./dist/src/index.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"prepublishOnly": "npm run build && npm run test",
|
|
12
|
+
"prepublishOnly": "npm run build && npm run test && chmod +x dist/src/index.js",
|
|
13
13
|
"build": "tsc",
|
|
14
|
+
"postbuild": "chmod +x dist/src/index.js || true",
|
|
14
15
|
"dev": "tsx watch src/index.ts",
|
|
15
|
-
"start": "node dist/index.js",
|
|
16
|
+
"start": "node dist/src/index.js",
|
|
16
17
|
"test": "vitest run",
|
|
17
18
|
"test:watch": "vitest",
|
|
18
19
|
"test:integration": "vitest run --config vitest.config.integration.ts"
|
|
19
20
|
},
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@modelcontextprotocol/sdk": "
|
|
22
|
-
"@skillsmith/core": "
|
|
22
|
+
"@modelcontextprotocol/sdk": "1.25.3",
|
|
23
|
+
"@skillsmith/core": "0.4.1",
|
|
23
24
|
"esbuild": "0.27.2"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
|
-
"tsx": "
|
|
27
|
+
"tsx": "4.21.0",
|
|
27
28
|
"vitest": "4.0.16",
|
|
28
29
|
"zod": "^3.25.0"
|
|
29
30
|
},
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
# Skillsmith User Guide
|
|
2
|
-
|
|
3
|
-
Welcome to Skillsmith, the skill discovery and management system for Claude Code.
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
### 1. Configure MCP Server
|
|
8
|
-
|
|
9
|
-
Add to `~/.claude/settings.json`:
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{
|
|
13
|
-
"mcpServers": {
|
|
14
|
-
"skillsmith": {
|
|
15
|
-
"command": "npx",
|
|
16
|
-
"args": ["-y", "@skillsmith/mcp-server"]
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### 2. Restart Claude Code
|
|
23
|
-
|
|
24
|
-
Close and reopen your Claude Code session.
|
|
25
|
-
|
|
26
|
-
### 3. Start Using
|
|
27
|
-
|
|
28
|
-
Ask Claude:
|
|
29
|
-
- "Search for testing skills"
|
|
30
|
-
- "Install the commit skill"
|
|
31
|
-
- "What skills do I have installed?"
|
|
32
|
-
|
|
33
|
-
## What Gets Installed
|
|
34
|
-
|
|
35
|
-
On first run, Skillsmith automatically installs essential skills:
|
|
36
|
-
|
|
37
|
-
| Skill | Purpose |
|
|
38
|
-
|-------|---------|
|
|
39
|
-
| **varlock** | Secure environment variable management |
|
|
40
|
-
| **commit** | Git commit message generation |
|
|
41
|
-
| **governance** | Code quality enforcement |
|
|
42
|
-
| **skill-builder** | Create custom skills |
|
|
43
|
-
| **skillsmith** | This documentation |
|
|
44
|
-
|
|
45
|
-
## Trust Tiers
|
|
46
|
-
|
|
47
|
-
Always check the trust tier before installing skills:
|
|
48
|
-
|
|
49
|
-
| Tier | Safety | Action |
|
|
50
|
-
|------|--------|--------|
|
|
51
|
-
| **Official** (Green) | Highest | Install freely |
|
|
52
|
-
| **Verified** (Blue) | High | Install freely |
|
|
53
|
-
| **Community** (Yellow) | Medium | Review first |
|
|
54
|
-
| **Unverified** (Red) | Unknown | Careful review |
|
|
55
|
-
|
|
56
|
-
### Quick Trust Check
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
"Show details for community/some-skill"
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Look for:
|
|
63
|
-
- Trust tier badge
|
|
64
|
-
- Quality score (aim for 70+)
|
|
65
|
-
- Number of stars
|
|
66
|
-
- Days since published
|
|
67
|
-
|
|
68
|
-
## Common Tasks
|
|
69
|
-
|
|
70
|
-
### Search for Skills
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
"Find testing skills"
|
|
74
|
-
"Search for devops skills with score above 80"
|
|
75
|
-
"Find verified git workflow skills"
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Install a Skill
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
"Install community/jest-helper"
|
|
82
|
-
"Install the commit skill"
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Compare Skills
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
"Compare jest-helper and vitest-helper"
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Get Recommendations
|
|
92
|
-
|
|
93
|
-
```
|
|
94
|
-
"Recommend skills for my React project"
|
|
95
|
-
"What skills would help with this codebase?"
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Create a Custom Skill
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
"Create a skill for generating changelogs"
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Quota Limits
|
|
105
|
-
|
|
106
|
-
| Tier | API Calls/Month | Price |
|
|
107
|
-
|------|-----------------|-------|
|
|
108
|
-
| Community | 1,000 | Free |
|
|
109
|
-
| Individual | 10,000 | $9.99/mo |
|
|
110
|
-
| Team | 100,000 | $25/user/mo |
|
|
111
|
-
| Enterprise | Unlimited | $55/user/mo |
|
|
112
|
-
|
|
113
|
-
Check your usage:
|
|
114
|
-
```
|
|
115
|
-
"What's my Skillsmith quota?"
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Upgrade at: https://skillsmith.app/upgrade
|
|
119
|
-
|
|
120
|
-
## Security Best Practices
|
|
121
|
-
|
|
122
|
-
1. **Prefer Verified or Official skills** for important projects
|
|
123
|
-
2. **Review Community skills** before installing
|
|
124
|
-
3. **Never install Unverified skills** without manual review
|
|
125
|
-
4. **Check the quality score** - aim for 70+
|
|
126
|
-
5. **Report suspicious skills** to security@skillsmith.app
|
|
127
|
-
|
|
128
|
-
## Data Sources
|
|
129
|
-
|
|
130
|
-
Skillsmith uses different data sources depending on context:
|
|
131
|
-
|
|
132
|
-
| Context | Data Source | Description |
|
|
133
|
-
|---------|-------------|-------------|
|
|
134
|
-
| **Production** | Supabase Registry | Live database with indexed skills from GitHub |
|
|
135
|
-
| **Development** | Local SQLite + Seed Data | Sample skills for testing |
|
|
136
|
-
|
|
137
|
-
### Live Registry (Production)
|
|
138
|
-
|
|
139
|
-
When you install `@skillsmith/mcp-server` via npx, it connects to the **live Supabase registry**. This registry is populated by:
|
|
140
|
-
|
|
141
|
-
1. **GitHub Indexer** - Automatically discovers skills with topics like `claude-code-skill`
|
|
142
|
-
2. **High-Trust Authors** - Pre-indexed skills from verified publishers (Anthropic, Hugging Face, Vercel)
|
|
143
|
-
3. **Community Submissions** - Skills submitted via the registry API
|
|
144
|
-
|
|
145
|
-
### Seed Data (Development Only)
|
|
146
|
-
|
|
147
|
-
The seed data in `packages/core/tests/fixtures/skills/seed-skills.json` is **only for local development and testing**. It is NOT the production registry.
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
# Development only - loads sample skills to local SQLite
|
|
151
|
-
npm run seed
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
> **Note**: If you're using Skillsmith normally (via npx), you don't need seed data. The MCP server connects directly to the live registry.
|
|
155
|
-
|
|
156
|
-
## Where Skills Are Installed
|
|
157
|
-
|
|
158
|
-
Skills install to: `~/.claude/skills/<skill-name>/`
|
|
159
|
-
|
|
160
|
-
Each skill contains:
|
|
161
|
-
- `SKILL.md` - Main skill file (Claude reads this)
|
|
162
|
-
- Optional: `docs/`, `scripts/`, `templates/`
|
|
163
|
-
|
|
164
|
-
## Troubleshooting
|
|
165
|
-
|
|
166
|
-
### "Skill not found"
|
|
167
|
-
|
|
168
|
-
The skill may not exist in the registry. Try:
|
|
169
|
-
```
|
|
170
|
-
"Search for similar-name"
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### "Installation failed"
|
|
174
|
-
|
|
175
|
-
Check:
|
|
176
|
-
1. Internet connection
|
|
177
|
-
2. Quota remaining
|
|
178
|
-
3. Skill hasn't been blocklisted
|
|
179
|
-
|
|
180
|
-
### "Security scan failed"
|
|
181
|
-
|
|
182
|
-
The skill was blocked for security reasons. Try a different skill or contact support if you believe this is an error.
|
|
183
|
-
|
|
184
|
-
### Quota Exceeded
|
|
185
|
-
|
|
186
|
-
You've hit your monthly limit. Options:
|
|
187
|
-
1. Wait until quota resets (1st of month)
|
|
188
|
-
2. Upgrade your tier
|
|
189
|
-
|
|
190
|
-
## Offline Usage
|
|
191
|
-
|
|
192
|
-
Installed skills work offline. Only these operations require internet:
|
|
193
|
-
- Searching for new skills
|
|
194
|
-
- Installing skills
|
|
195
|
-
- Getting recommendations
|
|
196
|
-
|
|
197
|
-
## Updating Skillsmith
|
|
198
|
-
|
|
199
|
-
```bash
|
|
200
|
-
npx @skillsmith/mcp-server@latest
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Or let it auto-update via npx.
|
|
204
|
-
|
|
205
|
-
## Getting Help
|
|
206
|
-
|
|
207
|
-
- **Documentation**: `npx @skillsmith/mcp-server --docs`
|
|
208
|
-
- **Issues**: https://github.com/smith-horn/skillsmith/issues
|
|
209
|
-
- **Support**: support@skillsmith.app
|
|
210
|
-
- **Security**: security@skillsmith.app
|
|
211
|
-
|
|
212
|
-
## License
|
|
213
|
-
|
|
214
|
-
Skillsmith is licensed under **Elastic License 2.0**:
|
|
215
|
-
- Self-hosting for internal use: Allowed
|
|
216
|
-
- Modification for own use: Allowed
|
|
217
|
-
- Offering as managed service: Not allowed
|
|
218
|
-
- Circumventing license keys: Not allowed
|
|
219
|
-
|
|
220
|
-
Full license: https://www.elastic.co/licensing/elastic-license
|