bailangcheng818

docx-comparison-mcp

Community bailangcheng818
Updated

MCP Server for generating Japanese Word documents (新旧比較表・仕様書)

docx-comparison-mcp

A3横向き 新旧比較表 / A4縦向き 仕様書 Word ドキュメント生成 MCP サーバー

Dify / LangFlow / LangChain / Claude Desktop など任意の AI フレームワークから呼び出せる、ローカル MCP サーバーです。

設計思想:GET schema → POST generate

excel-mcp と同じ「スキーマをまず取得してから生成する」パターンを採用しています。

ただし excel-mcp との根本的な違いがあります:

excel-mcp docx-mcp
スキーマの由来 実行時に Excel ファイルのヘッダー行を読む(動的) コンパイル時に固定された出力フォーマット(静的)
「書き込み先」 決まった Excel ファイル(常に同じパス) 毎回新規生成(PDF アップロードのたびに新しいドキュメント)
append 概念 あり(既存行に追記) なし(PDF 1回 = 新しい docx 1本)

Dify ワークフローでの位置づけ:

[HTTP ノード] GET /schema/comparison
     ↓ prompt_context(列定義の代わりに出力フォーマット定義)
[LLM ノード] アップロードされた PDF を Gemini が読む + schema context を注入
     ↓ { doc_title, sections: [...] } の JSON
[HTTP ノード] POST /generate  { spec: { ... } }
     ↓ download_url
[End]

prompt_context フィールドは Dify の LLM ノードのシステムプロンプトにそのまま貼り付けられる形式になっています。

機能

  • A3横向き、旧/新/備考 3列フォーマット(新旧比較表)
  • A4縦向き、表紙・制定改廃経歴表・本文(仕様書)
  • 赤字テキスト(変更・追加箇所)
  • 青い下線付き Word コメントアンカー
  • 複数セクション対応(表紙、制定改廃経歴、各条項)
  • stdio モード(Claude Desktop / Claude Code 向け)
  • HTTP モード(Dify / LangFlow 向け)

セットアップ

# 1. 依存パッケージのインストール
npm install

# 2. テスト実行
npm test
# → test-output.docx が生成されます

# 3a. MCP (stdio) モード起動 — Claude Desktop / Claude Code 向け
npm start

# 3b. HTTP モード起動 — Dify / LangFlow / REST 向け
npm run start:http
# → http://localhost:3456 で起動

Claude Desktop への登録

~/.claude/claude_desktop_config.json に追加:

{
  "mcpServers": {
    "docx-comparison": {
      "command": "node",
      "args": ["/absolute/path/to/docx-mcp/src/index.js"],
      "env": {
        "OUTPUT_DIR": "/Users/yourname/Desktop/docx-output"
      }
    }
  }
}

エンドポイント一覧

メソッド パス 説明
GET /health サーバー死活確認
GET /schema API ドキュメント(静的)
GET /schema/comparison 新旧比較表の LLM 注入用スキーマ
GET /schema/manual 仕様書の LLM 注入用スキーマ
POST /generate 新旧比較表の生成(ローカル保存)
POST /generate/download 新旧比較表の生成(ファイル直接ストリーム)
POST /generate/manual 仕様書の生成(ローカル保存)
POST /generate/manual/download 仕様書の生成(ファイル直接ストリーム)

GET /schema/comparison — 新旧比較表スキーマ

LLM に注入するフォーマット定義を返します。prompt_context フィールドを Dify の LLM ノードのシステムプロンプトに貼り付けてください。

レスポンス概要:

{
  "doc_type": "comparison",
  "description": "新旧比較表(A3横、旧/新/備考 3カラム)Word文書の生成スキーマ",
  "prompt_context": "## 新旧比較表 生成形式\n\nPOST /generate に渡す spec を...",
  "required_fields": ["doc_title", "sections"],
  "sections_schema": { ... },
  "paragraph_schema": { ... },
  "example": { ... }
}

GET /schema/manual — 仕様書スキーマ

{
  "doc_type": "manual",
  "description": "仕様書(A4縦、表紙・経歴表・本文)Word文書の生成スキーマ",
  "prompt_context": "## 仕様書 生成形式\n\nPOST /generate/manual に渡す spec を...",
  "required_fields": ["doc_title", "sections"],
  "sections_schema": { ... },
  "history_schema": { ... },
  "example": { ... }
}

Dify ワークフロー統合パターン

新旧比較表(PDF 比較)

[ファイルアップロード] ユーザーが PDF をアップロード
     ↓
[HTTP ノード] GET /schema/comparison
     ↓ body.prompt_context を変数に格納
[LLM ノード]
  システムプロンプト: {{schema_prompt_context}}
  ユーザーメッセージ: {{uploaded_pdf_content}}
     ↓ spec JSON(新旧比較表形式)
[HTTP ノード] POST /generate  { "spec": {{llm_output}} }
     ↓ { "download_url": "http://...", "filename": "...", "sections": N }
[End]

Gemini はアップロードされた PDF をマルチモーダルで読み取ります。サーバー側での PDF パースは不要です。

仕様書生成

[HTTP ノード] GET /schema/manual
     ↓ prompt_context
[LLM ノード] 仕様書内容の構造化
[HTTP ノード] POST /generate/manual  { "spec": {...} }

JSON スペック仕様(新旧比較表)

段落スペック(old_paragraphs / new_paragraphs の各要素)

{
  "text": "テキスト(シンプルな場合)",
  "segments": [
    { "text": "通常テキスト" },
    { "text": "赤い変更箇所", "color": "red", "underline": true },
    { "text": "続き" }
  ],
  "bold": false,
  "color": "black",
  "underline": false,
  "align": "justify",
  "indent": 0,
  "sz": 19
}

textsegments はどちらか一方を使います。segments は1段落内に複数フォーマットが混在する場合に使います。

コメントアンカー

{
  "anchor": "作業手順確認書類",
  "text": "名称変更:作業手順確認書類→作業安全確認表",
  "column": "old"
}
  • anchor: コメントをつけたいテキスト(完全一致)
  • text: Word コメントバルーンに表示される内容
  • column: "old" | "new" | "both"

LangFlow / Python での使用例

import requests

# 1. スキーマ取得(Dify HTTP ノードの代替)
schema = requests.get("http://localhost:3456/schema/comparison").json()
print(schema["prompt_context"])  # → LLM に注入するテキスト

# 2. 新旧比較表生成
spec = {
  "doc_title": "通信関係請負工事共通仕様書 比較表",
  "sections": [
    {
      "id": "section19",
      "title": "【19.施工方法】",
      "status": "changed",
      "old_paragraphs": [{"text": "19.施工方法および工事工程", "bold": True}],
      "new_paragraphs": [{"text": "20.施工方法および工事工程", "bold": True}],
      "notes": ["・名称変更に伴う見直し"],
      "comments": [{"anchor": "作業手順確認書類", "text": "名称変更", "column": "old"}],
    }
  ]
}

# ローカル保存 + パス返却
response = requests.post("http://localhost:3456/generate", json={
  "spec": spec,
  "output_filename": "比較表_第3回改正",
})
print(response.json())
# → {"success": true, "path": ".../比較表_第3回改正.docx", "download_url": "...", ...}

ファイル構成

docx-mcp/
├── src/
│   ├── index.js          # MCP stdio サーバー(Claude Desktop / Code)
│   ├── http-server.js    # HTTP REST サーバー(Dify / LangFlow)
│   ├── docx-generator.js # コア: JSON → 新旧比較表 .docx 変換エンジン
│   ├── manual-generator.js # コア: JSON → 仕様書 .docx 変換エンジン
│   ├── schema.js         # Zod バリデーション + LLM 注入用スキーマ定義
│   └── test.js           # テスト
├── docs/
│   └── dify-tool.yaml    # Dify Custom Tool / OpenAPI 定義
├── package.json
└── README.md

環境変数

変数 デフォルト 説明
OUTPUT_DIR ~/Desktop/docx-output 生成ファイルの保存先
PORT 3456 HTTP モードのポート番号

MCP Server · Populars

MCP Server · New