sdcvalidator 4.5.2__tar.gz → 4.5.3__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 (34) hide show
  1. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/PKG-INFO +6 -2
  2. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/README.md +5 -1
  3. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/pyproject.toml +1 -1
  4. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/__init__.py +1 -1
  5. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/mcp_server.py +22 -7
  6. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator.egg-info/PKG-INFO +6 -2
  7. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator.egg-info/SOURCES.txt +1 -0
  8. sdcvalidator-4.5.3/tests/test_registry_launch.py +79 -0
  9. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/LICENSE +0 -0
  10. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/setup.cfg +0 -0
  11. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/cli.py +0 -0
  12. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/constants.py +0 -0
  13. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/converters.py +0 -0
  14. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/error_classifier.py +0 -0
  15. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/error_mapper.py +0 -0
  16. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/exceptions.py +0 -0
  17. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/instance_modifier.py +0 -0
  18. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/schema_checker.py +0 -0
  19. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/validator.py +0 -0
  20. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator/xsd11_restriction.py +0 -0
  21. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator.egg-info/dependency_links.txt +0 -0
  22. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator.egg-info/entry_points.txt +0 -0
  23. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator.egg-info/requires.txt +0 -0
  24. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/src/sdcvalidator.egg-info/top_level.txt +0 -0
  25. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_converters.py +0 -0
  26. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_error_classifier.py +0 -0
  27. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_error_mapper.py +0 -0
  28. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_instance_modifier.py +0 -0
  29. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_mcp_server.py +0 -0
  30. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_recovery.py +0 -0
  31. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_schema_checker.py +0 -0
  32. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_validator.py +0 -0
  33. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_xsd11_restriction.py +0 -0
  34. {sdcvalidator-4.5.2 → sdcvalidator-4.5.3}/tests/test_xsi_type.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdcvalidator
3
- Version: 4.5.2
3
+ Version: 4.5.3
4
4
  Summary: SDC4 structural validator with ExceptionalValue recovery — thin wrapper over xmlschema
5
5
  Author: Axius SDC, Inc.
6
6
  License-Expression: Apache-2.0
@@ -151,9 +151,13 @@ sdcvalidator-json2xml data.json schema.xsd -o output.xml
151
151
  `sdcvalidator` ships a stdio MCP (Model Context Protocol) server so any MCP-capable agent can validate SDC4 data without importing the Python library. It implements JSON-RPC 2.0 directly over stdio — no external MCP SDK dependency.
152
152
 
153
153
  ```bash
154
- sdcvalidator-mcp serve --mcp
154
+ sdcvalidator # what an MCP registry client runs (uvx sdcvalidator)
155
+ sdcvalidator mcp # the same, spelled like the other Semantic Data Charter servers
156
+ sdcvalidator-mcp serve --mcp # still works for existing client configurations
155
157
  ```
156
158
 
159
+ A client configuration needs only `"command": "uvx", "args": ["sdcvalidator"]`.
160
+
157
161
  ### Tools
158
162
 
159
163
  | Tool | Purpose |
@@ -129,9 +129,13 @@ sdcvalidator-json2xml data.json schema.xsd -o output.xml
129
129
  `sdcvalidator` ships a stdio MCP (Model Context Protocol) server so any MCP-capable agent can validate SDC4 data without importing the Python library. It implements JSON-RPC 2.0 directly over stdio — no external MCP SDK dependency.
130
130
 
131
131
  ```bash
132
- sdcvalidator-mcp serve --mcp
132
+ sdcvalidator # what an MCP registry client runs (uvx sdcvalidator)
133
+ sdcvalidator mcp # the same, spelled like the other Semantic Data Charter servers
134
+ sdcvalidator-mcp serve --mcp # still works for existing client configurations
133
135
  ```
134
136
 
137
+ A client configuration needs only `"command": "uvx", "args": ["sdcvalidator"]`.
138
+
135
139
  ### Tools
136
140
 
137
141
  | Tool | Purpose |
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sdcvalidator"
7
- version = "4.5.2"
7
+ version = "4.5.3"
8
8
  description = "SDC4 structural validator with ExceptionalValue recovery — thin wrapper over xmlschema"
9
9
  license = "Apache-2.0"
10
10
  requires-python = ">=3.10"
@@ -14,7 +14,7 @@ Thin wrapper over xmlschema with two-tier error classification and the SDC4
14
14
  "quarantine-and-tag" recovery pattern (ISO 21090 ExceptionalValues).
15
15
  """
16
16
 
17
- __version__ = "4.5.2"
17
+ __version__ = "4.5.3"
18
18
 
19
19
  # etree_tostring is re-exported from xmlschema so callers can serialize the
20
20
  # ElementTree returned by validate_with_recovery() without importing xmlschema
@@ -36,7 +36,7 @@ from sdcvalidator.schema_checker import validate_sdc4_schema_compliance
36
36
  JSONRPC_VERSION = "2.0"
37
37
  MCP_PROTOCOL_VERSION = "2024-11-05"
38
38
  SERVER_NAME = "sdcvalidator"
39
- SERVER_VERSION = "4.5.2"
39
+ SERVER_VERSION = "4.5.3"
40
40
 
41
41
  # Validator cache: schema_path -> SDC4Validator
42
42
  _validators: dict[str, SDC4Validator] = {}
@@ -290,22 +290,37 @@ def run_stdio() -> None:
290
290
  sys.stdout.flush()
291
291
 
292
292
 
293
- def main() -> None:
294
- """Entry point for the sdcvalidator MCP server."""
293
+ def main(argv: list[str] | None = None) -> None:
294
+ """Entry point of the ``sdcvalidator`` and ``sdcvalidator-mcp`` console scripts.
295
+
296
+ Three spellings start the stdio server: no arguments at all (what an MCP
297
+ registry client runs: ``uvx sdcvalidator``), ``mcp`` (the spelling the other
298
+ Semantic Data Charter servers use) and ``serve --mcp`` (kept for existing
299
+ client configurations). Until 4.5.3 the bare command printed this help and
300
+ exited, so the registry entry never started a server (issue #15).
301
+ """
295
302
  import argparse
296
303
 
297
304
  parser = argparse.ArgumentParser(
298
- prog="sdcvalidator-mcp",
299
- description="SDC4 structural validator - MCP server",
305
+ prog="sdcvalidator",
306
+ description="SDC4 structural validator - MCP stdio server",
307
+ epilog="With no command the MCP server starts, reading JSON-RPC on stdin.",
300
308
  )
301
309
  subparsers = parser.add_subparsers(dest="command")
302
310
 
311
+ subparsers.add_parser("mcp", help="Run the MCP stdio server")
303
312
  serve_parser = subparsers.add_parser("serve", help="Start the validation server")
304
313
  serve_parser.add_argument("--mcp", action="store_true", help="Run as MCP stdio server")
305
314
 
306
- args = parser.parse_args()
315
+ args = parser.parse_args(argv)
307
316
 
308
- if args.command == "serve" and args.mcp:
317
+ if args.command is None or args.command == "mcp" or (args.command == "serve" and args.mcp):
318
+ if args.command is None and sys.stdin.isatty():
319
+ sys.stderr.write(
320
+ "sdcvalidator: MCP server reading JSON-RPC 2.0 on stdin "
321
+ "(sdcvalidator --help for options, Ctrl-D to stop)\n"
322
+ )
323
+ sys.stderr.flush()
309
324
  run_stdio()
310
325
  else:
311
326
  parser.print_help()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdcvalidator
3
- Version: 4.5.2
3
+ Version: 4.5.3
4
4
  Summary: SDC4 structural validator with ExceptionalValue recovery — thin wrapper over xmlschema
5
5
  Author: Axius SDC, Inc.
6
6
  License-Expression: Apache-2.0
@@ -151,9 +151,13 @@ sdcvalidator-json2xml data.json schema.xsd -o output.xml
151
151
  `sdcvalidator` ships a stdio MCP (Model Context Protocol) server so any MCP-capable agent can validate SDC4 data without importing the Python library. It implements JSON-RPC 2.0 directly over stdio — no external MCP SDK dependency.
152
152
 
153
153
  ```bash
154
- sdcvalidator-mcp serve --mcp
154
+ sdcvalidator # what an MCP registry client runs (uvx sdcvalidator)
155
+ sdcvalidator mcp # the same, spelled like the other Semantic Data Charter servers
156
+ sdcvalidator-mcp serve --mcp # still works for existing client configurations
155
157
  ```
156
158
 
159
+ A client configuration needs only `"command": "uvx", "args": ["sdcvalidator"]`.
160
+
157
161
  ### Tools
158
162
 
159
163
  | Tool | Purpose |
@@ -25,6 +25,7 @@ tests/test_error_mapper.py
25
25
  tests/test_instance_modifier.py
26
26
  tests/test_mcp_server.py
27
27
  tests/test_recovery.py
28
+ tests/test_registry_launch.py
28
29
  tests/test_schema_checker.py
29
30
  tests/test_validator.py
30
31
  tests/test_xsd11_restriction.py
@@ -0,0 +1,79 @@
1
+ """
2
+ The MCP registry entry starts the server (issue #15).
3
+
4
+ ``server.json`` declared no ``packageArguments``, so ``uvx sdcvalidator`` ran
5
+ ``main()`` with no arguments, which printed the CLI help and exited. These
6
+ tests start the console script's entry point the way a registry client, a
7
+ hand-written configuration and the pre-4.5.3 configuration do, and check that
8
+ ``server.json`` names the released version.
9
+ """
10
+ import json
11
+ import re
12
+ import subprocess
13
+ import sys
14
+ from pathlib import Path
15
+
16
+ import pytest
17
+
18
+ import sdcvalidator
19
+ from sdcvalidator.mcp_server import SERVER_VERSION
20
+
21
+ ROOT = Path(__file__).resolve().parents[1]
22
+ SERVER_JSON = json.loads((ROOT / "server.json").read_text(encoding="utf-8"))
23
+
24
+ INITIALIZE = {"jsonrpc": "2.0", "id": 1, "method": "initialize",
25
+ "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "t", "version": "0"}}}
26
+
27
+
28
+ def _launch(args):
29
+ proc = subprocess.run(
30
+ [sys.executable, "-m", "sdcvalidator.mcp_server", *args],
31
+ input=json.dumps(INITIALIZE) + "\n",
32
+ capture_output=True, text=True, timeout=60,
33
+ )
34
+ return proc
35
+
36
+
37
+ def _registry_args():
38
+ package = SERVER_JSON["packages"][0]
39
+ return [a["value"] for a in package.get("packageArguments", []) if a["type"] == "positional"]
40
+
41
+
42
+ @pytest.mark.parametrize("args", [
43
+ pytest.param([], id="bare, what a registry client without packageArguments runs"),
44
+ pytest.param(_registry_args(), id="server.json packageArguments"),
45
+ pytest.param(["mcp"], id="mcp"),
46
+ pytest.param(["serve", "--mcp"], id="serve --mcp (pre-4.5.3 configurations)"),
47
+ ])
48
+ def test_each_launch_spelling_answers_initialize(args):
49
+ proc = _launch(args)
50
+ assert proc.returncode == 0, proc.stderr
51
+ lines = [line for line in proc.stdout.splitlines() if line.strip()]
52
+ assert lines, f"no JSON-RPC response; stdout was help text?\n{proc.stdout}"
53
+ response = json.loads(lines[0])
54
+ assert response["id"] == 1
55
+ assert response["result"]["serverInfo"]["name"] == "sdcvalidator"
56
+ assert response["result"]["serverInfo"]["version"] == SERVER_VERSION
57
+ assert "usage:" not in proc.stdout
58
+
59
+
60
+ def test_serve_without_mcp_still_prints_help():
61
+ proc = _launch(["serve"])
62
+ assert proc.returncode == 0
63
+ assert "usage:" in proc.stdout
64
+
65
+
66
+ def test_server_json_declares_the_mcp_launch():
67
+ package = SERVER_JSON["packages"][0]
68
+ assert package["identifier"] == "sdcvalidator"
69
+ assert package["runtimeHint"] == "uvx"
70
+ assert _registry_args() == ["mcp"]
71
+
72
+
73
+ def test_server_json_names_the_released_version():
74
+ # A regex, not tomllib: the test matrix includes Python 3.10.
75
+ pyproject = re.search(r'^version = "([^"]+)"', (ROOT / "pyproject.toml").read_text(encoding="utf-8"), re.M).group(1)
76
+ assert SERVER_JSON["version"] == pyproject
77
+ assert SERVER_JSON["packages"][0]["version"] == pyproject
78
+ assert sdcvalidator.__version__ == pyproject
79
+ assert SERVER_VERSION == pyproject
File without changes
File without changes