-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Welcome to the sas-score-mcp-serverjs wiki!
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.
All tools are registered as sas-score-
- Start MCP Server
- Agent And Skills
- Model Management & Scoring
- Library Management
- Table Operations
- Job Management
- Program Execution
- Context & Configuration
- Utility Tools
If using stdio transport, most of the mcp clients will start the server automatically. But for http transport, the mcp server must be started.
If running locally
npx @sassoftware/sas-score-mcp-serverjs@latestThe mcp is also available as a docker image. Add or remove the env variables as needed.
docker run -p 8080:8080 --name sasscore -e VIYA_SERVER=<yourviyaserver> -e AUTHFLOW=oauth ghcr.io/sassoftware/sas-score-mcp-serverjs:latestTypically 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
- VIYA_SERVER=url for Viya server
These can be customized
-
AUTHFLOW=oauth|oauthclient|bearer|sascli|token|password
- Authentication method. Default is oauth
-
CLIENTID=vscodemcp
- Clientid for oauth and oauthclient AUTHFlOW. Must be PKCE clientid.
-
MCPTYPE=http|stdio
- The transport protocol for the mcp server.
-
MCPHOST=http://localhost:8080
- URL of the mcp server. If using remote mcp server, set this to remote MCP server
-
PROFILE=~/.sas
- profile name used by sas-cli to store the tokens
-
PORT=8080
- set it to what fits your environment.
-
CASSERVER=cas-shared-default
- Set to a valid cas server
-
COMPUTECONTEXT="SAS Job Execution compute context"
- Use one that is appropriate
If using remote mcp server, change the url in redirect to the remote url
{
client_id: 'vscodemcp',
scope: [ 'openid' ],
resource_ids: [ 'none' ],
autoapprove: true,
authorized_grant_types: [ 'authorization_code' ],
access_token_validity: 86400,
allowpublic: true,
redirect_uri: [ 'http://localhost:8080/callback' ]
}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.
- github copilot: http://127.0.0.1:33418/
- claude: https://claude.ai/api/mcp/auth_callback,https://claude.ai/api/auth/callback
This agent provides a unified interface for interacting with SAS Viya resources, including models, jobs, tables, and scoring endpoints. It automates the process of verifying, executing, and formatting requests, ensuring robust and consistent workflows for analytics and machine learning operations.
- VERIFY — Use find-resources to verify target resources exist
- EXECUTE — Use the appropriate execution tool (sas-score-read-table, sas-score-mas-score, sas-score-run-jobdef, sas-score-scr-score, etc.)
- FORMAT — Merge results and return to user
When you receive a SAS request, classify it using request-routing skill:
| Type | Trigger | Strategy | Tool |
|---|---|---|---|
| Find | "find", "locate", "exists" | find-resources | sas-score-find-library, sas-score-find-table, etc. |
| Read | "read", "show", "fetch", "query", "how many", "count by" | read-strategy | sas-score-read-table, sas-score-sas-query |
| Score | "score", "predict", "run model" | score-strategy | sas-score-mas-score, sas-score-run-jobdef, sas-score-scr-score |
| List | "list", "show all" | — | sas-score-list-libraries, sas-score-list-tables, sas-score-list-models, etc. |
Exception: SCR models can score without pre-verification.
Verify resources exist (find-resources)
↓
Execute action (sas-score-read-table, sas-score-mas-score, sas-score-run-jobdef, sas-score-scr-score, etc.)
↓
Merge and format results
Every table operation must explicitly determine whether the table is in CAS or SAS:
- CAS tables: Caslib.table (Casuser, Public, Samples, Formats, etc.)
- SAS tables: LIBREF.table (SASHELP, WORK, SASUSER, etc.)
Use find-resources to determine server if not specified by user.
If model type is ambiguous, default to MAS:
-
score with model X→ MAS (default) -
score with model X.mas→ MAS -
score with model X.job→ Job -
score with model X.jobdef→ JobDef -
score with model X.scr→ SCR (no pre-verification)
Never invent resource names, identifiers, servers, or model types. Always verify or ask.
These terms are overloaded in SAS and must be clarified:
- model: MAS, Job, JobDef, or SCR?
- score/scoring: Running a model on data (not code coverage)
- job: SAS Job or SAS JobDef?
- table: CAS table or SAS dataset? Which library?
- resource: Library, table, model, job, or jobdef?
- read/query: Raw row read or aggregation?
When ambiguous, ask one focused clarifying question.
See the strategies folder:
- request-routing — Universal three-step workflow + examples
- find-resources — How to verify resources exist
- read-strategy — How to read/query tables
- score-strategy — How to score/predict
- sas-score-mcp-serverjs-agent — Main orchestration agent
After completing a SAS Viya request, append a brief Strategy Summary:
---
**Strategy Summary:**
- **Classification**: [Request type you identified]
- **Verification**: [Resources verified or verification skipped]
- **Tool Used**: [Primary tool(s) invoked]
- **Routing Decision**: [Why you chose this path]
Example:
**Strategy Summary:**
- **Classification**: Score request with inline scenario
- **Verification**: Found job simplejob
- **Tool Used**: sas-score-run-jobdef
- **Routing Decision**: Job type (.job suffix) → run-jobdef tool
| Error | Action |
|---|---|
| Resource not found | Ask user to verify name/spelling and server |
| Server ambiguous | Use find-resources to determine CAS vs SAS |
| Model type unclear | Ask: "Is this a MAS, Job, JobDef, or SCR model?" |
| Table column mismatch | Ask user for column → input mapping |
| Empty result | Ask user to adjust filter or criteria |
User: "score a=1, b=2 with model simplejob.job"
Process:
- Classify: Score request, inline scenario, job type
- Verify: Find job simplejob → Found ✓
- Execute:
sas-score-run-job({ name: "simplejob", scenario: { a: 1, b: 2 } }) - Result:
{ a: 1, b: 2, c: 3 }
User: "average MSRP by make for cars from USA in sashelp.cars"
Process:
- Classify: Read request, analytical query
- Verify: SASHELP is default SAS library ✓
- Execute:
sas-score-sas-query({ table: "SASHELP.cars", query: "average MSRP by make where origin='USA'", ... }) - Result: Aggregated data by make
User: "read first 20 customers from Public"
Process:
- Classify: Read request, raw row read
- Verify: Find table customers in Public → CAS ✓
- Execute:
sas-score-read-table({ lib: "Public", table: "customers", server: "cas", limit: 20 }) - Result: 20 customer rows
User: "score all active customers with model risk_model"
Process:
- Classify: Score request, table rows
- Verify: Find model risk_model → MAS ✓, Find table customers → CAS ✓
- Execute:
- Read:
sas-score-read-table({ where: "status='active'" }) - Score:
sas-score-mas-score({ model: "risk_model", scenario: {each row} })
- Read:
- Result: Rows with risk_score appended
| Category | Tool | Purpose |
|---|---|---|
| Find | sas-score-find-library | Verify library exists |
| sas-score-find-table | Verify table exists + determine server | |
| sas-score-find-model | Verify MAS model exists | |
| sas-score-find-job | Verify job exists | |
| sas-score-find-jobdef | Verify jobdef exists | |
| Read | sas-score-read-table | Get raw rows from table |
| sas-score-sas-query | Query with aggregations | |
| Score | sas-score-mas-score | Score with MAS model |
| sas-score-run-jobdef | Run job or jobdef | |
| sas-score-scr-score | Score with SCR model | |
| List | sas-score-list-libraries | Browse all libraries |
| sas-score-list-tables | Browse tables in library | |
| sas-score-list-models | Browse MAS models | |
| sas-score-list-jobs | Browse jobs | |
| sas-score-list-jobdefs | Browse jobdefs |
Ask one focused question if:
- Resource name is missing or ambiguous
- Model type is not specified (.mas/.job/.jobdef/.scr)
- Table library is not specified
- Request involves "model" without type context
- User is asking for aggregation but column mapping is unclear
- Scoring inputs don't match model signature
Do NOT guess. Ambiguity is better resolved than guessed.
Always verify before executing, except:
- List operations (list-* tools don't need pre-verification)
- SCR scoring (SCR can score without pre-check)
This is a three-step, reliable system:
- Classify the request (find/read/score/list)
- Verify resources exist (except list and SCR)
- Execute with the right tool
- Format results + append Strategy Summary
No ambiguity. No guessing. No invented resource names.
Enumerate models published to MAS (Model Aggregation Service).
Parameters:
-
limit(number, default: 10): Number of models to return -
start(number, default: 1): 1-based offset for pagination
Usage:
- "list models"
- "show models"
- "list 25 models"
- "next models" (pagination)
Example:
list models
list 25 models
Locate a specific model deployed to MAS.
Parameters:
-
name(string, required): Exact model name
Usage:
- "find model churnRisk"
- "does model creditScore exist"
- "is model sales_forecast deployed"
Example:
find model myModel
Retrieve detailed metadata for a deployed model including input/output variables, data types, and constraints.
Parameters:
-
model(string, required): Model name as published to MAS
Returns:
- Input variable metadata (names, types, roles, ranges)
- Output variable information
- Model type and description
Usage:
- "What inputs does model X need?"
- "Describe model myModel"
- "Show the variables for sales_forecast"
Example:
model-info model=churnRisk
Score user-supplied scenario data using a MAS-published model.
Parameters:
-
model(string, required): Model name -
scenario(string | object | array, required): Data to score -
uflag(boolean, optional): Prefix model fields with underscore
Scenario formats:
- Comma-separated:
"x=1, y=2" - Object:
{x: 1, y: 2} - Array:
[{x: 1, y: 2}, {x: 3, y: 4}]
Usage:
- "Score this customer with model churnRisk"
- "Run model creditScore with age=45, income=60000"
Example:
model-score model=mycoolmodel scenario={x:1,y:2}
model-score model=cancer1 scenario="age=45, sex=M, tumor=stage2"
Return input/output schema and metadata for an SCR (Score Code Runtime) model.
Parameters:
-
name(string, required): SCR model identifier (URL or name)
Returns:
- Input variables (names, types, required/optional)
- Output variables (predictions, probabilities, scores)
Example:
scr-info name="https://scr-host/models/loan"
Score a scenario using an SCR container model.
Parameters:
-
url(string, required): SCR model identifier (URL) -
scenario(string | object | array, optional): Input values
Usage:
- Run scrInfo first to inspect expected inputs
- Omit scenario to get model metadata
Example:
scr-score url="loan" scenario="age=45, income=60000"
scr-score url="https://scr-host/models/loan" scenario={age:45, income:60000}
Enumerate CAS or SAS libraries.
Parameters:
-
server(cas|sas, default: 'cas'): Target environment -
limit(number, default: 10): Page size -
start(number, default: 1): 1-based offset -
where(string, optional): Filter expression
Usage:
- "list libs"
- "list libraries"
- "show cas libs"
- "list sas libs"
Example:
list libraries
list sas libs
show me 25 cas libraries
Locate a specific CAS or SAS library.
Parameters:
-
name(string, required): Exact library name -
server(cas|sas, default: 'cas'): Target environment
Usage:
- "find library Public"
- "does library SASHELP exist"
- "is PUBLIC library available in cas"
Example:
find lib Public
find library sasuser in sas
Enumerate tables within a specific CAS or SAS library.
Parameters:
-
lib(string, required): Library to inspect -
server(cas|sas, default: 'cas'): Target environment -
limit(number, default: 10): Page size -
start(number, default: 1): 1-based offset
Usage:
- "list tables in Samples"
- "show tables in sashelp"
- "list 25 tables in Public"
Example:
list tables in samples
show 25 tables in sashelp
Locate a table in a specified library.
Parameters:
-
lib(string, required): Library to search in -
name(string, required): Table name or substring -
server(cas|sas, default: 'cas'): Target environment
Usage:
- "find table iris in Public library in cas"
- "find table cars in sashelp in sas server"
Example:
find table iris in Public
find table cars in sashelp in sas
Return metadata about a table including columns, types, and statistics.
Parameters:
-
table(string, required): Table name -
lib(string, required): Library containing the table -
server(cas|sas, default: 'cas'): Target environment
Returns:
- Column metadata (name, type, label, formats)
- Table statistics (row count, file size, timestamps)
Usage:
- "describe table cars in Public"
- "info on table mydata in mylib"
Example:
table-info table=cars lib=Public
describe table air in lib sashelp on sas server
Retrieve rows from a table in a CAS or SAS library.
Parameters:
-
table(string, required): Table name -
lib(string, required): Library containing the table -
server(cas|sas, default: 'cas'): Target environment -
start(number, default: 1): Starting row (1-based) -
limit(number, default: 10): Maximum rows to return -
where(string, optional): SQL-style WHERE clause -
format(boolean, default: true): Return formatted or raw values -
row(number, optional): Read a specific row
Usage:
- "read table customers"
- "show me 10 rows from sales"
- "read from orders where status = 'shipped'"
Example:
read table cars in Samples
show 25 rows from customers
read orders where status = 'shipped' limit 50
read row 15 from employees in mylib on sas
Execute SQL queries on SAS tables using PROC SQL.
Parameters:
-
table(string, required): Table in format libname.tablename -
query(string, required): Natural language query -
sql(string, optional): Generated SQL SELECT statement -
job(string, default: 'sas_sql_tool'): Job to run query on
Workflow:
- User provides natural language query
- Convert to SAS PROC SQL SELECT statement
- Execute and return results
Example:
sasquery table=mylib.clm_dental query="Total paid amount, unique patients by procedure code"
sasquery table=mylib.students query="How many students in each year as percentage"
Enumerate SAS Viya job assets.
Parameters:
-
limit(number, default: 10): Number of jobs to return -
start(number, default: 1): 1-based offset -
where(string, optional): Filter expression
Usage:
- "list jobs"
- "show jobs"
- "list 25 jobs"
Example:
list jobs
list 25 jobs
Locate a specific SAS Viya job.
Parameters:
-
name(string, required): Exact job name
Usage:
- "find job cars_job_v4"
- "does job sales_summary exist"
- "verify job ETL_Daily"
Example:
find job cars_job_v4
Execute a job on a SAS Viya server.
Parameters:
-
name(string, required): Job name -
scenario(string | object, optional): Input parameters
Returns:
- Log, listing, and tables (depending on job definition)
Example:
run job xyz param1=10,param2=val2
run-job myjob scenario a=10,b=20
job myjob scenario a=10,b=20
Enumerate SAS Viya job definition assets.
Parameters:
-
limit(number, default: 10): Number to return -
start(number, default: 1): 1-based offset -
where(string, optional): Filter expression
Usage:
- "list jobdefs"
- "show job definitions"
Example:
list jobdefs
list 25 jobdefs
Locate a specific job definition.
Parameters:
-
name(string, required): Exact jobdef name
Usage:
- "find jobdef cars_job_v4"
- "does jobdef ETL exist"
Example:
find jobdef metricsRefresh
Execute a job definition on a SAS Viya server.
Parameters:
-
name(string, required): Job definition name -
scenario(string | object, optional): Input parameters
Returns:
- Log, listing, and tables
Example:
run-jobdef xyz param1=10,param2=val2
jobdef myjobdef scenario a=10,b=20
Execute arbitrary SAS code or stored programs on a SAS Viya server.
Parameters:
-
src(string, required): SAS code or .sas filename -
folder(string, optional): Server folder path if src is a filename -
scenario(string | object, optional): Input parameters -
output(string, optional): Name of output table returned as JSON -
limit(number, default: 100): Max rows from output table
Usage:
- Direct code execution
- Running stored .sas files
- With input parameters and output capture
Example:
run program "data a; x=1; run;"
program "data work.a; x=1; run;" output=a limit=50
run program sample folder=/Public/models output=A limit=50
program sample folder=/Public/models scenario="name='John', age=45" output=a
Submit and execute a SAS macro on a SAS Viya server.
Parameters:
-
macro(string, required): Macro name (without leading %) -
scenario(string, optional): Parameters or SAS setup code
Scenario formats:
- Comma-separated:
"x=1, y=abc"→ converted to %let statements - Raw SAS:
"%let x=1; %let y=abc;"→ passed through unchanged
Example:
run macro abc with scenario x=1, y=2
run macro summarize with scenario %let x=1; %let y=2;
Set the CAS and SAS server contexts for subsequent tool calls.
Parameters:
-
cas(string, optional): CAS server name -
sas(string, optional): SAS compute context name
Returns:
- Current CAS and SAS context values
Usage:
- Switch between server environments
- Check current context (call with no parameters)
Example:
set-context cas=finance-cas-server
set-context sas="SAS Studio Compute Context"
set-context (returns current context)
Use this to verify that the mcp server is up and running.
Compute a numeric score based on two input values using the formula: (a + b) × 42
Parameters:
-
a(number, required): First numeric input -
b(number, required): Second numeric input
Returns:
- Numeric result: (a + b) × 42
Usage:
- "Calculate deva score for 5 and 10"
- For sequences: chain calls left-to-right
Example:
deva-score a=5 b=10 // returns 630
deva-score a=1 b=2 // returns 126
| Category | Tool Count | Tools |
|---|---|---|
| Model Management | 6 | list-models, find-model, model-info, model-score, scr-info, scr-score |
| Library Management | 2 | list-libraries, find-library |
| Table Operations | 5 | list-tables, find-table, table-info, read-table, sas-query |
| Job Management | 6 | list-jobs, find-job, job, list-jobdefs, find-jobdef, job-def |
| Program Execution | 2 | run-program, run-macro |
| Context & Config | 1 | set-context |
| Utilities | 1 | deva-score |
| Total | 24 |
- List tools to discover available resources
- Find tools to locate specific items
- Info tools to inspect metadata
- Execution tools to perform actions
Many list tools support pagination:
- First page:
{ start: 1, limit: 10 } - Next page:
{ start: 11, limit: 10 }
Tools that interact with data support server parameter:
-
'cas'- CAS server (default) -
'sas'- SAS compute server
Tools accepting scenarios support multiple formats:
-
String:
"x=1, y=2" -
Object:
{x: 1, y: 2} -
Array:
[{x: 1, y: 2}]
- All tools are designed to work with SAS Viya environments
- Authentication and connectivity are handled by the MCP server configuration
- Tools are stateless unless context is explicitly set using set-context
- Error handling returns structured error objects from the backend
- Case sensitivity varies by backend (library/table names may be case-insensitive)
Document generated for @sassoftware/mcp-serverjs
Last updated: December 2024