feat(mcp): add side-effect-free request preflight

Add local ocs_read validate calls that check operation parameters, nested definitions, request envelopes and batch bindings without dispatching. Report document-dependent checks and unresolved result bindings explicitly. Share validation with execution and validate inline JSON Schema fragments before dispatch.

Validation: 66 targeted tests, desktop build, WebAssembly app/worker check, schema validation and MCP stdio smoke tests.
This commit is contained in:
Karim Jerbi committed 2026-10-13 09:33:49 +01:00
1 parent 97afb57333
commit 006be8909e
4 files changed
+293 -188

No files matched your search

+20
View File
@@ -144,6 +144,26 @@ def legacy(server: Path) -> None:
assert not entity_schema["result"].get("isError"), entity_schema
contract = entity_schema["result"]["structuredContent"]["schema"]
assert contract["required"] == ["type", "center", "radius"]
validated = request(process, {
"jsonrpc": "2.0", "id": "preflight", "method": "tools/call",
"params": {"name": "ocs_read", "arguments": {
"op": "validate", "parameters": {"request": {
"op": "entities_create", "entities": contract["examples"],
}},
}},
})
assert validated["result"]["structuredContent"]["valid"] is True
assert validated["result"]["structuredContent"]["executed"] is False
rejected = request(process, {
"jsonrpc": "2.0", "id": "bad-preflight", "method": "tools/call",
"params": {"name": "ocs_read", "arguments": {
"op": "validate", "parameters": {"request": {
"op": "entities_create", "entities": [{"type": "Circle", "center": ["bad", 0], "radius": 5}],
}},
}},
})
assert rejected["result"]["isError"] is True
assert "/entities/0/center/0" in rejected["result"]["content"][0]["text"]
close(process)