Skip to main content
Glama
README.md
# ElixirOffice MCP

An unofficial local stdio MCP server that drives the ElixirOffice desktop editor using a narrow, fixed set of Office JavaScript API commands. It does not edit Office files directly. The integration was verified with the installed ElixirOffice 0.2.1 AppImage on Linux; see [architecture and evidence](docs/architecture.md) and the [capability matrix](docs/capability-matrix.md).

## Requirements

- ElixirOffice desktop AppImage 0.2.1 or a later version with the same `--remote-debugging-pipe` and local API contracts
- Node.js 22 or later
- Linux x86_64 (the AppImage target currently tested)
- One MCP server process per ElixirOffice application instance; do not connect multiple servers to the same single-instance app

## Install and run

```sh
npm ci
npm run build
ELIXIROFFICE_ALLOWED_ROOTS="$HOME/Documents/agent-work" npm start
```

The default executable is `~/Applications/ElixirOffice.AppImage`. Override it with `ELIXIROFFICE_APPIMAGE=/absolute/path/to/ElixirOffice.AppImage`. `ELIXIROFFICE_ALLOWED_ROOTS` is a colon-separated list of existing directories; only regular, non-symlink files below those roots may be opened. By default only the current working directory is authorized. Set `ELIXIROFFICE_PROFILE` to a dedicated ElixirOffice user-data profile when isolation is desired. The AppImage itself is not modified. On hosts without accessible `/dev/fuse`, use the host's already-supported AppImage extraction mode with `APPIMAGE_EXTRACT_AND_RUN=1`; this does not disable Electron's renderer sandbox.

## MCP client configuration

Build first, then configure the client to launch this project's local executable. MCP stdio is the only transport; stdout is reserved for protocol messages and diagnostics go to stderr.

Codex `config.toml`:

```toml
[mcp_servers.elixiroffice]
command = "node"
args = ["/absolute/path/to/elixiroffice-mcp/dist/index.js"]
cwd = "/absolute/path/to/elixiroffice-mcp"
env = { ELIXIROFFICE_ALLOWED_ROOTS = "/absolute/path/to/agent-work", ELIXIROFFICE_APPIMAGE = "/absolute/path/to/ElixirOffice.AppImage" }
```

Claude Code `.mcp.json`:

```json
{
  "mcpServers": {
    "elixiroffice": {
      "command": "node",
      "args": ["/absolute/path/to/elixiroffice-mcp/dist/index.js"],
      "cwd": "/absolute/path/to/elixiroffice-mcp",
      "env": {
        "ELIXIROFFICE_ALLOWED_ROOTS": "/absolute/path/to/agent-work",
        "ELIXIROFFICE_APPIMAGE": "/absolute/path/to/ElixirOffice.AppImage"
      }
    }
  }
}
```

## Available tools

- `document`: open, list, inspect, read Word structure, append/search/replace text, save, and request clean close.
- `spreadsheet`: inspect worksheets; read values and formula fields; bulk-write cell values and basic formatting; add and rename sheets.
- `presentation`: inspect slides, shape text, and notes; add a slide with optional text.
- `pdf`: inspect pages/fields/annotations; add an annotation. Existing form-field filling is wired but not integration-tested.
- `editor_capabilities`: report detected version, implemented operations, and limitations.

Every operation uses an opaque `documentId` returned by `document(open)`. Only one document is controlled at once. The `active-document` resource exposes read-only metadata.

New-document creation, Save As, export destination selection, close-document return-to-home, and many Office operations are not claimed as working. The MCP app does not automate native file dialogs. Close can return `DOCUMENT_CLOSE_NOT_CONFIRMED` if the desktop IPC does not return the renderer to home; save and disconnect/relaunch is currently the reliable persistence path. See the matrix before relying on a feature.

## Testing

```sh
npm test                 # strict TypeScript compilation and unit tests
npm run test:integration # launches the real installed AppImage; needs a graphical session
npm run test:pdf         # live PDF annotation/save/reopen test
```

Set `ELIXIROFFICE_TEST_PPTX` to a disposable blank PPTX to include the live presentation test in `test:integration`.

Integration test details, the temporary profile strategy, and cleanup behavior are in [docs/testing.md](docs/testing.md). The suite uses generated disposable DOCX, XLSX, and PDF files under `/tmp`; an optional blank PPTX can be passed to cover presentation editing. It never opens or changes an existing personal document.

## Security and licensing

The MCP server grants file access only to configured roots, rejects symlinks, caps document and result sizes, uses a private inherited debugging pipe rather than a TCP port, and exposes only static allowlisted API operations. It does not accept JavaScript expressions, raw CDP methods, or Electron IPC arguments from an MCP client. The private debugger still gives this local MCP process significant authority over its launched editor renderer; keep the server trusted, local, and configured with narrow roots.

This repository is MIT-licensed. ElixirOffice and the editor components are AGPL-3.0-only. This separate-process integration does not copy or modify upstream source, but distribution, bundling, or derivative changes can raise AGPL obligations; obtain qualified legal advice for a commercial distribution and preserve upstream notices. See [docs/architecture.md](docs/architecture.md#licensing).