# How OfficeCLI's MCP Server Mode Works for AI Coding Agents

> Discover how OfficeCLI's MCP server mode enables AI coding agents to control PowerPoint and Excel directly using JSON-RPC. Learn about this powerful integration with iOfficeAI/OfficeCLI.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: internals
- Published: 2026-07-08

---

**OfficeCLI's MCP server mode exposes the full Office automation CLI as a JSON-RPC tool over stdin/stdout, allowing AI agents to execute PowerPoint and Excel commands directly via the Model Context Protocol.**

OfficeCLI is an open-source command-line interface for automating Microsoft Office documents. Its MCP server mode transforms the standalone binary into a long-running server that communicates through a simple STDIO-JSON-RPC 2.0 channel, enabling AI coding agents to drive Office operations without spawning external processes.

## Starting the MCP Server and Registration

The MCP server mode is initiated through the `officecli mcp` command. In [`src/officecli/Program.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Program.cs) (lines 70-78), the CLI parses the `mcp` subcommand and delegates to `OfficeCli.McpServer.RunAsync()` to start the long-lived server process.

When a specific target is supplied—such as `officecli mcp claude` or `officecli mcp cursor`—the `McpInstaller` class handles registration with the respective AI client. Located in [`src/officecli/McpInstaller.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/McpInstaller.cs) (lines 10-18), this logic writes the necessary configuration files to integrate the binary with Claude Desktop, LM Studio, or Cursor.

## The JSON-RPC Request Loop

Once started, `McpServer.RunAsync` opens `Console.OpenStandardInput()` and `Console.OpenStandardOutput()` and enters an infinite read-loop (lines 75-88 in [`src/officecli/McpServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/McpServer.cs)). Each line is parsed as a single JSON-RPC request; batch requests are explicitly rejected (lines 86-97).

The server implements four core protocol handlers:

- **`initialize`** – `HandleInitialize` (lines 115-118) returns the protocol version, server capabilities, and server info
- **`tools/list`** – `HandleToolsList` (lines 122-124) advertises a single tool named **officecli** with its description
- **`tools/call`** – `HandleToolsCall` (lines 126-132) executes the actual CLI commands
- **`ping`** – Inline writer (line 120) provides a simple health-check mechanism

All responses are constructed using `Utf8JsonWriter` (lines 15-17) to maintain trim-friendly binary size.

## The CLI-as-a-Tool Bridge

`HandleToolsCall` (lines 132-162) acts as the bridge between the MCP protocol and OfficeCLI's internal command pipeline. This method validates the incoming `params` object, extracts the **tool name** and **arguments**, then delegates to `ExecuteCommandLine` (line 170).

The implementation enforces strict validation:

- **Tool name** must be exactly `"officecli"`; any other name returns JSON-RPC error code `-32602` (lines 155-156)
- `ExecuteCommandLine` (lines 170-197) converts the JSON-encoded `command` payload into a standard `argv` array via `ExtractArgv` and `Tokenize`
- The first token `"officecli"` is automatically stripped in `ExtractArgv` (lines 22-25), allowing the AI model to pass verbs like `add`, `set`, or `view` directly

## Command Execution Paths

The MCP server supports three distinct execution paths based on the tokenized command:

**Skill Loading** – When `argv[0]` matches `load_skill`, `skill`, or `skills`, the server calls `HandleSkillCommand` to return the skill catalog or specific [`SKILL.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/SKILL.md) documentation (lines 168-183).

**Screenshot Generation** – If `argv` starts with `view` and contains `screenshot`, the `IsScreenshot` detector (line 63) triggers `RunScreenshotArgv`. This executes the `view … screenshot` command, writes the PNG to a temporary file, and returns a base-64 encoded image block (lines 186-200).

**Regular CLI Execution** – All other commands delegate to `RunCliRaw`, the same in-process runner used by the standalone CLI. Results are packaged into `McpContent` blocks containing STDOUT/STDERR (lines 197-205).

The final JSON-RPC response wraps the result in a `"result"` object with an **array of content blocks** (`type`, `text`/`data`, `mimeType`) and an `isError` flag (lines 227-242).

## Environment Configuration and Auto-Upgrades

Before entering the request loop, the server configures two critical environment flags to prevent unwanted behavior in the MCP context (lines 41-52):

1. Disables the resident process that normally keeps OfficeCLI running between commands
2. Suppresses the "stdin is also redirected" warning that would corrupt the JSON stream

To ensure long-running MCP processes receive updates without中断ing the JSON-RPC stream, a background task `RunPeriodicUpgradeCheckAsync` runs the standard OfficeCLI auto-upgrade logic every hour (lines 46-73). This checks for new releases asynchronously while the server continues processing requests.

## Code Examples

### Starting the MCP Server

```bash

# Start the server (blocks terminal, waits for JSON-RPC on stdin)

officecli mcp

```

### Registering with LM Studio

```bash

# One-time registration with LM Studio

officecli mcp lms

```

### Python Client Example

```python
import subprocess, json

proc = subprocess.Popen(
    ["officecli", "mcp"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    text=True,
)

def rpc(method, params=None, id=1):
    req = {"jsonrpc": "2.0", "id": id, "method": method}
    if params:
        req["params"] = params
    proc.stdin.write(json.dumps(req) + "\n")
    proc.stdin.flush()
    return json.loads(proc.stdout.readline())

# Initialize and list available tools

print(rpc("initialize"))
print(rpc("tools/list"))

# Execute a CLI command via MCP

cmd = {
    "name": "officecli",
    "arguments": {
        "command": "add deck.pptx /slide[1] --type shape --prop text=Hello"
    }
}
print(rpc("tools/call", cmd))

```

### Requesting a Screenshot

```json
{
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "officecli",
    "arguments": {
      "command": ["view", "deck.pptx", "screenshot", "--out", "tmp.png"]
    }
  }
}

```

The server returns a content block with `"type":"image"` and base-64 encoded PNG data (`"mimeType":"image/png"`).

## Summary

- **OfficeCLI's MCP server mode** exposes the entire CLI through a single `officecli` tool over JSON-RPC 2.0 on stdin/stdout
- The **registration system** in [`McpInstaller.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/McpInstaller.cs) supports Claude, LM Studio, Cursor, and other MCP-compatible clients
- **Command execution** strips the binary name automatically, allowing natural language commands like `add` or `view` to flow directly into the System.CommandLine pipeline
- **Special handlers** manage skill documentation retrieval and screenshot generation with base-64 image encoding
- **Background auto-upgrades** ensure the long-running server stays current without corrupting the JSON stream

## Frequently Asked Questions

### What is the Model Context Protocol (MCP) in OfficeCLI?

The Model Context Protocol is a standardized interface that allows AI agents to discover and call tools. In OfficeCLI, the MCP server mode implements this protocol over STDIO using JSON-RPC 2.0, exposing the Office automation CLI as a single tool that AI agents can invoke to manipulate PowerPoint and Excel files programmatically.

### How does OfficeCLI handle authentication in MCP server mode?

OfficeCLI's MCP server mode relies on the same authentication mechanisms as the standard CLI. Since the server runs as the same user process, it inherits existing Office 365 or local file system permissions. No additional authentication tokens are required specifically for the MCP interface; the `Initialize` handler simply validates the protocol version and capabilities.

### Can AI agents execute arbitrary shell commands through the MCP server?

No. The MCP server strictly validates that the tool name equals `"officecli"` (returning error `-32602` otherwise). The `ExecuteCommandLine` method in [`McpServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/McpServer.cs) tokenizes the command argument and routes it through the internal CLI parser, preventing shell injection while allowing full access to OfficeCLI's documented commands like `add`, `set`, `view`, and `load_skill`.

### How does the screenshot functionality work for AI agents?

When an AI agent sends a `tools/call` request containing `view [file] screenshot`, the server detects this pattern via `IsScreenshot` (line 63), executes the rendering command, writes the PNG to a temporary file, and returns a base-64 encoded image block in the JSON-RPC response. This allows agents to "see" the document state visually without managing file paths or external viewers.