Skip to main content
Glama

概要

MCP-Resume-Tailorは、LibreOfficeのUNO APIを通じてドキュメント編集を自動化するModel Context Protocolサーバーシステムです。「ドキュメントエディター」と「求人情報キーワード抽出器」という2つのMCPサーバーがClaude Desktopに接続し、自然な会話からAI主導の履歴書カスタマイズを実現します。

エディターは、中間形式に変換するのではなく、LibreOfficeの内部ドキュメントオブジェクトモデルを通じて.odtファイルを直接操作することで、ドキュメントの完全な忠実性を維持します。ブックマークで区切られたセクションが編集可能な領域を定義し、テンプレートの書式設定、スタイル、レイアウトを保持したままコンテンツが置換されます。キーワード抽出器はClaude APIを通じて求人情報を分析し、調整プロセスをガイドする構造化された5段階のランク付けされた出力を返します。

Related MCP server: Resume Tailor MCP Server

技術スタック

設計原則

1. ネイティブAPIによるドキュメントの忠実性

目標: すべての編集において、テンプレートの完全な書式設定、スタイル、レイアウトを維持する。

ドキュメントをMarkdownやHTMLに変換する(情報が失われる変換)のではなく、エディターはローカルソケット経由でLibreOfficeのUNOブリッジに接続し、ライブドキュメントモデルを操作します。ブックマークのペアが編集可能な領域を区切ります。コンテンツの置換はドキュメントオブジェクトレベルで行われるため、フォント、段落スタイル、間隔、ページ構造はテンプレート作成者が設計した通りに正確に保持されます。

2. MCPネイティブなツール設計

目標: ドキュメント編集とキーワード抽出を、RESTラッパーではなく、ファーストクラスのMCPツールとして公開する。

両方のサーバーは、型定義されたツールスキーマを使用してFastMCP上に直接構築されています。Claude DesktopはModel Context Protocolを通じてそれらを呼び出します。グルーコードやプロンプトインジェクション、APIの調整は不要です。AIは会話のコンテキストに基づいて各ツールをいつどのように呼び出すかを決定し、キーワード抽出の出力とドキュメント編集を単一のインタラクティブなセッションで組み合わせます。

3. トランスポートに依存しないデプロイメント

目標: 開発用にローカルで実行し、信頼性のためにコンテナ化する。どちらの場合も同じMCPツールインターフェースを使用する。

ローカルモードではstdioトランスポートを使用します。Claude DesktopがPythonプロセスを直接起動します。Dockerモードでは、両方のサーバーをNginxの背後で実行し、プロキシスクリプトがClaude Desktopのstdioプロトコルをコンテナ内のHTTP/SSEエンドポイントにブリッジします。MCPツールインターフェースはどちらのモードでも同一であり、コードの変更や機能の差異はありません。


アーキテクチャ

ローカル / stdio

Claude Desktop ──stdio──▶ resume_editor_server.py ──UNO──▶ LibreOffice (port 2002) ──▶ .odt
Claude Desktop ──stdio──▶ jd_keyword_extractor_mcp.py ──API──▶ Claude API

Claude Desktopは各MCPサーバーを子プロセスとして起動します。ドキュメントエディターは、ポート2002のUNOブリッジ経由でヘッドレスLibreOfficeインスタンスに接続します。キーワード抽出器はAnthropic APIを直接呼び出します。

コンテナ化 / HTTP

Claude Desktop ──stdio──▶ macOS proxy ──HTTP──▶ Docker (Nginx)
                                                  ├─ :5001 → Resume Editor MCP (port 8000, streamable-http)
                                                  ├─ :5002 → JD Extractor MCP (port 9000, streamable-http)
                                                  └─ LibreOffice headless (port 2002, internal)

macOSプロキシスクリプトは、Claude Desktopのstdio MCPプロトコルとコンテナ化されたHTTP/SSEエンドポイントの間を変換し、MCPセッションIDの管理とサーバー送信イベントストリームの解析を処理します。Nginxはトラフィックを適切な内部サービスにルーティングします。


MCPツールインターフェース

ツール

サーバー

説明

update_resume_section

ドキュメントエディター

ブックマークで区切られた単一セクションのコンテンツを置換

update_multiple_resume_sections

ドキュメントエディター

複数のセクションを一度にアトミックに更新

get_available_sections

ドキュメントエディター

現在のテンプレート内のすべての編集可能なブックマーク領域をリストアップ

extract_jd_keywords

キーワード抽出器

求人情報を分析し、構造化されたキーワードランキングを返す

編集可能なセクション

ドキュメントエディターは、ブックマークペアで区切られた領域を操作します。現在のテンプレートでは以下が公開されています:

セクション

ブックマーク範囲

Skills

Skills_Start → Skills_End

Summary

Summary_Start → Summary_End

WorkExperience1

WorkExperience1_Start → WorkExperience1_End

WorkExperience2

WorkExperience2_Start → WorkExperience2_End

WorkExperience3

WorkExperience3_Start → WorkExperience3_End

キーワード抽出の出力

extract_jd_keywordsツールは、以下の構造化されたJSONを返します:

  • 5段階のランク付けされたキーワード — 必須、高、中、低、あれば尚可

  • 要件の概要と役割のコンテキスト

  • 投稿から抽出されたツール、技術、手法

  • 主な責任と望ましい成果

  • 役割のレベル、範囲、および会社のコンテキスト


解決された最も困難な問題

1. LibreOffice UNOブリッジの信頼性

問題: LibreOfficeのUNO APIには、ポート2002で開かれたソケットを持つ実行中のヘッドレスインスタンスが必要です。接続の切断、ドキュメントのロック、プロセス状態のリークは、長時間実行されるセッションにおける一般的な障害モードです。

解決策: エディターは、UNOブリッジの確立、URLプロトコル経由でのドキュメントの読み込み、開閉状態の処理、およびテンプレートを上書きしないためのタイムスタンプ付き出力ファイルへの書き込みなど、接続のライフサイクル全体を管理します。Dockerデプロイメントでは、MCPサーバーがリクエストの処理を開始する前にLibreOfficeが接続を受け入れていることを保証するために、専用の起動シーケンスを使用します。

2. MCPトランスポートブリッジング (stdioからHTTPへ)

問題: Claude DesktopはstdioベースのMCPトランスポートのみをサポートしています。コンテナ化されたサービスはHTTPエンドポイントを公開します。これらは根本的に異なるプロトコルモデルであり、ストリームセマンティクスに互換性がありません。

解決策: カスタムプロキシスクリプト(mac_proxy_resume_editor.py、mac_proxy_jd_extractor.py)がそのギャップを埋めます。これらはstdinからJSON-RPCメッセージを読み取り、HTTPリクエストとしてコンテナに転送し、SSEレスポンスストリームをMCPメッセージに解析し直し、接続ライフサイクル全体でセッションIDを管理します。Claude Desktopからはローカルのstdioサーバーに見え、コンテナからは標準的なHTTPクライアントに見えます。

3. ブックマークを保持したコンテンツ置換

問題: .odtドキュメント内のブックマーク間のテキストを置換する際、基盤となるXMLを破損させることなく、周囲のドキュメント構造(段落スタイル、文字書式、ページレイアウト)を保持する必要があります。

解決策: UNO APIは生のXMLではなく、LibreOfficeのライブドキュメントオブジェクトモデル上で動作します。replace_bookmark_range_text()は、ペアになったブックマーク(Section_Start / Section_End)間のテキスト範囲を列挙し、既存のコンテンツを段落ごとに削除し、テンプレートのデフォルトの段落および文字スタイルを継承しながら新しいコンテンツを挿入します。


前提条件

  • Python 3.10+

  • UNOサポート付きLibreOffice (libreoffice-script-provider-python)

  • ブックマークペアを持つ.odt履歴書テンプレート(ブックマーク設定ガイドを参照)

  • コンテナ化されたデプロイメントの場合: DockerおよびDocker Compose

  • キーワード抽出の場合: Anthropic APIキー

ローカルセットアップ

git clone https://github.com/adi2355/MCP-Resume-Tailor.git
cd MCP-Resume-Tailor

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# Link system UNO modules into venv
ln -s /usr/lib/python3/dist-packages/uno.py .venv/lib/python3.*/site-packages/uno.py
ln -s /usr/lib/python3/dist-packages/unohelper.py .venv/lib/python3.*/site-packages/unohelper.py

LibreOfficeの起動

soffice --accept="socket,host=localhost,port=2002;urp;" --headless --norestore --nologo --nodefault &

Claude Desktopの設定 (stdio)

Claude Desktopの設定に以下を追加します:

{
  "mcpServers": {
    "LibreOfficeResumeEditor": {
      "command": "/path/to/MCP-Resume-Tailor/.venv/bin/python",
      "args": ["resume_editor_server.py"],
      "cwd": "/path/to/MCP-Resume-Tailor"
    },
    "JDKeywordExtractor": {
      "command": "/path/to/MCP-Resume-Tailor/.venv/bin/python",
      "args": ["jd_keyword_extractor_mcp.py"],
      "cwd": "/path/to/MCP-Resume-Tailor"
    }
  }
}

Dockerデプロイメント

docker compose up --build

コンテナ化された使用のためにClaude Desktopを設定します:

{
  "mcpServers": {
    "LibreOfficeResumeEditor": {
      "url": "http://localhost:5001"
    },
    "JDKeywordExtractor": {
      "url": "http://localhost:5002"
    }
  }
}

プラットフォーム固有の詳細については、DockerデプロイメントガイドおよびmacOSセットアップガイドを参照してください。


ドキュメント

ドキュメント

説明

Claude MCP使用ガイド

サンプルプロンプトを使用したClaude Desktop統合のステップバイステップガイド

Dockerデプロイメント

コンテナ化されたセットアップ、ポートマッピング、およびサービス管理

macOSセットアップ

プラットフォーム固有のインストールおよびUNO設定

最適化されたワークフロー

2段階のパイプライン:JDキーワード抽出とそれに続くターゲットを絞った調整

ブックマーク設定

LibreOfficeで.odtテンプレートにブックマークペア領域を追加する方法


MCP-Resume-Tailor/
├── resume_editor_server.py            # MCP server: document section editing via UNO
├── jd_keyword_extractor_mcp.py        # MCP server: JD keyword extraction via Claude API
├── edit_resume_uno.py                 # Core LibreOffice UNO API operations
├── container_api.py                   # Flask REST wrapper for container mode
├── mac_proxy_resume_editor.py         # stdio → HTTP proxy (document editor)
├── mac_proxy_jd_extractor.py          # stdio → HTTP proxy (keyword extractor)
├── docker-compose.yml                 # Multi-service container orchestration
├── Dockerfile                         # Ubuntu 22.04 + LibreOffice + Python
├── start_container_service.sh         # Docker entrypoint script
├── start_resume_tailor_services.sh    # Start both MCP services locally
├── requirements.txt                   # Python dependencies
├── claude_desktop_config.json         # Claude Desktop config (stdio mode)
├── claude_desktop_config_docker.json  # Claude Desktop config (HTTP/Docker mode)
├── CLAUDE_MCP_USAGE.md                # Integration guide
├── DOCKER_README.md                   # Docker documentation
├── MACOS_SETUP.md                     # macOS setup guide
├── OPTIMIZED_SYSTEM_USAGE.md          # Workflow documentation
└── setup_resume_bookmarks.md          # Template bookmark guide

Related MCP Connectors

Related MCP Servers