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

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.
@@ -1,123 +1,127 @@
1
- ---
2
- name: sas-list-tables-smart
3
- description: >
4
- List all tables in a SAS Viya library with intelligent server detection. When the server is not
5
- specified, automatically checks CAS first, then SAS if not found. Informs the user if the library
6
- does not exist in either server. Use this skill when the user wants to browse or explore available
7
- tables. Trigger phrases include: "list tables in", "show tables in", "what tables are in",
8
- "browse tables in", "tables in library", "enumerate tables", or any request to explore data sources.
9
- ---
10
-
11
- # Smart Data Access in SAS Library (List, Read, Query)
12
-
13
- Intelligently enumerates tables in a SAS Viya library, automatically determining the correct server
14
- when not explicitly specified.
15
-
16
- **If the user specifies the server explicitly** (e.g., "list tables in Public in cas"):
17
- - Use the specified server: `server: "cas"` or `server: "sas"`
18
- - Proceed directly to listing tables
19
-
20
- **If the server is NOT specified:**
21
- 1. **First attempt**: Check CAS (`server: "cas"`)
22
- 2. **If no tables found in CAS**: Check SAS (`server: "sas"`)
23
- 3. **If no tables found in either**:
24
- - Inform user: *"The library '<lib>' was not found in CAS or SAS. Please verify the library name is correct."*
25
- - Ask: *"Would you like to list available libraries?"* (suggest `list-libraries`)
26
-
27
- ---
28
-
29
- ## Using list-tables
30
-
31
- **When:**
32
- - User wants to browse all tables in a library
33
- - User wants to see what data is available
34
- - User wants to explore library contents before querying
35
-
36
- **How:**
37
- ```
38
- list-tables({
39
- lib: "libraryname", // required
40
- server: "cas" or "sas", // required; determined by server check
41
- limit: 10, // optional; default 10, adjust for pagination
42
- start: 1 // optional; default 1, use for pagination
43
- })
44
- ```
45
-
46
- **Rules:**
47
- - Always determine the correct server first (cas → sas → neither)
48
- - **For SAS server: always uppercase the library name** (e.g., "maps" → "MAPS")
49
- - If library name is missing, ask: *"Which library should I list tables from?"*
50
- - Default page size is 10; adjust based on user request ("show me all", "25 tables", etc.)
51
- - If returned table count equals the limit, suggest pagination: *"There may be more tables. Use `start: {next_offset}` to see more."*
52
- - If no tables are found despite library existing, report: *"No tables found in {lib} on {server} server."*
53
- - Return table names only; do not fetch table metadata unless explicitly requested
54
-
55
- ---
56
-
57
- ## Smart server detection logic
58
-
59
- ```
60
- IF server specified by user
61
- → IF server is "sas"
62
- → uppercase lib
63
- use that server
64
- ELSE
65
- TRY list-tables(lib, server="cas")
66
- IF tables found
67
- → success, return tables
68
- ELSE
69
- uppercase lib
70
- TRY list-tables(lib.toUpperCase(), server="sas")
71
- IF tables found
72
- success, return tables
73
- ELSE
74
- inform user library not found in either server
75
- ```
76
-
77
- ---
78
-
79
- ## Common patterns
80
-
81
- **Pattern 1 — List tables, server unspecified**
82
- > "List tables in Public"
83
-
84
- 1. Try CAS: `list-tables({ lib: "Public", server: "cas" })`
85
- 2. If empty, try SAS with uppercase: `list-tables({ lib: "PUBLIC", server: "sas" })`
86
- 3. If still empty → inform user
87
-
88
- **Pattern 2 List tables with explicit server (SAS)**
89
- > "List tables in sashelp in sas"
90
-
91
- 1. Skip server detection
92
- 2. Call with uppercase lib: `list-tables({ lib: "SASHELP", server: "sas" })`
93
-
94
- **Pattern 3 — List tables with explicit server (CAS)**
95
- > "List tables in Public in cas"
96
-
97
- 1. No uppercase needed for CAS
98
- 2. Call: `list-tables({ lib: "Public", server: "cas" })`
99
-
100
- **Pattern 4 Pagination**
101
- > "Show me 25 tables in Samples, then the next batch"
102
-
103
- 1. First call: `list-tables({ lib: "Samples", limit: 25, start: 1 })`
104
- 2. Next call: `list-tables({ lib: "Samples", limit: 25, start: 26 })`
105
-
106
- **Pattern 5 Library not found**
107
- > "List tables in foo"
108
-
109
- 1. Try CAS: empty
110
- 2. Try SAS with uppercase: empty
111
- 3. Response: *"The library 'foo' was not found in CAS or SAS. Please verify the library name."*
112
-
113
- ---
114
-
115
- ## Error handling
116
-
117
- | Scenario | Action |
118
- |---|---|
119
- | Library not found in either server | Inform user and ask to verify library name |
120
- | Empty result on first server | Automatically check second server |
121
- | User specifies invalid server | Return error; ask user to clarify: `"cas"` or `"sas"` |
122
- | Missing library name | Ask: *"Which library should I list tables from?"* |
123
-
1
+ ---
2
+ name: sas-list-tables-smart
3
+ description: >
4
+ List all tables in a SAS Viya library with intelligent server detection. When the server is not
5
+ specified, automatically checks CAS first, then SAS if not found. Informs the user if the library
6
+ does not exist in either server. Use this skill when the user wants to browse or explore available
7
+ tables. Trigger phrases include: "list tables in", "show tables in", "what tables are in",
8
+ "browse tables in", "tables in library", "enumerate tables", or any request to explore data sources.
9
+ ---
10
+
11
+ # Smart Data Access in SAS Library (List, Read, Query)
12
+
13
+ Intelligently enumerates tables in a SAS Viya library, automatically determining the correct server
14
+ when not explicitly specified.
15
+
16
+ > **Pre-flight check**: Before listing tables, verify the library exists using the `sas-find-library-smart` skill.
17
+ > This ensures consistent server detection across all data operations.
18
+
19
+ **If the user specifies the server explicitly** (e.g., "list tables in Public in cas"):
20
+ - Use the specified server: `server: "cas"` or `server: "sas"`
21
+ - Proceed directly to listing tables
22
+
23
+ **If the server is NOT specified:**
24
+ 1. **First attempt**: Check CAS (`server: "cas"`)
25
+ 2. **If no tables found in CAS**: Check SAS (`server: "sas"`)
26
+ 3. **If no tables found in either**:
27
+ - Inform user: *"The library '<lib>' was not found in CAS or SAS. Please verify the library name is correct."*
28
+ - Ask: *"Would you like to list available libraries?"* (suggest `sas-score-list-libraries`)
29
+
30
+ ---
31
+
32
+ ## Using sas-score-list-tables
33
+
34
+ **When:**
35
+ - User wants to browse all tables in a library
36
+ - User wants to see what data is available
37
+ - User wants to explore library contents before querying
38
+
39
+ **How:**
40
+ ```
41
+ sas-score-list-tables({
42
+ lib: "libraryname", // required
43
+ server: "cas" or "sas", // required; determined by server check
44
+ limit: 10, // optional; default 10, adjust for pagination
45
+ start: 1 // optional; default 1, use for pagination
46
+ })
47
+ ```
48
+
49
+ **Rules:**
50
+ - Always determine the correct server first (cas sas neither)
51
+ - **For SAS server: always uppercase the library name** (e.g., "maps" "MAPS")
52
+ - If library name is missing, ask: *"Which library should I list tables from?"*
53
+ - Default page size is 10; adjust based on user request ("show me all", "25 tables", etc.)
54
+ - If returned table count equals the limit, suggest pagination: *"There may be more tables. Use `start: {next_offset}` to see more."*
55
+ - If no tables are found despite library existing, report: *"No tables found in {lib} on {server} server."*
56
+ - Return table names only; do not fetch table metadata unless explicitly requested
57
+
58
+ ---
59
+
60
+ ## Smart server detection logic
61
+
62
+ ```
63
+ IF server specified by user
64
+ → IF server is "sas"
65
+ uppercase lib
66
+ use that server
67
+ ELSE
68
+ → TRY sas-score-list-tables(lib, server="cas")
69
+ IF tables found
70
+ success, return tables
71
+ ELSE
72
+ uppercase lib
73
+ → TRY sas-score-list-tables(lib.toUpperCase(), server="sas")
74
+ IF tables found
75
+ → success, return tables
76
+ ELSE
77
+ → inform user library not found in either server
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Common patterns
83
+
84
+ **Pattern 1 List tables, server unspecified**
85
+ > "List tables in Public"
86
+
87
+ 1. Try CAS: `sas-score-list-tables({ lib: "Public", server: "cas" })`
88
+ 2. If empty, try SAS with uppercase: `sas-score-list-tables({ lib: "PUBLIC", server: "sas" })`
89
+ 3. If still empty inform user
90
+
91
+ **Pattern 2 — List tables with explicit server (SAS)**
92
+ > "List tables in sashelp in sas"
93
+
94
+ 1. Skip server detection
95
+ 2. Call with uppercase lib: `sas-score-list-tables({ lib: "SASHELP", server: "sas" })`
96
+
97
+ **Pattern 3 List tables with explicit server (CAS)**
98
+ > "List tables in Public in cas"
99
+
100
+ 1. No uppercase needed for CAS
101
+ 2. Call: `sas-score-list-tables({ lib: "Public", server: "cas" })`
102
+
103
+ **Pattern 4 Pagination**
104
+ > "Show me 25 tables in Samples, then the next batch"
105
+
106
+ 1. First call: `sas-score-list-tables({ lib: "Samples", limit: 25, start: 1 })`
107
+ 2. Next call: `sas-score-list-tables({ lib: "Samples", limit: 25, start: 26 })`
108
+
109
+ **Pattern 5 Library not found**
110
+ > "List tables in foo"
111
+
112
+ 1. Try CAS: empty
113
+ 2. Try SAS with uppercase: empty
114
+ 3. Response: *"The library 'foo' was not found in CAS or SAS. Please verify the library name."*
115
+
116
+ ---
117
+
118
+ ## Error handling
119
+
120
+ | Scenario | Action |
121
+ |---|---|
122
+ | Library not found in either server | Inform user and ask to verify library name |
123
+ | Empty result on first server | Automatically check second server |
124
+ | User specifies invalid server | Return error; ask user to clarify: `"cas"` or `"sas"` |
125
+ | Missing library name | Ask: *"Which library should I list tables from?"* |
126
+ | Library verification needed | Use `sas-find-library-smart` skill to verify library exists first |
127
+
@@ -2,7 +2,7 @@
2
2
  name: sas-read-and-score
3
3
  description: >
4
4
  Guide the full read → score workflow in SAS Viya: reading records from a table and then scoring
5
- them with a MAS model (using model-score). Use this skill whenever the user wants to score records
5
+ them with a MAS model (using sas-score-model-score). Use this skill whenever the user wants to score records
6
6
  from a table, run a model against query results, predict outcomes for a set of rows, or any
7
7
  combination of fetching data and scoring it. Trigger phrases include: "score these records",
8
8
  "score results of my query", "run the model on this table", "predict for these customers",
@@ -17,6 +17,17 @@ with a deployed MAS model.
17
17
 
18
18
  ---
19
19
 
20
+ ## Pre-flight verification
21
+
22
+ **Before attempting to read or score table data:**
23
+ 1. **Verify library exists**: Use `sas-find-library-smart` to check the library in CAS first, then SAS if needed
24
+ 2. **Verify table exists**: Use `sas-score-find-table` to confirm the table is in the library
25
+ 3. **Confirm server location**: Ensure you know which server (CAS or SAS) contains the data
26
+
27
+ This ensures consistent behavior with other data access operations.
28
+
29
+ ---
30
+
20
31
  ## Workflow overview
21
32
 
22
33
  The typical flow involves:
@@ -72,7 +83,7 @@ If the user specifies a model name that's new/unknown:
72
83
  ## Rules
73
84
 
74
85
  - Always validate table/library existence before attempting to read
75
- - Always check model exists before invoking `model-score`
86
+ - Always check model exists before invoking `sas-score-model-score`
76
87
  - Match table columns to model input variables; warn on mismatch
77
88
  - If multiple records: score batch if possible; fall back to row-by-row
78
89
  - Merge predictions with original data using row index or key column
@@ -90,3 +101,11 @@ If the user specifies a model name that's new/unknown:
90
101
  | Scoring error | Return structured error, suggest checking model inputs |
91
102
  | Empty read result | Inform user, ask if they want to adjust the query/filter |
92
103
  | Data type mismatch | Warn user about type conversion, proceed or ask for clarification |
104
+
105
+ ---
106
+
107
+ ## Integration with other skills
108
+
109
+ - **Before this workflow**: Use `sas-find-library-smart` to verify the library exists
110
+ - **For data retrieval**: Use `sas-read-strategy` to choose the right read tool (read-table vs sas-query)
111
+ - **For scoring**: Use `sas-score-workflow` for advanced scoring options beyond MAS models
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: sas-read-strategy
3
3
  description: >
4
- Guide the user in choosing the right data retrieval tool: read-table (for raw row access with filters)
5
- or sas-query (for analytical queries, aggregations, joins). Use this skill when the user wants to
4
+ Guide the user in choosing the right data retrieval tool: sas-score-read-table (for raw row access with filters)
5
+ or sas-score-sas-query (for analytical queries, aggregations, joins). Use this skill when the user wants to
6
6
  fetch records from a SAS/CAS table. Trigger phrases include: "read records from", "get data where",
7
7
  "fetch rows from", "query the table", "give me the first N records", "aggregate by", "join tables",
8
8
  or any request that starts with data retrieval.
@@ -10,19 +10,25 @@ description: >
10
10
 
11
11
  # SAS Read Strategy
12
12
 
13
- Guides the decision between `read-table` and `sas-query` based on the user's intent and the nature
13
+ Guides the decision between `sas-score-read-table` and `sas-score-sas-query` based on the user's intent and the nature
14
14
  of the data operation. Determines which server contains the data and which retrieval tool is most appropriate.
15
15
 
16
16
  ## Determine the server location
17
17
 
18
- Before retrieving data, check which server(s) contain the table:
18
+ Before retrieving data, verify the library and determine which server(s) contain the table:
19
19
 
20
- 1. **Check both servers**: Use `find-table` to check if the table exists in CAS and/or SAS
21
- 2. **Decide server placement**:
22
- - If table exists **only in CAS** set `server: "cas"`
23
- - If table exists **only in SAS** set `server: "sas"`
24
- - If table exists **in both** → ask the user: *"The table exists in both CAS and SAS. Which server would you prefer to query from?"*
25
- - If table exists **in neither** → inform user and ask which library to search in
20
+ **Step 1: Verify library existence**
21
+ - Use `sas-find-library-smart` skill to check the library in CAS first, then SAS if needed
22
+ - This establishes the correct server and uppercase convention for SAS libraries
23
+ - Informs the user which server contains the library
24
+
25
+ **Step 2: Locate the specific table**
26
+ - Use `sas-score-find-table` to check if the table exists in the library
27
+ - Possible outcomes:
28
+ - If table exists **only in CAS** → set `server: "cas"`
29
+ - If table exists **only in SAS** → set `server: "sas"`
30
+ - If table exists **in both** → ask the user: *"The table exists in both CAS and SAS. Which server would you prefer to query from?"*
31
+ - If table exists **in neither** → inform user and suggest verifying the table name
26
32
 
27
33
  ---
28
34
 
@@ -35,8 +41,8 @@ Ask yourself: does the user already have the data in hand?
35
41
 
36
42
  | User's Intent | Tool | Example |
37
43
  |---|---|---|
38
- | Get specific raw rows, apply simple filter, retrieve first N records | `read-table` | "Show me 10 rows from customers where status='active'" |
39
- | Aggregate/summarize, calculate, join tables, analytical question | `sas-query` | "Average salary by department", "Count orders by region" |
44
+ | Get specific raw rows, apply simple filter, retrieve first N records | `sas-score-read-table` | "Show me 10 rows from customers where status='active'" |
45
+ | Aggregate/summarize, calculate, join tables, analytical question | `sas-score-sas-query` | "Average salary by department", "Count orders by region" |
40
46
 
41
47
  ---
42
48
 
@@ -49,17 +55,17 @@ Ask yourself: does the user already have the data in hand?
49
55
 
50
56
  **How:**
51
57
  ```
52
- read-table({
58
+ sas-score-read-table({
53
59
  table: "tablename",
54
60
  lib: "libraryname",
55
- server: "cas" or "sas", // determined from find-table check
61
+ server: "cas" or "sas", // determined from sas-score-find-table check
56
62
  limit: N, // default 10, adjust based on user request
57
63
  where: "..." // optional SQL WHERE clause
58
64
  })
59
65
  ```
60
66
 
61
67
  **Rules:**
62
- - Always determine the server first using `find-table`
68
+ - Always determine the server first using `sas-score-find-table`
63
69
  - Keep batch size ≤ 50 rows unless the user explicitly requests more
64
70
  - If table name is missing, ask: *"Which table should I read from? (format: lib.tablename)"*
65
71
  - If library is missing, ask: *"Which library contains the table?"*
@@ -85,7 +91,7 @@ sas-query({
85
91
  ```
86
92
 
87
93
  **Rules:**
88
- - Check which server(s) contain the table using `find-table` first
94
+ - Check which server(s) contain the table using `sas-score-find-table` first
89
95
  - If table exists in both CAS and SAS, ask user which to query from
90
96
  - Parse the user's natural language question into a PROC SQL SELECT statement
91
97
  - Ensure SELECT statement is valid SQL syntax
@@ -100,22 +106,22 @@ sas-query({
100
106
  **Pattern A — Raw row retrieval**
101
107
  > "Show me the first 5 rows from Public.customers"
102
108
 
103
- → `read-table({ table: "customers", lib: "Public", limit: 5 })`
109
+ → `sas-score-read-table({ table: "customers", lib: "Public", limit: 5 })`
104
110
 
105
111
  **Pattern B — Filtered retrieval**
106
112
  > "Get all high-value orders (amount > 5000) from mylib.orders"
107
113
 
108
- → `read-table({ table: "orders", lib: "mylib", where: "amount > 5000" })`
114
+ → `sas-score-read-table({ table: "orders", lib: "mylib", where: "amount > 5000" })`
109
115
 
110
116
  **Pattern C — Aggregation**
111
117
  > "What is the average price by make in Public.cars?"
112
118
 
113
- → `sas-query({ table: "Public.cars", query: "average price by make", sql: "SELECT make, AVG(msrp) AS avg_price FROM Public.cars GROUP BY make" })`
119
+ → `sas-score-sas-query({ table: "Public.cars", query: "average price by make", sql: "SELECT make, AVG(msrp) AS avg_price FROM Public.cars GROUP BY make" })`
114
120
 
115
121
  **Pattern D — Join + analysis**
116
122
  > "Show me total sales by customer in the sales and customers tables"
117
123
 
118
- → `sas-query()` with a JOIN in the generated SQL
124
+ → `sas-score-sas-query()` with a JOIN in the generated SQL
119
125
 
120
126
  ---
121
127
 
@@ -123,16 +129,23 @@ sas-query({
123
129
 
124
130
  | Problem | Action |
125
131
  |---|---|
126
- | Table not found in either server | Inform user and ask: *"Which library contains this table? (e.g., Public, Samples, mylib)"* |
132
+ | Library not found | Use `sas-find-library-smart` skill to verify the library exists |
133
+ | Table not found in either server | Inform user and suggest checking the table name |
127
134
  | Table exists in both CAS and SAS | Ask: *"The table exists in both servers. Which would you prefer: CAS or SAS?"* |
128
135
  | Table exists only in one server | Use that server automatically in your request |
129
- | Library not found | Inform user and ask to verify the library name |
130
136
  | Table name missing entirely | Ask: *"Which table should I read from?"* |
131
137
  | Ambiguous intent (raw vs aggregate) | Ask: *"Do you want individual rows or a summary by some field?"* |
132
138
  | Empty result | Inform user, ask to adjust filter or query |
133
139
 
134
140
  ---
135
141
 
142
+ ## Integration with other skills
143
+
144
+ - **Before this skill**: Use `sas-find-library-smart` to verify and locate the library
145
+ - **After this skill**: Use `sas-read-and-score` to score the retrieved data
146
+
147
+ ---
148
+
136
149
  ## Next steps
137
150
 
138
151
  Once data is retrieved, typical follow-ups include: