trackmcp
Back to directory
adi2355

MCP-Resume-Editor

View on GitHub

MCP server system for AI-driven resume customization through LibreOffice UNO, dual stdio/HTTP deployment, structured job-description keyword extraction, and bookmark-preserving document editing via Claude Desktop

1 stars PythonOthers Updated Apr 20, 2026
ai-toolsanthropicautomationclaudeclaude-desktopdockerdocument-editingfastmcplibreofficemcpmodel-context-protocolpythonresumeuno-api

Documentation

Overview

MCP-Resume-Tailor is a Model Context Protocol server system that automates document editing through LibreOffice's UNO API. Two MCP servers — a document editor and a job-description keyword extractor — connect to Claude Desktop, enabling AI-driven resume customization from natural conversation.

The editor preserves full document fidelity by operating directly on `.odt` files through LibreOffice's internal document-object model rather than converting to intermediate formats. Bookmark-delimited sections define the editable regions, and content is replaced while retaining the template's formatting, styles, and layout. The keyword extractor analyzes job descriptions through the Claude API and returns structured, 5-tier ranked output that guides the tailoring process.

Technology Stack

Language

Protocol

Document Engine

AI

Infrastructure

Validation

Design Principles

1. Document Fidelity Through Native API

> Goal: Preserve the template's full formatting, styles, and layout across every edit.

Rather than converting documents to Markdown or HTML — a lossy transformation — the editor connects to LibreOffice's UNO bridge over a local socket and operates on the live document model. Bookmark pairs delimit editable regions. Content replacement happens at the document-object level, so fonts, paragraph styles, spacing, and page structure are preserved exactly as the template author designed them.

2. MCP-Native Tool Design

> Goal: Expose document editing and keyword extraction as first-class MCP tools, not REST wrappers.

Both servers are built directly on FastMCP with typed tool schemas. Claude Desktop invokes them through the Model Context Protocol — no glue code, no prompt injection, no API choreography. The AI decides when and how to call each tool based on the conversation context, combining keyword extraction output with document editing in a single interactive session.

3. Transport-Agnostic Deployment

> Goal: Run locally for development, containerized for reliability — same MCP tool surface either way.

Local mode uses stdio transport: Claude Desktop launches the Python process directly. Docker mode runs both servers behind Nginx, with proxy scripts bridging Claude Desktop's stdio protocol to HTTP/SSE endpoints inside the container. The MCP tool surface is identical in both modes — no code changes, no feature differences.


Architecture

Local / stdio

code
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 launches each MCP server as a child process. The document editor connects to a headless LibreOffice instance via UNO bridge on port 2002. The keyword extractor calls the Anthropic API directly.

Containerized / HTTP

code
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)

The macOS proxy scripts translate between Claude Desktop's stdio MCP protocol and the containerized HTTP/SSE endpoints, handling MCP session ID management and server-sent event stream parsing. Nginx routes traffic to the correct internal service.


MCP Tool Surface

ToolServerDescription
`update_resume_section`Document EditorReplace content in a single bookmark-delimited section
`update_multiple_resume_sections`Document EditorUpdate multiple sections atomically in one pass
`get_available_sections`Document EditorList all editable bookmark regions in the current template
`extract_jd_keywords`Keyword ExtractorAnalyze a job description and return structured keyword rankings

Editable Sections

The document editor operates on bookmark-pair-delimited regions. The current template exposes:

SectionBookmark Range
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`

Keyword Extraction Output

The `extract_jd_keywords` tool returns structured JSON with:

  • 5-tier ranked keywords — critical, high, medium, low, and nice-to-have
  • Requirements summary and role context
  • Tools, technologies, and methodologies extracted from the posting
  • Core responsibilities and desired outcomes
  • Role level, scope, and company context

Hardest Problems Solved

1. LibreOffice UNO Bridge Reliability

Problem: LibreOffice's UNO API requires a running headless instance with an open socket on port 2002. Connection drops, document locks, and process state leaks are common failure modes in long-running sessions.

Solution: The editor manages the full connection lifecycle — establishing the UNO bridge, loading documents via URL protocol, handling open/close state, and writing to timestamped output files to avoid clobbering the template. The Docker deployment uses a dedicated startup sequence to guarantee LibreOffice is accepting connections before the MCP server begins handling requests.

2. MCP Transport Bridging (stdio to HTTP)

Problem: Claude Desktop only supports stdio-based MCP transport. Containerized services expose HTTP endpoints. These are fundamentally different protocol models with incompatible stream semantics.

Solution: Custom proxy scripts (`mac_proxy_resume_editor.py`, `mac_proxy_jd_extractor.py`) bridge the gap: they read JSON-RPC messages from stdin, forward them as HTTP requests to the container, parse the SSE response stream back into MCP messages, and manage session IDs across the connection lifecycle. Claude Desktop sees a local stdio server; the container sees standard HTTP clients.

3. Bookmark-Preserving Content Replacement

Problem: Replacing text between bookmarks in an `.odt` document must preserve the surrounding document structure — paragraph styles, character formatting, page layout — without corrupting the underlying XML.

Solution: The UNO API operates on LibreOffice's live document-object model, not raw XML. `replace_bookmark_range_text()` enumerates the text range between paired bookmarks (`Section_Start` / `Section_End`), removes existing content paragraph by paragraph, and inserts new content while inheriting the template's default paragraph and character styles.


Quick Start

Prerequisites

  • Python 3.10+
  • LibreOffice with UNO support (`libreoffice-script-provider-python`)
  • An `.odt` resume template with bookmark pairs (see Bookmark Setup Guide)
  • For containerized deployment: Docker and Docker Compose
  • For keyword extraction: Anthropic API key

Local Setup

bash
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

Start LibreOffice

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

Claude Desktop Configuration (stdio)

Add to your Claude Desktop config:

json
{
  "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 Deployment

bash
docker compose up --build

Configure Claude Desktop for containerized use:

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

See Docker Deployment Guide and macOS Setup Guide for platform-specific details.


Documentation

DocumentDescription
Claude MCP Usage GuideStep-by-step Claude Desktop integration with example prompts
Docker DeploymentContainerized setup, port mapping, and service management
macOS SetupPlatform-specific installation and UNO configuration
Optimized WorkflowTwo-stage pipeline: JD keyword extraction followed by targeted tailoring
Bookmark SetupHow to add bookmark-pair regions to an `.odt` template in LibreOffice

Folder Structure

code
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

Frequently asked questions

What is MCP-Resume-Editor?

MCP-Resume-Editor is MCP server system for AI-driven resume customization through LibreOffice UNO, dual stdio/HTTP deployment, structured job-description keyword extraction, and bookmark-preserving document editing via Claude Desktop

How do I install MCP-Resume-Editor?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is MCP-Resume-Editor open source?

Yes — it is hosted on GitHub at https://github.com/adi2355/MCP-Resume-Editor and has 1 stars.

Related MCP tools

OpenOSINTOpenOSINT

AI-powered OSINT agent with interactive REPL, MCP server, and CLI. 19 tools. Works with Claude, GPT-4, or local models. For authorized security research only.

1,523 Python
ai-agentanthropicclaude+16
riponcmprojectmem

Open-source coding agent memory. Records issues, attempts, fixes and decisions, then warns your agent before it repeats an approach that already failed. Native MCP server for Claude Code, Cursor, Antigravity and Codex. 100% local, no cloud, no telemetry. MIT.

796 Python
ai-agentsai-memoryai-tools+17
IBMmcp-context-forge

An AI Gateway, registry, and proxy that sits in front of any MCP, A2A, or REST/gRPC APIs, exposing a unified endpoint with centralized discovery, guardrails and management. Optimizes Agent & Tool calling, and supports plugins.

4,422 Python
agentsaiapi-gateway+17
mukul975cve-mcp-server

Production-grade MCP server giving Claude 27 security intelligence tools across 21 APIs — CVE lookup, EPSS scoring, CISA KEV, MITRE ATT&CK, Shodan, VirusTotal, and more.

1,383 Python
cisa-kevclaude-aicve+15
IvanMurzakUnity-MCP

AI Skills, MCP Tools, and CLI for Unity Engine. Full AI develop and test loop. Use cli for quick setup. Efficient token usage, advanced tools. Any C# method may be turned into a tool by a single line. Works with Claude Code, Gemini, Copilot, Cursor and any other absolutely for free.

4,137 C#
aiai-integrationgame-development+16
jlowinfastmcp

🚀 The fast, Pythonic way to build MCP servers and clients Trusted by 19900+ developers. Trusted by 19900+ developers. Trusted by 19900+ developers.

19,927 Python
agentsfastmcpllms+6

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP