@sassoftware/sas-score-mcp-serverjs 1.1.4 → 1.1.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.
@@ -16,7 +16,7 @@ Note: the five-step phrasing (Identify → Verify → Select → Execute → For
16
16
  - Append a **Strategy Summary** to every response.
17
17
  - Always determine table server (CAS vs SAS) during verification; ask if ambiguous.
18
18
  - Do not invent resource names, servers, or model types — verify or ask.
19
- - Pagination: always pass `start=1` and `limit=10` when calling any tool that accepts these parameters, unless the user specifies different values.
19
+ - Pagination: if the tool accepts start and limit parameters, default to `start=1` and `limit=10` when calling any tool that accepts these parameters, unless the user specifies different values.
20
20
 
21
21
  ## Model types
22
22
  All of the following are treated as **models** that can be scored:
@@ -19,15 +19,20 @@ description: >
19
19
  | Job | `sas-score-find-job` | `sas-score-job-score` |
20
20
  | JobDef | `sas-score-find-jobdef` | `sas-score-jobdef-score` |
21
21
 
22
+ ##
22
23
  ## Inline Scenario Scoring
23
24
 
25
+
24
26
  **Job:**
25
- 1. Verify: `sas-score-find-job({ name })`
26
- 2. Score: `sas-score-job-score({ name, scenario })`
27
+
28
+ 1. Strip suffix '.job' from the model name, if present
29
+ 2. Verify: `sas-score-find-job({ name })`
30
+ 3. Score: `sas-score-job-score({ name, scenario })`
27
31
 
28
32
  **JobDef:**
29
- 1. Verify: `sas-score-find-jobdef({ name })`
30
- 2. Score: `sas-score-jobdef-score({ name, scenario })`
33
+ 1. Strip suffix '.jobdef' from the model name, if present
34
+ 2. Verify: `sas-score-find-jobdef({ name })`
35
+ 3. Score: `sas-score-jobdef-score({ name, scenario })`
31
36
 
32
37
  ## Table Row Scoring
33
38
 
@@ -22,12 +22,14 @@ description: >
22
22
  ## Inline Scenario Scoring
23
23
 
24
24
  **MAS:**
25
- 1. Verify: `sas-score-find-mas({ model })`
26
- 2. Score: `sas-score-mas-score({ model, scenario })`
25
+ 1. Strip suffix '.mas' from the model name, if present
26
+ 2. Verify: `sas-score-find-mas({ model })`
27
+ 3. Score: `sas-score-mas-score({ model, scenario })`
27
28
 
28
29
  **SCR:**
29
- 1. Verify: `sas-score-find-scr({ model })`
30
- 2. Score: `sas-score-scr-score({ model, scenario })`
30
+ 1. Strip suffix '.scr' from the model name, if present
31
+ 2. Verify: `sas-score-find-scr({ model })`
32
+ 3. Score: `sas-score-scr-score({ model, scenario })`
31
33
 
32
34
  ## Table Row Scoring
33
35
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassoftware/sas-score-mcp-serverjs",
3
- "version": "1.1.4",
3
+ "version": "1.1.7",
4
4
  "description": "A mcp server for SAS Viya",
5
5
  "author": "Deva Kumar <deva.kumar@sas.com>",
6
6
  "license": "Apache-2.0",
@@ -0,0 +1,35 @@
1
+ import fs from 'fs';
2
+ import jobScore from '../src/toolSet/jobScore.js';
3
+
4
+ async function main() {
5
+ // Build minimal _appContext from environment
6
+ const VIYA_SERVER = process.env.VIYA_SERVER || null;
7
+ let token = process.env.TOKEN || null;
8
+ if (!token && process.env.TOKENFILE) {
9
+ try { token = fs.readFileSync(process.env.TOKENFILE, 'utf8').trim(); } catch (e) { /* ignore */ }
10
+ }
11
+
12
+ const _appContext = {
13
+ storeConfig: { casProxy: true, options: { ns: null, proxyServer: null, httpOptions: null } },
14
+ logonPayload: (VIYA_SERVER && token) ? { host: VIYA_SERVER, authType: 'server', token: token, tokenType: 'Bearer' } : null,
15
+ contexts: { host: VIYA_SERVER }
16
+ };
17
+
18
+ const spec = jobScore(_appContext);
19
+
20
+ const params = {
21
+ name: 'simplejob.job',
22
+ scenario: 'a=1,b=2',
23
+ _appContext: _appContext
24
+ };
25
+
26
+ try {
27
+ const r = await spec.handler(params);
28
+ console.log(JSON.stringify(r, null, 2));
29
+ } catch (err) {
30
+ console.error('Error invoking job-score:', err);
31
+ process.exitCode = 2;
32
+ }
33
+ }
34
+
35
+ main();
@@ -54,11 +54,14 @@ async function _jobSubmit(params) {
54
54
  let store = restaf.initStore(_appContext.storeConfig);
55
55
  let msg = await store.logon(_appContext.logonPayload);
56
56
  type = (type == null) ? 'job' : type.toLowerCase();
57
-
57
+ console.error(`Job submission type resolved to: ${type}`);
58
+ console.error(`Job submission name resolved to: ${name}`);
59
+ console.error(`Job submission scenario resolved to: ${JSON.stringify(scenario)}`);
58
60
  let r = (type === 'definition' || type === 'def')
59
61
  ? await restaflib.jesRun(store, name, scenario)
60
62
  : await restaflib.jobRun(store, name, scenario);
61
63
 
64
+ console.error(`Response from job submission: ${JSON.stringify(r)}`);
62
65
  let response = (query === true) ? { tabled: r.tables.rows } : { tables: r.tables, listing: r.listing, log: r.log };
63
66
 
64
67
  return {
@@ -51,8 +51,8 @@ Returns log output, listings, tables from jobdef. Error if jobdef not found.
51
51
  handler: async (params) => {
52
52
  let {scenario, name} = params;
53
53
 
54
- if (name.endsWith('.job')) {
55
- params.name = name.slice(0, -4);
54
+ if (name.endsWith('.jobdef')) {
55
+ name = name.slice(0, -7);
56
56
  }
57
57
  // Convert the scenario string to an object
58
58
  // Example: "x=1, y=2, z=3" to { x: 1, y: 2, z: 3 }
@@ -71,7 +71,8 @@ Returns log output, listings, tables from jobdef. Error if jobdef not found.
71
71
  return acc;
72
72
  }, {});
73
73
  }
74
- params.scenario = scenarioObj;
74
+ params.scenario = scenarioObj;
75
+ params.name = name;
75
76
  params.type = 'def';
76
77
  // Provide runtime context for auth and server settings
77
78
  let r = await _jobSubmit(params);
@@ -38,7 +38,7 @@ NEGATIVE EXAMPLES (do not route here)
38
38
  - is jobdef X available (use ${_appContext.brand}-find-jobdef)
39
39
  - list jobs (use ${_appContext.brand}-list-jobs)
40
40
  - score jobdef abc (use ${_appContext.brand}-jobdef-score)
41
- - list models (use ${_appContext.brand}-list-models)
41
+ - list mas (use ${_appContext.brand}-list-mas)
42
42
 
43
43
  PAGINATION
44
44
  If returned length === limit, hint: next start = start + limit. Empty result with start > 1 means paged past end.
@@ -35,7 +35,7 @@ EXAMPLES
35
35
  NEGATIVE EXAMPLES (do not route here)
36
36
  - find job abc (use ${_appContext.brand}-find-job)
37
37
  - score job abc (use ${_appContext.brand}-job-score)
38
- - list models (use ${_appContext.brand}-list-models)
38
+ - list mas (use ${_appContext.brand}-list-mas)
39
39
  - list tables in lib xyz (use ${_appContext.brand}-list-tables)
40
40
 
41
41
  PAGINATION
@@ -36,8 +36,8 @@ EXAMPLES
36
36
  - "Show variables for myModel" → { model: "myModel" }
37
37
 
38
38
  NEGATIVE EXAMPLES (do not route here)
39
- - "list mas" (use list-models)
40
- - "find mas X" (use find-model)
39
+ - "list mas" (use list-mas)
40
+ - "find mas X" (use find-mas)
41
41
  - "score with mas X" (use model-score)
42
42
 
43
43
  ERRORS
@@ -37,7 +37,6 @@ EXAMPLES
37
37
  NEGATIVE EXAMPLES (do not route here)
38
38
  - "find model X" (use find-model)
39
39
  - "what inputs does model need" (use model-info)
40
- - "list models" (use list-models)
41
40
  - "score job X" (use job-score)
42
41
 
43
42
  ERRORS