📚

GitHub Copilot + MCPで、VS CodeからSnowflakeを自然言語で操作してみた

に公開

概要

GitHub CopilotのエージェントモードとMCPを組み合わせて、VS Code上で自然言語からSnowflakeにクエリを実行できるかを検証してみました。

本記事では、以下を紹介します:

  • MCP Serverのセットアップ方法
  • 実際に自然言語クエリを試した結果

今回使用したMCP Serverはこちら:
https://github.com/datawiz168/mcp-snowflake-service

MCP Serverのセットアップ

基本的にはこちらのリポジトリのREADMEに沿って進めていきます。
https://github.com/datawiz168/mcp-snowflake-service

  1. リポジトリのクローン
git clone https://github.com/datawiz168/mcp-snowflake-service.git
  1. 仮想環境の作成と、依存関係のインストール(事前にuvのインストールが必要です)
cd .\mcp-snowflake-service\
uv venv
.venv\Scripts\activate
uv pip install -r .\requirements.txt
  1. .envファイルの作成
    Snowflakeへの接続情報を環境変数に記載します。今回は特定のスキーマやロールで動作させたかったため、SNOWFLAKE_SCHEMASNOWFLAKE_ROLEも追加しました。
SNOWFLAKE_USER=your_username       # Your username
SNOWFLAKE_PASSWORD=your_password   # Your password
SNOWFLAKE_ACCOUNT=your_account     # Account Identifier
SNOWFLAKE_DATABASE=your_database   # Your database
SNOWFLAKE_WAREHOUSE=your_warehouse # Your warehouse
SNOWFLAKE_SCHEMA=your_schema       # 追加:Your schema
SNOWFLAKE_ROLE=role                # 追加:Your role
  1. SnowflakeConnectionクラスの__init__の修正
    上記.envファイルに追加した都合上、ソースコードも修正します。
    def __init__(self):
        # 初始化配置信息 / Initialize configuration
        self.config = {
            "user": os.getenv("SNOWFLAKE_USER"),
            "password": os.getenv("SNOWFLAKE_PASSWORD"),
            "account": os.getenv("SNOWFLAKE_ACCOUNT"),
            "database": os.getenv("SNOWFLAKE_DATABASE"),
            "warehouse": os.getenv("SNOWFLAKE_WAREHOUSE"),
            "schema": os.getenv("SNOWFLAKE_SCHEMA"), # 追加
            "role": os.getenv("SNOWFLAKE_ROLE"), # 追加
        }
        print(self.config)
        self.conn: Optional[snowflake.connector.SnowflakeConnection] = None
        logger.info(
            f"Initialized with config (excluding password): {json.dumps({k:v for k,v in self.config.items() if k != 'password'})}"
        )
  1. VS Codeの設定からChat> Agent: Enbaledにチェックを入れる
  2. VS Codeの設定からmcpで検索し、「setting.jsonで編集」をクリック
  3. jsonファイルに下記設定を追加
  "mcp": {
    "servers": {
      "snowflake": {
        "command": "uv",
        "args": [
          "--directory",
          "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-snowflake-service",,
          "run",
          "server.py"
        ]
      }
    }
  },

Snowflakeにテストデータを用意する

お試し用のデータベース、スキーマ、テーブルとその中身を作る。

CREATE OR REPLACE DATABASE RETAIL;
CREATE OR REPLACE SCHEMA RETAIL.DATAMART;

CREATE OR REPLACE TABLE RETAIL.DATAMART.SALES_SUMMARY (
  SALE_DATE DATE,
  STORE_ID STRING,
  PRODUCT_ID STRING,
  UNITS_SOLD INTEGER,
  SALES_AMOUNT FLOAT
);

CREATE OR REPLACE TABLE RETAIL.DATAMART.PRODUCT_MASTER (
  PRODUCT_ID STRING,
  PRODUCT_NAME STRING,
  CATEGORY STRING,
  PRICE FLOAT
);

CREATE OR REPLACE TABLE RETAIL.DATAMART.STORE_MASTER (
  STORE_ID STRING,
  STORE_NAME STRING,
  REGION STRING
);

INSERT INTO RETAIL.DATAMART.PRODUCT_MASTER VALUES
('P001', 'コーヒー', '飲料', 120.0),
('P002', '紅茶', '飲料', 130.0),
('P003', 'ミネラルウォーター', '飲料', 100.0),
('P004', 'パン', '食品', 150.0),
('P005', 'おにぎり', '食品', 180.0),
('P006', '弁当', '食品', 450.0),
('P007', 'カップラーメン', '食品', 200.0),
('P008', 'チョコレート', 'お菓子', 160.0),
('P009', 'ガム', 'お菓子', 90.0),
('P010', 'キャンディ', 'お菓子', 110.0);

INSERT INTO RETAIL.DATAMART.STORE_MASTER VALUES
('S001', '東京店', '関東'),
('S002', '大阪店', '関西'),
('S003', '名古屋店', '中部'),
('S004', '福岡店', '九州'),
('S005', '札幌店', '北海道'),
('S006', '仙台店', '東北'),
('S007', '広島店', '中国'),
('S008', '高松店', '四国'),
('S009', '那覇店', '沖縄'),
('S010', '横浜店', '関東');

INSERT INTO RETAIL.DATAMART.SALES_SUMMARY VALUES
('2025-04-01', 'S001', 'P001', 30, 3600),
('2025-04-01', 'S002', 'P002', 25, 3250),
('2025-04-01', 'S003', 'P003', 40, 4000),
('2025-04-01', 'S004', 'P004', 10, 1500),
('2025-04-01', 'S005', 'P005', 12, 2160),
('2025-04-01', 'S006', 'P006', 8, 3600),
('2025-04-01', 'S007', 'P007', 20, 4000),
('2025-04-01', 'S008', 'P008', 15, 2400),
('2025-04-01', 'S009', 'P009', 18, 1620),
('2025-04-01', 'S010', 'P010', 22, 2420);

VS Codeで自然言語クエリを試す

GitHub Copilotのチャットを開き、右下の「質問する」のプルダウンから「エージェント」を選択。

チャットでいろいろ聞いてみる。

  • どんなテーブルがある?

  • 売上金額が最も高い商品IDは?

  • 売上金額が最も高い商品の名前は?
    JOINを必要とするクエリだったため、適切なクエリを組み立てられなかったようです。

感想

  • LLMがどのようにクエリ組み立てれば目的の結果が得られるかが分かるようにデータ基盤を構築する必要がありそう
  • 自分でもMCP Server作ってみよう

Discussion