@get-technology-inc/jamf-docs-mcp-server 1.0.0 → 1.2.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 (103) hide show
  1. package/README.md +61 -139
  2. package/dist/completions.d.ts +13 -0
  3. package/dist/completions.d.ts.map +1 -0
  4. package/dist/completions.js +31 -0
  5. package/dist/completions.js.map +1 -0
  6. package/dist/constants.d.ts +123 -1
  7. package/dist/constants.d.ts.map +1 -1
  8. package/dist/constants.js +187 -17
  9. package/dist/constants.js.map +1 -1
  10. package/dist/index.js +46 -6
  11. package/dist/index.js.map +1 -1
  12. package/dist/prompts/compare-versions.d.ts +7 -0
  13. package/dist/prompts/compare-versions.d.ts.map +1 -0
  14. package/dist/prompts/compare-versions.js +56 -0
  15. package/dist/prompts/compare-versions.js.map +1 -0
  16. package/dist/prompts/index.d.ts +6 -0
  17. package/dist/prompts/index.d.ts.map +1 -0
  18. package/dist/prompts/index.js +12 -0
  19. package/dist/prompts/index.js.map +1 -0
  20. package/dist/prompts/setup-guide.d.ts +7 -0
  21. package/dist/prompts/setup-guide.d.ts.map +1 -0
  22. package/dist/prompts/setup-guide.js +53 -0
  23. package/dist/prompts/setup-guide.js.map +1 -0
  24. package/dist/prompts/troubleshoot.d.ts +7 -0
  25. package/dist/prompts/troubleshoot.d.ts.map +1 -0
  26. package/dist/prompts/troubleshoot.js +52 -0
  27. package/dist/prompts/troubleshoot.js.map +1 -0
  28. package/dist/resources/index.d.ts +13 -0
  29. package/dist/resources/index.d.ts.map +1 -0
  30. package/dist/resources/index.js +121 -0
  31. package/dist/resources/index.js.map +1 -0
  32. package/dist/schemas/index.d.ts +29 -63
  33. package/dist/schemas/index.d.ts.map +1 -1
  34. package/dist/schemas/index.js +35 -16
  35. package/dist/schemas/index.js.map +1 -1
  36. package/dist/schemas/output.d.ts +63 -0
  37. package/dist/schemas/output.d.ts.map +1 -0
  38. package/dist/schemas/output.js +63 -0
  39. package/dist/schemas/output.js.map +1 -0
  40. package/dist/services/cache.d.ts +37 -12
  41. package/dist/services/cache.d.ts.map +1 -1
  42. package/dist/services/cache.js +141 -41
  43. package/dist/services/cache.js.map +1 -1
  44. package/dist/services/metadata.d.ts +78 -0
  45. package/dist/services/metadata.d.ts.map +1 -0
  46. package/dist/services/metadata.js +362 -0
  47. package/dist/services/metadata.js.map +1 -0
  48. package/dist/services/scraper.d.ts +3 -2
  49. package/dist/services/scraper.d.ts.map +1 -1
  50. package/dist/services/scraper.js +170 -145
  51. package/dist/services/scraper.js.map +1 -1
  52. package/dist/services/search-suggestions.d.ts +27 -0
  53. package/dist/services/search-suggestions.d.ts.map +1 -0
  54. package/dist/services/search-suggestions.js +193 -0
  55. package/dist/services/search-suggestions.js.map +1 -0
  56. package/dist/services/tokenizer.d.ts +17 -1
  57. package/dist/services/tokenizer.d.ts.map +1 -1
  58. package/dist/services/tokenizer.js +122 -66
  59. package/dist/services/tokenizer.js.map +1 -1
  60. package/dist/tools/get-article.d.ts +1 -1
  61. package/dist/tools/get-article.d.ts.map +1 -1
  62. package/dist/tools/get-article.js +145 -70
  63. package/dist/tools/get-article.js.map +1 -1
  64. package/dist/tools/get-toc.d.ts +1 -1
  65. package/dist/tools/get-toc.d.ts.map +1 -1
  66. package/dist/tools/get-toc.js +107 -47
  67. package/dist/tools/get-toc.js.map +1 -1
  68. package/dist/tools/list-products.d.ts +1 -1
  69. package/dist/tools/list-products.d.ts.map +1 -1
  70. package/dist/tools/list-products.js +42 -13
  71. package/dist/tools/list-products.js.map +1 -1
  72. package/dist/tools/search.d.ts +1 -1
  73. package/dist/tools/search.d.ts.map +1 -1
  74. package/dist/tools/search.js +142 -69
  75. package/dist/tools/search.js.map +1 -1
  76. package/dist/transport/http.d.ts +12 -0
  77. package/dist/transport/http.d.ts.map +1 -0
  78. package/dist/transport/http.js +297 -0
  79. package/dist/transport/http.js.map +1 -0
  80. package/dist/transport/index.d.ts +13 -0
  81. package/dist/transport/index.d.ts.map +1 -0
  82. package/dist/transport/index.js +40 -0
  83. package/dist/transport/index.js.map +1 -0
  84. package/dist/types.d.ts +12 -18
  85. package/dist/types.d.ts.map +1 -1
  86. package/dist/types.js.map +1 -1
  87. package/dist/utils/doc-type.d.ts +9 -0
  88. package/dist/utils/doc-type.d.ts.map +1 -0
  89. package/dist/utils/doc-type.js +16 -0
  90. package/dist/utils/doc-type.js.map +1 -0
  91. package/dist/utils/progress.d.ts +13 -0
  92. package/dist/utils/progress.d.ts.map +1 -0
  93. package/dist/utils/progress.js +18 -0
  94. package/dist/utils/progress.js.map +1 -0
  95. package/dist/utils/sanitize.d.ts +30 -0
  96. package/dist/utils/sanitize.d.ts.map +1 -0
  97. package/dist/utils/sanitize.js +57 -0
  98. package/dist/utils/sanitize.js.map +1 -0
  99. package/dist/utils/url.d.ts +11 -0
  100. package/dist/utils/url.d.ts.map +1 -0
  101. package/dist/utils/url.js +23 -0
  102. package/dist/utils/url.js.map +1 -0
  103. package/package.json +8 -5
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Security sanitization utilities
3
+ *
4
+ * Functions for sanitizing user-controlled or externally-sourced content
5
+ * before interpolation into Markdown output or client-facing error messages.
6
+ */
7
+ /**
8
+ * Escape Markdown special characters in text to prevent Markdown injection.
9
+ * Use this for titles, snippets, and other text interpolated into Markdown.
10
+ */
11
+ export function sanitizeMarkdownText(text) {
12
+ return text.replace(/[[\]()#*_`~>!|\\]/g, '\\$&');
13
+ }
14
+ /**
15
+ * Sanitize a URL for use in Markdown link syntax.
16
+ * - Only allows https: protocol
17
+ * - Percent-encodes parentheses to prevent breaking Markdown links
18
+ * - Returns '#' for invalid or non-https URLs
19
+ */
20
+ export function sanitizeMarkdownUrl(url) {
21
+ try {
22
+ const parsed = new URL(url);
23
+ if (parsed.protocol !== 'https:') {
24
+ return '#';
25
+ }
26
+ // Percent-encode parentheses in the URL to prevent breaking Markdown link syntax
27
+ return url.replace(/\(/g, '%28').replace(/\)/g, '%29');
28
+ }
29
+ catch {
30
+ return '#';
31
+ }
32
+ }
33
+ /**
34
+ * Extract and sanitize an error message from an unknown thrown value.
35
+ */
36
+ export function getSafeErrorMessage(error) {
37
+ const raw = error instanceof Error ? error.message : 'Unknown error occurred';
38
+ return sanitizeErrorMessage(raw);
39
+ }
40
+ /**
41
+ * Sanitize error messages before returning to clients.
42
+ * - Replaces backend hostnames with frontend equivalents
43
+ * - Removes absolute file paths
44
+ * - Removes stack traces
45
+ */
46
+ export function sanitizeErrorMessage(message) {
47
+ let sanitized = message;
48
+ // Replace backend hostname with frontend (hostnames extracted from DOCS_API_URL / DOCS_BASE_URL)
49
+ sanitized = sanitized.replaceAll('learn-be.jamf.com', 'learn.jamf.com');
50
+ // Remove absolute file paths (Unix and Windows)
51
+ sanitized = sanitized.replace(/\/[\w./-]+\.\w{1,4}/g, '<path>');
52
+ sanitized = sanitized.replace(/[A-Z]:\\[\w.\\-]+\.\w{1,4}/g, '<path>');
53
+ // Remove stack traces (lines starting with "at ")
54
+ sanitized = sanitized.replace(/\n\s*at\s+.+/g, '');
55
+ return sanitized;
56
+ }
57
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,GAAG,CAAC;QACb,CAAC;QACD,iFAAiF;QACjF,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;IAC9E,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,IAAI,SAAS,GAAG,OAAO,CAAC;IAExB,iGAAiG;IACjG,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;IAExE,gDAAgD;IAChD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IAChE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;IAEvE,kDAAkD;IAClD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAEnD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * URL validation utilities
3
+ *
4
+ * Hostname allowlist and validation for Jamf documentation URLs.
5
+ * Shared by both the schema layer and the scraper service.
6
+ */
7
+ /** Allowed hostnames for URL validation. */
8
+ export declare const ALLOWED_HOSTNAMES: Set<string>;
9
+ /** Check whether a URL string points to an allowed Jamf documentation hostname. */
10
+ export declare function isAllowedHostname(urlStr: string): boolean;
11
+ //# sourceMappingURL=url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,aAI5B,CAAC;AAEH,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOzD"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * URL validation utilities
3
+ *
4
+ * Hostname allowlist and validation for Jamf documentation URLs.
5
+ * Shared by both the schema layer and the scraper service.
6
+ */
7
+ /** Allowed hostnames for URL validation. */
8
+ export const ALLOWED_HOSTNAMES = new Set([
9
+ 'learn.jamf.com',
10
+ 'learn-be.jamf.com',
11
+ 'docs.jamf.com',
12
+ ]);
13
+ /** Check whether a URL string points to an allowed Jamf documentation hostname. */
14
+ export function isAllowedHostname(urlStr) {
15
+ try {
16
+ const url = new URL(urlStr);
17
+ return ALLOWED_HOSTNAMES.has(url.hostname);
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ //# sourceMappingURL=url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4CAA4C;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,gBAAgB;IAChB,mBAAmB;IACnB,eAAe;CAChB,CAAC,CAAC;AAEH,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@get-technology-inc/jamf-docs-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "MCP Server for accessing Jamf Documentation (learn.jamf.com)",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -11,10 +11,13 @@
11
11
  "build": "tsc",
12
12
  "dev": "tsx watch src/index.ts",
13
13
  "start": "node dist/index.js",
14
+ "start:http": "node dist/index.js --transport http",
14
15
  "test": "vitest run",
15
16
  "test:watch": "vitest",
16
17
  "test:unit": "vitest run test/unit",
17
18
  "test:integration": "vitest run test/integration",
19
+ "test:e2e": "vitest run test/e2e",
20
+ "test:all": "vitest run test/unit && vitest run test/integration && vitest run test/e2e",
18
21
  "test:coverage": "vitest run --coverage",
19
22
  "test:inspector": "npx @modelcontextprotocol/inspector node dist/index.js",
20
23
  "lint": "eslint src/**/*.ts",
@@ -37,18 +40,18 @@
37
40
  "author": "GET Technology Inc.",
38
41
  "license": "MIT",
39
42
  "dependencies": {
40
- "@modelcontextprotocol/sdk": "^1.0.0",
41
- "axios": "^1.7.0",
43
+ "@modelcontextprotocol/sdk": "^1.27.1",
44
+ "axios": "^1.13.6",
42
45
  "cheerio": "^1.0.0",
43
46
  "turndown": "^7.2.0",
44
- "zod": "^3.23.0"
47
+ "zod": "^4.3.6"
45
48
  },
46
49
  "devDependencies": {
47
50
  "@eslint/js": "^9.17.0",
48
51
  "@types/node": "^25.0.9",
49
52
  "@types/turndown": "^5.0.5",
50
53
  "@vitest/coverage-v8": "^4.0.17",
51
- "eslint": "^9.17.0",
54
+ "eslint": "^9.39.4",
52
55
  "tsx": "^4.19.0",
53
56
  "typescript": "^5.6.0",
54
57
  "typescript-eslint": "^8.18.0",