Skip to main content
Glama
README.md
# Office MCP

[![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Cross--Platform%20Fallback-lightgrey.svg)](https://github.com/)
[![MCP Specification](https://img.shields.io/badge/MCP-1.0.0-purple.svg)](https://modelcontextprotocol.io/)

**Office MCP** is a Windows-native [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server providing high-fidelity automation, AST inspection, and transactional mutation of Microsoft Office documents (**Excel**, **Word**, and **PowerPoint**).

Built on top of **FastMCP**, Office MCP combines native Windows COM automation (via `pywin32` with Single-Threaded Apartment isolation) with pure-Python fallbacks (`openpyxl`, `python-docx`, `python-pptx`), backed by an airtight **Safety Engine** featuring path sandboxing, in-memory concurrency locks, automatic SHA-256 pre-mutation snapshots, SQLite WAL audit logging, and post-mutation invariant verifiers.

---

## Table of Contents

1. [Architecture Overview](#architecture-overview)
2. [Key Capabilities & Safety Guarantees](#key-capabilities--safety-guarantees)
3. [Prerequisites & Installation](#prerequisites--installation)
4. [Configuration](#configuration)
5. [Client Integration](#client-integration)
   - [Claude Desktop](#claude-desktop)
   - [Antigravity / Gemini CLI](#antigravity--gemini-cli)
   - [VS Code / Cursor (.mcp.json)](#vs-code--cursor-mcpjson)
6. [MCP Tools Reference (19 Tools)](#mcp-tools-reference)
   - [Excel Tools](#excel-tools)
   - [Word Tools](#word-tools)
   - [PowerPoint Tools](#powerpoint-tools)
   - [General & Safety Tools](#general--safety-tools)
7. [MCP Resources & Prompts](#mcp-resources--prompts)
8. [Transactional ChangeSet Protocol](#transactional-changeset-protocol)
   - [Excel ChangeSet Example](#excel-changeset-example)
   - [Word ChangeSet Example](#word-changeset-example)
   - [PowerPoint ChangeSet Example](#powerpoint-changeset-example)
9. [Development & Testing](#development--testing)
10. [Troubleshooting & COM Error Handling](#troubleshooting--com-error-handling)

---

## Architecture Overview

```mermaid
flowchart TD
    Client["LLM / MCP Client<br/>(Claude, Antigravity, Cursor)"] -->|JSON-RPC| Server["FastMCP Server<br/>(office_mcp.server)"]

    subgraph SafetyEngine ["Safety & Concurrency Engine"]
        Sandbox["Path Sandbox<br/>(OFFICE_MCP_ALLOWED_ROOTS)"]
        LockMgr["DocumentLockManager<br/>(Exclusive in-memory write locks)"]
        SnapMgr["SnapshotManager<br/>(.office_snapshots + SHA-256)"]
        Audit["AuditLogger<br/>(SQLite WAL: office_audit.db)"]
    end

    subgraph ExecutionLayer ["Transactional Execution Pipeline"]
        Executor["ChangeSet Executor"]
        Verifier["Verification Engine<br/>(AST, Formula Errors, Visual PNG)"]
    end

    subgraph DriverLayer ["Dual-Tier Office Drivers"]
        Worker["STA Worker Registry<br/>(Dedicated Thread + pythoncom Pump)"]
        COM["Windows COM Automation<br/>(Excel, Word, PowerPoint .Application)"]
        Fallback["Pure-Python Fallbacks<br/>(openpyxl, python-docx, python-pptx)"]
    end

    Server --> Sandbox
    Sandbox --> LockMgr
    LockMgr --> SnapMgr
    SnapMgr --> Executor
    Executor --> DriverLayer
    DriverLayer --> Worker
    Worker --> COM
    Worker -.->|Non-Windows| Fallback
    Executor --> Verifier
    Verifier -->|Pass| Commit["Commit Document & Release Lock"]
    Verifier -->|Fail| Rollback["Auto-Rollback to .bak Snapshot"]
    Commit --> Audit
    Rollback --> Audit
```

---

## Key Capabilities & Safety Guarantees

- **Inspect First, Minimize Mutations, Verify Everything**: Full document hierarchy and metadata inspection prior to applying modifications.
- **STA COM Isolation**: Windows COM calls execute in dedicated Single-Threaded Apartment background threads with active message pumps (`pythoncom.PumpWaitingMessages()`) and task timeouts to avoid modal dialog deadlocks.
- **Canonical Filesystem Sandboxing**: Operations outside `OFFICE_MCP_ALLOWED_ROOTS` are immediately rejected (`SecuritySandboxError`).
- **Pre-Mutation Snapshot & Auto-Rollback**: Byte-exact `.bak` snapshots are generated before any write. Invariant failures (e.g., `#REF!`, `#DIV/0!`, corrupted AST, missing elements) trigger an automatic, immediate rollback.
- **High-Performance 2D SAFEARRAY Marshaling**: Bulk matrix data assignment in Excel COM runs orders of magnitude faster than individual cell writes.
- **Visual Slide Verification**: PowerPoint slides can be exported to PNG at custom resolutions and validated against bounding box collisions.
- **SQLite WAL Audit Trail**: All reads, writes, snapshots, and rollbacks are recorded with execution metrics in `office_audit.db`.

---

## Prerequisites & Installation

### System Requirements
- **Operating System**: Windows 10/11 or Windows Server (for native COM automation). Cross-platform environments will utilize fallback drivers.
- **Microsoft Office**: Office 2016, 2019, 2021, or Microsoft 365 desktop apps installed (for COM drivers).
- **Python**: Version `3.10` or higher.

### Installation

Clone the repository and install the package using `pip` or `uv`:

```powershell
# Clone repository
git clone https://github.com/your-org/office-mcp.git
cd office-mcp

# Create and activate virtual environment
python -m venv .venv
.venv\Scripts\activate

# Install package in editable mode
pip install -e .

# (Optional) Install development dependencies
pip install -e ".[dev]"
```

---

## Configuration

Office MCP is configured through environment variables or a `.env` file in the root directory:

| Environment Variable | Default Value | Description |
|---|---|---|
| `OFFICE_MCP_ALLOWED_ROOTS` | `["<cwd>"]` | JSON array or comma-separated list of allowed absolute paths for file operations. |
| `OFFICE_MCP_SNAPSHOT_DIR_NAME` | `.office_snapshots` | Directory name for pre-mutation `.bak` snapshots. |
| `OFFICE_MCP_AUDIT_DB_PATH` | `office_audit.db` | Path to SQLite audit database (WAL mode enabled). |
| `OFFICE_MCP_COM_TIMEOUT_SECONDS`| `30.0` | Timeout in seconds for individual COM task execution. |
| `OFFICE_MCP_LOCK_TIMEOUT_SECONDS`| `10.0` | Timeout in seconds for acquiring an exclusive document lock. |
| `OFFICE_MCP_MAX_SNAPSHOT_RETENTION`| `50` | Maximum number of snapshots preserved per document directory. |
| `OFFICE_MCP_LOG_LEVEL` | `INFO` | Logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`). |
| `OFFICE_MCP_ENABLE_VBA_EXECUTION`| `false` | Security flag controlling whether VBA macros are allowed to run. |

---

## Client Integration

### Claude Desktop

Add the server to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "office-mcp": {
      "command": "python",
      "args": ["-m", "office_mcp.server"],
      "env": {
        "OFFICE_MCP_ALLOWED_ROOTS": "[\"C:\\\\path\\\\to\\\\documents\", \"C:\\\\path\\\\to\\\\workspace\"]",
        "OFFICE_MCP_LOG_LEVEL": "INFO"
      }
    }
  }
}
```

### Antigravity / Gemini CLI

In your project configuration or user settings (`mcp_config.json`):

```json
{
  "mcpServers": {
    "office-mcp": {
      "command": "python",
      "args": ["-m", "office_mcp.server"],
      "cwd": "C:/path/to/office-mcp",
      "env": {
        "OFFICE_MCP_ALLOWED_ROOTS": "[\"C:/path/to/office-mcp\"]"
      }
    }
  }
}
```

### VS Code / Cursor (.mcp.json)

```json
{
  "servers": {
    "office-mcp": {
      "type": "stdio",
      "command": "${workspaceFolder}/.venv/Scripts/python.exe",
      "args": ["-m", "office_mcp.server"]
    }
  }
}
```

---

## MCP Tools Reference

The server exposes 19 specialized tools categorized by application and function:

### Excel Tools

| Tool Name | Parameters | Description |
|---|---|---|
| `excel_open` | `path: str`, `read_only: bool = False` | Opens an Excel workbook within allowed roots and returns sheet, table, and range metadata. |
| `excel_create_workbook` | `path: str`, `sheets: list[str] = None` | Creates a new workbook (.xlsx) with optional custom sheet names. |
| `excel_inspect` | `path: str`, `sheet_name: str = None` | Returns AST metadata: used ranges, tables (`ListObjects`), charts, and named ranges. |
| `excel_read_range` | `path: str`, `range_address: str`, `sheet_name: str = None` | Reads a 2D matrix of values and formulas from an Excel range (e.g. `"A1:D10"`). |
| `excel_apply_changeset` | `changeset: dict` | Applies an atomic batch of operations (values, formulas, formatting, tables, charts) with post-validation and automatic rollback. |
| `excel_export_pdf` | `path: str`, `target_pdf: str` | Exports workbook or active sheet directly to high-fidelity PDF. |

### Word Tools

| Tool Name | Parameters | Description |
|---|---|---|
| `word_open` | `path: str`, `read_only: bool = False` | Opens a Word document (.docx) and extracts its AST metadata. |
| `word_create_document` | `path: str`, `title: str = None` | Creates a new document with an optional Heading 1 title. |
| `word_inspect` | `path: str` | Extracts full document AST (headings, paragraphs, styles, word/character count, and tables). |
| `word_apply_changeset` | `changeset: dict` | Applies atomic operations (headings, paragraphs, bullet lists, tables, cell merges, styles) with structural invariant verification. |
| `word_export_pdf` | `path: str`, `target_pdf: str` | Exports a Word document directly to PDF format. |

### PowerPoint Tools

| Tool Name | Parameters | Description |
|---|---|---|
| `powerpoint_open` | `path: str`, `read_only: bool = False` | Opens a presentation (.pptx) and returns slide metadata. |
| `powerpoint_create_presentation` | `path: str`, `aspect_ratio: str = "16:9"` | Creates a new presentation with 16:9 widescreen or 4:3 standard aspect ratio. |
| `powerpoint_inspect` | `path: str` | Inspects slides, shape geometries, text frames, positions, and layout types. |
| `powerpoint_apply_changeset` | `changeset: dict` | Applies slide creations, textbox additions, shape updates, and image insertions with bounding box checks. |
| `powerpoint_render_slide` | `path: str`, `slide_index: int = 1`, `target_png: str = None`, `width: int = 1920`, `height: int = 1080` | Renders a specific slide to a PNG image for visual inspection. |
| `powerpoint_export_pdf` | `path: str`, `target_pdf: str` | Exports the full presentation to PDF. |

### General & Safety Tools

| Tool Name | Parameters | Description |
|---|---|---|
| `office_rollback_document` | `path: str`, `snapshot_id: str = None` | Manually restores a document to its pre-mutation `.bak` snapshot. |
| `office_query_audit_logs` | `limit: int = 50`, `app_type: str = None`, `status: str = None`, `canonical_path: str = None` | Queries recorded audit logs from `office_audit.db`. |

---

## MCP Resources & Prompts

### Resources
- `office://audit-logs`: Live JSON stream of recent document operations and status codes.
- `office://settings`: Current runtime configuration and canonical allowed root paths.

### Workflow Prompts
- `spreadsheet-audit`: Pre-configured guided prompt for scanning Excel workbooks for formula errors, broken references, and unformatted data ranges.
- `report-generation`: Guided workflow for assembling professional Word documents with structured tables, executive summaries, and heading hierarchies.
- `presentation-builder`: Guided workflow for generating polished PowerPoint decks adhering to widescreen aspect ratios and visual typography rules.

---

## Transactional ChangeSet Protocol

ChangeSets represent atomic units of work. If any operation fails or any invariant is violated during post-mutation verification, the entire batch is rolled back to the pre-mutation snapshot.

### Excel ChangeSet Example

```json
{
  "document_id": "C:/path/to/documents/Financials.xlsx",
  "intent": "Update Q4 Revenue and format summary table",
  "operations": [
    {
      "op_type": "set_range",
      "target": "A1:C3",
      "params": {
        "sheet": "Summary",
        "values": [
          ["Quarter", "Revenue", "Expenses"],
          ["Q3", 150000, 90000],
          ["Q4", 220000, 110000]
        ]
      }
    },
    {
      "op_type": "set_formula",
      "target": "B4",
      "params": {
        "sheet": "Summary",
        "formula": "=SUM(B2:B3)"
      }
    },
    {
      "op_type": "format_range",
      "target": "A1:C1",
      "params": {
        "sheet": "Summary",
        "bold": true,
        "bg_color_rgb": "#1F4E78",
        "color_rgb": "#FFFFFF"
      }
    },
    {
      "op_type": "create_table",
      "target": "SummaryTable",
      "params": {
        "sheet": "Summary",
        "range_address": "A1:C3",
        "style": "TableStyleMedium9"
      }
    }
  ],
  "expected_invariants": [
    "no_formula_errors"
  ],
  "risk_level": "low",
  "dry_run": false
}
```

### Word ChangeSet Example

```json
{
  "document_id": "C:/path/to/documents/Quarterly_Report.docx",
  "intent": "Add Executive Summary and Financial Metrics Table",
  "operations": [
    {
      "op_type": "add_heading",
      "target": "Executive Summary",
      "params": { "level": 1 }
    },
    {
      "op_type": "add_paragraph",
      "target": "During Q4, overall performance exceeded targets across all key business units.",
      "params": { "font_size_pt": 11 }
    },
    {
      "op_type": "insert_table",
      "target": "",
      "params": {
        "rows": 3,
        "cols": 3,
        "headers": ["Department", "Budget", "Actual"],
        "data": [
          ["Engineering", "$500,000", "$480,000"],
          ["Marketing", "$200,000", "$210,000"]
        ],
        "style": "Table Grid"
      }
    }
  ],
  "expected_invariants": [
    {
      "invariant_type": "min_paragraphs",
      "expected_value": 2
    }
  ],
  "risk_level": "low"
}
```

### PowerPoint ChangeSet Example

```json
{
  "document_id": "C:/path/to/documents/PitchDeck.pptx",
  "intent": "Add Title Slide and KPI Callout Shapes",
  "operations": [
    {
      "op_type": "add_slide",
      "target": "",
      "params": {
        "layout_num": 12,
        "title": "Q4 Performance Overview"
      }
    },
    {
      "op_type": "add_textbox",
      "target": "Strategic Growth & Milestones",
      "params": {
        "slide_index": 1,
        "left": 100,
        "top": 120,
        "width": 800,
        "height": 60,
        "font_size": 32,
        "bold": true,
        "color_rgb": "#111827"
      }
    },
    {
      "op_type": "add_shape",
      "target": "rounded_rectangle",
      "params": {
        "slide_index": 1,
        "left": 100,
        "top": 220,
        "width": 300,
        "height": 160,
        "fill_color": "#2563EB",
        "text": "+45% YoY Growth"
      }
    }
  ],
  "expected_invariants": [
    {
      "invariant_type": "min_slide_count",
      "expected_value": 1
    }
  ],
  "risk_level": "medium"
}
```

---

## Development & Testing

Office MCP includes an extensive unit and integration test suite using `pytest`:

```powershell
# Run full test suite
pytest

# Run tests with verbose output
pytest -v

# Run only Excel driver tests
pytest tests/test_excel.py

# Run only safety engine tests
pytest tests/test_safety.py
```

Code formatting and static type checking are enforced via `ruff` and `mypy`:

```powershell
# Format and lint code
ruff check src tests
ruff format src tests

# Static type verification
mypy src
```

---

## Troubleshooting & COM Error Handling

Office MCP translates low-level Windows COM `HRESULT` codes into clear, actionable domain exceptions:

| COM HRESULT | Hex Code | Domain Exception | Description & Recovery |
|---|---|---|---|
| `DISP_E_EXCEPTION` | `0x80020009` | `ComExecutionError` | An internal Office application error occurred. Check parameters. |
| `RPC_E_CALL_REJECTED` | `0x80010001` | `ComTimeoutError` | Office application is busy displaying a modal dialog. Closed via watchdog. |
| `RPC_E_SERVERCALL_RETRYLATER` | `0x8001010A` | `ComTimeoutError` | Office application is handling user interaction. Retried automatically. |
| `RPC_E_WRONG_THREAD` | `0x8001010E` | `ComExecutionError` | COM object accessed across apartment boundaries without marshaling. STA worker ensures thread affinity. |
| `FILE_NOT_FOUND` | `0x80070002` | `DocumentNotFoundError` | The requested document path does not exist. |
| `SHARING_VIOLATION` | `0x80070020` | `DocumentLockError` | Document is locked by another process or instance. |
| `E_FAIL` | `0x80004005` | `OfficeMCPError` | Unspecified COM failure. The engine performs an automatic snapshot restore. |

### Diagnostic Tips
1. **Orphaned Office Processes**: If Excel, Word, or PowerPoint remain hanging in Task Manager, Office MCP's `ProcessManager` terminates registered instances on shutdown. You can also force-terminate via PowerShell:
   ```powershell
   Stop-Process -Name EXCEL, WINWORD, POWERPNT -Force -ErrorAction SilentlyContinue
   ```
2. **Audit Inspection**: Inspect `office_audit.db` using the `office_query_audit_logs` tool or any SQLite viewer to review error stack traces and rollback history.



TDQS

A3.5/5.0

Scored across 19 tools

Disambiguation3/5

Format prefixes make tool groups clear, but within each format `open` and `inspect` heavily overlap: both return metadata or structural information. An agent could easily select the wrong one when trying to examine a document. Other tools like read_range, apply_changeset, and export_pdf are more distinct.

Naming Consistency5/5

All tools follow a consistent `{scope}_{verb}_{object}` snake_case pattern, such as excel_create_workbook and powerpoint_render_slide. The cross-cutting office_* tools are also predictable and fit the convention. Naming is highly consistent across all 19 tools.

Tool Count4/5

19 tools is slightly above the ideal sweet spot, but the count is justified by three distinct document formats and shared cross-cutting capabilities. Each format has a coherent set of create/open/inspect/apply/export tools, plus PowerPoint rendering, so nothing feels extraneous.

Completeness4/5

The tool surface covers the core document lifecycle: create, open, inspect/read, mutate via changesets, rollback, export, and audit. The main gaps are minor, such as no explicit save-as or search tool, but agents can work around these with inspect and changeset operations. Overall, the domain is well covered without severe dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues