@sassoftware/sas-score-mcp-serverjs 0.4.1-3 → 0.4.1-6

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
@@ -84,7 +84,7 @@ const args = parseArgs({
84
84
 
85
85
  // Handle help flag
86
86
  if (args.values.help) {
87
- console.log(`
87
+ console.error(`
88
88
  Usage: sas-score-mcp-serverjs [options]
89
89
 
90
90
  Options:
@@ -108,7 +108,7 @@ Environment Variables:
108
108
  // Handle version flag
109
109
  if (args.values.version) {
110
110
  let pkgJson = JSON.parse(pkg);
111
- console.log(pkgJson.version);
111
+ console.error(pkgJson.version);
112
112
  process.exit(0);
113
113
  }
114
114
 
@@ -122,7 +122,7 @@ if (process.env.ENVFILE === 'FALSE') {
122
122
  console.error('Env file:', envf);
123
123
  if (fs.existsSync(envf)) {
124
124
  console.error(`Loading environment variables from ${envf}...`);
125
- let e = iconfig(envf); // avoid dotenv since it writes to console.log
125
+ let e = iconfig(envf); // avoid dotenv since it writes to console.error
126
126
  console.error('[Note]: Environment variables loaded from .env file...');
127
127
  console.error('Loaded env variables:', e);
128
128
  // dotenvExpand.expand(e);
@@ -354,6 +354,8 @@ console.error('[Note] appEnvBase is', JSON.stringify(appEnvBase, null,2));
354
354
  // 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
355
355
  let sessionId = randomUUID();
356
356
  sessionCache.set(sessionId, appEnvBase);
357
+ sessionCache.set('currentId', sessionId);
358
+
357
359
  if (mcpType === 'stdio') {
358
360
  console.error('[Note] Setting up stdio transport with sessionId:', sessionId);
359
361
  console.error('[Note] Used in setting up tools and some persistence(not all).');
@@ -390,7 +392,7 @@ function iconfig(envFile) {
390
392
  });
391
393
  return envData;
392
394
  } catch (err) {
393
- console.log(err);
395
+ console.error(err);
394
396
  process.exit(0);
395
397
  }
396
398
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassoftware/sas-score-mcp-serverjs",
3
- "version": "0.4.1-3",
3
+ "version": "0.4.1-6",
4
4
  "description": "A mcp server for SAS Viya",
5
5
  "author": "Deva Kumar <deva.kumar@sas.com>",
6
6
  "license": "Apache-2.0",
@@ -81,7 +81,7 @@ async function createMcpServer(cache, _appContext) {
81
81
 
82
82
  console.error(`\n[Note] Registering tool ${i + 1} : ${toolName}`);
83
83
  let toolHandler = wrapf(cache, tool.handler);
84
- console.log(`[Note] Registering tool ${toolName} with config: ${JSON.stringify(config)}`);
84
+ console.error(`[Note] Registering tool ${toolName} with config: ${JSON.stringify(config)}`);
85
85
  let r = mcpServer.registerTool(toolName, config, toolHandler);
86
86
  toolNames.push(toolName);
87
87
  });
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "mcp__sasmcp__sas-score-deva-score"
5
+ ]
6
+ }
7
+ }
@@ -44,7 +44,6 @@ Returns { score: (a + b) * 42 }
44
44
  a: z.number(),
45
45
  b: z.number(),
46
46
  }),
47
- required: ['a', 'b'],
48
47
  handler: async ({ a, b }) => {
49
48
  console.error(a, b);
50
49
  let r = { score: (a + b) * 42 };
@@ -44,7 +44,8 @@ Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Nev
44
44
  name: 'find-library',
45
45
  description: description,
46
46
  inputSchema: z.object({
47
- name: z.string()
47
+ name: z.string(),
48
+ server: z.string().optional()
48
49
  }),
49
50
 
50
51
  handler: async (params) => {
@@ -48,7 +48,7 @@ Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hal
48
48
  description: description,
49
49
  inputSchema: z.object({
50
50
  name: z.string(),
51
- lib: z.string().optional(),
51
+ lib: z.string(),
52
52
  server: z.string().optional() // default server is 'cas'
53
53
  }),
54
54
 
@@ -51,7 +51,8 @@ Returns empty array if no tables found.
51
51
  lib: z.string(),
52
52
  server: z.string().optional(),
53
53
  limit: z.number().optional(),
54
- start: z.number().optional()
54
+ start: z.number().optional(),
55
+ where: z.string().optional()
55
56
  }),
56
57
  handler: async (params) => {
57
58
  let r = await _listTables(params);
@@ -46,13 +46,13 @@ Returns rows array, total count, filtered_count, columns metadata. Empty array i
46
46
  name: 'read-table',
47
47
  description: describe,
48
48
  inputSchema: z.object({
49
- table: z.string(),
50
- lib: z.string().optional(),
51
- start: z.number().optional(),
52
- limit: z.number().optional(),
53
- server: z.string().optional(),
54
- where: z.string().optional()
55
- }),
49
+ table: z.string(),
50
+ lib: z.string().optional(),
51
+ start: z.number().optional(),
52
+ limit: z.number().optional(),
53
+ server: z.string().optional(),
54
+ where: z.string().optional()
55
+ }),
56
56
  handler: async (params) => {
57
57
  let r = await _readTable(params,'query');
58
58
  return r;
@@ -41,7 +41,7 @@ Returns log output, listings, tables from job. Error if job not found.
41
41
  description: description,
42
42
  inputSchema: z.object({
43
43
  name: z.string(),
44
- scenario: z.string()
44
+ scenario: z.string().optional()
45
45
  }),
46
46
  handler: async (params) => {
47
47
  let scenario = params.scenario;
@@ -42,7 +42,7 @@ Returns log output, listings, tables from jobdef. Error if jobdef not found.
42
42
  description: description,
43
43
  inputSchema: z.object({
44
44
  name: z.string(),
45
- scenario: z.string()
45
+ scenario: z.string().optional()
46
46
  }),
47
47
  handler: async (params) => {
48
48
  let scenario = params.scenario;
@@ -40,8 +40,9 @@ Returns log, ods, tables created by macro. Auto-converts "x=1, y=2" to "%let x=1
40
40
  name: 'run-macro',
41
41
  description: description,
42
42
 
43
- inputSchema: z.object({
44
- macro: z.string()
43
+ inputSchema: z.object({
44
+ macro: z.string(),
45
+ scenario: z.string().optional()
45
46
  }),
46
47
 
47
48
  handler: async (params) => {
@@ -44,16 +44,12 @@ Returns log, ods, tables array, data (if output specified). Error if execution f
44
44
  name: 'run-program',
45
45
  description: description,
46
46
  inputSchema: z.object({
47
- src: z.string().optional,
48
- scenario: z.any(),
49
- output: z.string(),
50
- folder: z.string(),
47
+ src: z.string(),
48
+ scenario: z.string().optional(),
49
+ output: z.string().optional(),
50
+ folder: z.string().optional(),
51
51
  limit: z.number().optional()
52
52
  }),
53
- // NOTE: Previously 'required' incorrectly listed 'program' which does not
54
- // exist in the schema. This prevented execution in some orchestrators that
55
- // enforce required parameter presence, causing only descriptions to appear.
56
- // Corrected to 'src'.
57
53
  handler: async (params) => {
58
54
  let {src, folder, scenario, _appContext} = params;
59
55
  // figure out src
@@ -45,7 +45,7 @@ Returns rows array, columns metadata, log. Returns error if SQL invalid or table
45
45
  inputSchema: z.object({
46
46
  query: z.string(),
47
47
  table: z.string(),
48
- sql: z.string()
48
+ sql: z.string().optional()
49
49
  }),
50
50
  handler: async (params) => {
51
51
  let {table,query, sql, job, _appContext} = params;
@@ -39,8 +39,7 @@ Examples
39
39
  description: description,
40
40
  inputSchema: z.object({
41
41
  url: z.string(),
42
- scenario: z.string()
43
-
42
+ scenario: z.string().optional()
44
43
  }),
45
44
 
46
45
  handler: async (params) => {
@@ -43,9 +43,10 @@ Returns columns array (name, type, label, format, length) and tableInfo (rowCoun
43
43
  name: 'table-info',
44
44
  description: describe,
45
45
  inputSchema: z.object({
46
- table: z.string(),
47
- lib: z.string().optional()
48
- }),
46
+ table: z.string(),
47
+ lib: z.string().optional(),
48
+ server: z.string().optional()
49
+ }),
49
50
  handler: async (params) => {
50
51
  params.describe = true;
51
52
  let r = await _tableInfo(params);