mcp-validation-server 0.1.0__py3-none-any.whl
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.
- mcp_validation_server/__init__.py +85 -0
- mcp_validation_server/__main__.py +8 -0
- mcp_validation_server/app.py +39 -0
- mcp_validation_server/contract.py +800 -0
- mcp_validation_server/entities.py +652 -0
- mcp_validation_server/findings.py +204 -0
- mcp_validation_server/py.typed +0 -0
- mcp_validation_server/reconcile.py +498 -0
- mcp_validation_server/server.py +71 -0
- mcp_validation_server/tools.py +671 -0
- mcp_validation_server-0.1.0.dist-info/METADATA +531 -0
- mcp_validation_server-0.1.0.dist-info/RECORD +16 -0
- mcp_validation_server-0.1.0.dist-info/WHEEL +5 -0
- mcp_validation_server-0.1.0.dist-info/entry_points.txt +2 -0
- mcp_validation_server-0.1.0.dist-info/licenses/LICENSE +21 -0
- mcp_validation_server-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""mcp-validation-server — deterministic data-validation tools over MCP.
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol server that exposes four checks a model cannot argue
|
|
4
|
+
with: contract validation with quarantine, arithmetic reconciliation, distinct
|
|
5
|
+
entity counting, and duplicate reporting for human review.
|
|
6
|
+
|
|
7
|
+
The design rule: **a validation failure is a result, not an exception.** Every
|
|
8
|
+
tool returns structured findings with stable codes and row/column locators, so a
|
|
9
|
+
calling model can report what failed and recover. Only malformed tool arguments
|
|
10
|
+
raise.
|
|
11
|
+
|
|
12
|
+
The tool functions are importable and callable directly, which is how the unit
|
|
13
|
+
tests exercise them without an MCP client:
|
|
14
|
+
|
|
15
|
+
>>> from mcp_validation_server import validate_rows
|
|
16
|
+
>>> result = validate_rows([{"amount": "-5"}], [{"name": "amount", "type": "number", "min": 0}])
|
|
17
|
+
>>> result["ok"], result["summary"]["quarantined"]
|
|
18
|
+
(False, 1)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from .app import SERVER_NAME, SERVER_VERSION, mcp
|
|
24
|
+
from .contract import (
|
|
25
|
+
ColumnSpecError,
|
|
26
|
+
Field,
|
|
27
|
+
Max,
|
|
28
|
+
Min,
|
|
29
|
+
NotBlank,
|
|
30
|
+
OneOf,
|
|
31
|
+
Pattern,
|
|
32
|
+
Range,
|
|
33
|
+
RowContract,
|
|
34
|
+
Rule,
|
|
35
|
+
ValidationOutcome,
|
|
36
|
+
parse_columns,
|
|
37
|
+
)
|
|
38
|
+
from .entities import (
|
|
39
|
+
DistinctOutcome,
|
|
40
|
+
DuplicateGroup,
|
|
41
|
+
DuplicateOutcome,
|
|
42
|
+
count_distinct_rows,
|
|
43
|
+
find_duplicate_groups,
|
|
44
|
+
normalise_key,
|
|
45
|
+
)
|
|
46
|
+
from .findings import Finding, Locator, envelope
|
|
47
|
+
from .reconcile import Movement, ReconcileOutcome, reconcile_arithmetic
|
|
48
|
+
from .tools import count_distinct, duplicate_report, reconcile, validate_rows
|
|
49
|
+
|
|
50
|
+
__version__ = SERVER_VERSION
|
|
51
|
+
|
|
52
|
+
__all__ = [
|
|
53
|
+
"ColumnSpecError",
|
|
54
|
+
"DistinctOutcome",
|
|
55
|
+
"DuplicateGroup",
|
|
56
|
+
"DuplicateOutcome",
|
|
57
|
+
"Field",
|
|
58
|
+
"Finding",
|
|
59
|
+
"Locator",
|
|
60
|
+
"Max",
|
|
61
|
+
"Min",
|
|
62
|
+
"Movement",
|
|
63
|
+
"NotBlank",
|
|
64
|
+
"OneOf",
|
|
65
|
+
"Pattern",
|
|
66
|
+
"Range",
|
|
67
|
+
"ReconcileOutcome",
|
|
68
|
+
"RowContract",
|
|
69
|
+
"Rule",
|
|
70
|
+
"SERVER_NAME",
|
|
71
|
+
"SERVER_VERSION",
|
|
72
|
+
"ValidationOutcome",
|
|
73
|
+
"__version__",
|
|
74
|
+
"count_distinct",
|
|
75
|
+
"count_distinct_rows",
|
|
76
|
+
"duplicate_report",
|
|
77
|
+
"envelope",
|
|
78
|
+
"find_duplicate_groups",
|
|
79
|
+
"mcp",
|
|
80
|
+
"normalise_key",
|
|
81
|
+
"parse_columns",
|
|
82
|
+
"reconcile",
|
|
83
|
+
"reconcile_arithmetic",
|
|
84
|
+
"validate_rows",
|
|
85
|
+
]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""The server instance.
|
|
2
|
+
|
|
3
|
+
Kept in its own module so that :mod:`mcp_validation_server.tools` can import it
|
|
4
|
+
and register tools with the ``@mcp.tool()`` decorator without a circular import.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from mcp.server.mcpserver import MCPServer
|
|
10
|
+
|
|
11
|
+
SERVER_NAME = "mcp-validation-server"
|
|
12
|
+
SERVER_VERSION = "0.1.0"
|
|
13
|
+
|
|
14
|
+
INSTRUCTIONS = """\
|
|
15
|
+
Deterministic data-validation tools. Use these when a claim about a dataset needs
|
|
16
|
+
to be checked rather than asserted: to validate rows against a column contract, to
|
|
17
|
+
confirm that a period of arithmetic closes, to count distinct entities rather than
|
|
18
|
+
rows, or to surface suspected duplicates for review.
|
|
19
|
+
|
|
20
|
+
Every tool returns a JSON result with the same envelope: `ok`, `verdict`,
|
|
21
|
+
`findings`, and `guidance`. A validation failure is a RESULT, not an error. When a
|
|
22
|
+
tool returns `ok: false` the call succeeded — the data failed. Read the `findings`
|
|
23
|
+
array, which gives a stable `code`, a human-readable `message`, and a `locator`
|
|
24
|
+
naming the exact row (and column) for each problem. The `guidance` field says what
|
|
25
|
+
to do next.
|
|
26
|
+
|
|
27
|
+
Nothing here drops, merges, repairs, or overwrites data. Rows that fail are
|
|
28
|
+
quarantined and reported; suspected duplicates are returned for a human to decide.
|
|
29
|
+
Do not describe a dataset as validated unless the tool returned `ok: true`.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
mcp = MCPServer(
|
|
33
|
+
name=SERVER_NAME,
|
|
34
|
+
title="Data Validation",
|
|
35
|
+
version=SERVER_VERSION,
|
|
36
|
+
instructions=INSTRUCTIONS,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
__all__ = ["INSTRUCTIONS", "SERVER_NAME", "SERVER_VERSION", "mcp"]
|