@sassoftware/sas-score-mcp-serverjs 0.3.11 → 0.3.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassoftware/sas-score-mcp-serverjs",
3
- "version": "0.3.11",
3
+ "version": "0.3.14",
4
4
  "description": "A mcp server for SAS Viya",
5
5
  "author": "Deva Kumar <deva.kumar@sas.com>",
6
6
  "license": "Apache-2.0",
@@ -23,7 +23,7 @@ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
23
23
 
24
24
  async function expressMcpServer(mcpServer, cache, baseAppEnvContext) {
25
25
  // setup for change to persistence session
26
- let headerCache = {};
26
+ cache.set("headerCache", {});
27
27
 
28
28
  const app = express();
29
29
 
@@ -120,7 +120,7 @@ function requireBearer(req, res, next) {
120
120
  headerCache.refreshToken = hdr2;
121
121
  headerCache.AUTHFLOW = "refresh";
122
122
  }
123
-
123
+ cache.set("headerCache", headerCache);
124
124
  next();
125
125
  }
126
126
 
@@ -128,15 +128,17 @@ function requireBearer(req, res, next) {
128
128
  const handleRequest = async (req, res) => {
129
129
  let transport;
130
130
  let transports = cache.get("transports");
131
+ console.error("current transports in cache:", Object.keys(transports));
131
132
  try {
132
133
 
133
134
  let sessionId = req.headers["mcp-session-id"];
134
135
 
135
136
  // we have session id, get existing transport
136
-
137
+ console.error('>>>>>>>>>>>>>> Received request for MCP endpoint with session ID:', req.method, sessionId);
137
138
  if (sessionId != null) {
138
- /* existing transport */
139
+ console.error("Looking for transport with session ID:", sessionId);
139
140
  transport = transports[sessionId];
141
+ console.error("Found transport:", transport != null);
140
142
  if (transport == null) {
141
143
  throw new Error(`No transport found for session ID: ${sessionId}`);
142
144
  }
@@ -151,23 +153,27 @@ const handleRequest = async (req, res) => {
151
153
  if (_appContext == null) {
152
154
 
153
155
  let appEnvTemplate = cache.get("appEnvTemplate");
156
+ let headerCache = cache.get("headerCache");
154
157
  _appContext = Object.assign({}, appEnvTemplate, headerCache);
155
158
  cache.set(sessionId, _appContext);
156
159
  }
157
160
  console.error("[Note] Using existing transport for session ID:", sessionId);
158
161
 
159
162
  await transport.handleRequest(req, res, req.body);
163
+ return;
160
164
  }
161
165
 
162
166
  // initialize request
163
167
  else if (!sessionId && isInitializeRequest(req.body)) {
164
168
  // create transport
165
-
169
+ console.error("[Note] Initializing new transport for MCP session...");
166
170
  transport = new StreamableHTTPServerTransport({
167
171
  sessionIdGenerator: () => randomUUID(),
168
172
  enableJsonResponse: true,
173
+ enableDnsRebindingProtection: true,
169
174
  onsessioninitialized: (sessionId) => {
170
175
  // Store the transport by session ID
176
+ console.error("++++++++++++++++++++++++++++++ Transport initialized with ID:", sessionId);
171
177
  transports[sessionId] = transport;
172
178
  },
173
179
  });
@@ -178,14 +184,16 @@ const handleRequest = async (req, res) => {
178
184
  }
179
185
  };
180
186
  console.error("[Note] Connecting mcpServer to new transport...");
187
+ console.error('connecting mcp Server with session ID:', transport.sessionId);
188
+ console.error('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> connecting mcp Server with session ID:', transport.sessionId);
181
189
  await mcpServer.connect(transport);
182
190
 
183
191
  // Save transport data and app context for use in tools
184
-
185
- await transport.handleRequest(req, res, req.body);
186
- // cache transport
192
+ console.error('connected mcpServer');
187
193
  cache.set("transports", transports);
188
-
194
+ return await transport.handleRequest(req, res, req.body);
195
+ // cache transport
196
+
189
197
  }
190
198
  }
191
199
  catch (error) {
@@ -208,13 +216,13 @@ const handleGetDelete = async (req, res) => {
208
216
  const sessionId = req.headers["mcp-session-id"];
209
217
  console.error("Handling GET/DELETE for session ID:", sessionId);
210
218
  let transports = cache.get("transports");
211
- let transport = transports[sessionId];
219
+ let transport = (sessionId == null) ? null : transports[sessionId];
212
220
  if (!sessionId || transport == null) {
213
221
  res.status(400).send(`[Error] In ${req.method}: Invalid or missing session ID ${sessionId}`);
214
222
  return;
215
223
  }
216
224
  await transport.handleRequest(req, res);
217
- if (req.method === "DELETE") {
225
+ if (req.method === "DELETE" && sessionId != null) {
218
226
  console.error("Deleting transport and cache for session ID:", sessionId);
219
227
  delete transports[sessionId];
220
228
  cache.del(sessionId);
@@ -7,7 +7,7 @@ function openAPIJson(version) {
7
7
  "swagger": "2.0",
8
8
  "info": {
9
9
  "title": "sas-score-mcp-serverjs API",
10
- "version": version,
10
+ "version": "1.0.0",
11
11
  "description": "sas-score-mcp-serverjs is a mcp server for SAS Viya"
12
12
  },
13
13
  "host": "localhost:8080",
@@ -17,9 +17,9 @@ function openAPIJson(version) {
17
17
  "produces": ["application/json"],
18
18
  "paths": {
19
19
  "/health": {
20
- "GET": {
20
+ "get": {
21
21
  "summary": "Health check",
22
- "operationId": "GetHealth",
22
+ "operationId": "getHealth",
23
23
  "description": "Returns health and version information.",
24
24
  "responses": {
25
25
  "200": {
@@ -39,7 +39,7 @@ function openAPIJson(version) {
39
39
  }
40
40
  },
41
41
  "/apiMeta": {
42
- "GET": {
42
+ "get": {
43
43
  "summary": "API metadata using apiMeta",
44
44
  "operationId": "GetApiMeta",
45
45
  "responses": {
@@ -50,8 +50,8 @@ function openAPIJson(version) {
50
50
  }
51
51
  }
52
52
  },
53
- "/openapi.json": {
54
- "GET": {
53
+ "/openapi.json": {
54
+ "get": {
55
55
  "summary": "API metadata using openapi.json",
56
56
  "operationId": "GetOpenApiJson",
57
57
  "description": "Returns the OpenAPI specification for this server.",
@@ -64,7 +64,7 @@ function openAPIJson(version) {
64
64
  }
65
65
  },
66
66
  "/mcp": {
67
- "OPTIONS": {
67
+ "options": {
68
68
  "summary": "CORS preflight",
69
69
  "operationId": "OptionsMcp",
70
70
  "description": "CORS preflight endpoint.",
@@ -72,7 +72,7 @@ function openAPIJson(version) {
72
72
  "204": { "description": "No Content" }
73
73
  }
74
74
  },
75
- "POST": {
75
+ "post": {
76
76
  "summary": "MCP request",
77
77
  "operationId": "PostMcp",
78
78
  "parameters": [
@@ -122,8 +122,8 @@ function openAPIJson(version) {
122
122
  }
123
123
  }
124
124
  },
125
- "GET": {
126
- "summary": "Get MCP session",
125
+ "get": {
126
+ "summary": "get MCP session",
127
127
  "operationId": "GetMcp",
128
128
  "description": "Retrieves information for an MCP session.",
129
129
  "parameters": [
@@ -145,7 +145,7 @@ function openAPIJson(version) {
145
145
  }
146
146
  }
147
147
  },
148
- "DELETE": {
148
+ "delete": {
149
149
  "summary": "Delete MCP session",
150
150
  "operationId": "DeleteMcp",
151
151
  "parameters": [
@@ -169,7 +169,7 @@ function openAPIJson(version) {
169
169
  }
170
170
  }
171
171
  }
172
- };
172
+ }
173
173
  spec.info.version = version;
174
174
  return spec;
175
175
  };