feat(cell validation): add comprehensive data validation capabilities (#37)

- Add cell_validation.py module for Excel data validation metadata extraction
- Implement get_data_validation_for_cell() and get_all_validation_ranges()
- Include validation metadata in read_data_from_excel responses automatically
- Add get_data_validation_info MCP tool for validation rule summaries
- Resolve range references in list validations to actual cell values
- Support all validation types: list, whole, decimal, date, time, textLength
- Include operators (between, notBetween, equal, greaterThan, etc.) in metadata

This allows LLMs to understand Excel validation constraints including
dropdown options, numeric ranges, date constraints, and text length limits.
This commit is contained in:
Nate
2025-06-06 21:42:00 -07:00
committed by GitHub
parent b2c9ce8e6a
commit bb537b35be
5 changed files with 393 additions and 19 deletions

25
uv.lock generated
View File

@ -1,5 +1,4 @@
version = 1
revision = 1
requires-python = ">=3.10"
[[package]]
@ -67,17 +66,19 @@ wheels = [
[[package]]
name = "excel-mcp-server"
version = "0.1.1"
version = "0.1.3"
source = { editable = "." }
dependencies = [
{ name = "mcp", extra = ["cli"] },
{ name = "openpyxl" },
{ name = "typer" },
]
[package.metadata]
requires-dist = [
{ name = "mcp", extras = ["cli"], specifier = ">=1.2.0" },
{ name = "mcp", extras = ["cli"], specifier = ">=1.6.0" },
{ name = "openpyxl", specifier = ">=3.1.2" },
{ name = "typer", specifier = ">=0.15.1" },
]
[[package]]
@ -158,7 +159,7 @@ wheels = [
[[package]]
name = "mcp"
version = "1.2.1"
version = "1.9.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@ -166,13 +167,14 @@ dependencies = [
{ name = "httpx-sse" },
{ name = "pydantic" },
{ name = "pydantic-settings" },
{ name = "python-multipart" },
{ name = "sse-starlette" },
{ name = "starlette" },
{ name = "uvicorn" },
{ name = "uvicorn", marker = "sys_platform != 'emscripten'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fc/30/51e4555826126e3954fa2ab1e934bf74163c5fe05e98f38ca4d0f8abbf63/mcp-1.2.1.tar.gz", hash = "sha256:c9d43dbfe943aa1530e2be8f54b73af3ebfb071243827b4483d421684806cb45", size = 103968 }
sdist = { url = "https://files.pythonhosted.org/packages/e7/bc/54aec2c334698cc575ca3b3481eed627125fb66544152fa1af927b1a495c/mcp-1.9.1.tar.gz", hash = "sha256:19879cd6dde3d763297617242888c2f695a95dfa854386a6a68676a646ce75e4", size = 316247 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4c/0d/6770742a84c8aa1d36c0d628896a380584c5759612e66af7446af07d8775/mcp-1.2.1-py3-none-any.whl", hash = "sha256:579bf9c9157850ebb1344f3ca6f7a3021b0123c44c9f089ef577a7062522f0fd", size = 66453 },
{ url = "https://files.pythonhosted.org/packages/a6/c0/4ac795585a22a0a2d09cd2b1187b0252d2afcdebd01e10a68bbac4d34890/mcp-1.9.1-py3-none-any.whl", hash = "sha256:2900ded8ffafc3c8a7bfcfe8bc5204037e988e753ec398f371663e6a06ecd9a9", size = 130261 },
]
[package.optional-dependencies]
@ -322,6 +324,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
]
[[package]]
name = "python-multipart"
version = "0.0.20"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 },
]
[[package]]
name = "rich"
version = "13.9.4"