excel-mcp-server 2.2.3__tar.gz → 2.2.4__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 (228) hide show
  1. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/PKG-INFO +1 -1
  2. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/pyproject.toml +1 -1
  3. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/pyproject.toml.orig +1 -1
  4. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/slicer_place.py +3 -1
  5. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sparklines.py +2 -4
  6. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/extensions.py +15 -4
  7. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/patch.py +36 -9
  8. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/references.py +5 -2
  9. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/LICENSE +0 -0
  10. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/README.md +0 -0
  11. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/__init__.py +0 -0
  12. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/__main__.py +0 -0
  13. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/cells.py +0 -0
  14. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/criteria.py +0 -0
  15. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/dependencies.py +0 -0
  16. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/dynamic.py +0 -0
  17. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/engine.py +0 -0
  18. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/__init__.py +0 -0
  19. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/arrays.py +0 -0
  20. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/conditional.py +0 -0
  21. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/datetime.py +0 -0
  22. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/depreciation.py +0 -0
  23. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/distributions.py +0 -0
  24. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/financial.py +0 -0
  25. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/helpers.py +0 -0
  26. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/indirect.py +0 -0
  27. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/information.py +0 -0
  28. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/logical.py +0 -0
  29. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/lookup.py +0 -0
  30. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/math.py +0 -0
  31. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/regression.py +0 -0
  32. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/securities.py +0 -0
  33. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/statistical.py +0 -0
  34. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/subtotals.py +0 -0
  35. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/functions/text.py +0 -0
  36. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/operators.py +0 -0
  37. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/parser.py +0 -0
  38. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/r1c1.py +0 -0
  39. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/registry.py +0 -0
  40. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/scheduler.py +0 -0
  41. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/solver.py +0 -0
  42. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/steps.py +0 -0
  43. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/tablerefs.py +0 -0
  44. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/textformat.py +0 -0
  45. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/values.py +0 -0
  46. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/calc/wildcard.py +0 -0
  47. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/cell_budget.py +0 -0
  48. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/cfb.py +0 -0
  49. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/chart_roundtrip.py +0 -0
  50. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/cli.py +0 -0
  51. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/config.py +0 -0
  52. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/errors.py +0 -0
  53. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/formula_syntax.py +0 -0
  54. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/formulas.py +0 -0
  55. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/function_arguments.json +0 -0
  56. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/inputs.py +0 -0
  57. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/lazy_edit.py +0 -0
  58. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/lazy_find.py +0 -0
  59. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/lazy_lines.py +0 -0
  60. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/lazy_rows.py +0 -0
  61. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/lazy_shared.py +0 -0
  62. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/lazy_source.py +0 -0
  63. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/lazy_workbook.py +0 -0
  64. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/links.py +0 -0
  65. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/macros.py +0 -0
  66. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/__init__.py +0 -0
  67. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/calculated.py +0 -0
  68. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/cells.py +0 -0
  69. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chart_index.py +0 -0
  70. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chart_info.py +0 -0
  71. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex.py +0 -0
  72. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_parts/box_whisker_style.xml +0 -0
  73. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_parts/colors.xml +0 -0
  74. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_parts/funnel_style.xml +0 -0
  75. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_parts/histogram_style.xml +0 -0
  76. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_parts/sunburst_style.xml +0 -0
  77. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_parts/treemap_style.xml +0 -0
  78. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_parts/waterfall_style.xml +0 -0
  79. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/chartex_xml.py +0 -0
  80. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts.py +0 -0
  81. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_axes.py +0 -0
  82. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_check.py +0 -0
  83. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_data.py +0 -0
  84. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_look.py +0 -0
  85. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_modern.py +0 -0
  86. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_options.py +0 -0
  87. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_series.py +0 -0
  88. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/charts_style.py +0 -0
  89. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/columns.py +0 -0
  90. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/comparison.py +0 -0
  91. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/conditional.py +0 -0
  92. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/conditional_kinds.py +0 -0
  93. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/conditional_rule.py +0 -0
  94. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/conditional_x14.py +0 -0
  95. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/csv_export.py +0 -0
  96. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/csv_format.py +0 -0
  97. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/csv_import.py +0 -0
  98. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/csv_values.py +0 -0
  99. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/date_width.py +0 -0
  100. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/drawings.py +0 -0
  101. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/duplicates.py +0 -0
  102. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/files.py +0 -0
  103. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/fill.py +0 -0
  104. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/filter_criteria.py +0 -0
  105. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/filter_stored.py +0 -0
  106. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/filters.py +0 -0
  107. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/formatting.py +0 -0
  108. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/goal_seek.py +0 -0
  109. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/hyperlinks.py +0 -0
  110. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/images.py +0 -0
  111. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/inspect.py +0 -0
  112. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/layout.py +0 -0
  113. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/line_edit_objects.py +0 -0
  114. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/line_edit_rules.py +0 -0
  115. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/line_edit_styles.py +0 -0
  116. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/line_edits.py +0 -0
  117. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/names.py +0 -0
  118. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/notes.py +0 -0
  119. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/paste.py +0 -0
  120. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot.py +0 -0
  121. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_axis.py +0 -0
  122. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_cache.py +0 -0
  123. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_calc.py +0 -0
  124. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_definition.py +0 -0
  125. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_fields.py +0 -0
  126. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_groups.py +0 -0
  127. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_index.py +0 -0
  128. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_options.py +0 -0
  129. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_rebuild.py +0 -0
  130. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_records.py +0 -0
  131. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_render.py +0 -0
  132. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_showas.py +0 -0
  133. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_source.py +0 -0
  134. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_specs.py +0 -0
  135. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/pivot_values.py +0 -0
  136. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/print_setup.py +0 -0
  137. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/protection.py +0 -0
  138. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/replace.py +0 -0
  139. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/rule_clear.py +0 -0
  140. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/rules.py +0 -0
  141. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sheet_copy.py +0 -0
  142. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sheet_counts.py +0 -0
  143. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sheet_refs.py +0 -0
  144. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sheet_shapes.py +0 -0
  145. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sheet_view.py +0 -0
  146. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sheets.py +0 -0
  147. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/shifting.py +0 -0
  148. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/slicer_index.py +0 -0
  149. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/slicer_manage.py +0 -0
  150. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/slicer_pivot.py +0 -0
  151. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/slicer_table.py +0 -0
  152. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/slicer_xml.py +0 -0
  153. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/slicers.py +0 -0
  154. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sorting.py +0 -0
  155. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/spans.py +0 -0
  156. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sparkline_style.py +0 -0
  157. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/sparkline_xml.py +0 -0
  158. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/spill.py +0 -0
  159. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/table_options.py +0 -0
  160. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/tables.py +0 -0
  161. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/text_split.py +0 -0
  162. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/trace.py +0 -0
  163. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/transform.py +0 -0
  164. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/used_range.py +0 -0
  165. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/vba.py +0 -0
  166. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/vba_write.py +0 -0
  167. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/workbook_rewrite.py +0 -0
  168. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/workbook_settings.py +0 -0
  169. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/operations/x14_xml.py +0 -0
  170. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/ovba.py +0 -0
  171. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/ovba_compress.py +0 -0
  172. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/ovba_write.py +0 -0
  173. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/__init__.py +0 -0
  174. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/anchors.py +0 -0
  175. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/arrays.py +0 -0
  176. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/capture.py +0 -0
  177. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/capture_sheet.py +0 -0
  178. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/consistency.py +0 -0
  179. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/guards.py +0 -0
  180. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/lazy_records.py +0 -0
  181. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/lines.py +0 -0
  182. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/metadata.py +0 -0
  183. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/model.py +0 -0
  184. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/opc.py +0 -0
  185. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/pivot_records.py +0 -0
  186. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/pivots.py +0 -0
  187. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/properties.py +0 -0
  188. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/reader.py +0 -0
  189. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/restore.py +0 -0
  190. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/restore_sheet.py +0 -0
  191. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/scan.py +0 -0
  192. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/shape_names.py +0 -0
  193. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/package/vml.py +0 -0
  194. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/paths.py +0 -0
  195. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/plain_refs.py +0 -0
  196. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/py.typed +0 -0
  197. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/refs.py +0 -0
  198. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/rewrite.py +0 -0
  199. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/__init__.py +0 -0
  200. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/annotation_tools.py +0 -0
  201. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/areas.py +0 -0
  202. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/csv_tools.py +0 -0
  203. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/data_tools.py +0 -0
  204. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/format_tools.py +0 -0
  205. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/formula_tools.py +0 -0
  206. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/http.py +0 -0
  207. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/image_tools.py +0 -0
  208. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/object_tools.py +0 -0
  209. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/params.py +0 -0
  210. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/pivot_tools.py +0 -0
  211. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/registry.py +0 -0
  212. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/results.py +0 -0
  213. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/sheet_tools.py +0 -0
  214. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/slicer_tools.py +0 -0
  215. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/validation.py +0 -0
  216. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/vba_tools.py +0 -0
  217. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/vba_write_tools.py +0 -0
  218. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/server/workbook_tools.py +0 -0
  219. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/spill.py +0 -0
  220. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/structured.py +0 -0
  221. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/text.py +0 -0
  222. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/upload_links.py +0 -0
  223. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/upload_scan.py +0 -0
  224. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/values.py +0 -0
  225. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/workspace.py +0 -0
  226. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/xlfn.py +0 -0
  227. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/xlm.py +0 -0
  228. {excel_mcp_server-2.2.3 → excel_mcp_server-2.2.4}/src/excel_mcp/zip_limits.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: excel-mcp-server
3
- Version: 2.2.3
3
+ Version: 2.2.4
4
4
  Summary: MCP server for creating, reading and editing Excel workbooks without Microsoft Excel
5
5
  Keywords: mcp,mcp-server,model-context-protocol,excel,xlsx,xlsm,spreadsheet,openpyxl,charts,pivot-table,formulas,vba,llm,ai,claude,cursor
6
6
  Author: Haris Musa
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "excel-mcp-server"
3
- version = "2.2.3"
3
+ version = "2.2.4"
4
4
  description = "MCP server for creating, reading and editing Excel workbooks without Microsoft Excel"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "excel-mcp-server"
3
- version = "2.2.3"
3
+ version = "2.2.4"
4
4
  description = "MCP server for creating, reading and editing Excel workbooks without Microsoft Excel"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -7,6 +7,7 @@ from openpyxl.workbook import Workbook
7
7
  from openpyxl.workbook.defined_name import DefinedName
8
8
  from openpyxl.worksheet.worksheet import Worksheet
9
9
 
10
+ from excel_mcp.errors import WorkbookError
10
11
  from excel_mcp.operations import slicer_xml as xml
11
12
  from excel_mcp.package import Link, Part, SheetPackage, state_of
12
13
  from excel_mcp.package.anchors import Geometry
@@ -119,7 +120,8 @@ def _list_in(extensions: dict[str, str], uri: str, element: str) -> None:
119
120
  assert reference is not None
120
121
  existing = extensions[uri]
121
122
  closing = re.search(r"</(?:\w+:)(?:slicerCaches|timelineCacheRefs)>", existing)
122
- assert closing is not None
123
+ if closing is None:
124
+ raise WorkbookError("The workbook's list of slicer or timeline caches is malformed.")
123
125
  extensions[uri] = existing[: closing.start()] + reference[0] + existing[closing.start() :]
124
126
 
125
127
 
@@ -17,7 +17,7 @@ from excel_mcp.operations.sparkline_style import SparklineInfo, SparklineStyle,
17
17
  from excel_mcp.operations.sparkline_xml import build_group, read_groups
18
18
  from excel_mcp.operations.x14_xml import X14, XM, sheet_prefix
19
19
  from excel_mcp.package import state_of
20
- from excel_mcp.package.extensions import SPARKLINES, edit_sparklines
20
+ from excel_mcp.package.extensions import SPARKLINES, edit_sparklines, sparkline_location
21
21
  from excel_mcp.refs import CellRange, cell_name, parse_range
22
22
  from excel_mcp.workspace import get_sheet
23
23
 
@@ -117,9 +117,7 @@ def _delete(extensions: dict[str, str], doomed: Callable[[str], bool]) -> int:
117
117
 
118
118
  def handle(item: str) -> list[str]:
119
119
  nonlocal removed
120
- location = _LOCATION.search(item)
121
- assert location is not None
122
- if doomed(location[1]):
120
+ if doomed(sparkline_location(item)):
123
121
  removed += 1
124
122
  return []
125
123
  return [item]
@@ -12,6 +12,7 @@ from xml.sax.saxutils import escape
12
12
 
13
13
  from openpyxl.utils.cell import column_index_from_string, get_column_letter
14
14
 
15
+ from excel_mcp.errors import WorkbookError
15
16
  from excel_mcp.package.lines import LineEdit
16
17
  from excel_mcp.package.scan import unescape
17
18
  from excel_mcp.refs import CellRange, clip_areas, parse_range
@@ -232,11 +233,21 @@ def _sparklines(xml: str, handle: Callable[[str], list[str]]) -> str | None:
232
233
  return xml if re.search(r"<x14:sparklineGroup\b", xml) else None
233
234
 
234
235
 
235
- def _moved_sparkline(item: str, rewriter: Rewriter) -> list[str]:
236
+ def sparkline_location(item: str) -> str:
237
+ """The cell of a ``<x14:sparkline>``. Excel refuses a file with a sparkline that has none."""
236
238
  location = _RANGE.search(item)
239
+ if location is None:
240
+ raise WorkbookError(
241
+ "The workbook has a sparkline without a location (<xm:sqref>), which Excel "
242
+ "cannot open. Remove it from the file."
243
+ )
244
+ return location[1]
245
+
246
+
247
+ def _moved_sparkline(item: str, rewriter: Rewriter) -> list[str]:
248
+ location = sparkline_location(item)
237
249
  source = _FORMULA.search(item)
238
- assert location is not None
239
- moved = rewriter.ranges(location[1], grow=False)
250
+ moved = rewriter.ranges(location, grow=False)
240
251
  if moved is None:
241
252
  return []
242
253
  item = _RANGE.sub(lambda _: f"<xm:sqref>{moved}</xm:sqref>", item)
@@ -246,7 +257,7 @@ def _moved_sparkline(item: str, rewriter: Rewriter) -> list[str]:
246
257
  item = item.replace(source[0], "")
247
258
  else:
248
259
  item = item.replace(source[0], f"<xm:f>{escape(read)}</xm:f>")
249
- return [item, *_inserted_copies(item, location[1], rewriter)]
260
+ return [item, *_inserted_copies(item, location, rewriter)]
250
261
 
251
262
 
252
263
  def _moved_formula(match: re.Match[str], rewriter: Rewriter) -> str:
@@ -2,6 +2,7 @@
2
2
 
3
3
  import re
4
4
  from collections.abc import Callable
5
+ from itertools import pairwise
5
6
 
6
7
  from excel_mcp.errors import WorkbookError
7
8
  from excel_mcp.package.scan import Scan, scan
@@ -146,18 +147,44 @@ def _with_extension(rule: bytes, qname: str, extension: str, offset: int) -> Edi
146
147
  return (offset, offset + len(rule), text)
147
148
 
148
149
 
150
+ # Looking each cell up by its address reads the sheet once per cell, which is fastest for a
151
+ # few cells; for more, one pass over all the cells does not grow with the number to patch.
152
+ _FEW_CELLS = 16
153
+ _CELL = re.compile(rb'<c r="([^"]*)"([^>]*?)(?:/>|>(.*?)</c>)', re.S)
154
+
155
+
149
156
  def patch_cells(data: bytes, edits: dict[str, CellEdit]) -> bytes:
150
157
  """Rewrite chosen cells of ``sheetData``; an edit gets a cell's attributes and its content."""
151
158
  if not edits:
152
159
  return data
153
- cell = re.compile(rb'<c r="([^"]*)"([^>]*?)(?:/>|>(.*?)</c>)', re.S)
160
+ if len(edits) <= _FEW_CELLS:
161
+ return splice(data, _located_edits(data, edits))
154
162
 
155
163
  def rewrite(match: re.Match[bytes]) -> bytes:
156
- coordinate = match[1].decode()
157
- if coordinate not in edits:
158
- return match[0]
159
- attributes, body = edits[coordinate](match[2].decode(), (match[3] or b"").decode())
160
- start = f'<c r="{coordinate}"{attributes}'
161
- return f"{start}>{body}</c>".encode() if body else f"{start}/>".encode()
162
-
163
- return cell.sub(rewrite, data)
164
+ edit = edits.get(match[1].decode())
165
+ return _rewritten(match, edit) if edit else match[0]
166
+
167
+ return _CELL.sub(rewrite, data)
168
+
169
+
170
+ def _located_edits(data: bytes, edits: dict[str, CellEdit]) -> list[Edit]:
171
+ found: list[Edit] = []
172
+ for coordinate, edit in edits.items():
173
+ opening = b'<c r="%b"' % coordinate.encode()
174
+ start = data.find(opening)
175
+ while start >= 0:
176
+ match = _CELL.match(data, start)
177
+ if match is None:
178
+ raise WorkbookError(f"Cell {coordinate} of a worksheet is malformed.")
179
+ found.append((match.start(), match.end(), _rewritten(match, edit)))
180
+ start = data.find(opening, match.end())
181
+ found.sort()
182
+ if any(before[1] > after[0] for before, after in pairwise(found)):
183
+ raise WorkbookError("A worksheet has cells inside other cells.")
184
+ return found
185
+
186
+
187
+ def _rewritten(match: re.Match[bytes], edit: CellEdit) -> bytes:
188
+ attributes, body = edit(match[2].decode(), (match[3] or b"").decode())
189
+ start = f'<c r="{match[1].decode()}"{attributes}'
190
+ return f"{start}>{body}</c>".encode() if body else f"{start}/>".encode()
@@ -26,6 +26,7 @@ from xml.sax.saxutils import escape
26
26
  from openpyxl import Workbook
27
27
  from openpyxl.worksheet.worksheet import Worksheet
28
28
 
29
+ from excel_mcp.errors import WorkbookError
29
30
  from excel_mcp.package import extensions
30
31
  from excel_mcp.package.anchors import Geometry, Moved, move_anchors, move_vml_shape
31
32
  from excel_mcp.package.lines import LineEdit
@@ -120,7 +121,8 @@ def _ranged_items(xml: str, item: str, attribute: str, rewriter: _Rewriter) -> s
120
121
  def move(match: re.Match[str]) -> str:
121
122
  text = match[0]
122
123
  value = re.search(rf'\b{attribute}="([^"]*)"', text)
123
- assert value is not None
124
+ if value is None:
125
+ raise WorkbookError(f"A <{item}> of the workbook has no {attribute} attribute.")
124
126
  moved = rewriter.ranges(value[1], grow=attribute == "sqref")
125
127
  return "" if moved is None else text.replace(value[0], f'{attribute}="{moved}"', 1)
126
128
 
@@ -134,7 +136,8 @@ def _sort_state(xml: str, rewriter: _Rewriter) -> str | None:
134
136
 
135
137
  def move(match: re.Match[str]) -> str:
136
138
  found = ref.search(match[0])
137
- assert found is not None
139
+ if found is None:
140
+ raise WorkbookError("A <sortCondition> of the workbook has no ref attribute.")
138
141
  moved = rewriter.ranges(found[1])
139
142
  return "" if moved is None else match[0].replace(found[0], f'ref="{moved}"', 1)
140
143