@skillsmith/mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -0
- package/dist/src/__tests__/get-skill.test.d.ts +6 -0
- package/dist/src/__tests__/get-skill.test.d.ts.map +1 -0
- package/dist/src/__tests__/get-skill.test.js +88 -0
- package/dist/src/__tests__/get-skill.test.js.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts +7 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.js +304 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.js.map +1 -0
- package/dist/src/__tests__/middleware/license.test.d.ts +7 -0
- package/dist/src/__tests__/middleware/license.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/license.test.js +500 -0
- package/dist/src/__tests__/middleware/license.test.js.map +1 -0
- package/dist/src/__tests__/search.test.d.ts +6 -0
- package/dist/src/__tests__/search.test.d.ts.map +1 -0
- package/dist/src/__tests__/search.test.js +86 -0
- package/dist/src/__tests__/search.test.js.map +1 -0
- package/dist/src/__tests__/test-utils.d.ts +19 -0
- package/dist/src/__tests__/test-utils.d.ts.map +1 -0
- package/dist/src/__tests__/test-utils.js +87 -0
- package/dist/src/__tests__/test-utils.js.map +1 -0
- package/dist/src/context/index.d.ts +19 -0
- package/dist/src/context/index.d.ts.map +1 -0
- package/dist/src/context/index.js +25 -0
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/context/project-detector.d.ts +145 -0
- package/dist/src/context/project-detector.d.ts.map +1 -0
- package/dist/src/context/project-detector.js +321 -0
- package/dist/src/context/project-detector.js.map +1 -0
- package/dist/src/context.d.ts +100 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +157 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/core-shim.d.ts +7 -0
- package/dist/src/core-shim.d.ts.map +1 -0
- package/dist/src/core-shim.js +9 -0
- package/dist/src/core-shim.js.map +1 -0
- package/dist/src/health/healthCheck.d.ts +88 -0
- package/dist/src/health/healthCheck.d.ts.map +1 -0
- package/dist/src/health/healthCheck.js +117 -0
- package/dist/src/health/healthCheck.js.map +1 -0
- package/dist/src/health/index.d.ts +21 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +21 -0
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/health/readinessCheck.d.ts +139 -0
- package/dist/src/health/readinessCheck.d.ts.map +1 -0
- package/dist/src/health/readinessCheck.js +266 -0
- package/dist/src/health/readinessCheck.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +178 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/index.test.d.ts +2 -0
- package/dist/src/index.test.d.ts.map +1 -0
- package/dist/src/index.test.js +43 -0
- package/dist/src/index.test.js.map +1 -0
- package/dist/src/logger.d.ts +26 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +179 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/middleware/__tests__/csp.test.d.ts +2 -0
- package/dist/src/middleware/__tests__/csp.test.d.ts.map +1 -0
- package/dist/src/middleware/__tests__/csp.test.js +389 -0
- package/dist/src/middleware/__tests__/csp.test.js.map +1 -0
- package/dist/src/middleware/csp.d.ts +87 -0
- package/dist/src/middleware/csp.d.ts.map +1 -0
- package/dist/src/middleware/csp.js +273 -0
- package/dist/src/middleware/csp.js.map +1 -0
- package/dist/src/middleware/degradation.d.ts +99 -0
- package/dist/src/middleware/degradation.d.ts.map +1 -0
- package/dist/src/middleware/degradation.js +315 -0
- package/dist/src/middleware/degradation.js.map +1 -0
- package/dist/src/middleware/errorFormatter.d.ts +119 -0
- package/dist/src/middleware/errorFormatter.d.ts.map +1 -0
- package/dist/src/middleware/errorFormatter.js +294 -0
- package/dist/src/middleware/errorFormatter.js.map +1 -0
- package/dist/src/middleware/index.d.ts +10 -0
- package/dist/src/middleware/index.d.ts.map +1 -0
- package/dist/src/middleware/index.js +14 -0
- package/dist/src/middleware/index.js.map +1 -0
- package/dist/src/middleware/license.d.ts +161 -0
- package/dist/src/middleware/license.d.ts.map +1 -0
- package/dist/src/middleware/license.js +281 -0
- package/dist/src/middleware/license.js.map +1 -0
- package/dist/src/middleware/toolFeatureMapping.d.ts +36 -0
- package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -0
- package/dist/src/middleware/toolFeatureMapping.js +90 -0
- package/dist/src/middleware/toolFeatureMapping.js.map +1 -0
- package/dist/src/onboarding/first-run.d.ts +64 -0
- package/dist/src/onboarding/first-run.d.ts.map +1 -0
- package/dist/src/onboarding/first-run.js +77 -0
- package/dist/src/onboarding/first-run.js.map +1 -0
- package/dist/src/onboarding/index.d.ts +7 -0
- package/dist/src/onboarding/index.d.ts.map +1 -0
- package/dist/src/onboarding/index.js +7 -0
- package/dist/src/onboarding/index.js.map +1 -0
- package/dist/src/suggestions/index.d.ts +21 -0
- package/dist/src/suggestions/index.d.ts.map +1 -0
- package/dist/src/suggestions/index.js +20 -0
- package/dist/src/suggestions/index.js.map +1 -0
- package/dist/src/suggestions/suggestion-engine.d.ts +185 -0
- package/dist/src/suggestions/suggestion-engine.d.ts.map +1 -0
- package/dist/src/suggestions/suggestion-engine.js +352 -0
- package/dist/src/suggestions/suggestion-engine.js.map +1 -0
- package/dist/src/suggestions/types.d.ts +88 -0
- package/dist/src/suggestions/types.d.ts.map +1 -0
- package/dist/src/suggestions/types.js +21 -0
- package/dist/src/suggestions/types.js.map +1 -0
- package/dist/src/tools/analyze.d.ts +151 -0
- package/dist/src/tools/analyze.d.ts.map +1 -0
- package/dist/src/tools/analyze.js +205 -0
- package/dist/src/tools/analyze.js.map +1 -0
- package/dist/src/tools/compare.d.ts +149 -0
- package/dist/src/tools/compare.d.ts.map +1 -0
- package/dist/src/tools/compare.js +464 -0
- package/dist/src/tools/compare.js.map +1 -0
- package/dist/src/tools/get-skill.d.ts +116 -0
- package/dist/src/tools/get-skill.d.ts.map +1 -0
- package/dist/src/tools/get-skill.js +224 -0
- package/dist/src/tools/get-skill.js.map +1 -0
- package/dist/src/tools/index.d.ts +20 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +20 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/install.d.ts +122 -0
- package/dist/src/tools/install.d.ts.map +1 -0
- package/dist/src/tools/install.js +314 -0
- package/dist/src/tools/install.js.map +1 -0
- package/dist/src/tools/recommend.d.ts +171 -0
- package/dist/src/tools/recommend.d.ts.map +1 -0
- package/dist/src/tools/recommend.js +325 -0
- package/dist/src/tools/recommend.js.map +1 -0
- package/dist/src/tools/search.d.ts +121 -0
- package/dist/src/tools/search.d.ts.map +1 -0
- package/dist/src/tools/search.js +249 -0
- package/dist/src/tools/search.js.map +1 -0
- package/dist/src/tools/suggest.d.ts +181 -0
- package/dist/src/tools/suggest.d.ts.map +1 -0
- package/dist/src/tools/suggest.js +342 -0
- package/dist/src/tools/suggest.js.map +1 -0
- package/dist/src/tools/uninstall.d.ts +123 -0
- package/dist/src/tools/uninstall.d.ts.map +1 -0
- package/dist/src/tools/uninstall.js +250 -0
- package/dist/src/tools/uninstall.js.map +1 -0
- package/dist/src/tools/validate.d.ts +122 -0
- package/dist/src/tools/validate.d.ts.map +1 -0
- package/dist/src/tools/validate.js +497 -0
- package/dist/src/tools/validate.js.map +1 -0
- package/dist/src/utils/installed-skills.d.ts +101 -0
- package/dist/src/utils/installed-skills.d.ts.map +1 -0
- package/dist/src/utils/installed-skills.js +220 -0
- package/dist/src/utils/installed-skills.js.map +1 -0
- package/dist/src/utils/validation.d.ts +76 -0
- package/dist/src/utils/validation.d.ts.map +1 -0
- package/dist/src/utils/validation.js +153 -0
- package/dist/src/utils/validation.js.map +1 -0
- package/dist/src/webhooks/index.d.ts +8 -0
- package/dist/src/webhooks/index.d.ts.map +1 -0
- package/dist/src/webhooks/index.js +9 -0
- package/dist/src/webhooks/index.js.map +1 -0
- package/dist/src/webhooks/webhook-endpoint.d.ts +149 -0
- package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -0
- package/dist/src/webhooks/webhook-endpoint.js +339 -0
- package/dist/src/webhooks/webhook-endpoint.js.map +1 -0
- package/dist/tests/compare.test.d.ts +6 -0
- package/dist/tests/compare.test.d.ts.map +1 -0
- package/dist/tests/compare.test.js +225 -0
- package/dist/tests/compare.test.js.map +1 -0
- package/dist/tests/context/project-detector.test.d.ts +6 -0
- package/dist/tests/context/project-detector.test.d.ts.map +1 -0
- package/dist/tests/context/project-detector.test.js +719 -0
- package/dist/tests/context/project-detector.test.js.map +1 -0
- package/dist/tests/e2e/compare.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/compare.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/compare.e2e.test.js +286 -0
- package/dist/tests/e2e/compare.e2e.test.js.map +1 -0
- package/dist/tests/e2e/install-flow.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/install-flow.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/install-flow.e2e.test.js +209 -0
- package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -0
- package/dist/tests/e2e/recommend.e2e.test.d.ts +12 -0
- package/dist/tests/e2e/recommend.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/recommend.e2e.test.js +347 -0
- package/dist/tests/e2e/recommend.e2e.test.js.map +1 -0
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/skill-flow.e2e.test.js +280 -0
- package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -0
- package/dist/tests/e2e/suggest.e2e.test.d.ts +13 -0
- package/dist/tests/e2e/suggest.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/suggest.e2e.test.js +347 -0
- package/dist/tests/e2e/suggest.e2e.test.js.map +1 -0
- package/dist/tests/e2e/utils/baseline-collector.d.ts +107 -0
- package/dist/tests/e2e/utils/baseline-collector.d.ts.map +1 -0
- package/dist/tests/e2e/utils/baseline-collector.js +211 -0
- package/dist/tests/e2e/utils/baseline-collector.js.map +1 -0
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts +46 -0
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +1 -0
- package/dist/tests/e2e/utils/hardcoded-detector.js +255 -0
- package/dist/tests/e2e/utils/hardcoded-detector.js.map +1 -0
- package/dist/tests/e2e/utils/index.d.ts +7 -0
- package/dist/tests/e2e/utils/index.d.ts.map +1 -0
- package/dist/tests/e2e/utils/index.js +7 -0
- package/dist/tests/e2e/utils/index.js.map +1 -0
- package/dist/tests/e2e/utils/linear-reporter.d.ts +60 -0
- package/dist/tests/e2e/utils/linear-reporter.d.ts.map +1 -0
- package/dist/tests/e2e/utils/linear-reporter.js +232 -0
- package/dist/tests/e2e/utils/linear-reporter.js.map +1 -0
- package/dist/tests/health.test.d.ts +9 -0
- package/dist/tests/health.test.d.ts.map +1 -0
- package/dist/tests/health.test.js +308 -0
- package/dist/tests/health.test.js.map +1 -0
- package/dist/tests/integration/analyze.integration.test.d.ts +2 -0
- package/dist/tests/integration/analyze.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/analyze.integration.test.js +244 -0
- package/dist/tests/integration/analyze.integration.test.js.map +1 -0
- package/dist/tests/integration/compare.integration.test.d.ts +2 -0
- package/dist/tests/integration/compare.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/compare.integration.test.js +120 -0
- package/dist/tests/integration/compare.integration.test.js.map +1 -0
- package/dist/tests/integration/fixtures/test-skills.d.ts +62 -0
- package/dist/tests/integration/fixtures/test-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/test-skills.js +644 -0
- package/dist/tests/integration/fixtures/test-skills.js.map +1 -0
- package/dist/tests/integration/get-skill.integration.test.d.ts +6 -0
- package/dist/tests/integration/get-skill.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/get-skill.integration.test.js +203 -0
- package/dist/tests/integration/get-skill.integration.test.js.map +1 -0
- package/dist/tests/integration/github-api.integration.test.d.ts +14 -0
- package/dist/tests/integration/github-api.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/github-api.integration.test.js +190 -0
- package/dist/tests/integration/github-api.integration.test.js.map +1 -0
- package/dist/tests/integration/install.integration.test.d.ts +6 -0
- package/dist/tests/integration/install.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/install.integration.test.js +282 -0
- package/dist/tests/integration/install.integration.test.js.map +1 -0
- package/dist/tests/integration/recommend.integration.test.d.ts +2 -0
- package/dist/tests/integration/recommend.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/recommend.integration.test.js +215 -0
- package/dist/tests/integration/recommend.integration.test.js.map +1 -0
- package/dist/tests/integration/search.integration.test.d.ts +6 -0
- package/dist/tests/integration/search.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/search.integration.test.js +229 -0
- package/dist/tests/integration/search.integration.test.js.map +1 -0
- package/dist/tests/integration/setup.d.ts +71 -0
- package/dist/tests/integration/setup.d.ts.map +1 -0
- package/dist/tests/integration/setup.js +124 -0
- package/dist/tests/integration/setup.js.map +1 -0
- package/dist/tests/integration/uninstall.integration.test.d.ts +6 -0
- package/dist/tests/integration/uninstall.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/uninstall.integration.test.js +296 -0
- package/dist/tests/integration/uninstall.integration.test.js.map +1 -0
- package/dist/tests/integration/validate.integration.test.d.ts +2 -0
- package/dist/tests/integration/validate.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/validate.integration.test.js +181 -0
- package/dist/tests/integration/validate.integration.test.js.map +1 -0
- package/dist/tests/onboarding/first-run.test.d.ts +7 -0
- package/dist/tests/onboarding/first-run.test.d.ts.map +1 -0
- package/dist/tests/onboarding/first-run.test.js +258 -0
- package/dist/tests/onboarding/first-run.test.js.map +1 -0
- package/dist/tests/performance/search-performance.test.d.ts +10 -0
- package/dist/tests/performance/search-performance.test.d.ts.map +1 -0
- package/dist/tests/performance/search-performance.test.js +218 -0
- package/dist/tests/performance/search-performance.test.js.map +1 -0
- package/dist/tests/recommend.test.d.ts +6 -0
- package/dist/tests/recommend.test.d.ts.map +1 -0
- package/dist/tests/recommend.test.js +208 -0
- package/dist/tests/recommend.test.js.map +1 -0
- package/dist/tests/suggestions/suggestion-engine.test.d.ts +6 -0
- package/dist/tests/suggestions/suggestion-engine.test.d.ts.map +1 -0
- package/dist/tests/suggestions/suggestion-engine.test.js +448 -0
- package/dist/tests/suggestions/suggestion-engine.test.js.map +1 -0
- package/dist/tests/test-utils.d.ts +74 -0
- package/dist/tests/test-utils.d.ts.map +1 -0
- package/dist/tests/test-utils.js +98 -0
- package/dist/tests/test-utils.js.map +1 -0
- package/dist/tests/tools.test.d.ts +5 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +138 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/tests/unit/installed-skills.test.d.ts +6 -0
- package/dist/tests/unit/installed-skills.test.d.ts.map +1 -0
- package/dist/tests/unit/installed-skills.test.js +285 -0
- package/dist/tests/unit/installed-skills.test.js.map +1 -0
- package/dist/tests/unit/logger.test.d.ts +6 -0
- package/dist/tests/unit/logger.test.d.ts.map +1 -0
- package/dist/tests/unit/logger.test.js +281 -0
- package/dist/tests/unit/logger.test.js.map +1 -0
- package/dist/tests/validate.test.d.ts +5 -0
- package/dist/tests/validate.test.d.ts.map +1 -0
- package/dist/tests/validate.test.js +303 -0
- package/dist/tests/validate.test.js.map +1 -0
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts +8 -0
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts.map +1 -0
- package/dist/tests/webhooks/proxy-trust.security.test.js +145 -0
- package/dist/tests/webhooks/proxy-trust.security.test.js.map +1 -0
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts +8 -0
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts.map +1 -0
- package/dist/tests/webhooks/rate-limiter.security.test.js +122 -0
- package/dist/tests/webhooks/rate-limiter.security.test.js.map +1 -0
- package/dist/vitest.config.d.ts +6 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +13 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Security Policy middleware and utilities for MCP server
|
|
3
|
+
*
|
|
4
|
+
* While the MCP server currently uses stdio transport, these utilities
|
|
5
|
+
* provide CSP support for potential HTTP transport scenarios.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* CSP directive types
|
|
9
|
+
*/
|
|
10
|
+
export interface CspDirectives {
|
|
11
|
+
'default-src'?: string[];
|
|
12
|
+
'script-src'?: string[];
|
|
13
|
+
'style-src'?: string[];
|
|
14
|
+
'img-src'?: string[];
|
|
15
|
+
'font-src'?: string[];
|
|
16
|
+
'connect-src'?: string[];
|
|
17
|
+
'media-src'?: string[];
|
|
18
|
+
'object-src'?: string[];
|
|
19
|
+
'frame-src'?: string[];
|
|
20
|
+
'worker-src'?: string[];
|
|
21
|
+
'form-action'?: string[];
|
|
22
|
+
'frame-ancestors'?: string[];
|
|
23
|
+
'base-uri'?: string[];
|
|
24
|
+
'manifest-src'?: string[];
|
|
25
|
+
sandbox?: string[];
|
|
26
|
+
'report-uri'?: string[];
|
|
27
|
+
'report-to'?: string;
|
|
28
|
+
'require-trusted-types-for'?: string[];
|
|
29
|
+
'upgrade-insecure-requests'?: boolean;
|
|
30
|
+
'block-all-mixed-content'?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* CSP validation result with details
|
|
34
|
+
*/
|
|
35
|
+
export interface CspValidationResult {
|
|
36
|
+
valid: boolean;
|
|
37
|
+
warnings: string[];
|
|
38
|
+
errors: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Default CSP directives for MCP server
|
|
42
|
+
*/
|
|
43
|
+
export declare const DEFAULT_CSP_DIRECTIVES: CspDirectives;
|
|
44
|
+
/**
|
|
45
|
+
* Strict CSP directives for maximum security
|
|
46
|
+
*/
|
|
47
|
+
export declare const STRICT_CSP_DIRECTIVES: CspDirectives;
|
|
48
|
+
/**
|
|
49
|
+
* Generates a cryptographically secure nonce for CSP
|
|
50
|
+
* @returns A 32-character base64 nonce
|
|
51
|
+
*/
|
|
52
|
+
export declare function generateNonce(): string;
|
|
53
|
+
/**
|
|
54
|
+
* Converts CSP directives object to a CSP header string
|
|
55
|
+
* @param directives - The CSP directives to convert
|
|
56
|
+
* @param nonce - Optional nonce to add to script-src and style-src
|
|
57
|
+
* @returns The CSP header value
|
|
58
|
+
*/
|
|
59
|
+
export declare function buildCspHeader(directives: CspDirectives, nonce?: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Validates a CSP header string
|
|
62
|
+
* @param csp - The CSP header string to validate
|
|
63
|
+
* @returns true if valid, false otherwise
|
|
64
|
+
*/
|
|
65
|
+
export declare function validateCspHeader(csp: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Validates a CSP header string with detailed results
|
|
68
|
+
* @param csp - The CSP header string to validate
|
|
69
|
+
* @returns Detailed validation result with warnings and errors
|
|
70
|
+
*/
|
|
71
|
+
export declare function validateCspHeaderDetailed(csp: string): CspValidationResult;
|
|
72
|
+
/**
|
|
73
|
+
* HTTP middleware function for adding CSP headers
|
|
74
|
+
* This can be used if the MCP server adds HTTP transport in the future
|
|
75
|
+
*/
|
|
76
|
+
export declare function cspMiddleware(directives?: CspDirectives): (req: any, res: any, next: () => void) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Gets CSP configuration for different environments
|
|
79
|
+
*
|
|
80
|
+
* NOTE: Test environment uses relaxed CSP for testing purposes.
|
|
81
|
+
* Production code should always use STRICT_CSP_DIRECTIVES.
|
|
82
|
+
*
|
|
83
|
+
* @param env - The environment (development, production, test)
|
|
84
|
+
* @returns The appropriate CSP directives
|
|
85
|
+
*/
|
|
86
|
+
export declare function getCspForEnvironment(env?: string): CspDirectives;
|
|
87
|
+
//# sourceMappingURL=csp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csp.d.ts","sourceRoot":"","sources":["../../../src/middleware/csp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,2BAA2B,CAAC,EAAE,MAAM,EAAE,CAAA;IACtC,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,yBAAyB,CAAC,EAAE,OAAO,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAgBpC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAkBnC,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAaD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CA+BhF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGtD;AA6BD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAiG1E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,GAAE,aAAsC,IACtE,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,IAAI,UAe7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAqB,GAAG,aAAa,CA2B9E"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Security Policy middleware and utilities for MCP server
|
|
3
|
+
*
|
|
4
|
+
* While the MCP server currently uses stdio transport, these utilities
|
|
5
|
+
* provide CSP support for potential HTTP transport scenarios.
|
|
6
|
+
*/
|
|
7
|
+
import { randomBytes } from 'node:crypto';
|
|
8
|
+
/**
|
|
9
|
+
* Default CSP directives for MCP server
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_CSP_DIRECTIVES = {
|
|
12
|
+
'default-src': ["'self'"],
|
|
13
|
+
'script-src': ["'self'"],
|
|
14
|
+
'style-src': ["'self'"],
|
|
15
|
+
'img-src': ["'self'", 'data:', 'https:'],
|
|
16
|
+
'font-src': ["'self'"],
|
|
17
|
+
'connect-src': ["'self'"],
|
|
18
|
+
'media-src': ["'self'"],
|
|
19
|
+
'object-src': ["'none'"],
|
|
20
|
+
'frame-src': ["'none'"],
|
|
21
|
+
'worker-src': ["'self'"],
|
|
22
|
+
'form-action': ["'self'"],
|
|
23
|
+
'frame-ancestors': ["'none'"],
|
|
24
|
+
'base-uri': ["'self'"],
|
|
25
|
+
'upgrade-insecure-requests': true,
|
|
26
|
+
'block-all-mixed-content': true,
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Strict CSP directives for maximum security
|
|
30
|
+
*/
|
|
31
|
+
export const STRICT_CSP_DIRECTIVES = {
|
|
32
|
+
'default-src': ["'none'"],
|
|
33
|
+
'script-src': ["'self'"],
|
|
34
|
+
'style-src': ["'self'"],
|
|
35
|
+
'img-src': ["'self'", 'data:'],
|
|
36
|
+
'font-src': ["'self'"],
|
|
37
|
+
'connect-src': ["'self'"],
|
|
38
|
+
'media-src': ["'none'"],
|
|
39
|
+
'object-src': ["'none'"],
|
|
40
|
+
'frame-src': ["'none'"],
|
|
41
|
+
'worker-src': ["'none'"],
|
|
42
|
+
'form-action': ["'none'"],
|
|
43
|
+
'frame-ancestors': ["'none'"],
|
|
44
|
+
'base-uri': ["'none'"],
|
|
45
|
+
'manifest-src': ["'self'"],
|
|
46
|
+
'require-trusted-types-for': ["'script'"],
|
|
47
|
+
'upgrade-insecure-requests': true,
|
|
48
|
+
'block-all-mixed-content': true,
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Generates a cryptographically secure nonce for CSP
|
|
52
|
+
* @returns A 32-character base64 nonce
|
|
53
|
+
*/
|
|
54
|
+
export function generateNonce() {
|
|
55
|
+
// Use Node.js crypto.randomBytes for cryptographically secure random bytes
|
|
56
|
+
return randomBytes(16).toString('base64');
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Sanitize a CSP source value to prevent directive injection
|
|
60
|
+
* @param source - The source value to sanitize
|
|
61
|
+
* @returns Sanitized source value
|
|
62
|
+
*/
|
|
63
|
+
function sanitizeCspSource(source) {
|
|
64
|
+
// Remove characters that could be used for injection
|
|
65
|
+
// CSP sources should not contain ; (directive separator) or newlines
|
|
66
|
+
return source.replace(/[;\r\n]/g, '');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Converts CSP directives object to a CSP header string
|
|
70
|
+
* @param directives - The CSP directives to convert
|
|
71
|
+
* @param nonce - Optional nonce to add to script-src and style-src
|
|
72
|
+
* @returns The CSP header value
|
|
73
|
+
*/
|
|
74
|
+
export function buildCspHeader(directives, nonce) {
|
|
75
|
+
const parts = [];
|
|
76
|
+
for (const [directive, value] of Object.entries(directives)) {
|
|
77
|
+
// Sanitize directive name (should be alphanumeric with hyphens only)
|
|
78
|
+
const sanitizedDirective = directive.replace(/[^a-zA-Z0-9-]/g, '');
|
|
79
|
+
if (typeof value === 'boolean') {
|
|
80
|
+
if (value) {
|
|
81
|
+
parts.push(sanitizedDirective);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (typeof value === 'string') {
|
|
85
|
+
// Handle string directives like report-to
|
|
86
|
+
const sanitizedValue = sanitizeCspSource(value);
|
|
87
|
+
parts.push(`${sanitizedDirective} ${sanitizedValue}`);
|
|
88
|
+
}
|
|
89
|
+
else if (Array.isArray(value)) {
|
|
90
|
+
const sources = value.map(sanitizeCspSource);
|
|
91
|
+
// Add nonce to script-src and style-src if provided
|
|
92
|
+
if (nonce && (directive === 'script-src' || directive === 'style-src')) {
|
|
93
|
+
// Validate nonce format (base64)
|
|
94
|
+
if (/^[A-Za-z0-9+/=]+$/.test(nonce)) {
|
|
95
|
+
sources.push(`'nonce-${nonce}'`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
parts.push(`${sanitizedDirective} ${sources.join(' ')}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return parts.join('; ');
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validates a CSP header string
|
|
105
|
+
* @param csp - The CSP header string to validate
|
|
106
|
+
* @returns true if valid, false otherwise
|
|
107
|
+
*/
|
|
108
|
+
export function validateCspHeader(csp) {
|
|
109
|
+
const result = validateCspHeaderDetailed(csp);
|
|
110
|
+
return result.valid;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Parse CSP header into directives map
|
|
114
|
+
* @param csp - The CSP header string
|
|
115
|
+
* @returns Map of directive name to values
|
|
116
|
+
*/
|
|
117
|
+
function parseCspDirectives(csp) {
|
|
118
|
+
const directives = new Map();
|
|
119
|
+
const parts = csp
|
|
120
|
+
.split(';')
|
|
121
|
+
.map((p) => p.trim())
|
|
122
|
+
.filter((p) => p.length > 0);
|
|
123
|
+
for (const part of parts) {
|
|
124
|
+
const spaceIndex = part.indexOf(' ');
|
|
125
|
+
if (spaceIndex === -1) {
|
|
126
|
+
// Directive without value (e.g., upgrade-insecure-requests)
|
|
127
|
+
directives.set(part.toLowerCase(), '');
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
const name = part.substring(0, spaceIndex).toLowerCase();
|
|
131
|
+
const value = part.substring(spaceIndex + 1);
|
|
132
|
+
directives.set(name, value);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return directives;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Validates a CSP header string with detailed results
|
|
139
|
+
* @param csp - The CSP header string to validate
|
|
140
|
+
* @returns Detailed validation result with warnings and errors
|
|
141
|
+
*/
|
|
142
|
+
export function validateCspHeaderDetailed(csp) {
|
|
143
|
+
const result = {
|
|
144
|
+
valid: true,
|
|
145
|
+
warnings: [],
|
|
146
|
+
errors: [],
|
|
147
|
+
};
|
|
148
|
+
if (!csp || typeof csp !== 'string') {
|
|
149
|
+
result.valid = false;
|
|
150
|
+
result.errors.push('CSP header must be a non-empty string');
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
// Parse directives for per-directive analysis
|
|
154
|
+
const directives = parseCspDirectives(csp);
|
|
155
|
+
const lowercaseCsp = csp.toLowerCase();
|
|
156
|
+
// Check for unsafe-eval in script-src or default-src (per-directive check)
|
|
157
|
+
const scriptSrc = directives.get('script-src') || '';
|
|
158
|
+
const defaultSrc = directives.get('default-src') || '';
|
|
159
|
+
if (scriptSrc.includes("'unsafe-eval'") || defaultSrc.includes("'unsafe-eval'")) {
|
|
160
|
+
result.warnings.push('unsafe-eval detected in script-src or default-src - allows arbitrary code execution');
|
|
161
|
+
console.warn('[CSP] Warning: unsafe-eval detected in CSP policy');
|
|
162
|
+
}
|
|
163
|
+
// Check for unsafe-inline WITHOUT nonce in the SAME directive (per-directive check)
|
|
164
|
+
// This is the correct check - unsafe-inline in script-src is only mitigated by nonce in script-src
|
|
165
|
+
if (scriptSrc.includes("'unsafe-inline'") && !scriptSrc.includes("'nonce-")) {
|
|
166
|
+
result.warnings.push('unsafe-inline without nonce in script-src - vulnerable to XSS');
|
|
167
|
+
console.warn('[CSP] Warning: unsafe-inline without nonce detected in script-src');
|
|
168
|
+
}
|
|
169
|
+
const styleSrc = directives.get('style-src') || '';
|
|
170
|
+
if (styleSrc.includes("'unsafe-inline'") && !styleSrc.includes("'nonce-")) {
|
|
171
|
+
result.warnings.push('unsafe-inline without nonce in style-src - vulnerable to CSS injection');
|
|
172
|
+
console.warn('[CSP] Warning: unsafe-inline without nonce detected in style-src');
|
|
173
|
+
}
|
|
174
|
+
// Check for wildcard sources in sensitive directives
|
|
175
|
+
const sensitiveDirectives = ['script-src', 'style-src', 'object-src', 'base-uri'];
|
|
176
|
+
for (const directive of sensitiveDirectives) {
|
|
177
|
+
const directiveValue = directives.get(directive) || '';
|
|
178
|
+
// Check for standalone wildcard (not part of *.example.com)
|
|
179
|
+
if (/(?:^|\s)\*(?:\s|$)/.test(directiveValue)) {
|
|
180
|
+
result.warnings.push(`Wildcard (*) in ${directive} is overly permissive`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Check for data: URI in script-src (XSS risk)
|
|
184
|
+
if (scriptSrc.includes('data:')) {
|
|
185
|
+
result.warnings.push('data: URI in script-src allows XSS attacks');
|
|
186
|
+
}
|
|
187
|
+
// Check for blob: and filesystem: in script-src (XSS risk)
|
|
188
|
+
if (scriptSrc.includes('blob:')) {
|
|
189
|
+
result.warnings.push('blob: URI in script-src can be used for XSS');
|
|
190
|
+
}
|
|
191
|
+
if (scriptSrc.includes('filesystem:')) {
|
|
192
|
+
result.warnings.push('filesystem: URI in script-src can be used for XSS');
|
|
193
|
+
}
|
|
194
|
+
// Verify object-src is properly restricted (Flash/plugin attacks)
|
|
195
|
+
const objectSrc = directives.get('object-src') || '';
|
|
196
|
+
if (directives.has('object-src')) {
|
|
197
|
+
if (!objectSrc.includes("'none'") && !objectSrc.includes("'self'")) {
|
|
198
|
+
// Check if it has potentially dangerous values
|
|
199
|
+
if (objectSrc.includes('*') || objectSrc.includes('data:') || objectSrc.includes('blob:')) {
|
|
200
|
+
result.warnings.push('object-src has permissive values - vulnerable to plugin-based attacks');
|
|
201
|
+
}
|
|
202
|
+
else if (objectSrc.trim() !== '') {
|
|
203
|
+
result.warnings.push('object-src should be restricted to prevent plugin-based attacks');
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Check for missing default-src (fallback for other directives)
|
|
208
|
+
if (!directives.has('default-src')) {
|
|
209
|
+
result.warnings.push('Missing default-src - other directives may fall back to permissive defaults');
|
|
210
|
+
}
|
|
211
|
+
// Should have at least one directive
|
|
212
|
+
if (!csp.includes('-src') &&
|
|
213
|
+
!csp.includes('upgrade-insecure-requests') &&
|
|
214
|
+
!csp.includes('sandbox')) {
|
|
215
|
+
result.valid = false;
|
|
216
|
+
result.errors.push('CSP must contain at least one valid directive');
|
|
217
|
+
}
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* HTTP middleware function for adding CSP headers
|
|
222
|
+
* This can be used if the MCP server adds HTTP transport in the future
|
|
223
|
+
*/
|
|
224
|
+
export function cspMiddleware(directives = DEFAULT_CSP_DIRECTIVES) {
|
|
225
|
+
return (req, res, next) => {
|
|
226
|
+
const nonce = generateNonce();
|
|
227
|
+
const cspHeader = buildCspHeader(directives, nonce);
|
|
228
|
+
// Set CSP header
|
|
229
|
+
res.setHeader('Content-Security-Policy', cspHeader);
|
|
230
|
+
// Add nonce to response locals for use in templates
|
|
231
|
+
if (!res.locals) {
|
|
232
|
+
res.locals = {};
|
|
233
|
+
}
|
|
234
|
+
res.locals.cspNonce = nonce;
|
|
235
|
+
next();
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Gets CSP configuration for different environments
|
|
240
|
+
*
|
|
241
|
+
* NOTE: Test environment uses relaxed CSP for testing purposes.
|
|
242
|
+
* Production code should always use STRICT_CSP_DIRECTIVES.
|
|
243
|
+
*
|
|
244
|
+
* @param env - The environment (development, production, test)
|
|
245
|
+
* @returns The appropriate CSP directives
|
|
246
|
+
*/
|
|
247
|
+
export function getCspForEnvironment(env = 'production') {
|
|
248
|
+
switch (env) {
|
|
249
|
+
case 'development':
|
|
250
|
+
// Slightly relaxed for development - only unsafe-eval for dev tools
|
|
251
|
+
// Still maintains object-src: 'none' for plugin protection
|
|
252
|
+
return {
|
|
253
|
+
...DEFAULT_CSP_DIRECTIVES,
|
|
254
|
+
'script-src': ["'self'", "'unsafe-eval'"], // Allow eval for dev tools
|
|
255
|
+
'object-src': ["'none'"], // Always restrict plugins
|
|
256
|
+
};
|
|
257
|
+
case 'test':
|
|
258
|
+
// More permissive for testing, but maintain critical security restrictions
|
|
259
|
+
// Note: Tests requiring unsafe-inline should use nonces instead for better security testing
|
|
260
|
+
return {
|
|
261
|
+
...DEFAULT_CSP_DIRECTIVES,
|
|
262
|
+
'script-src': ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
|
|
263
|
+
'style-src': ["'self'", "'unsafe-inline'"],
|
|
264
|
+
'object-src': ["'none'"], // Always restrict plugins even in test
|
|
265
|
+
'frame-ancestors': ["'none'"], // Prevent clickjacking even in test
|
|
266
|
+
};
|
|
267
|
+
case 'production':
|
|
268
|
+
default:
|
|
269
|
+
// Strict for production
|
|
270
|
+
return STRICT_CSP_DIRECTIVES;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=csp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csp.js","sourceRoot":"","sources":["../../../src/middleware/csp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1060: Graceful Degradation Middleware
|
|
3
|
+
*
|
|
4
|
+
* Middleware that wraps tool handlers with graceful degradation,
|
|
5
|
+
* returning helpful messages instead of hard errors when features
|
|
6
|
+
* are unavailable.
|
|
7
|
+
*/
|
|
8
|
+
import { type LicenseMiddleware } from './license.js';
|
|
9
|
+
import { type FeatureFlag } from './toolFeatureMapping.js';
|
|
10
|
+
/**
|
|
11
|
+
* MCP tool request structure
|
|
12
|
+
*/
|
|
13
|
+
export interface McpToolRequest {
|
|
14
|
+
name: string;
|
|
15
|
+
arguments: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* MCP tool response structure
|
|
19
|
+
*/
|
|
20
|
+
export interface McpToolResponse {
|
|
21
|
+
content: Array<{
|
|
22
|
+
type: 'text';
|
|
23
|
+
text: string;
|
|
24
|
+
}>;
|
|
25
|
+
isError?: boolean;
|
|
26
|
+
_meta?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Tool handler function type
|
|
30
|
+
*/
|
|
31
|
+
export type ToolHandler<T = unknown> = (request: McpToolRequest) => Promise<T>;
|
|
32
|
+
/**
|
|
33
|
+
* Degradation event for logging
|
|
34
|
+
*/
|
|
35
|
+
export interface DegradationLogEvent {
|
|
36
|
+
timestamp: string;
|
|
37
|
+
toolName: string;
|
|
38
|
+
feature: FeatureFlag | null;
|
|
39
|
+
tier: 'community' | 'team' | 'enterprise';
|
|
40
|
+
action: 'allowed' | 'degraded' | 'error';
|
|
41
|
+
message?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Degradation logger interface
|
|
45
|
+
*/
|
|
46
|
+
export interface DegradationLogger {
|
|
47
|
+
log(event: DegradationLogEvent): void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Degradation middleware options
|
|
51
|
+
*/
|
|
52
|
+
export interface DegradationMiddlewareOptions {
|
|
53
|
+
/** License middleware instance */
|
|
54
|
+
licenseMiddleware?: LicenseMiddleware;
|
|
55
|
+
/** Logger for degradation events */
|
|
56
|
+
logger?: DegradationLogger;
|
|
57
|
+
/** Enable verbose logging */
|
|
58
|
+
verbose?: boolean;
|
|
59
|
+
/** Custom upgrade URL base */
|
|
60
|
+
upgradeUrlBase?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Console logger for degradation events
|
|
64
|
+
*/
|
|
65
|
+
export declare const consoleDegradationLogger: DegradationLogger;
|
|
66
|
+
/**
|
|
67
|
+
* Get tier comparison message
|
|
68
|
+
*/
|
|
69
|
+
export declare function getTierComparisonMessage(): string;
|
|
70
|
+
/**
|
|
71
|
+
* Create the degradation middleware
|
|
72
|
+
*
|
|
73
|
+
* This middleware wraps tool handlers to provide graceful degradation
|
|
74
|
+
* when features are unavailable due to license restrictions.
|
|
75
|
+
*
|
|
76
|
+
* @param options - Middleware configuration options
|
|
77
|
+
* @returns Middleware wrapper function
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const middleware = createDegradationMiddleware({
|
|
82
|
+
* logger: consoleDegradationLogger,
|
|
83
|
+
* verbose: true,
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* const wrappedHandler = middleware.wrapHandler('audit_query', originalHandler);
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function createDegradationMiddleware(options?: DegradationMiddlewareOptions): {
|
|
90
|
+
wrapHandler: <T>(toolName: string, handler: ToolHandler<T>, request: McpToolRequest) => Promise<T | McpToolResponse>;
|
|
91
|
+
createWrappedHandler: <T>(toolName: string, handler: ToolHandler<T>) => (request: McpToolRequest) => Promise<T | McpToolResponse>;
|
|
92
|
+
wouldDegrade: (toolName: string) => Promise<boolean>;
|
|
93
|
+
getDegradationStatus: () => Promise<Map<string, boolean>>;
|
|
94
|
+
getUpgradePrompt: (toolName: string) => Promise<string | null>;
|
|
95
|
+
getTierComparisonMessage: typeof getTierComparisonMessage;
|
|
96
|
+
licenseMiddleware: LicenseMiddleware;
|
|
97
|
+
};
|
|
98
|
+
export type DegradationMiddleware = ReturnType<typeof createDegradationMiddleware>;
|
|
99
|
+
//# sourceMappingURL=degradation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"degradation.d.ts","sourceRoot":"","sources":["../../../src/middleware/degradation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,iBAAiB,EAIvB,MAAM,cAAc,CAAA;AACrB,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAA;AA0ChC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAE9E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,YAAY,CAAA;IACzC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAA;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,kCAAkC;IAClC,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,oCAAoC;IACpC,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8BAA8B;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAaD;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,iBAMtC,CAAA;AA8CD;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAyBjD;AAyFD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,4BAAiC;kBAOzD,CAAC,YAChB,MAAM,WACP,WAAW,CAAC,CAAC,CAAC,WACd,cAAc,KACtB,OAAO,CAAC,CAAC,GAAG,eAAe,CAAC;2BAyDD,CAAC,YACnB,MAAM,WACP,WAAW,CAAC,CAAC,CAAC,KACtB,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,GAAG,eAAe,CAAC;6BAStB,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;gCAYxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;iCAa1B,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;;;EAqB1E;AAMD,MAAM,MAAM,qBAAqB,GAAG,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAA"}
|