mcp-excel-server

anagashima82/mcp-excel-server

3.1

If you are the rightful owner of mcp-excel-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

This document provides a comprehensive guide to setting up an MCP server for Excel operations using Dify and openpyxl.

Tools
7
Resources
0
Prompts
0

Dify + openpyxl MCPサーバー構築手順

DifyからローカルでExcel操作を行うためのMCPサーバー構築手順です。

前提条件

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

手順1: MCPサーバーのセットアップ

1-1. ディレクトリ作成

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

1-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")

1-3. requirements.txt を作成

mcp[cli]>=1.0.0
openpyxl>=3.1.0

1-4. 依存関係インストール

python3 -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -r requirements.txt

1-5. MCPサーバー起動

source venv/bin/activate
python server.py

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

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

手順2: DifyにMCPツールを登録

2-1. Dify管理画面を開く

ブラウザで http://localhost にアクセス

2-2. MCPサーバーを追加

  1. 上部メニューから ツール をクリック
  2. MCP タブを選択
  3. MCPサーバー(HTTP)を追加 をクリック
  4. 以下を入力:
項目
サーバーURLhttp://host.docker.internal:8000/mcp
名前Excel操作
サーバー識別子excel-mcp
  1. 保存 をクリック

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

2-3. 接続確認

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

手順3: ワークフローで使用

3-1. ワークフロー作成

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

3-2. create_excel の設定例

パラメータ
filenametest.xlsx
data[["名前", "年齢"], ["太郎", "25"], ["花子", "30"]]
sheet_nameSheet1

3-3. 実行

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


利用可能なツール一覧

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

トラブルシューティング

MCPサーバーに接続できない

  1. MCPサーバーが起動しているか確認

    curl http://localhost:8000/mcp
    
  2. Difyの設定で host.docker.internal を使用しているか確認

ファイルが作成されない

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

注意事項

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