Skip to content

Repository files navigation

Office Document MCP Server

Fork of rcarmo/python-office-mcp-server with --namespace filtering for selective tool loading and reduced token overhead.

MCP server providing tools to extract, convert, and generate Microsoft Office documents (Word, Excel, PowerPoint). Originally developed by @rcarmo in parallel with go-ooxml.

Namespace Filtering (--namespace)

The --namespace flag controls which tool modules load at startup. When used with LLM agents, this reduces the tool schema injected into context, saving tokens.

# Load only Word tools + unified office tools
office-mcp-server --namespace word
# Combine multiple namespaces
office-mcp-server --namespace word --namespace excel
# No flag = all 52 tools (backward compatible)
office-mcp-server

Available namespaces:word, excel, pptx, web, azure-pricing

Each document namespace (word, excel, pptx) automatically includes the unified office_* tools (read, inspect, patch, comment, table, template, audit, image) since they are the primary interface for any document type.

Token Savings

LoadToolsEstimated Tokensvs Full
All (no namespace)52~19,400
--namespace word22~9,700-50%
--namespace excel16~7,700-60%
--namespace pptx24~9,500-51%
--namespace web5~1,800-91%
--namespace azure-pricing7~2,800-86%
--namespace word --namespace excel27~11,700-40%

Token estimates based on JSON tool schema size (tool names, descriptions, parameter schemas).

Available Tools

Unified Tools (Primary Interface)

These 8 tools auto-detect document format from file extension:

ToolDescription
office_readRead content from Word/Excel/PowerPoint as JSON or Markdown
office_inspectGet document structure (sheets, slides, sections, tables, comments)
office_patchEdit cells, shapes, sections, or replace placeholders
office_commentAdd or get comments from any document type
office_tableTable operations: add rows, create tables, add bullets
office_templateCopy templates or analyze template structure
office_auditAudit for placeholders, completion, or tracking status
office_imageInsert images into Word, Excel, or PowerPoint documents

Specialized Tools

Word SOW Generation

These were a proof-of-concept approach fod managing and updating specific document templates - all the tools marked sow are deprecated and kept only for historical interest.

ToolDescription
word_generate_sowFill SOW template with structured data
word_cleanup_sowRemove template artifacts and guidance (tracked)
word_get_section_guidanceExtract template instructions from a section
word_parse_sow_templateAnalyze SOW template structure
word_create_sow_from_markdownCreate SOW from Markdown content
word_extract_sow_structureExtract structured data from existing SOW
word_enable_track_changesEnable Word's track changes mode
word_patch_with_track_changesReplace text with revision marks

PowerPoint Slide Management

ToolDescription
pptx_add_slideAdd new slide with specified layout
pptx_delete_slideRemove a slide
pptx_duplicate_slideCopy a slide
pptx_reorder_slidesChange slide order
pptx_hide_slideHide/unhide a slide
pptx_set_notesSet speaker notes
pptx_recommend_layoutGet best layout for content type
pptx_log_changesAdd change log slide

Document Conversion

ToolDescription
word_from_markdownCreate Word document from Markdown (supports inline text or markdown_file path for large inputs)
excel_from_markdownCreate Excel workbook from Markdown tables (supports inline text or markdown_file for large inputs)
pptx_from_markdownCreate PowerPoint from Markdown slides (supports inline text or markdown_file for large inputs)

Utility

ToolDescription
restart_serverHot-reload the server after code changes
list_supported_formatsShow available document formats

Quick Examples

Reading Documents

# Read Excel as Markdownoffice_read(file_path="data.xlsx", output_format="markdown")
# Read specific rangeoffice_read(file_path="data.xlsx", scope="Sheet1!A1:D10")
# Read a single worksheetoffice_read(file_path="data.xlsx", scope="Sheet1")
# Read Word documentoffice_read(file_path="report.docx", output_format="markdown")

Inspecting Structure

# List Excel sheetsoffice_inspect(file_path="data.xlsx", what="sheets")
# List Word tablesoffice_inspect(file_path="report.docx", what="tables")
# List PowerPoint slidesoffice_inspect(file_path="deck.pptx", what="slides")

Editing Content

# Patch Excel celloffice_patch(
file_path="data.xlsx",
changes=[{"target": "A1", "value": "New Value"}]
)
# Patch Word placeholderoffice_patch(
file_path="report.docx",
changes=[{"target": "<Customer>", "value": "Contoso"}]
)
# Patch PowerPoint shapeoffice_patch(
file_path="deck.pptx",
changes=[{"target": "slide:1/Title 1", "value": "New Title"}]
)
# PowerPoint soft return in a single text boxoffice_patch(
file_path="deck.pptx",
changes=[{"target": "slide:1/Title 2", "value": "Contoso{br}Project"}]
)

Table Operations

# Add row to Word tableoffice_table(
file_path="report.docx",
operation="add_row",
table_id="staffing",
data={"Role": "PM", "Count": "1", "Notes": "Lead"}
)
# Create table in Wordoffice_table(
file_path="report.docx",
operation="create",
data={
"headers": ["Phase", "Owner", "Target Date"],
"rows": [{"Phase": "Discovery", "Owner": "PM", "Target Date": "2026-04-01"}],
"insert_after_section": "Delivery Plan"
}
)
# Add table to PowerPointoffice_table(
file_path="deck.pptx",
operation="create",
table_id="3",
data={
"headers": ["Phase", "Duration"],
"rows": [["Discovery", "2 weeks"]]
}
)

Large Markdown Inputs

# Avoid MCP argument-size limits by passing a markdown_file pathword_from_markdown(
output_path="report.docx",
markdown_file="inputs/large-report.md"
)
excel_from_markdown(
output_path="budget.xlsx",
markdown_file="inputs/budget-tables.md"
)
pptx_from_markdown(
output_path="deck.pptx",
markdown_file="inputs/deck.md"
)
word_create_sow_from_markdown(
output_path="sow.docx",
template_path="templates/Agile.docx",
markdown_file="inputs/sow.md"
)

Auditing

# Audit for placeholdersoffice_audit(file_path="report.docx", checks=["placeholders"])
# Audit for completionoffice_audit(file_path="report.docx", checks=["completion"])

Word Review Workflow

The recommended workflow for reviewing documents is this:

1. office_template(operation="copy") → Create working document from template
2. office_template(operation="analyze") → Understand what to preserve vs fill
3. office_inspect(what="tables") → Get EXACT column names for all tables
4. word_generate_sow → Fill placeholders and tables with data
5. office_patch(operation="section") → Add prose to Introduction, Business Context
6. office_table(operation="insert_row") → Add engagement-specific rows to tables
7. office_patch(operation="fix_split") → Replace any remaining split placeholders
8. office_comment(operation="add") → Add review comments for stakeholders
9. word_cleanup_sow → Remove template guidance (tracked)
10. office_audit(checks=["completion"]) → Verify completion score ≥ 80%

Quality Bar: All review tools preserve document structure by editing templates rather than creating new documents from scratch. All changes are tracked for stakeholder review.

Setup

Install from repository (recommended)

Using uv:

uv pip install "git+https://github.com/cjnova/python-office-mcp-server.git"

Using pip:

pip install "git+https://github.com/cjnova/python-office-mcp-server.git"

This installs the office-mcp-server command. Requires Python ≥3.10 (tested with 3.12).

Install from local clone

git clone https://github.com/cjnova/python-office-mcp-server.git
cd python-office-mcp-server
uv pip install .# or: pip install .# or for development: pip install -e .

Run without installing

git clone https://github.com/cjnova/python-office-mcp-server.git
cd python-office-mcp-server
pip install -r requirements.txt
python office_server.py

MCP client configuration

VS Code (.vscode/mcp.json):

{
"servers": {
"office": {
"command": "office-mcp-server"
}
}
}

With namespace filtering:

{
"servers": {
"office-word": {
"command": "office-mcp-server",
"args": ["--namespace", "word"]
},
"office-excel": {
"command": "office-mcp-server",
"args": ["--namespace", "excel"]
}
}
}

Claude Desktop (claude_desktop_config.json):

{
"mcpServers": {
"office": {
"command": "office-mcp-server",
"args": ["--namespace", "word", "--namespace", "excel"]
}
}
}

"args": ["--from", "git+https://github.com/cjnova/python-office-mcp-server.git", "office-mcp-server"] Using uvx (no pre-install needed):

{
"command": "uvx",
"args": ["--from", "git+https://github.com/cjnova/python-office-mcp-server.git", "office-mcp-server", "--namespace", "word"]
}

Using uv tool install (pre-installed, no startup latency):

uv tool install "git+https://github.com/cjnova/python-office-mcp-server.git"

Tool Activation Note

Some MCP clients can start with subsets of tools disabled by policy/session settings. If a call returns a disabled-tool error, enable the corresponding MCP tools in the client first, then retry. This enablement behavior is controlled by the MCP client/host, not by this server.

VS Code (Automatic)

The server can be set to be auto-discovered from .vscode/mcp.json. That is left as an exercise to the reader, but to verify: Open Command Palette → MCP: List Servers → confirm officeServer is listed.

GitHub Copilot CLI

Add the server to your Copilot CLI configuration:

# Open config file
code ~/.config/github-copilot/config.json
# Add this to the mcpServers section:
{
"mcpServers": {
"officeServer": {
"command": "python",
"args": ["/path/to/.github/mcp/office_server.py"]
}
}
}

Running Manually

cd .github/mcp
pip install -r requirements.txt
python office_server.py

Windows Single-File Distribution

Build a standalone .exe using PyInstaller.

Build on Windows

cd .github/mcp
python -m pip install -r requirements.txt
python -m pip install -r requirements-build.txt
python build_windows_onefile.py --clean

Output artifact:

  • dist/office-mcp-server.exe

Custom output name

python build_windows_onefile.py --name office-server-prod

Run executable

dist\office-mcp-server.exe

Use the generated executable in MCP client configuration by pointing command to the .exe path.

Dependencies

  • python-docx — Word document handling
  • openpyxl — Excel workbook handling
  • python-pptx — PowerPoint presentation handling
  • aioumcp — Async MCP server framework
  • pyinstaller — Build-time dependency for one-file Windows executable

Architecture

The server dynamically loads tool modules from tools/:

  • office_unified_tools.py — Unified interface (7 tools)
  • word_tools.py — Word conversion tools
  • word_advanced_tools.py — SOW-specific tools
  • excel_tools.py — Excel conversion tools
  • excel_advanced_tools.py — Excel advanced operations (internal)
  • pptx_tools.py — PowerPoint conversion tools
  • pptx_advanced_tools.py — Slide management tools
  • web_tools.py — Web utilities (fetch, extract, search)
  • azure_pricing_tools.py — Azure pricing queries

Tools are discovered automatically by class name pattern (*Tools).

Namespace Filtering (internals)

The --namespace flag is parsed in office_server.py via _parse_namespace_args(). It calls tools.set_namespace_filter() which restricts _discover_tool_module_names() to only return modules mapped in NAMESPACE_MODULES:

NAMESPACE_MODULES= {
"office": ["office_unified_tools"],
"word": ["office_unified_tools", "word_tools", "word_advanced_tools"],
"excel": ["office_unified_tools", "excel_tools", "excel_advanced_tools"],
"pptx": ["office_unified_tools", "pptx_tools", "pptx_advanced_tools"],
"web": ["web_tools"],
"azure-pricing": ["azure_pricing_tools"],
}

Tool classes are loaded lazily after namespace filtering, then composed into the server class via multiple inheritance (MRO). The unified office_* tools delegate to format-specific tools via self.tool_* method resolution, which is why they must be loaded alongside any document namespace.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages