Metadata-Version: 2.4
Name: excel-tools-mcp
Version: 0.1.0
Summary: A standalone MCP server for inspecting and editing Excel .xlsx files.
Author: wasziyang
License-Expression: MIT
Keywords: excel,xlsx,mcp,model-context-protocol
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: mcp>=1.27.0
Requires-Dist: openpyxl>=3.1.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.0

# Excel Tools MCP

A standalone MCP server for inspecting and editing `.xlsx` files.

## Tools

- `excel_inspect`: inspect workbook metadata and sheet dimensions.
- `excel_read_range`: read a rectangular cell range.
- `excel_profile_structure`: summarize row structure patterns.
- `excel_unmerge_cells`: unmerge intersecting merged cells and optionally fill values.

Only local file paths are supported. The old `fileId` server-side download flow has been removed.

## Run With npx

MCP client config:

```json
{
  "mcpServers": {
    "excel-tools-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["--yes", "@wasziyang/excel-tools-mcp"]
    }
  }
}
```

The npm package is a launcher. On first run it creates a Python virtual environment under
the user's cache directory, installs the bundled Python MCP server, and starts it over stdio.

Requirements:

- Node.js 20+
- Python 3.10+

Test from a terminal:

```bash
npx --yes @wasziyang/excel-tools-mcp
```

The command may appear to do nothing. That is normal for an MCP stdio server: it waits for the MCP
host to send JSON-RPC messages over stdin.

### Custom Python Path

By default, the launcher searches for `python3`, then `python`.

Only set `EXCEL_TOOLS_MCP_PYTHON` when Python is installed somewhere unusual. Do not copy
`/path/to/python` literally.

```json
{
  "mcpServers": {
    "excel-tools-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["--yes", "@wasziyang/excel-tools-mcp"],
      "env": {
        "EXCEL_TOOLS_MCP_PYTHON": "/absolute/path/to/python"
      }
    }
  }
}
```

Examples:

```bash
EXCEL_TOOLS_MCP_PYTHON=/usr/bin/python3 npx --yes @wasziyang/excel-tools-mcp
```

```powershell
$env:EXCEL_TOOLS_MCP_PYTHON = "C:\Users\Alice\AppData\Local\Programs\Python\Python312\python.exe"
npx --yes @wasziyang/excel-tools-mcp
```

### Windows, WSL, and VS Code

If your `mcp.json` lives under a Windows path such as:

```text
C:\Users\<you>\AppData\Roaming\Code\User\mcp.json
```

VS Code usually starts the MCP server from Windows, not from WSL. In that case Windows must have
Node.js and Python installed, and Excel file paths should be Windows paths:

```json
{
  "mcpServers": {
    "excel-tools-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["--yes", "@wasziyang/excel-tools-mcp"]
    }
  }
}
```

Example tool argument:

```json
{
  "file_path": "C:\\Users\\Alice\\Documents\\report.xlsx",
  "sheet": "Sheet1",
  "start_cell": "A1",
  "end_cell": "D20"
}
```

If you want VS Code on Windows to run the server inside WSL, call `wsl` explicitly:

```json
{
  "mcpServers": {
    "excel-tools-mcp": {
      "type": "stdio",
      "command": "wsl",
      "args": [
        "bash",
        "-lc",
        "npx --yes @wasziyang/excel-tools-mcp"
      ]
    }
  }
}
```

When the server runs in WSL, use Linux/WSL paths:

```json
{
  "file_path": "/mnt/c/Users/Alice/Documents/report.xlsx",
  "sheet": "Sheet1",
  "start_cell": "A1",
  "end_cell": "D20"
}
```

Avoid setting `cwd` until the minimal config works. If you do set it, make sure it is valid in the
same environment that runs the server.

## Run With uvx

This project can also be distributed as a Python package on PyPI. After it is published to PyPI,
users who have `uv` installed can run it with `uvx`:

```json
{
  "mcpServers": {
    "excel-tools-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from",
        "excel-tools-mcp",
        "excel-tools-mcp"
      ]
    }
  }
}
```

Terminal test:

```bash
uvx --from excel-tools-mcp excel-tools-mcp
```

`uvx` downloads the package from PyPI, creates an isolated cached environment, and runs the
`excel-tools-mcp` console command declared in `pyproject.toml`.

Requirements:

- `uv`
- Python compatible with this package, currently Python 3.10+

The npm and uvx routes are equivalent at runtime: both eventually start the same Python MCP server.
The difference is only the distribution layer:

```text
npx -> npm package -> Node launcher -> Python MCP server
uvx -> PyPI package -> Python MCP server
```

## Run With Docker

Build locally:

```bash
docker build -t excel-tools-mcp .
```

MCP client config example:

```json
{
  "command": "docker",
  "args": [
    "run",
    "-i",
    "--rm",
    "-v",
    "/absolute/path/to/excel/files:/workspace",
    "excel-tools-mcp"
  ]
}
```

Inside Docker, pass file paths under `/workspace`, for example `/workspace/report.xlsx`.

Docker images are not published yet. The npm launcher is the recommended installation path for now.

## Run As Python

```bash
pip install .
excel-tools-mcp
```

Or:

```bash
python3 -m excel_tools.server
```

## Publishing To npm

To make `npx --yes @wasziyang/excel-tools-mcp` work for other users, the package name must exist on the npm registry.

Basic flow for this scoped public package:

```bash
npm login
npm publish --access public
```

Before publishing, check the current registry state:

```bash
npm view @wasziyang/excel-tools-mcp
```

If npm returns package metadata, the package already exists. If npm returns `404`, publish it with
`npm publish --access public`.

Publishing a new version requires a new semver value. npm does not allow overwriting an already
published version:

```bash
npm version patch
npm publish --access public
```

Users who do not specify a version get the npm `latest` dist-tag:

```bash
npx --yes @wasziyang/excel-tools-mcp
```

That normally resolves to the newest published version tagged as `latest`.

## Publishing To PyPI

Publish to PyPI if you want users to run:

```bash
uvx --from excel-tools-mcp excel-tools-mcp
```

Build and upload:

```bash
python3 -m pip install --upgrade build twine
python3 -m build
python3 -m twine upload dist/*
```

PyPI also does not allow overwriting an already published version. Before uploading a new release,
update the version in `pyproject.toml`, for example:

```toml
version = "0.1.1"
```

If you publish both npm and PyPI packages, keep `package.json` and `pyproject.toml` versions aligned
unless you intentionally release one distribution channel ahead of the other.

### Docker Cache Pre-Warm

If a Docker image uses `uvx` to launch the PyPI package, you can pre-warm the uv cache at image build
time so the container starts faster:

```dockerfile
RUN uvx --from excel-tools-mcp excel-tools-mcp --help >/dev/null 2>&1 || true
```

That command downloads and installs the PyPI package into uv's cache during `docker build`. The
`|| true` keeps the build from failing if the command exits after printing help.
