@get-technology-inc/jamf-docs-mcp-server 3.0.50 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -0
- package/dist/core/apps/generated/app-html.d.ts +9 -0
- package/dist/core/apps/generated/app-html.d.ts.map +1 -0
- package/dist/core/apps/generated/app-html.js +9 -0
- package/dist/core/apps/generated/app-html.js.map +1 -0
- package/dist/core/apps/index.d.ts +38 -0
- package/dist/core/apps/index.d.ts.map +1 -0
- package/dist/core/apps/index.js +59 -0
- package/dist/core/apps/index.js.map +1 -0
- package/dist/core/create-server.d.ts +12 -1
- package/dist/core/create-server.d.ts.map +1 -1
- package/dist/core/create-server.js +74 -7
- package/dist/core/create-server.js.map +1 -1
- package/dist/core/prompts/compare-versions.d.ts +1 -1
- package/dist/core/prompts/compare-versions.d.ts.map +1 -1
- package/dist/core/prompts/compare-versions.js +1 -1
- package/dist/core/prompts/compare-versions.js.map +1 -1
- package/dist/core/prompts/index.d.ts +1 -1
- package/dist/core/prompts/index.d.ts.map +1 -1
- package/dist/core/prompts/setup-guide.d.ts +1 -1
- package/dist/core/prompts/setup-guide.d.ts.map +1 -1
- package/dist/core/prompts/setup-guide.js +1 -1
- package/dist/core/prompts/setup-guide.js.map +1 -1
- package/dist/core/prompts/troubleshoot.d.ts +1 -1
- package/dist/core/prompts/troubleshoot.d.ts.map +1 -1
- package/dist/core/prompts/troubleshoot.js +1 -1
- package/dist/core/prompts/troubleshoot.js.map +1 -1
- package/dist/core/resources/index.d.ts +1 -1
- package/dist/core/resources/index.d.ts.map +1 -1
- package/dist/core/resources/index.js +30 -5
- package/dist/core/resources/index.js.map +1 -1
- package/dist/core/schemas/index.d.ts +11 -11
- package/dist/core/schemas/index.js +3 -3
- package/dist/core/schemas/index.js.map +1 -1
- package/dist/core/schemas/output.d.ts +9 -0
- package/dist/core/schemas/output.d.ts.map +1 -1
- package/dist/core/schemas/output.js +29 -0
- package/dist/core/schemas/output.js.map +1 -1
- package/dist/core/services/article-service.d.ts +9 -1
- package/dist/core/services/article-service.d.ts.map +1 -1
- package/dist/core/services/article-service.js +4 -5
- package/dist/core/services/article-service.js.map +1 -1
- package/dist/core/services/ft-client.d.ts.map +1 -1
- package/dist/core/services/ft-client.js +2 -1
- package/dist/core/services/ft-client.js.map +1 -1
- package/dist/core/services/glossary.js +2 -2
- package/dist/core/services/glossary.js.map +1 -1
- package/dist/core/services/interfaces/cache.d.ts +1 -1
- package/dist/core/services/interfaces/cache.d.ts.map +1 -1
- package/dist/core/services/interfaces/logger.d.ts +0 -2
- package/dist/core/services/interfaces/logger.d.ts.map +1 -1
- package/dist/core/services/logging.d.ts +7 -15
- package/dist/core/services/logging.d.ts.map +1 -1
- package/dist/core/services/logging.js +7 -25
- package/dist/core/services/logging.js.map +1 -1
- package/dist/core/services/maps-registry.d.ts +0 -1
- package/dist/core/services/maps-registry.d.ts.map +1 -1
- package/dist/core/services/maps-registry.js +16 -15
- package/dist/core/services/maps-registry.js.map +1 -1
- package/dist/core/services/metadata.d.ts +27 -3
- package/dist/core/services/metadata.d.ts.map +1 -1
- package/dist/core/services/metadata.js +66 -26
- package/dist/core/services/metadata.js.map +1 -1
- package/dist/core/services/search-service.js.map +1 -1
- package/dist/core/services/toc-service.js.map +1 -1
- package/dist/core/services/topic-resolver.d.ts.map +1 -1
- package/dist/core/services/topic-resolver.js +62 -19
- package/dist/core/services/topic-resolver.js.map +1 -1
- package/dist/core/tools/batch-get-articles.d.ts +1 -1
- package/dist/core/tools/batch-get-articles.d.ts.map +1 -1
- package/dist/core/tools/get-article.d.ts +1 -1
- package/dist/core/tools/get-article.d.ts.map +1 -1
- package/dist/core/tools/get-article.js +34 -18
- package/dist/core/tools/get-article.js.map +1 -1
- package/dist/core/tools/get-toc.d.ts +1 -1
- package/dist/core/tools/get-toc.d.ts.map +1 -1
- package/dist/core/tools/get-toc.js +8 -0
- package/dist/core/tools/get-toc.js.map +1 -1
- package/dist/core/tools/glossary-lookup.d.ts +1 -1
- package/dist/core/tools/glossary-lookup.d.ts.map +1 -1
- package/dist/core/tools/glossary-lookup.js +2 -1
- package/dist/core/tools/glossary-lookup.js.map +1 -1
- package/dist/core/tools/list-products.d.ts +1 -1
- package/dist/core/tools/list-products.d.ts.map +1 -1
- package/dist/core/tools/search.d.ts +1 -1
- package/dist/core/tools/search.d.ts.map +1 -1
- package/dist/core/tools/search.js +28 -7
- package/dist/core/tools/search.js.map +1 -1
- package/dist/core/types.d.ts +10 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/progress.d.ts +13 -5
- package/dist/core/utils/progress.d.ts.map +1 -1
- package/dist/core/utils/progress.js +6 -2
- package/dist/core/utils/progress.js.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/platforms/node/cache.d.ts +1 -1
- package/dist/platforms/node/cache.d.ts.map +1 -1
- package/dist/platforms/node/cache.js.map +1 -1
- package/dist/platforms/node/config.d.ts.map +1 -1
- package/dist/platforms/node/config.js +3 -5
- package/dist/platforms/node/config.js.map +1 -1
- package/dist/platforms/node/http-server.d.ts +1 -1
- package/dist/platforms/node/http-server.d.ts.map +1 -1
- package/dist/platforms/node/http-server.js +21 -7
- package/dist/platforms/node/http-server.js.map +1 -1
- package/dist/platforms/node/logger.d.ts +0 -2
- package/dist/platforms/node/logger.d.ts.map +1 -1
- package/dist/platforms/node/logger.js +0 -3
- package/dist/platforms/node/logger.js.map +1 -1
- package/dist/transport/http-handler.d.ts +51 -9
- package/dist/transport/http-handler.d.ts.map +1 -1
- package/dist/transport/http-handler.js +213 -32
- package/dist/transport/http-handler.js.map +1 -1
- package/dist/transport/http-types.d.ts +14 -2
- package/dist/transport/http-types.d.ts.map +1 -1
- package/dist/transport/http-types.js +1 -1
- package/dist/transport/http-types.js.map +1 -1
- package/package.json +14 -6
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* native request/response types to/from Web Standard objects and
|
|
6
6
|
* call the `handler` function returned by `createHttpHandler`.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { createMcpHandler, InMemoryServerEventBus } from '@modelcontextprotocol/server';
|
|
9
9
|
import { RateLimiter } from './rate-limiter.js';
|
|
10
10
|
import { LLMS_TXT, PayloadTooLargeError, } from './http-types.js';
|
|
11
11
|
// ============================================================================
|
|
@@ -20,6 +20,26 @@ const SECURITY_HEADERS = {
|
|
|
20
20
|
// ============================================================================
|
|
21
21
|
// CORS helper
|
|
22
22
|
// ============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Request headers a browser-based MCP client is allowed to send.
|
|
25
|
+
*
|
|
26
|
+
* `Mcp-Method` / `Mcp-Name` are mandatory on Streamable HTTP POSTs from
|
|
27
|
+
* protocol revision 2026-07-28 (SEP-2243) — omitting them from the preflight
|
|
28
|
+
* allowlist makes every cross-origin call from a conforming client fail before
|
|
29
|
+
* it reaches the handler. `MCP-Protocol-Version`, `Mcp-Session-Id` and
|
|
30
|
+
* `Last-Event-ID` are kept for the 2025-era clients this endpoint still serves.
|
|
31
|
+
*/
|
|
32
|
+
export const CORS_ALLOWED_HEADERS = [
|
|
33
|
+
'Content-Type',
|
|
34
|
+
'Authorization',
|
|
35
|
+
'Mcp-Method',
|
|
36
|
+
'Mcp-Name',
|
|
37
|
+
'MCP-Protocol-Version',
|
|
38
|
+
'Mcp-Session-Id',
|
|
39
|
+
'Last-Event-ID',
|
|
40
|
+
].join(', ');
|
|
41
|
+
/** Response headers a browser-based MCP client is allowed to read. */
|
|
42
|
+
export const CORS_EXPOSED_HEADERS = ['Mcp-Session-Id'].join(', ');
|
|
23
43
|
function getCorsHeaders(origin, allowedOrigins) {
|
|
24
44
|
const headers = { ...SECURITY_HEADERS };
|
|
25
45
|
if (allowedOrigins.length === 0) {
|
|
@@ -30,14 +50,16 @@ function getCorsHeaders(origin, allowedOrigins) {
|
|
|
30
50
|
if (allowedOrigins.includes('*')) {
|
|
31
51
|
headers['Access-Control-Allow-Origin'] = '*';
|
|
32
52
|
headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS';
|
|
33
|
-
headers['Access-Control-Allow-Headers'] =
|
|
53
|
+
headers['Access-Control-Allow-Headers'] = CORS_ALLOWED_HEADERS;
|
|
54
|
+
headers['Access-Control-Expose-Headers'] = CORS_EXPOSED_HEADERS;
|
|
34
55
|
return headers;
|
|
35
56
|
}
|
|
36
57
|
// Otherwise, check exact match against the allowed list
|
|
37
58
|
if (origin !== null && allowedOrigins.includes(origin)) {
|
|
38
59
|
headers['Access-Control-Allow-Origin'] = origin;
|
|
39
60
|
headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS';
|
|
40
|
-
headers['Access-Control-Allow-Headers'] =
|
|
61
|
+
headers['Access-Control-Allow-Headers'] = CORS_ALLOWED_HEADERS;
|
|
62
|
+
headers['Access-Control-Expose-Headers'] = CORS_EXPOSED_HEADERS;
|
|
41
63
|
headers['Access-Control-Max-Age'] = '86400';
|
|
42
64
|
headers.Vary = 'Origin';
|
|
43
65
|
}
|
|
@@ -83,32 +105,178 @@ function textResponse(status, body, contentType, extraHeaders = {}) {
|
|
|
83
105
|
});
|
|
84
106
|
}
|
|
85
107
|
// ============================================================================
|
|
86
|
-
//
|
|
108
|
+
// Request classification helpers
|
|
87
109
|
// ============================================================================
|
|
110
|
+
/**
|
|
111
|
+
* Whether a parsed body is a `subscriptions/listen` request.
|
|
112
|
+
*
|
|
113
|
+
* These are long-lived SSE streams, not exchanges: they never complete on
|
|
114
|
+
* their own, so shutdown ends them rather than waiting for them.
|
|
115
|
+
*/
|
|
116
|
+
function isSubscriptionListen(parsedBody) {
|
|
117
|
+
return (typeof parsedBody === 'object'
|
|
118
|
+
&& parsedBody !== null
|
|
119
|
+
&& parsedBody.method === 'subscriptions/listen');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Decrement the in-flight count only once the response body has been fully
|
|
123
|
+
* consumed (or cancelled).
|
|
124
|
+
*
|
|
125
|
+
* In `'auto'`/`'sse'` response mode the SDK resolves `fetch` as soon as the
|
|
126
|
+
* first frame is ready and keeps writing the result into the stream, and the
|
|
127
|
+
* per-request server stays registered as in-flight until that stream ends.
|
|
128
|
+
* Counting only up to `fetch` resolving would therefore let shutdown tear the
|
|
129
|
+
* server down mid-stream and truncate the response.
|
|
130
|
+
*/
|
|
131
|
+
function trackBody(response, done) {
|
|
132
|
+
const source = response.body;
|
|
133
|
+
if (source === null) {
|
|
134
|
+
done();
|
|
135
|
+
return response;
|
|
136
|
+
}
|
|
137
|
+
// `Response.body` is typed as `ReadableStream<any>` in the ambient lib, so
|
|
138
|
+
// the element type has to be re-stated for the pass-through to stay typed.
|
|
139
|
+
const reader = source.getReader();
|
|
140
|
+
const tracked = new ReadableStream({
|
|
141
|
+
async pull(controller) {
|
|
142
|
+
try {
|
|
143
|
+
const { done: finished, value } = await reader.read();
|
|
144
|
+
if (finished) {
|
|
145
|
+
controller.close();
|
|
146
|
+
done();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
controller.enqueue(value);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
done();
|
|
153
|
+
controller.error(err);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
async cancel(reason) {
|
|
157
|
+
done();
|
|
158
|
+
await reader.cancel(reason);
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
return new Response(tracked, {
|
|
162
|
+
status: response.status,
|
|
163
|
+
statusText: response.statusText,
|
|
164
|
+
headers: response.headers,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
88
167
|
/**
|
|
89
168
|
* Create a platform-agnostic HTTP handler for the MCP server.
|
|
90
169
|
*
|
|
91
170
|
* @param createServer - Factory that returns a fresh McpServer per request.
|
|
92
171
|
* The MCP SDK requires one Protocol/Server instance per connection, so each
|
|
93
|
-
* request gets its own server
|
|
172
|
+
* request gets its own server rather than sharing a singleton.
|
|
94
173
|
* Callers decide the server's lifecycle/state model (stateless, per-session, …).
|
|
95
174
|
* @param config - HTTP handler configuration
|
|
96
175
|
* @param getClientIp - Platform-specific function to extract client IP from a Request
|
|
97
176
|
* @param logger - Optional logger instance
|
|
98
|
-
* @returns An object with:
|
|
99
|
-
* - `handler`: async function that takes a Web Standard Request and returns a Response
|
|
100
|
-
* - `cleanup`: function to stop the rate limiter cleanup interval
|
|
101
177
|
*/
|
|
102
178
|
export function createHttpHandler(createServer, config, getClientIp, logger) {
|
|
103
179
|
const rateLimiter = new RateLimiter(config.rateLimitRpm, 60_000);
|
|
104
180
|
const cleanupIntervalId = setInterval(() => { rateLimiter.cleanup(); }, 5 * 60_000);
|
|
181
|
+
const handlerOptions = {
|
|
182
|
+
legacy: 'stateless',
|
|
183
|
+
responseMode: config.responseMode,
|
|
184
|
+
onerror: (err) => {
|
|
185
|
+
logger?.error(`MCP handler error: ${err.message}`);
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
// Two entries over one factory and one event bus, split by lifetime rather
|
|
189
|
+
// than by protocol era.
|
|
190
|
+
//
|
|
191
|
+
// `McpHttpHandler.close()` does two things at once: it completes the open
|
|
192
|
+
// `subscriptions/listen` streams, and it aborts every in-flight modern
|
|
193
|
+
// exchange (which the client sees as HTTP 499). Graceful shutdown needs the
|
|
194
|
+
// first immediately — those sockets are what would otherwise keep
|
|
195
|
+
// `http.Server.close()` from ever returning — and the second only after the
|
|
196
|
+
// drain window. One handler cannot offer both moments, and the SDK exposes no
|
|
197
|
+
// narrower door: `bus` is shared configuration, the listen router behind it
|
|
198
|
+
// is not reachable on its own.
|
|
199
|
+
//
|
|
200
|
+
// So subscriptions get their own entry. Sharing `bus` keeps them subscribed
|
|
201
|
+
// to the same change-event stream the exchange leg publishes on, which is
|
|
202
|
+
// what makes the split invisible to clients.
|
|
203
|
+
const bus = new InMemoryServerEventBus((err) => {
|
|
204
|
+
logger?.error(`MCP event bus error: ${err.message}`);
|
|
205
|
+
});
|
|
206
|
+
// Ordinary traffic: 2026-07-28 envelope requests on the modern path, and
|
|
207
|
+
// 2025-era requests through the SDK's stateless legacy fallback. Legacy
|
|
208
|
+
// responses stream over SSE, which the 2025 Streamable HTTP binding already
|
|
209
|
+
// requires clients to accept.
|
|
210
|
+
const exchanges = createMcpHandler(() => createServer(), { ...handlerOptions, bus });
|
|
211
|
+
// `subscriptions/listen` only. Same factory, same bus, same options — it
|
|
212
|
+
// differs solely in when it is closed.
|
|
213
|
+
const subscriptions = createMcpHandler(() => createServer(), { ...handlerOptions, bus });
|
|
105
214
|
// Prevent the interval from keeping the process alive (Node.js-specific,
|
|
106
215
|
// but calling .unref() is harmless on platforms that lack it).
|
|
107
216
|
if (typeof cleanupIntervalId === 'object' && 'unref' in cleanupIntervalId) {
|
|
108
217
|
cleanupIntervalId.unref();
|
|
109
218
|
}
|
|
219
|
+
// ------------------------------------------------------------------------
|
|
220
|
+
// Shutdown bookkeeping
|
|
221
|
+
// ------------------------------------------------------------------------
|
|
222
|
+
/** Exchanges past dispatch whose response body has not been consumed yet. */
|
|
223
|
+
let inFlight = 0;
|
|
224
|
+
const drainWaiters = new Set();
|
|
225
|
+
function enterExchange() {
|
|
226
|
+
inFlight++;
|
|
227
|
+
let left = false;
|
|
228
|
+
return () => {
|
|
229
|
+
if (left) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
left = true;
|
|
233
|
+
inFlight--;
|
|
234
|
+
if (inFlight === 0) {
|
|
235
|
+
for (const wake of drainWaiters) {
|
|
236
|
+
wake();
|
|
237
|
+
}
|
|
238
|
+
drainWaiters.clear();
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/** Resolves `true` once nothing is in flight, `false` if `timeoutMs` runs out. */
|
|
243
|
+
async function drain(timeoutMs) {
|
|
244
|
+
if (inFlight === 0) {
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
let timer;
|
|
248
|
+
const expired = new Promise((resolve) => {
|
|
249
|
+
timer = setTimeout(() => { resolve(false); }, timeoutMs);
|
|
250
|
+
});
|
|
251
|
+
const drained = new Promise((resolve) => {
|
|
252
|
+
drainWaiters.add(() => { resolve(true); });
|
|
253
|
+
});
|
|
254
|
+
try {
|
|
255
|
+
return await Promise.race([drained, expired]);
|
|
256
|
+
}
|
|
257
|
+
finally {
|
|
258
|
+
clearTimeout(timer);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
110
261
|
function cleanup() {
|
|
111
262
|
clearInterval(cleanupIntervalId);
|
|
263
|
+
void subscriptions.close();
|
|
264
|
+
void exchanges.close();
|
|
265
|
+
}
|
|
266
|
+
async function shutdown(timeoutMs = config.shutdownTimeoutMs) {
|
|
267
|
+
clearInterval(cleanupIntervalId);
|
|
268
|
+
// 1. Subscription streams end now — they would never drain on their own.
|
|
269
|
+
// Closing their handler completes each one properly rather than just
|
|
270
|
+
// dropping the socket, and frees the connections the HTTP server is
|
|
271
|
+
// waiting on.
|
|
272
|
+
await subscriptions.close();
|
|
273
|
+
// 2. Give exchanges already past dispatch their window to answer.
|
|
274
|
+
if (!(await drain(timeoutMs))) {
|
|
275
|
+
logger?.warning(`Shutdown drain timed out after ${String(timeoutMs)}ms with ${String(inFlight)} request(s) in flight`);
|
|
276
|
+
}
|
|
277
|
+
// 3. Only now may the exchange leg go: this is the step that would have
|
|
278
|
+
// answered 499 to everything still running.
|
|
279
|
+
await exchanges.close();
|
|
112
280
|
}
|
|
113
281
|
async function handler(request) {
|
|
114
282
|
// Use hardcoded base URL to prevent Host header injection
|
|
@@ -138,17 +306,20 @@ export function createHttpHandler(createServer, config, getClientIp, logger) {
|
|
|
138
306
|
}
|
|
139
307
|
// MCP endpoint
|
|
140
308
|
if (pathname === '/mcp') {
|
|
141
|
-
return await handleMcp(request,
|
|
309
|
+
return await handleMcp(request, config, corsHeaders, {
|
|
310
|
+
exchanges,
|
|
311
|
+
subscriptions,
|
|
312
|
+
enterExchange,
|
|
313
|
+
...(logger !== undefined && { logger }),
|
|
314
|
+
});
|
|
142
315
|
}
|
|
143
316
|
// 404 fallback
|
|
144
317
|
return jsonResponse(404, { error: 'Not found' }, corsHeaders);
|
|
145
318
|
}
|
|
146
|
-
return { handler, cleanup };
|
|
319
|
+
return { handler, cleanup, shutdown };
|
|
147
320
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// ============================================================================
|
|
151
|
-
async function handleMcp(request, createServer, config, corsHeaders, logger) {
|
|
321
|
+
async function handleMcp(request, config, corsHeaders, deps) {
|
|
322
|
+
const { logger } = deps;
|
|
152
323
|
// Read body (with size enforcement)
|
|
153
324
|
let bodyText;
|
|
154
325
|
try {
|
|
@@ -160,19 +331,17 @@ async function handleMcp(request, createServer, config, corsHeaders, logger) {
|
|
|
160
331
|
}
|
|
161
332
|
throw err;
|
|
162
333
|
}
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
// and
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
});
|
|
172
|
-
// Connect the per-request server to this transport
|
|
173
|
-
await mcpServer.connect(transport);
|
|
334
|
+
// A POST with no body is a client error, but it cannot be left to the SDK to
|
|
335
|
+
// say so: reading the body above consumed the stream, and the entry answers
|
|
336
|
+
// an absent `parsedBody` by cloning the request to re-read it — which throws
|
|
337
|
+
// on a used body and surfaces as 500. GET and DELETE carry no body by
|
|
338
|
+
// design and are unaffected.
|
|
339
|
+
if (request.method === 'POST' && bodyText.length === 0) {
|
|
340
|
+
return jsonResponse(400, { error: 'Empty request body' }, corsHeaders);
|
|
341
|
+
}
|
|
174
342
|
try {
|
|
175
|
-
// Parse body if present
|
|
343
|
+
// Parse body if present. Reading it above consumed the request stream, so
|
|
344
|
+
// the parsed value must be handed to the MCP handler explicitly.
|
|
176
345
|
let parsedBody;
|
|
177
346
|
if (bodyText.length > 0) {
|
|
178
347
|
try {
|
|
@@ -182,20 +351,32 @@ async function handleMcp(request, createServer, config, corsHeaders, logger) {
|
|
|
182
351
|
return jsonResponse(400, { error: 'Invalid JSON in request body' }, corsHeaders);
|
|
183
352
|
}
|
|
184
353
|
}
|
|
185
|
-
//
|
|
186
|
-
|
|
354
|
+
// A subscription stream is not an exchange: it stays open until the client
|
|
355
|
+
// or the server ends it. It goes to the entry that shutdown closes first,
|
|
356
|
+
// and it is excluded from the drain — waiting on something that never
|
|
357
|
+
// finishes would burn the whole window.
|
|
358
|
+
const listen = isSubscriptionListen(parsedBody);
|
|
359
|
+
const entry = listen ? deps.subscriptions : deps.exchanges;
|
|
360
|
+
const release = listen ? undefined : deps.enterExchange();
|
|
361
|
+
let webRes;
|
|
362
|
+
try {
|
|
363
|
+
// The entry classifies the era itself and builds a fresh server per
|
|
364
|
+
// request from the factory it was given.
|
|
365
|
+
webRes = await entry.fetch(request, { parsedBody });
|
|
366
|
+
}
|
|
367
|
+
catch (err) {
|
|
368
|
+
release?.();
|
|
369
|
+
throw err;
|
|
370
|
+
}
|
|
187
371
|
// Add CORS + security headers to the response
|
|
188
372
|
for (const [key, value] of Object.entries(corsHeaders)) {
|
|
189
373
|
webRes.headers.set(key, value);
|
|
190
374
|
}
|
|
191
|
-
return webRes;
|
|
375
|
+
return release === undefined ? webRes : trackBody(webRes, release);
|
|
192
376
|
}
|
|
193
377
|
catch (err) {
|
|
194
378
|
logger?.error(`MCP handler error: ${err instanceof Error ? err.message : String(err)}`);
|
|
195
379
|
return jsonResponse(500, { error: 'Internal server error' }, corsHeaders);
|
|
196
380
|
}
|
|
197
|
-
finally {
|
|
198
|
-
await transport.close();
|
|
199
|
-
}
|
|
200
381
|
}
|
|
201
382
|
//# sourceMappingURL=http-handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-handler.js","sourceRoot":"","sources":["../../src/transport/http-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"http-handler.js","sourceRoot":"","sources":["../../src/transport/http-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared types and constants for the HTTP transport layer.
|
|
3
3
|
*/
|
|
4
|
+
import type { PerRequestResponseMode } from '@modelcontextprotocol/server';
|
|
4
5
|
import type { Logger } from '../core/services/interfaces/index.js';
|
|
5
|
-
export type { Logger };
|
|
6
|
+
export type { Logger, PerRequestResponseMode };
|
|
6
7
|
export interface HttpHandlerConfig {
|
|
7
8
|
serverVersion: string;
|
|
8
9
|
corsAllowedOrigins: string[];
|
|
9
10
|
trustProxy: boolean;
|
|
10
11
|
rateLimitRpm: number;
|
|
11
12
|
maxBodySize: number;
|
|
12
|
-
|
|
13
|
+
/**
|
|
14
|
+
* How responses are shaped.
|
|
15
|
+
*
|
|
16
|
+
* - `'auto'` (default) — a single JSON body, upgrading to an SSE stream only
|
|
17
|
+
* when a handler emits something before its result. In practice that means
|
|
18
|
+
* progress notifications reach the client instead of being discarded.
|
|
19
|
+
* - `'sse'` — always stream.
|
|
20
|
+
* - `'json'` — never stream, which silently drops mid-call notifications.
|
|
21
|
+
* Choose it when a response cache in front of this handler stores a single
|
|
22
|
+
* JSON body.
|
|
23
|
+
*/
|
|
24
|
+
responseMode: PerRequestResponseMode;
|
|
13
25
|
shutdownTimeoutMs: number;
|
|
14
26
|
}
|
|
15
27
|
/** Platform-specific IP extraction -- Node reads socket, Workers reads CF header */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-types.d.ts","sourceRoot":"","sources":["../../src/transport/http-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAEnE,YAAY,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"http-types.d.ts","sourceRoot":"","sources":["../../src/transport/http-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAEnE,YAAY,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;AAM/C,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;OAUG;IACH,YAAY,EAAE,sBAAsB,CAAC;IACrC,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,oFAAoF;AACpF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;AAE7D,eAAO,MAAM,mBAAmB,EAAE,iBAQjC,CAAC;AAMF,eAAO,MAAM,QAAQ,+tDAuCpB,CAAC;AAMF,qBAAa,oBAAqB,SAAQ,KAAK;;CAK9C"}
|
|
@@ -7,7 +7,7 @@ export const DEFAULT_HTTP_CONFIG = {
|
|
|
7
7
|
trustProxy: false,
|
|
8
8
|
rateLimitRpm: 60,
|
|
9
9
|
maxBodySize: 1_048_576,
|
|
10
|
-
|
|
10
|
+
responseMode: 'auto',
|
|
11
11
|
shutdownTimeoutMs: 10_000,
|
|
12
12
|
};
|
|
13
13
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-types.js","sourceRoot":"","sources":["../../src/transport/http-types.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"http-types.js","sourceRoot":"","sources":["../../src/transport/http-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmCH,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,YAAY,EAAE,MAAM;IACpB,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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@get-technology-inc/jamf-docs-mcp-server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "MCP Server for accessing Jamf Documentation (learn.jamf.com)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"jamf-docs-mcp-server": "./dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
11
|
+
"build": "npm run build:app-ui && tsc",
|
|
12
12
|
"dev": "tsx watch src/index.ts",
|
|
13
13
|
"start": "node dist/index.js",
|
|
14
14
|
"start:http": "node dist/index.js --transport http",
|
|
@@ -20,10 +20,12 @@
|
|
|
20
20
|
"test:all": "vitest run test/unit && vitest run test/integration && vitest run test/e2e",
|
|
21
21
|
"test:coverage": "vitest run --coverage",
|
|
22
22
|
"test:inspector": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
23
|
-
"lint": "eslint src/**/*.ts",
|
|
23
|
+
"lint": "eslint 'src/**/*.ts' 'app-ui/**/*.ts' 'scripts/**/*.mjs'",
|
|
24
24
|
"typecheck": "tsc --noEmit",
|
|
25
25
|
"clean": "rm -rf dist",
|
|
26
|
-
"prepublishOnly": "npm run build"
|
|
26
|
+
"prepublishOnly": "npm run build",
|
|
27
|
+
"build:app-ui": "node scripts/build-app-ui.mjs",
|
|
28
|
+
"typecheck:app-ui": "tsc --noEmit -p app-ui/tsconfig.json"
|
|
27
29
|
},
|
|
28
30
|
"keywords": [
|
|
29
31
|
"mcp",
|
|
@@ -40,7 +42,6 @@
|
|
|
40
42
|
"author": "GET Technology Inc.",
|
|
41
43
|
"license": "MIT",
|
|
42
44
|
"dependencies": {
|
|
43
|
-
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
44
45
|
"cheerio": "^1.0.0",
|
|
45
46
|
"fuse.js": "^7.1.0",
|
|
46
47
|
"turndown": "^7.2.0",
|
|
@@ -48,12 +49,16 @@
|
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@eslint/js": "^9.17.0",
|
|
52
|
+
"@modelcontextprotocol/client": "^2.0.0",
|
|
53
|
+
"@modelcontextprotocol/ext-apps": "^1.7.5",
|
|
54
|
+
"@modelcontextprotocol/server": "^2.0.0",
|
|
51
55
|
"@semantic-release/changelog": "^6.0.3",
|
|
52
56
|
"@semantic-release/git": "^10.0.1",
|
|
53
57
|
"@types/node": "^26.0.0",
|
|
54
58
|
"@types/turndown": "^5.0.5",
|
|
55
59
|
"@vitest/coverage-v8": "^4.0.17",
|
|
56
60
|
"conventional-changelog-conventionalcommits": "^9.3.0",
|
|
61
|
+
"esbuild": "^0.28.1",
|
|
57
62
|
"eslint": "^10.1.0",
|
|
58
63
|
"semantic-release": "^25.0.3",
|
|
59
64
|
"tsx": "^4.19.0",
|
|
@@ -81,7 +86,7 @@
|
|
|
81
86
|
}
|
|
82
87
|
},
|
|
83
88
|
"engines": {
|
|
84
|
-
"node": ">=
|
|
89
|
+
"node": ">=20"
|
|
85
90
|
},
|
|
86
91
|
"files": [
|
|
87
92
|
"dist",
|
|
@@ -94,5 +99,8 @@
|
|
|
94
99
|
"homepage": "https://github.com/GET-Technology-Inc/jamf-docs-mcp-server#readme",
|
|
95
100
|
"bugs": {
|
|
96
101
|
"url": "https://github.com/GET-Technology-Inc/jamf-docs-mcp-server/issues"
|
|
102
|
+
},
|
|
103
|
+
"peerDependencies": {
|
|
104
|
+
"@modelcontextprotocol/server": "^2.0.0"
|
|
97
105
|
}
|
|
98
106
|
}
|