update_resume_sectionLABSCO SUMMARY
Tailoring a resume without the document losing its shape.
Everything hard about this sits in the last mile: an assistant can write a sharper skills paragraph in seconds, and then the only way into the document is to paste it and repair the formatting by hand. Editing through LibreOffice's object model instead of a Markdown round trip removes that step, and pairing it with a ranked read of the posting means the rewrite is aimed at something specific rather than generically polished.
What it is
Two servers that work as one pass. The keyword extractor reads a job description and returns a ranked structure — critical down to nice-to-have, alongside the tools, technologies, methodologies, core responsibilities, role level and company context it found. The document editor writes the tailored content back into an .odt resume: it does not convert the file, it drives LibreOffice's own document-object model over a local socket and replaces the text between paired bookmarks, so fonts, paragraph styles, spacing and page structure survive exactly as the template author set them, and output goes to a timestamped file rather than over the template. Editable regions are whatever bookmark pairs a template defines; the one that ships exposes summary, skills and three work-experience blocks. The editor talks to a headless LibreOffice, which has to be running before it can open anything.
What you get
- A job description parsed into ranked keywords, from critical to nice-to-have, with a requirements summary, the tools and methodologies named in the posting, the core responsibilities, and the role's level and scope
- The editable regions the current template exposes, listed by name
- One section's content replaced, with the template's fonts, styles and layout preserved
- Several sections replaced atomically in a single pass, rather than one call at a time
- Output written to a timestamped file, so the template itself is never overwritten
Setup effort
Build from source — git clone https://github.com/adi2355/MCP-Resume-Editor.git
USE CASES
Reading what a posting actually asks for
Parse the job description into ranked keywords with the responsibilities, tools and role level beside them, so the rewrite has something to aim at.
Finding out which parts of the template you can rewrite
List the bookmark-delimited regions the current document exposes before asking for a change that has nowhere to land.
Rewriting one section for one application
Replace the summary or the skills block on its own, with the template's fonts and layout coming through unchanged.
Tailoring the whole resume in one pass
Extract the posting's keywords, then update every affected section together rather than one call and one reload at a time.
4 tools
Listed in project docs. Your client may show a different list.
update_multiple_resume_sectionsget_available_sectionsextract_jd_keywordsBEFORE YOU INSTALL
What to know first
Tools you get
4 tools named in the project's documentation.
Requires
- Python 3.10+
- LibreOffice with UNO support (libreoffice-script-provider-python), running headless on port 2002
- An Anthropic API key in CLAUDE_API_KEY (keyword extractor only)
INSTALLATION
Connect your client
Server setup
git clone https://github.com/adi2355/MCP-Resume-Editor.git
cd MCP-Resume-Editor
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
soffice --accept="socket,host=localhost,port=2002;urp;" --headless --norestore --nologo --nodefault &MCP Clients
Claude Desktop — stdio
{
"mcpServers": {
"LibreOfficeResumeEditor": {
"command": "<YOUR_PATH_TO_MCP_RESUME_EDITOR>/.venv/bin/python",
"args": [
"<YOUR_PATH_TO_MCP_RESUME_EDITOR>/resume_editor_server.py"
]
},
"JDKeywordExtractor": {
"command": "<YOUR_PATH_TO_MCP_RESUME_EDITOR>/.venv/bin/python",
"args": [
"<YOUR_PATH_TO_MCP_RESUME_EDITOR>/jd_keyword_extractor_mcp.py"
],
"env": {
"CLAUDE_API_KEY": "<YOUR_CLAUDE_API_KEY>"
}
}
}
}