MCP server that bridges Claude Code to Microsoft Office (Word and Excel) via WebSocket, enabling AI-powered document and spreadsheet editing through Office.js
Strong tool naming (verb_noun pattern consistently applied across all 15 tools). Descriptions are detailed and context-rich (avg ~180 chars), well above the 10-char minimum. All tools have explicit Zod schemas with type definitions and parameter descriptions. However, output schemas are not documented, LLMs cannot predict response structure. Error handling is basic (asMcpError wrapper) with no recovery guidance. Missing tool annotations (readOnlyHint, destructiveHint) despite clear risk classifications. No pagination support on list-like tools (excel_list_sheets, excel_find_value). Some parameter descriptions could be more prescriptive about constraints (e.g., A1 notation format for excel_read_range).
Delete one or more rows from the active Excel worksheet starting at a specified row number. Existing rows below are shifted up.
Search for a value in Excel cells across one or all sheets. Returns matching cells with their sheet, row, column, A1 address, and cell value. Supports case-sensitive and whole-cell matching.
Get the currently selected range in the active Excel worksheet. Returns the address, sheet name, row/column counts, and cell values.
Insert one or more blank rows into the active Excel worksheet at a specified row number. Existing rows below are shifted down.
List all worksheets in the active workbook. Returns sheet names, positions, used ranges, and row/column counts for each sheet.
Read cell values from a specified range in Excel. Specify `address` (A1 notation, optionally sheet-qualified like 'Sheet1!A1:C5') and optionally `sheet`. With no address, returns the used range of the sheet. Returns address, row/column counts, and cell values.
Output schemas not documented. LLMs cannot predict response structure (e.g., what fields does office_read_paragraphs return? Is it {paragraphs: [...], count: number}?). Forces agents to guess and parse unstructured JSON.
Missing tool annotations. Tools like office_replace_paragraphs (WRITE), excel_delete_rows (DESTRUCTIVE), and office_get_selection (READ_ONLY) have risk classifications in comments but no destructiveHint/readOnlyHint in schema. Agents cannot infer safety constraints.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2026-07-28+ | v2 |
Select a range of cells in Excel. The range is specified in A1 notation and can be sheet-qualified (e.g., 'Sheet1!A1:D9'). The specified sheet is activated if different from the current sheet.
Write cell values to a specified range in Excel. Requires `address` (A1 notation) and `values` (a 2D array). The shape of the range must match the shape of the values array exactly.
Remove comments from the active Word document. Specify exactly one of: `paragraph_ids` (clear comments anchored on these paragraphs), `heading_section` (clear comments in this section), or `all: true` (clear every comment in the doc). Useful when starting a fresh review pass or after addressing prior findings.
Remove highlight formatting from text in the active Word document. Specify exactly one of: `paragraph_ids` (clear highlights from these specific paragraphs), `heading_section` (clear an entire section by heading), or `all: true` (clear every highlight in the document). Call this when the user has addressed prior findings.
Get the user's current selection in the Word document. Returns selected text, the paragraph IDs the selection covers, and intra-paragraph character ranges. Call this whenever the user refers to 'this', 'here', 'the selection', or asks to edit existing content without specifying location.
Highlight text in the active Word document, color-coded by severity. Use for review and QC workflows where you want the user to *see* findings directly in the doc rather than hunt through a chat list. Pass an array of targets — each highlights either the whole paragraph (no `query`) or specific text within it (a `query` substring). Severities map to highlight colors: error→red, warning→yellow (default), info→turquoise, uncertain→pink. Pair with `office_add_comment` to attach an explanation to each highlight so the user knows what's wrong and how to fix it.
Insert new paragraphs into the active Word document. Specify `after` as either { id: <paragraph_id> } to insert after a specific paragraph, or { heading: <heading_text> } to insert at the top of that section (immediately after the heading). Set `track_changes: true` to insert as a tracked-change for review. Leave `style_per_para` unset to inherit style from surrounding context.
Read paragraphs from the active Word document. Specify exactly one of `ids` (paragraph IDs), `heading_section` (a heading text — returns everything under that heading until the next same-or-higher-level heading), or `range` (an [start_index, end_index] paragraph range). With NO arguments, returns every paragraph in the doc as a **preview** truncated to ~500 characters each — use this for orientation only. When a preview paragraph has `truncated: true` (and a `full_length` field), the actual paragraph is longer; re-read it via `ids: [<id>]` (full text, no truncation) before quoting or analyzing in-paragraph content. To force a full no-args dump of the whole doc, pass `preview: false` (heavy — only use for short docs).
Replace the entire text of specific paragraphs, 1:1 by ID. **Use this ONLY when the whole paragraph is genuinely being rewritten from scratch** — the user said 'rewrite p47' or 'redraft this paragraph.' For anything narrower (changing a word, fixing a phrase, renaming a term, adjusting one sentence inside an otherwise-intact paragraph), use `office_replace_text` instead — never re-emit a whole paragraph to change part of it. The paragraph's existing style is preserved unless you pass style_per_para. Pass track_changes: true so the user can review the rewrite.
No pagination or result limits documented. excel_list_sheets and excel_find_value could return unbounded results. No mention of max result count, offset/limit params, or next_cursor. Large result sets risk context window exhaustion.
Error handling lacks recovery guidance. asMcpError() wraps errors as plain text with no categorization (retryable vs user-fixable vs fatal). Agents cannot determine next steps, should they retry, ask user, or abort?
Parameter constraints not fully specified. excel_read_range and excel_write_range accept A1 notation but description lacks format detail (e.g., 'A1:C5 or Sheet1!A1:C5'). Agents may pass invalid formats. office_highlight severity enum is documented but no guidance on when to use each level.