@sassoftware/sas-score-mcp-serverjs 1.0.1-9 → 1.1.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.
Files changed (118) hide show
  1. package/.skills/.claude-plugin/plugin.json +59 -0
  2. package/.skills/agents/sas-score-mcp-serverjs-agent.md +26 -0
  3. package/.skills/copilot-instructions.md +62 -0
  4. package/.skills/skills/README.md +204 -0
  5. package/.skills/skills/detail-strategy/SKILL.md +316 -0
  6. package/.skills/skills/find-library-server/SKILL.md +62 -0
  7. package/.skills/skills/find-resources/SKILL.md +66 -0
  8. package/.skills/skills/list-library/SKILL.md +30 -0
  9. package/.skills/skills/list-mas-job-jobdef/SKILL.md +31 -0
  10. package/.skills/skills/list-tables/SKILL.md +30 -0
  11. package/.skills/skills/read-strategy/SKILL.md +87 -0
  12. package/.skills/skills/request-routing/SKILL.md +112 -0
  13. package/.skills/skills/score-cas/SKILL.md +95 -0
  14. package/.skills/skills/score-job-jobdef/SKILL.md +58 -0
  15. package/.skills/skills/score-mas-scr/SKILL.md +58 -0
  16. package/.skills/skills/score-program/SKILL.md +59 -0
  17. package/.skills/skills/score-strategy/SKILL.md +39 -0
  18. package/README.md +96 -54
  19. package/cli.js +11 -13
  20. package/openApi.yaml +121 -121
  21. package/package.json +16 -14
  22. package/scripts/docs/SCORE_SKILL_REFERENCE.md +17 -16
  23. package/scripts/docs/TOOL_DESCRIPTION_TEMPLATE.md +3 -3
  24. package/scripts/docs/TOOL_UPDATES_SUMMARY.md +65 -63
  25. package/scripts/docs/oauth-http-transport.md +2 -2
  26. package/scripts/docs/sas-mcp-tools-reference.md +43 -32
  27. package/scripts/plot_msrp_usa.py +49 -0
  28. package/scripts/refreshtoken.js +58 -0
  29. package/scripts/runListScr.mjs +16 -0
  30. package/src/createMcpServer.js +4 -1
  31. package/src/expressMcpServer.js +47 -49
  32. package/src/oauthHandlers/authorize.js +4 -1
  33. package/src/oauthHandlers/baseUrl.js +4 -0
  34. package/src/oauthHandlers/callback.js +4 -0
  35. package/src/oauthHandlers/getMetadata.js +4 -0
  36. package/src/oauthHandlers/index.js +4 -0
  37. package/src/oauthHandlers/token.js +4 -0
  38. package/src/openApi.yaml +121 -121
  39. package/src/processHeaders.js +10 -7
  40. package/src/setupSkills.js +1 -18
  41. package/src/toolHelpers/_casScore.js +32 -0
  42. package/src/toolHelpers/_desc.js +14 -0
  43. package/src/toolHelpers/_findJob.js +12 -0
  44. package/src/toolHelpers/_findJobdef.js +10 -0
  45. package/src/toolHelpers/_findLibrary.js +11 -0
  46. package/src/toolHelpers/_findMas.js +13 -0
  47. package/src/toolHelpers/_findScr.js +36 -0
  48. package/src/toolHelpers/_findTable.js +11 -0
  49. package/src/toolHelpers/_listJobdefs.js +12 -2
  50. package/src/toolHelpers/_listJobs.js +19 -8
  51. package/src/toolHelpers/{_listModels.js → _listMas.js} +4 -4
  52. package/src/toolHelpers/_listScr.js +13 -0
  53. package/src/toolHelpers/{_scrInfo.js → _scrDescribe.js} +4 -4
  54. package/src/toolHelpers/_scrScore.js +2 -2
  55. package/src/toolHelpers/_submitCasl.js +19 -17
  56. package/src/toolHelpers/{_tableInfo.js → _tableDescribe.js} +2 -2
  57. package/src/toolHelpers/getLogonPayload.js +2 -2
  58. package/src/toolSet/casModelScore.js +93 -0
  59. package/src/toolSet/casProgramScore.js +105 -0
  60. package/src/toolSet/devaScore.js +11 -6
  61. package/src/toolSet/findJob.js +74 -59
  62. package/src/toolSet/findJobdef.js +67 -64
  63. package/src/toolSet/findLibrary.js +28 -23
  64. package/src/toolSet/findMas.js +72 -0
  65. package/src/toolSet/findScr.js +69 -0
  66. package/src/toolSet/findTable.js +34 -27
  67. package/src/toolSet/getEnv.js +57 -57
  68. package/src/toolSet/jobDescribe.js +65 -0
  69. package/src/toolSet/jobScore.js +90 -0
  70. package/src/toolSet/jobdefDescribe.js +67 -0
  71. package/src/toolSet/jobdefScore.js +85 -0
  72. package/src/toolSet/listJobdefs.js +17 -8
  73. package/src/toolSet/listJobs.js +15 -8
  74. package/src/toolSet/listLibraries.js +16 -10
  75. package/src/toolSet/listMas.js +71 -0
  76. package/src/toolSet/listScr.js +62 -0
  77. package/src/toolSet/listTables.js +78 -66
  78. package/src/toolSet/{runMacro.js → macroScore.js} +86 -82
  79. package/src/toolSet/makeTools.js +39 -25
  80. package/src/toolSet/masDescribe.js +67 -0
  81. package/src/toolSet/masScore.js +95 -0
  82. package/src/toolSet/{runProgram.js → programScore.js} +96 -93
  83. package/src/toolSet/readTable.js +43 -26
  84. package/src/toolSet/sasQuery.js +24 -18
  85. package/src/toolSet/scrDescribe.js +55 -0
  86. package/src/toolSet/scrScore.js +63 -70
  87. package/src/toolSet/searchAssets.js +1 -1
  88. package/src/toolSet/setContext.js +8 -3
  89. package/src/toolSet/superstat.js +61 -61
  90. package/src/toolSet/tableDescribe.js +65 -0
  91. package/.agents/sas-score-mcp-serverjs-agent.md +0 -58
  92. package/.instructions/copilot-instructions.md +0 -201
  93. package/.instructions/enforce-find-resource-strategy.md +0 -35
  94. package/.skills/sas-find-library-smart/SKILL.md +0 -155
  95. package/.skills/sas-find-resource-strategy/SKILL.md +0 -105
  96. package/.skills/sas-list-resource-strategy/SKILL.md +0 -124
  97. package/.skills/sas-list-tables-smart/SKILL.md +0 -128
  98. package/.skills/sas-read-and-score-strategy/SKILL.md +0 -113
  99. package/.skills/sas-read-strategy/SKILL.md +0 -154
  100. package/.skills/sas-request-classifier/SKILL.md +0 -74
  101. package/.skills/sas-score-workflow-strategy/SKILL.md +0 -314
  102. package/scripts/optimize_final.py +0 -140
  103. package/scripts/optimize_tools.py +0 -99
  104. package/scripts/setup-skills.js +0 -34
  105. package/scripts/update_descriptions.py +0 -46
  106. package/src/authpkce.js +0 -219
  107. package/src/handleGetDelete.js +0 -34
  108. package/src/handleRequest.js +0 -112
  109. package/src/hapiMcpServer.js +0 -241
  110. package/src/toolSet/findModel.js +0 -60
  111. package/src/toolSet/listModels.js +0 -56
  112. package/src/toolSet/modelInfo.js +0 -55
  113. package/src/toolSet/modelScore.js +0 -89
  114. package/src/toolSet/runCasProgram.js +0 -98
  115. package/src/toolSet/runJob.js +0 -81
  116. package/src/toolSet/runJobdef.js +0 -82
  117. package/src/toolSet/scrInfo.js +0 -52
  118. package/src/toolSet/tableInfo.js +0 -58
@@ -1,59 +1,74 @@
1
- /*
2
- * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
- import { z } from 'zod';
6
- import _listJobs from '../toolHelpers/_listJobs.js';
7
- function findJob(_appContext) {
8
-
9
- let description = `
10
- find-job locate a specific SAS Viya job.
11
-
12
- USE when: find job, does job exist, is there a job named, lookup job, verify job exists
13
- DO NOT USE for: list jobs (use list-jobs), run job (use run-job), execute jobdef (use run-jobdef), find lib/table/model (use respective tools)
14
-
15
- PARAMETERS
16
- - name: string (required) — job name to locate; if multiple supplied, use first
17
-
18
- ROUTING RULES
19
- - "find job <name>" → { name: "<name>" }
20
- - "does job <name> exist" → { name: "<name>" }
21
- - "is there a job named <name>" { name: "<name>" }
22
- - "lookup/verify job <name>" → { name: "<name>" }
23
- - "find job" with no name → ask "Which job name would you like to find?"
24
- - "find all jobs / list jobs" use list-jobs instead
25
- - "run job <name>" → use run-job instead
26
-
27
- EXAMPLES
28
- - "find job cars_job_v4" → { name: "cars_job_v4" }
29
- - "does job ETL exist" → { name: "ETL" }
30
- - "is there a job named metricsRefresh" → { name: "metricsRefresh" }
31
-
32
- NEGATIVE EXAMPLES (do not route here)
33
- - "list jobs" (use list-jobs)
34
- - "run job cars_job_v4" (use run-job)
35
- - "execute jobdef cars_job_v4" (use run-jobdef)
36
-
37
- ERRORS
38
- Returns { jobs: [] } if not found; { jobs: [name, ...] } if found. Never hallucinate job names.
39
- `;
40
-
41
- let spec = {
42
- name: 'find-job',
43
- description: description,
44
- inputSchema: z.object({
45
- name: z.string()
46
- }),
47
- handler: async (params) => {
48
- let r = await _listJobs(params);
49
- return r;
50
- }
51
- }
52
-
53
-
54
- /* correct spec for registerTool with inputSchema */
55
-
56
- return spec;
57
- }
58
- export default findJob;
59
-
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { z } from 'zod';
6
+ import _listJobs from '../toolHelpers/_listJobs.js';
7
+ import _findJob from '../toolHelpers/_findJob.js';
8
+ function findJob(_appContext) {
9
+ const isAgent = _appContext && _appContext.agent;
10
+ let description = isAgent ? `
11
+ find-job — verify a Job model exists.
12
+ PARAMS: name (string, required)
13
+ RETURNS: job metadata if found, error if not found
14
+ ` : `
15
+ find-job — locate a specific SAS Viya job.
16
+
17
+ USE when: find job, does job exist, is there a job named, lookup job, verify job exists
18
+ DO NOT USE for: list jobs (use ${_appContext.brand}-list-jobs), score job (use ${_appContext.brand}-job-score), score jobdef (use ${_appContext.brand}-jobdef-score), find lib/table/model (use respective tools)
19
+
20
+ PARAMETERS
21
+ - name: string (required) job name to locate; if multiple supplied, use first
22
+
23
+ Naming Rules:
24
+ - If user provides name with "job" suffix ".job", strip the suffix (e.g., "cars_job_v4.job"), and look for "cars_job_v4".
25
+
26
+ ROUTING RULES
27
+ - "find job <name>" → { name: "<name>" }
28
+ - "find name.job" → { name: "<name>" }
29
+ - "does job <name> exist" → { name: "<name>" }
30
+ - "is there a job named <name>" → { name: "<name>" }
31
+ - "lookup/verify job <name>" → { name: "<name>" }
32
+ - "find job" with no name → ask "Which job name would you like to find?"
33
+ - "find all jobs / list jobs" use ${_appContext.brand}-list-jobs instead
34
+ - "score job <name>" use ${_appContext.brand}-job-score instead
35
+
36
+ EXAMPLES
37
+ - "find job cars_job_v4" → { name: "cars_job_v4" }
38
+ - "does job ETL exist" { name: "ETL" }
39
+ - "is there a job named metricsRefresh" → { name: "metricsRefresh" }
40
+
41
+ NEGATIVE EXAMPLES (do not route here)
42
+ - "list jobs" (use ${_appContext.brand}-list-jobs)
43
+ - "score job cars_job_v4" (use ${_appContext.brand}-job-score)
44
+ - "score jobdef cars_job_v4" (use ${_appContext.brand}-jobdef-score)
45
+
46
+ ERRORS
47
+ Returns { jobs: [] } if not found; { jobs: [name, ...] } if found. Never hallucinate job names.
48
+ `;
49
+
50
+ let spec = {
51
+ name: 'find-job',
52
+ description: description,
53
+ inputSchema: z.object({
54
+ name: z.string()
55
+ }),
56
+ handler: async (params) => {
57
+ if (params.name != null) {
58
+ if (params.name.endsWith('.job')) {
59
+ params.name = params.name.slice(0, -4);
60
+ }
61
+ }
62
+ params.tool = 'find';
63
+ let r = await _findJob(params);
64
+ return r;
65
+ }
66
+ }
67
+
68
+
69
+ /* correct spec for registerTool with inputSchema */
70
+
71
+ return spec;
72
+ }
73
+ export default findJob;
74
+
@@ -1,64 +1,67 @@
1
- /*
2
- * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
- import { z } from 'zod';
6
- import _listJobdefs from '../toolHelpers/_listJobdefs.js';
7
- function findJobdef(_appContext) {
8
- let llmDescription= {
9
- "purpose": "Map natural language requests to find a jobdef (job definition) in SAS Viya and return structured results.",
10
- "param_mapping": {
11
- "name": "required - single name. If missing, ask 'Which jobdef name would you like to find?'.",
12
-
13
- },
14
- "response_schema": "{ jobs: Array<string|object> }",
15
- "behavior": "Return only JSON matching response_schema when invoked by an LLM. If no matches, return { jobs: [] }"
16
- };
17
- let description = `
18
- find-jobdef — locate a specific SAS Viya job definition.
19
-
20
- USE when: find jobdef, does jobdef exist, is there a jobdef named, lookup jobdef, verify jobdef exists
21
- DO NOT USE for: list jobdefs (use list-jobdefs), run jobdef (use run-jobdef), find job/lib/table/model (use respective tools)
22
-
23
- PARAMETERS
24
- - name: string (required) jobdef name to locate; if multiple supplied, use first
25
-
26
- ROUTING RULES
27
- - "find jobdef <name>" → { name: "<name>" }
28
- - "does jobdef <name> exist" { name: "<name>" }
29
- - "is there a jobdef named <name>" → { name: "<name>" }
30
- - "lookup/verify jobdef <name>" → { name: "<name>" }
31
- - "find jobdef" with no name → ask "Which jobdef name would you like to find?"
32
- - "find all jobdefs / list jobdefs" → use list-jobdefs instead
33
- - "run jobdef <name>" → use run-jobdef instead
34
-
35
- EXAMPLES
36
- - "find jobdef cars_job_v4" → { name: "cars_job_v4" }
37
- - "does jobdef ETL exist" → { name: "ETL" }
38
- - "is there a jobdef named metricsRefresh" { name: "metricsRefresh" }
39
-
40
- NEGATIVE EXAMPLES (do not route here)
41
- - "list jobdefs" (use list-jobdefs)
42
- - "run jobdef cars_job_v4" (use run-jobdef)
43
- - "find job ETL" (use find-job)
44
- - "find table cars" (use find-table)
45
-
46
- ERRORS
47
- Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never hallucinate jobdef names.
48
- `;
49
-
50
- let spec = {
51
- name: 'find-jobdef',
52
- description: description,
53
- inputSchema: z.object({
54
- name: z.string()
55
- }),
56
- handler: async (params) => {
57
- let r = await _listJobdefs(params);
58
- return r;
59
- }
60
- }
61
- return spec;
62
- }
63
- export default findJobdef;
64
-
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { z } from 'zod';
6
+ import _findJobdef from '../toolHelpers/_findJobdef.js';
7
+ function findJobdef(_appContext) {
8
+ const isAgent = _appContext && _appContext.agent;
9
+ let description = isAgent ? `
10
+ find-jobdef — verify a JobDef model exists.
11
+ PARAMS: name (string, required)
12
+ RETURNS: jobdef metadata if found, error if not found
13
+ ` : `
14
+ find-jobdef locate a specific SAS Viya job definition.
15
+
16
+ USE when: find jobdef, does jobdef exist, is there a jobdef named, lookup jobdef, verify jobdef exists
17
+ DO NOT USE for: list jobdefs (use ${_appContext.brand}-list-jobdefs), score jobdef (use ${_appContext.brand}-jobdef-score), find job/lib/table/model (use respective tools)
18
+
19
+ PARAMETERS
20
+ - name: string (required) jobdef name to locate; if multiple supplied, use first
21
+
22
+ ROUTING RULES
23
+ - "find jobdef <name>" → { name: "<name>" }
24
+ - "find name.jobdef" { name: "<name>" }
25
+ - "does jobdef <name> exist" → { name: "<name>" }
26
+ - "is there a jobdef named <name>" → { name: "<name>" }
27
+ - "lookup/verify jobdef <name>" → { name: "<name>" }
28
+ - "find jobdef" with no name → ask "Which jobdef name would you like to find?"
29
+ - "find all jobdefs / list jobdefs" → use ${_appContext.brand}-list-jobdefs instead
30
+ - "score jobdef <name>" → use ${_appContext.brand}-jobdef-score instead
31
+
32
+ EXAMPLES
33
+ - "find jobdef cars_job_v4" → { name: "cars_job_v4" }
34
+ - "does jobdef ETL exist" → { name: "ETL" }
35
+ - "is there a jobdef named metricsRefresh" → { name: "metricsRefresh" }
36
+
37
+ NEGATIVE EXAMPLES (do not route here)
38
+ - "list jobdefs" (use ${_appContext.brand}-list-jobdefs)
39
+ - "score jobdef cars_job_v4" (use ${_appContext.brand}-jobdef-score)
40
+ - "find job ETL" (use ${_appContext.brand}-find-job)
41
+ - "find table cars" (use ${_appContext.brand}-find-table)
42
+
43
+ ERRORS
44
+ Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never hallucinate jobdef names.
45
+ `;
46
+
47
+ let spec = {
48
+ name: 'find-jobdef',
49
+ description: description,
50
+ inputSchema: z.object({
51
+ name: z.string()
52
+ }),
53
+ handler: async (params) => {
54
+ if (params.name != null) {
55
+ if (params.name.endsWith('.jobdef')) {
56
+ params.name = params.name.slice(0, -7);
57
+ }
58
+ }
59
+ params.tool = 'find';
60
+ let r = await _findJobdef(params);
61
+ return r;
62
+ }
63
+ }
64
+ return spec;
65
+ }
66
+ export default findJobdef;
67
+
@@ -1,40 +1,44 @@
1
- /*
2
- * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { z } from 'zod';
6
6
  import _listLibrary from '../toolHelpers/_listLibrary.js';
7
7
  function findLibrary(_appContext) {
8
-
9
- let description = `
10
- find-library — locate a specific CAS or SAS library.
8
+ const isAgent = _appContext && _appContext.agent;
9
+ let description = isAgent ? `
10
+ find-library — verify a library exists.
11
+ PARAMS: name (string, required), server ('cas'|'sas', required)
12
+ RETURNS: library metadata if found, error if not found
13
+ ` : `
14
+ find-library — locate a specific CAS or SAS library.
11
15
 
12
16
  USE when: find library, find lib, does library exist, is library available, lookup library
13
- DO NOT USE for: list libraries (use list-libraries), find table/job/jobdef/model (use respective tools), table structure (use table-info), create library (use run-sas-program)
17
+ DO NOT USE for: list libraries (use ${_appContext.brand}-list-libraries), find table/job/jobdef/model (use respective tools), table structure (use ${_appContext.brand}-table-describe), create library (use ${_appContext.brand}-program-score)
14
18
 
15
19
  PARAMETERS
16
- - name: string (required) library/caslib name; if multiple supplied, use first
17
- - server: 'cas' | 'sas' (default: 'cas') target environment
20
+ - name: string (required) — library/caslib name; if multiple supplied, use first
21
+ - server: 'cas' | 'sas' (required) — target environment
18
22
 
19
23
  ROUTING RULES
20
- - "find lib <name>" { name: "<name>", server: "cas" }
21
- - "find lib <name> in cas" { name: "<name>", server: "cas" }
22
- - "find library <name> in sas" { name: "<name>", server: "sas" }
23
- - "does library <name> exist" { name: "<name>", server: "cas" }
24
- - "find lib" with no name ask "Which library name would you like to find?"
25
- - "list libraries / list libs" use list-libraries instead
26
- - "tables in <lib>" use list-tables instead
24
+ - "find lib <name>" → { name: "<name>", server: "cas" }
25
+ - "find lib <name> in cas" → { name: "<name>", server: "cas" }
26
+ - "find library <name> in sas" → { name: "<name>", server: "sas" }
27
+ - "does library <name> exist" → { name: "<name>", server: "cas" }
28
+ - "find lib" with no name → ask "Which library name would you like to find?"
29
+ - "list libraries / list libs" → use ${_appContext.brand}-list-libraries instead
30
+ - "tables in <lib>" → use ${_appContext.brand}-list-tables instead
27
31
 
28
32
  EXAMPLES
29
- - "find lib Public" { name: "Public", server: "cas" }
30
- - "find library sasuser in sas" { name: "sasuser", server: "sas" }
31
- - "does library Formats exist" { name: "Formats", server: "cas" }
33
+ - "find lib Public" → { name: "Public", server: "cas" }
34
+ - "find library sasuser in sas" → { name: "sasuser", server: "sas" }
35
+ - "does library Formats exist" → { name: "Formats", server: "cas" }
32
36
 
33
37
  NEGATIVE EXAMPLES (do not route here)
34
- - "list libs" (use list-libraries)
35
- - "show tables in Public" (use list-tables)
36
- - "find table cars in sashelp" (use find-table)
37
- - "find job cars_job" (use find-job)
38
+ - "list libs" (use ${_appContext.brand}-list-libraries)
39
+ - "show tables in Public" (use ${_appContext.brand}-list-tables)
40
+ - "find table cars in sashelp" (use ${_appContext.brand}-find-table)
41
+ - "find job cars_job" (use ${_appContext.brand}-find-job)
38
42
 
39
43
  ERRORS
40
44
  Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
@@ -57,7 +61,7 @@ Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Nev
57
61
  if (params.name && /[,\s]+/.test(params.name.trim())) {
58
62
  params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
59
63
  }
60
-
64
+ params.tool = 'find';
61
65
  let r = await _listLibrary(params);
62
66
  return r;
63
67
  }
@@ -66,3 +70,4 @@ Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Nev
66
70
  }
67
71
  export default findLibrary;
68
72
 
73
+
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import _findmas from '../toolHelpers/_findmas.js';
8
+
9
+
10
+ function findMas(_appContext) {
11
+ const isAgent = _appContext && _appContext.agent;
12
+ let description = isAgent ? `
13
+ find-mas — verify a MAS model exists.
14
+ PARAMS: name (string, required)
15
+ RETURNS: model metadata if found, error if not found
16
+ ` : `
17
+ find-mas — locate a specific MAS mas deployed to MAS server
18
+
19
+ USE when: find mas, does mas exist, is mas deployed, lookup mas, verify mas exists
20
+ DO NOT USE for: list mass (use ${_appContext.brand}-list-mass), mas info/variables (use ${_appContext.brand}-mas-describe), score mas (use ${_appContext.brand}-mas-score), find table/job/lib (use respective tools), scr mass (use ${_appContext.brand}-scr-describe/${_appContext.brand}-scr-score)
21
+
22
+ PARAMETERS
23
+ - name: string (required) — mas name to locate; if multiple supplied, use first
24
+
25
+ ROUTING RULES
26
+ - "find mas <name>" → { name: "<name>" }
27
+ - "find name.mas" → { name: "<name>" }
28
+ - "does mas <name> exist" → { name: "<name>" }
29
+ - "is mas <name> deployed" → { name: "<name>" }
30
+ - "lookup/verify mas <name>" → { name: "<name>" }
31
+ - "find mas" with no name → ask "Which mas name would you like to find?"
32
+ - "find all mass / list mass" → use ${_appContext.brand}-list-mas instead
33
+ - "describe mas / mas info" → use ${_appContext.brand}-mas-describe instead
34
+
35
+ EXAMPLES
36
+ - "find mas mymas" → { name: "mymas" }
37
+ - "does mas churn_score exist" → { name: "churn_score" }
38
+ - "is mas riskmas deployed" → { name: "riskmas" }
39
+ - "lookup mas claims_fraud_v1" → { name: "claims_fraud_v1" }
40
+
41
+ NEGATIVE EXAMPLES (do not route here)
42
+ - "list mass" (use ${_appContext.brand}-list-mas)
43
+ - "score mas mymas" (use ${_appContext.brand}-mas-score)
44
+ - "mas info for churnRisk" (use ${_appContext.brand}-mas-describe)
45
+
46
+ ERRORS
47
+ Returns { mass: [] } if not found; { mass: [name, ...] } if found. Never hallucinate mas names.
48
+ `;
49
+
50
+ let spec = {
51
+ name: 'find-mas',
52
+ description: description,
53
+ inputSchema: z.object({
54
+ name: z.string()
55
+ }),
56
+ handler: async (params) => {
57
+ if (params.name != null) {
58
+ if (params.name.endsWith('.mas')) {
59
+ params.name = params.name.slice(0, -4);
60
+ }
61
+ }
62
+ params.tool = 'find';
63
+ let r = await _findmas(params);
64
+ return r;
65
+ }
66
+ }
67
+ return spec;
68
+ }
69
+
70
+ export default findMas;
71
+
72
+
@@ -0,0 +1,69 @@
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import _findScr from '../toolHelpers/_findScr.js';
8
+
9
+
10
+ function findScr(_appContext) {
11
+ const isAgent = _appContext && _appContext.agent;
12
+ let description = isAgent ? `
13
+ find-scr — verify an SCR model exists.
14
+ PARAMS: name (string, required)
15
+ RETURNS: SCR model metadata if found, error if not found
16
+ ` : `
17
+ find-scr — locate a specific SCR scr deployed to SCR server
18
+
19
+ USE when: find scr, does scr exist, is scr deployed, lookup scr, verify scr exists
20
+ DO NOT USE for: list scrs (use list-scr), scr info/variables (use scr-describe), score scr (use scr-score), find table/job/lib (use respective tools), mas scr (use mas-describe/mas-score)
21
+
22
+
23
+ PARAMETERS
24
+ - name: string (required) — scr name to locate; if multiple supplied, use first
25
+
26
+ ROUTING RULES
27
+ - "find scr <name>" → { name: "<name>" }
28
+ - "does scr <name> exist" → { name: "<name>" }
29
+ - "is scr <name> deployed" → { name: "<name>" }
30
+ - "lookup/verify scr <name>" → { name: "<name>" }
31
+ - "find scr" with no name → ask "Which scr name would you like to find?"
32
+ - "describe scr / scr info" → use scr-describe instead
33
+
34
+ EXAMPLES
35
+ - "find scr myscr" → { name: "myscr" }
36
+ - "does scr churn_score exist" → { name: "churn_score" }
37
+ - "is scr riskscr deployed" → { name: "riskscr" }
38
+ - "lookup scr claims_fraud_v1" → { name: "claims_fraud_v1" }
39
+
40
+ NEGATIVE EXAMPLES (do not route here)
41
+ - "list scr" (use ${_appContext.brand}-list-scr)
42
+ - "score scr myscr" (use ${_appContext.brand}-scr-score)
43
+ - "scr info for churnRisk" (use ${_appContext.brand}-scr-describe)
44
+
45
+ ERRORS
46
+ Returns { scr: [] } if not found; { scr: [name, ...] } if found. Never hallucinate scr urls.
47
+ `;
48
+
49
+ let spec = {
50
+ name: 'find-scr',
51
+ description: description,
52
+ inputSchema: z.object({
53
+ name: z.string()
54
+ }),
55
+ handler: async (params) => {
56
+ if (params.name.endsWith('.scr')) {
57
+ params.name = params.name.slice(0, -4);
58
+ }
59
+ params.tool = 'find';
60
+ let r = await _findScr(params);
61
+ return r;
62
+ }
63
+ }
64
+ return spec;
65
+ }
66
+
67
+ export default findScr;
68
+
69
+
@@ -1,43 +1,48 @@
1
- /*
2
- * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
6
  import { z } from 'zod';
7
7
  //import debug from 'debug';
8
- import _listTables from '../toolHelpers/_listTables.js';
8
+ import _findTable from '../toolHelpers/_findTable.js';
9
9
 
10
10
  function findTable(_appContext) {
11
- let description = `
12
- find-table locate a specific table in a CAS or SAS library.
11
+ const isAgent = _appContext && _appContext.agent;
12
+ let description = isAgent ? `
13
+ find-table — verify a table exists in a library.
14
+ PARAMS: lib (string, required), name (string, required), server ('cas'|'sas', required)
15
+ RETURNS: table metadata if found, error if not found
16
+ ` : `
17
+ find-table — locate a specific table in a CAS or SAS library.
13
18
 
14
19
  USE when: find table, does table exist, is table in library, verify table exists, locate table
15
- DO NOT USE for: list tables (use list-tables), table schema/columns (use table-info), read table data (use read-table), find lib/job/model (use respective tools)
20
+ DO NOT USE for: list tables (use ${_appContext.brand}-list-tables), table schema/columns (use ${_appContext.brand}-table-describe), read table data (use ${_appContext.brand}-read-table), find lib/job/model (use respective tools)
16
21
 
17
22
  PARAMETERS
18
- - lib: string (required) library name (e.g., 'Public', 'sashelp')
19
- - name: string (required) table name to locate
20
- - server: 'cas' | 'sas' . If not specified set it to 'cas' — target environment
23
+ - lib: string (required) — library name (e.g., 'Public', 'sashelp')
24
+ - name: string (required) — table name to locate
25
+ - server: 'cas' | 'sas' (required) — target environment
21
26
 
22
27
  ROUTING RULES
23
- - "find table <name> in <lib>" { lib: "<lib>", name: "<name>", server: "cas" }
24
- - "find table <name> in <lib> in sas" { lib: "<lib>", name: "<name>", server: "sas" }
25
- - "does table <name> exist in <lib>" { lib: "<lib>", name: "<name>", server: "cas" }
26
- - "find table" with missing lib ask "Which library contains the table?"
27
- - "find table" with missing name ask "Which table name would you like to find?"
28
- - "list tables in <lib>" use list-tables instead
28
+ - "find table <name> in <lib>" → { lib: "<lib>", name: "<name>", server: "cas" }
29
+ - "find table <name> in <lib> in sas" → { lib: "<lib>", name: "<name>", server: "sas" }
30
+ - "does table <name> exist in <lib>" → { lib: "<lib>", name: "<name>", server: "cas" }
31
+ - "find table" with missing lib → ask "Which library contains the table?"
32
+ - "find table" with missing name → ask "Which table name would you like to find?"
33
+ - "list tables in <lib>" → use ${_appContext.brand}-list-tables instead
29
34
 
30
35
  EXAMPLES
31
- - "find table iris in Public" { lib: "Public", name: "iris", server: "cas" }
32
- - "find table cars in sashelp in sas" { lib: "sashelp", name: "cars", server: "sas" }
33
- - "does customers exist in mylib" { lib: "mylib", name: "customers", server: "cas" }
34
- - "verify table orders in Samples" { lib: "Samples", name: "orders", server: "cas" }
36
+ - "find table iris in Public" → { lib: "Public", name: "iris", server: "cas" }
37
+ - "find table cars in sashelp in sas" → { lib: "sashelp", name: "cars", server: "sas" }
38
+ - "does customers exist in mylib" → { lib: "mylib", name: "customers", server: "cas" }
39
+ - "verify table orders in Samples" → { lib: "Samples", name: "orders", server: "cas" }
35
40
 
36
41
  NEGATIVE EXAMPLES (do not route here)
37
- - "list tables in Public" (use list-tables)
38
- - "find library Public" (use find-library)
39
- - "what columns in cars?" (use table-info)
40
- - "read data from customers" (use read-table)
42
+ - "list tables in Public" (use ${_appContext.brand}-list-tables)
43
+ - "find library Public" (use ${_appContext.brand}-find-library)
44
+ - "what columns in cars?" (use ${_appContext.brand}-table-describe)
45
+ - "read data from customers" (use ${_appContext.brand}-read-table)
41
46
 
42
47
  ERRORS
43
48
  Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hallucinate table names.
@@ -47,14 +52,15 @@ Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hal
47
52
  name: 'find-table',
48
53
  description: description,
49
54
  inputSchema: z.object({
50
- lib: z.string(),
51
- name: z.string(),
52
- server: z.string()
55
+ lib: z.string().min(1),
56
+ name: z.string().min(1),
57
+ server: z.enum(['cas', 'sas'])
53
58
  }),
54
59
 
55
60
  handler: async (params) => {
56
61
  // Check if the params.scenario is a string and parse it
57
- let r = await _listTables(params);
62
+ params.tool = 'find';
63
+ let r = await _findTable(params);
58
64
  return r;
59
65
  }
60
66
  }
@@ -63,3 +69,4 @@ Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hal
63
69
 
64
70
  export default findTable;
65
71
 
72
+