@sassoftware/sas-score-mcp-serverjs 0.0.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.
Files changed (96) hide show
  1. package/.babelrc +6 -0
  2. package/.env +13 -0
  3. package/.env.http +29 -0
  4. package/CHANGES.md +2 -0
  5. package/CONTRIBUTING.md +14 -0
  6. package/ContributorAgreement.txt +56 -0
  7. package/LICENSE +205 -0
  8. package/LICENSES.json +105 -0
  9. package/QUICK_REFERENCE.md +378 -0
  10. package/README.md +267 -0
  11. package/SECURITY.md +31 -0
  12. package/SUPPORT.md +3 -0
  13. package/TOOL_DESCRIPTION_TEMPLATE.md +157 -0
  14. package/TOOL_UPDATES_SUMMARY.md +208 -0
  15. package/cli.js +214 -0
  16. package/labs/.subclass.json +13 -0
  17. package/labs/README.md +4 -0
  18. package/mcpConfigurations/README.md +3 -0
  19. package/mcpConfigurations/http.json +8 -0
  20. package/mcpConfigurations/stdio.json +20 -0
  21. package/mcpConfigurations/stdiodev.json +20 -0
  22. package/mcpserver.png +0 -0
  23. package/openApi.json +106 -0
  24. package/openApi.yaml +84 -0
  25. package/package.json +72 -0
  26. package/sas-mcp-tools-reference.md +600 -0
  27. package/sasCode/sas-sql-query.sas +33 -0
  28. package/sasCode/sas_sql_tool.json +237 -0
  29. package/scripts/getViyaca.sh +8 -0
  30. package/src/core.js +19 -0
  31. package/src/coreSSE.js +14 -0
  32. package/src/corehttp.js +335 -0
  33. package/src/createHttpTransport.js +26 -0
  34. package/src/createMcpServer.js +76 -0
  35. package/src/db/scrModels.js +23 -0
  36. package/src/toolSet/devaScore.js +69 -0
  37. package/src/toolSet/findJob.js +90 -0
  38. package/src/toolSet/findJobdef.js +95 -0
  39. package/src/toolSet/findLibrary.js +100 -0
  40. package/src/toolSet/findModel.js +83 -0
  41. package/src/toolSet/findTable.js +94 -0
  42. package/src/toolSet/getEnv.js +72 -0
  43. package/src/toolSet/listJobdefs.js +96 -0
  44. package/src/toolSet/listJobs.js +110 -0
  45. package/src/toolSet/listLibraries.js +90 -0
  46. package/src/toolSet/listModels.js +83 -0
  47. package/src/toolSet/listTables.js +95 -0
  48. package/src/toolSet/makeTools.js +75 -0
  49. package/src/toolSet/mcp server .png +0 -0
  50. package/src/toolSet/modelInfo.js +87 -0
  51. package/src/toolSet/modelScore.js +131 -0
  52. package/src/toolSet/readTable.js +104 -0
  53. package/src/toolSet/runCasProgram.js +118 -0
  54. package/src/toolSet/runJob.js +81 -0
  55. package/src/toolSet/runJobdef.js +85 -0
  56. package/src/toolSet/runMacro.js +82 -0
  57. package/src/toolSet/runProgram.js +145 -0
  58. package/src/toolSet/sasQuery.js +126 -0
  59. package/src/toolSet/sasQueryTemplate.js +148 -0
  60. package/src/toolSet/sasQueryTemplate2.js +140 -0
  61. package/src/toolSet/scrInfo.js +55 -0
  62. package/src/toolSet/scrScore.js +71 -0
  63. package/src/toolSet/searchAssets.js +52 -0
  64. package/src/toolSet/setContext.js +98 -0
  65. package/src/toolSet/superstat.js +60 -0
  66. package/src/toolSet/tableInfo.js +102 -0
  67. package/src/toolhelpers/_catalogSearch.js +87 -0
  68. package/src/toolhelpers/_getEnv.js +10 -0
  69. package/src/toolhelpers/_itemsData.js +28 -0
  70. package/src/toolhelpers/_jobSubmit.js +78 -0
  71. package/src/toolhelpers/_listJobdefs.js +59 -0
  72. package/src/toolhelpers/_listJobs.js +63 -0
  73. package/src/toolhelpers/_listLibrary.js +56 -0
  74. package/src/toolhelpers/_listModels.js +41 -0
  75. package/src/toolhelpers/_listTables.js +52 -0
  76. package/src/toolhelpers/_masDescribe.js +27 -0
  77. package/src/toolhelpers/_masScoring.js +64 -0
  78. package/src/toolhelpers/_readTable.js +69 -0
  79. package/src/toolhelpers/_scrInfo.js +32 -0
  80. package/src/toolhelpers/_scrScore.js +49 -0
  81. package/src/toolhelpers/_submitCasl.js +34 -0
  82. package/src/toolhelpers/_submitCode.js +96 -0
  83. package/src/toolhelpers/_submitMacro.js +24 -0
  84. package/src/toolhelpers/_tableColumns.js +61 -0
  85. package/src/toolhelpers/_tableInfo.js +72 -0
  86. package/src/toolhelpers/deleteSession.js +13 -0
  87. package/src/toolhelpers/getLogonPayload.js +100 -0
  88. package/src/toolhelpers/getOpts.js +43 -0
  89. package/src/toolhelpers/getOptsViya.js +38 -0
  90. package/src/toolhelpers/getStoreOpts.js +18 -0
  91. package/src/toolhelpers/getToken.js +40 -0
  92. package/src/toolhelpers/refreshToken.js +48 -0
  93. package/test/README.md +63 -0
  94. package/test/listLibraries.test.js +245 -0
  95. package/tool-developer-guide.md +80 -0
  96. package/types.js +25 -0
@@ -0,0 +1,600 @@
1
+ # SAS MCP Server Tools Reference
2
+
3
+ ## Overview
4
+
5
+ The `@sassoftware/sas-score-mcp-serverjs` package provides a comprehensive set of tools for interacting with SAS Viya environments through the Model Context Protocol (MCP). This document catalogs all 24+ available tools organized by functional category.
6
+
7
+ All tools are registered as sas-score-<toolname>
8
+
9
+ ## Table of Contents
10
+
11
+ - [Model Management & Scoring](#model-management--scoring)
12
+ - [Library Management](#library-management)
13
+ - [Table Operations](#table-operations)
14
+ - [Job Management](#job-management)
15
+ - [Program Execution](#program-execution)
16
+ - [Context & Configuration](#context--configuration)
17
+ - [Utility Tools](#utility-tools)
18
+
19
+ ---
20
+
21
+ ## Model Management & Scoring
22
+
23
+ ### list-models
24
+
25
+ Enumerate models published to MAS (Model Aggregation Service).
26
+
27
+ **Parameters:**
28
+ - `limit` (number, default: 10): Number of models to return
29
+ - `start` (number, default: 1): 1-based offset for pagination
30
+
31
+ **Usage:**
32
+ - "list models"
33
+ - "show models"
34
+ - "list 25 models"
35
+ - "next models" (pagination)
36
+
37
+ **Example:**
38
+ ```
39
+ list models
40
+ list 25 models
41
+ ```
42
+
43
+ ---
44
+
45
+ ### find-model
46
+
47
+ Locate a specific model deployed to MAS.
48
+
49
+ **Parameters:**
50
+ - `name` (string, required): Exact model name
51
+
52
+ **Usage:**
53
+ - "find model churnRisk"
54
+ - "does model creditScore exist"
55
+ - "is model sales_forecast deployed"
56
+
57
+ **Example:**
58
+ ```
59
+ find model myModel
60
+ ```
61
+
62
+ ---
63
+
64
+ ### model-info
65
+
66
+ Retrieve detailed metadata for a deployed model including input/output variables, data types, and constraints.
67
+
68
+ **Parameters:**
69
+ - `model` (string, required): Model name as published to MAS
70
+
71
+ **Returns:**
72
+ - Input variable metadata (names, types, roles, ranges)
73
+ - Output variable information
74
+ - Model type and description
75
+
76
+ **Usage:**
77
+ - "What inputs does model X need?"
78
+ - "Describe model myModel"
79
+ - "Show the variables for sales_forecast"
80
+
81
+ **Example:**
82
+ ```
83
+ model-info model=churnRisk
84
+ ```
85
+
86
+ ---
87
+
88
+ ### model-score
89
+
90
+ Score user-supplied scenario data using a MAS-published model.
91
+
92
+ **Parameters:**
93
+ - `model` (string, required): Model name
94
+ - `scenario` (string | object | array, required): Data to score
95
+ - `uflag` (boolean, optional): Prefix model fields with underscore
96
+
97
+ **Scenario formats:**
98
+ - Comma-separated: `"x=1, y=2"`
99
+ - Object: `{x: 1, y: 2}`
100
+ - Array: `[{x: 1, y: 2}, {x: 3, y: 4}]`
101
+
102
+ **Usage:**
103
+ - "Score this customer with model churnRisk"
104
+ - "Run model creditScore with age=45, income=60000"
105
+
106
+ **Example:**
107
+ ```
108
+ model-score model=mycoolmodel scenario={x:1,y:2}
109
+ model-score model=cancer1 scenario="age=45, sex=M, tumor=stage2"
110
+ ```
111
+
112
+ ---
113
+
114
+ ### scr-info
115
+
116
+ Return input/output schema and metadata for an SCR (Score Code Runtime) model.
117
+
118
+ **Parameters:**
119
+ - `name` (string, required): SCR model identifier (URL or name)
120
+
121
+ **Returns:**
122
+ - Input variables (names, types, required/optional)
123
+ - Output variables (predictions, probabilities, scores)
124
+
125
+ **Example:**
126
+ ```
127
+ scr-info name="https://scr-host/models/loan"
128
+ ```
129
+
130
+ ---
131
+
132
+ ### scr-score
133
+
134
+ Score a scenario using an SCR container model.
135
+
136
+ **Parameters:**
137
+ - `url` (string, required): SCR model identifier (URL)
138
+ - `scenario` (string | object | array, optional): Input values
139
+
140
+ **Usage:**
141
+ - Run scrInfo first to inspect expected inputs
142
+ - Omit scenario to get model metadata
143
+
144
+ **Example:**
145
+ ```
146
+ scr-score url="loan" scenario="age=45, income=60000"
147
+ scr-score url="https://scr-host/models/loan" scenario={age:45, income:60000}
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Library Management
153
+
154
+ ### list-libraries
155
+
156
+ Enumerate CAS or SAS libraries.
157
+
158
+ **Parameters:**
159
+ - `server` (cas|sas, default: 'cas'): Target environment
160
+ - `limit` (number, default: 10): Page size
161
+ - `start` (number, default: 1): 1-based offset
162
+ - `where` (string, optional): Filter expression
163
+
164
+ **Usage:**
165
+ - "list libs"
166
+ - "list libraries"
167
+ - "show cas libs"
168
+ - "list sas libs"
169
+
170
+ **Example:**
171
+ ```
172
+ list libraries
173
+ list sas libs
174
+ show me 25 cas libraries
175
+ ```
176
+
177
+ ---
178
+
179
+ ### find-library
180
+
181
+ Locate a specific CAS or SAS library.
182
+
183
+ **Parameters:**
184
+ - `name` (string, required): Exact library name
185
+ - `server` (cas|sas, default: 'cas'): Target environment
186
+
187
+ **Usage:**
188
+ - "find library Public"
189
+ - "does library SASHELP exist"
190
+ - "is PUBLIC library available in cas"
191
+
192
+ **Example:**
193
+ ```
194
+ find lib Public
195
+ find library sasuser in sas
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Table Operations
201
+
202
+ ### list-tables
203
+
204
+ Enumerate tables within a specific CAS or SAS library.
205
+
206
+ **Parameters:**
207
+ - `lib` (string, required): Library to inspect
208
+ - `server` (cas|sas, default: 'cas'): Target environment
209
+ - `limit` (number, default: 10): Page size
210
+ - `start` (number, default: 1): 1-based offset
211
+
212
+ **Usage:**
213
+ - "list tables in Samples"
214
+ - "show tables in sashelp"
215
+ - "list 25 tables in Public"
216
+
217
+ **Example:**
218
+ ```
219
+ list tables in samples
220
+ show 25 tables in sashelp
221
+ ```
222
+
223
+ ---
224
+
225
+ ### find-table
226
+
227
+ Locate a table in a specified library.
228
+
229
+ **Parameters:**
230
+ - `lib` (string, required): Library to search in
231
+ - `name` (string, required): Table name or substring
232
+ - `server` (cas|sas, default: 'cas'): Target environment
233
+
234
+ **Usage:**
235
+ - "find table iris in Public library in cas"
236
+ - "find table cars in sashelp in sas server"
237
+
238
+ **Example:**
239
+ ```
240
+ find table iris in Public
241
+ find table cars in sashelp in sas
242
+ ```
243
+
244
+ ---
245
+
246
+ ### table-info
247
+
248
+ Return metadata about a table including columns, types, and statistics.
249
+
250
+ **Parameters:**
251
+ - `table` (string, required): Table name
252
+ - `lib` (string, required): Library containing the table
253
+ - `server` (cas|sas, default: 'cas'): Target environment
254
+
255
+ **Returns:**
256
+ - Column metadata (name, type, label, formats)
257
+ - Table statistics (row count, file size, timestamps)
258
+
259
+ **Usage:**
260
+ - "describe table cars in Public"
261
+ - "info on table mydata in mylib"
262
+
263
+ **Example:**
264
+ ```
265
+ table-info table=cars lib=Public
266
+ describe table air in lib sashelp on sas server
267
+ ```
268
+
269
+ ---
270
+
271
+ ### read-table
272
+
273
+ Retrieve rows from a table in a CAS or SAS library.
274
+
275
+ **Parameters:**
276
+ - `table` (string, required): Table name
277
+ - `lib` (string, required): Library containing the table
278
+ - `server` (cas|sas, default: 'cas'): Target environment
279
+ - `start` (number, default: 1): Starting row (1-based)
280
+ - `limit` (number, default: 10): Maximum rows to return
281
+ - `where` (string, optional): SQL-style WHERE clause
282
+ - `format` (boolean, default: true): Return formatted or raw values
283
+ - `row` (number, optional): Read a specific row
284
+
285
+ **Usage:**
286
+ - "read table customers"
287
+ - "show me 10 rows from sales"
288
+ - "read from orders where status = 'shipped'"
289
+
290
+ **Example:**
291
+ ```
292
+ read table cars in Samples
293
+ show 25 rows from customers
294
+ read orders where status = 'shipped' limit 50
295
+ read row 15 from employees in mylib on sas
296
+ ```
297
+
298
+ ---
299
+
300
+ ### sas-query
301
+
302
+ Execute SQL queries on SAS tables using PROC SQL.
303
+
304
+ **Parameters:**
305
+ - `table` (string, required): Table in format libname.tablename
306
+ - `query` (string, required): Natural language query
307
+ - `sql` (string, optional): Generated SQL SELECT statement
308
+ - `job` (string, default: 'sas_sql_tool'): Job to run query on
309
+
310
+ **Workflow:**
311
+ 1. User provides natural language query
312
+ 2. Convert to SAS PROC SQL SELECT statement
313
+ 3. Execute and return results
314
+
315
+ **Example:**
316
+ ```
317
+ sasquery table=mylib.clm_dental query="Total paid amount, unique patients by procedure code"
318
+ sasquery table=mylib.students query="How many students in each year as percentage"
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Job Management
324
+
325
+ ### list-jobs
326
+
327
+ Enumerate SAS Viya job assets.
328
+
329
+ **Parameters:**
330
+ - `limit` (number, default: 10): Number of jobs to return
331
+ - `start` (number, default: 1): 1-based offset
332
+ - `where` (string, optional): Filter expression
333
+
334
+ **Usage:**
335
+ - "list jobs"
336
+ - "show jobs"
337
+ - "list 25 jobs"
338
+
339
+ **Example:**
340
+ ```
341
+ list jobs
342
+ list 25 jobs
343
+ ```
344
+
345
+ ---
346
+
347
+ ### find-job
348
+
349
+ Locate a specific SAS Viya job.
350
+
351
+ **Parameters:**
352
+ - `name` (string, required): Exact job name
353
+
354
+ **Usage:**
355
+ - "find job cars_job_v4"
356
+ - "does job sales_summary exist"
357
+ - "verify job ETL_Daily"
358
+
359
+ **Example:**
360
+ ```
361
+ find job cars_job_v4
362
+ ```
363
+
364
+ ---
365
+
366
+ ### run-job
367
+
368
+ Execute a job on a SAS Viya server.
369
+
370
+ **Parameters:**
371
+ - `name` (string, required): Job name
372
+ - `scenario` (string | object, optional): Input parameters
373
+
374
+ **Returns:**
375
+ - Log, listing, and tables (depending on job definition)
376
+
377
+ **Example:**
378
+ ```
379
+ run job xyz param1=10,param2=val2
380
+ run-job myjob scenario a=10,b=20
381
+ job myjob scenario a=10,b=20
382
+ ```
383
+
384
+ ---
385
+
386
+ ### list-jobdefs
387
+
388
+ Enumerate SAS Viya job definition assets.
389
+
390
+ **Parameters:**
391
+ - `limit` (number, default: 10): Number to return
392
+ - `start` (number, default: 1): 1-based offset
393
+ - `where` (string, optional): Filter expression
394
+
395
+ **Usage:**
396
+ - "list jobdefs"
397
+ - "show job definitions"
398
+
399
+ **Example:**
400
+ ```
401
+ list jobdefs
402
+ list 25 jobdefs
403
+ ```
404
+
405
+ ---
406
+
407
+ ### find-jobdef
408
+
409
+ Locate a specific job definition.
410
+
411
+ **Parameters:**
412
+ - `name` (string, required): Exact jobdef name
413
+
414
+ **Usage:**
415
+ - "find jobdef cars_job_v4"
416
+ - "does jobdef ETL exist"
417
+
418
+ **Example:**
419
+ ```
420
+ find jobdef metricsRefresh
421
+ ```
422
+
423
+ ---
424
+
425
+ ### run-jobdef
426
+
427
+ Execute a job definition on a SAS Viya server.
428
+
429
+ **Parameters:**
430
+ - `name` (string, required): Job definition name
431
+ - `scenario` (string | object, optional): Input parameters
432
+
433
+ **Returns:**
434
+ - Log, listing, and tables
435
+
436
+ **Example:**
437
+ ```
438
+ run-jobdef xyz param1=10,param2=val2
439
+ jobdef myjobdef scenario a=10,b=20
440
+ ```
441
+
442
+ ---
443
+
444
+ ## Program Execution
445
+
446
+ ### run-program
447
+
448
+ Execute arbitrary SAS code or stored programs on a SAS Viya server.
449
+
450
+ **Parameters:**
451
+ - `src` (string, required): SAS code or .sas filename
452
+ - `folder` (string, optional): Server folder path if src is a filename
453
+ - `scenario` (string | object, optional): Input parameters
454
+ - `output` (string, optional): Name of output table returned as JSON
455
+ - `limit` (number, default: 100): Max rows from output table
456
+
457
+ **Usage:**
458
+ - Direct code execution
459
+ - Running stored .sas files
460
+ - With input parameters and output capture
461
+
462
+ **Example:**
463
+ ```
464
+ run program "data a; x=1; run;"
465
+ program "data work.a; x=1; run;" output=a limit=50
466
+ run program sample folder=/Public/models output=A limit=50
467
+ program sample folder=/Public/models scenario="name='John', age=45" output=a
468
+ ```
469
+
470
+ ---
471
+
472
+ ### run-macro
473
+
474
+ Submit and execute a SAS macro on a SAS Viya server.
475
+
476
+ **Parameters:**
477
+ - `macro` (string, required): Macro name (without leading %)
478
+ - `scenario` (string, optional): Parameters or SAS setup code
479
+
480
+ **Scenario formats:**
481
+ - Comma-separated: `"x=1, y=abc"` → converted to %let statements
482
+ - Raw SAS: `"%let x=1; %let y=abc;"` → passed through unchanged
483
+
484
+ **Example:**
485
+ ```
486
+ run macro abc with scenario x=1, y=2
487
+ run macro summarize with scenario %let x=1; %let y=2;
488
+ ```
489
+
490
+ ---
491
+
492
+ ## Context & Configuration
493
+
494
+ ### set-context
495
+
496
+ Set the CAS and SAS server contexts for subsequent tool calls.
497
+
498
+ **Parameters:**
499
+ - `cas` (string, optional): CAS server name
500
+ - `sas` (string, optional): SAS compute context name
501
+
502
+ **Returns:**
503
+ - Current CAS and SAS context values
504
+
505
+ **Usage:**
506
+ - Switch between server environments
507
+ - Check current context (call with no parameters)
508
+
509
+ **Example:**
510
+ ```
511
+ set-context cas=finance-cas-server
512
+ set-context sas="SAS Studio Compute Context"
513
+ set-context (returns current context)
514
+ ```
515
+ ---
516
+
517
+ ## Utility Tools
518
+
519
+ Use this to verify that the mcp server is up and running.
520
+
521
+ ### deva-score
522
+
523
+ Compute a numeric score based on two input values using the formula: (a + b) × 42
524
+
525
+ **Parameters:**
526
+ - `a` (number, required): First numeric input
527
+ - `b` (number, required): Second numeric input
528
+
529
+ **Returns:**
530
+ - Numeric result: (a + b) × 42
531
+
532
+ **Usage:**
533
+ - "Calculate deva score for 5 and 10"
534
+ - For sequences: chain calls left-to-right
535
+
536
+ **Example:**
537
+ ```
538
+ deva-score a=5 b=10 // returns 630
539
+ deva-score a=1 b=2 // returns 126
540
+ ```
541
+
542
+ ---
543
+
544
+ ## Tool Categories Summary
545
+
546
+ | Category | Tool Count | Tools |
547
+ |----------|-----------|-------|
548
+ | **Model Management** | 6 | list-models, find-model, model-info, model-score, scr-info, scr-score |
549
+ | **Library Management** | 2 | list-libraries, find-library |
550
+ | **Table Operations** | 5 | list-tables, find-table, table-info, read-table, sas-query |
551
+ | **Job Management** | 6 | list-jobs, find-job, job, list-jobdefs, find-jobdef, job-def |
552
+ | **Program Execution** | 2 | run-program, run-macro |
553
+ | **Context & Config** | 1 | set-context |
554
+ | **Utilities** | 1 | deva-score |
555
+ | **Total** | **24** | |
556
+
557
+ ---
558
+
559
+ ## Common Patterns
560
+
561
+ ### Discovery → Inspection → Action
562
+
563
+ 1. **List** tools to discover available resources
564
+ 2. **Find** tools to locate specific items
565
+ 3. **Info** tools to inspect metadata
566
+ 4. **Execution** tools to perform actions
567
+
568
+ ### Pagination
569
+
570
+ Many list tools support pagination:
571
+ - First page: `{ start: 1, limit: 10 }`
572
+ - Next page: `{ start: 11, limit: 10 }`
573
+
574
+ ### Server Targeting
575
+
576
+ Tools that interact with data support `server` parameter:
577
+ - `'cas'` - CAS server (default)
578
+ - `'sas'` - SAS compute server
579
+
580
+ ### Scenario Input Formats
581
+
582
+ Tools accepting scenarios support multiple formats:
583
+ - **String**: `"x=1, y=2"`
584
+ - **Object**: `{x: 1, y: 2}`
585
+ - **Array**: `[{x: 1, y: 2}]`
586
+
587
+ ---
588
+
589
+ ## Notes
590
+
591
+ - All tools are designed to work with SAS Viya environments
592
+ - Authentication and connectivity are handled by the MCP server configuration
593
+ - Tools are stateless unless context is explicitly set using set-context
594
+ - Error handling returns structured error objects from the backend
595
+ - Case sensitivity varies by backend (library/table names may be case-insensitive)
596
+
597
+ ---
598
+
599
+ *Document generated for @sassoftware/mcp-serverjs*
600
+ *Last updated: December 2024*
@@ -0,0 +1,33 @@
1
+ *
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ *
5
+
6
+ *
7
+ * template for handling sql statements in args
8
+ *
9
+ data _null_;
10
+ length sql_final $5000.;
11
+ sql_final="%superq(sql)";
12
+ call symput("sql_final",sql_final);
13
+ run;
14
+
15
+ filename joutput filesrvc parenturi="&SYS_JES_JOB_URI" name="query_results.json";
16
+
17
+ %macro run_sql_code;
18
+ cas mycas;
19
+ caslib _all_ assign;
20
+
21
+ proc sql;
22
+ create table work.query_results as
23
+ &sql_final.;
24
+ quit;
25
+
26
+ proc print data=work.query_results;run;
27
+
28
+ proc json out= joutput nosastags;
29
+ export query_results;
30
+ run;
31
+ %mend;
32
+
33
+ %run_sql_code;