1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Dify × MCP】ローカルでExcel操作を自動化する方法

1
Posted at

【Dify × MCP】ローカルでExcel操作を自動化する方法

はじめに

Difyでワークフローを作成していると、「Excelファイルを操作したい」と思うことはありませんか?

しかし、Difyはサンドボックス環境で動作するため、直接ローカルのファイルを操作することができません。

そこで今回は、MCP(Model Context Protocol)サーバーを使って、Difyからローカル環境のExcelファイルを操作する方法を紹介します。

MCPとは?

MCP(Model Context Protocol)は、AIモデルが外部ツールやデータソースと連携するための標準プロトコルです。MCPサーバーを立てることで、Difyのワークフローから様々な外部機能を呼び出すことができます。

前提条件

  • Docker / Docker Desktop がインストール済み
  • Python 3.10以上がインストール済み
  • Dify が Docker で起動済み

構築手順

Step 1: プロジェクトディレクトリの作成

mkdir -p mcp-excel-server
cd mcp-excel-server

Step 2: サーバーファイルの作成

server.py を作成します。

#!/usr/bin/env python3
"""
Excel操作用MCPサーバー
Difyからローカルでエクセルを操作するためのサーバー
"""
import json
import os
from typing import Any
from mcp.server.fastmcp import FastMCP
from openpyxl import Workbook, load_workbook

# MCPサーバー作成
mcp = FastMCP("excel-server")

# デフォルトの出力ディレクトリ
OUTPUT_DIR = os.path.expanduser("~/Documents/DifyExcel")
os.makedirs(OUTPUT_DIR, exist_ok=True)


@mcp.tool()
def create_excel(filename: str, data: list[list[str]], sheet_name: str = "Sheet1") -> str:
    """
    新しいExcelファイルを作成します。

    Args:
        filename: ファイル名(例: "report.xlsx")
        data: 2次元配列のデータ(例: [["A1", "B1"], ["A2", "B2"]])
        sheet_name: シート名(デフォルト: "Sheet1")

    Returns:
        作成したファイルのパス
    """
    wb = Workbook()
    ws = wb.active
    ws.title = sheet_name

    for row_idx, row in enumerate(data, 1):
        for col_idx, value in enumerate(row, 1):
            ws.cell(row=row_idx, column=col_idx, value=value)

    filepath = os.path.join(OUTPUT_DIR, filename)
    wb.save(filepath)
    return f"ファイルを作成しました: {filepath}"


@mcp.tool()
def read_excel(filepath: str, sheet_name: str = None) -> dict:
    """
    Excelファイルを読み込みます。

    Args:
        filepath: ファイルパス
        sheet_name: シート名(省略時は最初のシート)

    Returns:
        シートのデータ
    """
    if not os.path.isabs(filepath):
        filepath = os.path.join(OUTPUT_DIR, filepath)

    wb = load_workbook(filepath, data_only=True)
    ws = wb[sheet_name] if sheet_name else wb.active

    data = []
    for row in ws.iter_rows():
        data.append([cell.value for cell in row])

    return {
        "sheet_name": ws.title,
        "data": data,
        "row_count": len(data),
        "col_count": len(data[0]) if data else 0
    }


@mcp.tool()
def write_cell(filepath: str, cell: str, value: str, sheet_name: str = None) -> str:
    """
    Excelファイルの特定セルに書き込みます。

    Args:
        filepath: ファイルパス
        cell: セル位置(例: "A1", "B2")
        value: 書き込む値
        sheet_name: シート名(省略時は最初のシート)

    Returns:
        結果メッセージ
    """
    if not os.path.isabs(filepath):
        filepath = os.path.join(OUTPUT_DIR, filepath)

    wb = load_workbook(filepath)
    ws = wb[sheet_name] if sheet_name else wb.active
    ws[cell] = value
    wb.save(filepath)

    return f"セル {cell}'{value}' を書き込みました"


@mcp.tool()
def write_range(filepath: str, start_cell: str, data: list[list[str]], sheet_name: str = None) -> str:
    """
    Excelファイルの範囲に書き込みます。

    Args:
        filepath: ファイルパス
        start_cell: 開始セル(例: "A1")
        data: 2次元配列のデータ
        sheet_name: シート名(省略時は最初のシート)

    Returns:
        結果メッセージ
    """
    if not os.path.isabs(filepath):
        filepath = os.path.join(OUTPUT_DIR, filepath)

    wb = load_workbook(filepath)
    ws = wb[sheet_name] if sheet_name else wb.active

    from openpyxl.utils import coordinate_from_string, column_index_from_string
    col_letter, start_row = coordinate_from_string(start_cell)
    start_col = column_index_from_string(col_letter)

    for row_idx, row in enumerate(data):
        for col_idx, value in enumerate(row):
            ws.cell(row=start_row + row_idx, column=start_col + col_idx, value=value)

    wb.save(filepath)
    return f"{start_cell}から{len(data)}行x{len(data[0]) if data else 0}列を書き込みました"


@mcp.tool()
def list_sheets(filepath: str) -> list[str]:
    """
    Excelファイルのシート一覧を取得します。

    Args:
        filepath: ファイルパス

    Returns:
        シート名のリスト
    """
    if not os.path.isabs(filepath):
        filepath = os.path.join(OUTPUT_DIR, filepath)

    wb = load_workbook(filepath)
    return wb.sheetnames


@mcp.tool()
def add_sheet(filepath: str, sheet_name: str) -> str:
    """
    Excelファイルに新しいシートを追加します。

    Args:
        filepath: ファイルパス
        sheet_name: 新しいシート名

    Returns:
        結果メッセージ
    """
    if not os.path.isabs(filepath):
        filepath = os.path.join(OUTPUT_DIR, filepath)

    wb = load_workbook(filepath)
    wb.create_sheet(sheet_name)
    wb.save(filepath)

    return f"シート '{sheet_name}' を追加しました"


@mcp.tool()
def list_files() -> list[str]:
    """
    出力ディレクトリのExcelファイル一覧を取得します。

    Returns:
        ファイル名のリスト
    """
    files = [f for f in os.listdir(OUTPUT_DIR) if f.endswith(('.xlsx', '.xls'))]
    return files


if __name__ == "__main__":
    mcp.run(transport="streamable-http")

Step 3: 依存関係ファイルの作成

requirements.txt を作成します。

mcp[cli]>=1.0.0
openpyxl>=3.1.0

Step 4: 環境構築と起動

# 仮想環境の作成
python3 -m venv venv

# 仮想環境の有効化
source venv/bin/activate  # Windows: venv\Scripts\activate

# 依存関係のインストール
pip install -r requirements.txt

# サーバー起動
python server.py

起動すると以下のように表示されます:

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Difyでの設定

Step 1: MCPサーバーの登録

  1. ブラウザで http://localhost にアクセス(Difyの管理画面)
  2. 上部メニューから ツール をクリック
  3. MCP タブを選択
  4. MCPサーバー(HTTP)を追加 をクリック
  5. 以下を入力:
項目
サーバーURL http://host.docker.internal:8000/mcp
名前 Excel操作
サーバー識別子 excel-mcp
  1. 保存 をクリック

重要: localhost ではなく host.docker.internal を使用してください。
これはDockerコンテナからホストPCにアクセスするためのホスト名です。

Step 2: 接続確認

「認証済み」と表示され、7個のツールが認識されればOKです。

使い方

ワークフローでの使用

  1. スタジオで新規ワークフローを作成
  2. +ツール をクリック
  3. MCP タブから Excel操作 を選択
  4. 使いたいツールを選択(例: create_excel

テスト例:Excelファイル作成

パラメータ
filename test.xlsx
data [["名前", "年齢"], ["太郎", "25"], ["花子", "30"]]
sheet_name Sheet1

テスト実行すると ~/Documents/DifyExcel/test.xlsx にファイルが作成されます。

利用可能なツール一覧

ツール名 説明
create_excel 新規Excelファイル作成
read_excel Excelファイル読み込み
write_cell 特定セルに書き込み
write_range 範囲に書き込み
list_sheets シート一覧取得
add_sheet シート追加
list_files ファイル一覧取得

トラブルシューティング

接続できない場合

  1. MCPサーバーが起動しているか確認
curl http://localhost:8000/mcp
  1. Difyの設定で host.docker.internal を使用しているか確認

ファイルが作成されない場合

  1. 出力ディレクトリ ~/Documents/DifyExcel が存在するか確認
  2. MCPサーバーのログでエラーを確認

注意事項

  • MCPサーバーはDifyを使用する間、起動したままにしてください
  • Excelファイルは ~/Documents/DifyExcel に保存されます
  • Difyのサンドボックス制限を回避するため、MCPサーバー経由でopenpyxlを実行しています

まとめ

MCPサーバーを使うことで、Difyのワークフローからローカル環境のExcelファイルを自由に操作できるようになりました。

この仕組みを応用すれば、Excel以外にも様々なローカルリソースへのアクセスが可能になります。ぜひ活用してみてください!

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?