@get-technology-inc/jamf-docs-mcp-server 3.0.5 → 3.0.7
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/core/constants/doc-types.d.ts +48 -0
- package/dist/core/constants/doc-types.d.ts.map +1 -0
- package/dist/core/constants/doc-types.js +58 -0
- package/dist/core/constants/doc-types.js.map +1 -0
- package/dist/core/constants/index.d.ts +16 -0
- package/dist/core/constants/index.d.ts.map +1 -0
- package/dist/core/constants/index.js +12 -0
- package/dist/core/constants/index.js.map +1 -0
- package/dist/core/constants/limits.d.ts +39 -0
- package/dist/core/constants/limits.d.ts.map +1 -0
- package/dist/core/constants/limits.js +51 -0
- package/dist/core/constants/limits.js.map +1 -0
- package/dist/core/constants/locales.d.ts +34 -0
- package/dist/core/constants/locales.d.ts.map +1 -0
- package/dist/core/constants/locales.js +20 -0
- package/dist/core/constants/locales.js.map +1 -0
- package/dist/core/constants/products.d.ts +127 -0
- package/dist/core/constants/products.d.ts.map +1 -0
- package/dist/core/constants/products.js +135 -0
- package/dist/core/constants/products.js.map +1 -0
- package/dist/core/constants/topics.d.ts +168 -0
- package/dist/core/constants/topics.d.ts.map +1 -0
- package/dist/core/constants/topics.js +186 -0
- package/dist/core/constants/topics.js.map +1 -0
- package/dist/core/constants.d.ts +7 -404
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +16 -427
- package/dist/core/constants.js.map +1 -1
- package/dist/core/http-client.d.ts +14 -2
- package/dist/core/http-client.d.ts.map +1 -1
- package/dist/core/http-client.js +148 -17
- package/dist/core/http-client.js.map +1 -1
- package/dist/core/index.d.ts +12 -12
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +12 -13
- package/dist/core/index.js.map +1 -1
- package/dist/core/resources/index.js +1 -1
- package/dist/core/resources/index.js.map +1 -1
- package/dist/core/schemas/index.d.ts +3 -1
- package/dist/core/schemas/index.d.ts.map +1 -1
- package/dist/core/schemas/index.js +12 -1
- package/dist/core/schemas/index.js.map +1 -1
- package/dist/core/schemas/output.d.ts +7 -0
- package/dist/core/schemas/output.d.ts.map +1 -1
- package/dist/core/schemas/output.js +7 -0
- package/dist/core/schemas/output.js.map +1 -1
- package/dist/core/services/article-service.d.ts +24 -0
- package/dist/core/services/article-service.d.ts.map +1 -0
- package/dist/core/services/article-service.js +118 -0
- package/dist/core/services/article-service.js.map +1 -0
- package/dist/core/services/content-parser.d.ts +38 -0
- package/dist/core/services/content-parser.d.ts.map +1 -0
- package/dist/core/services/content-parser.js +146 -0
- package/dist/core/services/content-parser.js.map +1 -0
- package/dist/core/services/ft-client.d.ts +52 -0
- package/dist/core/services/ft-client.d.ts.map +1 -0
- package/dist/core/services/ft-client.js +87 -0
- package/dist/core/services/ft-client.js.map +1 -0
- package/dist/core/services/glossary.d.ts +9 -5
- package/dist/core/services/glossary.d.ts.map +1 -1
- package/dist/core/services/glossary.js +174 -107
- package/dist/core/services/glossary.js.map +1 -1
- package/dist/core/services/interfaces/cache.d.ts +6 -6
- package/dist/core/services/interfaces/cache.d.ts.map +1 -1
- package/dist/core/services/interfaces/index.d.ts +3 -3
- package/dist/core/services/interfaces/index.d.ts.map +1 -1
- package/dist/core/services/interfaces/logger.d.ts +17 -10
- package/dist/core/services/interfaces/logger.d.ts.map +1 -1
- package/dist/core/services/interfaces/metadata.d.ts +0 -10
- package/dist/core/services/interfaces/metadata.d.ts.map +1 -1
- package/dist/core/services/interfaces/providers.d.ts +26 -10
- package/dist/core/services/interfaces/providers.d.ts.map +1 -1
- package/dist/core/services/logging.d.ts +38 -18
- package/dist/core/services/logging.d.ts.map +1 -1
- package/dist/core/services/logging.js +78 -29
- package/dist/core/services/logging.js.map +1 -1
- package/dist/core/services/maps-registry.d.ts +82 -0
- package/dist/core/services/maps-registry.d.ts.map +1 -0
- package/dist/core/services/maps-registry.js +232 -0
- package/dist/core/services/maps-registry.js.map +1 -0
- package/dist/core/services/metadata.d.ts +18 -9
- package/dist/core/services/metadata.d.ts.map +1 -1
- package/dist/core/services/metadata.js +113 -254
- package/dist/core/services/metadata.js.map +1 -1
- package/dist/core/services/search-service.d.ts +31 -0
- package/dist/core/services/search-service.d.ts.map +1 -0
- package/dist/core/services/search-service.js +471 -0
- package/dist/core/services/search-service.js.map +1 -0
- package/dist/core/services/toc-service.d.ts +30 -0
- package/dist/core/services/toc-service.d.ts.map +1 -0
- package/dist/core/services/toc-service.js +101 -0
- package/dist/core/services/toc-service.js.map +1 -0
- package/dist/core/services/tokenizer.d.ts +1 -1
- package/dist/core/services/tokenizer.d.ts.map +1 -1
- package/dist/core/services/tokenizer.js +3 -3
- package/dist/core/services/tokenizer.js.map +1 -1
- package/dist/core/services/topic-resolver.d.ts +57 -0
- package/dist/core/services/topic-resolver.d.ts.map +1 -0
- package/dist/core/services/topic-resolver.js +185 -0
- package/dist/core/services/topic-resolver.js.map +1 -0
- package/dist/core/tools/batch-get-articles.d.ts +0 -2
- package/dist/core/tools/batch-get-articles.d.ts.map +1 -1
- package/dist/core/tools/batch-get-articles.js +12 -46
- package/dist/core/tools/batch-get-articles.js.map +1 -1
- package/dist/core/tools/get-article.d.ts.map +1 -1
- package/dist/core/tools/get-article.js +29 -112
- package/dist/core/tools/get-article.js.map +1 -1
- package/dist/core/tools/get-toc.js +1 -1
- package/dist/core/tools/get-toc.js.map +1 -1
- package/dist/core/tools/search.js +5 -5
- package/dist/core/tools/search.js.map +1 -1
- package/dist/core/types/context.d.ts +5 -2
- package/dist/core/types/context.d.ts.map +1 -1
- package/dist/core/types.d.ts +141 -31
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/bundle.d.ts +14 -1
- package/dist/core/utils/bundle.d.ts.map +1 -1
- package/dist/core/utils/bundle.js +19 -2
- package/dist/core/utils/bundle.js.map +1 -1
- package/dist/core/utils/format-article.d.ts +45 -0
- package/dist/core/utils/format-article.d.ts.map +1 -0
- package/dist/core/utils/format-article.js +138 -0
- package/dist/core/utils/format-article.js.map +1 -0
- package/dist/core/utils/ft-metadata.d.ts +22 -0
- package/dist/core/utils/ft-metadata.d.ts.map +1 -0
- package/dist/core/utils/ft-metadata.js +30 -0
- package/dist/core/utils/ft-metadata.js.map +1 -0
- package/dist/core/utils/sanitize.d.ts.map +1 -1
- package/dist/core/utils/sanitize.js +0 -2
- package/dist/core/utils/sanitize.js.map +1 -1
- package/dist/core/utils/url.d.ts.map +1 -1
- package/dist/core/utils/url.js +0 -1
- package/dist/core/utils/url.js.map +1 -1
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/platforms/node/http-server.d.ts +13 -0
- package/dist/platforms/node/http-server.d.ts.map +1 -0
- package/dist/platforms/node/http-server.js +231 -0
- package/dist/platforms/node/http-server.js.map +1 -0
- package/dist/platforms/node/index.d.ts +1 -1
- package/dist/platforms/node/index.d.ts.map +1 -1
- package/dist/platforms/node/index.js +1 -1
- package/dist/platforms/node/index.js.map +1 -1
- package/dist/platforms/node/logger.d.ts +13 -2
- package/dist/platforms/node/logger.d.ts.map +1 -1
- package/dist/platforms/node/logger.js +17 -4
- package/dist/platforms/node/logger.js.map +1 -1
- package/dist/transport/http-handler.d.ts +25 -0
- package/dist/transport/http-handler.d.ts.map +1 -0
- package/dist/transport/http-handler.js +193 -0
- package/dist/transport/http-handler.js.map +1 -0
- package/dist/transport/http-types.d.ts +22 -0
- package/dist/transport/http-types.d.ts.map +1 -0
- package/dist/transport/http-types.js +65 -0
- package/dist/transport/http-types.js.map +1 -0
- package/dist/transport/http.d.ts +4 -8
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/http.js +4 -376
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/index.js +2 -2
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/rate-limiter.d.ts +16 -0
- package/dist/transport/rate-limiter.d.ts.map +1 -0
- package/dist/transport/rate-limiter.js +55 -0
- package/dist/transport/rate-limiter.js.map +1 -0
- package/package.json +3 -3
- package/dist/core/services/interfaces.d.ts +0 -94
- package/dist/core/services/interfaces.d.ts.map +0 -1
- package/dist/core/services/interfaces.js +0 -8
- package/dist/core/services/interfaces.js.map +0 -1
- package/dist/core/services/scraper.d.ts +0 -90
- package/dist/core/services/scraper.d.ts.map +0 -1
- package/dist/core/services/scraper.js +0 -966
- package/dist/core/services/scraper.js.map +0 -1
- package/dist/core/utils/doc-type.d.ts +0 -12
- package/dist/core/utils/doc-type.d.ts.map +0 -1
- package/dist/core/utils/doc-type.js +0 -24
- package/dist/core/utils/doc-type.js.map +0 -1
- package/dist/platforms/node/metadata.d.ts +0 -18
- package/dist/platforms/node/metadata.d.ts.map +0 -1
- package/dist/platforms/node/metadata.js +0 -35
- package/dist/platforms/node/metadata.js.map +0 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types and constants for the HTTP transport layer.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_HTTP_CONFIG = {
|
|
5
|
+
serverVersion: '3.0.6',
|
|
6
|
+
corsAllowedOrigins: [],
|
|
7
|
+
trustProxy: false,
|
|
8
|
+
rateLimitRpm: 60,
|
|
9
|
+
maxBodySize: 1_048_576,
|
|
10
|
+
enableJsonResponse: true,
|
|
11
|
+
shutdownTimeoutMs: 10_000,
|
|
12
|
+
};
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Static content
|
|
15
|
+
// ============================================================================
|
|
16
|
+
export const LLMS_TXT = `# Jamf Docs MCP Server
|
|
17
|
+
|
|
18
|
+
> MCP server providing access to official Jamf documentation from learn.jamf.com
|
|
19
|
+
|
|
20
|
+
## Products
|
|
21
|
+
- Jamf Pro — Apple device management for enterprise
|
|
22
|
+
- Jamf School — Apple device management for education
|
|
23
|
+
- Jamf Connect — identity and access management
|
|
24
|
+
- Jamf Protect — endpoint security for Apple
|
|
25
|
+
- Jamf Now — simple device management for small businesses
|
|
26
|
+
- Jamf Safe Internet — content filtering and web security
|
|
27
|
+
- Jamf Insights — analytics and reporting for Apple fleet
|
|
28
|
+
- RapidIdentity — identity and access management platform
|
|
29
|
+
|
|
30
|
+
## Tools
|
|
31
|
+
- jamf_docs_list_products: discover available products and versions
|
|
32
|
+
- jamf_docs_search: search documentation by keyword with product/topic filters
|
|
33
|
+
- jamf_docs_get_article: retrieve full article content in markdown
|
|
34
|
+
- jamf_docs_get_toc: browse table of contents for a product
|
|
35
|
+
- jamf_docs_glossary_lookup: look up glossary terms with fuzzy matching
|
|
36
|
+
- jamf_docs_batch_get_articles: retrieve multiple articles in a single request
|
|
37
|
+
|
|
38
|
+
## Resources
|
|
39
|
+
- jamf://products — product list with metadata and versions
|
|
40
|
+
- jamf://topics — topic categories per product
|
|
41
|
+
- jamf://products/{productId}/toc — table of contents for a specific product
|
|
42
|
+
- jamf://products/{productId}/versions — available documentation versions
|
|
43
|
+
|
|
44
|
+
## Prompts
|
|
45
|
+
- jamf_troubleshoot: guided troubleshooting workflow
|
|
46
|
+
- jamf_setup_guide: step-by-step setup instructions
|
|
47
|
+
- jamf_compare_versions: compare features across versions
|
|
48
|
+
|
|
49
|
+
## Supported Locales
|
|
50
|
+
en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH
|
|
51
|
+
|
|
52
|
+
## Limitations
|
|
53
|
+
- Documentation content only — no Jamf REST API reference
|
|
54
|
+
- Content is sourced from learn.jamf.com and cached; not real-time
|
|
55
|
+
`;
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Error classes
|
|
58
|
+
// ============================================================================
|
|
59
|
+
export class PayloadTooLargeError extends Error {
|
|
60
|
+
constructor() {
|
|
61
|
+
super('Payload too large');
|
|
62
|
+
this.name = 'PayloadTooLargeError';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=http-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-types.js","sourceRoot":"","sources":["../../src/transport/http-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,aAAa,EAAE,OAAO;IACtB,kBAAkB,EAAE,EAAE;IACtB,UAAU,EAAE,KAAK;IACjB,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,SAAS;IACtB,kBAAkB,EAAE,IAAI;IACxB,iBAAiB,EAAE,MAAM;CAC1B,CAAC;AAEF,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCvB,CAAC;AAEF,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C;QACE,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
|
package/dist/transport/http.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Backward-compatible re-export.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The real implementation lives in `platforms/node/http-server.ts`.
|
|
5
|
+
* This shim preserves the dynamic import path used in `src/index.ts`.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Create and start an HTTP server for the MCP server
|
|
10
|
-
*/
|
|
11
|
-
export declare function startHttpServer(mcpServer: McpServer, port: number, host: string): Promise<void>;
|
|
7
|
+
export { startHttpServer } from '../platforms/node/http-server.js';
|
|
12
8
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/transport/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/transport/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC"}
|
package/dist/transport/http.js
CHANGED
|
@@ -1,380 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Backward-compatible re-export.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The real implementation lives in `platforms/node/http-server.ts`.
|
|
5
|
+
* This shim preserves the dynamic import path used in `src/index.ts`.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
|
|
9
|
-
import { createNodeConfig, getEnvNumber } from '../platforms/node/config.js';
|
|
10
|
-
const SERVER_VERSION = createNodeConfig().version;
|
|
11
|
-
import { createLogger } from '../core/services/logging.js';
|
|
12
|
-
const log = createLogger('http');
|
|
13
|
-
const SHUTDOWN_TIMEOUT = 10_000;
|
|
14
|
-
const MAX_BODY_SIZE = 1_048_576; // 1MB
|
|
15
|
-
const LLMS_TXT = `# Jamf Docs MCP Server
|
|
16
|
-
|
|
17
|
-
> MCP server providing access to official Jamf documentation from learn.jamf.com
|
|
18
|
-
|
|
19
|
-
## Products
|
|
20
|
-
- Jamf Pro — Apple device management for enterprise
|
|
21
|
-
- Jamf School — Apple device management for education
|
|
22
|
-
- Jamf Connect — identity and access management
|
|
23
|
-
- Jamf Protect — endpoint security for Apple
|
|
24
|
-
- Jamf Now — simple device management for small businesses
|
|
25
|
-
- Jamf Safe Internet — content filtering and web security
|
|
26
|
-
- Jamf Insights — analytics and reporting for Apple fleet
|
|
27
|
-
- RapidIdentity — identity and access management platform
|
|
28
|
-
|
|
29
|
-
## Tools
|
|
30
|
-
- jamf_docs_list_products: discover available products and versions
|
|
31
|
-
- jamf_docs_search: search documentation by keyword with product/topic filters
|
|
32
|
-
- jamf_docs_get_article: retrieve full article content in markdown
|
|
33
|
-
- jamf_docs_get_toc: browse table of contents for a product
|
|
34
|
-
- jamf_docs_glossary_lookup: look up glossary terms with fuzzy matching
|
|
35
|
-
- jamf_docs_batch_get_articles: retrieve multiple articles in a single request
|
|
36
|
-
|
|
37
|
-
## Resources
|
|
38
|
-
- jamf://products — product list with metadata and versions
|
|
39
|
-
- jamf://topics — topic categories per product
|
|
40
|
-
- jamf://products/{productId}/toc — table of contents for a specific product
|
|
41
|
-
- jamf://products/{productId}/versions — available documentation versions
|
|
42
|
-
|
|
43
|
-
## Prompts
|
|
44
|
-
- jamf_troubleshoot: guided troubleshooting workflow
|
|
45
|
-
- jamf_setup_guide: step-by-step setup instructions
|
|
46
|
-
- jamf_compare_versions: compare features across versions
|
|
47
|
-
|
|
48
|
-
## Supported Locales
|
|
49
|
-
en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH
|
|
50
|
-
|
|
51
|
-
## Limitations
|
|
52
|
-
- Documentation content only — no Jamf REST API reference
|
|
53
|
-
- Content is sourced from learn.jamf.com and cached; not real-time
|
|
54
|
-
`;
|
|
55
|
-
class PayloadTooLargeError extends Error {
|
|
56
|
-
constructor() {
|
|
57
|
-
super('Payload too large');
|
|
58
|
-
this.name = 'PayloadTooLargeError';
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// CORS configuration
|
|
62
|
-
const CORS_ALLOWED_ORIGINS = (process.env.CORS_ALLOWED_ORIGINS ?? '').split(',').map(s => s.trim()).filter(Boolean);
|
|
63
|
-
// Trust reverse proxy headers (X-Forwarded-For) only when explicitly enabled
|
|
64
|
-
const TRUST_PROXY = process.env.TRUST_PROXY === 'true' || process.env.TRUST_PROXY === '1';
|
|
65
|
-
// Maximum unique IPs tracked by rate limiter to prevent memory exhaustion
|
|
66
|
-
const MAX_RATE_LIMIT_BUCKETS = 10_000;
|
|
67
|
-
/**
|
|
68
|
-
* Token bucket rate limiter (per-IP)
|
|
69
|
-
*/
|
|
70
|
-
class RateLimiter {
|
|
71
|
-
buckets = new Map();
|
|
72
|
-
maxTokens;
|
|
73
|
-
windowMs;
|
|
74
|
-
maxBuckets;
|
|
75
|
-
constructor(maxTokens, windowMs, maxBuckets = MAX_RATE_LIMIT_BUCKETS) {
|
|
76
|
-
this.maxTokens = maxTokens;
|
|
77
|
-
this.windowMs = windowMs;
|
|
78
|
-
this.maxBuckets = maxBuckets;
|
|
79
|
-
}
|
|
80
|
-
isAllowed(ip) {
|
|
81
|
-
const now = Date.now();
|
|
82
|
-
let bucket = this.buckets.get(ip);
|
|
83
|
-
if (bucket === undefined) {
|
|
84
|
-
// Evict oldest entry if at capacity to prevent memory exhaustion
|
|
85
|
-
if (this.buckets.size >= this.maxBuckets) {
|
|
86
|
-
this.evictOldest();
|
|
87
|
-
}
|
|
88
|
-
bucket = { tokens: this.maxTokens, lastRefill: now };
|
|
89
|
-
this.buckets.set(ip, bucket);
|
|
90
|
-
}
|
|
91
|
-
// Refill tokens based on elapsed time
|
|
92
|
-
const elapsed = now - bucket.lastRefill;
|
|
93
|
-
const tokensToAdd = (elapsed / this.windowMs) * this.maxTokens;
|
|
94
|
-
bucket.tokens = Math.min(this.maxTokens, bucket.tokens + tokensToAdd);
|
|
95
|
-
bucket.lastRefill = now;
|
|
96
|
-
if (bucket.tokens >= 1) {
|
|
97
|
-
bucket.tokens -= 1;
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
// Evict the oldest (least recently seen) bucket entry
|
|
103
|
-
evictOldest() {
|
|
104
|
-
let oldestKey;
|
|
105
|
-
let oldestTime = Infinity;
|
|
106
|
-
for (const [key, bucket] of this.buckets.entries()) {
|
|
107
|
-
if (bucket.lastRefill < oldestTime) {
|
|
108
|
-
oldestTime = bucket.lastRefill;
|
|
109
|
-
oldestKey = key;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (oldestKey !== undefined) {
|
|
113
|
-
this.buckets.delete(oldestKey);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// Periodically clean up old entries to prevent memory leak
|
|
117
|
-
cleanup() {
|
|
118
|
-
const now = Date.now();
|
|
119
|
-
for (const [ip, bucket] of this.buckets.entries()) {
|
|
120
|
-
if (now - bucket.lastRefill > this.windowMs * 2) {
|
|
121
|
-
this.buckets.delete(ip);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
/** Security headers applied to all responses (defense-in-depth) */
|
|
127
|
-
const SECURITY_HEADERS = {
|
|
128
|
-
'X-Content-Type-Options': 'nosniff',
|
|
129
|
-
'X-Frame-Options': 'DENY',
|
|
130
|
-
'Cache-Control': 'no-store',
|
|
131
|
-
};
|
|
132
|
-
/**
|
|
133
|
-
* Get CORS headers for a given origin
|
|
134
|
-
*/
|
|
135
|
-
function getCorsHeaders(origin) {
|
|
136
|
-
const headers = { ...SECURITY_HEADERS };
|
|
137
|
-
if (CORS_ALLOWED_ORIGINS.length === 0) {
|
|
138
|
-
// No origins configured — deny cross-origin by not setting Access-Control-Allow-Origin
|
|
139
|
-
return headers;
|
|
140
|
-
}
|
|
141
|
-
const originStr = Array.isArray(origin) ? origin[0] : origin;
|
|
142
|
-
if (originStr !== undefined && CORS_ALLOWED_ORIGINS.includes(originStr)) {
|
|
143
|
-
headers['Access-Control-Allow-Origin'] = originStr;
|
|
144
|
-
headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS';
|
|
145
|
-
headers['Access-Control-Allow-Headers'] = 'Content-Type';
|
|
146
|
-
headers['Access-Control-Max-Age'] = '86400';
|
|
147
|
-
headers.Vary = 'Origin';
|
|
148
|
-
}
|
|
149
|
-
return headers;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Get client IP from request.
|
|
153
|
-
* Only trusts X-Forwarded-For when TRUST_PROXY is enabled.
|
|
154
|
-
*/
|
|
155
|
-
function getClientIp(req) {
|
|
156
|
-
if (TRUST_PROXY) {
|
|
157
|
-
const forwarded = req.headers['x-forwarded-for'];
|
|
158
|
-
if (typeof forwarded === 'string') {
|
|
159
|
-
return forwarded.split(',')[0]?.trim() ?? 'unknown';
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
// socket may be undefined in test environments
|
|
163
|
-
const socket = req.socket;
|
|
164
|
-
return socket?.remoteAddress ?? 'unknown';
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Convert Node.js IncomingMessage to a Web Standard Request
|
|
168
|
-
*/
|
|
169
|
-
function toWebRequest(req, body, url) {
|
|
170
|
-
const headers = new Headers();
|
|
171
|
-
for (const [key, value] of Object.entries(req.headers)) {
|
|
172
|
-
if (value !== undefined) {
|
|
173
|
-
if (Array.isArray(value)) {
|
|
174
|
-
for (const v of value) {
|
|
175
|
-
headers.append(key, v);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
headers.set(key, value);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
const method = req.method ?? 'GET';
|
|
184
|
-
const init = {
|
|
185
|
-
method,
|
|
186
|
-
headers,
|
|
187
|
-
};
|
|
188
|
-
// Only add body for methods that support it
|
|
189
|
-
if (method !== 'GET' && method !== 'HEAD' && method !== 'DELETE') {
|
|
190
|
-
init.body = body;
|
|
191
|
-
}
|
|
192
|
-
return new Request(url.toString(), init);
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Write a Web Standard Response back to Node.js ServerResponse
|
|
196
|
-
*/
|
|
197
|
-
async function writeWebResponse(webRes, res) {
|
|
198
|
-
res.writeHead(webRes.status, Object.fromEntries(webRes.headers.entries()));
|
|
199
|
-
if (webRes.body === null) {
|
|
200
|
-
res.end();
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const reader = webRes.body.getReader();
|
|
204
|
-
try {
|
|
205
|
-
for (;;) {
|
|
206
|
-
const result = await reader.read();
|
|
207
|
-
if (result.done) {
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
res.write(result.value);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
finally {
|
|
214
|
-
reader.releaseLock();
|
|
215
|
-
res.end();
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Collect request body from IncomingMessage into a Buffer.
|
|
220
|
-
* Enforces a maximum body size to prevent memory exhaustion.
|
|
221
|
-
*/
|
|
222
|
-
async function collectBody(req) {
|
|
223
|
-
const chunks = [];
|
|
224
|
-
let totalSize = 0;
|
|
225
|
-
for await (const chunk of req) {
|
|
226
|
-
const buf = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
|
|
227
|
-
totalSize += buf.length;
|
|
228
|
-
if (totalSize > MAX_BODY_SIZE) {
|
|
229
|
-
req.destroy();
|
|
230
|
-
throw new PayloadTooLargeError();
|
|
231
|
-
}
|
|
232
|
-
chunks.push(buf);
|
|
233
|
-
}
|
|
234
|
-
return Buffer.concat(chunks);
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Create and start an HTTP server for the MCP server
|
|
238
|
-
*/
|
|
239
|
-
export async function startHttpServer(mcpServer, port, host) {
|
|
240
|
-
const rateLimitRpm = getEnvNumber('RATE_LIMIT_RPM', 60, 1, 10000);
|
|
241
|
-
const rateLimiter = new RateLimiter(rateLimitRpm, 60_000);
|
|
242
|
-
setInterval(() => { rateLimiter.cleanup(); }, 5 * 60_000).unref();
|
|
243
|
-
const httpServer = createServer((req, res) => {
|
|
244
|
-
void handleHttpRequest(req, res, mcpServer, rateLimiter);
|
|
245
|
-
});
|
|
246
|
-
// Graceful shutdown
|
|
247
|
-
let shuttingDown = false;
|
|
248
|
-
function shutdown(signal) {
|
|
249
|
-
if (shuttingDown) {
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
shuttingDown = true;
|
|
253
|
-
log.info(`${signal} received, shutting down...`);
|
|
254
|
-
httpServer.close(() => {
|
|
255
|
-
log.info('HTTP server closed');
|
|
256
|
-
process.exit(0);
|
|
257
|
-
});
|
|
258
|
-
// Force exit after timeout
|
|
259
|
-
setTimeout(() => {
|
|
260
|
-
log.warning('Shutdown timeout, forcing exit');
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}, SHUTDOWN_TIMEOUT);
|
|
263
|
-
}
|
|
264
|
-
process.on('SIGINT', () => { shutdown('SIGINT'); });
|
|
265
|
-
process.on('SIGTERM', () => { shutdown('SIGTERM'); });
|
|
266
|
-
// Start listening
|
|
267
|
-
await new Promise((resolve, reject) => {
|
|
268
|
-
httpServer.on('error', (error) => {
|
|
269
|
-
if (error.code === 'EADDRINUSE') {
|
|
270
|
-
log.error(`Port ${port} is already in use`);
|
|
271
|
-
process.exit(1);
|
|
272
|
-
}
|
|
273
|
-
reject(error);
|
|
274
|
-
});
|
|
275
|
-
httpServer.listen(port, host, () => {
|
|
276
|
-
if (host !== '127.0.0.1' && host !== '::1') {
|
|
277
|
-
log.warning(`Server is binding to ${host}, which exposes it to the network. Use 127.0.0.1 for local-only access.`);
|
|
278
|
-
}
|
|
279
|
-
log.info(`Jamf Docs MCP Server running on http://${host}:${port}`);
|
|
280
|
-
log.info(`MCP endpoint: http://${host}:${port}/mcp`);
|
|
281
|
-
log.info(`Health check: http://${host}:${port}/health`);
|
|
282
|
-
log.info(`LLMs info: http://${host}:${port}/llms.txt`);
|
|
283
|
-
resolve();
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Handle a single HTTP request
|
|
289
|
-
*/
|
|
290
|
-
async function handleHttpRequest(req, res, mcpServer, rateLimiter) {
|
|
291
|
-
// Use hardcoded base URL to prevent Host header injection (SAST #8)
|
|
292
|
-
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
293
|
-
const { pathname } = url;
|
|
294
|
-
const { origin } = req.headers;
|
|
295
|
-
const corsHeaders = getCorsHeaders(origin);
|
|
296
|
-
// Handle CORS preflight
|
|
297
|
-
if (req.method === 'OPTIONS') {
|
|
298
|
-
res.writeHead(204, { ...corsHeaders, 'Content-Length': '0' });
|
|
299
|
-
res.end();
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
// Rate limiting
|
|
303
|
-
const clientIp = getClientIp(req);
|
|
304
|
-
if (!rateLimiter.isAllowed(clientIp)) {
|
|
305
|
-
res.writeHead(429, { 'Content-Type': 'application/json', ...corsHeaders });
|
|
306
|
-
res.end(JSON.stringify({ error: 'Too many requests' }));
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
// Health check endpoint
|
|
310
|
-
if (pathname === '/health' && req.method === 'GET') {
|
|
311
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...corsHeaders });
|
|
312
|
-
res.end(JSON.stringify({ status: 'ok', version: SERVER_VERSION }));
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
// llms.txt endpoint
|
|
316
|
-
if (pathname === '/llms.txt' && req.method === 'GET') {
|
|
317
|
-
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8', ...corsHeaders });
|
|
318
|
-
res.end(LLMS_TXT);
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
// MCP endpoint
|
|
322
|
-
if (pathname === '/mcp') {
|
|
323
|
-
let body;
|
|
324
|
-
try {
|
|
325
|
-
body = await collectBody(req);
|
|
326
|
-
}
|
|
327
|
-
catch (err) {
|
|
328
|
-
if (err instanceof PayloadTooLargeError) {
|
|
329
|
-
res.writeHead(413, { 'Content-Type': 'application/json', ...corsHeaders });
|
|
330
|
-
res.end(JSON.stringify({ error: 'Payload too large' }));
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
throw err;
|
|
334
|
-
}
|
|
335
|
-
// Create a per-request transport (stateless mode)
|
|
336
|
-
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
337
|
-
enableJsonResponse: true,
|
|
338
|
-
});
|
|
339
|
-
// Connect the MCP server to this transport
|
|
340
|
-
await mcpServer.connect(transport);
|
|
341
|
-
try {
|
|
342
|
-
// Convert Node request to Web Standard Request
|
|
343
|
-
const webReq = toWebRequest(req, body, url);
|
|
344
|
-
// Parse body for the transport if present
|
|
345
|
-
let parsedBody;
|
|
346
|
-
if (body.length > 0) {
|
|
347
|
-
try {
|
|
348
|
-
parsedBody = JSON.parse(body.toString());
|
|
349
|
-
}
|
|
350
|
-
catch {
|
|
351
|
-
res.writeHead(400, { 'Content-Type': 'application/json', ...corsHeaders });
|
|
352
|
-
res.end(JSON.stringify({ error: 'Invalid JSON in request body' }));
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
// Handle the request
|
|
357
|
-
const webRes = await transport.handleRequest(webReq, { parsedBody });
|
|
358
|
-
// Add CORS headers to the web response before writing
|
|
359
|
-
for (const [key, value] of Object.entries(corsHeaders)) {
|
|
360
|
-
webRes.headers.set(key, value);
|
|
361
|
-
}
|
|
362
|
-
// Write the response
|
|
363
|
-
await writeWebResponse(webRes, res);
|
|
364
|
-
}
|
|
365
|
-
catch {
|
|
366
|
-
if (!res.headersSent) {
|
|
367
|
-
res.writeHead(500, { 'Content-Type': 'application/json', ...corsHeaders });
|
|
368
|
-
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
finally {
|
|
372
|
-
await transport.close();
|
|
373
|
-
}
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
// 404 for everything else
|
|
377
|
-
res.writeHead(404, { 'Content-Type': 'application/json', ...corsHeaders });
|
|
378
|
-
res.end(JSON.stringify({ error: 'Not found' }));
|
|
379
|
-
}
|
|
7
|
+
export { startHttpServer } from '../platforms/node/http-server.js';
|
|
380
8
|
//# sourceMappingURL=http.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/transport/http.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/transport/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC"}
|
package/dist/transport/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Transport configuration and CLI argument parsing
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
const log =
|
|
4
|
+
import { createStderrLogger } from '../core/services/logging.js';
|
|
5
|
+
const log = createStderrLogger('transport');
|
|
6
6
|
/**
|
|
7
7
|
* Parse CLI arguments for transport configuration
|
|
8
8
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,GAAG,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;AAQ5C;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,IAAI,GAAkB;QAC1B,SAAS,EAAE,OAAO;QAClB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,WAAW;KAClB,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,IAAI,GAAG,KAAK,aAAa,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAChD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACxC,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,+BAA+B,CAAC,CAAC;gBACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAChC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;gBAC5C,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI,qBAAqB,CAAC,CAAC;gBACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token bucket rate limiter (per-IP)
|
|
3
|
+
*/
|
|
4
|
+
/** Maximum unique IPs tracked by rate limiter to prevent memory exhaustion */
|
|
5
|
+
export declare const MAX_RATE_LIMIT_BUCKETS = 10000;
|
|
6
|
+
export declare class RateLimiter {
|
|
7
|
+
private readonly buckets;
|
|
8
|
+
private readonly maxTokens;
|
|
9
|
+
private readonly windowMs;
|
|
10
|
+
private readonly maxBuckets;
|
|
11
|
+
constructor(maxTokens: number, windowMs: number, maxBuckets?: number);
|
|
12
|
+
isAllowed(ip: string): boolean;
|
|
13
|
+
private evictOldest;
|
|
14
|
+
cleanup(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/transport/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6D;IACrF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGlC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAA+B;IAO7C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IA2B9B,OAAO,CAAC,WAAW;IAQnB,OAAO,IAAI,IAAI;CAQhB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token bucket rate limiter (per-IP)
|
|
3
|
+
*/
|
|
4
|
+
/** Maximum unique IPs tracked by rate limiter to prevent memory exhaustion */
|
|
5
|
+
export const MAX_RATE_LIMIT_BUCKETS = 10_000;
|
|
6
|
+
export class RateLimiter {
|
|
7
|
+
buckets = new Map();
|
|
8
|
+
maxTokens;
|
|
9
|
+
windowMs;
|
|
10
|
+
maxBuckets;
|
|
11
|
+
constructor(maxTokens, windowMs, maxBuckets = MAX_RATE_LIMIT_BUCKETS) {
|
|
12
|
+
this.maxTokens = maxTokens;
|
|
13
|
+
this.windowMs = windowMs;
|
|
14
|
+
this.maxBuckets = maxBuckets;
|
|
15
|
+
}
|
|
16
|
+
isAllowed(ip) {
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
let bucket = this.buckets.get(ip);
|
|
19
|
+
if (bucket === undefined) {
|
|
20
|
+
// Evict oldest entry if at capacity to prevent memory exhaustion
|
|
21
|
+
if (this.buckets.size >= this.maxBuckets) {
|
|
22
|
+
this.evictOldest();
|
|
23
|
+
}
|
|
24
|
+
bucket = { tokens: this.maxTokens, lastRefill: now };
|
|
25
|
+
this.buckets.set(ip, bucket);
|
|
26
|
+
}
|
|
27
|
+
// Refill tokens based on elapsed time
|
|
28
|
+
const elapsed = now - bucket.lastRefill;
|
|
29
|
+
const tokensToAdd = (elapsed / this.windowMs) * this.maxTokens;
|
|
30
|
+
bucket.tokens = Math.min(this.maxTokens, bucket.tokens + tokensToAdd);
|
|
31
|
+
bucket.lastRefill = now;
|
|
32
|
+
if (bucket.tokens >= 1) {
|
|
33
|
+
bucket.tokens -= 1;
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// Evict the oldest bucket entry using Map insertion order (O(1))
|
|
39
|
+
evictOldest() {
|
|
40
|
+
const firstKey = this.buckets.keys().next().value;
|
|
41
|
+
if (firstKey !== undefined) {
|
|
42
|
+
this.buckets.delete(firstKey);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Periodically clean up old entries to prevent memory leak
|
|
46
|
+
cleanup() {
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
for (const [ip, bucket] of this.buckets.entries()) {
|
|
49
|
+
if (now - bucket.lastRefill > this.windowMs * 2) {
|
|
50
|
+
this.buckets.delete(ip);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/transport/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE7C,MAAM,OAAO,WAAW;IACL,OAAO,GAAG,IAAI,GAAG,EAAkD,CAAC;IACpE,SAAS,CAAS;IAClB,QAAQ,CAAS;IACjB,UAAU,CAAS;IAEpC,YACE,SAAiB,EACjB,QAAgB,EAChB,aAAqB,sBAAsB;QAE3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,SAAS,CAAC,EAAU;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAElC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,iEAAiE;YACjE,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,CAAC;YACD,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/B,CAAC;QAED,sCAAsC;QACtC,MAAM,OAAO,GAAG,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;QACxC,MAAM,WAAW,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;QAC/D,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;QACtE,MAAM,CAAC,UAAU,GAAG,GAAG,CAAC;QAExB,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iEAAiE;IACzD,WAAW;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,OAAO;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAClD,IAAI,GAAG,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;gBAChD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@get-technology-inc/jamf-docs-mcp-server",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.7",
|
|
4
4
|
"description": "MCP Server for accessing Jamf Documentation (learn.jamf.com)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"@types/turndown": "^5.0.5",
|
|
55
55
|
"@vitest/coverage-v8": "^4.0.17",
|
|
56
56
|
"conventional-changelog-conventionalcommits": "^9.3.0",
|
|
57
|
-
"eslint": "^
|
|
57
|
+
"eslint": "^10.1.0",
|
|
58
58
|
"semantic-release": "^25.0.3",
|
|
59
59
|
"tsx": "^4.19.0",
|
|
60
|
-
"typescript": "^
|
|
60
|
+
"typescript": "^6.0.2",
|
|
61
61
|
"typescript-eslint": "^8.18.0",
|
|
62
62
|
"vitest": "^4.0.17"
|
|
63
63
|
},
|