@sassoftware/sas-score-mcp-serverjs 0.4.0 → 0.4.1-15

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 (53) hide show
  1. package/cli.js +112 -33
  2. package/package.json +5 -5
  3. package/skills/sas-list-tables-smart/SKILL.md +123 -0
  4. package/skills/sas-read-and-score/SKILL.md +54 -53
  5. package/skills/sas-read-strategy/SKILL.md +10 -10
  6. package/skills/sas-score-workflow/SKILL.md +19 -1
  7. package/skills/sas-spec-migration/SKILL.md +303 -0
  8. package/src/authpkce.js +219 -0
  9. package/src/createMcpServer.js +16 -6
  10. package/src/expressMcpServer.js +354 -338
  11. package/src/handleGetDelete.js +1 -1
  12. package/src/oauthHandlers/authorize.js +46 -0
  13. package/src/oauthHandlers/baseUrl.js +8 -0
  14. package/src/oauthHandlers/callback.js +93 -0
  15. package/src/oauthHandlers/getMetadata.js +27 -0
  16. package/src/oauthHandlers/index.js +7 -0
  17. package/src/oauthHandlers/token.js +37 -0
  18. package/src/processHeaders.js +88 -0
  19. package/src/toolHelpers/_listLibrary.js +0 -1
  20. package/src/toolHelpers/getLogonPayload.js +5 -1
  21. package/src/toolHelpers/readCerts.js +4 -4
  22. package/src/toolHelpers/refreshTokenOauth.js +3 -3
  23. package/src/toolSet/.claude/settings.local.json +13 -0
  24. package/src/toolSet/devaScore.js +61 -61
  25. package/src/toolSet/findJob.js +9 -16
  26. package/src/toolSet/findJobdef.js +4 -5
  27. package/src/toolSet/findLibrary.js +68 -68
  28. package/src/toolSet/findModel.js +4 -5
  29. package/src/toolSet/findTable.js +6 -6
  30. package/src/toolSet/getEnv.js +10 -7
  31. package/src/toolSet/listJobdefs.js +61 -62
  32. package/src/toolSet/listJobs.js +61 -62
  33. package/src/toolSet/listLibraries.js +78 -80
  34. package/src/toolSet/listModels.js +56 -56
  35. package/src/toolSet/listTables.js +66 -66
  36. package/src/toolSet/makeTools.js +1 -3
  37. package/src/toolSet/modelInfo.js +4 -5
  38. package/src/toolSet/modelScore.js +7 -7
  39. package/src/toolSet/readTable.js +63 -67
  40. package/src/toolSet/runCasProgram.js +9 -9
  41. package/src/toolSet/runJob.js +81 -82
  42. package/src/toolSet/runJobdef.js +82 -83
  43. package/src/toolSet/runMacro.js +82 -82
  44. package/src/toolSet/runProgram.js +8 -13
  45. package/src/toolSet/sasQuery.js +77 -79
  46. package/src/toolSet/sasQueryTemplate.js +4 -5
  47. package/src/toolSet/sasQueryTemplate2.js +4 -5
  48. package/src/toolSet/scrInfo.js +3 -5
  49. package/src/toolSet/scrScore.js +69 -70
  50. package/src/toolSet/searchAssets.js +5 -6
  51. package/src/toolSet/setContext.js +65 -66
  52. package/src/toolSet/superstat.js +61 -60
  53. package/src/toolSet/tableInfo.js +58 -59
@@ -1,83 +1,82 @@
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 _jobSubmit from '../toolHelpers/_jobSubmit.js';
8
-
9
- function runJobdef(_appContext) {
10
- // JSON object for LLM/tooling
11
-
12
- let description = `
13
- run-jobdef — execute a SAS Viya job definition.
14
-
15
- USE when: run jobdef, execute jobdef, run with parameters
16
- DO NOT USE for: arbitrary SAS code (use run-sas-program), macros (use run-macro), list/find jobdefs
17
-
18
- PARAMETERS
19
- - name: string — jobdef name (required)
20
- - scenario: string | object — input parameters. Accepts: "x=1, y=2" or {x:1, y:2}
21
-
22
- ROUTING RULES
23
- - "run jobdef xyz" → { name: "xyz" }
24
- - "run jobdef xyz with param1=10, param2=val2" → { name: "xyz", scenario: {param1:10, param2:"val2"} }
25
-
26
- EXAMPLES
27
- - "run jobdef xyz" → { name: "xyz" }
28
- - "run jobdef monthly_report with month=10, year=2025" → { name: "monthly_report", scenario: {month:10, year:2025} }
29
-
30
- NEGATIVE EXAMPLES (do not route here)
31
- - "run SAS code" (use run-sas-program)
32
- - "run macro X" (use run-macro)
33
- - "list jobdefs" (use list-jobdefs)
34
- - "find jobdef X" (use find-jobdef)
35
-
36
- ERRORS
37
- Returns log output, listings, tables from jobdef. Error if jobdef not found.
38
- `;
39
-
40
- let spec = {
41
- name: 'run-jobdef',
42
- aliases: ['jobDef','jobdef','jobdef'],
43
- description: description,
44
- schema: {
45
- name: z.string(),
46
- scenario: z.any().default(''),
47
- },
48
- required: ['name'],
49
- handler: async (params) => {
50
- let scenario = params.scenario;
51
- let scenarioObj = {};
52
- let count = 0;
53
- //
54
- if (scenario == null) {
55
- scenarioObj = {};
56
- } else if (typeof scenario === 'object') {
57
- scenarioObj = scenario;
58
- } else if (Array.isArray(scenario)) {
59
- scenarioObj = scenario[0];
60
- } else if (typeof scenario === 'string') {
61
- if (scenario.trim() === '') {
62
- scenarioObj = {};
63
- } else {
64
- // console.error('Incoming scenario', scenario);
65
- scenarioObj = scenario.split(',').reduce((acc, pair) => {
66
- let [key, value] = pair.split('=');
67
- acc[key.trim()] = value;
68
- count++;
69
- return acc;
70
- }, {});
71
- }
72
- }
73
- params.type = 'def';
74
- params.scenario = scenarioObj;
75
- // Provide runtime context for auth and server settings
76
- let r = await _jobSubmit(params);
77
- return r;
78
- }
79
- };
80
- return spec;
81
- }
82
-
83
- export default runJobdef;
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 _jobSubmit from '../toolHelpers/_jobSubmit.js';
8
+
9
+ function runJobdef(_appContext) {
10
+ // JSON object for LLM/tooling
11
+
12
+ let description = `
13
+ run-jobdef — execute a SAS Viya job definition.
14
+
15
+ USE when: run jobdef, execute jobdef, run with parameters
16
+ DO NOT USE for: arbitrary SAS code (use run-sas-program), macros (use run-macro), list/find jobdefs
17
+
18
+ PARAMETERS
19
+ - name: string — jobdef name (required)
20
+ - scenario: string | object — input parameters. Accepts: "x=1, y=2" or {x:1, y:2}
21
+
22
+ ROUTING RULES
23
+ - "run jobdef xyz" → { name: "xyz" }
24
+ - "run jobdef xyz with param1=10, param2=val2" → { name: "xyz", scenario: {param1:10, param2:"val2"} }
25
+
26
+ EXAMPLES
27
+ - "run jobdef xyz" → { name: "xyz" }
28
+ - "run jobdef monthly_report with month=10, year=2025" → { name: "monthly_report", scenario: {month:10, year:2025} }
29
+
30
+ NEGATIVE EXAMPLES (do not route here)
31
+ - "run SAS code" (use run-sas-program)
32
+ - "run macro X" (use run-macro)
33
+ - "list jobdefs" (use list-jobdefs)
34
+ - "find jobdef X" (use find-jobdef)
35
+
36
+ ERRORS
37
+ Returns log output, listings, tables from jobdef. Error if jobdef not found.
38
+ `;
39
+
40
+ let spec = {
41
+ name: 'run-jobdef',
42
+ description: description,
43
+ inputSchema: z.object({
44
+ name: z.string(),
45
+ scenario: z.string().optional()
46
+ }),
47
+ handler: async (params) => {
48
+ let scenario = params.scenario;
49
+ let scenarioObj = {};
50
+ let count = 0;
51
+ //
52
+ if (scenario == null) {
53
+ scenarioObj = {};
54
+ } else if (typeof scenario === 'object') {
55
+ scenarioObj = scenario;
56
+ } else if (Array.isArray(scenario)) {
57
+ scenarioObj = scenario[0];
58
+ } else if (typeof scenario === 'string') {
59
+ if (scenario.trim() === '') {
60
+ scenarioObj = {};
61
+ } else {
62
+ // console.error('Incoming scenario', scenario);
63
+ scenarioObj = scenario.split(',').reduce((acc, pair) => {
64
+ let [key, value] = pair.split('=');
65
+ acc[key.trim()] = value;
66
+ count++;
67
+ return acc;
68
+ }, {});
69
+ }
70
+ }
71
+ params.type = 'def';
72
+ params.scenario = scenarioObj;
73
+ // Provide runtime context for auth and server settings
74
+ let r = await _jobSubmit(params);
75
+ return r;
76
+ }
77
+ };
78
+ return spec;
79
+ }
80
+
81
+ export default runJobdef;
82
+
@@ -1,82 +1,82 @@
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 _submitCode from '../toolHelpers/_submitCode.js';
8
-
9
-
10
- function runMacro(_appContext) {
11
- let description = `
12
- run-macro — submit and execute a SAS macro on SAS Viya server.
13
-
14
- USE when: run macro, execute macro with parameters
15
- DO NOT USE for: arbitrary SAS code (use run-sas-program), jobs, jobdefs
16
-
17
- PARAMETERS
18
- - macro: string — macro name without "%" (required)
19
- - scenario: string — parameters or setup code (optional). Accepts: "x=1, y=abc" or "%let x=1; %let y=abc;"
20
-
21
- ROUTING RULES
22
- - "run macro abc" → { macro: "abc", scenario: "" }
23
- - "run macro abc with x=1, y=2" → { macro: "abc", scenario: "x=1, y=2" }
24
- - "run macro xyz with %let a=1; %let b=2;" → { macro: "xyz", scenario: "%let a=1; %let b=2;" }
25
-
26
- EXAMPLES
27
- - "run macro abc" → { macro: "abc", scenario: "" }
28
- - "run macro summarize with x=1, y=2" → { macro: "summarize", scenario: "x=1, y=2" }
29
-
30
- NEGATIVE EXAMPLES (do not route here)
31
- - "run SAS code" (use run-sas-program)
32
- - "run job X" (use run-job)
33
- - "run jobdef X" (use run-jobdef)
34
-
35
- ERRORS
36
- Returns log, ods, tables created by macro. Auto-converts "x=1, y=2" to "%let x=1; %let y=2;" format.
37
- `;
38
-
39
- let spec = {
40
- name: 'run-macro',
41
- aliases: ['runMacro','run macro','run_macro'],
42
- description: description,
43
-
44
- schema: {
45
- macro: z.string(),
46
- scenario: z.string()
47
- },
48
- required: ['macro'],
49
- handler: async (params) => {
50
- const scenarioRaw = (params.scenario || '').trim();
51
- let setup = '';
52
- if (scenarioRaw) {
53
- // If the scenario already contains macro syntax, send it through unchanged
54
- const hasMacroSyntax = /%let\b|%[a-zA-Z_]\w*\s*\(|%[a-zA-Z_]\w*\s*;/.test(scenarioRaw) || scenarioRaw.includes('%');
55
- if (hasMacroSyntax) {
56
- setup = scenarioRaw;
57
- } else {
58
- // Convert "x=1,y=abc" -> "%let x=1; %let y=abc;"
59
- setup = scenarioRaw.split(',')
60
- .map(p => p.trim())
61
- .filter(Boolean)
62
- .map(p => {
63
- const [k, ...rest] = p.split('=');
64
- if (!k) return '';
65
- const key = k.trim();
66
- const val = rest.join('=').trim();
67
- return `%let ${key}=${val};`;
68
- })
69
- .filter(Boolean)
70
- .join(' ');
71
- }
72
- }
73
- const src = `${setup} %${params.macro};`;
74
- params.src = src;
75
- let r = await _submitCode(params);
76
- return r;
77
- }
78
- }
79
- return spec;
80
- }
81
-
82
- export default runMacro;
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 _submitCode from '../toolHelpers/_submitCode.js';
8
+
9
+
10
+ function runMacro(_appContext) {
11
+ let description = `
12
+ run-macro — submit and execute a SAS macro on SAS Viya server.
13
+
14
+ USE when: run macro, execute macro with parameters
15
+ DO NOT USE for: arbitrary SAS code (use run-sas-program), jobs, jobdefs
16
+
17
+ PARAMETERS
18
+ - macro: string — macro name without "%" (required)
19
+ - scenario: string — parameters or setup code (optional). Accepts: "x=1, y=abc" or "%let x=1; %let y=abc;"
20
+
21
+ ROUTING RULES
22
+ - "run macro abc" → { macro: "abc", scenario: "" }
23
+ - "run macro abc with x=1, y=2" → { macro: "abc", scenario: "x=1, y=2" }
24
+ - "run macro xyz with %let a=1; %let b=2;" → { macro: "xyz", scenario: "%let a=1; %let b=2;" }
25
+
26
+ EXAMPLES
27
+ - "run macro abc" → { macro: "abc", scenario: "" }
28
+ - "run macro summarize with x=1, y=2" → { macro: "summarize", scenario: "x=1, y=2" }
29
+
30
+ NEGATIVE EXAMPLES (do not route here)
31
+ - "run SAS code" (use run-sas-program)
32
+ - "run job X" (use run-job)
33
+ - "run jobdef X" (use run-jobdef)
34
+
35
+ ERRORS
36
+ Returns log, ods, tables created by macro. Auto-converts "x=1, y=2" to "%let x=1; %let y=2;" format.
37
+ `;
38
+
39
+ let spec = {
40
+ name: 'run-macro',
41
+ description: description,
42
+
43
+ inputSchema: z.object({
44
+ macro: z.string(),
45
+ scenario: z.string().optional()
46
+ }),
47
+
48
+ handler: async (params) => {
49
+ const scenarioRaw = (params.scenario || '').trim();
50
+ let setup = '';
51
+ if (scenarioRaw) {
52
+ // If the scenario already contains macro syntax, send it through unchanged
53
+ const hasMacroSyntax = /%let\b|%[a-zA-Z_]\w*\s*\(|%[a-zA-Z_]\w*\s*;/.test(scenarioRaw) || scenarioRaw.includes('%');
54
+ if (hasMacroSyntax) {
55
+ setup = scenarioRaw;
56
+ } else {
57
+ // Convert "x=1,y=abc" -> "%let x=1; %let y=abc;"
58
+ setup = scenarioRaw.split(',')
59
+ .map(p => p.trim())
60
+ .filter(Boolean)
61
+ .map(p => {
62
+ const [k, ...rest] = p.split('=');
63
+ if (!k) return '';
64
+ const key = k.trim();
65
+ const val = rest.join('=').trim();
66
+ return `%let ${key}=${val};`;
67
+ })
68
+ .filter(Boolean)
69
+ .join(' ');
70
+ }
71
+ }
72
+ const src = `${setup} %${params.macro};`;
73
+ params.src = src;
74
+ let r = await _submitCode(params);
75
+ return r;
76
+ }
77
+ }
78
+ return spec;
79
+ }
80
+
81
+ export default runMacro;
82
+
@@ -41,21 +41,15 @@ Returns log, ods, tables array, data (if output specified). Error if execution f
41
41
  `;
42
42
 
43
43
  let spec = {
44
- name: 'run-sas-program',
45
- aliases: ['Program','run program'],
44
+ name: 'run-program',
46
45
  description: description,
47
- schema: {
46
+ inputSchema: z.object({
48
47
  src: z.string(),
49
- scenario: z.any().default(''),
50
- output: z.string().default(''),
51
- folder: z.string().default(''),
52
- limit: z.number().default(100)
53
- },
54
- // NOTE: Previously 'required' incorrectly listed 'program' which does not
55
- // exist in the schema. This prevented execution in some orchestrators that
56
- // enforce required parameter presence, causing only descriptions to appear.
57
- // Corrected to 'src'.
58
- required: ['src'],
48
+ scenario: z.string().optional(),
49
+ output: z.string().optional(),
50
+ folder: z.string().optional(),
51
+ limit: z.number().optional()
52
+ }),
59
53
  handler: async (params) => {
60
54
  let {src, folder, scenario, _appContext} = params;
61
55
  // figure out src
@@ -96,3 +90,4 @@ Returns log, ods, tables array, data (if output specified). Error if execution f
96
90
  }
97
91
 
98
92
  export default runProgram;
93
+
@@ -1,79 +1,77 @@
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 _jobSubmit from '../toolHelpers/_jobSubmit.js';
7
-
8
- function sasQuery() {
9
-
10
- let description = `
11
- sas-query — convert natural language questions into SQL queries and execute them.
12
-
13
- USE when: how many/count/total/average by, aggregated analytics, complex filtering, statistical summaries
14
- DO NOT USE for: raw reads without filtering (use read-table), table structure (use table-info), SAS programs (use run-sas-program), jobs/jobdefs
15
-
16
- PARAMETERS
17
- - table: string — table in lib.table format (required), e.g. "Public.cars" or "sashelp.class"
18
- - query: string — natural language question (required)
19
- - sql: string — pre-generated SQL SELECT (optional, LLM generates)
20
- - job: string (default: 'program') — job name to execute
21
-
22
- ROUTING RULES
23
- - "how many cars by make in sashelp.cars" → { table: "sashelp.cars", query: "how many cars by make", sql: "SELECT make, COUNT(*) FROM sashelp.cars GROUP BY make" }
24
- - "average salary by department in Public.employees" → { table: "Public.employees", query: "average salary by department", sql: "SELECT department, AVG(salary) FROM Public.employees GROUP BY department" }
25
-
26
- EXAMPLES
27
- - "how many cars by make in sashelp.cars" → { table: "sashelp.cars", query: "how many cars by make", sql: "SELECT make, COUNT(*) FROM sashelp.cars GROUP BY make" }
28
- - "total sales by region from mylib.sales" → { table: "mylib.sales", query: "total sales by region", sql: "SELECT region, SUM(amount) FROM mylib.sales GROUP BY region" }
29
-
30
- NEGATIVE EXAMPLES (do not route here)
31
- - "read table cars" (use read-table)
32
- - "show 10 rows" (use read-table)
33
- - "table structure" (use table-info)
34
- - "run SAS code" (use run-sas-program)
35
- - "run job/macro" (use run-job/run-macro)
36
-
37
- ERRORS
38
- Returns rows array, columns metadata, log. Returns error if SQL invalid or table not found.
39
- `;
40
-
41
-
42
- let spec = {
43
- name: 'sas-query',
44
- aliases: ['sasQuery','sas query','sas_query'],
45
- description: description,
46
- schema: {
47
- query: z.string(),
48
- table: z.string(),
49
- sql: z.string().optional(),
50
- job: z.string().default('program')
51
- },
52
- required: ['query', 'table'],
53
- handler: async (params) => {
54
- let {table,query, sql, job, _appContext} = params;
55
- let sqlinput = (sql == null) ? ' ' : sql.replaceAll(';', ' ').replaceAll('\n', ' ').replaceAll('\r', ' ');
56
-
57
- let iparams = {
58
- scenario: {
59
- table: table,
60
- prompt: query,
61
- sql: sqlinput
62
- },
63
- name: (job == null) ? 'program' : job,
64
- type: 'job',
65
- query: true,
66
- _appContext: _appContext
67
- };
68
- if (sql == null || sql.trim().length === 0) {
69
- return { content: [{ type: 'text', text: 'Error: The SQL statement generated is blank. Please provide a valid natural language query that can be converted to SQL.' }] };
70
- }
71
-
72
- let r = await _jobSubmit(iparams);
73
- return r;
74
-
75
- }
76
- }
77
- return spec;
78
- }
79
- export default sasQuery;
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 _jobSubmit from '../toolHelpers/_jobSubmit.js';
7
+
8
+ function sasQuery() {
9
+
10
+ let description = `
11
+ sas-query — convert natural language questions into SQL queries and execute them.
12
+
13
+ USE when: how many/count/total/average by, aggregated analytics, complex filtering, statistical summaries
14
+ DO NOT USE for: raw reads without filtering (use read-table), table structure (use table-info), SAS programs (use run-sas-program), jobs/jobdefs
15
+
16
+ PARAMETERS
17
+ - table: string — table in lib.table format (required), e.g. "Public.cars" or "sashelp.class"
18
+ - query: string — natural language question (required)
19
+ - sql: string — pre-generated SQL SELECT (optional, LLM generates)
20
+ - job: string (default: 'program') — job name to execute
21
+
22
+ ROUTING RULES
23
+ - "how many cars by make in sashelp.cars" → { table: "sashelp.cars", query: "how many cars by make", sql: "SELECT make, COUNT(*) FROM sashelp.cars GROUP BY make" }
24
+ - "average salary by department in Public.employees" → { table: "Public.employees", query: "average salary by department", sql: "SELECT department, AVG(salary) FROM Public.employees GROUP BY department" }
25
+
26
+ EXAMPLES
27
+ - "how many cars by make in sashelp.cars" → { table: "sashelp.cars", query: "how many cars by make", sql: "SELECT make, COUNT(*) FROM sashelp.cars GROUP BY make" }
28
+ - "total sales by region from mylib.sales" → { table: "mylib.sales", query: "total sales by region", sql: "SELECT region, SUM(amount) FROM mylib.sales GROUP BY region" }
29
+
30
+ NEGATIVE EXAMPLES (do not route here)
31
+ - "read table cars" (use read-table)
32
+ - "show 10 rows" (use read-table)
33
+ - "table structure" (use table-info)
34
+ - "run SAS code" (use run-sas-program)
35
+ - "run job/macro" (use run-job/run-macro)
36
+
37
+ ERRORS
38
+ Returns rows array, columns metadata, log. Returns error if SQL invalid or table not found.
39
+ `;
40
+
41
+
42
+ let spec = {
43
+ name: 'sas-query',
44
+ description: description,
45
+ inputSchema: z.object({
46
+ query: z.string(),
47
+ table: z.string(),
48
+ sql: z.string().optional()
49
+ }),
50
+ handler: async (params) => {
51
+ let {table,query, sql, job, _appContext} = params;
52
+ let sqlinput = (sql == null) ? ' ' : sql.replaceAll(';', ' ').replaceAll('\n', ' ').replaceAll('\r', ' ');
53
+
54
+ let iparams = {
55
+ scenario: {
56
+ table: table,
57
+ prompt: query,
58
+ sql: sqlinput
59
+ },
60
+ name: (job == null) ? 'program' : job,
61
+ type: 'job',
62
+ query: true,
63
+ _appContext: _appContext
64
+ };
65
+ if (sql == null || sql.trim().length === 0) {
66
+ return { content: [{ type: 'text', text: 'Error: The SQL statement generated is blank. Please provide a valid natural language query that can be converted to SQL.' }] };
67
+ }
68
+
69
+ let r = await _jobSubmit(iparams);
70
+ return r;
71
+
72
+ }
73
+ }
74
+ return spec;
75
+ }
76
+ export default sasQuery;
77
+
@@ -108,13 +108,12 @@ async function sasQueryTemplate(uparams) {
108
108
  name: toolname,
109
109
  description: description,
110
110
 
111
- schema: {
111
+ inputSchema: z.object({
112
112
  query: z.string(),
113
113
  table: z.string().default(uTable),
114
- sql: z.string().optional()
115
- },
116
- required: ['query', 'table'],
117
- handler: async (params) => {
114
+ sql: z.string()
115
+ }),
116
+ handler: async (params) => {
118
117
 
119
118
 
120
119
  let { table, query, sql, _appContext} = params;
@@ -102,14 +102,13 @@ async function sasQueryTemplate2(uparams) {
102
102
  name: toolname,
103
103
  description: description,
104
104
 
105
- schema: {
105
+ inputSchema: z.object({
106
106
  query: z.string(),
107
107
  table: z.string().default(uTable),
108
- sql: z.string().optional(),
108
+ sql: z.string(),
109
109
 
110
- },
111
- required: ['query', 'table'],
112
- handler: async (params) => {
110
+ }),
111
+ handler: async (params) => {
113
112
 
114
113
  let { table, query, sql } = params;
115
114
  let sqlinput = (sql == null) ? ' ' : sql.replaceAll(';', ' ').replaceAll('\n', ' ').replaceAll('\r', ' ');
@@ -33,12 +33,10 @@ Examples
33
33
 
34
34
  let spec = {
35
35
  name: 'scr-info',
36
- aliases: ['scrInfo','scr info','scr_info'],
37
36
  description: description,
38
- schema: {
39
- url: z.string(),
40
- },
41
- required: ['url'],
37
+ inputSchema: z.object({
38
+ url: z.string()
39
+ }),
42
40
  handler: async (params) => {
43
41
  let {url, _appContext} = params;
44
42
  if (url === null) {