@sassoftware/sas-score-mcp-serverjs 0.3.19 → 0.3.29-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -16,14 +16,15 @@ import createMcpServer from './src/createMcpServer.js';
16
16
  import fs from 'fs';
17
17
  import { randomUUID } from 'node:crypto';
18
18
 
19
- import refreshToken from './src/toolHelpers/refreshToken.js';
20
- import getOptsViya from './src/toolHelpers/getOptsViya.js';
19
+ //import refreshToken from './src/toolHelpers/refreshToken.js';
20
+ //import getOptsViya from './src/toolHelpers/getOptsViya.js';
21
+ import readCerts from './src/toolHelpers/readCerts.js';
21
22
 
22
23
  import { fileURLToPath } from 'url';
23
24
  import { dirname } from 'path';
24
25
 
25
26
  import NodeCache from 'node-cache';
26
- import getOpts from './src/toolHelpers/getOpts.js';
27
+ //import getOpts from './src/toolHelpers/getOpts.js';
27
28
 
28
29
  const __dirname = dirname(fileURLToPath(import.meta.url));
29
30
 
@@ -70,7 +71,7 @@ console.error(
70
71
  // and storage provided by cloud providers
71
72
  console.error(process.env.COMPUTECONTEXT);
72
73
  debugger;
73
- let sessionCache = new NodeCache({ stdTTL: 0, checkperiod: 2 * 60, useClones: false });
74
+ let sessionCache = new NodeCache({ stdTTL: 24 *60*60, checkperiod: 2 * 60, useClones: false });
74
75
 
75
76
  //
76
77
  // Load environment variables from .env file if present
@@ -167,6 +168,7 @@ const appEnvBase = {
167
168
  casSession: null, /* restaf cas session object */
168
169
  computeSession: null, /* restaf compute session object */
169
170
  viyaCert: null, /* ssl/tsl certificates to connect to viya */
171
+ appCert: null,
170
172
  logonPayload: null, /* viya logon payload to connect to viya */
171
173
  casServerId: null,
172
174
  computeSessonId: null,
@@ -179,10 +181,15 @@ const appEnvBase = {
179
181
  process.env.APPPORT=appEnvBase.PORT;
180
182
 
181
183
  // setup TLS options for viya calls
182
-
183
184
  console.error('[Note]Viya SSL dir set to: ' + appEnvBase.VIYACERT);
184
- await getOptsViya(appEnvBase); /* appEnvBase.contexts.viyaCert is set here */
185
- appEnvBase.tlsOpts = getOpts(appEnvBase);
185
+ appEnvBase.contexts.viyaCert = readCerts(appEnvBase.VIYACERT); /* appEnvBase.contexts.viyaCert is set here */
186
+
187
+ // setup TLS options for app server (expressMcpServer or hapiMcpServer)
188
+
189
+ console.error('[Note]App SSL dir set to: ' + appEnvBase.SSLCERT);
190
+ appEnvBase.tlsOpts = readCerts(appEnvBase.SSLCERT);
191
+ appEnvBase.contexts.appCert = appEnvBase.tlsOpts; /* just for completeness */
192
+
186
193
  appEnvBase.contexts.storeConfig = {
187
194
  casProxy: true,
188
195
  options: { ns: null, proxyServer: null, httpOptions: appEnvBase.contexts.viyaCert }
@@ -205,19 +212,7 @@ if (appEnvBase.TOKENFILE != null) {
205
212
  }
206
213
  }
207
214
 
208
- // handle refresh token flow
209
- // use this for testing only.
210
- if (appEnvBase.REFRESH_TOKEN != null) {
211
- appEnvBase.refreshToken = appEnvBase.REFRESH_TOKEN;
212
- appEnvBase.AUTHFLOW = 'refresh';
213
- let t = await refreshToken(appEnvBase, { token: appEnvBase.REFRESH_TOKEN, host: appEnvBase.VIYA_SERVER });
214
- appEnvBase.contexts.logonPayload = {
215
- host: appEnvBase.VIYA_SERVER,
216
- authType: 'server',
217
- token: t,
218
- tokenType: 'Bearer'
219
- }
220
- }
215
+
221
216
 
222
217
  // if authflow is cli or code, postpone getting logonPayload until needed
223
218
 
@@ -232,16 +227,19 @@ let appEnvTemplate = Object.assign({}, appEnvBase);
232
227
 
233
228
  sessionCache.set('appEnvTemplate', appEnvTemplate);
234
229
 
235
- let transports = {};
230
+ let transports = {
231
+ "dummy": null
232
+ };
236
233
  sessionCache.set('transports', transports);
237
234
 
238
235
  // set this for stdio transport use
239
236
  // dummy sessionId for use in the tools
240
237
  let useHapi = process.env.AUTHFLOW === 'code' ? true : false;
238
+ console.error('[Note] appEnvBase is', JSON.stringify(appEnvBase, null,2));
239
+ // creat a dummy sessionId for stdio since there is only one session and transport in that case, and tools need a sessionId to access the appEnvBase and contexts
240
+ let sessionId = randomUUID();
241
+ sessionCache.set(sessionId, appEnvBase);
241
242
  if (mcpType === 'stdio') {
242
- let sessionId = randomUUID();
243
- sessionCache.set('currentId', sessionId);
244
- sessionCache.set(sessionId, appEnvBase);
245
243
  console.error('[Note] Setting up stdio transport with sessionId:', sessionId);
246
244
  console.error('[Note] Used in setting up tools and some persistence(not all).');
247
245
  await coreSSE(mcpServer);
@@ -249,6 +247,7 @@ if (mcpType === 'stdio') {
249
247
  } else {
250
248
  console.error('[Note] Starting HTTP MCP server...');
251
249
  if (useHapi === true) {
250
+ process.env.AUTHTYPE = null;
252
251
  await hapiMcpServer(mcpServer, sessionCache, appEnvBase);
253
252
  console.error('[Note] Using HAPI HTTP server...')
254
253
  } else {
package/openApi.yaml CHANGED
@@ -1,121 +1,121 @@
1
- swagger: "2.0"
2
- info:
3
- title: SAS Viya Sample MCP Server API
4
- version: "1.0.0"
5
- description: API for interacting with the SAS Viya Sample MCP Server.
6
- host: localhost:8080
7
- basePath: /
8
- schemes:
9
- - http
10
- - https
11
- consumes:
12
- - application/json
13
- produces:
14
- - application/json
15
- paths:
16
- /health:
17
- get:
18
- summary: Health check
19
- description: Returns health and version information.
20
- responses:
21
- 200:
22
- description: Health information
23
- schema:
24
- type: object
25
- properties:
26
- name:
27
- type: string
28
- version:
29
- type: string
30
- description:
31
- type: string
32
- endpoints:
33
- type: object
34
- usage:
35
- type: string
36
- /apiMeta:
37
- get:
38
- summary: API metadata
39
- description: Returns the OpenAPI specification for this server.
40
- responses:
41
- 200:
42
- description: OpenAPI document
43
- schema:
44
- type: object
45
- /mcp:
46
- options:
47
- summary: CORS preflight
48
- description: CORS preflight endpoint.
49
- responses:
50
- 204:
51
- description: No Content
52
- post:
53
- summary: MCP request
54
- description: Handles MCP JSON-RPC requests.
55
- parameters:
56
- - name: body
57
- in: body
58
- required: true
59
- schema:
60
- type: object
61
- - name: Authorization
62
- in: header
63
- required: false
64
- type: string
65
- description: Bearer token for authentication
66
- - name: X-VIYA-SERVER
67
- in: header
68
- required: false
69
- type: string
70
- description: Override VIYA server
71
- - name: X-REFRESH-TOKEN
72
- in: header
73
- required: false
74
- type: string
75
- description: Refresh token for authentication
76
- - name: mcp-session-id
77
- in: header
78
- required: false
79
- type: string
80
- description: Session ID
81
- responses:
82
- 200:
83
- description: MCP response
84
- schema:
85
- type: object
86
- 500:
87
- description: Server error
88
- schema:
89
- type: object
90
- get:
91
- summary: Get MCP session
92
- description: Retrieves information for an MCP session.
93
- parameters:
94
- - name: mcp-session-id
95
- in: header
96
- required: true
97
- type: string
98
- description: Session ID
99
- responses:
100
- 200:
101
- description: Session information
102
- schema:
103
- type: object
104
- 400:
105
- description: Invalid or missing session ID
106
- delete:
107
- summary: Delete MCP session
108
- description: Deletes an MCP session.
109
- parameters:
110
- - name: mcp-session-id
111
- in: header
112
- required: true
113
- type: string
114
- description: Session ID
115
- responses:
116
- 200:
117
- description: Session deleted
118
- schema:
119
- type: object
120
- 400:
121
- description: Invalid or missing session ID
1
+ swagger: "2.0"
2
+ info:
3
+ title: SAS Viya Sample MCP Server API
4
+ version: "1.0.0"
5
+ description: API for interacting with the SAS Viya Sample MCP Server.
6
+ host: localhost:8080
7
+ basePath: /
8
+ schemes:
9
+ - http
10
+ - https
11
+ consumes:
12
+ - application/json
13
+ produces:
14
+ - application/json
15
+ paths:
16
+ /health:
17
+ get:
18
+ summary: Health check
19
+ description: Returns health and version information.
20
+ responses:
21
+ 200:
22
+ description: Health information
23
+ schema:
24
+ type: object
25
+ properties:
26
+ name:
27
+ type: string
28
+ version:
29
+ type: string
30
+ description:
31
+ type: string
32
+ endpoints:
33
+ type: object
34
+ usage:
35
+ type: string
36
+ /apiMeta:
37
+ get:
38
+ summary: API metadata
39
+ description: Returns the OpenAPI specification for this server.
40
+ responses:
41
+ 200:
42
+ description: OpenAPI document
43
+ schema:
44
+ type: object
45
+ /mcp:
46
+ options:
47
+ summary: CORS preflight
48
+ description: CORS preflight endpoint.
49
+ responses:
50
+ 204:
51
+ description: No Content
52
+ post:
53
+ summary: MCP request
54
+ description: Handles MCP JSON-RPC requests.
55
+ parameters:
56
+ - name: body
57
+ in: body
58
+ required: true
59
+ schema:
60
+ type: object
61
+ - name: Authorization
62
+ in: header
63
+ required: false
64
+ type: string
65
+ description: Bearer token for authentication
66
+ - name: X-VIYA-SERVER
67
+ in: header
68
+ required: false
69
+ type: string
70
+ description: Override VIYA server
71
+ - name: X-REFRESH-TOKEN
72
+ in: header
73
+ required: false
74
+ type: string
75
+ description: Refresh token for authentication
76
+ - name: mcp-session-id
77
+ in: header
78
+ required: false
79
+ type: string
80
+ description: Session ID
81
+ responses:
82
+ 200:
83
+ description: MCP response
84
+ schema:
85
+ type: object
86
+ 500:
87
+ description: Server error
88
+ schema:
89
+ type: object
90
+ get:
91
+ summary: Get MCP session
92
+ description: Retrieves information for an MCP session.
93
+ parameters:
94
+ - name: mcp-session-id
95
+ in: header
96
+ required: true
97
+ type: string
98
+ description: Session ID
99
+ responses:
100
+ 200:
101
+ description: Session information
102
+ schema:
103
+ type: object
104
+ 400:
105
+ description: Invalid or missing session ID
106
+ delete:
107
+ summary: Delete MCP session
108
+ description: Deletes an MCP session.
109
+ parameters:
110
+ - name: mcp-session-id
111
+ in: header
112
+ required: true
113
+ type: string
114
+ description: Session ID
115
+ responses:
116
+ 200:
117
+ description: Session deleted
118
+ schema:
119
+ type: object
120
+ 400:
121
+ description: Invalid or missing session ID
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassoftware/sas-score-mcp-serverjs",
3
- "version": "0.3.19",
3
+ "version": "0.3.29-0",
4
4
  "description": "A mcp server for SAS Viya",
5
5
  "author": "Deva Kumar <deva.kumar@sas.com>",
6
6
  "license": "Apache-2.0",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "type": "module",
12
12
  "scripts": {
13
- "start": "node cli.js",
13
+ "start": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 node cli.js",
14
14
  "testi": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 npx @modelcontextprotocol/inspector",
15
15
  "test": "cd test && node",
16
16
  "debug": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 node --inspect-brk cli.js",
@@ -75,8 +75,9 @@ async function createMcpServer(cache, _appContext) {
75
75
  let toolName = _appContext.brand + '-' + tool.name;
76
76
  // console.error(`\n[Note] Registering tool ${i + 1} : ${toolName}`);
77
77
  let toolHandler = wrapf(cache, tool.handler);
78
-
78
+ tool.name = toolName; // update tool name with brand prefix for registration
79
79
  mcpServer.tool(toolName, tool.description, tool.schema, toolHandler);
80
+
80
81
  toolNames.push(toolName);
81
82
  });
82
83
  console.error(`[Note] Registered ${toolSet.length} tools: ${toolNames}`);
@@ -6,17 +6,14 @@ import express from "express";
6
6
 
7
7
  import https from "https";
8
8
  import cors from "cors";
9
- //import rateLimit from "express-rate-limit";
10
- //import helmet from "helmet";
11
9
  import bodyParser from "body-parser";
12
-
13
10
  import selfsigned from "selfsigned";
14
11
  import openAPIJson from "./openAPIJson.js";
15
- import fs from "fs";
16
12
 
17
13
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
18
14
  import { randomUUID } from "node:crypto";
19
15
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
16
+ import tlogon from "./toolHelpers/tlogon.js";
20
17
 
21
18
 
22
19
  // setup express server
@@ -98,10 +95,9 @@ app.get("/openapi.json", (req, res) => {
98
95
 
99
96
  // handle processing of information in header.
100
97
  function requireBearer(req, res, next) {
101
-
102
-
103
98
  // process any new header information
104
-
99
+ console.error("=======================================================");
100
+ console.error("Processing headers for incoming request to /mcp endpoint");
105
101
  // Allow different VIYA server per sessionid(user)
106
102
  let headerCache = {};
107
103
  if (req.header("X-VIYA-SERVER") != null) {
@@ -115,29 +111,44 @@ function requireBearer(req, res, next) {
115
111
  if (hdr != null) {
116
112
  headerCache.bearerToken = hdr.slice(7);
117
113
  headerCache.AUTHFLOW = "bearer";
114
+ console.error("[Note] Using user supplied bearer token for authorization");
115
+ console.error("[Debug] Bearer token starts with:", headerCache.bearerToken);
116
+ } else {
117
+ console.error("[Note] No bearer token supplied in Authorization header");
118
+ headerCache.bearerToken = null;
118
119
  }
119
120
 
120
121
  // faking out api key since Viya does not support
121
122
  // not ideal for production
122
123
  const hdr2 = req.header("X-REFRESH-TOKEN");
123
124
  if (hdr2 != null) {
124
- headerCache.refreshToken = hdr2;
125
+ headerCache.REFRESH_TOKEN = hdr2;
125
126
  headerCache.AUTHFLOW = "refresh";
127
+ console.error("[Note] Using user supplied refresh token for authorization");
126
128
  }
127
129
  cache.set("headerCache", headerCache);
128
130
  next();
131
+ console.error("Finished processing headers for /mcp request");
132
+ console.log("=======================================================");
129
133
  }
130
134
 
131
135
  // process mcp endpoint requests
132
136
  const handleRequest = async (req, res) => {
133
- let transport;
137
+ let transport = null;
134
138
  let transports = cache.get("transports");
139
+ console.error("=========================================================");
140
+ console.error("Processing POST /mcp request");
141
+ if (transports == null) {
142
+ console.error("[Error] ***** transports cache is null. This is an error");
143
+ transports = {};
144
+ cache.set("transports", transports);
145
+ }
146
+
135
147
  console.error("current transports in cache:", Object.keys(transports));
136
148
  try {
137
149
 
138
150
  let sessionId = req.headers["mcp-session-id"];
139
- console.error("========================================================");
140
- console.error("post /mcp called with session ID:", sessionId);
151
+ console.error("[Note]Incoming session ID:", sessionId);
141
152
  let body = (req.body == null) ? 'no body' : JSON.stringify(req.body);
142
153
  console.error('[Note] Payload is ', body);
143
154
  if (/*!sessionId &&*/ isInitializeRequest(req.body)) {
@@ -157,7 +168,7 @@ const handleRequest = async (req, res) => {
157
168
  });
158
169
  // Clean up transport when closed
159
170
  transport.onclose = () => {
160
- if (transport.sessionId) {
171
+ if (transport.sessionId && transports[transport.sessionId]) {
161
172
  delete transports[transport.sessionId];
162
173
  }
163
174
  };
@@ -165,9 +176,11 @@ const handleRequest = async (req, res) => {
165
176
  await mcpServer.connect(transport);
166
177
 
167
178
  // Save transport data and app context for use in tools
168
- console.error('connected mcpServer');
179
+ console.error('[Note] Connected to mcpServer');
169
180
  cache.set("transports", transports);
181
+ console.error("=======================================================");
170
182
  return await transport.handleRequest(req, res, req.body);
183
+
171
184
  // cache transport
172
185
 
173
186
  } else if (sessionId != null) {
@@ -176,8 +189,8 @@ const handleRequest = async (req, res) => {
176
189
  console.error("[Note] Found transport:", transport != null);
177
190
  if (transport == null) {
178
191
  // this can happen if client is holding on to old session id
179
- console.error("[Error] No transport found for session ID:", sessionId, "Returning a 400 error with instructions for the user");
180
- res.status(400).send(`Invalid or missing session ID ${sessionId}. Please ensure your MCP client is configured to use the correct session ID returned in the 'mcp-session-id' header of the response from the /mcp endpoint.`);
192
+ console.error("[Error] No transport found for session ID:", sessionId, "Returning a 404 error with instructions for the user");
193
+ res.status(404).send(`Invalid or missing session ID ${sessionId}. Please ensure your MCP client is configured to use the correct session ID returned in the 'mcp-session-id' header of the response from the /mcp endpoint.`);
181
194
  return;
182
195
  }
183
196
 
@@ -194,9 +207,15 @@ const handleRequest = async (req, res) => {
194
207
  let headerCache = cache.get("headerCache");
195
208
  _appContext = Object.assign({}, appEnvTemplate, headerCache);
196
209
  cache.set(sessionId, _appContext);
210
+ } else {
211
+ let headerCache = cache.get("headerCache");
212
+ console.error('compare tokens', headerCache.bearerToken === _appContext.bearerToken);
213
+ _appContext = Object.assign(_appContext, headerCache);
214
+ console.error('New bearerToken:', _appContext.bearerToken);
215
+ cache.set(sessionId, _appContext);
197
216
  }
198
217
  console.error("[Note] Using existing transport for session ID:", sessionId);
199
-
218
+ console.error("==========================================================");
200
219
  await transport.handleRequest(req, res, req.body);
201
220
  return;
202
221
  }
@@ -220,20 +239,27 @@ const handleRequest = async (req, res) => {
220
239
  }
221
240
  };
222
241
  const handleGetDelete = async (req, res) => {
223
- console.error(req.method, "/mcp called");
242
+ console.error("=========================================================");
243
+ console.error(`[Note] ${req.method} /mcp called`);
224
244
  const sessionId = req.headers["mcp-session-id"];
225
- console.error("Handling GET/DELETE for session ID:", sessionId);
245
+ console.error("[Note] SessionId:", sessionId);
246
+
226
247
  let transports = cache.get("transports");
227
248
  let transport = (sessionId == null) ? null : transports[sessionId];
249
+ console.error("[Note] Transport found:", transport != null);
228
250
  if (!sessionId || transport == null) {
229
- res.status(400).send(`[Error] In ${req.method}: Invalid or missing session ID ${sessionId}`);
251
+ res.status(404).send(`[Error] In ${req.method}: Invalid or missing session ID ${sessionId}`);
230
252
  return;
231
253
  }
232
- await transport.handleRequest(req, res);
254
+ if (req.method === "GET") {
255
+ await transport.handleRequest(req, res);
256
+ return;
257
+ }
233
258
  if (req.method === "DELETE" && sessionId != null) {
234
- console.error("Deleting transport and cache for session ID:", sessionId);
259
+ console.error("[Note] Deleting transport and cache for session ID:", sessionId);
235
260
  delete transports[sessionId];
236
261
  cache.del(sessionId);
262
+ res.status(201).send(`[Info] Deleted session ${sessionId}`);
237
263
  }
238
264
  }
239
265
 
@@ -241,26 +267,40 @@ app.options("/mcp", (_, res) => res.sendStatus(204));
241
267
  app.post("/mcp", requireBearer, handleRequest);
242
268
  app.get("/mcp", handleGetDelete);
243
269
  app.delete("/mcp", handleGetDelete);
244
- app.get("/startup", (_req, res) => {
245
- console.error("Received request for startup endpoint");
270
+ app.get("/StartUp", (_req, res) => {
271
+ console.error("===================================================================")
272
+ console.error("Received request for Startup endpoint. Current app status:", appStatus);
273
+ console.error("===================================================================");
246
274
  if (appStatus === false) {
247
- return res.status(500).json({ status: "starting" });
275
+ return res.status(503).json({ status: "starting" });
248
276
  }
249
277
  return res.status(200).json({ status: "started" });
250
278
  });
251
-
279
+ app.get("/tlogon", async (_req, res) => {
280
+ console.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Testing logon");
281
+ if (appStatus === false) {
282
+ return res.status(503).json({ status: "not ready" });
283
+ }
284
+ let r = await tlogon(baseAppEnvContext);
285
+ console.error(r);
286
+ return res.status(200).json(r);
287
+ });
252
288
  app.get("/status", (_req, res) => {
289
+ console.error("===================================================================")
253
290
  console.error("Received request for status endpoint. Current app status:", appStatus);
291
+ console.error("===================================================================");
254
292
  if (appStatus === false) {
255
- return res.status(500).json({ status: "not ready" });
293
+ return res.status(503).json({ status: "not ready" });
256
294
  }
257
295
  return res.status(200).json({ status: "ready" });
258
296
  });
259
297
 
260
298
  app.get("/ready", (_req, res) => {
299
+ console.error("===================================================================")
261
300
  console.error("Received request for ready endpoint. Current app status:", appStatus);
301
+ console.error("===================================================================")
262
302
  if (appStatus === false) {
263
- return res.status(500).json({ status: "not ready" });
303
+ return res.status(503).json({ status: "not ready" });
264
304
  }
265
305
  return res.status(200).json({ status: "ready" });
266
306
  });
@@ -274,12 +314,12 @@ let appServer;
274
314
 
275
315
  // get TLS options
276
316
  if (appEnvBase.HTTPS === 'TRUE') {
277
- //appEnvBase.tlsOpts = getOpts(appEnvBase);
278
317
  if (appEnvBase.tlsOpts == null) {
279
318
  appEnvBase.tlsOpts = await getTls(appEnvBase);
280
319
  console.error(Object.keys(appEnvBase.tlsOpts));
281
320
  appEnvBase.tlsOpts.requestCert = false;
282
321
  appEnvBase.tlsOpts.rejectUnauthorized = false;
322
+ appEnvBase.contexts.appCert = appEnvBase.tlsOpts; /* just for completeness */
283
323
  }
284
324
 
285
325
  cache.set("appEnvBase", appEnvBase);
@@ -5,22 +5,25 @@
5
5
 
6
6
  async function handleGetDelete(mcpServer, cache, req, h) {
7
7
  const sessionId = req.headers["mcp-session-id"];
8
- console.error(`Handling ${req.method} for session ID:`, sessionId);
8
+ console.error("=======================================================");
9
+ console.error(`[Note] Handling ${req.method} for session ID:`, sessionId);
9
10
  let transports = cache.get("transports");
10
11
  let transport = transports[sessionId];
11
12
  if (!sessionId || transport == null) {
12
13
  console.error('[Note] Looks like a fresh start - no session id or transport found');
13
- h.abandon;
14
+ return h.abandon;
14
15
  }
15
16
 
16
17
  if (req.method === "GET") {
17
18
  // You can customize the response as needed
19
+ console.error("[Note] Payload:", req.payload);
20
+ console.log("======================================================");
18
21
  await transport.handleRequest(req.raw.req, req.raw.res, req.payload);
19
22
  return h.abandon;
20
23
  }
21
24
 
22
25
  if (req.method === "DELETE") {
23
- console.error("Deleting transport and cache for session ID:", sessionId);
26
+ console.error("[Note] Deleting transport and cache for session ID:", sessionId);
24
27
  delete transports[sessionId];
25
28
  cache.del(sessionId);
26
29
  return h.response(`[Info] In DELETE: Session ID ${sessionId} deleted`).code(201);
@@ -126,6 +126,36 @@ async function hapiMcpServer(mcpServer, cache, baseAppEnvContext) {
126
126
  tags: ["mcp"],
127
127
  }
128
128
  },
129
+ {
130
+ method: ["GET"],
131
+ path: "/ready",
132
+ options: {
133
+ handler: async (req, h) => {
134
+ let status = {status: 1};
135
+ console.error("Ready check requested, returning:", status);
136
+ return h.response(status).code(200).type('application/json');
137
+ },
138
+ auth: false,
139
+ description: "probe readiness of the server",
140
+ notes: "Help",
141
+ tags: ["mcp"],
142
+ }
143
+ },
144
+ {
145
+ method: ["GET"],
146
+ path: "/StartUp",
147
+ options: {
148
+ handler: async (req, h) => {
149
+ let status = { status: 1 };
150
+ console.error("Startup check requested, returning:", status);
151
+ return h.response(status).code(200).type('application/json');
152
+ },
153
+ auth: false,
154
+ description: "probe startup of the server",
155
+ notes: "Help",
156
+ tags: ["mcp"],
157
+ }
158
+ },
129
159
  {
130
160
  method: ["GET"],
131
161
  path: "/apiMeta",