@sassoftware/sas-score-mcp-serverjs 1.0.1-3 → 1.0.1-31

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 (96) hide show
  1. package/.skills/agents/sas-score-mcp-serverjs-agent.md +190 -0
  2. package/.skills/copilot-instructions.md +241 -0
  3. package/.skills/skills/README.md +125 -0
  4. package/.skills/skills/detail-strategy/SKILL.md +272 -0
  5. package/.skills/skills/find-resources/SKILL.md +155 -0
  6. package/.skills/skills/list-resource/SKILL.md +258 -0
  7. package/.skills/skills/read-strategy/SKILL.md +137 -0
  8. package/.skills/skills/request-routing/SKILL.md +107 -0
  9. package/.skills/skills/score-strategy/SKILL.md +231 -0
  10. package/README.md +96 -54
  11. package/cli.js +37 -27
  12. package/openApi.yaml +121 -121
  13. package/package.json +14 -14
  14. package/scripts/docs/oauth-http-transport.md +2 -2
  15. package/scripts/refreshtoken.js +58 -0
  16. package/src/createMcpServer.js +0 -1
  17. package/src/expressMcpServer.js +47 -49
  18. package/src/oauthHandlers/authorize.js +4 -1
  19. package/src/oauthHandlers/baseUrl.js +4 -0
  20. package/src/oauthHandlers/callback.js +5 -1
  21. package/src/oauthHandlers/getMetadata.js +4 -0
  22. package/src/oauthHandlers/index.js +4 -0
  23. package/src/oauthHandlers/token.js +4 -0
  24. package/src/openApi.yaml +121 -121
  25. package/src/processHeaders.js +10 -7
  26. package/src/setupSkills.js +12 -7
  27. package/src/toolHelpers/_findJob.js +12 -0
  28. package/src/toolHelpers/_findJobdef.js +10 -0
  29. package/src/toolHelpers/_findLibrary.js +10 -0
  30. package/src/toolHelpers/_findModel.js +12 -0
  31. package/src/toolHelpers/_findTable.js +10 -0
  32. package/src/toolHelpers/_listJobs.js +2 -1
  33. package/src/toolHelpers/_listLibrary.js +1 -1
  34. package/src/toolHelpers/_listTables.js +1 -1
  35. package/src/toolHelpers/getLogonPayload.js +2 -2
  36. package/src/toolSet/devaScore.js +61 -61
  37. package/src/toolSet/findJob.js +2 -1
  38. package/src/toolSet/findJobdef.js +7 -7
  39. package/src/toolSet/findLibrary.js +68 -68
  40. package/src/toolSet/findModel.js +2 -2
  41. package/src/toolSet/findTable.js +2 -2
  42. package/src/toolSet/jobInfo.js +59 -0
  43. package/src/toolSet/jobdefInfo.js +59 -0
  44. package/src/toolSet/listJobdefs.js +61 -61
  45. package/src/toolSet/listJobs.js +61 -61
  46. package/src/toolSet/listLibraries.js +78 -78
  47. package/src/toolSet/listModels.js +56 -56
  48. package/src/toolSet/listTables.js +66 -66
  49. package/src/toolSet/makeTools.js +3 -0
  50. package/src/toolSet/modelInfo.js +1 -1
  51. package/src/toolSet/modelScore.js +23 -25
  52. package/src/toolSet/readTable.js +63 -63
  53. package/src/toolSet/runCasProgram.js +21 -10
  54. package/src/toolSet/runJob.js +15 -19
  55. package/src/toolSet/runJobdef.js +15 -19
  56. package/src/toolSet/runMacro.js +82 -82
  57. package/src/toolSet/sasQuery.js +77 -77
  58. package/src/toolSet/scrScore.js +60 -69
  59. package/src/toolSet/setContext.js +65 -65
  60. package/src/toolSet/superstat.js +61 -61
  61. package/src/toolSet/tableInfo.js +58 -58
  62. package/.skills_claude/README.md +0 -303
  63. package/.skills_claude/TESTING_GUIDE.md +0 -252
  64. package/.skills_claude/agents/sas-viya-scoring-expert.md +0 -58
  65. package/.skills_claude/claude-desktop-config.json +0 -16
  66. package/.skills_claude/claude-desktop-system-prompt.md +0 -127
  67. package/.skills_claude/copilot-instructions.md +0 -155
  68. package/.skills_claude/instructions.md +0 -184
  69. package/.skills_claude/skills/sas-find-library-smart/SKILL.md +0 -157
  70. package/.skills_claude/skills/sas-find-resource-strategy/SKILL.md +0 -105
  71. package/.skills_claude/skills/sas-list-resource-strategy/SKILL.md +0 -124
  72. package/.skills_claude/skills/sas-list-tables-smart/SKILL.md +0 -126
  73. package/.skills_claude/skills/sas-read-and-score/SKILL.md +0 -112
  74. package/.skills_claude/skills/sas-read-strategy/SKILL.md +0 -154
  75. package/.skills_claude/skills/sas-request-classifier/SKILL.md +0 -69
  76. package/.skills_claude/skills/sas-score-workflow/SKILL.md +0 -200
  77. package/.skills_claude/skills-index.md +0 -345
  78. package/.skills_github/agents/sas-viya-scoring-expert.md +0 -58
  79. package/.skills_github/copilot-instructions.md +0 -177
  80. package/.skills_github/skills/sas-find-library-smart/SKILL.md +0 -155
  81. package/.skills_github/skills/sas-find-resource-strategy/SKILL.md +0 -105
  82. package/.skills_github/skills/sas-list-resource-strategy/SKILL.md +0 -124
  83. package/.skills_github/skills/sas-list-tables-smart/SKILL.md +0 -128
  84. package/.skills_github/skills/sas-read-and-score/SKILL.md +0 -113
  85. package/.skills_github/skills/sas-read-strategy/SKILL.md +0 -154
  86. package/.skills_github/skills/sas-request-classifier/SKILL.md +0 -74
  87. package/.skills_github/skills/sas-score-workflow/SKILL.md +0 -314
  88. package/scripts/optimize_final.py +0 -140
  89. package/scripts/optimize_tools.py +0 -99
  90. package/scripts/setup-skills.js +0 -34
  91. package/scripts/update_descriptions.py +0 -46
  92. package/src/authpkce.js +0 -219
  93. package/src/handleGetDelete.js +0 -34
  94. package/src/handleRequest.js +0 -112
  95. package/src/hapiMcpServer.js +0 -241
  96. package/src/toolSet/.claude/settings.local.json +0 -13
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: read-strategy
3
+ description: >
4
+ Strategy for reading data from CAS or SAS tables. Determines which read tool to use (raw reads vs analytical queries).
5
+ ---
6
+
7
+ # Read Table Strategy
8
+
9
+ Use this strategy when the user requests to read, fetch, or query data from a table.
10
+
11
+ ## Prerequisites
12
+
13
+ Before reading:
14
+ 1. Verify the table exists using find-resource strategy
15
+ 2. Determine the server (CAS or SAS) from the find-resource verification step. If the server cannot be determined, ask the user to specify. Do not proceed with a default server unless explicitly instructed by the user.
16
+
17
+ ---
18
+
19
+ ## Two Types of Read Operations
20
+
21
+ ### Type 1: Raw Row Read
22
+
23
+ **Trigger phrases**: "read rows from", "show first N records", "fetch records where", "get data from table"
24
+
25
+ **Tool**: `sas-score-read-table`
26
+
27
+ **When to use**:
28
+ - User wants raw records, not aggregations
29
+ - User wants to filter by WHERE clause
30
+ - User wants to browse data
31
+
32
+ **Parameters**:
33
+ ```
34
+ lib: "<library>" # from find-resource verification
35
+ table: "<table>" # from find-resource verification
36
+ server: "cas" or "sas" # from find-resource verification
37
+ start: <row number> # default 1
38
+ limit: <max rows> # default 10, max 1000
39
+ where: "<SQL WHERE clause>" # optional filter
40
+ format: true # default: use formatted values
41
+ ```
42
+
43
+ **Example**:
44
+ ```
45
+ sas-score-read-table({
46
+ lib: "Public",
47
+ table: "customers",
48
+ server: "cas",
49
+ limit: 25,
50
+ where: "status='active'"
51
+ })
52
+ ```
53
+
54
+ ---
55
+
56
+ ### Type 2: Analytical Query
57
+
58
+ **Trigger phrases**: "how many", "count by", "average", "total", "sum", "group by", "aggregate", "distinct", "join"
59
+
60
+ **Tool**: `sas-score-sas-query`
61
+
62
+ **When to use**:
63
+ - User wants aggregations (SUM, AVG, COUNT, etc.)
64
+ - User wants GROUP BY or distinct counts
65
+ - User wants JOIN across tables
66
+ - User wants statistical summaries
67
+
68
+ **Parameters**:
69
+ ```
70
+ table: "lib.table" # CAS: "Public.customers", SAS: "SASHELP.cars"
71
+ query: "<natural language question>"
72
+ sql: "<SELECT SQL>" # optional: pre-generated SQL
73
+ ```
74
+
75
+ **Example**:
76
+ ```
77
+ sas-score-sas-query({
78
+ table: "Public.customers",
79
+ query: "count of customers by region and status",
80
+ sql: "SELECT region, status, COUNT(*) as count FROM Public.customers GROUP BY region, status"
81
+ })
82
+ ```
83
+
84
+ ---
85
+
86
+
87
+ ## Decision Tree
88
+
89
+ ```
90
+ User requests data from table
91
+
92
+ Is it an aggregation? (count, sum, avg, group by, distinct, etc.)
93
+ ├─ YES → Use sas-score-sas-query
94
+ └─ NO → Use sas-score-read-table
95
+
96
+ If the user's intent is ambiguous or mixes aggregation and raw reads, ask the user to clarify whether they want raw records or aggregated results before proceeding.
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Table Name Format
102
+
103
+ - **CAS tables**: `Caslib.table` or `Public.customers` (lowercase caslib, mixed case table)
104
+ - **SAS tables**: `LIBREF.table` or `SASHELP.cars` (uppercase libref, case-insensitive table)
105
+
106
+ ---
107
+
108
+ ## Error Handling
109
+
110
+ | Error | Action |
111
+ |---|---|
112
+ | Table not found | Verify table exists with find-resource first |
113
+ | Server mismatch | Use server from find-resource verification |
114
+ | Empty result | Ask user to adjust WHERE clause or criteria |
115
+ | Column not found | Ask user to verify column name (case sensitivity) |
116
+
117
+ ---
118
+
119
+ ## Examples
120
+
121
+ ### Example 1: Browse customer records
122
+ **Request**: "read first 20 customers from Public"
123
+ 1. Find table customers in Public → CAS
124
+ 2. Read: `sas-score-read-table({ lib: "Public", table: "customers", server: "cas", limit: 20 })`
125
+ 3. Return 20 rows
126
+
127
+ ### Example 2: Find active customers in a region
128
+ **Request**: "fetch customers from Public where status='active' and region='East'"
129
+ 1. Find table customers in Public → CAS
130
+ 2. Read: `sas-score-read-table({ lib: "Public", table: "customers", server: "cas", where: "status='active' and region='East'" })`
131
+ 3. Return matching rows
132
+
133
+ ### Example 3: Aggregate customers by region
134
+ **Request**: "how many customers by region in Public.customers"
135
+ 1. Find table customers in Public → CAS
136
+ 2. Query: `sas-score-sas-query({ table: "Public.customers", query: "count of customers by region", sql: "SELECT region, COUNT(*) FROM Public.customers GROUP BY region" })`
137
+ 3. Return aggregated result
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: request-routing
3
+ description: >
4
+ Universal routing strategy for all SAS Viya requests. Every request follows the same three-step workflow.
5
+ ---
6
+
7
+ # Universal Request Routing Strategy
8
+
9
+ All SAS Viya requests follow this three-step workflow:
10
+
11
+ ## Step 1: Verify Resources Exist
12
+
13
+ Before executing any action, verify that the target resources exist.
14
+
15
+ | Resource Type | Find Tool | Notes |
16
+ |---|---|---|
17
+ | Library | `sas-score-find-library` | For tables, if server is not specified (cas or sas), determine server here. Other resource types do not require server specification. |
18
+ | Table | `sas-score-find-table` | Requires library name and server. |
19
+ | MAS Model | `sas-score-find-model` | No server selection. |
20
+ | Job | `sas-score-find-job` | No server selection. |
21
+ | JobDef | `sas-score-find-jobdef` | No server selection. |
22
+ | SCR Model | Skip verification | SCR models do not require pre-verification. |
23
+
24
+ **Rule**: Always verify before executing. Exception: SCR models can be scored directly.
25
+
26
+ ---
27
+
28
+ ## Step 2: Execute the Request
29
+
30
+ Once resources are verified to exist, select the appropriate execution tool:
31
+
32
+ | Request Type | Tool | Input |
33
+ |---|---|---|
34
+ | Read table rows | `sas-score-read-table` | lib, table, server (from Step 1) |
35
+ | Query table (aggregation) | `sas-score-sas-query` | lib.table, SQL query |
36
+ | Score with MAS model | `sas-score-mas-score` | model name, scenario data |
37
+ | Run Job | `sas-score-run-jobdef` | job name, scenario parameters |
38
+ | Run JobDef | `sas-score-run-jobdef` | jobdef name, scenario parameters |
39
+ | Score with SCR model | `sas-score-scr-score` | SCR URL, scenario data |
40
+ | Describe MAS model | `sas-score-model-info` | model name |
41
+ | Describe Job/JobDef | `sas-score-job-info` | job or jobdef name |
42
+ | Describe SCR model | `sas-score-scr-info` | SCR URL |
43
+ | Describe table | `sas-score-table-info` | lib, table, server |
44
+
45
+ ---
46
+
47
+ ## Step 3: Merge Results
48
+
49
+ Combine verification and execution results:
50
+
51
+ - For **read/query**: Return rows as-is.
52
+ - For **scoring**: Merge predictions with input scenario data.
53
+ - For **jobs/jobdefs**: Return execution results (tables, logs).
54
+
55
+ ---
56
+
57
+
58
+ ## Special Case: Read + Score (Combined Workflow)
59
+
60
+ When the user requests scoring records from a table, follow these sub-workflows in order:
61
+
62
+ 1. **Verify**
63
+ - Find the table (determine server as described above)
64
+ - Find the model
65
+ 2. **Read**
66
+ - Fetch rows from the table using `sas-score-read-table` or `sas-score-sas-query`
67
+ 3. **Map**
68
+ - Check if table columns match model input variables
69
+ - If not, ask user for mapping
70
+ 4. **Score**
71
+ - Score each row using `sas-score-mas-score` (for MAS) or `sas-score-scr-score` (for SCR)
72
+ 5. **Merge**
73
+ - Combine predictions with original rows
74
+
75
+ ---
76
+
77
+ ## Error Handling
78
+
79
+ | Error | Action |
80
+ |---|---|
81
+ | Resource not found | Ask user to verify name and server (for tables). |
82
+ | Column/input mismatch | Ask user to map table columns to model inputs. |
83
+ | Empty result | Ask whether to adjust filter/criteria. |
84
+
85
+ ---
86
+
87
+ ## Examples
88
+
89
+ ### Example 1: Read a table
90
+ **Request**: "read customers in Public"
91
+ 1. Find library Public → Verified (CAS)
92
+ 2. Read table customers in Public (CAS)
93
+ 3. Return rows
94
+
95
+ ### Example 2: Score with inline scenario
96
+ **Request**: "score a=1, b=2 with model simplejob.job"
97
+ 1. Find job simplejob → Verified
98
+ 2. Run simplejob with scenario {a: 1, b: 2}
99
+ 3. Return result
100
+
101
+ ### Example 3: Score records from table
102
+ **Request**: "score records from Public.customers with model risk_model.mas"
103
+ 1. Find table customers in Public → Verified (CAS)
104
+ 2. Find model risk_model → Verified (MAS)
105
+ 3. Read rows from Public.customers
106
+ 4. Score each row with risk_model
107
+ 5. Return merged predictions + original data
@@ -0,0 +1,231 @@
1
+ ---
2
+ name: score-strategy
3
+ description: >
4
+ Unified scoring workflow. Handles MAS, Job, JobDef, SCR, and combined read+score scenarios.
5
+ Always verify resources before scoring.
6
+
7
+ To reduce cognitive load, follow the stepwise flowchart below for scoring requests.
8
+ ---
9
+
10
+ # Score Strategy
11
+
12
+ Use this strategy when the user requests model scoring, predictions, or running jobs/jobdefs.
13
+
14
+ ## Prerequisites
15
+
16
+ 1. Verify the model/job exists using find-resources skill
17
+ 2. If scoring table rows: Verify the table exists and determine server using find-resources skill
18
+ 3. If scoring with inline scenario: Parse the scenario data
19
+
20
+ ---
21
+
22
+
23
+ ## Step 1: Parse the Score Request
24
+
25
+ Identify the scoring target (model type) and input source:
26
+
27
+ ### Identify Model Type
28
+
29
+ ```
30
+ score with model X.mas → MAS model
31
+ score with model X.job → Job
32
+ score with model X.jobdef → JobDef
33
+ score with model X.scr → SCR model
34
+ score with model X (default to MAS if type is not specified) → MAS model
35
+ ```
36
+
37
+ ### Visual Flowchart
38
+
39
+ ```mermaid
40
+ flowchart TD
41
+ A[User score request] --> B{Model type specified?}
42
+ B -- .mas --> C[MAS model]
43
+ B -- .job --> D[Job]
44
+ B -- .jobdef --> E[JobDef]
45
+ B -- .scr --> F[SCR model]
46
+ B -- none --> C
47
+ C --> G[Verify MAS model]
48
+ D --> H[Verify Job]
49
+ E --> I[Verify JobDef]
50
+ F --> J[Skip verification]
51
+ ```
52
+
53
+ ### Identify Input Source
54
+
55
+ ```
56
+ score a=1, b=2 → Inline scenario
57
+ score with scenario {...} → Inline scenario
58
+ score records from table X → Table rows
59
+ score results of query... → Query results
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Step 2: Execute Scoring
65
+
66
+ ### Option A: Score with Inline Scenario
67
+
68
+ **Trigger phrases**: "score a=1, b=2", "predict with values", "score scenario"
69
+
70
+ **Tools**:
71
+ - MAS: `sas-score-mas-score`
72
+ - Job: `sas-score-run-job`
73
+ - JobDef: `sas-score-run-jobdef`
74
+ - SCR: `sas-score-scr-score`
75
+
76
+ **Flow**:
77
+ 1. Find model (find-resources)
78
+ 2. Score with inline data
79
+ 3. Return prediction + input data merged
80
+
81
+ **Parameters** (MAS):
82
+
83
+ ```
84
+ sas-score-mas-score({
85
+ model: "<model name>",
86
+ scenario: { a: 1, b: 2 }
87
+ })
88
+ ```
89
+
90
+ **Parameters** (job):
91
+ ```
92
+ sas-score-run-job({
93
+ name: "<job name>",
94
+ scenario: { a: 1, b: 2 }
95
+ })
96
+ ```
97
+
98
+ **Parameters** (jobdef):
99
+ ```
100
+ sas-score-run-jobdef({
101
+ name: "<jobdef name>",
102
+ scenario: { a: 1, b: 2 }
103
+ })
104
+ ```
105
+
106
+ **Parameters** (SCR):
107
+ ```
108
+ sas-score-scr-score({
109
+ url: "<scr endpoint>",
110
+ scenario: { a: 1, b: 2 }
111
+ })
112
+ ```
113
+
114
+ ---
115
+
116
+ ### Option B: Score Table Rows (Read + Score)
117
+
118
+ **Trigger phrases**: "score records from", "run model on table", "predict for customers in", "score rows from"
119
+
120
+ **Flow**:
121
+ 1. Find model (find-resources)
122
+ 2. Find table (find-resources) → get server
123
+ 3. Read rows from table (read-strategy)
124
+ 4. Score each row (or batch score)
125
+ 5. Merge predictions with original rows
126
+
127
+ **Decision**: Read strategy first
128
+ - If user requests aggregation: Use `sas-score-sas-query`
129
+ - If user requests raw rows: Use `sas-score-read-table`
130
+
131
+ **Example workflow**:
132
+ ```
133
+ Request: "score records from Public.customers with model risk_model"
134
+
135
+ 1. Find table customers in Public → CAS
136
+ 2. Find model risk_model → MAS
137
+ 3. Read rows: sas-score-read-table({ lib: "Public", table: "customers", server: "cas", limit: 1000 })
138
+ 4. Score each row: for each row, sas-score-mas-score({ model: "risk_model", scenario: {row} })
139
+ 5. Merge: combine risk score with customer data
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Step 3: Result Formatting
145
+
146
+ ### MAS Scoring Result
147
+
148
+ Return merged object:
149
+ ```
150
+ Input data + Prediction fields
151
+ Example: { a: 1, b: 2, prediction: 0.85, probability_0: 0.15, probability_1: 0.85 }
152
+ ```
153
+
154
+ ### Job/JobDef Result
155
+
156
+ Return execution output:
157
+ ```
158
+ Tables, logs, listings as returned by job
159
+ ```
160
+
161
+ ### SCR Result
162
+
163
+ Return merged object:
164
+ ```
165
+ Input data + Prediction fields from SCR response
166
+ ```
167
+
168
+ ### Batch Scoring (Table Rows)
169
+
170
+ Return rows with predictions appended:
171
+ ```
172
+ [
173
+ { customer_id: 1, name: "Alice", ..., risk_score: 0.32 },
174
+ { customer_id: 2, name: "Bob", ..., risk_score: 0.78 },
175
+ ...
176
+ ]
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Column/Variable Mapping
182
+
183
+ If table columns don't match model input variable names:
184
+
185
+ 1. Ask user: "Which table column maps to model input X?"
186
+ 2. Wait for mapping: e.g., { customer_age: age, customer_income: income }
187
+ 3. Transform row data using mapping
188
+ 4. Score transformed data
189
+ 5. Return with original column names
190
+
191
+ ---
192
+
193
+ ## Error Handling
194
+
195
+ | Error | Action |
196
+ |---|---|
197
+ | Model not found | Verify model name with user |
198
+ | Table not found | Verify table name and library |
199
+ | Scenario mismatch | Ask user to verify input variable names |
200
+ | Empty table | Ask whether to adjust filter or continue |
201
+ | Scoring failure | Return error message from scoring tool |
202
+
203
+ ---
204
+
205
+ ## Examples
206
+
207
+ ### Example 1: Score with inline scenario
208
+ **Request**: "score a=1, b=2 with model simplejob.job"
209
+ 1. Find job simplejob using find-resources strategy
210
+ 2. Run: `sas-score-run-jobdef({ name: "simplejob", scenario: { a: 1, b: 2 } })`
211
+ 3. Return: `{ c: 3 }`
212
+
213
+ ### Example 2: Score with MAS model
214
+ **Request**: "predict churn for age=45, income=60000 with model churn_predictor"
215
+ 1. Find model churn_predictor.mas using find-resources strategy
216
+ 2. Score: `sas-score-mas-score({ model: "churn_predictor", scenario: { age: 45, income: 60000 } })`
217
+ 3. Return: `{ age: 45, income: 60000, churn_probability: 0.23, prediction: "no_churn" }`
218
+
219
+ ### Example 3: Score table rows
220
+ **Request**: "score all active customers with model risk_model and table Public.customers"
221
+ 1. Find model risk_model.mad using find-resources strategy
222
+ 2. Find table Public.customers using find-resources strategy
223
+ 3. Read: `sas-score-read-table({ lib: "Public", table: "customers", server: "cas", where: "status='active'" })`
224
+ 4. Score each row with risk_model
225
+ 5. Return: customers with risk_score appended
226
+
227
+ ### Example 4: Score with SCR model
228
+ **Request**: "score age=50, income=75000 with model loan.scr"
229
+ 1. Prepare: SCR URL for "loan"
230
+ 2. Score: `sas-score-scr-score({ url: "loan", scenario: { age: 50, income: 75000 } })`
231
+ 3. Return predictions from SCR endpoint
package/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # sas-score-mcp-serverjs
2
- A Model Context Protocol (MCP) Server for Scoring with SAS Viya
2
+ A Model Context Protocol (MCP) Server for Scoring with SAS Viya.
3
+ See [wiki](https://github.com/sassoftware/sas-score-mcp-serverjs/wiki) for the capabilities of the server.
3
4
 
4
5
  ## Major changes in release 1.0.0
5
6
 
@@ -8,6 +9,8 @@ A Model Context Protocol (MCP) Server for Scoring with SAS Viya
8
9
 
9
10
  - Agent - can be deployed as an agent
10
11
 
12
+ - Docker image: ghcr.io/sassoftware/sas-score-mcp-serverjs
13
+
11
14
 
12
15
  ## Overview
13
16
  This MCP server is designed for scoring with SAS Viya.
@@ -22,6 +25,33 @@ Some examples are:
22
25
  - job Definitions
23
26
  - jobs using SAS Studio or other interfaces
24
27
 
28
+ ## Start the mcp server
29
+
30
+ If using stdio transport, most of the mcp clients will start the server automatically.
31
+ But for http transport, the mcp server must be started.
32
+
33
+ If running locally
34
+ ```sh
35
+ npx @sassoftware/sas-score-mcp-serverjs@latest
36
+ ```
37
+
38
+ The mcp is also available as a docker image. Add or remove the env variables as needed.
39
+
40
+ ```sh
41
+ docker run -p 8080:8080 --name sasscore -e VIYA_SERVER=<yourviyaserver> -e AUTHFLOW=oauth ghcr.io/sassoftware/sas-score-mcp-serverjs:latest
42
+ ```
43
+
44
+ ## Capabilities
45
+
46
+ The tools can be grouped into these categories
47
+
48
+ - Scoring with MAS models, job, jobdef and scr
49
+ - Viewing and querying tables
50
+
51
+ Supporting tools can be grouped into these categories
52
+ - Listing of MAS models, job, jobdef , tables
53
+ - Describing MAS models, job, jobdef, scr and tables
54
+
25
55
  ## Target Audience
26
56
  This MCP server was developed for two types of SAS users.
27
57
 
@@ -44,88 +74,102 @@ Typically these are set either in the .env file or as environment variables or a
44
74
 
45
75
  ### Required Options
46
76
 
47
- VIYA_SERVER=<url for Viya server>
48
- MCPTYPE=http|stdio
49
- MCPHOST=<url for the mcp server = http://localhost:8080 or some remote mcp server>
77
+ 1. VIYA_SERVER=
78
+ <url for Viya server>.
50
79
 
51
- >Recommended authflow is oauth - the most secure of all the options since all oauth flow occurs in the server and the actual token is never sent to the client. Bearer authflow is useful when the mcp server is remote with its own authentication process
80
+ ### Options with defaults
52
81
 
53
- AUTHFLOW=oauth|oauthclient|bearer|sascli|token|password
82
+ These can be customized
54
83
 
55
- > Options for oauth. The clientid must have a redirect of http://localhost:8080/callback,https://localhost:8080/callback
84
+ 1. AUTHFLOW=**oauth**|oauthclient|bearer|sascli|token|password
85
+ - Authentication method. Default is oauth
56
86
 
57
- CLIENTID=<pkce clientid>
87
+ 2. CLIENTID=**vscodemcp**
88
+ - Clientid for oauth and oauthclient AUTHFlOW. Must be PKCE clientid.
89
+
58
90
 
91
+ 3. MCPTYPE=**http**|stdio
92
+ - The transport protocol for the mcp server.
59
93
 
60
- > OauthClient Flow. Clientid with redirect appropriate for the client. Some examples are shown below. Note that the explicit port used by github copilot is not guaranteed.
94
+ 4. MCPHOST=**http://localhost:8080**
95
+ - URL of the mcp server. If using remote mcp server, set this to remote MCP server
61
96
 
62
- - github copilot: http://127.0.0.1:33418/
63
- - claude: https://claude.ai/api/mcp/auth_callback,https://claude.ai/api/auth/callback
97
+ 5. PROFILE=**~/.sas**
98
+ - profile name used by sas-cli to store the tokens
64
99
 
65
- > bearer - Use this when the remote mcp server sends the token in the header.
100
+ 6. PORT=**8080**
101
+ - set it to what fits your environment.
66
102
 
103
+ 7. CASSERVER=**cas-shared-default**
104
+ - Set to a valid cas server
67
105
 
68
- > sascli - Use sas-viya cli to create the token information. It is stored in ~/.sas folder by default
106
+ 8. COMPUTECONTEXT=**"SAS Job Execution compute context"**
107
+ - Use one that is appropriate
69
108
 
70
- ```env
71
- PROFILE=<profile name used by sas-cli to store the tokens in ~/.sas>
72
- ```
109
+ ### Clientid specifications
73
110
 
74
- ### Other options
111
+ If using remote mcp server, change the url in redirect to the remote url
75
112
 
76
- ```env
77
- PORT=<default is 8080>
78
- HTTPS=FALSE
79
- CASSERVER=CAS server name (default: cas-shared-default)
80
- COMPUTECONTEXT=Compute session name or context (default: SAS Job Execution compute context)
113
+ ```js
114
+ {
115
+ client_id: 'vscodemcp',
116
+ scope: [ 'openid' ],
117
+ resource_ids: [ 'none' ],
118
+ autoapprove: true,
119
+ authorized_grant_types: [ 'authorization_code' ],
120
+ access_token_validity: 86400,
121
+ allowpublic: true,
122
+ redirect_uri: [ 'http://localhost:8080/callback' ]
123
+ }
81
124
  ```
82
125
 
83
- ## Agent
126
+ > OauthClient Flow. Clientid with redirect appropriate for the client. Some examples are shown below. Note that the explicit port used by github copilot is not guaranteed.
127
+
128
+ - github copilot: http://127.0.0.1:33418/
129
+ - claude: https://claude.ai/api/mcp/auth_callback,https://claude.ai/api/auth/callback
84
130
 
85
- > The mcp server can be deployed as an agent in github copilot
86
- > The configuration files for claude can be installed locally. You have to move the files to the appriopiate place.
87
131
 
88
- Specify the following configuration values to enable agent mode
132
+ ## Agent and skills
89
133
 
90
- ```env
91
- AGENT=TRUE
92
- MCPCLIENT=github|claude
93
- ```
134
+ > The mcp server can be deployed as an agent in github copilot
135
+ > The configuration files for claude can be installed locally. You have to move the files to the appriopiate place.
94
136
 
95
- By default the agent information is installed in the user's home directory as .github or .claude} To install it where the mcp server is running do the following:
137
+ To download the skills to your environment issue this command:
96
138
 
97
- ```env
98
- MCPCLIENT=.github|.claude
139
+ ```sh
140
+ npx @sassoftware/sas-score-mcp-serverjs --skills github|claude
99
141
  ```
142
+ The skills and related files will be written to .github or .claude
100
143
 
101
144
 
102
145
  ## Configure the mcp client for localhost
103
146
 
104
- The mcp configuration is show below
147
+ The mcp configuration for oauth flow. For remote mcp, change the url to the
148
+ remote url
105
149
 
106
150
  ```json
107
151
  "sasmcp": {
108
152
  "type": "http",
109
- "url": "http://localhost:8080/mcp"``
153
+ "url": "http://localhost:8080/mcp"
110
154
  "oauth: {
111
- "type": "oauth2"
155
+ "type": "oauth2",
156
+ "clientId: "vscodemcp"
112
157
  }
113
158
  }
114
159
  ```
115
160
 
116
- For remote mcp servers:
161
+ For bearer authflow.
117
162
  ```json
118
163
  "sasmcp": {
119
164
  "type": "http",
120
- "url": "your remote mcp server`,
121
- "oauth": {
122
- "type": 'oauth2
123
- }
165
+ "url": "http://localhost:8080/mcp`,
166
+ "headers" {
167
+ "Authorization": "bearer <tokenstring>"
168
+ }
124
169
  }
125
170
  ```
126
171
 
127
- For transport protocol stdio. For claude drop the type
128
-
172
+ For stdio scenario
129
173
  ```json
130
174
  "sas-mcp-server": {
131
175
  "type: "stdio"
@@ -141,17 +185,7 @@ For transport protocol stdio. For claude drop the type
141
185
  }
142
186
  ```
143
187
 
144
- #### Step 2: Start the mcp server
145
188
 
146
- If using stdio transport, most of the mcp clients will start the server automatically.
147
- But this step is necessary of using http transport.
148
-
149
-
150
- ```sh
151
- npx @sassoftware/sas-score-mcp-serverjs@latest
152
- ```
153
-
154
- Make sure that the .env file is in the current working directory or specify the options in the command line
155
189
 
156
190
 
157
191
  ## Notes
@@ -196,7 +230,15 @@ NODE_EXTRA_CA_CERTS=c:\Users\<your_username>\AppData\Local\mkcert\rootCA.pem
196
230
  ```
197
231
 
198
232
  ## License
199
- This project is licensed under the [Apache 2.0 license](LICENSE).
233
+ This project is licensed under the Apache License 2.0. See [LICENSE](LICENSE).
234
+
235
+ The container image published from this repository also includes third-party software, each component under its own license:
236
+
237
+ - The npm dependencies that ship with this project, along with their respective licenses, are listed in [LICENSES.json](LICENSES.json).
238
+ - The container is built from the 25-alpine base image; license texts for its included software ship inside the image itself. License information for each Alpine package is available at [pkgs.alpinelinux.org](https://pkgs.alpinelinux.org/packages).
239
+
240
+ As with any container image, direct and indirect dependencies are governed by their own licenses.
241
+ Users of the published container image are responsible for ensuring that their use complies with all applicable licenses.
200
242
 
201
243
  ## Additional Resources
202
244