SAS Viya について
SAS Viya MCP Serverは、分析担当者やエージェントがMCP経由でSAS Viyaを操作するためのサーバーです。コード実行からデータ、レポート、モデルまで扱い、階層別のツール選択と読み取り専用設定に対応します。
主な機能
- 01SASコードとコンピュート処理の実行
- 02データ、ファイル、レポートの確認と操作
- 03AutoMLの実行、モデル管理とスコアリング
- 04階層別のツール選択と読み取り専用設定
- 05インタラクティブビューとプロンプトテンプレート
活用シーン
- 01エージェント経由でSAS分析コードを実行
- 02データ、ログ、可視化レポートを確認
- 03AutoMLプロジェクトの学習とモデル評価
MCP 対応
HTTPまたはstdioで、SAS Viyaのツール、リソース、プロンプトをMCPクライアントに公開します。OAuth 2.0 PKCE認証、階層別のツール制限、読み取り専用設定に対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e VIYA_ENDPOINT -e SSL_VERIFY -e CLIENT_ID -e COMPUTE_CONTEXT_NAME -e MCP_TIERS -e MCP_READ_ONLY -e MCP_APPS -e MCP_STATELESS_HTTP -e VIYA_CLIENT_TIMEOUT ghcr.io/sassoftware/sas-mcp-server:1.19.0VIYA_ENDPOINTBase URL of your SAS Viya environment, e.g. https://viya.example.com. No trailing slash.SSL_VERIFYSet false only for a self-signed Viya certificate. Disables verification for the whole process, so prefer a trusted certificate.CLIENT_IDSASLogon OAuth client id used for the token refresh exchange.COMPUTE_CONTEXT_NAMECompute context that backs SAS code execution.MCP_TIERSExpose only some tool tiers, e.g. 0-4 or 0,1,7. Empty exposes all 92 tools. Tiers: 0 Compute, 1 Data Discovery, 2 Data Operations, 3 Reports, 4 Batch Jobs, 5 AutoML, 6 Models, 7 Decisioning, 8 Workbench, 9 Business Glossary.MCP_READ_ONLYExpose only tools that neither change server-side state nor cause server-side work (51 of 92). Composes with MCP_TIERS.MCP_APPSRegister interactive views (MCP Apps) for the data, SAS log and glossary tools. Additive: text-only clients are unaffected. Set false to register none.MCP_STATELESS_HTTPServe HTTP requests without an MCP session. Needed by clients that speak only the sessionless 2026-07-28 protocol revision (claude.ai custom connectors); the legacy handshake works either way.VIYA_CLIENT_TIMEOUTTimeout in seconds for every SAS Viya REST call the tools make.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/sassoftware/sas-mcp-server:1.19.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
SAS Viya MCP サーバー
SAS Viya 環境で SAS コードを実行したり、AutoML プロジェクトをトレーニングしたり、モデルをスコアリングしたり、その他さまざまな処理を行うための Model Context Protocol(MCP)サーバーです。
機能
- SAS Viya のアナリティクスライフサイクル全体を対象とする、10 の選択可能なティアにわたる 92 個のツール
- データ、SAS ログ、用語集の編集に対応したインタラクティブビュー(MCP Apps)。Claude、ChatGPT、Microsoft 365 Copilot、VS Code、Cursor など、これらを表示できるクライアントで利用できます
- SAS コードの改善に役立つプロンプトテンプレート
- PKCE フローによる OAuth2 認証
- MCP クライアントと互換性のある HTTP ベースの MCP サーバー
記事と動画
ここでは、さまざまなツールで SAS MCP サーバーを使用、統合する方法や、SAS MCP サーバーを使って何を構築できるかを紹介する記事をご覧いただけます。
- REST API から AI エージェントへ:SAS Viya MCP サーバーが重要な理由
- SAS Viya MCP サーバーを使って GitHub Copilot を SAS Viya に接続する
- 独自のキーを使用:GitHub Copilot CLI と SAS Viya MCP サーバー
- GitHub Copilot で SAS Viya MCP サーバーを活用する
- SAS Viya MCP サーバーを使って Claude Code CLI を SAS Viya に接続する
- Claude Code CLI で SAS Viya MCP サーバーを活用する
- SAS Retrieval Agent Manager(RAM)との統合
- SAS Viya MCP サーバーを活用する 5 つの業界別ユースケース(動画)
はじめに
前提条件
-
必須
- Python 3.12+
- uv 0.8+
- コンピュートサービスを備えた SAS Viya 環境
- MCP 用に Viya 環境をセットアップします
- configuration.md を参照してください
-
任意
- Docker:コンテナーのセットアップを参照してください
- Kubernetes:deploy/ に Contour または nginx のサンプルマニフェストと Helm チャートがあります
インストール
- リポジトリをクローンします:
git clone <repository-url>
cd sas-mcp-server
- 依存関係をインストールします
uv sync
注:デフォルトでは、プロジェクトのルートディレクトリに .venv という名前の仮想環境が作成されます。
何らかの理由で仮想環境が作成されない場合は、uv venv を実行してから、uv sync を再度実行してください。
使用方法
- 環境変数を設定します:
cp .env.sample .env
.env を編集して、次の値を設定します
VIYA_ENDPOINT=https://your-viya-server.com
- MCP サーバーを起動します(以下のデプロイモードの選択を参照してください):
オプション A:HTTP モード(サーバーを事前に起動し、MCP クライアントから接続します)
uv run app
デフォルトでは、サーバーは http://localhost:8134/mcp で利用できます。認証はブラウザーでの OAuth2 PKCE フローを介して行われます。
オプション B:Stdio モード(MCP クライアントが必要に応じてサーバーを起動します)
一度認証します。同等の方法が 2 つあります:
# Option B1 — if you have the SAS Viya CLI installed:
sas-viya auth loginCode
# Option B2 — built-in helper, no external CLI needed (Viya 2022.11+):
uv run sas-mcp-login
どちらのフローでも、アクセストークンがローカルキャッシュに書き込まれます(それぞれ ~/.sas/credentials.json と ~/.sas-mcp-server/credentials.json)。Stdio サーバーは、見つかった方を読み込みます。トークンの有効期限が切れたら、同じコマンドを再実行してください。
次に、サーバーを直接起動するように MCP クライアントを設定します(以下を参照してください)。
オプション C:Docker/Podman(コンテナ化されたデプロイ)
GitHub Container Registry からビルド済みイメージをプルします:
docker pull ghcr.io/sassoftware/sas-mcp-server:latest
docker run -e VIYA_ENDPOINT=https://your-viya-server.com -p 8134:8134 ghcr.io/sassoftware/sas-mcp-server:latest
または、ソースからローカルでビルドします:
docker build -t sas-mcp-server .
docker run -e VIYA_ENDPOINT=https://your-viya-server.com -p 8134:8134 sas-mcp-server
利用可能なイメージタグ:
latest— 最新のタグ付きリリース<major>.<minor>.<patch>(例:1.0.0)— 特定のリリース<major>.<minor>(例:1.0)— マイナーリリースの最新パッチedge—mainの最新コミット(未リリース、テスト用)sha-<short>— 特定のコミットに固定
既存の Viya トークンを持つプログラムクライアント
呼び出し元がすでに Viya アクセストークンを保持している場合(たとえば、SAS Viya CLI を使って取得した自動化スクリプト)、ALLOW_RAW_BEARER=true を指定して HTTP モードのサーバーを起動し、トークンを直接渡します:
curl -H "Authorization: Bearer $VIYA_TOKEN" http://localhost:8134/mcp ...
サーバーは Viya の JWKS に対してトークンを検証し、MCP JWT の交換を経由せず、そのまま上流で使用します。デフォルトの OAuth2 PKCE フローも引き続き動作し、両方のクライアントタイプが同じ /mcp エンドポイントを共有します。
Viya API を意図的に認証なしで公開している場合(たとえば、ローカル/開発用の Compute API エンドポイント)、VIYA_AUTH=false を設定すると、HTTP モードと Stdio モードの両方で、すべての SASLogon/OAuth フローをバイパスできます。このモードでは、サーバーは Authorization ヘッダーを付けずに上流へのリクエストを送信します。
Compute のデプロイ環境で /compute/contexts が公開されず、固定セッションのみがサポートされている場合は、COMPUTE_SESSION_ID=<session_id> を設定します。Compute ツールはコンテキストに基づくセッションを作成せず、そのセッションを直接使用します。
デプロイモードの選択
| HTTP | Stdio | Docker | Kubernetes | |
|---|---|---|---|---|
| 実行方法 | 別途起動する長時間稼働サーバー | MCP クライアントが必要に応じて起動 | コンテナ化された HTTP サーバー | イングレスの背後で実行するコンテナ |
| 認証 | OAuth2 PKCE フロー(ブラウザーのポップアップ) | sas-viya CLI または sas-mcp-login を使ったトークンのキャッシュ | OAuth2 PKCE フロー(ブラウザーのポップアップ) | PKCE および/または Viya のベアラートークン |
| 最適な用途 | 複数ユーザーまたは共有環境。本番環境に近い環境 | 単一ユーザーのローカル開発。手軽な実験 | チームでのデプロイ。CI/CD。Python がインストールされていない環境 | Viya と併せた、組織内での共有デプロイ |
| 必要なもの | Python + uv | Python + uv(任意で sas-viya CLI) | Docker または Podman のみ | クラスター、イングレスコントローラー、TLS シークレット |
| 認証情報の保存 | いいえ — ユーザーが対話形式で認証します | いいえ — アクセストークンのみ(パスワードは保存しません)をキャッシュします | いいえ — ユーザーが対話形式で認証します | いいえ — 署名キーを Secret に保存し、ユーザー自身が認証します |
| MCP クライアントの設定 | クライアントの接続先を http://localhost:8134/mcp に設定 | クライアントが uv run app-stdio を実行 | クライアントの接続先を http://host:8134/mcp に設定 | クライアントの接続先を https://<viya-host>/mcp に設定 |
簡単なガイド:
- 始めたばかり、または試してみたい場合:stdio を使います。
sas-viya auth loginCodeまたはuv run sas-mcp-loginを一度実行すれば、MCP クライアントがサーバーのライフサイクルを管理します。 - 安全な対話型認証が必要な場合:HTTP を使います。パスワードは保存されず、ユーザーごとにブラウザーから認証します。
- チーム向け、またはサーバーにデプロイする場合:Docker を使います。移植性があり、ホストに Python を依存させず、オーケストレーターと簡単に連携できます。
- 組織全体で実行する場合:Kubernetes を使います。サンプルマニフェストと Helm チャートは deploy/ にあります。OAuth フローに必要なルーティング設定も含まれています。対応するのは Contour(チャートのデフォルトであり、既存のホスト名上のパスプレフィックスの下にサーバーをマウントできる唯一の選択肢)または ingress-nginx です。
- Gemini CLI を使用する場合:stdio を使います。Gemini CLI は HTTP モードやブラウザーベースの OAuth をサポートしていません。Gemini CLI の設定を参照してください。
- Microsoft 365 Copilot と連携する場合:Kubernetes(またはその他のリモート HTTPS デプロイ)を使います。Copilot の宣言型エージェントが接続できるのは、リモートでホストされた MCP サーバーのみです。すぐにサイドロードできるエージェントパッケージと手順は examples/m365-copilot/ にあります。
- Microsoft Copilot Studio のエージェントに追加する場合:同じリモート HTTPS デプロイに加えて、
MCP_TOOL_RENAME=catalog_=infocat_を指定します。Copilot Studio のエージェントランタイムは、catalog_で始まるツール名を処理できません。手順は examples/copilot-studio/ にあります。 - Microsoft のどの方法が適しているか分からない場合:examples/microsoft-copilot.md では、宣言型エージェントと Copilot Studio エージェントを比較し、両方に対応するデプロイの設定を説明しています。
- クライアントのサーバーカタログからインストールする場合:この方法では、公開済みコンテナを HTTP サーバーとしてではなく、stdio モード(
app-stdio)で実行します。そのため、~/.sasのトークンキャッシュを使って認証します。このキャッシュはコンテナ内の/app/.sasにマウントする必要があります。
公開するツールの制限(ティア)
ツールは番号付きのティアに分類されています。デフォルトでは、サーバーはすべてのツールを公開します。MCP_TIERS を設定すると、一部のティアだけを公開できます。クライアントのツール一覧を小さく、目的に絞ったものにしたり、デプロイ環境で提供すべきでない機能を非表示にしたりする場合に便利です。範囲とカンマ区切りのリストを指定できます(例:MCP_TIERS=0-4 または MCP_TIERS=0,1,6,7)。未設定の場合は、すべてのティアが対象です。
| Tier | Group |
|---|---|
| 0 | コンピューティングコンテキストとコード実行 |
| 1 | データ探索 |
| 2 | データ操作とファイル |
| 3 | レポートと可視化 |
| 4 | バッチジョブと非同期実行 |
| 5 | 自動機械学習 |
| 6 | モデル管理とスコアリング |
| 7 | 意思決定(SAS Intelligent Decisioning) |
| 8 | Workbench(コード実行のみ) |
| 9 | ビジネス用語集(SAS Data Governance) |
# Example: expose only compute/discovery/data-ops and reporting
MCP_TIERS=0-3 uv run app
読み取り専用モード
MCP_READ_ONLY=true を設定すると、サーバー側の状態を変更せず、サーバー側の処理も開始しないツールだけが公開されます。92 個のツールのうち 51 個が対象です。除外されたツールは登録されないため、クライアントのツール一覧には一切表示されません。モデルから見えないので、実行を試みることもありません。
これはティアに対するフィルターであり、それ自体がティアではありません。読み取りと書き込みの区分はすべてのティアにまたがります(ティア 3 には get_report と delete_report の両方があります)。次の 2 つの設定は併用できます。
# Every read tool, all tiers
MCP_READ_ONLY=true uv run app
# Read tools of the reporting and decisioning tiers only
MCP_TIERS=3,7 MCP_READ_ONLY=true uv run app
定義は厳格です。書き込みも処理の開始も行わないツールのみが該当します。明らかな作成/更新/削除ツールのほか、次のツールも除外されます。
| 除外対象 | 理由 |
|---|---|
execute_sas_code、submit_batch_job | 任意のコードを実行できるため、削除を含むあらゆる操作が可能です |
score_data、catalog_run_agent、catalog_run_adhoc_analysis | データを返す場合でも、サーバー側のジョブを開始し、実行記録を残します |
promote_table_to_memory | CAS のインメモリ状態を変更します |
cancel_job、reset_compute_session | 呼び出し元が所有するものを破棄します |
分類はフェイルクローズ方式です。読み取り専用として明示的に分類されていないツールは除外されます。一覧は src/sas_mcp_server/tools/_access.py にあり、テストで登録済みのすべてのツールが対象になっていることを検証します。そのため、新しく追加されたツールが読み取り専用モードに誤って含まれることはありません。
ツールのアノテーション(クライアントに伝える情報)
同じ分類が、読み取り専用モードの有効・無効にかかわらず、各 tools/list エントリーの MCP ツールアノテーションとしてすべてのクライアントに通知されます。
| ヒント | 導出元 |
|---|---|
readOnlyHint | 上記の読み取り専用ツールセットそのものです。単一の表から導出されるため、クライアントに伝える内容と MCP_READ_ONLY による制御が食い違うことはありません |
destructiveHint | 既存の状態を削除または上書きできるツールです。任意のコード(execute_sas_code、submit_batch_job)、delete_*、cancel_job、reset_compute_session、update_* の PUT、apply_report_operations、create_report/copy_report(競合時の replace ポリシー)、publish_ml_champion_model が該当します |
idempotentHint | 読み取り、update_* の PUT、削除、cancel_job、reset_compute_session、promote_table_to_memory が該当します |
openWorldHint | Viya の外部にアクセスできるツールのみが対象です。任意のコード、およびアップロードツールの url ソースが該当します |
クライアントはこれらのヒントを使って承認 UX を調整します。たとえば Claude は、読み取り専用ツールをワンクリックで承認できるようまとめ、破壊的なツールの実行前に警告します。また、ユーザーに処理を中断して確認すべきタイミングの判断にも使います。これらはあくまでヒントであり、強制力はありません。仕様では、サーバーが信頼できる場合を除き、クライアントはヒントを信頼できないものとして扱うよう定められています。サーバー側の制御には、引き続き MCP_READ_ONLY を使用します。アノテーションがない場合、クライアントは仕様の悲観的なデフォルト(書き込み可能、破壊的、オープンワールド)をすべてのツールに適用する必要があるため、アノテーションによって操作が煩雑になることはありません。ブラウザーのランディングページでは、同じヒントに基づいて各ツールに read-only/write/destructive のラベルを表示します。
インタラクティブビュー(MCP Apps)
ツールがどれほど適切な形式で結果を整えても、テキストとしては読みづらい結果もあります。テーブルの何百行ものデータ、SAS ログ、フォーム一式分の入力属性などです。そのため、10 個のツールには MCP Apps extension を使った小さな HTML ビューも用意されています。対応クライアントは、結果の横にあるサンドボックス化されたフレームにこれを表示します。
| ビュー | ツール | 機能 |
|---|---|---|
| データグリッド | query_data, get_castable_data, get_compute_table_data | 行の並べ替え、フィルタリング、ページ送りができます。ページ送りではビューから同じツールを再度呼び出すため、モデルが最初のページだけを保持したまま、ユーザーは大きなテーブルを閲覧できます。 |
| SAS ログ | execute_sas_code, get_job_log, submit_batch_job | 色分けされた ERROR / WARNING / NOTE 行、次の問題への移動、問題のみ表示およびノート非表示のフィルター、独立したタブでのリスティング、そして Results タブでの SAS 独自の HTML 出力(HTML results を参照)を表示します。バッチジョブを送信すると、終了するまでビューからポーリングし、その後ログを取得します。 |
| 用語集の用語エディター | get_glossary_term_type, get_glossary_term | 用語の種類からフォームを生成します。ブール値には実際のチェックボックス、日付ピッカー、複数選択などを用意し、属性値の入力ミスを防ぎます。用語を作成または更新し、保存内容をアシスタントに伝えます。まだ下書きの用語はここから公開できます。API でこれが許可される方法はこれだけです。 |
| 用語集ブラウザー | list_glossary_terms | 詳細ペインの横に、移動可能なツリーとして用語集全体を表示します。名前、定義、説明、属性値を横断して検索でき、用語の種類や「アセットあり」でフィルタリングできます。パンくずリスト、子項目のカード、属性、割り当てられたアセット、階層のサンバースト図も表示します。仕切りをドラッグしてツリーペインのサイズを変更したり、完全に非表示にしたりできます。リスティング固有のフィルターが初期フィルターになり、残りの用語集はビューがページ単位で読み込むため、モデルが保持するのは最初のページだけです。下書きは作成者以外には見えません。そのため、気づく場所はツリーです。下書きは詳細ペインから公開できます。 |
| 用語集のインポート | import_glossary_terms | dry_run=true の場合、送信される順序で行を表示し、解決済みの親パスを含め、CSV 独自の Definition 列と Description 列を分けたまま表示します。また、Import ボタンも表示します。実際にインポートした後は、各行の結果と、その行が作成した用語の ID を表示します。用語が新規か既存かも含まれます。インポートジョブ自体はどちらの場合も成功として数えます。 |
どのビューにも ⤢ ボタンがあり、ホストが対応している場合は全画面表示で開きます(Claude は対応しています)。横幅の広いテーブルや長いログは、ここで読むことを想定しています。対応していないホストでは、このボタンは表示されません。
これらはすべて追加機能です。ツールの戻り値は変わらないため、この拡張機能に対応していないクライアント(Claude Code、スクリプト、古いクライアントなど)には、これまでとまったく同じものが表示されます。ビューからのリクエストはすべて、セッションのトークンを使った通常のツール呼び出しとして、ホストを経由してこのサーバーに送られます。ブラウザーが Viya と直接通信することはありません。また、MCP_TIERS または MCP_READ_ONLY によってデプロイ環境で利用を制限されているツールには、ビューもありません。そのツールを呼び出すコントロールもビュー内に表示されないため、読み取り専用のデプロイ環境では、用語集ブラウザーに Publish ボタンが表示されません。押しても失敗するだけのボタンが表示されることはありません。ページはすべて完全にインライン化されています。ベンダー提供の @modelcontextprotocol/ext-apps ブリッジも含まれるため、CSP 宣言を無視するホストや、エアギャップ環境の Viya でも表示できます。MCP_APPS=false の場合、ビューは登録されません。
ビューが表示されるかどうかは、クライアントと接続方法によって異なります。
| クライアント | 表示 |
|---|---|
| ChatGPT、Microsoft 365 Copilot、GitHub Copilot を使用する VS Code、Cursor、Goose | 表示されます — これらのクライアントは拡張機能を実装しています。 |
| HTTP サーバーにカスタムコネクターとして接続された Claude(web、Desktop、Cowork) | SAS ログビューの「結果」タブを含めて表示されます。このコネクターは、ハンドシェイクにセッションがない 2026 プロトコル改訂版を使用するため、サーバーで MCP_STATELESS_HTTP=true を設定し、Anthropic のサーバーからアクセスできる URL を指定する必要があります。 |
claude_desktop_config.json でサーバーを設定した Claude Desktop(stdio サーバーのみ受け付けます) | Claude Desktop 2.2553(2026 年 9 月 22 日)以降は表示されません。 Desktop はローカルサーバーのツールをブリッジ経由でチャットに渡しますが、そのブリッジは各ツールのメタデータを再構築してビューとの関連付けを削除するため、チャットがページを要求することはありません。ツールはこれまでどおり動作し、結果はテキストで返されます。また、execute_sas_code は引き続き HTML 結果へのリンクを返します。anthropics/claude-ai-mcp#1069 として報告されています。 |
| Microsoft Copilot Studio エージェント | 表示されません — エージェントのランタイムは拡張機能を実装していません(UI 機能を通知せず、ビューを読み取ることもありません)。execute_sas_code は引き続き HTML 結果へのリンクを返します。 |
| Claude Code | 表示されません — 設計上、テキストのみです。 |
ビュー内のコントロールはほかのツールを呼び出します(結果タブはページを download_file 経由で読み込みます。Tier 2)。そのため、これらの Tier を利用できない構成では、コントロールなしでビューが表示されます。ビューの URI にはページのフィンガープリントが含まれており(ui://sas-viya/sas-log/execute_sas_code.<hash>.html)、サーバーのバージョン、ページファイル、Tier の選択に応じて変わります。ホストは URI を使ってページをキャッシュするためです。claude.ai では、コネクターを削除して再追加した場合でもキャッシュされます。古いツール一覧を保持しているホスト向けに、通常の URI も提供されます。
HTML 結果
execute_sas_code は SAS ログとリスティングをテキストで返し、モデルはこの内容を読み取ります。デフォルトでは、SAS Data and AI Studio に表示されるページも生成します。ODS でスタイル設定されたテーブルと描画されたグラフを含み、そのページへのリンクも返します。
- 仕組み。 コンピュートコンテキストは HTML 出力先を独自に開かないため、サーバーは
ods html5ステートメントとその終了ステートメントの間でコードを実行します。終了ステートメントの前には;*';*";*/;run;quit;が挿入されます。これにより、コードで開いたままになっているもの(終了していないステートメント、引用符またはコメント、あるいはrun;のないステップ)が終了し、終了ステートメントが実行されます。これらはモデルが読むログには表示されません。html_results=falseの場合、コードは指定されたとおりに送信されます。 - リンク。 コードが何かを出力すると、ページは Viya Files サービスに保存され、結果に
html_results_urlが追加されます。ブラウザーで開くと、SAS Viya へのサインインを求められます。ファイルはどのフォルダーにも属さないため、Viya のデフォルトルールにより、コードを実行したユーザーと管理者のみが開けます。ページは有効期限を設定せずに保存されます。これは Files サービスのデフォルトであり、削除されるまで残ります。 - SAS ログビューでは、ページは「結果」タブに表示され、コードが正常に実行された場合は最初に表示されます。ビューは
download_file経由でページを取得するため、Tier 2 のない構成ではリンクは表示されますが、タブは表示されません。 - コスト。 出力先を開いて閉じる処理により、ジョブの実行時間が約 0.1 秒増え、ページの保存にはリクエストが 1 回追加されます。ページ本体は 40~70 KB で、その大部分を ODS のスタイルシートが占めます。ページ本体がモデルのコンテキストに入ることはなく、リンクだけが入ります。
利用可能なツール
以下の見出しは、上記の番号付きティアに対応しています。そのため、MCP_TIERS で公開するツールを直接指定できます(例:MCP_TIERS=0-3 は Tier 0~3 を指定します)。
Tier 0 — コンピューティングコンテキストとコード実行
- execute_sas_code:SAS コードのスニペットを実行し、実行結果(ログとリスティング出力)と、
html_results=falseの場合を除き HTML results へのリンクを取得します。ユーザーごとに再利用可能なコンピューティングセッションで実行され、呼び出し間もセッションがウォーム状態に保たれるため、SAS の状態(WORK テーブル、マクロ変数、割り当て済みの libref)は連続する呼び出し間で保持されます。新しい状態で開始するには、reset_compute_session を使用してください。 - list_compute_contexts:利用可能なコンピューティングコンテキストを一覧表示します。
- reset_compute_session:コンテキストのキャッシュ済みコンピューティングセッションを削除し、SAS の状態を破棄します。次回の呼び出しでは、新しいセッションが開始されます。
Tier 1 — データの検出
SAS Data Governance(メタデータの検出とプロファイリング):
- catalog_search:SAS カタログ検索文法(フリーテキスト、
AssetType:Reportのようなファセット、範囲)を使用して、アセット(テーブル、列、レポートなど)をカタログから検索します。各検索結果にはresource_uriが含まれ、対応するツール(例:get_report、get_castable_data)に渡すことができます。 - catalog_search_helper:カタログのクエリ方法を確認できます。利用可能なファセット、または特定のファセットで有効な値を一覧表示し、正確な
catalog_searchクエリを作成できます。 - catalog_find_instance:ソースアセットの
resource_uriに対応するカタログの instance を特定し、インスタンス ID を手動で扱うことなく、検索結果をプロファイリングおよびダウンロードツールにつなぎます。 - catalog_run_adhoc_analysis:テーブルのアドホックプロファイリングジョブを送信します。NLP による拡充(言語、感情、セマンティック ID)はデフォルトで有効になっており、
informationPrivacy、nlpTerms、nlpTags、mostImportantFieldsに値が入力されます。 - catalog_get_adhoc_analysis:プロファイリングジョブの完了を確認し、対象インスタンスを照合します。結果がアセットに反映されると
profile_readyを報告するため、ダウンロードが早すぎるタイミングで実行されることを防げます。 - catalog_download_table_profile:
instance_idまたはresource_uriを指定して、テーブルのデータディクショナリと列プロファイルを CSV としてダウンロードします。 - catalog_list_agents:カタログの検出エージェント(メタデータを取り込むクローラー)を一覧表示します。
- catalog_run_agent:検出エージェントの実行を開始します(非同期)。データソースをクロールして、カタログのメタデータを更新します。
- catalog_get_agent_history:エージェントの実行履歴を確認します。各実行のステータスと、列挙・追加・更新・削除されたメタデータの量を確認できます。
CAS データ(メモリ内):
- list_cas_servers:利用可能な CAS サーバーを一覧表示します。
- list_caslibs:サーバー上の CAS ライブラリを一覧表示します。
- list_castables:CAS ライブラリ内のテーブルを一覧表示します。
- list_source_tables:まだメモリに読み込まれていないソーステーブル(プロモーション候補)を一覧表示します。
- get_castable_info:テーブルのメタデータ(行数、列、サイズ)を取得します。
- get_castable_columns:列名、型、ラベル、フォーマットを取得します。
- get_castable_data:CAS テーブルからサンプル行を取得します。
- query_data:CAS またはコンピューティングデータに対して FedSQL の
SELECTを実行し、行を取得します。両方のストレージ階層で共通の SQL インターフェースを使用します。targetで階層を選択してください(casはcaslib.table、computeはlibref.table)。結合、サブクエリ、集計、UNIONを使用できます。行数の上限はツールによってサーバー側で適用されます(不正なLIMITは CAS によって黙って破棄されるため、記述したLIMITは無視されます)。必要に応じて、クエリをCREATE VIEWのテキストとして返し、自分で実行することもできます。読み取り専用です。書き込みは事前チェックで拒否されます。また、マクロプロセッサが SQL の外部で展開してしまうため、SAS マクロトリガー(%/&)も拒否されます。2 つの階層を 1 つのステートメントで結合することはできません。
コンピューティングライブラリ(コンピューティングコンテキスト内の SAS/Compute):
- list_compute_libraries:コンピューティングコンテキストに割り当てられた SAS ライブラリ(libref)を一覧表示します。
- list_compute_tables:コンピューティングコンテキスト内の SAS ライブラリにあるテーブルを一覧表示します。
- list_compute_columns:SAS ライブラリ内のテーブルの列を一覧表示します。
- get_compute_table_data:SAS ライブラリ内のテーブルから行のページを取得します。値は SAS で表示される形式で返されます。
get_castable_dataに対応するコンピューティング階層のツールです。
Tier 2 — データ操作とファイル
- upload_data:データファイルを CAS テーブルにアップロードします。
file_path(サーバーがディスクから読み取ります)またはurl(サーバーが取得し、エンドポイントが必要とするマルチパートアップロード形式に変換します)から、サーバー側で読み取るため、データがモデルのコンテキストを通過することはありません。casManagementuploadTableAPI が受け付ける形式(csv、tsv(csv + タブ区切り)、xls、xlsx(単一シート)、sas7bdat、sashdat)を取り込みます。形式は拡張子から自動検出されるか、data_formatで指定できます。parquet はこのエンドポイントでは受け付けられないため、事前に拒否され、対処方法(パスベースの caslib 経由で読み込み、promote_table_to_memoryを実行するか、csv/sas7bdat に変換する)が案内されます。 - upload_inline_data:文字列として渡されたインラインの csv/tsv テキストから、小さな CAS テーブルを作成します(モデルがその場で作成するルックアップ/マッピングテーブルや、簡単なテストテーブルなど)。ペイロードはモデルのコンテキストを通過するため、ごく小さなテーブル専用です。ファイルや、それより大きなデータには upload_data を使用してください。
- promote_table_to_memory:ソーステーブルをグローバルスコープのメモリに読み込みます(べき等)
- list_files:Viya Files Service 内のファイルを一覧表示します
- upload_file:ファイルを Viya Files Service にアップロードします。必要に応じて Content フォルダー内に配置できます(
parent_folder_uri)。コンテンツには、content(インラインテキスト)、file_path(サーバー側で読み取り。バイナリセーフで、xlsx、zip、画像に対応。ALLOW_LOCAL_FILE_UPLOADによって制御)、url(サーバー側で取得)のいずれか1つだけを指定します。 - download_file:ファイルの内容をダウンロードします
Tier 3 — レポートと可視化
- list_reports: Visual Analytics レポートを一覧表示します
- get_report: レポートのメタデータと定義を取得します
- export_report: VA サービスがサポートする任意の形式(
package(zip)、pdf、png、svg、csv、tsv、xlsx、summary)で、レポート(または特定のレポートオブジェクト)をエクスポートします。テキスト形式はインラインで返され、pngは画像コンテンツとして、バイナリ形式(package/pdf/xlsx)は適切な MIME タイプの埋め込みファイルとして返されます。 - describe_report_objects: レポートに含められる内容を確認します。8 つのレポート操作と、追加可能なすべてのオブジェクト(棒グラフ、リストテーブル、地図、キー値など)について、1 行の用途説明、データロール、一般的なオプション、ペイロードの例を確認できます。引数なしでカタログ(インテント→オブジェクトの対応表、配置ガイド、レイアウトのレシピ、API の厳密な制限を含む)を取得し、
object_type=で 1 つのオブジェクトの仕様を取得します(kpiなどの通称エイリアスも解決されます)。category=で絞り込み、operation=で 1 つの操作の全仕様を取得できます。operation="addData"では、dataItems(列名の変更、SAS 形式、集計、地理分類)が説明されます。apply_report_operationsのループを支援します。 - create_report: Visual Analytics レポートを作成し、その ID を返します。オプションで
operations配列を渡すと、1 回のアトミックな呼び出しでレポート全体を作成できます。結果には、作成されたページ/オブジェクトの名前とラベル、および検証のヒントが含まれます。 - apply_report_operations: オーサリングの中心となるツールです。ネイティブな VA 操作(
addData、addPage、addObject、updateObject、setParameterValue、updateData、changeData、applyDataView)を順序付きのバッチとしてレポートに適用します。addPageのtitleフィールドでページにタイトルを付けます(ページ本文の上部にテキスト帯として表示されます。VA ヘッダーはコントロール専用です)。各チャートは追加時にoptions.object.titleでタイトルを付けます。配置には、page、relativeToObject(列、行、グリッドに対する左/右/上/下)、container(standardContainerにまとめる)、またはreportを指定します(new_pageを使うと、1 つのバッチ内でページを作成し、その場で名前を付けられるため、複数ページのレポートを作成できます)。バッチはアトミックに実行されます。カタログに照らしてすべての操作、オブジェクトキー、配置を事前に検証し、すべてのエラーを一度に報告します。dry_runに対応し、ETag の同時実行ハンドシェイクを処理します。また、save_as=trueとresult_report_name/result_folderを指定すると、バッチを名前を付けて保存し、新しいレポートに適用して、元のレポートは変更しません。モードはこのフラグだけで決まります。フラグがなければレポートはその場で編集され、フラグなしで名前またはフォルダーを指定すると、処理は拒否され、実行されません。一般的なループは、describe_report_objects→get_castable_columns→apply_report_operations→get_report_outline/export_report(ページごとに png)で検証する流れです。 - get_report_outline: レポートの構造を読み取ります。ページからオブジェクトまで、他のツールで必要な識別子を確認できます(配置/
updateObjectの対象にはオブジェクトのname、export_reportにはlabel、ページの配置にはページのlabelを使用します)。 - copy_report: レポートを新しいレポートにコピーします(必要に応じて名前やフォルダーを変更できます)。コピーして置き換えるパターンでは、
changeData操作と組み合わせます。 - delete_report: レポートとそのコンテンツを削除します。
Tier 4 — バッチジョブと非同期実行
- submit_batch_job: SAS ジョブを非同期実行用に送信します
- get_job_status: ジョブの状態を確認します
- list_jobs: 最近のジョブ/実行中のジョブを一覧表示します
- cancel_job: 実行中のジョブをキャンセルします
- get_job_log: ジョブログを取得します
Tier 5 — 自動機械学習
- list_ml_projects: AutoML プロジェクトを一覧表示します
- create_ml_project: 読み込み済みのグローバルスコープ CAS テーブル(caslib + table + オプションの CAS サーバー)から、新しい AutoML プロジェクトを作成します
- run_ml_project: パイプラインの自動化を実行します
- register_ml_champion_model: AutoML プロジェクトのチャンピオンモデルを Model Repository に登録します
- publish_ml_champion_model: AutoML プロジェクトのチャンピオンモデルをスコアリング先に公開します
ティア 6 — モデル管理とスコアリング
- list_registered_models: リポジトリ内のモデルを一覧表示します
- list_publishing_destinations: 利用可能なスコアリング/公開先を一覧表示します。publish_ml_champion_model で使用します
- list_mas_modules: 公開済みの MAS モジュールを一覧表示します
- get_mas_module_step_signature: スコアリング前に、公開済み MAS モジュールのステップの入力/出力変数シグネチャを確認します
- score_data: 公開済みのモデルまたは判断に対してデータをスコアリングします
ティア 7 — 意思決定(SAS Intelligent Decisioning)
SAS Intelligent Decisioning のルールセットと意思決定フローをエンドツーエンドで構築・管理し、フローを Micro Analytic Score(MAS)に公開して、score_data で実行できるようにします。
ビジネスルール — ルールセット:
- create_business_ruleset / update_business_ruleset / get_business_ruleset / list_business_rulesets / delete_business_ruleset: ルールセット(ルールが処理する入力/出力シグネチャ)を管理します
- lock_business_ruleset_revision: 現在のルールセットの状態を不変のリビジョンとしてロックします(意思決定ステップが参照するものです)
- list_business_ruleset_revisions: ルールセットのロック済みリビジョンを一覧表示します
ビジネスルール — ルール:
- create_business_rule / update_business_rule / get_business_rule / list_business_rules / delete_business_rule: ルールセット内の条件付きルールを管理します
意思決定フロー:
- create_decision_flow / update_decision_flow / get_decision_flow / list_decision_flows / delete_decision_flow: ルールセットのステップを連結する意思決定フローを管理します
- get_decision_flow_code: フロー用に生成された DS2 実行コードを取得します
- lock_decision_flow_revision / list_decision_flow_revisions / get_decision_flow_revision: 不変の意思決定リビジョンをロック、一覧表示、取得します
- publish_decision_flow: ロック済みの意思決定リビジョンを MAS の公開先に公開し、完了までポーリングして、サーバーが生成した MAS
moduleIdを返します(get_mas_module_step_signature / score_data ですぐに使用できます)
ティア 8 — ワークベンチ(コード実行のみ)
- execute_sas_code: SAS コードのスニペットを実行し、実行結果(ログとリスティング出力)に加えて、
html_results=falseでない場合は HTML の結果 へのリンクを取得します。呼び出し間でウォーム状態を維持する再利用可能なコンピュートセッションで実行されるため、SAS の状態(WORK テーブル、マクロ変数、割り当て済みの libref)は連続する呼び出し間で保持されます
ティア 9 — ビジネス用語集(SAS Data Governance)
SAS Business Glossary を参照・作成し、その用語を説明対象の列にリンクします。ティア 1 では列名が CD_NAC_RSK であることがわかり、このティアではその意味と、誰が定義しているかがわかります。
使い始める前に知っておくとよい用語集の特徴が 2 つあります。どちらも生の API からは見えませんが、ここではどちらも自動的に処理されます。
- 用語には 2 つの ID があります。 用語は Glossary オブジェクトであると同時に Catalog エンティティでもあり、それぞれ異なる識別子を持ちます。すべてのツールが両方を返すため、
term_id(glossary)とcatalog_entity_id(catalog)のどちらを保持しているかを自分で判断する必要はありません。 - カスタム属性は UUID キーで保存されます。 これらのツールは、用語集 UI に表示される ラベル(
{"Scope": "Group"})を使ってカスタム属性を読み書きし、呼び出し前に必須属性と単一選択値を検証します。 用語集: - search_glossary_terms:用語名と定義を対象に、関連度順でフリーテキスト検索します。IDではなく単語が分かっている場合の入り口です。
assigned_asset_countを報告するため、その用語が実際に使用されているかを確認できます - list_glossary_terms:用語タイプ、親(正式な階層)、名前の一部を指定して、正確な構造の一覧を取得します。
include_attributesを指定すると、各用語の属性値を返します(一覧にすでに含まれているため無料です)。また、attribute_filterを指定すると、たとえば{"Used in Risk": true}に一致する用語だけに絞り込めます。用語集はサーバー側で属性によるフィルタリングができないため、このフィルターはここで適用され、結果にはスキャンした用語集の範囲が報告されます - get_glossary_term:1つの用語の全情報を取得します。カスタム属性はハッシュ値ではなく名前で表示されます
- list_glossary_term_types / get_glossary_term_type:利用可能な用語タイプと、そのタイプの用語が満たす必要のある属性の仕様を取得します。用語を作成する前に後者を呼び出してください。各属性について、Viya が受け付ける値の形式が1つ報告されます。この形式は API のドキュメントには記載されていません
用語とデータが結び付く場所:
- list_term_assets:用語が割り当てられている列と、その列が属するテーブルを取得します。「この用語はどこで使われているか?」に対する正式な回答です
- list_table_terms:逆方向の情報を取得します。テーブルのすべての列と、割り当てられた用語を、用語の定義とともに表示します。そのテーブルがガバナンス対象かどうかを最も手早く確認できます
用語の作成・編集:
- create_glossary_term:用語を作成します。デフォルトで公開されます。基盤となる API は、明示的に指定しない限り非表示の下書きを作成します。後から
update_glossary_term(publish=true)で公開できます - import_glossary_terms:1回の呼び出しで複数の用語とその階層を作成します。子用語は親のIDではなく名前を指定するため、行は任意の順序で渡せ、階層間でIDを受け渡す必要もありません。行ごとの失敗は個別に報告されます。各行の用語の
term_idが返されるため、次の手順で検索する必要はありません。また、実際に新規作成された行と、用語がすでに存在していた行を区別します。インポートジョブでは、どちらも成功としてカウントされます。行は全体が書き込まれるため、update_existingはそのパスにある用語をマージするのではなく、置き換えます。dry_run=trueを指定すると、インポートせずに解決済みの行を確認できます。対話型ビューでは、これが[インポート]ボタン付きのテーブルとして表示されます - update_glossary_term:用語のテキスト、親、または属性を変更します。現在の用語にマージするため、省略したフィールドは空白にされず、そのまま残ります。
parent_idで階層内の位置を変更でき、publishで下書きを公開できます。下書きは API では独立したリソースであるため、この操作はそれに応じて書き込み先を切り替えます。切り替えない場合、下書きの編集は詳細のない 404 エラーで失敗します - delete_glossary_term:用語と、その用語を参照するすべての割り当てを完全に削除します。カスケード削除はありません。子用語がある用語は削除できないため、サブツリーは末端から削除してください
- assign_glossary_term / unassign_glossary_term:用語をテーブル列に割り当てる、または割り当てを解除します。この操作によって用語がデータをガバナンスするようになります。割り当てられたアセットがない用語は、何もガバナンスしません
語彙の設計:
- create_glossary_term_type / update_glossary_term_type / delete_glossary_term_type:用語を作成するためのテンプレートを定義します。含めるカスタム属性、必須の属性、各属性が受け付ける値を指定します。編集時はラベルで属性を照合し、それぞれの識別子を維持するため、すでに値が設定されている用語から値が失われることはありません。属性の名前を変更するには、新しいラベルとともに
attribute_idを指定してください。新しいラベルは何とも一致せず、指定しないと新しい属性が作成されます。このタイプを用語がまだ使用している間は削除できません
この方法で割り当てた用語は、datasets インデックスで Column.term:"<term name>" ファセットを使用する Tier 1 の catalog_search からも検索でき、個々の列を解決せずに、その用語が割り当てられたテーブルを取得できます。
プロンプトテンプレート
- debug_sas_log:SAS ログを分析し、根本原因の説明とともにエラーを特定します
- explore_dataset:データプロファイリング用の SAS コードを生成します
- data_quality_check:データ品質(DQ)評価コードを生成します
- statistical_analysis:診断を含む統計ワークフローを設定します
- optimize_sas_code:SAS コードをレビューして最適化します
- explain_sas_code:コードをブロックごとに説明します
- sas_macro_builder:本番環境品質の SAS マクロを作成します
- generate_report:ODS/PROC REPORT コードを生成します
- build_va_dashboard:CAS テーブルから洗練された複数ページの Visual Analytics ダッシュボードを作成する手順を案内します。レポート作成ツールを使い、「発見 → 形状化 → 構成 → 仕上げ → 検証」の手法で進めます
MCP クライアントの設定
設定例は examples/ フォルダーにあります。以下に、一般的なクライアント向けのクイックスタート用スニペットを示します。
ヒント — エンドポイントをブラウザーで開きます。 HTTP モードでは、ブラウザーで MCP URL(例:
http://localhost:8134/mcp、またはデプロイ済みサーバーの場合はhttps://<host>/mcp)を開くと、単なる401の代わりにランディングページが表示されます。サーバーの概要、接続先の SAS Viya、デプロイで公開されているツールの階層(各ツールの概要付き)、Claude Code、VS Code、Cursor、Claude コネクター、汎用のmcp.jsonクライアント向けのコピーしてすぐ使える設定が表示されます。設定には、デプロイ環境の実際の URL があらかじめ入力されています。この方法で応答するのは、通常のブラウザーGET(Accept: text/html)だけです。MCP クライアントとcurlの応答は以前とまったく変わりません。このページは認証不要で、デプロイ環境の構成のみを表示します(ユーザーデータは表示されません)。管理者はMCP_LANDING_PAGE=falseを設定して無効にできます。
VS Code/Cursor/Claude Code(.vscode/mcp.json)
HTTP モード(別途 uv run app を実行しておく必要があります):
{
"servers": {
"sas-execution-mcp": {
"url": "http://localhost:8134/mcp",
"type": "http"
}
}
}
Stdio モード(必要に応じてサーバーを起動します):
{
"servers": {
"sas-execution-mcp": {
"command": "uv",
"args": ["run", "app-stdio"],
"cwd": "${workspaceFolder}"
}
}
}
Gemini CLI(.gemini/settings.json)
Gemini CLI は Stdio モードのみをサポートします。~/.gemini/settings.json またはプロジェクトレベルの .gemini/settings.json に追加します。
{
"mcpServers": {
"sas-viya-mcp": {
"command": "uv",
"args": ["run", "app-stdio"],
"cwd": "/path/to/sas-mcp-server",
"timeout": 60000
}
}
}
注:
timeoutフィールド(ミリ秒単位)は重要です。SAS Viya API の呼び出しには、Gemini CLI のデフォルトである 10 秒より長い時間がかかる場合があります。60000(60 秒)を推奨します。cwdはsas-mcp-serverのチェックアウト先の絶対パスに設定してください。
例
MCP ツールを通じて SAS コードを実行します。
data work.students;
input Name $ Age Grade $;
datalines;
Alice 20 A
Bob 22 B
;
run;
proc print data=work.students;
run;
詳細、設定オプション、デプロイオプションについては、examples フォルダーを参照し、そこに記載された手順に従ってください。
コレクションモード(利用状況テレメトリー)
サーバーが実際にどのように使われているか、つまり、どのツールがどのような目的で、どのような入力を使って呼び出され、どこで期待に応えられていないかを記録する、オプトインでデフォルトでは無効のモードです。対象となるユーザーは次の 2 種類です。
- **メンテナーに構造化されたフィードバックを提供するコントリビューター。**文章でバグを報告する代わりに、しばらく有効にして、生成されたログを共有できます。これにより、メンテナーは、どのツールが使われ、どのツールが失敗し、どの目的に対して適切なツールがまだないかを把握できます。これは、既存のツールを改善し、新しいツールを特定するための直接的な指標になります。
- **自組織のユーザー向けにサーバーを運用する組織。**MCP サーバーを内部にデプロイしているチームは、これを有効にすることで、ユーザーが何のためにどのように利用しているかを、すべて自組織のインフラストラクチャ内で把握できます。
FastMCP のミドルウェアラッパー(telemetry.py + usage_logger.py)として実装されており、ツールへの変更は一切不要です。
🔒 **データが自動的にどこかへ送信されることはありません。**コレクションモードでは、サーバーを実行しているマシン上のローカルログファイルに追記するだけです。明示的に有効にしない限り無効であり、有効にしてもデータはディスク上にとどまります。メンテナーを含む誰かと共有する場合は、ファイルを自分で送信するという意図的な手順が必要です。ホームへの通信も、ネットワーク経由の送信も、第三者の関与もありません。
有効にすると、次の 2 つの処理を行います。
-
すべてのツールのスキーマに必須の
goalパラメーターを追加し、モデルに、現在のリクエストでそのツールを選んだ「理由」を 1 文で記述するよう求めます。実際のツールが実行される前に、goalは引数から取り除かれるため、ツールがこれを受け取ることはありません。 -
ツール呼び出しごとに 1 行の JSON(JSON Lines / NDJSON、スキーマ v3)をローカルログファイルに追記します。記録されるのは、タイムスタンプ、実行 ID、実行ごとの連番、ツール名、目的、引数(再試行の分析に使う固定の
args_hashも含む)、結果、ステータス、エラー、レイテンシー、呼び出し元クライアントのclient_name/client_versionです。ツールが失敗をデータとして宣言する場合(例:{"status": "apply_failed"}。MCP レイヤーからは成功として認識されます)、レコードにはtool_status/is_tool_error/tool_message/failed_operation_indexも含まれるため、すべてのモードでツールレベルの失敗率を分析できます。run_startヘッダーレコード(トランスポート、PID、サーバーバージョン、結果モード、そして A/B テストの実行を識別する任意のCOLLECTION_RUN_TAGラベル)でログを開始し、1000 レコードごとに再出力します。これにより、ログのローテーション後にヘッダーのない部分が生じることを防げます。各出力はバイト単位で同一のため、どれか 1 つあれば十分です。秘密情報のようなキーとインラインの Bearer/JWT トークンは編集され、エラー/結果テキスト内の Viya ホスト名はマスクされ、すべてのフィールドにサイズ上限が設けられます。**レコードは MCP セッションごとではなく、
run_idごとにグループ化されます。これはサーバープロセスごとに 1 つです。**プロトコルはセッションレスモデルへ移行しており(FastMCP 4 ではこれがデフォルトです)、session_idが存在しないか、リクエストごとに生成されるため、これを基準にグループ化すると、トレースがすべて単一呼び出しの断片に分断されてしまいます。stdio では 1 つのプロセスが 1 つのクライアントにサービスを提供するため、実行はそのクライアントのトレースになります。HTTP では、実行はそのプロセスがサービスを提供したすべてのクライアントにまたがり、それらを区別する唯一の情報はclient_name/client_versionです。つまり、同じクライアントソフトウェアを使う 2 人のユーザーは、同じrun_idとseqカウンターを共有します。これはセッションキーを廃止したことによる、受け入れ済みの制約です。プロセスごとのCOLLECTION_LOG_PATHでは解決できません(これはプロセスごとに分割するもので、その軸はすでにrun_idがカバーしています)。
有効化
.env のトグルを設定します(すべてのオプションは .env.sample に記載されています)。
COLLECTION_MODE=true
# optional overrides (defaults shown):
# COLLECTION_LOG_PATH=~/.sas-mcp-server/tool-usage.log
# COLLECTION_LOG_RESULTS=failures # never | failures | always (see below)
# COLLECTION_RUN_TAG= # free-text label stamped into run_start
ツールの結果は、COLLECTION_LOG_RESULTS の設定に従って記録されます。この設定は、次の 3 つの値を取ります。never は、内容を含まない形状の概要(型とキー名。例:{"_type":"object","_keys":["status","report_id"]})のみを記録します。failures(デフォルト)は、エラーになった呼び出し、またはツールが失敗を宣言した呼び出しに限り、結果の内容を(上限設定とマスキングを適用して)記録します。失敗の診断情報は最も価値の高いトレースデータであり、テーブルの行を含むことはまれなので、適度な設定といえます。また、never では成功とツールが宣言した失敗をログ上で区別できません。always は、すべての呼び出しで結果の内容を記録します。引数、目標、ステータス、エラーテキスト、ツールが宣言した結果のフィールドは、どのモードでも記録されます(true/false も、それぞれ always/never のエイリアスとして引き続き使用できます)。
⚠️ **プライバシー:**有効にすると、ログにはツールへの入力(送信した SAS コードやクエリなど)が記録されます。また、
failures/alwaysモードでは、テーブルの行、SAS のリスティング、PII を含む可能性のある実際の結果データも記録されます。マスキングはヒューリスティック方式(認証情報らしいキー + Bearer/JWT + Viya ホスト名)であり、データ値に含まれる PII は検出しません。**共有する前にログを確認してください。**ファイルはユーザーのみがアクセスできるよう保護されます(POSIX では chmod 0600、Windows では best-effort で icacls)。
パフォーマンスへの影響
コレクションモードは、常時有効にしても十分に軽量になるよう設計されています。このリポジトリでの測定結果(登録済みツール 45 個、FastMCP 3.4.2):
- **プロンプトトークン。**挿入される
goalフィールドによって、モデルに表示されるtools/listスキーマは、ターンごとに約 **+2,400 入力トークン(約 29%)**増加します。ツールリストはセッション中に変わらないため、初回のターン以降はプロンプトキャッシュから提供されます(定常状態では 1 ターンあたり約 +240 トークン)。これに加えて、モデルがgoalの文を生成するため、呼び出しごとに出力トークンが約 15~30 個増えます。これはクライアントから見える唯一のコストで、コレクションモードが有効な間のみ発生します。 - **呼び出しごとのレイテンシ。**ミドルウェアとログ記録による追加時間は、形状のみを記録するデフォルト設定で 約 1.4 ms/呼び出し(
COLLECTION_LOG_RESULTS=alwaysでは 約 5.3 ms)です。JSONL の書き込みはワーカースレッドにオフロードされるため、イベントループをブロックすることはありません。通常数百ミリ秒から数秒かかる実際の Viya 呼び出しと比べると、これは無視できる程度です。コレクションモードをオフにした場合もオンにした場合もライブ統合テストは同じように成功し、通常のネットワーク変動に埋もれる程度のオーバーヘッドでした。 - **ディスク。**形状のみを記録するデフォルト設定で、ツール呼び出し 1 回あたり約 0.5~0.7 KBです。ログは
COLLECTION_MAX_LOG_BYTES(デフォルトは 10 MiB、約 16,000 回の呼び出し)でローテーションされ、ローテーション済みファイルはCOLLECTION_LOG_BACKUPS(デフォルトは 3 個)個保持されるため、ディスク使用量の増加には上限があります。
サーバーログ
サーバーログの先頭には、実行中の内容を示す 1 行が記録されます。ここにはサーバーと FastMCP のバージョン、トランスポート、SAS Viya エンドポイントが含まれます。その後、すべてのツール呼び出しについて、ツール名と実行時に使用する SAS Viya ユーザーが記録されます。
Tool call: execute_sas_code (user: sasdemo)
ユーザーは、呼び出し元自身のトークンを使って取得した GET /identities/users/@currentUser の id です。つまり、Viya がその呼び出しを承認する際に使う本人情報と正確に一致します。クライアント認証情報トークンの場合、これはクライアントの ID です。この参照は呼び出しごとではなく、トークンごとに 1 回行われます。参照に失敗した場合もツールは失敗せず、user: unknown と記録されます。共有 HTTP デプロイでは、これによりフィールドレポートをアクセスしたユーザーと結び付けられます。
HTTP デバッグトレース
ツールが失敗したとき、モデルによるエラーの要約には、原因となったリクエスト(パスの誤り、メディアタイプの欠落、形式が正しくないボディなど)がほとんど表示されません。また、1 回のツール呼び出しで複数のリクエスト(ページング、計算ジョブのポーリング、ログの取得など)が送信されることがあります。.env で HTTP_DEBUG=true を設定すると、サーバーが SAS Viya API に送信するすべてのリクエストと各レスポンスが、それぞれ別のファイルに記録されます。
HTTP_DEBUG=true
# The defaults; `docker --env-file` keeps a trailing comment as part of the value, so none here.
HTTP_DEBUG_LOG_PATH=~/.sas-mcp-server/http-debug.log
# Cap per recorded body in bytes; 0 records no bodies.
HTTP_DEBUG_MAX_BODY_BYTES=4096
各やり取りは、同じ id を持つ 2 行の JSON で構成されます。1 行目は request レコード(メソッド、URL、ヘッダー、ボディ)、2 行目は response レコード(ステータス、elapsed_ms、ヘッダー、ボディ)です。対応するレスポンスがないリクエストは、タイムアウト、接続拒否、TLS エラーなどにより、通信中に失敗したことを示します。トレースはサーバーログには出力されないため、標準出力がプロトコルを伝送する stdio モードでも安全です。
Authorization、Cookie、その他の認証情報に該当するヘッダー、クエリパラメーター、ボディキーは秘匿化され、インラインの Bearer/JWT 文字列も同様に秘匿化されます。ただし、データ値は秘匿化されません。テーブルの行や SAS コードがボディに含まれるため、共有する前にファイルを確認してください。バイナリボディはサイズと種類が記録され、ボディのサイズは HTTP_DEBUG_MAX_BODY_BYTES で上限が設定されます。ファイルはコレクションログと同じようにローテーションされます。トレースが有効な間は、サーバーの起動時に警告がログに記録されます。トレースはトラブルシューティング用であり、共有デプロイ環境で常時有効にするものではありません。OAuth サインインとトークン更新の呼び出しはトレースされません。
テスト
このプロジェクトには 2 層のテストが含まれています。ユニットテスト(高速で、認証情報は不要)と、統合テスト(実際の SAS Viya インスタンスに対して実行)です。
run_tests.shとpytestの直接実行 — プラットフォームに応じて選択してください。run_tests.shは Bash の便利なラッパーです(ruff + pyright のチェック、認証情報の設定、JUnit レポートの出力を追加します)。Linux/macOS で実行できます。Windows では Git Bash または WSL でのみ実行できます。Windows PowerShell またはcmdでは、以下の各モードに記載されているuv run python -m pytest …コマンドを使用してください。これらはクロスプラットフォームで、同じテストを選択して実行でき、uv sync以外のセットアップは不要です。
ユニットテストの実行
ユニットテストでは、ネットワーク呼び出しを行わずにツールのスキーマ、リクエストペイロード、内部ロジックを検証します。
./run_tests.sh # Linux/macOS (also runs ruff + pyright)
uv run python -m pytest -m "not integration" -v # any platform, incl. Windows PowerShell
これにより、ユニットテスト一式を実行し、統合テストは選択対象から除外されます。そのため、概要には 28 deselected などと表示されます。これは想定どおりです。これらのテストは、ユニットテストのみの実行では実行されません。稼働中の Viya インスタンスが必要なため、以下の統合テストモードでのみ実行されます。not integration の実行でこれらを「有効化」するフラグはありません。
統合テストの実行
統合テストでは、稼働中の Viya 環境に対してすべてのツールを呼び出します。認証情報が必要で、.env または CLI 引数で指定します。
uv sync を実行すると、統合テストスイートに必要なものがすべてインストールされます。これには、Excel の upload_data フィクスチャの作成に使用する openpyxl も含まれます。これは test-formats 依存関係グループに含まれており、[tool.uv] default-groups によってデフォルトで同期されるため、追加のインストール手順は不要です。
テストスイート全体(単体テスト+統合テスト) — .env から VIYA_ENDPOINT、VIYA_USERNAME、VIYA_PASSWORD を読み込みます:
./run_tests.sh --integration # Linux/macOS
uv run python -m pytest -v # any platform
コマンドラインで認証情報を渡す場合(ラッパーのみ):
./run_tests.sh --integration \
--endpoint https://your-viya-server.com \
--username youruser \
--password yourpassword
pytest コマンドを直接実行する場合は、代わりに同じ3つの変数を .env に設定する(またはシェルでエクスポートする)必要があります。
統合テストのみ(単体テストをスキップ):
./run_tests.sh --integration-only # Linux/macOS
uv run python -m pytest -m integration --no-cov -v # any platform
pytest のマーカーは
integrationであり、integration-onlyではありません。--integration-onlyはrun_tests.shラッパーのフラグです。基盤となる pytest のマーカーはintegrationだけです。pytest -m "integration-only"を実行しても一致するマーカーがなく、すべてのテストが黙って選択解除されます(0 selected)。-m integrationを使用してください。なぜ
--no-covが必要なのですか?pytest.iniではカバレッジの最低基準が90%に設定されていますが、この基準を満たせるのは単体テストスイート全体だけです。統合テストのみを実行した場合、実行されるコードは大幅に少なく(約65%)、--no-covを指定しないと、選択されたテストがすべて成功していても、カバレッジ不足により pytest はゼロ以外の終了コードを返します。run_tests.sh --integration-onlyは--no-covを自動で追加します。pytest を直接実行する場合は自分で追加してください(または--cov-fail-under=0を使用してください)。
バイナリアップロード形式。 Excel の upload_data 統合テストでは、uv sync がデフォルトでインストールする test-formats グループの openpyxl を使って .xlsx フィクスチャを生成します(上記参照)。意図的にこれを含めずに同期した場合(例:uv sync --no-default-groups)、テストは importorskip によってスキップされます。失敗ではなく、スキップとして表示されます。csv、tsv、file_path/data_format のカバレッジには追加の依存関係は必要ありません。sas7bdat/sashdat フィクスチャの生成には SAS 自体が必要なため、この2つの形式はライブ環境ではなく、単体テストレベルのペイロードテストのみでカバーされています。
92個のツールと9個のプロンプトテンプレートのすべてに統合テストがあり、test_every_tool_has_integration_coverage/test_every_prompt_has_integration_coverage ガードによってこれが保証されています。統合テストのカバレッジなしで新しいツールやプロンプトを追加すると、テストスイートは失敗します。リソースに依存するテストでは、インスタンス上の実際の対象を検出します。score_data は最終更新日時が最も新しい MAS モジュールをスコアリングし(実際のステップとその入力を検出します)、run_ml_project は最終更新日時が最も新しい completed ML プロジェクトを再実行します。該当するリソースがインスタンスにまったくない場合に限り、これらのテストは skip されます。同様に、SAS Data Governance に Public という名前のディスカバリーエージェントが設定されていないインスタンスでは、test_catalog_agents_workflow は "No discovery agent named 'Public'" と表示して skip されます。これは想定されたスキップであり、失敗ではありません。このテストを実行する必要がある場合は、Viya 管理者に設定を依頼してください。
CI での実行: .github/workflows/integration.yml ワークフローは、リポジトリのシークレットを使って、必要に応じて(手動での起動、または PR への run-integration ラベルの追加で)このテストスイートを実行し、結果をステータスチェック、固定コメント、ダウンロード可能な JUnit アーティファクトとして PR に公開します。結果ファイルは reports/(git の追跡対象外)に書き込まれ、コミットされることはありません。
ローカルで実行する場合(結果を自分で PR に添付): --report を付けて実行すると、JUnit XML と Markdown の概要が reports/(git の追跡対象外)に書き込まれます。その後、GitHub CLI で PR に投稿できます。コミットも CI も不要です:
./run_tests.sh --integration-only --report
gh pr comment <PR> --body-file reports/integration-summary.md # summary table as a comment
gh gist create reports/integration.xml # full XML as a linkable gist
GitHub には PR にバイナリファイルを添付する API/CLI がありません(ドラッグ&ドロップでのアップロードはブラウザーでのみ可能です)。そのため、概要はコメントとして投稿し、生の XML は gist リンクで共有するか、折りたたみ可能な
<details>ブロックに貼り付けます。代わりに、ローカルマシンから標準の Actions アーティファクトを生成するには、ワークフローをリモートで起動します:gh workflow run integration.yml。
テスト構成
| ファイル | 説明 |
|---|---|
tests/test_tool_payloads.py | Tier 0~8 の全 75 ツールに対するペイロードのアサーション(URL パス、JSON ボディ、クエリパラメーター、ヘッダー)とエラーパスの網羅 |
tests/test_integration.py | 実際の Viya インスタンスに対するエンドツーエンドのワークフローテスト |
tests/test_tools.py | viya_client の汎用 Viya REST ヘルパー(get_json、post_json、make_client、…)の単体テスト |
tests/test_viya_utils.py | Viya のコンピュートセッションとジョブオーケストレーションの単体テスト |
tests/test_mcp_server.py | HTTP 認証ミドルウェア、ヘルスルート、トークン取得関数の単体テスト |
tests/test_config.py | 設定読み込みの単体テスト |
tests/test_config_oauth.py | PermissiveOAuthProxy による未加工のベアラートークン処理の単体テスト |
tests/test_auth_login.py | sas-mcp-login OAuth/PKCE ヘルパーの単体テスト |
tests/test_stdio_server.py | stdio のトークン解決とデバイスコードフローの単体テスト |
tests/test_env.py | env_bool ヘルパーの単体テスト |
tests/test_prompts.py | プロンプトテンプレートのレンダリングに関する単体テスト |
コントリビューション
メンテナーは、このプロジェクトへのパッチやコントリビューションを受け付けています。このプロジェクトへのコントリビューションの提出方法については、CONTRIBUTING.md をお読みください。
ライセンスとクレジット
/static フォルダーの内容を除き、このプロジェクトは Apache 2.0 ライセンス の下でライセンスされています。
/static フォルダー内の要素は SAS が所有しており、オープンソースライセンスの下では公開されていません。
SAS およびその他すべての SAS Institute Inc. の製品名またはサービス名は、米国およびその他の国における SAS Institute Inc. の登録商標または商標です。® は米国での登録を示します。
SAS ソフトウェア(例:SAS Viya)の個別の商用ライセンスは含まれていません。SAS ソフトウェアでこれらの機能を使用するには、別途ライセンスが必要です。
すべてのコンテナーイメージと同様に、直接および間接の依存関係には、それぞれ独自のライセンスが適用されます。 公開されているコンテナーイメージのユーザーは、使用が適用されるすべてのライセンスに準拠していることを確認する責任を負います。
参照されているすべてのサードパーティ商標は、それぞれの所有者に帰属します。ここでは識別および参照のみを目的として使用しており、商標所有者との提携や、商標所有者による推奨を示唆するものではありません。
サードパーティ依存関係
このプロジェクトでは、以下の依存関係が必要です。
| 依存関係 | ライセンス |
|---|---|
| Python | Python Software License |
| FastMCP | Apache License 2.0 |
| uvicorn | BSD 3-Clause License |
| starlette | BSD 3-Clause License |
| httpx | MIT License |
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。