@sassoftware/sas-score-mcp-serverjs 0.4.1-1 → 0.4.1-5

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);
@@ -390,7 +390,7 @@ function iconfig(envFile) {
390
390
  });
391
391
  return envData;
392
392
  } catch (err) {
393
- console.log(err);
393
+ console.error(err);
394
394
  process.exit(0);
395
395
  }
396
396
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassoftware/sas-score-mcp-serverjs",
3
- "version": "0.4.1-1",
3
+ "version": "0.4.1-5",
4
4
  "description": "A mcp server for SAS Viya",
5
5
  "author": "Deva Kumar <deva.kumar@sas.com>",
6
6
  "license": "Apache-2.0",
@@ -73,18 +73,16 @@ async function createMcpServer(cache, _appContext) {
73
73
  let toolNames = [];
74
74
  toolSet.forEach((tool, i) => {
75
75
  let toolName = _appContext.brand + '-' + tool.name;
76
- tool.inputSchema.additionalProperties = false; // disallow extra properties
76
+ //tool.inputSchema.additionalProperties = false; // disallow extra properties
77
77
  let config = {
78
- title: toolName,
79
78
  description: tool.description,
80
79
  inputSchema: tool.inputSchema
81
80
  }
82
- console.error(`[Note] Configuring tool ${toolName} with input schema: ${JSON.stringify(tool.inputSchema)}`);
81
+
83
82
  console.error(`\n[Note] Registering tool ${i + 1} : ${toolName}`);
84
83
  let toolHandler = wrapf(cache, tool.handler);
85
-
84
+ console.error(`[Note] Registering tool ${toolName} with config: ${JSON.stringify(config)}`);
86
85
  let r = mcpServer.registerTool(toolName, config, toolHandler);
87
- console.error(`[Note] Tool ${toolName} registered with result: ${JSON.stringify(r)}`);
88
86
  toolNames.push(toolName);
89
87
  });
90
88
  console.error(`[Note] Registered ${toolSet.length} tools: ${toolNames}`);
@@ -1,61 +1,61 @@
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
-
7
- function devaScore(_appContext) {
8
-
9
- let description = `
10
- deva-score — compute a numeric score based on two input values.
11
-
12
- USE when: calculate deva score, score these values, compute score for numbers
13
- DO NOT USE for: model scoring (use model-score), statistical calculations, data lookup
14
-
15
- PARAMETERS
16
- - a: number (required) — first input value
17
- - b: number (required) — second input value
18
-
19
- FORMULA: (a + b) * 42
20
-
21
- ROUTING RULES
22
- - "calculate deva score for 5 and 10" → { a: 5, b: 10 }
23
- - "score 1 and 2" → { a: 1, b: 2 }
24
- - "deva score a=3, b=7" → { a: 3, b: 7 }
25
- - Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
26
-
27
- EXAMPLES
28
- - "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
29
- - "Score 1 and 2" → { a: 1, b: 2 } returns 126
30
- - "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
31
-
32
- NEGATIVE EXAMPLES (do not route here)
33
- - "Score this customer with credit model" (use model-score)
34
- - "Calculate the mean of these values" (use run-sas-program or sas-query)
35
- - "Statistical analysis of numbers" (use sas-query)
36
-
37
- RESPONSE
38
- Returns { score: (a + b) * 42 }
39
- `;
40
- let spec = {
41
- name: 'deva-score',
42
- description: description,
43
- inputSchema: z.object({
44
- a: z.number(),
45
- b: z.number()
46
- }),
47
- handler: async ({ a, b }) => {
48
- console.error(a, b);
49
- let r = { score: (a + b) * 42 };
50
- console.error('deva score result', r);
51
- return {
52
- content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
53
- structuredContent: r
54
- };
55
- }
56
- }
57
-
58
- return spec;
59
- }
60
- export default devaScore;
61
-
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
+
7
+ function devaScore(_appContext) {
8
+
9
+ let description = `
10
+ deva-score — compute a numeric score based on two input values.
11
+
12
+ USE when: calculate deva score, score these values, compute score for numbers
13
+ DO NOT USE for: model scoring (use model-score), statistical calculations, data lookup
14
+
15
+ PARAMETERS
16
+ - a: number (required) — first input value
17
+ - b: number (required) — second input value
18
+
19
+ FORMULA: (a + b) * 42
20
+
21
+ ROUTING RULES
22
+ - "calculate deva score for 5 and 10" → { a: 5, b: 10 }
23
+ - "score 1 and 2" → { a: 1, b: 2 }
24
+ - "deva score a=3, b=7" → { a: 3, b: 7 }
25
+ - Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
26
+
27
+ EXAMPLES
28
+ - "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
29
+ - "Score 1 and 2" → { a: 1, b: 2 } returns 126
30
+ - "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
31
+
32
+ NEGATIVE EXAMPLES (do not route here)
33
+ - "Score this customer with credit model" (use model-score)
34
+ - "Calculate the mean of these values" (use run-sas-program or sas-query)
35
+ - "Statistical analysis of numbers" (use sas-query)
36
+
37
+ RESPONSE
38
+ Returns { score: (a + b) * 42 }
39
+ `;
40
+ let spec = {
41
+ name: 'deva-score',
42
+ description: description,
43
+ inputSchema: z.object({
44
+ a: z.number(),
45
+ b: z.number(),
46
+ }),
47
+ handler: async ({ a, b }) => {
48
+ console.error(a, b);
49
+ let r = { score: (a + b) * 42 };
50
+ console.error('deva score result', r);
51
+ return {
52
+ content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
53
+ structuredContent: r
54
+ };
55
+ }
56
+ }
57
+
58
+ return spec;
59
+ }
60
+ export default devaScore;
61
+
@@ -42,7 +42,7 @@ Returns { jobs: [] } if not found; { jobs: [name, ...] } if found. Never halluci
42
42
  name: 'find-job',
43
43
  description: description,
44
44
  inputSchema: z.object({
45
- name: z.string(),
45
+ name: z.string()
46
46
  }),
47
47
  handler: async (params) => {
48
48
  let r = await _listJobs(params);
@@ -51,7 +51,7 @@ Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never h
51
51
  name: 'find-jobdef',
52
52
  description: description,
53
53
  inputSchema: z.object({
54
- name: z.string()
54
+ name: z.string()
55
55
  }),
56
56
  handler: async (params) => {
57
57
  let r = await _listJobdefs(params);
@@ -61,4 +61,4 @@ Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never h
61
61
  return spec;
62
62
  }
63
63
  export default findJobdef;
64
-
64
+
@@ -1,67 +1,68 @@
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 _listLibrary from '../toolHelpers/_listLibrary.js';
7
- function findLibrary(_appContext) {
8
-
9
- let description = `
10
- find-library — locate a specific CAS or SAS library.
11
-
12
- 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)
14
-
15
- PARAMETERS
16
- - name: string (required) — library/caslib name; if multiple supplied, use first
17
- - server: 'cas' | 'sas' (default: 'cas') — target environment
18
-
19
- 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
27
-
28
- 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" }
32
-
33
- 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
-
39
- ERRORS
40
- Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
41
- `;
42
-
43
- let spec = {
44
- name: 'find-library',
45
- description: description,
46
- inputSchema: z.object({
47
- name: z.string(),
48
- server: z.string()
49
- }),
50
- handler: async (params) => {
51
- // normalize server to lowercase & default
52
- if (!params.server) params.server = 'cas';
53
- params.server = params.server.toLowerCase();
54
-
55
- // If multiple names passed (comma or space separated), take the first token (defensive)
56
- if (params.name && /[,\s]+/.test(params.name.trim())) {
57
- params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
58
- }
59
-
60
- let r = await _listLibrary(params);
61
- return r;
62
- }
63
- }
64
- return spec;
65
- }
66
- export default findLibrary;
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 _listLibrary from '../toolHelpers/_listLibrary.js';
7
+ function findLibrary(_appContext) {
8
+
9
+ let description = `
10
+ find-library — locate a specific CAS or SAS library.
11
+
12
+ 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)
14
+
15
+ PARAMETERS
16
+ - name: string (required) — library/caslib name; if multiple supplied, use first
17
+ - server: 'cas' | 'sas' (default: 'cas') — target environment
18
+
19
+ 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
27
+
28
+ 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" }
32
+
33
+ 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
+
39
+ ERRORS
40
+ Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
41
+ `;
42
+
43
+ let spec = {
44
+ name: 'find-library',
45
+ description: description,
46
+ inputSchema: z.object({
47
+ name: z.string(),
48
+ server: z.string().optional()
49
+ }),
50
+
51
+ handler: async (params) => {
52
+ // normalize server to lowercase & default
53
+ if (!params.server) params.server = 'cas';
54
+ params.server = params.server.toLowerCase();
55
+
56
+ // If multiple names passed (comma or space separated), take the first token (defensive)
57
+ if (params.name && /[,\s]+/.test(params.name.trim())) {
58
+ params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
59
+ }
60
+
61
+ let r = await _listLibrary(params);
62
+ return r;
63
+ }
64
+ }
65
+ return spec;
66
+ }
67
+ export default findLibrary;
68
+
@@ -46,7 +46,7 @@ Returns { models: [] } if not found; { models: [name, ...] } if found. Never hal
46
46
  name: 'find-model',
47
47
  description: description,
48
48
  inputSchema: z.object({
49
- 'name': z.string()
49
+ name: z.string()
50
50
  }),
51
51
  handler: async (params) => {
52
52
  let r = await _listModels(params);
@@ -57,4 +57,4 @@ Returns { models: [] } if not found; { models: [name, ...] } if found. Never hal
57
57
  }
58
58
 
59
59
  export default findModel;
60
-
60
+
@@ -47,10 +47,11 @@ Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hal
47
47
  name: 'find-table',
48
48
  description: description,
49
49
  inputSchema: z.object({
50
- server: z.string(), // default server is 'cas',
51
50
  name: z.string(),
52
- lib: z.string()
51
+ lib: z.string(),
52
+ server: z.string().optional() // default server is 'cas'
53
53
  }),
54
+
54
55
  handler: async (params) => {
55
56
  // Check if the params.scenario is a string and parse it
56
57
  let r = await _listTables(params);
@@ -40,9 +40,13 @@ Returns variable name with current value, or null if not found. Return structure
40
40
  let spec = {
41
41
  name: 'get-env',
42
42
  description: description,
43
- inputSchema: z.object({
44
- name: z.string()
45
- }),
43
+ inputSchema: {
44
+ type: 'object',
45
+ properties: {
46
+ name: { type: 'string' }
47
+ },
48
+ required: ['name']
49
+ },
46
50
  handler: async (params) => {
47
51
  return await _getEnv(params);
48
52
  }
@@ -50,4 +54,4 @@ Returns variable name with current value, or null if not found. Return structure
50
54
  return spec;
51
55
  }
52
56
  export default getEnv;
53
-
57
+
@@ -1,61 +1,61 @@
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 listJobdefs(_appContext) {
8
-
9
- let description = `
10
- list-jobdefs — enumerate SAS Viya job definitions (jobdefs) assets.
11
-
12
- USE when: list jobdefs, show jobdefs, browse jobdefs, list available jobdefs, next page
13
- DO NOT USE for: find single jobdef (use find-jobdef), execute jobdef (use run-jobdef), find job (use find-job), sas code (use run-sas-program)
14
-
15
- PARAMETERS
16
- - limit: number (default: 10) — number of jobdefs per page
17
- - start: number (default: 1) — 1-based page offset
18
- - where: string (default: '') — optional filter expression
19
-
20
- ROUTING RULES
21
- - list jobdefs → { start: 1, limit: 10 }
22
- - show me 25 jobdefs → { start: 1, limit: 25 }
23
- - next jobdefs → { start: previousStart + previousLimit, limit: previousLimit }
24
-
25
- EXAMPLES
26
- - list jobdefs → { start: 1, limit: 10 }
27
- - list 25 jobdefs → { start: 1, limit: 25 }
28
- - next jobdefs → { start: 11, limit: 10 }
29
-
30
- NEGATIVE EXAMPLES (do not route here)
31
- - find jobdef abc (use find-jobdef)
32
- - list jobs (use list-jobs)
33
- - run jobdef abc (use run-jobdef)
34
- - list models (use list-models)
35
-
36
- PAGINATION
37
- If returned length === limit, hint: next start = start + limit. Empty result with start > 1 means paged past end.
38
-
39
- ERRORS
40
- Surface backend error directly; never fabricate jobdef names.
41
- `;
42
-
43
- let spec = {
44
- name: 'list-jobdefs',
45
- description: description,
46
- inputSchema: z.object({
47
- limit: z.number(),
48
- start: z.number(),
49
- where: z.string()
50
- }),
51
- // No 'server' required; backend context is implicit in helper
52
- handler: async (params) => {
53
- // _listJobdefs handles all validation and defaults
54
- const result = await _listJobdefs(params);
55
- return result;
56
- }
57
- }
58
- return spec;
59
- }
60
- export default listJobdefs;
61
-
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 listJobdefs(_appContext) {
8
+
9
+ let description = `
10
+ list-jobdefs — enumerate SAS Viya job definitions (jobdefs) assets.
11
+
12
+ USE when: list jobdefs, show jobdefs, browse jobdefs, list available jobdefs, next page
13
+ DO NOT USE for: find single jobdef (use find-jobdef), execute jobdef (use run-jobdef), find job (use find-job), sas code (use run-sas-program)
14
+
15
+ PARAMETERS
16
+ - limit: number (default: 10) — number of jobdefs per page
17
+ - start: number (default: 1) — 1-based page offset
18
+ - where: string (default: '') — optional filter expression
19
+
20
+ ROUTING RULES
21
+ - list jobdefs → { start: 1, limit: 10 }
22
+ - show me 25 jobdefs → { start: 1, limit: 25 }
23
+ - next jobdefs → { start: previousStart + previousLimit, limit: previousLimit }
24
+
25
+ EXAMPLES
26
+ - list jobdefs → { start: 1, limit: 10 }
27
+ - list 25 jobdefs → { start: 1, limit: 25 }
28
+ - next jobdefs → { start: 11, limit: 10 }
29
+
30
+ NEGATIVE EXAMPLES (do not route here)
31
+ - find jobdef abc (use find-jobdef)
32
+ - list jobs (use list-jobs)
33
+ - run jobdef abc (use run-jobdef)
34
+ - list models (use list-models)
35
+
36
+ PAGINATION
37
+ If returned length === limit, hint: next start = start + limit. Empty result with start > 1 means paged past end.
38
+
39
+ ERRORS
40
+ Surface backend error directly; never fabricate jobdef names.
41
+ `;
42
+
43
+ let spec = {
44
+ name: 'list-jobdefs',
45
+ description: description,
46
+ inputSchema: z.object({
47
+ limit: z.number().optional(),
48
+ start: z.number().optional(),
49
+ where: z.string().optional()
50
+ }),
51
+ // No 'server' required; backend context is implicit in helper
52
+ handler: async (params) => {
53
+ // _listJobdefs handles all validation and defaults
54
+ const result = await _listJobdefs(params);
55
+ return result;
56
+ }
57
+ }
58
+ return spec;
59
+ }
60
+ export default listJobdefs;
61
+
@@ -1,61 +1,61 @@
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 listJobs(_appContext) {
8
-
9
- let description = `
10
- list-jobs — enumerate SAS Viya job assets.
11
-
12
- USE when: list jobs, show jobs, browse jobs, list available jobs, next page
13
- DO NOT USE for: find single job (use find-job), execute job (use run-job), run job def (use run-jobdef), sas code (use run-sas-program)
14
-
15
- PARAMETERS
16
- - limit: number (default: 10) — number of jobs per page
17
- - start: number (default: 1) — 1-based page offset
18
- - where: string (default: '') — optional filter expression
19
-
20
- ROUTING RULES
21
- - list jobs → { start: 1, limit: 10 }
22
- - show me 25 jobs → { start: 1, limit: 25 }
23
- - next jobs → { start: previousStart + previousLimit, limit: previousLimit }
24
-
25
- EXAMPLES
26
- - list jobs → { start: 1, limit: 10 }
27
- - list 25 jobs → { start: 1, limit: 25 }
28
- - next jobs → { start: 11, limit: 10 }
29
-
30
- NEGATIVE EXAMPLES (do not route here)
31
- - find job abc (use find-job)
32
- - run job abc (use run-job)
33
- - list models (use list-models)
34
- - list tables in lib xyz (use list-tables)
35
-
36
- PAGINATION
37
- If returned length === limit, hint: next start = start + limit. Empty result with start > 1 means paged past end.
38
-
39
- ERRORS
40
- Surface backend error directly; never fabricate job names.
41
- `;
42
-
43
- let spec = {
44
- name: 'list-jobs',
45
- description: description,
46
- inputSchema: z.object({
47
- limit: z.number(),
48
- start: z.number(),
49
- where: z.string()
50
- }),
51
- // No 'server' required; backend context is implicit in helper
52
- handler: async (params) => {
53
- // _listJob handles all validation and defaults
54
- const result = await _listJobs(params);
55
- return result;
56
- }
57
- }
58
- return spec;
59
- }
60
- export default listJobs;
61
-
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 listJobs(_appContext) {
8
+
9
+ let description = `
10
+ list-jobs — enumerate SAS Viya job assets.
11
+
12
+ USE when: list jobs, show jobs, browse jobs, list available jobs, next page
13
+ DO NOT USE for: find single job (use find-job), execute job (use run-job), run job def (use run-jobdef), sas code (use run-sas-program)
14
+
15
+ PARAMETERS
16
+ - limit: number (default: 10) — number of jobs per page
17
+ - start: number (default: 1) — 1-based page offset
18
+ - where: string (default: '') — optional filter expression
19
+
20
+ ROUTING RULES
21
+ - list jobs → { start: 1, limit: 10 }
22
+ - show me 25 jobs → { start: 1, limit: 25 }
23
+ - next jobs → { start: previousStart + previousLimit, limit: previousLimit }
24
+
25
+ EXAMPLES
26
+ - list jobs → { start: 1, limit: 10 }
27
+ - list 25 jobs → { start: 1, limit: 25 }
28
+ - next jobs → { start: 11, limit: 10 }
29
+
30
+ NEGATIVE EXAMPLES (do not route here)
31
+ - find job abc (use find-job)
32
+ - run job abc (use run-job)
33
+ - list models (use list-models)
34
+ - list tables in lib xyz (use list-tables)
35
+
36
+ PAGINATION
37
+ If returned length === limit, hint: next start = start + limit. Empty result with start > 1 means paged past end.
38
+
39
+ ERRORS
40
+ Surface backend error directly; never fabricate job names.
41
+ `;
42
+
43
+ let spec = {
44
+ name: 'list-jobs',
45
+ description: description,
46
+ inputSchema: z.object({
47
+ limit: z.number().optional(),
48
+ start: z.number().optional(),
49
+ where: z.string().optional()
50
+ }),
51
+ // No 'server' required; backend context is implicit in helper
52
+ handler: async (params) => {
53
+ // _listJob handles all validation and defaults
54
+ const result = await _listJobs(params);
55
+ return result;
56
+ }
57
+ }
58
+ return spec;
59
+ }
60
+ export default listJobs;
61
+