@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.
Files changed (306) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/src/__tests__/get-skill.test.d.ts +6 -0
  3. package/dist/src/__tests__/get-skill.test.d.ts.map +1 -0
  4. package/dist/src/__tests__/get-skill.test.js +88 -0
  5. package/dist/src/__tests__/get-skill.test.js.map +1 -0
  6. package/dist/src/__tests__/middleware/errorFormatter.test.d.ts +7 -0
  7. package/dist/src/__tests__/middleware/errorFormatter.test.d.ts.map +1 -0
  8. package/dist/src/__tests__/middleware/errorFormatter.test.js +304 -0
  9. package/dist/src/__tests__/middleware/errorFormatter.test.js.map +1 -0
  10. package/dist/src/__tests__/middleware/license.test.d.ts +7 -0
  11. package/dist/src/__tests__/middleware/license.test.d.ts.map +1 -0
  12. package/dist/src/__tests__/middleware/license.test.js +500 -0
  13. package/dist/src/__tests__/middleware/license.test.js.map +1 -0
  14. package/dist/src/__tests__/search.test.d.ts +6 -0
  15. package/dist/src/__tests__/search.test.d.ts.map +1 -0
  16. package/dist/src/__tests__/search.test.js +86 -0
  17. package/dist/src/__tests__/search.test.js.map +1 -0
  18. package/dist/src/__tests__/test-utils.d.ts +19 -0
  19. package/dist/src/__tests__/test-utils.d.ts.map +1 -0
  20. package/dist/src/__tests__/test-utils.js +87 -0
  21. package/dist/src/__tests__/test-utils.js.map +1 -0
  22. package/dist/src/context/index.d.ts +19 -0
  23. package/dist/src/context/index.d.ts.map +1 -0
  24. package/dist/src/context/index.js +25 -0
  25. package/dist/src/context/index.js.map +1 -0
  26. package/dist/src/context/project-detector.d.ts +145 -0
  27. package/dist/src/context/project-detector.d.ts.map +1 -0
  28. package/dist/src/context/project-detector.js +321 -0
  29. package/dist/src/context/project-detector.js.map +1 -0
  30. package/dist/src/context.d.ts +100 -0
  31. package/dist/src/context.d.ts.map +1 -0
  32. package/dist/src/context.js +157 -0
  33. package/dist/src/context.js.map +1 -0
  34. package/dist/src/core-shim.d.ts +7 -0
  35. package/dist/src/core-shim.d.ts.map +1 -0
  36. package/dist/src/core-shim.js +9 -0
  37. package/dist/src/core-shim.js.map +1 -0
  38. package/dist/src/health/healthCheck.d.ts +88 -0
  39. package/dist/src/health/healthCheck.d.ts.map +1 -0
  40. package/dist/src/health/healthCheck.js +117 -0
  41. package/dist/src/health/healthCheck.js.map +1 -0
  42. package/dist/src/health/index.d.ts +21 -0
  43. package/dist/src/health/index.d.ts.map +1 -0
  44. package/dist/src/health/index.js +21 -0
  45. package/dist/src/health/index.js.map +1 -0
  46. package/dist/src/health/readinessCheck.d.ts +139 -0
  47. package/dist/src/health/readinessCheck.d.ts.map +1 -0
  48. package/dist/src/health/readinessCheck.js +266 -0
  49. package/dist/src/health/readinessCheck.js.map +1 -0
  50. package/dist/src/index.d.ts +8 -0
  51. package/dist/src/index.d.ts.map +1 -0
  52. package/dist/src/index.js +178 -0
  53. package/dist/src/index.js.map +1 -0
  54. package/dist/src/index.test.d.ts +2 -0
  55. package/dist/src/index.test.d.ts.map +1 -0
  56. package/dist/src/index.test.js +43 -0
  57. package/dist/src/index.test.js.map +1 -0
  58. package/dist/src/logger.d.ts +26 -0
  59. package/dist/src/logger.d.ts.map +1 -0
  60. package/dist/src/logger.js +179 -0
  61. package/dist/src/logger.js.map +1 -0
  62. package/dist/src/middleware/__tests__/csp.test.d.ts +2 -0
  63. package/dist/src/middleware/__tests__/csp.test.d.ts.map +1 -0
  64. package/dist/src/middleware/__tests__/csp.test.js +389 -0
  65. package/dist/src/middleware/__tests__/csp.test.js.map +1 -0
  66. package/dist/src/middleware/csp.d.ts +87 -0
  67. package/dist/src/middleware/csp.d.ts.map +1 -0
  68. package/dist/src/middleware/csp.js +273 -0
  69. package/dist/src/middleware/csp.js.map +1 -0
  70. package/dist/src/middleware/degradation.d.ts +99 -0
  71. package/dist/src/middleware/degradation.d.ts.map +1 -0
  72. package/dist/src/middleware/degradation.js +315 -0
  73. package/dist/src/middleware/degradation.js.map +1 -0
  74. package/dist/src/middleware/errorFormatter.d.ts +119 -0
  75. package/dist/src/middleware/errorFormatter.d.ts.map +1 -0
  76. package/dist/src/middleware/errorFormatter.js +294 -0
  77. package/dist/src/middleware/errorFormatter.js.map +1 -0
  78. package/dist/src/middleware/index.d.ts +10 -0
  79. package/dist/src/middleware/index.d.ts.map +1 -0
  80. package/dist/src/middleware/index.js +14 -0
  81. package/dist/src/middleware/index.js.map +1 -0
  82. package/dist/src/middleware/license.d.ts +161 -0
  83. package/dist/src/middleware/license.d.ts.map +1 -0
  84. package/dist/src/middleware/license.js +281 -0
  85. package/dist/src/middleware/license.js.map +1 -0
  86. package/dist/src/middleware/toolFeatureMapping.d.ts +36 -0
  87. package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -0
  88. package/dist/src/middleware/toolFeatureMapping.js +90 -0
  89. package/dist/src/middleware/toolFeatureMapping.js.map +1 -0
  90. package/dist/src/onboarding/first-run.d.ts +64 -0
  91. package/dist/src/onboarding/first-run.d.ts.map +1 -0
  92. package/dist/src/onboarding/first-run.js +77 -0
  93. package/dist/src/onboarding/first-run.js.map +1 -0
  94. package/dist/src/onboarding/index.d.ts +7 -0
  95. package/dist/src/onboarding/index.d.ts.map +1 -0
  96. package/dist/src/onboarding/index.js +7 -0
  97. package/dist/src/onboarding/index.js.map +1 -0
  98. package/dist/src/suggestions/index.d.ts +21 -0
  99. package/dist/src/suggestions/index.d.ts.map +1 -0
  100. package/dist/src/suggestions/index.js +20 -0
  101. package/dist/src/suggestions/index.js.map +1 -0
  102. package/dist/src/suggestions/suggestion-engine.d.ts +185 -0
  103. package/dist/src/suggestions/suggestion-engine.d.ts.map +1 -0
  104. package/dist/src/suggestions/suggestion-engine.js +352 -0
  105. package/dist/src/suggestions/suggestion-engine.js.map +1 -0
  106. package/dist/src/suggestions/types.d.ts +88 -0
  107. package/dist/src/suggestions/types.d.ts.map +1 -0
  108. package/dist/src/suggestions/types.js +21 -0
  109. package/dist/src/suggestions/types.js.map +1 -0
  110. package/dist/src/tools/analyze.d.ts +151 -0
  111. package/dist/src/tools/analyze.d.ts.map +1 -0
  112. package/dist/src/tools/analyze.js +205 -0
  113. package/dist/src/tools/analyze.js.map +1 -0
  114. package/dist/src/tools/compare.d.ts +149 -0
  115. package/dist/src/tools/compare.d.ts.map +1 -0
  116. package/dist/src/tools/compare.js +464 -0
  117. package/dist/src/tools/compare.js.map +1 -0
  118. package/dist/src/tools/get-skill.d.ts +116 -0
  119. package/dist/src/tools/get-skill.d.ts.map +1 -0
  120. package/dist/src/tools/get-skill.js +224 -0
  121. package/dist/src/tools/get-skill.js.map +1 -0
  122. package/dist/src/tools/index.d.ts +20 -0
  123. package/dist/src/tools/index.d.ts.map +1 -0
  124. package/dist/src/tools/index.js +20 -0
  125. package/dist/src/tools/index.js.map +1 -0
  126. package/dist/src/tools/install.d.ts +122 -0
  127. package/dist/src/tools/install.d.ts.map +1 -0
  128. package/dist/src/tools/install.js +314 -0
  129. package/dist/src/tools/install.js.map +1 -0
  130. package/dist/src/tools/recommend.d.ts +171 -0
  131. package/dist/src/tools/recommend.d.ts.map +1 -0
  132. package/dist/src/tools/recommend.js +325 -0
  133. package/dist/src/tools/recommend.js.map +1 -0
  134. package/dist/src/tools/search.d.ts +121 -0
  135. package/dist/src/tools/search.d.ts.map +1 -0
  136. package/dist/src/tools/search.js +249 -0
  137. package/dist/src/tools/search.js.map +1 -0
  138. package/dist/src/tools/suggest.d.ts +181 -0
  139. package/dist/src/tools/suggest.d.ts.map +1 -0
  140. package/dist/src/tools/suggest.js +342 -0
  141. package/dist/src/tools/suggest.js.map +1 -0
  142. package/dist/src/tools/uninstall.d.ts +123 -0
  143. package/dist/src/tools/uninstall.d.ts.map +1 -0
  144. package/dist/src/tools/uninstall.js +250 -0
  145. package/dist/src/tools/uninstall.js.map +1 -0
  146. package/dist/src/tools/validate.d.ts +122 -0
  147. package/dist/src/tools/validate.d.ts.map +1 -0
  148. package/dist/src/tools/validate.js +497 -0
  149. package/dist/src/tools/validate.js.map +1 -0
  150. package/dist/src/utils/installed-skills.d.ts +101 -0
  151. package/dist/src/utils/installed-skills.d.ts.map +1 -0
  152. package/dist/src/utils/installed-skills.js +220 -0
  153. package/dist/src/utils/installed-skills.js.map +1 -0
  154. package/dist/src/utils/validation.d.ts +76 -0
  155. package/dist/src/utils/validation.d.ts.map +1 -0
  156. package/dist/src/utils/validation.js +153 -0
  157. package/dist/src/utils/validation.js.map +1 -0
  158. package/dist/src/webhooks/index.d.ts +8 -0
  159. package/dist/src/webhooks/index.d.ts.map +1 -0
  160. package/dist/src/webhooks/index.js +9 -0
  161. package/dist/src/webhooks/index.js.map +1 -0
  162. package/dist/src/webhooks/webhook-endpoint.d.ts +149 -0
  163. package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -0
  164. package/dist/src/webhooks/webhook-endpoint.js +339 -0
  165. package/dist/src/webhooks/webhook-endpoint.js.map +1 -0
  166. package/dist/tests/compare.test.d.ts +6 -0
  167. package/dist/tests/compare.test.d.ts.map +1 -0
  168. package/dist/tests/compare.test.js +225 -0
  169. package/dist/tests/compare.test.js.map +1 -0
  170. package/dist/tests/context/project-detector.test.d.ts +6 -0
  171. package/dist/tests/context/project-detector.test.d.ts.map +1 -0
  172. package/dist/tests/context/project-detector.test.js +719 -0
  173. package/dist/tests/context/project-detector.test.js.map +1 -0
  174. package/dist/tests/e2e/compare.e2e.test.d.ts +10 -0
  175. package/dist/tests/e2e/compare.e2e.test.d.ts.map +1 -0
  176. package/dist/tests/e2e/compare.e2e.test.js +286 -0
  177. package/dist/tests/e2e/compare.e2e.test.js.map +1 -0
  178. package/dist/tests/e2e/install-flow.e2e.test.d.ts +10 -0
  179. package/dist/tests/e2e/install-flow.e2e.test.d.ts.map +1 -0
  180. package/dist/tests/e2e/install-flow.e2e.test.js +209 -0
  181. package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -0
  182. package/dist/tests/e2e/recommend.e2e.test.d.ts +12 -0
  183. package/dist/tests/e2e/recommend.e2e.test.d.ts.map +1 -0
  184. package/dist/tests/e2e/recommend.e2e.test.js +347 -0
  185. package/dist/tests/e2e/recommend.e2e.test.js.map +1 -0
  186. package/dist/tests/e2e/skill-flow.e2e.test.d.ts +10 -0
  187. package/dist/tests/e2e/skill-flow.e2e.test.d.ts.map +1 -0
  188. package/dist/tests/e2e/skill-flow.e2e.test.js +280 -0
  189. package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -0
  190. package/dist/tests/e2e/suggest.e2e.test.d.ts +13 -0
  191. package/dist/tests/e2e/suggest.e2e.test.d.ts.map +1 -0
  192. package/dist/tests/e2e/suggest.e2e.test.js +347 -0
  193. package/dist/tests/e2e/suggest.e2e.test.js.map +1 -0
  194. package/dist/tests/e2e/utils/baseline-collector.d.ts +107 -0
  195. package/dist/tests/e2e/utils/baseline-collector.d.ts.map +1 -0
  196. package/dist/tests/e2e/utils/baseline-collector.js +211 -0
  197. package/dist/tests/e2e/utils/baseline-collector.js.map +1 -0
  198. package/dist/tests/e2e/utils/hardcoded-detector.d.ts +46 -0
  199. package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +1 -0
  200. package/dist/tests/e2e/utils/hardcoded-detector.js +255 -0
  201. package/dist/tests/e2e/utils/hardcoded-detector.js.map +1 -0
  202. package/dist/tests/e2e/utils/index.d.ts +7 -0
  203. package/dist/tests/e2e/utils/index.d.ts.map +1 -0
  204. package/dist/tests/e2e/utils/index.js +7 -0
  205. package/dist/tests/e2e/utils/index.js.map +1 -0
  206. package/dist/tests/e2e/utils/linear-reporter.d.ts +60 -0
  207. package/dist/tests/e2e/utils/linear-reporter.d.ts.map +1 -0
  208. package/dist/tests/e2e/utils/linear-reporter.js +232 -0
  209. package/dist/tests/e2e/utils/linear-reporter.js.map +1 -0
  210. package/dist/tests/health.test.d.ts +9 -0
  211. package/dist/tests/health.test.d.ts.map +1 -0
  212. package/dist/tests/health.test.js +308 -0
  213. package/dist/tests/health.test.js.map +1 -0
  214. package/dist/tests/integration/analyze.integration.test.d.ts +2 -0
  215. package/dist/tests/integration/analyze.integration.test.d.ts.map +1 -0
  216. package/dist/tests/integration/analyze.integration.test.js +244 -0
  217. package/dist/tests/integration/analyze.integration.test.js.map +1 -0
  218. package/dist/tests/integration/compare.integration.test.d.ts +2 -0
  219. package/dist/tests/integration/compare.integration.test.d.ts.map +1 -0
  220. package/dist/tests/integration/compare.integration.test.js +120 -0
  221. package/dist/tests/integration/compare.integration.test.js.map +1 -0
  222. package/dist/tests/integration/fixtures/test-skills.d.ts +62 -0
  223. package/dist/tests/integration/fixtures/test-skills.d.ts.map +1 -0
  224. package/dist/tests/integration/fixtures/test-skills.js +644 -0
  225. package/dist/tests/integration/fixtures/test-skills.js.map +1 -0
  226. package/dist/tests/integration/get-skill.integration.test.d.ts +6 -0
  227. package/dist/tests/integration/get-skill.integration.test.d.ts.map +1 -0
  228. package/dist/tests/integration/get-skill.integration.test.js +203 -0
  229. package/dist/tests/integration/get-skill.integration.test.js.map +1 -0
  230. package/dist/tests/integration/github-api.integration.test.d.ts +14 -0
  231. package/dist/tests/integration/github-api.integration.test.d.ts.map +1 -0
  232. package/dist/tests/integration/github-api.integration.test.js +190 -0
  233. package/dist/tests/integration/github-api.integration.test.js.map +1 -0
  234. package/dist/tests/integration/install.integration.test.d.ts +6 -0
  235. package/dist/tests/integration/install.integration.test.d.ts.map +1 -0
  236. package/dist/tests/integration/install.integration.test.js +282 -0
  237. package/dist/tests/integration/install.integration.test.js.map +1 -0
  238. package/dist/tests/integration/recommend.integration.test.d.ts +2 -0
  239. package/dist/tests/integration/recommend.integration.test.d.ts.map +1 -0
  240. package/dist/tests/integration/recommend.integration.test.js +215 -0
  241. package/dist/tests/integration/recommend.integration.test.js.map +1 -0
  242. package/dist/tests/integration/search.integration.test.d.ts +6 -0
  243. package/dist/tests/integration/search.integration.test.d.ts.map +1 -0
  244. package/dist/tests/integration/search.integration.test.js +229 -0
  245. package/dist/tests/integration/search.integration.test.js.map +1 -0
  246. package/dist/tests/integration/setup.d.ts +71 -0
  247. package/dist/tests/integration/setup.d.ts.map +1 -0
  248. package/dist/tests/integration/setup.js +124 -0
  249. package/dist/tests/integration/setup.js.map +1 -0
  250. package/dist/tests/integration/uninstall.integration.test.d.ts +6 -0
  251. package/dist/tests/integration/uninstall.integration.test.d.ts.map +1 -0
  252. package/dist/tests/integration/uninstall.integration.test.js +296 -0
  253. package/dist/tests/integration/uninstall.integration.test.js.map +1 -0
  254. package/dist/tests/integration/validate.integration.test.d.ts +2 -0
  255. package/dist/tests/integration/validate.integration.test.d.ts.map +1 -0
  256. package/dist/tests/integration/validate.integration.test.js +181 -0
  257. package/dist/tests/integration/validate.integration.test.js.map +1 -0
  258. package/dist/tests/onboarding/first-run.test.d.ts +7 -0
  259. package/dist/tests/onboarding/first-run.test.d.ts.map +1 -0
  260. package/dist/tests/onboarding/first-run.test.js +258 -0
  261. package/dist/tests/onboarding/first-run.test.js.map +1 -0
  262. package/dist/tests/performance/search-performance.test.d.ts +10 -0
  263. package/dist/tests/performance/search-performance.test.d.ts.map +1 -0
  264. package/dist/tests/performance/search-performance.test.js +218 -0
  265. package/dist/tests/performance/search-performance.test.js.map +1 -0
  266. package/dist/tests/recommend.test.d.ts +6 -0
  267. package/dist/tests/recommend.test.d.ts.map +1 -0
  268. package/dist/tests/recommend.test.js +208 -0
  269. package/dist/tests/recommend.test.js.map +1 -0
  270. package/dist/tests/suggestions/suggestion-engine.test.d.ts +6 -0
  271. package/dist/tests/suggestions/suggestion-engine.test.d.ts.map +1 -0
  272. package/dist/tests/suggestions/suggestion-engine.test.js +448 -0
  273. package/dist/tests/suggestions/suggestion-engine.test.js.map +1 -0
  274. package/dist/tests/test-utils.d.ts +74 -0
  275. package/dist/tests/test-utils.d.ts.map +1 -0
  276. package/dist/tests/test-utils.js +98 -0
  277. package/dist/tests/test-utils.js.map +1 -0
  278. package/dist/tests/tools.test.d.ts +5 -0
  279. package/dist/tests/tools.test.d.ts.map +1 -0
  280. package/dist/tests/tools.test.js +138 -0
  281. package/dist/tests/tools.test.js.map +1 -0
  282. package/dist/tests/unit/installed-skills.test.d.ts +6 -0
  283. package/dist/tests/unit/installed-skills.test.d.ts.map +1 -0
  284. package/dist/tests/unit/installed-skills.test.js +285 -0
  285. package/dist/tests/unit/installed-skills.test.js.map +1 -0
  286. package/dist/tests/unit/logger.test.d.ts +6 -0
  287. package/dist/tests/unit/logger.test.d.ts.map +1 -0
  288. package/dist/tests/unit/logger.test.js +281 -0
  289. package/dist/tests/unit/logger.test.js.map +1 -0
  290. package/dist/tests/validate.test.d.ts +5 -0
  291. package/dist/tests/validate.test.d.ts.map +1 -0
  292. package/dist/tests/validate.test.js +303 -0
  293. package/dist/tests/validate.test.js.map +1 -0
  294. package/dist/tests/webhooks/proxy-trust.security.test.d.ts +8 -0
  295. package/dist/tests/webhooks/proxy-trust.security.test.d.ts.map +1 -0
  296. package/dist/tests/webhooks/proxy-trust.security.test.js +145 -0
  297. package/dist/tests/webhooks/proxy-trust.security.test.js.map +1 -0
  298. package/dist/tests/webhooks/rate-limiter.security.test.d.ts +8 -0
  299. package/dist/tests/webhooks/rate-limiter.security.test.d.ts.map +1 -0
  300. package/dist/tests/webhooks/rate-limiter.security.test.js +122 -0
  301. package/dist/tests/webhooks/rate-limiter.security.test.js.map +1 -0
  302. package/dist/vitest.config.d.ts +6 -0
  303. package/dist/vitest.config.d.ts.map +1 -0
  304. package/dist/vitest.config.js +13 -0
  305. package/dist/vitest.config.js.map +1 -0
  306. 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"}