@sassoftware/sas-score-mcp-serverjs 0.4.1-1 → 0.4.1-3
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/package.json +1 -1
- package/src/createMcpServer.js +3 -5
- package/src/toolSet/devaScore.js +62 -61
- package/src/toolSet/findJob.js +1 -1
- package/src/toolSet/findJobdef.js +2 -2
- package/src/toolSet/findLibrary.js +67 -67
- package/src/toolSet/findModel.js +2 -2
- package/src/toolSet/findTable.js +3 -2
- package/src/toolSet/getEnv.js +8 -4
- package/src/toolSet/listJobdefs.js +61 -61
- package/src/toolSet/listJobs.js +61 -61
- package/src/toolSet/listLibraries.js +78 -78
- package/src/toolSet/listModels.js +56 -56
- package/src/toolSet/listTables.js +65 -65
- package/src/toolSet/modelInfo.js +2 -2
- package/src/toolSet/modelScore.js +6 -5
- package/src/toolSet/readTable.js +63 -65
- package/src/toolSet/runCasProgram.js +7 -6
- package/src/toolSet/runJob.js +81 -81
- package/src/toolSet/runJobdef.js +82 -82
- package/src/toolSet/runMacro.js +80 -80
- package/src/toolSet/runProgram.js +2 -2
- package/src/toolSet/sasQuery.js +77 -78
- package/src/toolSet/scrInfo.js +1 -1
- package/src/toolSet/scrScore.js +70 -68
- package/src/toolSet/setContext.js +65 -65
- package/src/toolSet/superstat.js +61 -59
- package/src/toolSet/tableInfo.js +57 -57
- package/skills/mcp-tool-description-optimizer/SKILL.md +0 -129
- package/skills/mcp-tool-description-optimizer/references/examples.md +0 -123
- package/skills/sas-read-and-score/SKILL.md +0 -91
- package/skills/sas-read-strategy/SKILL.md +0 -143
- package/skills/sas-score-workflow/SKILL.md +0 -283
package/src/toolSet/scrInfo.js
CHANGED
package/src/toolSet/scrScore.js
CHANGED
|
@@ -1,69 +1,71 @@
|
|
|
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 _scrScore from '../toolHelpers/_scrScore.js';
|
|
8
|
-
|
|
9
|
-
function scrScore(_appContext) {
|
|
10
|
-
let description = `
|
|
11
|
-
## scr-score
|
|
12
|
-
|
|
13
|
-
Purpose
|
|
14
|
-
Score a scenario using a model deployed as a SCR container in Azure or another host).
|
|
15
|
-
|
|
16
|
-
Inputs
|
|
17
|
-
- url (string, required): SCR model identifier (URL)
|
|
18
|
-
- scenario (string | object | array, optional): Input values to score. Accepts:
|
|
19
|
-
- a comma-separated key=value string (e.g. "x=1, y=2"),
|
|
20
|
-
- a JSON object with field names and values (recommended for typed inputs),
|
|
21
|
-
- an array of objects for batch scoring. If omitted, the tool will return the model's input variable definitions.
|
|
22
|
-
|
|
23
|
-
What it returns
|
|
24
|
-
- When scoring: the SCR endpoint response (predictions, probabilities, scores) merged with or alongside the supplied inputs.
|
|
25
|
-
- When \`scenario\` is omitted: metadata describing the model's input variables (names, types, required/optional).
|
|
26
|
-
|
|
27
|
-
Usage notes
|
|
28
|
-
- Run \`scr-info\` first to inspect the expected input variables and types.
|
|
29
|
-
- Prefer structured objects for numeric/date values to avoid type ambiguity; the simple string parser keeps values as strings.
|
|
30
|
-
- Ensure network connectivity and any required credentials for the target SCR service.
|
|
31
|
-
|
|
32
|
-
Examples
|
|
33
|
-
- scrScore with url="loan" and scenario="age=45, income=60000"
|
|
34
|
-
- scrScore with url="https://scr-host/models/loan" and scenario={age:45, income:60000}
|
|
35
|
-
`;
|
|
36
|
-
|
|
37
|
-
let spec = {
|
|
38
|
-
name: 'scr-score',
|
|
39
|
-
description: description,
|
|
40
|
-
inputSchema: z.object({
|
|
41
|
-
url: z.string(),
|
|
42
|
-
scenario: z.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return acc;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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 _scrScore from '../toolHelpers/_scrScore.js';
|
|
8
|
+
|
|
9
|
+
function scrScore(_appContext) {
|
|
10
|
+
let description = `
|
|
11
|
+
## scr-score
|
|
12
|
+
|
|
13
|
+
Purpose
|
|
14
|
+
Score a scenario using a model deployed as a SCR container in Azure or another host).
|
|
15
|
+
|
|
16
|
+
Inputs
|
|
17
|
+
- url (string, required): SCR model identifier (URL)
|
|
18
|
+
- scenario (string | object | array, optional): Input values to score. Accepts:
|
|
19
|
+
- a comma-separated key=value string (e.g. "x=1, y=2"),
|
|
20
|
+
- a JSON object with field names and values (recommended for typed inputs),
|
|
21
|
+
- an array of objects for batch scoring. If omitted, the tool will return the model's input variable definitions.
|
|
22
|
+
|
|
23
|
+
What it returns
|
|
24
|
+
- When scoring: the SCR endpoint response (predictions, probabilities, scores) merged with or alongside the supplied inputs.
|
|
25
|
+
- When \`scenario\` is omitted: metadata describing the model's input variables (names, types, required/optional).
|
|
26
|
+
|
|
27
|
+
Usage notes
|
|
28
|
+
- Run \`scr-info\` first to inspect the expected input variables and types.
|
|
29
|
+
- Prefer structured objects for numeric/date values to avoid type ambiguity; the simple string parser keeps values as strings.
|
|
30
|
+
- Ensure network connectivity and any required credentials for the target SCR service.
|
|
31
|
+
|
|
32
|
+
Examples
|
|
33
|
+
- scrScore with url="loan" and scenario="age=45, income=60000"
|
|
34
|
+
- scrScore with url="https://scr-host/models/loan" and scenario={age:45, income:60000}
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
let spec = {
|
|
38
|
+
name: 'scr-score',
|
|
39
|
+
description: description,
|
|
40
|
+
inputSchema: z.object({
|
|
41
|
+
url: z.string(),
|
|
42
|
+
scenario: z.string()
|
|
43
|
+
|
|
44
|
+
}),
|
|
45
|
+
|
|
46
|
+
handler: async (params) => {
|
|
47
|
+
let {url, scenario,_appContext} = params;
|
|
48
|
+
|
|
49
|
+
if (url === null) {
|
|
50
|
+
return { status: { statusCode: 2, msg: `SCR model ${url} was not specified` }, results: {} };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Normalize simple string scenarios like "x=1, y=2" into an object
|
|
54
|
+
if (typeof scenario === 'string' && scenario.includes('=')) {
|
|
55
|
+
scenario = scenario.split(',').reduce((acc, pair) => {
|
|
56
|
+
const [k, ...rest] = pair.split('=');
|
|
57
|
+
if (!k) return acc;
|
|
58
|
+
acc[k.trim()] = rest.join('=').trim();
|
|
59
|
+
return acc;
|
|
60
|
+
}, {});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let r = await _scrScore({ url: url, scenario: scenario , _appContext: _appContext});
|
|
64
|
+
return r;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return spec;
|
|
69
|
+
}
|
|
70
|
+
|
|
69
71
|
export default scrScore;
|
|
@@ -1,65 +1,65 @@
|
|
|
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
|
-
|
|
8
|
-
function setContext(_appContext) {
|
|
9
|
-
let description = `
|
|
10
|
-
set-context — set the CAS and SAS server contexts for subsequent tool calls.
|
|
11
|
-
|
|
12
|
-
USE when: switch to CAS server, change compute context, check current context, set both
|
|
13
|
-
DO NOT USE for: get variables (use get-env), read data (use read-table), run programs (use run-sas-program)
|
|
14
|
-
|
|
15
|
-
PARAMETERS
|
|
16
|
-
- cas: string — CAS server name (optional), e.g. 'cas-shared-default', 'finance-cas-server'
|
|
17
|
-
- sas: string — SAS compute context (optional), e.g. 'SAS Studio Compute Context', 'batch-compute'
|
|
18
|
-
|
|
19
|
-
ROUTING RULES
|
|
20
|
-
- "use finance-cas-server" → { cas: "finance-cas-server" }
|
|
21
|
-
- "switch to SAS Studio Compute Context" → { sas: "SAS Studio Compute Context" }
|
|
22
|
-
- "use finance-cas for CAS and batch-compute for SAS" → { cas: "finance-cas", sas: "batch-compute" }
|
|
23
|
-
- "what context am I using" → { } (no params, returns current)
|
|
24
|
-
|
|
25
|
-
EXAMPLES
|
|
26
|
-
- "use finance-cas-server" → { cas: "finance-cas-server" }
|
|
27
|
-
- "switch to batch-compute" → { sas: "batch-compute" }
|
|
28
|
-
- "what's my current context" → { }
|
|
29
|
-
|
|
30
|
-
NEGATIVE EXAMPLES (do not route here)
|
|
31
|
-
- "read table cars" (use read-table)
|
|
32
|
-
- "what's the value of X" (use get-env)
|
|
33
|
-
- "run program" (use run-sas-program)
|
|
34
|
-
|
|
35
|
-
ERRORS
|
|
36
|
-
Returns current or updated context values {cas, sas}. Error if server not found or invalid name.
|
|
37
|
-
`;
|
|
38
|
-
|
|
39
|
-
let spec = {
|
|
40
|
-
name: 'set-context',
|
|
41
|
-
description: description,
|
|
42
|
-
inputSchema: z.object({
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
handler: async (params) => {
|
|
47
|
-
|
|
48
|
-
let {cas, sas} = params;
|
|
49
|
-
if (typeof cas === 'string' && cas.trim().length > 0) {
|
|
50
|
-
_appContext.contexts.cas = cas.trim();
|
|
51
|
-
}
|
|
52
|
-
if (typeof sas === 'string' && sas.trim().length > 0) {
|
|
53
|
-
_appContext.contexts.sas = sas.trim();
|
|
54
|
-
}
|
|
55
|
-
// Return a structured response without extraneous keys
|
|
56
|
-
return {
|
|
57
|
-
content: [{ type: 'text', text: JSON.stringify(_appContext.contexts) }],
|
|
58
|
-
structuredContent: _appContext.contexts
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return spec;
|
|
63
|
-
}
|
|
64
|
-
export default setContext;
|
|
65
|
-
|
|
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
|
+
|
|
8
|
+
function setContext(_appContext) {
|
|
9
|
+
let description = `
|
|
10
|
+
set-context — set the CAS and SAS server contexts for subsequent tool calls.
|
|
11
|
+
|
|
12
|
+
USE when: switch to CAS server, change compute context, check current context, set both
|
|
13
|
+
DO NOT USE for: get variables (use get-env), read data (use read-table), run programs (use run-sas-program)
|
|
14
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- cas: string — CAS server name (optional), e.g. 'cas-shared-default', 'finance-cas-server'
|
|
17
|
+
- sas: string — SAS compute context (optional), e.g. 'SAS Studio Compute Context', 'batch-compute'
|
|
18
|
+
|
|
19
|
+
ROUTING RULES
|
|
20
|
+
- "use finance-cas-server" → { cas: "finance-cas-server" }
|
|
21
|
+
- "switch to SAS Studio Compute Context" → { sas: "SAS Studio Compute Context" }
|
|
22
|
+
- "use finance-cas for CAS and batch-compute for SAS" → { cas: "finance-cas", sas: "batch-compute" }
|
|
23
|
+
- "what context am I using" → { } (no params, returns current)
|
|
24
|
+
|
|
25
|
+
EXAMPLES
|
|
26
|
+
- "use finance-cas-server" → { cas: "finance-cas-server" }
|
|
27
|
+
- "switch to batch-compute" → { sas: "batch-compute" }
|
|
28
|
+
- "what's my current context" → { }
|
|
29
|
+
|
|
30
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
31
|
+
- "read table cars" (use read-table)
|
|
32
|
+
- "what's the value of X" (use get-env)
|
|
33
|
+
- "run program" (use run-sas-program)
|
|
34
|
+
|
|
35
|
+
ERRORS
|
|
36
|
+
Returns current or updated context values {cas, sas}. Error if server not found or invalid name.
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
let spec = {
|
|
40
|
+
name: 'set-context',
|
|
41
|
+
description: description,
|
|
42
|
+
inputSchema: z.object({
|
|
43
|
+
cas: z.string().optional(),
|
|
44
|
+
sas: z.string().optional()
|
|
45
|
+
}),
|
|
46
|
+
handler: async (params) => {
|
|
47
|
+
|
|
48
|
+
let {cas, sas} = params;
|
|
49
|
+
if (typeof cas === 'string' && cas.trim().length > 0) {
|
|
50
|
+
_appContext.contexts.cas = cas.trim();
|
|
51
|
+
}
|
|
52
|
+
if (typeof sas === 'string' && sas.trim().length > 0) {
|
|
53
|
+
_appContext.contexts.sas = sas.trim();
|
|
54
|
+
}
|
|
55
|
+
// Return a structured response without extraneous keys
|
|
56
|
+
return {
|
|
57
|
+
content: [{ type: 'text', text: JSON.stringify(_appContext.contexts) }],
|
|
58
|
+
structuredContent: _appContext.contexts
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return spec;
|
|
63
|
+
}
|
|
64
|
+
export default setContext;
|
|
65
|
+
|
package/src/toolSet/superstat.js
CHANGED
|
@@ -1,59 +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
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- compute superstat for
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}),
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
run;
|
|
48
|
-
|
|
49
|
-
run;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type } from 'node:os';
|
|
6
|
+
import _submitCode from '../toolHelpers/_submitCode.js';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
function superstat(_appContext) {
|
|
10
|
+
let desc = `
|
|
11
|
+
## superstat: compute superstat for two numbers using SAS programming
|
|
12
|
+
|
|
13
|
+
## Details
|
|
14
|
+
This is a tool to demonstrate using SAS programming to score. The SAS program for suprestat is
|
|
15
|
+
below. In a real application this would be a more complex program that is
|
|
16
|
+
available to the SAS server.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
ods html style=barrettsblue;
|
|
20
|
+
data temp;
|
|
21
|
+
superstat = (&a + &b) * 42;
|
|
22
|
+
run;
|
|
23
|
+
proc print data=temp;
|
|
24
|
+
run;
|
|
25
|
+
ods html close;
|
|
26
|
+
run;
|
|
27
|
+
|
|
28
|
+
## Sample Prompt
|
|
29
|
+
|
|
30
|
+
- compute superstat for 1 and 2
|
|
31
|
+
- compute superstat for 3,5
|
|
32
|
+
|
|
33
|
+
`;
|
|
34
|
+
let spec = {
|
|
35
|
+
name: 'superstat',
|
|
36
|
+
description: desc,
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
a: z.number().optional()
|
|
39
|
+
}),
|
|
40
|
+
required: ['a', 'b']
|
|
41
|
+
},
|
|
42
|
+
handler: async (params) => {
|
|
43
|
+
let src = `
|
|
44
|
+
ods html style=barrettsblue;
|
|
45
|
+
data temp;
|
|
46
|
+
superstat = (&a + &b) * 42;
|
|
47
|
+
run;
|
|
48
|
+
proc print data=temp;
|
|
49
|
+
run;
|
|
50
|
+
ods html close;
|
|
51
|
+
run;
|
|
52
|
+
`;
|
|
53
|
+
params.src = src;
|
|
54
|
+
let r = await _submitCode(params);
|
|
55
|
+
return r;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
};
|
|
59
|
+
return spec;
|
|
60
|
+
}
|
|
61
|
+
export default superstat;
|
package/src/toolSet/tableInfo.js
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
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 debug from 'debug';
|
|
7
|
-
|
|
8
|
-
import _tableInfo from '../toolHelpers/_tableInfo.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- "
|
|
25
|
-
- "
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- "
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- "
|
|
34
|
-
- "
|
|
35
|
-
- "
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
handler: async (params) => {
|
|
50
|
-
params.describe = true;
|
|
51
|
-
let r = await _tableInfo(params);
|
|
52
|
-
return r;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return specs;
|
|
56
|
-
}
|
|
57
|
-
export default tableInfo;
|
|
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 debug from 'debug';
|
|
7
|
+
|
|
8
|
+
import _tableInfo from '../toolHelpers/_tableInfo.js';
|
|
9
|
+
import { type } from 'node:os';
|
|
10
|
+
function tableInfo(_appContext) {
|
|
11
|
+
|
|
12
|
+
let describe = `
|
|
13
|
+
table-info — retrieve metadata about a table in a CAS or SAS library.
|
|
14
|
+
|
|
15
|
+
USE when: what columns, describe structure, show schema, table statistics, column info
|
|
16
|
+
DO NOT USE for: read data (use read-table), list tables (use list-tables), find table (use find-table), queries (use sas-query)
|
|
17
|
+
|
|
18
|
+
PARAMETERS
|
|
19
|
+
- table: string — table name (required)
|
|
20
|
+
- lib: string — caslib or libref (required)
|
|
21
|
+
- server: string (default: 'cas') — 'cas' or 'sas'
|
|
22
|
+
|
|
23
|
+
ROUTING RULES
|
|
24
|
+
- "what columns are in cars" → { table: "cars", lib: "<lib>", server: "cas" }
|
|
25
|
+
- "describe table sales in Public" → { table: "sales", lib: "Public", server: "cas" }
|
|
26
|
+
- "show schema for mylib.iris on sas" → { table: "iris", lib: "mylib", server: "sas" }
|
|
27
|
+
|
|
28
|
+
EXAMPLES
|
|
29
|
+
- "what columns in cars" → { table: "cars", lib: "<lib>", server: "cas" }
|
|
30
|
+
- "describe structure of customers in Public" → { table: "customers", lib: "Public", server: "cas" }
|
|
31
|
+
|
|
32
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
33
|
+
- "read table cars" (use read-table)
|
|
34
|
+
- "list tables in Public" (use list-tables)
|
|
35
|
+
- "does table exist" (use find-table)
|
|
36
|
+
- "query table" (use sas-query)
|
|
37
|
+
|
|
38
|
+
ERRORS
|
|
39
|
+
Returns columns array (name, type, label, format, length) and tableInfo (rowCount, fileSize, created, modified).
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
let specs = {
|
|
43
|
+
name: 'table-info',
|
|
44
|
+
description: describe,
|
|
45
|
+
inputSchema: z.object({
|
|
46
|
+
table: z.string(),
|
|
47
|
+
lib: z.string().optional()
|
|
48
|
+
}),
|
|
49
|
+
handler: async (params) => {
|
|
50
|
+
params.describe = true;
|
|
51
|
+
let r = await _tableInfo(params);
|
|
52
|
+
return r;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return specs;
|
|
56
|
+
}
|
|
57
|
+
export default tableInfo;
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: mcp-tool-description-optimizer
|
|
3
|
-
description: >
|
|
4
|
-
Optimize MCP (Model Context Protocol) tool descriptions for token efficiency and LLM routing accuracy.
|
|
5
|
-
Use this skill whenever a user shares a raw, verbose, or poorly structured MCP tool description and wants
|
|
6
|
-
it improved, rewritten, or reviewed. Trigger on phrases like: "optimize this tool description",
|
|
7
|
-
"rewrite my MCP tool description", "make this tool description more efficient", "clean up my tool spec",
|
|
8
|
-
"improve how Claude picks my tool", or when a user pastes a JavaScript/TypeScript tool description string
|
|
9
|
-
and asks for help with it. Also trigger when the user mentions token efficiency, tool routing,
|
|
10
|
-
or LLM disambiguation in the context of MCP servers.
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# MCP Tool Description Optimizer
|
|
14
|
-
|
|
15
|
-
Rewrites verbose or poorly structured MCP tool descriptions into compact, signal-rich versions that
|
|
16
|
-
improve LLM tool selection accuracy while reducing token usage.
|
|
17
|
-
|
|
18
|
-
## Why this matters
|
|
19
|
-
|
|
20
|
-
Claude and other LLMs select MCP tools based entirely on the `description` field. Descriptions that are
|
|
21
|
-
too long, redundant, or badly structured waste context tokens and reduce routing precision.
|
|
22
|
-
A well-optimized description:
|
|
23
|
-
- States what the tool does and when to use it upfront
|
|
24
|
-
- Eliminates redundancy (same info repeated across sections)
|
|
25
|
-
- Uses a compact, scannable format (labeled blocks, not nested markdown)
|
|
26
|
-
- Includes clear negative examples to prevent mis-routing
|
|
27
|
-
- Keeps parameters terse — name, type, default, one-line purpose
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## Optimization Process
|
|
32
|
-
|
|
33
|
-
### Step 1 — Analyze the input description
|
|
34
|
-
|
|
35
|
-
Before rewriting, identify these problems in the original:
|
|
36
|
-
|
|
37
|
-
| Problem | Example |
|
|
38
|
-
|---|---|
|
|
39
|
-
| **Redundancy** | Trigger phrases listed in 3+ places |
|
|
40
|
-
| **Filler sections** | "Rationale", "Behavior Summary", "Response Contract" with no routing signal |
|
|
41
|
-
| **Orphaned syntax** | Arrows (`→`) or bullets with no target |
|
|
42
|
-
| **Overlong examples** | Long prose examples when one-liners suffice |
|
|
43
|
-
| **Heavy markdown** | `##` headers for every minor point |
|
|
44
|
-
| **Duplicated parameter docs** | Same param described in both a table and prose |
|
|
45
|
-
|
|
46
|
-
Call out 2–4 of the most impactful issues before writing the new version.
|
|
47
|
-
|
|
48
|
-
### Step 2 — Rewrite using the standard template
|
|
49
|
-
|
|
50
|
-
Use this exact block structure for the output. Omit blocks that don't apply.
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
<tool-name> — <one-line purpose>.
|
|
54
|
-
|
|
55
|
-
USE when: <comma-separated user intents or trigger phrases>
|
|
56
|
-
DO NOT USE for: <comma-separated anti-patterns with → redirect where applicable>
|
|
57
|
-
|
|
58
|
-
PARAMETERS
|
|
59
|
-
- <name>: <type> (default: <val>) — <one-line purpose>
|
|
60
|
-
...
|
|
61
|
-
|
|
62
|
-
ROUTING RULES
|
|
63
|
-
- "<trigger phrase>" → { param: value }
|
|
64
|
-
- "<trigger phrase>" → { param: value }
|
|
65
|
-
- <ambiguous case> → <ask for clarification | default behavior>
|
|
66
|
-
|
|
67
|
-
EXAMPLES
|
|
68
|
-
- "<user utterance>" → { param: value, ... }
|
|
69
|
-
- "<user utterance>" → { param: value, ... }
|
|
70
|
-
|
|
71
|
-
NEGATIVE EXAMPLES (do not route here)
|
|
72
|
-
- "<user utterance>" → <correct tool>
|
|
73
|
-
|
|
74
|
-
PAGINATION (include only if tool is paginated)
|
|
75
|
-
If returned count === limit → hint: next start = start + limit.
|
|
76
|
-
If start > 1 and result empty → note paging may exceed available items.
|
|
77
|
-
|
|
78
|
-
ERRORS
|
|
79
|
-
<One or two lines: return structure, hallucination policy>
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Step 3 — Apply these rules consistently
|
|
83
|
-
|
|
84
|
-
**USE/DO NOT USE block**
|
|
85
|
-
- Write as comma-separated inline list, not a bullet list
|
|
86
|
-
- DO NOT USE entries should name the redirect tool in parentheses where known
|
|
87
|
-
|
|
88
|
-
**ROUTING RULES block**
|
|
89
|
-
- One rule per line; quote the trigger phrase; use `→ { }` for param mapping
|
|
90
|
-
- Consolidate synonyms on one line: `"cas libs / cas libraries / in cas" → { server: 'cas' }`
|
|
91
|
-
- List the default/fallback rule last
|
|
92
|
-
|
|
93
|
-
**PARAMETERS block**
|
|
94
|
-
- One line per param: `- name: type (default: val) — purpose`
|
|
95
|
-
- Skip obvious params (e.g. don't explain what `limit` means if it's standard pagination)
|
|
96
|
-
|
|
97
|
-
**EXAMPLES block**
|
|
98
|
-
- Each example fits on one line
|
|
99
|
-
- For "next page" examples, include the prior call's state inline: `"next" (prev: start:1, limit:10) → { start: 11, limit: 10 }`
|
|
100
|
-
|
|
101
|
-
**NEGATIVE EXAMPLES block**
|
|
102
|
-
- Only include when mis-routing is a real risk
|
|
103
|
-
- Format: `"<utterance>" → <correct-tool-name>`
|
|
104
|
-
|
|
105
|
-
**Tone**
|
|
106
|
-
- Imperative, terse. No filler words ("Please note that...", "It is important to...")
|
|
107
|
-
- Never include a "Rationale" or "Behavior Summary" section — if behavior matters, encode it as a rule
|
|
108
|
-
|
|
109
|
-
### Step 4 — Validate before returning
|
|
110
|
-
|
|
111
|
-
Check the rewritten description against this list:
|
|
112
|
-
|
|
113
|
-
- [ ] No trigger phrase appears in more than one block
|
|
114
|
-
- [ ] No orphaned `→` arrows or dangling bullets
|
|
115
|
-
- [ ] Parameter defaults are stated explicitly
|
|
116
|
-
- [ ] Negative examples cover the tool's most common mis-routing risks
|
|
117
|
-
- [ ] Total length is ≤ 50% of the original (target: 30–40% reduction)
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## Output format
|
|
122
|
-
|
|
123
|
-
Always return:
|
|
124
|
-
|
|
125
|
-
1. **Analysis** — 2–4 bullet points naming the key issues found in the original
|
|
126
|
-
2. **Rewritten description** — inside a JavaScript code block (matching the user's original code style)
|
|
127
|
-
3. **Change summary** — a short table or bullet list of what changed and why
|
|
128
|
-
|
|
129
|
-
See `references/examples.md` for before/after examples of real tool descriptions.
|