@sassoftware/sas-score-mcp-serverjs 1.0.1-0 → 1.0.1-2

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/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # sas-score-mcp-serverjs
2
2
  A Model Context Protocol (MCP) Server for Scoring with SAS Viya
3
3
 
4
+ ## Major changes in release 1.0.0
5
+
6
+ - Authentication: Oauth flow is now supported.
7
+ - Note that for Claude the mcp server must be remote. (ex: as a Azure Client App, Azure Container App etc...).
8
+
9
+ - Agent - can be deployed as an agent
10
+
11
+
4
12
  ## Overview
5
13
  This MCP server is designed for scoring with SAS Viya.
6
14
 
@@ -24,257 +32,114 @@ See this [quick reference](sas-mcp-tools-reference.md) for details.
24
32
  ### MCP tool developers
25
33
  SAS developers who want to extend the capabilities of the server with their own tools. See the [guide](tool-developer-guide.md) for details.
26
34
 
27
- ## Configuration Variables
28
- Typically these are set either in the .env file or as environment variables (or both). This is full list of the configuration variables used the mcp server. You will need only a subset of these for the different [transport,authentication] schemes
29
-
30
- ```env
31
-
32
- # Indicate what type of transport(stdio|http)
33
- # http is useful for remote mcp servers
34
- # If running locally, recommend stdio
35
-
36
- MCPTYPE=<stdio|http>
37
-
38
- # Port for http transport(default is 8080)
39
35
 
40
- PORT=8080
36
+ ## Transport Protocol supported
41
37
 
42
- # If transport is http, optionally specify if the server
43
- # is using http or https
38
+ - http
39
+ - stdio
44
40
 
45
- HTTPS=TRUE|FALSE
46
41
 
47
- # Viya Authentication
48
- # The mcp server support different ways to authenticate(see section on Authentication)
49
-
50
- # * sascli * will look for tokens created with sas-viya cli
51
- # * token * a custom token
52
- # * password * userid/password
53
- # * code * Oauth using authorization_code flow(pkce not supported in this release)
54
-
55
- AUTHFLOW=sascli|token|password|code
42
+ ## Configuration Variables
43
+ Typically these are set either in the .env file or as environment variables or as command line options(if using npx). You will need only a subset of these for the different [transport,authentication] schemes
56
44
 
57
- SAS_CLI_CONFIG=your-home-directory
58
- SAS_CLI_PROFILE=your-sas-cli-profile
45
+ ### Required Options
59
46
 
60
- # VIYA_SERVER URL for AUTHFLOW of token and password
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>
61
50
 
62
- VIYA_SERVER= your Viya server url
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
63
52
 
64
- # if AUTHFLOW=token, specify the file with the token
65
- TOKENFILE=
53
+ AUTHFLOW=oauth|oauthclient|bearer|sascli|token|password
66
54
 
67
- # if password flow or oauth flow specify these
68
- CLIENTID=
69
- CLIENTSECRET=
55
+ > Options for oauth. The clientid must have a redirect of http://localhost:8080/callback,https://localhost:8080/callback
70
56
 
71
- # specify this if password AUTHFLOW
72
- PASSWORD=
57
+ CLIENTID=<pkce clientid>
73
58
 
74
- # When HTTPS is TRUE, specify the folder with SSL certificates for the mcp server
75
- # All files in that folder will be loaded and used in the TLS connection
76
- # If not set and HTTPS is true, the server will create a self-signed certificate
77
59
 
78
- SSLCERT=<some folder>
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.
79
61
 
62
+ - github copilot: http://127.0.0.1:33418/
63
+ - claude: https://claude.ai/api/mcp/auth_callback,https://claude.ai/api/auth/callback
80
64
 
81
- # This certificate isused in the http calls to SAS Viya from MCP server
82
- # Used in restaf (ultimately axios and fetch)
83
- # All files in the folder will be loaded and used in the TLS connection
84
- # if not set, no ssl certificates will be used
85
- # See the script in scripts/getViyaca.sh to get this certificate from the SAS Viya server
65
+ > bearer - Use this when the remote mcp server sends the token in the header.
86
66
 
87
- VIYACERT=<some folder>
88
67
 
89
- # SAS Contexts
90
- # These are for the CAS and SAS sessions
91
- # Defaults are:
92
- COMPUTECONTEXT=SAS Job Execution compute context
93
- CASSERVER=cas-shared-default
68
+ > sascli - Use sas-viya cli to create the token information. It is stored in ~/.sas folder by default
94
69
 
70
+ ```env
71
+ PROFILE=<profile name used by sas-cli to store the tokens in ~/.sas>
95
72
  ```
96
73
 
97
- ## Authentication
98
- The server supports multiple ways to authenticate.
99
-
100
- ### sas-viya cli
101
-
102
- > Note: To use this, set `AUTHFLOW=sascli`
103
-
104
- This MCP server CLI works similar to SAS supplied sas-viya CLI commands.
105
- Use the following command to create the necessary token and refresh token.
106
-
107
- `create a default auth Profile`.
108
- Issue this command and follow instruction: `sas-viya profile init`
109
-
110
- `create token`
111
- Issue this command and follow the instructions: `sas-viya auth loginCode`
112
-
113
- You need to do this once every 90 days or whenever the refresh token expires.
114
-
115
- At this point the tools can make authenticated calls to SAS Viya.
116
-
117
- ### Password
118
-
119
- > Note: To use this, set `AUTHTYPE=password`
120
-
121
- Ths requires additional setup:
122
-
123
- - Create a clientid and client password for Oauth password flow.
124
- - Set these in the .env file or the mcp configuration file
125
-
126
- ### Custom token
127
-
128
- > Note: To use this, set `AUTHTYPE=token`
129
-
130
- Set the env TOKENFILE to a file containing the token.
131
-
132
- There seems to be a pattern of using a long-lived token.
133
- If this is your use case, set the TOKENFILE to a file containing this token.
134
-
135
- ### Oauth - (experimental) Authentication handled by the mcp server
136
-
137
- In this approach, the mcp client does not participate in the Oauth authentication process. It is handled by the mcp server at startup.
138
-
139
- > This is marked as experimental since the testing is not complete
140
-
141
- #### SAS viya setup.
142
-
143
- Create a Oauth client with the following properties
144
-
145
- ```js
146
- {
147
- auth flow: authorization_code|password
148
- clientid: <your client id>
149
- clientsecret: <some client secret - pkce not supported at this time>
150
- redirect: https://localhost:8080/mcpserver
151
- }
152
-
153
- #### Use an .env file as follows(sample values shown)
74
+ ### Other options
154
75
 
155
76
  ```env
156
- PORT=8080
157
- AUTHFLOW=code
158
- SSLCERT=c:\Users\kumar\.tls
159
- VIYACERT=c:\Users\kumar\viyaCert
160
- CAS_SERVER=cas-shared-default
161
- COMPUTECONTEXT=SAS Job Execution compute context
162
-
163
- PORT=8080
164
- HTTPS=true
165
- MCPTYPE=http
166
- USELOGON=FALSE
167
- USETOKEN=TRUE
168
- APPNAME=sas-score-mcp-serverjs
169
-
170
- CLIENTID=mcpserver
171
- CLIENTSECRET=xxxxxx
172
-
173
-
174
- # SAMESITE=Lax,secure
175
-
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)
176
81
  ```
177
82
 
178
- #### Usage
83
+ ## Agent
179
84
 
180
- Start the server with this command:
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.
181
87
 
182
- ```sh
183
- npx @sassoftware/sas-score-mcp-serverjs@latest
184
- ```
88
+ Specify the following configuration values to enable agent mode
185
89
 
186
- Then visit this site on your browser:
187
-
188
- ```sh
189
- https://localhost:8080/mcpserver
90
+ ```env
91
+ AGENT=TRUE
92
+ MCPCLIENT=github|claude
190
93
  ```
191
94
 
192
- You will be prompted to logon to SAS Viya.
193
- A dialog will be displayed if the logon was successful.
194
- Icon this window and proceed to your mcp client
195
-
196
-
197
- ## Transport Methods
198
- This server supports both stdio and http transport methods.
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:
199
96
 
200
- ### stdio transport
201
- This is ideal for running mcp servers locally.
202
- Most clients will autostart the mcp server for you.
203
-
204
- The env variables can be specified in two ways:
97
+ ```env
98
+ MCPCLIENT=.github|.claude
99
+ ```
205
100
 
206
- 1. As part of the mcp configuration as shown below.
207
- 2. Create a .env file and specify the env variables in that file.
208
101
 
102
+ ## Configure the mcp client for localhost
209
103
 
210
- > Note: You must set the MCPTYPE in the environment variable.
104
+ The mcp configuration is show below
211
105
 
212
106
  ```json
213
- "sasmcp": {
214
- "type": "stdio",
215
- "command": "npx",
216
- "args": [
217
- "-y",
218
- "@sassoftware/sas-score-mcp-serverjs@latest",
219
- ],
220
- "env": {
221
- "MCPTYPE": "stdio",
222
- "AUTHFLOW": "sascli", // sascli|password|token|none
223
- "SAS_CLI_PROFILE": "cli profile name or Default",
224
- "SAS_CLI_CONFIG":"where sas-cli stores authentication information",
225
- "SSLCERT": "where you have stored the tls information(see below)",
226
- "VIYACERT": "where you have stored the viya server ssl certificates for calls to Viya server",
227
- "VIYA_SERVER": "viya server if AUTHFLOW=password|token|refresh",
228
- "PASSWORD": "password if AUTHFLOW is password",
229
- "USERNAME": "username if AUTHFLOW is password",
230
- "CLIENTID": "client password if AUTHFLOW is password",
231
- "CLIENTSECRET": "client id if AUTHFLOW is password",
232
- "TOKENFILE": "file if AUTHFLOW is token",
233
- "COMPUTECONTEXT": "SAS Job Execution compute context",
234
- "CASSERVER": "cas-shared-default",
107
+ "sasmcp": {
108
+ "type": "http",
109
+ "url": "http://localhost:8080/mcp"``
110
+ "oauth: {
111
+ "type": "oauth2"
235
112
  }
236
- }
237
-
113
+ }
238
114
  ```
239
115
 
240
- ### http transport
241
-
242
- This is an alternate to using stdio.
243
- This requires the .env file, which has the necessary configuration values described earlier in this document.
244
- It also requires the MCP server to be running (see step 2).
245
-
246
- > Remote MCP servers: This is under development
247
-
248
- #### Step 1: Configure the mcp client for localhost
249
-
250
- The mcp configuration is show below
251
-
116
+ For remote mcp servers:
252
117
  ```json
253
118
  "sasmcp": {
254
119
  "type": "http",
255
- "url": "http(s)//localhost:8080/mcp"``
120
+ "url": "your remote mcp server`,
121
+ "oauth": {
122
+ "type": 'oauth2
123
+ }
256
124
  }
257
125
  ```
258
126
 
259
- Here is a typical .env file for http transport. Note the value of MCPTYPE.
260
-
261
- ```env
262
-
263
- PORT=8080
264
- HTTPS=FALSE
265
- MCPTYPE=http
266
- VIYA_SERVER=https://myviya.com
267
- AUTHFLOW=sascli
268
- SAS_CLI_PROFILE=00m
269
- SAS_CLI_CONFIG=c:\Users\<yourusername>
270
- SSLCERT=c:\Users\yourusername\.tls
271
- VIYACERT=c:\Users\yourusername\viyaCert
272
- CAS_SERVER=cas-shared-default
273
- COMPUTECONTEXT=SAS Job Execution compute context
127
+ For transport protocol stdio. For claude drop the type
274
128
 
129
+ ```json
130
+ "sas-mcp-server": {
131
+ "type: "stdio"
132
+ "command": "npx",
133
+ "args": [
134
+ "-y",
135
+ "@sassoftware/sas-score-mcp-serverjs@1.0.0"
136
+ -v "<your viya url>"
137
+ -m "stdio"
138
+ --profile "dtl"
139
+ -a "sascli"
140
+ ]
141
+ }
275
142
  ```
276
- Use https if the environment variables HTTPS=TRUE
277
-
278
143
 
279
144
  #### Step 2: Start the mcp server
280
145
 
@@ -286,7 +151,7 @@ But this step is necessary of using http transport.
286
151
  npx @sassoftware/sas-score-mcp-serverjs@latest
287
152
  ```
288
153
 
289
- Make sure that the .env file is in the current working directory
154
+ Make sure that the .env file is in the current working directory or specify the options in the command line
290
155
 
291
156
 
292
157
  ## Notes
package/cli.js CHANGED
@@ -51,11 +51,6 @@ const args = parseArgs({
51
51
  type: 'boolean',
52
52
  description: 'Use HTTPS for the server (default: FALSE)'
53
53
  },
54
- 'skills-folder': {
55
- type: 'string',
56
- short: 'f',
57
- description: 'Skills folder name'
58
- },
59
54
 
60
55
  viya: {
61
56
  type: 'string',
@@ -103,8 +98,13 @@ const args = parseArgs({
103
98
  short: 'e',
104
99
  description: 'Environment file path (default: .env in current working directory)'
105
100
  },
101
+ agent: {
102
+ type: 'boolean',
103
+ description: 'Enable agent mode with a pre-configured set of skills based on the client specified (default: false)'
104
+ },
106
105
  client: {
107
106
  type: 'string',
107
+ alias: 'mcpclient',
108
108
  description: 'MCP client name (github, claude...). Defaults to \'github\''
109
109
  },
110
110
  help: {
@@ -137,10 +137,13 @@ Options:
137
137
  MCP server options:
138
138
  -t, --mcptype <type> MCP server type: http or stdio (default: http)
139
139
  -m, --mcphost <host> MCP server host - can be remote URL - (default: http://localhost:8080)
140
+
141
+ Agent options:
142
+ --agent Enable agent mode with a pre-configured set of skills based on the client specified (default: false)
140
143
  --client <name> MCP client name (github, claude...). Defaults to 'github'.Use to install skills
141
144
  Authentication options:
142
145
  -a, --authflow <flow> Authentication flow: oauth, oauthclient, sascli, code, token(default oauth)
143
- -s, --clientsecret <secret> Client Secret for authentication(if necessary). See clientid option as well.
146
+ -s, --clientsecret <secret> Client Secret for oauth authentication (not needed for pkce)
144
147
  --profile <name> SAS CLI profile name for sascli flow (default: Default)
145
148
  --config <path> SAS CLI config directory for sascli flow (default: user home directory)
146
149
 
@@ -162,7 +165,7 @@ Environment Variables:
162
165
  `);
163
166
  process.exit(0);
164
167
  }
165
-
168
+ console.error('Parsed command line arguments:', args.values);
166
169
  // read env file and then override with command line arguments
167
170
  if (args.values.env) {
168
171
  console.error('Working Directory', process.cwd());
@@ -184,23 +187,22 @@ if (args.values.env) {
184
187
  // Apply command line arguments to override environment variables
185
188
 
186
189
  process.env.PORT = process.env.PORT || '8080';
187
- process.env.HTTPS = (args.values.https) ? 'TRUE' : 'FALSE';
190
+ process.env.HTTPS = args.values.https ? 'TRUE' : (process.env.HTTPS === 'TRUE' ? 'TRUE' : 'FALSE');
188
191
  process.env.MCPTYPE = args.values.mcptype || process.env.MCPTYPE || 'http';
189
192
  process.env.MCPHOST = args.values.mcphost || process.env.MCPHOST || 'http://localhost:8080';
190
193
  process.env.AUTHFLOW = args.values.authflow || process.env.AUTHFLOW || 'oauth';
191
194
  process.env.MCPCLIENT = args.values.client || process.env.MCPCLIENT || 'github';
192
- process.env.VIYA_SERVER = args.values.viya || process.env.VIYA_SERVER || null;
195
+ process.env.VIYA_SERVER = args.values.viya || process.env.VIYA_SERVER;
193
196
  process.env.CLIENTID = args.values.clientid || process.env.CLIENTID || 'vscodemcp';
194
197
  process.env.CLIENTSECRET = args.values.clientsecret || process.env.CLIENTSECRET || null;
195
198
  process.env.SAS_CLI_PROFILE = args.values.profile || process.env.SAS_CLI_PROFILE || 'Default';
196
- process.env.SAS_CLI_CONFIG = args.values.config || process.env.SAS_CLI_CONFIG || process.env.HOME; // default to user home directory
199
+ process.env.SAS_CLI_CONFIG = args.values.config || process.env.SAS_CLI_CONFIG || os.homedir(); // default to user home directory
197
200
  process.env.CASSERVER = args.values.casserver || process.env.CASSERVER || 'cas-shared-default';
198
201
  process.env.COMPUTECONTEXT = args.values.computecontext || process.env.COMPUTECONTEXT || 'SAS Job Execution compute context';
199
202
  process.env.APPHOST = 'localhost';
203
+ process.env.AGENT = args.values.agent ? 'TRUE' : process.env.AGENT;
200
204
  process.env.CLIENT = args.values.client || process.env.CLIENT || 'github';
201
205
 
202
-
203
-
204
206
  process.env.SAMESITE = 'Lax,secure';
205
207
  process.env.APPHOST = '0.0.0.0';
206
208
  process.env.APPNAME = 'sas-score-mcp-serverjs';
@@ -217,51 +219,6 @@ if (args.values.version) {
217
219
  console.error(`[Note] MCP client set to: ${process.env.CLIENT}`);
218
220
 
219
221
 
220
- let client = process.env.CLIENT;
221
- if (client !== 'none') {
222
- console.error(`[Note] Setting up skills for client: ${client}...`);
223
- setupSkills(client);
224
- } else {
225
- console.error(`[Note] No client specified, skipping skill setup...`);
226
- }
227
-
228
-
229
- /*
230
- if (client !== 'none') {
231
- let destdir = '.' + client;
232
- let skillsDest = join(os.homedir(), destdir,'skills');
233
- const skillsSrc = join(__dirname, '.github');
234
- if (!fs.existsSync(skillsSrc)) {
235
- console.error('No skills directory found in this package.');
236
- process.exit(1);
237
- }
238
- fs.mkdirSync(skillsDest, { recursive: true });
239
-
240
- const skills = fs.readdirSync(skillsSrc, { withFileTypes: true })
241
- .filter(d => d.isDirectory())
242
- .map(d => d.name);
243
-
244
- if (skills.length === 0) {
245
- console.error('[Note]No skills found to install.');
246
- } else {
247
- console.error(`Installing ${skills.length} skill(s) to ${skillsDest}...`);
248
- for (const skill of skills) {
249
- const src = join(skillsSrc, skill);
250
- const dest = join(skillsDest, skill);
251
- fs.cpSync(src, dest, { recursive: true });
252
- console.error(` installed: ${skill}`);
253
- }
254
- console.error(`\n installed in cli. ${client}`);
255
- console.error(`\n${skills.length} skill(s) installed to ${skillsDest}`);
256
- console.error('[Note] Skills are ready for use.');
257
-
258
- }
259
- }
260
- */
261
-
262
-
263
-
264
-
265
222
  /********************************* */
266
223
  const BRAND = 'sas-score'
267
224
  /********************************* */
@@ -309,7 +266,7 @@ const appEnvBase = {
309
266
  brand: (process.env.BRAND == null) ? BRAND : process.env.BRAND,
310
267
  HTTPS: https,
311
268
  SAS_CLI_PROFILE: process.env.SAS_CLI_PROFILE || 'Default',
312
- SAS_CLI_CONFIG: process.env.SAS_CLI_CONFIG || process.env.HOME, // default to user home directory
269
+ SAS_CLI_CONFIG: process.env.SAS_CLI_CONFIG || os.homedir(), // default to user home directory
313
270
  SSLCERT: process.env.SSLCERT || null,
314
271
  VIYACERT: process.env.VIYACERT || null,
315
272
 
@@ -414,6 +371,16 @@ if (appEnvBase.TOKENFILE != null) {
414
371
  // setup mcpServer (both http and stdio use this)
415
372
  // this is singleton - best practices recommend this
416
373
 
374
+ // setup skills based on client before mcp initialization
375
+ //
376
+ if (process.env.AGENT === 'TRUE') {
377
+ if (process.env.CLIENT !== 'none') {
378
+ console.error(`[Note] Setting up skills for client: ${process.env.CLIENT}...`);
379
+ setupSkills(process.env.CLIENT);
380
+ }
381
+ } else {
382
+ console.error(`[Note] Agent mode not enabled`);
383
+ }
417
384
  let mcpServer = await createMcpServer(sessionCache, appEnvBase);
418
385
 
419
386
  sessionCache.set('appEnvBase', appEnvBase);
@@ -470,14 +437,15 @@ Options:
470
437
  `);
471
438
 
472
439
  console.error('===================================================================');
473
- console.error(`
474
- [Note] The SAS Viya Scoring Expert agent has been installed successfully.
475
- Depending on the client you are using, the agent might not be active
476
- If the agent does not appear in the agent dropdown list your options are:
477
- - use the /subagent command
478
- - exit this app and issue the npx command to restart the server
479
- `);
480
-
440
+ if (process.env.AGENT === 'TRUE') {
441
+ console.error(`
442
+ [Note] The SAS Viya Scoring Expert agent has been installed successfully.
443
+ Depending on the client you are using, the agent might not be active
444
+ If the agent does not appear in the agent dropdown list your options are:
445
+ - use the /subagent command
446
+ - exit this app and issue the npx command to restart the server
447
+ `);
448
+ }
481
449
  if (mcpType === 'stdio') {
482
450
  console.error('[Note] Setting up stdio transport with sessionId:', sessionId);
483
451
  console.error('[Note] Used in setting up tools and some persistence(not all).');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassoftware/sas-score-mcp-serverjs",
3
- "version": "1.0.1-0",
3
+ "version": "1.0.1-2",
4
4
  "description": "A mcp server for SAS Viya",
5
5
  "author": "Deva Kumar <deva.kumar@sas.com>",
6
6
  "license": "Apache-2.0",
@@ -7,8 +7,8 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
7
  // Paths
8
8
  let client = (process.env.CLIENTNAME == null) ? '.github' : `.${process.env.CLIENTNAME.toLowerCase()}`;
9
9
  const source = path.join(__dirname, `../.skills`);
10
- //const destination = path.join(process.cwd(), client);
11
- const destination = path.join(os.homedir(), client)
10
+ const destination = path.join(process.cwd(), client);
11
+ // const destination = path.join(os.homedir(), client)
12
12
  console.error(`📁 Copying ${source} to ${destination}...`);
13
13
  function copyFolderSync(from, to) {
14
14
  if (!fs.existsSync(from)) return;
@@ -7,38 +7,49 @@ import { fileURLToPath } from 'url';
7
7
  function setupSkills(clientName) {
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
9
  // Paths
10
- const source = path.join(__dirname, `../.skills`)
11
- let client = (clientName == null) ? 'github' : `${clientName.toLowerCase()}`;
12
10
  let destination;
13
- // still hoping to put the definitions in the cache
14
- // if it starts with ., then copy agent to where the command is run, otherwise copy to home directory
15
- if (client.startsWith('.')) {
16
- destination = path.join(process.cwd(), client);
11
+ if (clientName.startsWith('.')) {
12
+ console.error('-----------------------',process.cwd());
13
+ destination = path.join(process.cwd(), clientName);
14
+ clientName = clientName.slice(1);
17
15
  } else {
18
- client = '.' + client;
19
- destination = path.join(os.homedir(), client);
16
+ destination = path.join(os.homedir(), '.' + clientName);
20
17
  }
21
18
 
22
- console.error(`📁 Copying ${source} to ${destination}...`);
19
+ const source = path.join(__dirname, `../.skills` + '_' + clientName.toLowerCase());
20
+ console.error("==================================================================");
21
+ console.error(` Copying ${source} to ${destination}...`);
22
+
23
23
  function copyFolderSync(from, to) {
24
- if (!fs.existsSync(from)) return;
25
- if (!fs.existsSync(to)) fs.mkdirSync(to, { recursive: true });
26
- console.error(`📁 Copying folder: ${from} to ${to}`);
24
+ if (!fs.existsSync(from)) return [];
25
+ if (!fs.existsSync(to)) fs.mkdirSync(to, { recursive: true });;
27
26
  fs.readdirSync(from).forEach(element => {
28
- console.error(`📁 Processing: ${element}`);
29
27
  const fromPath = path.join(from, element);
30
28
  const toPath = path.join(to, element);
31
29
  if (fs.lstatSync(fromPath).isFile()) {
30
+ console.error(` 📄 Copying file: ${element}`);
32
31
  fs.copyFileSync(fromPath, toPath);
33
32
  } else if (fs.lstatSync(fromPath).isDirectory()) {
34
- copyFolderSync(fromPath, toPath);
33
+ console.error(`📂 Copying folder: ${element}`);
34
+ copyFolderSync(fromPath, toPath) ;
35
35
  }
36
36
  });
37
37
  }
38
38
 
39
+ function listExpandedFolder(dir, indent = "") {
40
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
41
+
42
+ for (const entry of entries) {
43
+ console.log(indent + entry.name);
44
+
45
+ if (entry.isDirectory()) {
46
+ listExpandedFolder(path.join(dir, entry.name), indent + " ");
47
+ }
48
+ }
49
+ }
39
50
  try {
40
51
  copyFolderSync(source, destination);
41
- console.error(`✅ Success: ${destination} folder is now in your project root.`);
52
+ //listExpandedFolder(destination);
42
53
  } catch (err) {
43
54
  console.error('❌ Error copying files:', err.message);
44
55
  }
@@ -1,58 +0,0 @@
1
- ---
2
- name: SAS Viya Scoring Expert
3
- description: Specialized SAS and Viya agent that classifies requests, selects the right SAS skill, and uses MCP tools safely for jobs, CAS data, libraries, models, scoring, and content workflows.
4
- ---
5
-
6
- # SAS Viya Scoring Expert
7
-
8
- You are a SAS Viya expert agent.
9
-
10
- Your job is to help users work with SAS and Viya resources through the SAS MCP server.
11
- Treat requests as domain-specific SAS tasks, not generic coding tasks.
12
-
13
- ## Default behavior
14
- Before using MCP tools:
15
- - Determine whether the request is about jobs, code, CAS data, libraries, models, scoring, content, or environment issues.
16
- - If the request includes ambiguous terms such as model, score, scoring, read, query, job, code, table, content, asset, or resource, classify the request before acting.
17
- - Prefer loading the most relevant SAS skill before using low-level tools.
18
- - If confidence is low, ask one focused clarifying question.
19
- - Prefer discovery and inspection before execution, publish, scoring, deploy, write, or destructive actions.
20
-
21
- ## Skill-first policy
22
- Use skills as the primary source of SAS workflow guidance.
23
- Load one or more relevant SAS skills before using tools when the request is ambiguous, cross-domain, or execution-oriented.
24
- Do not load unrelated skills.
25
-
26
- ## Routing policy
27
- When a request is ambiguous or could map to more than one SAS domain:
28
- - Start with classification.
29
- - Identify the most likely SAS asset or workflow type.
30
- - Choose the best matching SAS skill.
31
- - Only then select MCP tools.
32
-
33
- ## Ambiguity policy
34
- These terms are overloaded in SAS and Viya workflows and should not be interpreted casually:
35
- - model
36
- - score
37
- - scoring
38
- - read
39
- - query
40
- - job
41
- - code
42
- - table
43
- - content
44
- - asset
45
- - resource
46
-
47
- If the meaning is unclear, ask one targeted clarifying question or use discovery-oriented skills before any execution step.
48
-
49
- ## Tool usage policy
50
- - Prefer read-only discovery before execution.
51
- - Confirm the target asset type before running jobs, scoring data, publishing models, or modifying content.
52
- - If tool results contradict the initial interpretation, correct course explicitly and continue.
53
- - Never invent asset names, identifiers, libraries, or model types.
54
-
55
- ## Response style
56
- Be concise, explicit, and domain-aware.
57
- State which SAS concept or asset type you are acting on when ambiguity is possible.
58
- Prefer short structured answers when guiding the user.