dcc-mcp-excel 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. dcc_mcp_excel-0.1.1/.github/workflows/ci.yml +55 -0
  2. dcc_mcp_excel-0.1.1/.github/workflows/release.yml +97 -0
  3. dcc_mcp_excel-0.1.1/.gitignore +9 -0
  4. dcc_mcp_excel-0.1.1/.release-please-manifest.json +3 -0
  5. dcc_mcp_excel-0.1.1/AGENTS.md +72 -0
  6. dcc_mcp_excel-0.1.1/CHANGELOG.md +8 -0
  7. dcc_mcp_excel-0.1.1/LICENSE +21 -0
  8. dcc_mcp_excel-0.1.1/PKG-INFO +140 -0
  9. dcc_mcp_excel-0.1.1/README.md +105 -0
  10. dcc_mcp_excel-0.1.1/docs/README.md +6 -0
  11. dcc_mcp_excel-0.1.1/docs/adr/004-headless-xlsx-single-implementation.md +38 -0
  12. dcc_mcp_excel-0.1.1/docs/adr/005-capability-grading.md +39 -0
  13. dcc_mcp_excel-0.1.1/docs/adr/README.md +6 -0
  14. dcc_mcp_excel-0.1.1/examples/output/draft-production-report.xlsx +0 -0
  15. dcc_mcp_excel-0.1.1/examples/output/draft-shot-list.xlsx +0 -0
  16. dcc_mcp_excel-0.1.1/examples/shot_list.json +61 -0
  17. dcc_mcp_excel-0.1.1/install.md +78 -0
  18. dcc_mcp_excel-0.1.1/pyproject.toml +62 -0
  19. dcc_mcp_excel-0.1.1/release-please-config.json +15 -0
  20. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/__init__.py +45 -0
  21. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/_standalone_entry.py +117 -0
  22. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/capabilities.py +152 -0
  23. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/com_export.py +94 -0
  24. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/compiler.py +292 -0
  25. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/host_client.py +167 -0
  26. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/host_matrix.py +112 -0
  27. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/readback.py +247 -0
  28. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/server_launcher.py +88 -0
  29. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/sidecar/__init__.py +1 -0
  30. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-capabilities/SKILL.md +63 -0
  31. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-capabilities/scripts/capabilities.py +45 -0
  32. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-capabilities/scripts/preflight.py +38 -0
  33. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-capabilities/tools.yaml +39 -0
  34. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-workbook/SKILL.md +113 -0
  35. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-workbook/scripts/generate_workbook.py +103 -0
  36. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-workbook/scripts/inspect_workbook.py +101 -0
  37. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-workbook/scripts/validate_workbook.py +79 -0
  38. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/skills/excel-workbook/tools.yaml +82 -0
  39. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/validate.py +83 -0
  40. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/workbook_io.py +87 -0
  41. dcc_mcp_excel-0.1.1/src/dcc_mcp_excel/workbook_ir.py +493 -0
  42. dcc_mcp_excel-0.1.1/tests/conftest.py +28 -0
  43. dcc_mcp_excel-0.1.1/tests/test_compiler.py +445 -0
  44. dcc_mcp_excel-0.1.1/tests/test_e2e.py +96 -0
  45. dcc_mcp_excel-0.1.1/tests/test_host_client.py +77 -0
  46. dcc_mcp_excel-0.1.1/tests/test_host_matrix.py +52 -0
  47. dcc_mcp_excel-0.1.1/tests/test_readback.py +301 -0
  48. dcc_mcp_excel-0.1.1/tests/test_runtime_purity.py +57 -0
  49. dcc_mcp_excel-0.1.1/tests/test_skill_scripts.py +104 -0
  50. dcc_mcp_excel-0.1.1/tests/test_validate.py +115 -0
  51. dcc_mcp_excel-0.1.1/tests/test_version.py +45 -0
  52. dcc_mcp_excel-0.1.1/tests/test_workbook_ir.py +275 -0
@@ -0,0 +1,55 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ python:
13
+ # Headless by design: the xlsx compile + read-back gate must prove it does
14
+ # NOT depend on a desktop Excel installation, so it runs on Linux.
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version: ["3.9", "3.11", "3.12"]
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+ - name: Install
26
+ run: python -m pip install -e ".[dev]"
27
+ - name: Ruff
28
+ run: ruff check src tests
29
+ - name: Pytest
30
+ run: pytest -q
31
+
32
+ packaging:
33
+ # Windows-only: dcc-mcp-cli ships as a Windows binary through the
34
+ # dcc-mcp-core release train (not pip), and there is no Linux build to
35
+ # fall back on. The headless gate above already covers the Office-free
36
+ # path, so Windows here adds coverage rather than gating on it.
37
+ runs-on: windows-latest
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ - uses: actions/setup-python@v5
41
+ with:
42
+ python-version: "3.12"
43
+ - name: Install
44
+ run: python -m pip install -e ".[dev]"
45
+ - name: CLI smoke (version + preflight must work on a clean install)
46
+ shell: pwsh
47
+ run: |
48
+ python -m dcc_mcp_excel._standalone_entry --version
49
+ python -m dcc_mcp_excel._standalone_entry preflight
50
+ - name: Skill lint (official dcc-mcp-cli validator)
51
+ shell: pwsh
52
+ run: |
53
+ # dcc-mcp-cli ships through the dcc-mcp-core release train, not pip.
54
+ Invoke-WebRequest -Uri "https://github.com/dcc-mcp/dcc-mcp-core/releases/download/v0.20.6/dcc-mcp-cli-windows-x86_64.exe" -OutFile "$env:RUNNER_TEMP\dcc-mcp-cli.exe"
55
+ & "$env:RUNNER_TEMP\dcc-mcp-cli.exe" lint src/dcc_mcp_excel/skills --warnings-as-errors --non-interactive
@@ -0,0 +1,97 @@
1
+ name: Release
2
+
3
+ # Automated releases via release-please (conventional commits), mirroring
4
+ # dcc-mcp-office's release flow.
5
+ #
6
+ # Every push to main runs release-please, which keeps a release PR up to date.
7
+ # When that PR is merged, release-please creates the GitHub release and tag;
8
+ # this workflow publishes the wheel to PyPI from that exact tag after
9
+ # verifying the tag, the manifest and pyproject.toml agree on one version.
10
+ #
11
+ # No standalone binary job on purpose: dcc-mcp-excel is a headless,
12
+ # Office-free adapter (ADR 004) and ships the same wheel to every platform.
13
+ # The PyOxidizer bundle in dcc-mcp-powerpoint exists to carry the Windows-only
14
+ # C# COM host; nothing here needs it.
15
+
16
+ on:
17
+ push:
18
+ branches: [main]
19
+
20
+ permissions:
21
+ contents: write
22
+ pull-requests: write
23
+
24
+ jobs:
25
+ release-please:
26
+ runs-on: ubuntu-latest
27
+ outputs:
28
+ release_created: ${{ steps.release.outputs.release_created }}
29
+ tag_name: ${{ steps.release.outputs.tag_name }}
30
+ steps:
31
+ - uses: googleapis/release-please-action@v4
32
+ id: release
33
+ with:
34
+ # A PAT (user-owned) is required: PRs opened with the default
35
+ # GITHUB_TOKEN do not trigger pull_request workflows, so CI would
36
+ # never run on release PRs.
37
+ token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
38
+ config-file: release-please-config.json
39
+ manifest-file: .release-please-manifest.json
40
+
41
+ publish-pypi:
42
+ name: Publish to PyPI
43
+ runs-on: ubuntu-latest
44
+ needs: [release-please]
45
+ if: needs.release-please.outputs.release_created == 'true'
46
+ environment:
47
+ name: pypi
48
+ url: https://pypi.org/p/dcc-mcp-excel
49
+ permissions:
50
+ contents: read
51
+ id-token: write
52
+ env:
53
+ RELEASE_TAG: ${{ needs.release-please.outputs.tag_name }}
54
+ steps:
55
+ - uses: actions/checkout@v4
56
+ with:
57
+ ref: ${{ needs.release-please.outputs.tag_name }}
58
+ fetch-depth: 0
59
+ persist-credentials: false
60
+ - name: Verify release identity and version
61
+ env:
62
+ EXPECTED_VERSION: ${{ needs.release-please.outputs.tag_name }}
63
+ shell: bash
64
+ run: |
65
+ set -euo pipefail
66
+ [[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
67
+ echo "Release target must be a canonical vMAJOR.MINOR.PATCH tag." >&2
68
+ exit 1
69
+ }
70
+ export EXPECTED_VERSION="${RELEASE_TAG#v}"
71
+ python - <<'PY'
72
+ import json
73
+ import os
74
+ import re
75
+ from pathlib import Path
76
+
77
+ expected = os.environ["EXPECTED_VERSION"]
78
+ manifest = json.loads(Path(".release-please-manifest.json").read_text(encoding="utf-8"))["."]
79
+ source = Path("pyproject.toml").read_text(encoding="utf-8")
80
+ match = re.search(r'^version = "([0-9]+\.[0-9]+\.[0-9]+)"', source, re.MULTILINE)
81
+ if match is None or manifest != expected or match.group(1) != expected:
82
+ raise SystemExit("Checked-out package version does not match the release target.")
83
+ PY
84
+
85
+ - uses: actions/setup-python@v5
86
+ with:
87
+ python-version: "3.12"
88
+ - name: Build package
89
+ run: |
90
+ python -m pip install --upgrade pip build twine
91
+ python -m build
92
+ python -m twine check dist/*
93
+ - name: Publish to PyPI with trusted publishing
94
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
95
+ with:
96
+ verbose: true
97
+ print-hash: true
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ .ruff_cache/
5
+ .venv/
6
+ dist/
7
+ *.egg-info/
8
+ .idea/
9
+ .vscode/
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.1"
3
+ }
@@ -0,0 +1,72 @@
1
+ # AGENTS.md — dcc-mcp-excel
2
+
3
+ > Progressive disclosure: this file is a **map**, not an encyclopedia.
4
+
5
+ ## 30-Second Summary
6
+
7
+ `dcc-mcp-excel` is the **thin Excel adapter** over `dcc-mcp-office`. It owns
8
+ Excel application semantics only: workbook generation from structured data,
9
+ the headless XLSX compile + read-back path, capability grading and the
10
+ office-host launcher. Shared machinery (protocol, IR envelope, C# COM
11
+ runtime, jobs, security policy) comes from `dcc-mcp-office` + `dcc-mcp-core`.
12
+
13
+ **Current status:** v0.1.0 — headless path live. Workbook IR → Open XML
14
+ compile → read-back verification runs end to end with **no Excel
15
+ installation**, and the gate runs on a Linux runner in CI. Native
16
+ recalculation, chart/pivot rendering and PDF export are `host_limited`:
17
+ declared, graded, and never claimed as verified.
18
+
19
+ ## Repo Map
20
+
21
+ | Path | What it is |
22
+ |---|---|
23
+ | `src/dcc_mcp_excel/workbook_ir.py` | Workbook IR contract (mirrors dcc-mcp-office-ir) |
24
+ | `src/dcc_mcp_excel/workbook_io.py` | shared write/read helpers (titles, value comparison) |
25
+ | `src/dcc_mcp_excel/compiler.py` | headless Open XML compiler: Workbook IR → XLSX (openpyxl) |
26
+ | `src/dcc_mcp_excel/readback.py` | write-then-read-back verification (the 1.0 gate) |
27
+ | `src/dcc_mcp_excel/capabilities.py` | verified / host_limited / unimplemented grading |
28
+ | `src/dcc_mcp_excel/host_matrix.py` | host matrix + preflight self-check |
29
+ | `src/dcc_mcp_excel/com_export.py` | desktop COM PDF export (pywin32, Windows only) |
30
+ | `src/dcc_mcp_excel/host_client.py` | stdlib-only JSON-RPC client for the shared office host |
31
+ | `src/dcc_mcp_excel/server_launcher.py` | registers the bundled skills with `dcc-mcp-server` |
32
+ | `src/dcc_mcp_excel/skills/excel-workbook/` | SKILL.md + tools.yaml + scripts (generate/validate/inspect) |
33
+ | `src/dcc_mcp_excel/skills/excel-capabilities/` | capability report + preflight scripts |
34
+ | `examples/` | shot-list Workbook IR + generated XLSX |
35
+ | `tests/` | pytest (headless; COM only via subprocess boundary) |
36
+ | `docs/adr/` | adapter-level decisions |
37
+
38
+ ## Upstream Dependencies
39
+
40
+ - `dcc-mcp-core` (pip) — gateway, skills runtime, sidecar lifecycle.
41
+ - `dcc-mcp-office` — Rust crates (`dcc-mcp-office-protocol`,
42
+ `dcc-mcp-office-ir`, `dcc-mcp-office-tools`) + the `office-host` runtime.
43
+
44
+ ## Capabilities owned here
45
+
46
+ - `workbook.compile` — Workbook IR → XLSX (headless) → read-back verification.
47
+ - `workbook.read_back` — reopen the artifact and compare every cell.
48
+ - `excel.workbook.calculate` / `excel.chart.generate` / `excel.pivot.refresh`
49
+ — `host_limited` in v0.1.0 (COM backend not wired).
50
+ - Graph Workbook sessions (proposal §6.3) — out of scope; needs Azure app
51
+ registration and tenant consent.
52
+
53
+ ## Dependency policy
54
+
55
+ - **Package import is stdlib-only.** openpyxl and pywin32 are **opt-in**:
56
+ `compiler` / `readback` import openpyxl inside the module, `com_export`
57
+ imports pywin32 inside the function body. A test pins this
58
+ (`tests/test_runtime_purity.py`).
59
+ - One xlsx implementation only (ADR 004): no second writer inside the
60
+ adapter, even as a fallback. A missing shared host is reported, not worked
61
+ around.
62
+
63
+ ## Test
64
+
65
+ ```bash
66
+ pip install -e ".[dev]"
67
+ pytest
68
+ ruff check src tests
69
+ ```
70
+
71
+ The headless gate must stay green on **Linux** — that is the proof the
72
+ adapter does not depend on a desktop Excel installation.
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## [0.1.1](https://github.com/dcc-mcp/dcc-mcp-excel/compare/v0.1.0...v0.1.1) (2026-10-09)
4
+
5
+
6
+ ### Features
7
+
8
+ * headless Workbook IR to XLSX adapter with read-back verification ([e83fe29](https://github.com/dcc-mcp/dcc-mcp-excel/commit/e83fe29f5baa70ba09b549b2b751ea4657d2d09d))
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.5
2
+ Name: dcc-mcp-excel
3
+ Version: 0.1.1
4
+ Summary: Excel adapter for the DCC-MCP ecosystem — headless Workbook IR to XLSX compile with read-back verification over the dcc-mcp-office runtime
5
+ Project-URL: Homepage, https://github.com/dcc-mcp/dcc-mcp-excel
6
+ Author-email: Long Hao <hal.long@outlook.com>
7
+ License: MIT
8
+ License-File: LICENSE
9
+ Keywords: ai,dcc,excel,llm,mcp,model-context-protocol,office,xlsx
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: dcc-mcp-core<1.0.0,>=0.18.2
22
+ Provides-Extra: dev
23
+ Requires-Dist: build; extra == 'dev'
24
+ Requires-Dist: hatchling; extra == 'dev'
25
+ Requires-Dist: openpyxl>=3.1; extra == 'dev'
26
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
27
+ Requires-Dist: pytest>=7.0; extra == 'dev'
28
+ Requires-Dist: pywin32>=306; (sys_platform == 'win32') and extra == 'dev'
29
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
30
+ Provides-Extra: headless
31
+ Requires-Dist: openpyxl>=3.1; extra == 'headless'
32
+ Provides-Extra: sidecar
33
+ Requires-Dist: dcc-mcp-server>=0.17.43; extra == 'sidecar'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # dcc-mcp-excel
37
+
38
+ Excel adapter for the DCC-MCP ecosystem — the **thin application layer** over
39
+ [dcc-mcp-office](https://github.com/dcc-mcp/dcc-mcp-office): structured
40
+ workbook generation from production data, headless XLSX compilation and
41
+ read-back verification.
42
+
43
+ **Status: v0.1.0 — headless path live.** The compile pipeline runs end to end
44
+ without Excel installed: Workbook IR (`office-ir/1.0`) → headless Open XML
45
+ compile (openpyxl) → write-then-read-back verification → structural report.
46
+ Skill scripts execute through the dcc-mcp gateway.
47
+
48
+ Two grades of capability, and the difference is evidence:
49
+
50
+ | Grade | What it means | Examples |
51
+ |---|---|---|
52
+ | `verified` | CI-green on a Linux runner, no Office installed | workbook compile, read-back, grid/formula/named-range/validation/conditional-format writes |
53
+ | `host_limited` | Requires desktop Excel (COM); the artifact is valid but the value only materializes when Excel opens it | native recalculation, chart and pivot rendering, PDF export |
54
+
55
+ Run `dcc-mcp-excel capabilities` (or the `excel-capabilities` skill) for the
56
+ full graded list.
57
+
58
+ <!-- dcc-mcp-coverage-pointer:start -->
59
+ <!-- Generated from dcc-mcp-catalog.yml by scripts/generate_adapter_pointer.py in dcc-mcp/dcc-mcp-core. Do not edit by hand. -->
60
+ ## Part of the DCC-MCP host matrix
61
+
62
+ **dcc-mcp-excel** — Excel adapter for DCC-MCP — headless Workbook IR to XLSX compile
63
+ with read-back verification over the dcc-mcp-office runtime.
64
+
65
+ It is one of **39 host adapters** in the DCC-MCP catalog. Every adapter speaks the same
66
+ MCP protocol and builds on the same core runtime contract; each one exposes the tools
67
+ its own host needs on top of that.
68
+
69
+ - [All host adapters and install metadata](https://dcc-mcp.github.io/ecosystem)
70
+ - [Host matrix on the core README](https://github.com/dcc-mcp/dcc-mcp-core#readme)
71
+ - [Showcase](https://dcc-mcp.github.io/showcase)
72
+
73
+ This block is generated from the catalog entry in
74
+ [`dcc-mcp-catalog.yml`](https://github.com/dcc-mcp/dcc-mcp-core/blob/main/dcc-mcp-catalog.yml).
75
+ Re-run the generator after changing the catalog.
76
+ <!-- dcc-mcp-coverage-pointer:end -->
77
+
78
+ ## Why headless first
79
+
80
+ The `dcc-mcp-office` shared core already ships a CI-green headless xlsx
81
+ writer (`skills/office-generate-production-dashboard`). Building the adapter
82
+ on that path means the 1.0 gate — host matrix, preflight self-check,
83
+ write-then-read-back — is verifiable in CI on a plain Linux runner instead of
84
+ depending on a licensed desktop Office install.
85
+
86
+ Desktop Excel stays the path for the things only Excel can do: evaluate a
87
+ formula, render a chart, refresh a pivot, paginate a PDF. Those are declared
88
+ and graded `host_limited`, never claimed as verified.
89
+
90
+ ## Install
91
+
92
+ ```bash
93
+ pip install "dcc-mcp-excel"
94
+ # headless compilation needs the openpyxl extra:
95
+ pip install "dcc-mcp-excel[headless]"
96
+ ```
97
+
98
+ See [install.md](./install.md) for the verified live route.
99
+
100
+ ## Skill packs
101
+
102
+ - `excel-workbook` — compile a Workbook IR into an editable XLSX, then reopen
103
+ it and verify every cell against the source IR; validate an IR; inventory an
104
+ existing workbook.
105
+ - `excel-capabilities` — the graded capability report plus the host matrix and
106
+ the start-up preflight self-check.
107
+
108
+ ## Agent usage (via dcc-mcp-cli / gateway)
109
+
110
+ 1. Start the registered adapter (the launcher binds the bundled skill packs
111
+ and script runtime to the official `dcc-mcp-server`):
112
+ `dcc-mcp-excel serve`
113
+ 2. Run a skill script directly (gateway `execute_script` contract —
114
+ stdin JSON or CLI flags):
115
+ ```bash
116
+ python src/dcc_mcp_excel/skills/excel-workbook/scripts/generate_workbook.py \
117
+ --input examples/shot_list.json --out out
118
+ ```
119
+ 3. Validate the packs with the official linter:
120
+ ```bash
121
+ dcc-mcp-cli lint src/dcc_mcp_excel/skills --warnings-as-errors --non-interactive
122
+ ```
123
+
124
+ ## From production tracking to a spreadsheet
125
+
126
+ `dcc-mcp-fpt` reads Flow Production Tracking; this adapter turns what it
127
+ returns into something you can send. `tests/test_e2e.py` pins that chain with
128
+ a real `find_entities` payload: entities → Workbook IR → XLSX → read-back.
129
+
130
+ ## Development
131
+
132
+ ```bash
133
+ pip install -e ".[dev]"
134
+ pytest
135
+ ruff check src tests
136
+ ```
137
+
138
+ ## License
139
+
140
+ MIT
@@ -0,0 +1,105 @@
1
+ # dcc-mcp-excel
2
+
3
+ Excel adapter for the DCC-MCP ecosystem — the **thin application layer** over
4
+ [dcc-mcp-office](https://github.com/dcc-mcp/dcc-mcp-office): structured
5
+ workbook generation from production data, headless XLSX compilation and
6
+ read-back verification.
7
+
8
+ **Status: v0.1.0 — headless path live.** The compile pipeline runs end to end
9
+ without Excel installed: Workbook IR (`office-ir/1.0`) → headless Open XML
10
+ compile (openpyxl) → write-then-read-back verification → structural report.
11
+ Skill scripts execute through the dcc-mcp gateway.
12
+
13
+ Two grades of capability, and the difference is evidence:
14
+
15
+ | Grade | What it means | Examples |
16
+ |---|---|---|
17
+ | `verified` | CI-green on a Linux runner, no Office installed | workbook compile, read-back, grid/formula/named-range/validation/conditional-format writes |
18
+ | `host_limited` | Requires desktop Excel (COM); the artifact is valid but the value only materializes when Excel opens it | native recalculation, chart and pivot rendering, PDF export |
19
+
20
+ Run `dcc-mcp-excel capabilities` (or the `excel-capabilities` skill) for the
21
+ full graded list.
22
+
23
+ <!-- dcc-mcp-coverage-pointer:start -->
24
+ <!-- Generated from dcc-mcp-catalog.yml by scripts/generate_adapter_pointer.py in dcc-mcp/dcc-mcp-core. Do not edit by hand. -->
25
+ ## Part of the DCC-MCP host matrix
26
+
27
+ **dcc-mcp-excel** — Excel adapter for DCC-MCP — headless Workbook IR to XLSX compile
28
+ with read-back verification over the dcc-mcp-office runtime.
29
+
30
+ It is one of **39 host adapters** in the DCC-MCP catalog. Every adapter speaks the same
31
+ MCP protocol and builds on the same core runtime contract; each one exposes the tools
32
+ its own host needs on top of that.
33
+
34
+ - [All host adapters and install metadata](https://dcc-mcp.github.io/ecosystem)
35
+ - [Host matrix on the core README](https://github.com/dcc-mcp/dcc-mcp-core#readme)
36
+ - [Showcase](https://dcc-mcp.github.io/showcase)
37
+
38
+ This block is generated from the catalog entry in
39
+ [`dcc-mcp-catalog.yml`](https://github.com/dcc-mcp/dcc-mcp-core/blob/main/dcc-mcp-catalog.yml).
40
+ Re-run the generator after changing the catalog.
41
+ <!-- dcc-mcp-coverage-pointer:end -->
42
+
43
+ ## Why headless first
44
+
45
+ The `dcc-mcp-office` shared core already ships a CI-green headless xlsx
46
+ writer (`skills/office-generate-production-dashboard`). Building the adapter
47
+ on that path means the 1.0 gate — host matrix, preflight self-check,
48
+ write-then-read-back — is verifiable in CI on a plain Linux runner instead of
49
+ depending on a licensed desktop Office install.
50
+
51
+ Desktop Excel stays the path for the things only Excel can do: evaluate a
52
+ formula, render a chart, refresh a pivot, paginate a PDF. Those are declared
53
+ and graded `host_limited`, never claimed as verified.
54
+
55
+ ## Install
56
+
57
+ ```bash
58
+ pip install "dcc-mcp-excel"
59
+ # headless compilation needs the openpyxl extra:
60
+ pip install "dcc-mcp-excel[headless]"
61
+ ```
62
+
63
+ See [install.md](./install.md) for the verified live route.
64
+
65
+ ## Skill packs
66
+
67
+ - `excel-workbook` — compile a Workbook IR into an editable XLSX, then reopen
68
+ it and verify every cell against the source IR; validate an IR; inventory an
69
+ existing workbook.
70
+ - `excel-capabilities` — the graded capability report plus the host matrix and
71
+ the start-up preflight self-check.
72
+
73
+ ## Agent usage (via dcc-mcp-cli / gateway)
74
+
75
+ 1. Start the registered adapter (the launcher binds the bundled skill packs
76
+ and script runtime to the official `dcc-mcp-server`):
77
+ `dcc-mcp-excel serve`
78
+ 2. Run a skill script directly (gateway `execute_script` contract —
79
+ stdin JSON or CLI flags):
80
+ ```bash
81
+ python src/dcc_mcp_excel/skills/excel-workbook/scripts/generate_workbook.py \
82
+ --input examples/shot_list.json --out out
83
+ ```
84
+ 3. Validate the packs with the official linter:
85
+ ```bash
86
+ dcc-mcp-cli lint src/dcc_mcp_excel/skills --warnings-as-errors --non-interactive
87
+ ```
88
+
89
+ ## From production tracking to a spreadsheet
90
+
91
+ `dcc-mcp-fpt` reads Flow Production Tracking; this adapter turns what it
92
+ returns into something you can send. `tests/test_e2e.py` pins that chain with
93
+ a real `find_entities` payload: entities → Workbook IR → XLSX → read-back.
94
+
95
+ ## Development
96
+
97
+ ```bash
98
+ pip install -e ".[dev]"
99
+ pytest
100
+ ruff check src tests
101
+ ```
102
+
103
+ ## License
104
+
105
+ MIT
@@ -0,0 +1,6 @@
1
+ # docs
2
+
3
+ - `adr/` — adapter-level architecture decisions (single headless
4
+ implementation, capability grading)
5
+ - the platform proposal itself lives in
6
+ `dcc-mcp-office/docs/proposals/office-automation-platform-v1.0.md`
@@ -0,0 +1,38 @@
1
+ # ADR 004 — 无头 xlsx 只保留一份实现,落在共享核心
2
+
3
+ - **Status**: Accepted
4
+ - **Date**: 2026-10-06
5
+ - **Related**: dcc-mcp-office ADR-006, PIP-4281, PIP-4276
6
+
7
+ ## Context
8
+
9
+ `dcc-mcp-office` v0.2.3 已经有一条 CI 绿的无头 xlsx 路径
10
+ (`skills/office-generate-production-dashboard/scripts/generate_dashboard.py`,
11
+ Python + openpyxl,在 ubuntu-latest 上跑通)。adapter 侧需要同样的能力。
12
+
13
+ 薄适配层是生态约定:adapter 只带应用语义,重型实现留在共享核心。如果在
14
+ adapter 内再起一套 openpyxl writer,短期更快,长期必然语义漂移 —— 两套
15
+ 实现对同一个 Workbook IR 的边界处理(ragged rows、sheet 名长度、公式
16
+ 求值语义)迟早分叉,而 ADR 006 已明确「keeping exactly one COM
17
+ implementation」。
18
+
19
+ ## Decision
20
+
21
+ 1. **无头 xlsx writer 只有一个**:位于 `dcc-mcp-office`(共享核心或其
22
+ `skills/`)。adapter 通过一个薄的 `host_client` 调它,不在仓内另起一套。
23
+ 2. **adapter 内不实现 fallback**。共享 host 缺失时 `rpc()` 返回
24
+ `OFFICE_HOST_NOT_FOUND` 并带上修复提示,绝不静默回退到本地 writer。
25
+ 3. **本次过渡期**:`compiler.py` 直接调 openpyxl,结构与共享核心的
26
+ dashboard 脚本对齐(同样的 `office-ir/1.0` envelope、同样的 A1 寻址)。
27
+ 共享核心 `workbook.compile` capability 落地后,`compiler.py` 换成一次
28
+ `office.command.execute` RPC —— 调用面不变,实现位置变。
29
+ 4. **能力分级写进契约**:无头可验证的标 `verified`,只有 Excel 能做
30
+ (recalc / chart / pivot / PDF)标 `host_limited`,永不冒充 verified。
31
+
32
+ ## Consequences
33
+
34
+ - 只有一份实现,语义漂移面消失。
35
+ - CI 可以在 Linux runner 上验证 1.0 门禁(写后回读),不依赖 Office 授权。
36
+ - 共享 host 未就绪时 adapter 的降级是显式的、可诊断的,不是静默的。
37
+ - 过渡期 `compiler.py` 与共享脚本存在一段代码相似期;切换点被
38
+ `host_client.compile_workbook()` 签名固定,切换只需替换函数体。
@@ -0,0 +1,39 @@
1
+ # ADR 005 — 能力分级写进代码,不是写进文档
2
+
3
+ - **Status**: Accepted
4
+ - **Date**: 2026-10-06
5
+ - **Related**: PIP-4276, PIP-4281
6
+
7
+ ## Context
8
+
9
+ Excel 有一批能力只有装了 Excel 才成立:原生公式重算、图表渲染、数据透视
10
+ 刷新、分页 PDF 导出。无头 Open XML 路径写得出结构,但写不出这些值。
11
+
12
+ 如果在文档里「说明」而代码里不区分,会出现两类失败:
13
+
14
+ 1. agent 读 README 后向用户承诺「表里已经有算好的数」,实际是公式文本;
15
+ 2. 后续维护者把 `host_limited` 能力当成已验证能力继续往上搭。
16
+
17
+ `dcc-mcp-powerpoint` 的 `render_deck` 已有先例:Office 不可用时返回显式
18
+ reason,绝不产出假产物。
19
+
20
+ ## Decision
21
+
22
+ 1. **`capabilities.py` 是唯一分级来源**:每条能力带
23
+ `grade` / `summary` / `evidence` / `requires_office`,`verified` 与
24
+ `host_limited` 两集合不重叠(有测试钉住)。
25
+ 2. **分级可被机器读取**:`dcc-mcp-excel capabilities` 与
26
+ `excel-capabilities` skill 输出同一份 `dcc-mcp-capability-grade/1` JSON。
27
+ 3. **`host_limited` 能力在校验里报 warning,不报 passing check**。
28
+ `validate_envelope` 遇到 IR 里的 chart / pivot 只声明「已声明、未验证」,
29
+ 不生成一条名为 chart 的绿色检查 —— 测试钉住这一点。
30
+ 4. **缺失的 desktop Excel 是报告不是失败**:`preflight()` 的 `ok` 只反映
31
+ 无头后端,Linux runner 上不算挂。
32
+ 5. **`unimplemented` 单独一档**,用于 Graph Workbook 会话这类「评估过、
33
+ 明确不做」的能力,避免与「还没做」混淆。
34
+
35
+ ## Consequences
36
+
37
+ - agent 在承诺 Excel 能力前可以先查分级,而不是猜。
38
+ - 把 `host_limited` 冒充 `verified` 会直接测试失败。
39
+ - 新增能力必须带 evidence 字段(有测试钉住),分级无法退化成装饰。
@@ -0,0 +1,6 @@
1
+ # Architecture Decision Records
2
+
3
+ | ADR | Title | Status |
4
+ |---|---|---|
5
+ | [004](004-headless-xlsx-single-implementation.md) | 无头 xlsx 只保留一份实现,落在共享核心 | Accepted |
6
+ | [005](005-capability-grading.md) | 能力分级写进代码,不是写进文档 | Accepted |