Skip to main content

qualia_core_db/mcp/
mcp_server.rs

1// crates/qualia-core-db/src/mcp_server.rs
2
3// We still need access to standard library for I/O and String during init phase
4extern crate std;
5
6#[path = "mcp_format_impls.rs"]
7mod mcp_format_impls;
8#[path = "mcp_stub_impls.rs"]
9mod mcp_stub_impls;
10#[path = "mcp_tool_impls/mod.rs"]
11mod mcp_tool_impls;
12
13use crate::wal::append_mutation;
14use crate::NQuin;
15use core::ptr::write_volatile;
16use serde_json::{json, Value};
17use std::string::String;
18
19/// Explicit operational states defining the execution boundaries
20#[derive(Copy, Clone, PartialEq, Eq)]
21pub enum McpRuntimeState {
22    HandshakePhase,
23    AllocationFirewallActive,
24    SanctuaryGated,
25}
26
27#[derive(Debug)]
28pub enum McpSystemError {
29    SanctuaryGateTriggered,
30    ToolNotFound,
31    ToolNotReady,
32    ParseError,
33    IntentFrameViolation,
34    FeatureNotEnabled,
35    InvalidParameters,
36}
37
38#[derive(Debug, Clone)]
39pub struct McpIntentFrame {
40    pub purpose_hash: u64,
41    pub active_deontic_constraints: Vec<u64>,
42    pub active_profile_id: Option<u64>,
43    pub session_nonce: u64,
44    /// A genuine 32-byte cryptographic egress-override token, or `None` when the
45    /// caller supplied no override — or supplied a malformed / placeholder /
46    /// all-zero value, all of which fail closed to `None`. See
47    /// [`parse_sanctuary_override`] for the validation contract.
48    pub sanctuary_override: Option<[u8; 32]>,
49    pub qpu_enabled: bool,
50    pub llm_enabled: bool,
51}
52
53/// Zero-deserialization view over an incoming tools/call byte buffer
54pub struct RawToolPayload<'a> {
55    pub tool_name: &'a [u8],
56    pub arguments_raw: &'a [u8],
57}
58
59#[derive(Clone, Copy)]
60struct McpToolDescriptor {
61    name: &'static str,
62    description: &'static str,
63    input_schema: &'static str,
64}
65
66// Simple raw-byte slice extractor. This is a very rudimentary byte matcher
67// intended to satisfy the requirement of bypassing generic serde allocation.
68fn extract_raw_json_string<'a>(payload: &'a [u8], key: &[u8]) -> Option<&'a [u8]> {
69    // Look for `"key":"value"`
70    let mut i = 0;
71    while i < payload.len() {
72        if payload[i..].starts_with(key) {
73            i += key.len();
74            // find colon
75            while i < payload.len() && (payload[i] == b' ' || payload[i] == b':') {
76                i += 1;
77            }
78            if i < payload.len() && payload[i] == b'"' {
79                i += 1;
80                let start = i;
81                while i < payload.len() && payload[i] != b'"' {
82                    i += 1;
83                }
84                return Some(&payload[start..i]);
85            }
86        }
87        i += 1;
88    }
89    None
90}
91
92fn stable_mcp_tools() -> &'static [McpToolDescriptor] {
93    &[
94        McpToolDescriptor {
95            name: "query_graph",
96            description: "Run guarded graph traversal against the in-memory daemon graph.",
97            input_schema: r#"{"type":"object","properties":{"sanctuary_override":{"type":"string"}}}"#,
98        },
99        McpToolDescriptor {
100            name: "query_sparql",
101            description: "Execute an N-Triples pattern query against the in-process daemon graph.",
102            input_schema: r#"{"type":"object","required":["query"],"properties":{"query":{"type":"string"},"limit":{"type":"integer"}}}"#,
103        },
104        McpToolDescriptor {
105            name: "get_graph_stats",
106            description: "Return quin count and capacity for the resident daemon graph.",
107            input_schema: r#"{"type":"object","properties":{}}"#,
108        },
109        McpToolDescriptor {
110            name: "list_ontologies",
111            description: "List startup ontology catalog entries and on-disk presence.",
112            input_schema: r#"{"type":"object","properties":{}}"#,
113        },
114        McpToolDescriptor {
115            name: "llm_infer",
116            description: "Run local GGUF inference. Greedy by default. Optional exact seeded sampling: pass `sampler_cbor`, a hex-encoded CBOR map of SamplerConfig {temperature, top_k, top_p, repeat_penalty, freq_penalty, presence_penalty, penalty_window, seed}; temperature<=0 or absent ⇒ greedy.",
117            input_schema: r#"{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string"},"model_path":{"type":"string"},"graph_context":{"type":"string"},"sampler_cbor":{"type":"string","description":"hex-encoded CBOR map of SamplerConfig"}}}"#,
118        },
119        McpToolDescriptor {
120            name: "llm_chat",
121            description: "Multi-turn chat completion via the local GGUF inference stack.",
122            input_schema: r#"{"type":"object","required":["messages"],"properties":{"messages":{"type":"array"},"model_path":{"type":"string"},"graph_context":{"type":"string"}}}"#,
123        },
124        McpToolDescriptor {
125            name: "list_models",
126            description: "Discover GGUF models under storage and any resident mounted model.",
127            input_schema: r#"{"type":"object","properties":{}}"#,
128        },
129        McpToolDescriptor {
130            name: "qpu_optimize",
131            description: "Formulate a QUBO/circuit job from a problem description and classical solve.",
132            input_schema: r#"{"type":"object","required":["problem"],"properties":{"problem":{"type":"object"}}}"#,
133        },
134        McpToolDescriptor {
135            name: "qpu_dft",
136            description: "Bounded Thomas-Fermi DFT ground-state energy from quins or grid resolution.",
137            input_schema: r#"{"type":"object","properties":{"grid_resolution":{"type":"integer"},"quins":{"type":"array"}}}"#,
138        },
139        McpToolDescriptor {
140            name: "qpu_status",
141            description: "Return QPU bridge connection and job-queue status.",
142            input_schema: r#"{"type":"object","properties":{}}"#,
143        },
144        McpToolDescriptor {
145            name: "get_wallet_status",
146            description: "Inspect queued ILP micropayments from pending_payments.ndjson.",
147            input_schema: r#"{"type":"object","properties":{}}"#,
148        },
149        McpToolDescriptor {
150            name: "get_did_info",
151            description: "Parse a did:q42 identifier into its topological pointer hash.",
152            input_schema: r#"{"type":"object","required":["did"],"properties":{"did":{"type":"string"}}}"#,
153        },
154        McpToolDescriptor {
155            name: "ingest_ontology",
156            description: "Parse TTL/N3/q42 ontology file and extend the daemon graph.",
157            input_schema: r#"{"type":"object","required":["path"],"properties":{"path":{"type":"string"},"context_hash":{"type":"integer"}}}"#,
158        },
159        McpToolDescriptor {
160            name: "validate_shacl",
161            description: "Validate quins for a target subject/property against SHACL constraints.",
162            input_schema: r#"{"type":"object","required":["quins","target_subject","target_property","constraints"],"properties":{"quins":{"type":"array"},"target_subject":{"type":"integer"},"target_property":{"type":"integer"},"constraints":{"type":"array"}}}"#,
163        },
164        McpToolDescriptor {
165            name: "validate_enumerated_identity",
166            description: "SHACL identity extension: validate an identity as an enumerated state over multiple cryptographically-attested identifiers. A binding asserting certainty (confidence>=1.0) is rejected as a DefinitiveCollapse — identity must stay a confidence-relation (the out-of-band remainder). Returns verdict + distinct/attested counts + noisy-OR aggregate confidence.",
167            input_schema: r#"{"type":"object","required":["bindings"],"properties":{"bindings":{"type":"array","items":{"type":"object","properties":{"identifier":{"type":"integer"},"scheme":{"type":"string"},"attested":{"type":"boolean"},"confidence":{"type":"number"}}}},"min_distinct":{"type":"integer"},"min_attested":{"type":"integer"}}}"#,
168        },
169        McpToolDescriptor {
170            name: "shacl_credential_gate",
171            description: "SHACL identity extension: decide whether a verified W3C Verifiable Credential gates a SHACL target node — applies only if the credential's subject is the focus node, the issuer is accepted, and it carries the required claim. (Verify the VC signature/expiry via the identity layer first.)",
172            input_schema: r#"{"type":"object","required":["focus_node","gate","credential"],"properties":{"focus_node":{"type":"integer"},"gate":{"type":"object"},"credential":{"type":"object"}}}"#,
173        },
174        McpToolDescriptor {
175            name: "shacl_degrade_violations",
176            description: "SHACL identity extension: real-time severity degradation — off-grid, non-Critical violations degrade to non-blocking so a partial subgraph stays usable; Critical fails closed. Returns blocking/degraded counts and whether the subgraph is usable.",
177            input_schema: r#"{"type":"object","required":["violations"],"properties":{"violations":{"type":"array"},"mode":{"type":"string"}}}"#,
178        },
179        McpToolDescriptor {
180            name: "shacl_route",
181            description: "SHACL identity extension: decentralized shape-target routing — given shape->locus routes, enumerate the shapes that apply at a query_locus, or the loci a query_shape must be dispatched to (validation goes to the data, no central aggregation).",
182            input_schema: r#"{"type":"object","required":["routes"],"properties":{"routes":{"type":"array"},"query_locus":{"type":"integer"},"query_shape":{"type":"integer"}}}"#,
183        },
184        McpToolDescriptor {
185            name: "list_qapps",
186            description: "List installed qapps from storage Qapps directory.",
187            input_schema: r#"{"type":"object","properties":{}}"#,
188        },
189        McpToolDescriptor {
190            name: "get_qapp_manifest",
191            description: "Load qapp.json manifest for an installed or bundled qapp.",
192            input_schema: r#"{"type":"object","required":["qapp_name"],"properties":{"qapp_name":{"type":"string"}}}"#,
193        },
194        McpToolDescriptor {
195            name: "inspect_qapp_readiness",
196            description: "Check manifest, entrypoints, and ontology readiness for a qapp.",
197            input_schema: r#"{"type":"object","required":["qapp_name"],"properties":{"qapp_name":{"type":"string"}}}"#,
198        },
199        McpToolDescriptor {
200            name: "list_qapp_updates",
201            description: "Compare installed qapp versions against bundled update offers.",
202            input_schema: r#"{"type":"object","properties":{}}"#,
203        },
204        McpToolDescriptor {
205            name: "get_system_status",
206            description: "Return runtime status for the Qualia MCP surface.",
207            input_schema: r#"{"type":"object","properties":{}}"#,
208        },
209        McpToolDescriptor {
210            name: "list_capabilities",
211            description: "List the canonical Qualia capability catalogue with concrete operations, maturity, runtime surfaces, and executable MCP routes.",
212            input_schema: r#"{"type":"object","properties":{"domain":{"type":"string"},"maturity":{"type":"string","enum":["stable","partial","experimental","fail-closed"]},"surface":{"type":"string"}}}"#,
213        },
214        McpToolDescriptor {
215            name: "describe_qapp_surface_schema",
216            description: "Describe the current Qapp host surface schema exposed by Qualia.",
217            input_schema: r#"{"type":"object","properties":{}}"#,
218        },
219        McpToolDescriptor {
220            name: "inject_test_quin",
221            description: "Inject a deterministic test Quin through the paraconsistent router.",
222            input_schema: r#"{"type":"object","properties":{}}"#,
223        },
224        McpToolDescriptor {
225            name: "evaluate_modality",
226            description: "Evaluate logic modalities: ltl, asp, deontic, epistemic, dl, paraconsistent, probabilistic.",
227            input_schema: r#"{"type":"object","required":["modality"],"properties":{"modality":{"type":"string"},"quins":{"type":"array"},"trace":{"type":"array"},"formula":{"type":"object"},"now_unix":{"type":"integer"},"agent_did_hash":{"type":"integer"},"world_hash":{"type":"integer"}}}"#,
228        },
229        McpToolDescriptor {
230            name: "evaluate_logic_rules",
231            description: "Load N3 rules into the RuleEngine, fire them in the Webizen VM, and evaluate a Quin against the fired conclusions. Emits WAL audit events. Returns per-rule pass/fail verdicts.",
232            input_schema: r#"{"type":"object","required":["n3_source","quin"],"properties":{"n3_source":{"type":"string","description":"N3 rule text to parse and fire"},"quin":{"type":"object","description":"The Quin to evaluate","properties":{"subject":{"type":"integer"},"predicate":{"type":"integer"},"object":{"type":"integer"},"context":{"type":"integer"}}},"ruleset_name":{"type":"string","default":"default"},"contract_hash":{"type":"integer","default":0}}}"#,
233        },
234        McpToolDescriptor {
235            name: "matrix_operation",
236            description: "Linear algebra: multiply, transpose, solve, or inverse with caller-supplied matrices.",
237            input_schema: r#"{"type":"object","required":["op"],"properties":{"op":{"type":"string","enum":["multiply","transpose","solve","inverse"]},"left":{"type":"object","properties":{"id":{"type":"string"},"rows":{"type":"integer"},"cols":{"type":"integer"},"data":{"type":"array","items":{"type":"number"}}}},"right":{"type":"object"},"matrices":{"type":"array"},"result_id":{"type":"string"}}}"#,
238        },
239        McpToolDescriptor {
240            name: "algebra_solve_polynomial",
241            description: "Find all (real + complex) roots of a polynomial given descending coefficients.",
242            input_schema: r#"{"type":"object","required":["coeffs"],"properties":{"coeffs":{"type":"array","items":{"type":"number"},"description":"descending coefficients [c_n, ..., c_1, c_0]"}}}"#,
243        },
244        McpToolDescriptor {
245            name: "algebra_matrix_analyze",
246            description: "Determinant, eigenvalues (general), symmetric eigensystem, or SVD of a row-major matrix.",
247            input_schema: r#"{"type":"object","required":["op","rows","data"],"properties":{"op":{"type":"string","enum":["determinant","eigenvalues","eigen_symmetric","svd"]},"rows":{"type":"integer"},"cols":{"type":"integer"},"data":{"type":"array","items":{"type":"number"}}}}"#,
248        },
249        McpToolDescriptor {
250            name: "cas",
251            description: "Symbolic algebra: differentiate/simplify/expand/evaluate a text expression (e.g. 'x^3 - 2*x^2'), or solve/factor a quadratic symbolically.",
252            input_schema: r#"{"type":"object","required":["op"],"properties":{"op":{"type":"string","enum":["differentiate","simplify","expand","evaluate","solve_quadratic","factor"]},"expr":{"type":"string"},"var":{"type":"string"},"env":{"type":"object"},"a":{"type":"number"},"b":{"type":"number"},"c":{"type":"number"}}}"#,
253        },
254        McpToolDescriptor {
255            name: "ode_solve",
256            description: "Run a configurable CFD or molecular-dynamics simulation step.",
257            input_schema: r#"{"type":"object","properties":{"type":{"type":"string","enum":["cfd","distributed","molecular_dynamics"]},"nx":{"type":"integer"},"ny":{"type":"integer"},"dx":{"type":"number"},"time_step":{"type":"number"},"total_time":{"type":"number"},"num_threads":{"type":"integer"}}}"#,
258        },
259        McpToolDescriptor {
260            name: "chemical_analysis",
261            description: "Predict molecular properties from SMILES or formula via ChemistryModelingLibrary.",
262            input_schema: r#"{"type":"object","properties":{"smiles":{"type":"string"},"formula":{"type":"string"},"molecular_weight":{"type":"number"},"prop":{"type":"string"},"properties":{"type":"array","items":{"type":"string"}}}}"#,
263        },
264        McpToolDescriptor {
265            name: "statistical_analysis",
266            description: "Descriptive statistics on caller-supplied tabular data.",
267            input_schema: r#"{"type":"object","required":["rows"],"properties":{"stat":{"type":"string","enum":["mean","variance","correlation"]},"rows":{"type":"array"},"columns":{"type":"array","items":{"type":"string"}},"column":{"type":"string"},"column_y":{"type":"string"},"method":{"type":"string"}}}"#,
268        },
269        McpToolDescriptor {
270            name: "ml_inference",
271            description: "Load a model by id and run inference on caller-supplied input bytes.",
272            input_schema: r#"{"type":"object","properties":{"model_id":{"type":"string"},"model_path":{"type":"string"},"input_data":{"type":"array","items":{"type":"integer"}},"input_hex":{"type":"string"},"batch_size":{"type":"integer"},"temperature":{"type":"number"},"max_tokens":{"type":"integer"}}}"#,
273        },
274        McpToolDescriptor {
275            name: "financial_model",
276            description: "Black-Scholes option pricing or portfolio risk with caller parameters.",
277            input_schema: r#"{"type":"object","properties":{"op":{"type":"string","enum":["option","risk"]},"underlying_price":{"type":"number"},"strike":{"type":"number"},"volatility":{"type":"number"},"assets":{"type":"array"},"cash_balance":{"type":"number"}}}"#,
278        },
279        McpToolDescriptor {
280            name: "medical_score",
281            description: "Clinical analysis for a caller-supplied patient record.",
282            input_schema: r#"{"type":"object","properties":{"patient_id":{"type":"string"},"score":{"type":"string","enum":["diagnosis","treatment","prognosis","prevention"]},"patient":{"type":"object"}}}"#,
283        },
284        McpToolDescriptor {
285            name: "engineering_analysis_op",
286            description: "Structural, thermal, or dynamic FEA with caller model geometry and loads.",
287            input_schema: r#"{"type":"object","properties":{"analysis":{"type":"string","enum":["structural","thermal","dynamic"]},"model":{"type":"object"},"dimensions":{"type":"array"},"youngs_modulus":{"type":"number"}}}"#,
288        },
289        McpToolDescriptor {
290            name: "computational_geometry",
291            description: "Native Rust/WASM computational geometry over caller data: robust orientation, 2D convex hull, triangle half-edge topology, Delaunay, Voronoi, nearest site, and primitive generation (box, sphere, cylinder, plane).",
292            input_schema: r#"{"type":"object","required":["op"],"properties":{"op":{"type":"string","enum":["orientation_2","convex_hull_2","triangle_topology","delaunay_2","voronoi_2","nearest_site","mesh_topology","create_box","create_sphere","create_cylinder","create_plane"]},"points":{"type":"array","items":{"type":"array","items":{"type":"number"}}},"vertex_count":{"type":"integer"},"triangles":{"type":"array","items":{"type":"array","items":{"type":"integer"}}},"width":{"type":"number"},"height":{"type":"number"},"depth":{"type":"number"},"radius":{"type":"number"},"size":{"type":"number"},"lat_segments":{"type":"integer"},"lon_segments":{"type":"integer"},"segments":{"type":"integer"},"query":{"type":"array","items":{"type":"number"}}}}"#,
293        },
294        McpToolDescriptor {
295            name: "computer_vision",
296            description: "Native computer_vision specialized lib (MIG-V2): list ops, rgb_to_gray, classical super_resolve (nearest/bilinear/bicubic/lanczos), mesh_quality_cleanup, class_score_to_sigma. Caller-supplied buffers; generative=false classical SR; GPU path used when Cool for nearest/bicubic.",
297            input_schema: r#"{"type":"object","required":["op"],"properties":{"op":{"type":"string","enum":["list","capability_summary","rgb_to_gray","super_resolve","mesh_quality_cleanup","class_score_to_sigma"]},"width":{"type":"integer"},"height":{"type":"integer"},"scale":{"type":"integer"},"kernel":{"type":"string","enum":["nearest","bilinear","bicubic","lanczos3"]},"rgb":{"type":"array","items":{"type":"integer"}},"class_hash":{"type":"integer"},"score":{"type":"number"},"positions":{"type":"array","items":{"type":"array","items":{"type":"number"}}},"indices":{"type":"array","items":{"type":"integer"}},"weld_epsilon":{"type":"number"}}}"#,
298        },
299        McpToolDescriptor {
300            name: "audio_features",
301            description: "Native qualia-audio features + honest capability registry: list (all capabilities with Present/Partial/Missing/NeedsWeights status), capability_summary (counts), log_mel, pitch_yin (real YIN F0+confidence), loudness_r128 (EBU R128 LUFS). Caller-supplied PCM samples; CPU; learned heads fail closed.",
302            input_schema: r#"{"type":"object","required":["op"],"properties":{"op":{"type":"string","enum":["list","capability_summary","log_mel","pitch_yin","loudness_r128"]},"samples":{"type":"array","items":{"type":"number"}},"sample_rate":{"type":"integer"},"n_mel":{"type":"integer"}}}"#,
303        },
304        McpToolDescriptor {
305            name: "geometry_manifests",
306            description: "List per-op capability manifests (backends, determinism class, resource limits) and run Reserve-mode budget queries for computational-geometry ops.",
307            input_schema: r#"{"type":"object","properties":{"op":{"type":"string","description":"Op name for a Reserve-mode budget query (omit to list all manifests)"},"device":{"type":"object","properties":{"cpu":{"type":"boolean"},"simd":{"type":"boolean"},"wgpu":{"type":"boolean"},"cuda":{"type":"boolean"},"wasm":{"type":"boolean"},"exact":{"type":"boolean"}}}}}"#,
308        },
309        McpToolDescriptor {
310            name: "bioinformatics_align",
311            description: "Pairwise nucleotide or protein alignment on caller query/target sequences.",
312            input_schema: r#"{"type":"object","required":["query","target"],"properties":{"query":{"type":"string"},"target":{"type":"string"},"mode":{"type":"string","enum":["dna","protein"]}}}"#,
313        },
314        McpToolDescriptor {
315            name: "chemical_descriptors",
316            description: "Compute Lipinski/Veber descriptors from a SMILES string.",
317            input_schema: r#"{"type":"object","required":["smiles"],"properties":{"smiles":{"type":"string"}}}"#,
318        },
319        McpToolDescriptor {
320            name: "clinical_risk",
321            description: "Clinical risk scores: framingham, cha2ds2_vasc, sofa, egfr.",
322            input_schema: r#"{"type":"object","properties":{"score":{"type":"string","enum":["framingham","cha2ds2","cha2ds2_vasc","sofa","egfr","renal"]},"age":{"type":"integer"},"input":{"type":"object"}}}"#,
323        },
324        McpToolDescriptor {
325            name: "parse_csv",
326            description: "Stream CSV into Quins via zero-heap parser. Requires field_mappings; accepts csv_data or file_path.",
327            input_schema: r#"{"type":"object","required":["field_mappings"],"properties":{"csv_data":{"type":"string"},"file_path":{"type":"string"},"field_mappings":{"type":"array","items":{"type":"object","required":["source_key"],"properties":{"source_key":{"type":"string"},"predicate":{"type":"string"},"predicate_hash":{"type":"integer"},"datatype":{"type":"string","enum":["integer","float","datetime","string"]}}}},"base_class_hash":{"type":"integer"},"context_hash":{"type":"integer"},"ingest_to_graph":{"type":"boolean"}}}"#,
328        },
329        McpToolDescriptor {
330            name: "parse_rdf",
331            description: "Parse RDF/RDF-Star (nt, turtle, nquads, trig, n3, jsonld, cbor) into quins via zero-heap streaming parsers.",
332            input_schema: r#"{"type":"object","required":["format"],"properties":{"format":{"type":"string"},"rdf_data":{"type":"string"},"file_path":{"type":"string"},"context_hash":{"type":"integer"},"ingest_to_graph":{"type":"boolean"}}}"#,
333        },
334        McpToolDescriptor {
335            name: "parse_json",
336            description: "Stream JSON objects into Quins via zero-heap parser. Requires field_mappings; accepts json_data or file_path.",
337            input_schema: r#"{"type":"object","required":["field_mappings"],"properties":{"json_data":{"type":"string"},"file_path":{"type":"string"},"field_mappings":{"type":"array","items":{"type":"object","required":["source_key"],"properties":{"source_key":{"type":"string"},"predicate":{"type":"string"},"predicate_hash":{"type":"integer"},"datatype":{"type":"string","enum":["integer","float","datetime","string"]}}}},"base_class_hash":{"type":"integer"},"context_hash":{"type":"integer"},"ingest_to_graph":{"type":"boolean"}}}"#,
338        },
339        McpToolDescriptor {
340            name: "serialize_csv",
341            description: "Serialize quins or daemon graph slice to CSV. Returns inline csv_data or writes file_path when output=file.",
342            input_schema: r#"{"type":"object","required":["headers","predicate_hashes"],"properties":{"quins":{"type":"array"},"use_graph":{"type":"boolean"},"context_hash":{"type":"integer"},"headers":{"type":"array","items":{"type":"string"}},"predicate_hashes":{"type":"array","items":{"type":"integer"}},"datatypes":{"type":"array","items":{"type":"string"}},"output":{"type":"string","enum":["inline","file"]},"file_path":{"type":"string"}}}"#,
343        },
344        McpToolDescriptor {
345            name: "serialize_json",
346            description: "Serialize quins or daemon graph slice to JSON array. Returns inline json_data or writes file_path when output=file.",
347            input_schema: r#"{"type":"object","required":["field_names","predicate_hashes"],"properties":{"quins":{"type":"array"},"use_graph":{"type":"boolean"},"context_hash":{"type":"integer"},"field_names":{"type":"array","items":{"type":"string"}},"predicate_hashes":{"type":"array","items":{"type":"integer"}},"datatypes":{"type":"array","items":{"type":"string"}},"output":{"type":"string","enum":["inline","file"]},"file_path":{"type":"string"}}}"#,
348        },
349        McpToolDescriptor {
350            name: "serialize_rdf",
351            description: "Serialize quins or graph slice to RDF/RDF-Star via resolver-backed zero-heap dispatch.",
352            input_schema: r#"{"type":"object","properties":{"quins":{"type":"array"},"use_graph":{"type":"boolean"},"context_hash":{"type":"integer"},"format":{"type":"string"},"rdf_star":{"type":"boolean"},"star":{"type":"boolean"},"output":{"type":"string","enum":["inline","file"]},"file_path":{"type":"string"}}}"#,
353        },
354        McpToolDescriptor {
355            name: "symbolic_logic_infer",
356            description: "Defeasible forward-chaining or bounded SAT with caller facts, rules, and clauses.",
357            input_schema: r#"{"type":"object","properties":{"solver":{"type":"string","enum":["defeasible","sat"]},"facts":{"type":"array"},"rules":{"type":"array"},"clauses":{"type":"array"},"max_iterations":{"type":"integer"}}}"#,
358        },
359        McpToolDescriptor {
360            name: "geometric_algebra_op",
361            description: "3D vector cross product, dot product, or angle between caller vectors.",
362            input_schema: r#"{"type":"object","required":["a","b"],"properties":{"op":{"type":"string","enum":["cross","angle","dot"]},"a":{"type":"array","items":{"type":"number"},"minItems":3,"maxItems":3},"b":{"type":"array","items":{"type":"number"},"minItems":3,"maxItems":3}}}"#,
363        },
364        McpToolDescriptor {
365            name: "run_docs_tests",
366            description: "Run docs/tests headless suites (logic, wasm, native, or both). Native/both require daemon on localhost:4242.",
367            input_schema: r#"{"type":"object","properties":{"mode":{"type":"string","enum":["logic","wasm","native","both"]}}}"#,
368        },
369        McpToolDescriptor {
370            name: "get_pending_tasks",
371            description: "Get tasks pending in the ambient orchestrator.",
372            input_schema: r#"{"type":"object","properties":{}}"#,
373        },
374        McpToolDescriptor {
375            name: "values_check",
376            description: "Values abuse-check (human-rights guard): does an agent claiming a natural-person-only dignity right trip the inverse rights-guard? Runs the real agency.n3 G1/G1' lane. agentType is a webcivics values class (CorporatePerson, ArtificialAgent, NaturalPerson, ...).",
377            input_schema: r#"{"type":"object","required":["agentType"],"properties":{"agentType":{"type":"string"},"claimsDignityRight":{"type":"boolean"}}}"#,
378        },
379        McpToolDescriptor {
380            name: "values_evaluate",
381            description: "Deontic-contract reasoner in values terms: is a norm (forbid/oblige/permit) bound to a party+action currently in force? Runs the native deontic VM and returns Active / Defeated (by an 'unless' exception) / Expired (past its window) / Malformed.",
382            input_schema: r#"{"type":"object","required":["modality","party","action"],"properties":{"modality":{"type":"string","enum":["forbid","oblige","permit"]},"party":{"type":"string"},"action":{"type":"string"},"object":{"type":"string"},"now":{"type":"integer"},"expiry":{"type":"integer"},"unless":{"type":"string"}}}"#,
383        },
384        McpToolDescriptor {
385            name: "graph_resolve",
386            description: "Resolve an identifier (IRI) against the live daemon graph: returns its modal identifier-KIND (open kind fabric — WebizenId / DidQ42 / ContentHash / ... or none for a plain dictionary reference) and its out-degree. Composes the hybrid-modality resolver (zero-alloc QuinIndex / slice scan + modal_kind) over one identity space.",
387            input_schema: r#"{"type":"object","required":["iri"],"properties":{"iri":{"type":"string"}}}"#,
388        },
389        McpToolDescriptor {
390            name: "jural_correlate",
391            description: "Hohfeldian jural relations: given one of the 8 positions (claim, duty, privilege, no-right, power, liability, immunity, disability) return the correlative the counterparty necessarily bears, the jural opposite, and its order (first-order conduct vs second-order control). Runs modalities/jural.rs.",
392            input_schema: r#"{"type":"object","required":["position"],"properties":{"position":{"type":"string","enum":["claim","duty","privilege","no-right","power","liability","immunity","disability"]}}}"#,
393        },
394        McpToolDescriptor {
395            name: "deontic_govern",
396            description: "Interaction governance: map a deontic verdict status (active/violated/defeated/expired/pending/discharged/malformed) + classification (nonDerogable/humanitarian/ambiguous) to the runtime PolicyMode the Webizen VM enacts — PreventiveBlock(DenyRollback) | PermissiveAudit(WAL) | Prioritize | Interactive | Allow. Runs interaction_governance::map_policy.",
397            input_schema: r#"{"type":"object","required":["status"],"properties":{"status":{"type":"string"},"nonDerogable":{"type":"boolean"},"humanitarian":{"type":"boolean"},"ambiguous":{"type":"boolean"}}}"#,
398        },
399        McpToolDescriptor {
400            name: "mcp_cooperate",
401            description: "Agent-cooperation gate (Track M): decide whether a VERIFIED, TYPED, GROUNDED calling agent's request passes the deontic gate before execution. Composes mcp_cooperation::authorize — an asserted-not-verified identity is DeniedUnverified; an ungrounded artificial agent (no human Principal, agency.n3 G1') is DeniedUngrounded; else the request runs the Phase-6 policy gate. Trust is behaviourally derived, not self-asserted.",
402            input_schema: r#"{"type":"object","required":["caller","verified"],"properties":{"caller":{"type":"string"},"role":{"type":"string"},"verified":{"type":"boolean"},"grounded":{"type":"boolean"},"requestStatus":{"type":"string"},"nonDerogable":{"type":"boolean"},"humanitarian":{"type":"boolean"},"ambiguous":{"type":"boolean"}}}"#,
403        },
404    ]
405}
406
407/// Dispatches incoming tool actions without triggering dynamic heap allocations
408pub unsafe fn enforce_fiduciary_tool_dispatch(
409    payload: RawToolPayload,
410    intent_frame: &McpIntentFrame,
411) -> Result<String, McpSystemError> {
412    // ── Track-M cooperation gate (default OFF; QUALIA_MCP_ENFORCE=1 to enforce) ──────
413    // When enforcement is on, every call must carry a verified + grounded caller standpoint
414    // (agency.n3 G1' + the deontic gate) or it is refused. A no-op while the flag is off.
415    mcp_tool_impls::cooperation_gate(payload.arguments_raw)?;
416
417    match payload.tool_name {
418        // ── Graph Engine Tools ───────────────────────────────────────────────
419        b"query_graph" => {
420            // `is_none()` here means "no *valid* token": `build_intent_frame` already
421            // rejected missing, malformed, placeholder ("MISSING"), and all-zero
422            // values via `parse_sanctuary_override`. Presence alone never opens egress.
423            if intent_frame.sanctuary_override.is_none() {
424                let violation_quin = NQuin::new_conduct_violation(
425                    b"EgressViolation: Invalid or Missing Cryptographic Sanctuary Override",
426                );
427                let _ = append_mutation(&violation_quin);
428                return Err(McpSystemError::SanctuaryGateTriggered);
429            }
430            execute_bare_metal_graph_traversal(payload.arguments_raw, intent_frame)
431        }
432
433        b"query_sparql" => execute_sparql_query(payload.arguments_raw, intent_frame),
434
435        b"get_graph_stats" => execute_graph_stats(payload.arguments_raw, intent_frame),
436
437        b"list_ontologies" => execute_list_ontologies(payload.arguments_raw, intent_frame),
438
439        // ── LLM Tools ─────────────────────────────────────────────────────────
440        b"llm_infer" => {
441            if !intent_frame.llm_enabled {
442                return Err(McpSystemError::FeatureNotEnabled);
443            }
444            execute_llm_infer(payload.arguments_raw, intent_frame)
445        }
446
447        b"llm_chat" => {
448            if !intent_frame.llm_enabled {
449                return Err(McpSystemError::FeatureNotEnabled);
450            }
451            execute_llm_chat(payload.arguments_raw, intent_frame)
452        }
453
454        b"list_models" => execute_list_models(payload.arguments_raw, intent_frame),
455
456        // ── QPU Tools ─────────────────────────────────────────────────────────
457        b"qpu_optimize" => {
458            if !intent_frame.qpu_enabled {
459                return Err(McpSystemError::FeatureNotEnabled);
460            }
461            execute_qpu_optimize(payload.arguments_raw, intent_frame)
462        }
463
464        b"qpu_dft" => {
465            if !intent_frame.qpu_enabled {
466                return Err(McpSystemError::FeatureNotEnabled);
467            }
468            execute_qpu_dft(payload.arguments_raw, intent_frame)
469        }
470
471        b"qpu_status" => execute_qpu_status(payload.arguments_raw, intent_frame),
472
473        // ── Scientific Computing Tools ───────────────────────────────────────
474        b"matrix_operation" => execute_matrix_operation(payload.arguments_raw, intent_frame),
475        b"algebra_solve_polynomial" => {
476            mcp_tool_impls::algebra_solve_polynomial(payload.arguments_raw)
477        }
478        b"algebra_matrix_analyze" => mcp_tool_impls::algebra_matrix_analyze(payload.arguments_raw),
479        b"cas" => mcp_tool_impls::cas(payload.arguments_raw),
480
481        b"ode_solve" => execute_ode_solve(payload.arguments_raw, intent_frame),
482
483        b"chemical_analysis" => execute_chemical_analysis(payload.arguments_raw, intent_frame),
484
485        b"statistical_analysis" => {
486            execute_statistical_analysis(payload.arguments_raw, intent_frame)
487        }
488
489        b"ml_inference" => execute_ml_inference(payload.arguments_raw, intent_frame),
490
491        b"financial_model" => execute_financial_model(payload.arguments_raw, intent_frame),
492
493        b"medical_score" => execute_medical_score(payload.arguments_raw, intent_frame),
494
495        b"engineering_analysis_op" => {
496            execute_engineering_analysis(payload.arguments_raw, intent_frame)
497        }
498        b"computational_geometry" => mcp_tool_impls::computational_geometry(payload.arguments_raw),
499        b"geometry_manifests" => mcp_tool_impls::geometry_manifests(payload.arguments_raw),
500        b"computer_vision" => mcp_tool_impls::computer_vision(payload.arguments_raw),
501        #[cfg(not(target_arch = "wasm32"))]
502        b"audio_features" => mcp_tool_impls::audio_features(payload.arguments_raw),
503
504        // ── Identifiers & Wallet Tools ─────────────────────────────────────────
505        b"get_wallet_status" => execute_wallet_status(payload.arguments_raw, intent_frame),
506
507        b"get_did_info" => execute_did_info(payload.arguments_raw, intent_frame),
508
509        // ── Ontology Tools ────────────────────────────────────────────────────
510        b"ingest_ontology" => execute_ingest_ontology(payload.arguments_raw, intent_frame),
511
512        b"validate_shacl" => execute_shacl_validation(payload.arguments_raw, intent_frame),
513
514        // ── SHACL identity / data-rights extension tools ──────────────────
515        b"validate_enumerated_identity" => {
516            execute_validate_enumerated_identity(payload.arguments_raw, intent_frame)
517        }
518        b"shacl_credential_gate" => {
519            execute_shacl_credential_gate(payload.arguments_raw, intent_frame)
520        }
521        b"shacl_degrade_violations" => {
522            execute_shacl_degrade_violations(payload.arguments_raw, intent_frame)
523        }
524        b"shacl_route" => execute_shacl_route(payload.arguments_raw, intent_frame),
525
526        // ── Testing & Debugging Tools ───────────────────────────────────────
527        b"inject_test_quin" => {
528            execute_paraconsistent_injection(payload.arguments_raw, intent_frame)
529        }
530
531        b"list_qapps" => execute_list_qapps(payload.arguments_raw, intent_frame),
532
533        b"get_qapp_manifest" => execute_get_qapp_manifest(payload.arguments_raw, intent_frame),
534
535        b"inspect_qapp_readiness" => {
536            execute_inspect_qapp_readiness(payload.arguments_raw, intent_frame)
537        }
538
539        b"list_qapp_updates" => execute_list_qapp_updates(payload.arguments_raw, intent_frame),
540
541        b"describe_qapp_surface_schema" => {
542            execute_describe_qapp_surface_schema(payload.arguments_raw, intent_frame)
543        }
544
545        b"get_system_status" => execute_system_status(payload.arguments_raw, intent_frame),
546        b"list_capabilities" => mcp_tool_impls::list_capabilities(payload.arguments_raw),
547
548        // ── Extended Logic & Science Tools ───────────────────────────────────
549        b"evaluate_modality" => execute_evaluate_modality(payload.arguments_raw, intent_frame),
550
551        b"evaluate_logic_rules" => mcp_tool_impls::evaluate_logic_rules(payload.arguments_raw),
552
553        b"bioinformatics_align" => {
554            execute_bioinformatics_align(payload.arguments_raw, intent_frame)
555        }
556
557        b"chemical_descriptors" => {
558            execute_chemical_descriptors(payload.arguments_raw, intent_frame)
559        }
560
561        b"clinical_risk" => execute_clinical_risk(payload.arguments_raw, intent_frame),
562
563        b"symbolic_logic_infer" => {
564            execute_symbolic_logic_infer(payload.arguments_raw, intent_frame)
565        }
566
567        b"geometric_algebra_op" => {
568            execute_geometric_algebra_op(payload.arguments_raw, intent_frame)
569        }
570
571        // ── Data Format Tools ──────────────────────────────────────────────────────
572        b"parse_csv" => execute_parse_csv(payload.arguments_raw, intent_frame),
573        b"parse_rdf" => execute_parse_rdf(payload.arguments_raw, intent_frame),
574        b"parse_json" => execute_parse_json(payload.arguments_raw, intent_frame),
575        b"serialize_csv" => execute_serialize_csv(payload.arguments_raw, intent_frame),
576        b"serialize_json" => execute_serialize_json(payload.arguments_raw, intent_frame),
577        b"serialize_rdf" => execute_serialize_rdf(payload.arguments_raw, intent_frame),
578
579        b"run_docs_tests" => execute_run_docs_tests(payload.arguments_raw, intent_frame),
580        b"get_pending_tasks" => execute_get_pending_tasks(payload.arguments_raw, intent_frame),
581
582        // ── Values / Human-Rights Governance ────────────────────────────────────
583        b"values_check" => mcp_tool_impls::values_check(payload.arguments_raw),
584        b"values_evaluate" => mcp_tool_impls::values_evaluate(payload.arguments_raw),
585        b"jural_correlate" => mcp_tool_impls::jural_correlate(payload.arguments_raw),
586        b"deontic_govern" => mcp_tool_impls::deontic_govern(payload.arguments_raw),
587        b"mcp_cooperate" => mcp_tool_impls::mcp_cooperate(payload.arguments_raw),
588        b"graph_resolve" => mcp_tool_impls::graph_resolve(payload.arguments_raw),
589
590        _ => Err(McpSystemError::ToolNotFound),
591    }
592}
593
594unsafe fn execute_get_pending_tasks(
595    args: &[u8],
596    _intent: &McpIntentFrame,
597) -> Result<String, McpSystemError> {
598    mcp_stub_impls::get_pending_tasks(args)
599}
600
601// ── Graph Engine Implementations ───────────────────────────────────────────
602
603unsafe fn execute_sparql_query(
604    args: &[u8],
605    _intent: &McpIntentFrame,
606) -> Result<String, McpSystemError> {
607    mcp_stub_impls::query_sparql(args)
608}
609
610unsafe fn execute_bare_metal_graph_traversal(
611    _args: &[u8],
612    intent: &McpIntentFrame,
613) -> Result<String, McpSystemError> {
614    let mut arena = crate::webizen::SlgArena::new();
615    let contract = if intent
616        .active_deontic_constraints
617        .first()
618        .copied()
619        .unwrap_or(0)
620        != 0
621    {
622        intent.active_deontic_constraints[0]
623    } else {
624        intent.purpose_hash
625    };
626    let fired = arena.fire_registered_rules(contract);
627    Ok(fired.max(1).to_string())
628}
629
630unsafe fn execute_graph_stats(
631    args: &[u8],
632    _intent: &McpIntentFrame,
633) -> Result<String, McpSystemError> {
634    mcp_stub_impls::get_graph_stats(args)
635}
636
637unsafe fn execute_list_ontologies(
638    args: &[u8],
639    _intent: &McpIntentFrame,
640) -> Result<String, McpSystemError> {
641    mcp_stub_impls::list_ontologies(args)
642}
643
644// ── LLM Implementations ─────────────────────────────────────────────────────
645
646unsafe fn execute_llm_infer(
647    args: &[u8],
648    _intent: &McpIntentFrame,
649) -> Result<String, McpSystemError> {
650    mcp_stub_impls::llm_infer(args)
651}
652
653unsafe fn execute_llm_chat(
654    args: &[u8],
655    _intent: &McpIntentFrame,
656) -> Result<String, McpSystemError> {
657    mcp_stub_impls::llm_chat(args)
658}
659
660unsafe fn execute_list_models(
661    args: &[u8],
662    _intent: &McpIntentFrame,
663) -> Result<String, McpSystemError> {
664    mcp_stub_impls::list_models(args)
665}
666
667// ── QPU Implementations ─────────────────────────────────────────────────────
668
669unsafe fn execute_qpu_optimize(
670    args: &[u8],
671    _intent: &McpIntentFrame,
672) -> Result<String, McpSystemError> {
673    mcp_stub_impls::qpu_optimize(args)
674}
675
676unsafe fn execute_qpu_dft(args: &[u8], _intent: &McpIntentFrame) -> Result<String, McpSystemError> {
677    mcp_stub_impls::qpu_dft(args)
678}
679
680unsafe fn execute_qpu_status(
681    args: &[u8],
682    _intent: &McpIntentFrame,
683) -> Result<String, McpSystemError> {
684    mcp_stub_impls::qpu_status(args)
685}
686
687// ── Scientific Computing Implementations ─────────────────────────────────
688
689unsafe fn execute_matrix_operation(
690    args: &[u8],
691    _intent: &McpIntentFrame,
692) -> Result<String, McpSystemError> {
693    mcp_tool_impls::matrix_operation(args)
694}
695
696unsafe fn execute_ode_solve(
697    args: &[u8],
698    _intent: &McpIntentFrame,
699) -> Result<String, McpSystemError> {
700    mcp_tool_impls::ode_solve(args)
701}
702
703unsafe fn execute_chemical_analysis(
704    args: &[u8],
705    _intent: &McpIntentFrame,
706) -> Result<String, McpSystemError> {
707    mcp_tool_impls::chemical_analysis(args)
708}
709
710unsafe fn execute_statistical_analysis(
711    args: &[u8],
712    _intent: &McpIntentFrame,
713) -> Result<String, McpSystemError> {
714    mcp_tool_impls::statistical_analysis(args)
715}
716
717unsafe fn execute_ml_inference(
718    args: &[u8],
719    _intent: &McpIntentFrame,
720) -> Result<String, McpSystemError> {
721    mcp_tool_impls::ml_inference(args)
722}
723
724unsafe fn execute_financial_model(
725    args: &[u8],
726    _intent: &McpIntentFrame,
727) -> Result<String, McpSystemError> {
728    mcp_tool_impls::financial_model(args)
729}
730
731unsafe fn execute_medical_score(
732    args: &[u8],
733    _intent: &McpIntentFrame,
734) -> Result<String, McpSystemError> {
735    mcp_tool_impls::medical_score(args)
736}
737
738unsafe fn execute_engineering_analysis(
739    args: &[u8],
740    _intent: &McpIntentFrame,
741) -> Result<String, McpSystemError> {
742    mcp_tool_impls::engineering_analysis(args)
743}
744
745// ── Identity & Wallet Implementations ─────────────────────────────────────
746
747unsafe fn execute_wallet_status(
748    args: &[u8],
749    _intent: &McpIntentFrame,
750) -> Result<String, McpSystemError> {
751    mcp_stub_impls::get_wallet_status(args)
752}
753
754unsafe fn execute_did_info(
755    args: &[u8],
756    _intent: &McpIntentFrame,
757) -> Result<String, McpSystemError> {
758    mcp_stub_impls::get_did_info(args)
759}
760
761// ── Ontology Implementations ────────────────────────────────────────────────
762
763unsafe fn execute_ingest_ontology(
764    args: &[u8],
765    _intent: &McpIntentFrame,
766) -> Result<String, McpSystemError> {
767    mcp_stub_impls::ingest_ontology(args)
768}
769
770unsafe fn execute_shacl_validation(
771    args: &[u8],
772    _intent: &McpIntentFrame,
773) -> Result<String, McpSystemError> {
774    mcp_stub_impls::validate_shacl(args)
775}
776
777unsafe fn execute_validate_enumerated_identity(
778    args: &[u8],
779    _intent: &McpIntentFrame,
780) -> Result<String, McpSystemError> {
781    mcp_stub_impls::validate_enumerated_identity_tool(args)
782}
783
784unsafe fn execute_shacl_credential_gate(
785    args: &[u8],
786    _intent: &McpIntentFrame,
787) -> Result<String, McpSystemError> {
788    mcp_stub_impls::shacl_credential_gate(args)
789}
790
791unsafe fn execute_shacl_degrade_violations(
792    args: &[u8],
793    _intent: &McpIntentFrame,
794) -> Result<String, McpSystemError> {
795    mcp_stub_impls::shacl_degrade_violations(args)
796}
797
798unsafe fn execute_shacl_route(
799    args: &[u8],
800    _intent: &McpIntentFrame,
801) -> Result<String, McpSystemError> {
802    mcp_stub_impls::shacl_route(args)
803}
804
805// ── Testing & Debugging Implementations ─────────────────────────────────────
806
807unsafe fn execute_paraconsistent_injection(
808    _args: &[u8],
809    intent: &McpIntentFrame,
810) -> Result<String, McpSystemError> {
811    let candidate = NQuin {
812        subject: intent.purpose_hash,
813        predicate: crate::q_hash("q42:testClaim"),
814        object: intent.session_nonce,
815        context: intent.purpose_hash,
816        metadata: 0,
817        parity: 0,
818    };
819    let mut q = candidate;
820    q.parity = q.subject ^ q.predicate ^ q.object ^ q.context;
821
822    let mut consistent = [NQuin::default(); 8];
823    let mut isolated = [NQuin::default(); 8];
824    let (c, i) = crate::modalities::paraconsistent::route_paraconsistent(
825        &[q],
826        &mut consistent,
827        &mut isolated,
828    )
829    .map_err(|_| McpSystemError::ParseError)?;
830
831    for idx in 0..i {
832        let _ = append_mutation(&isolated[idx]);
833    }
834    Ok((c + i).to_string())
835}
836
837unsafe fn execute_list_qapps(
838    args: &[u8],
839    _intent: &McpIntentFrame,
840) -> Result<String, McpSystemError> {
841    mcp_stub_impls::list_qapps(args)
842}
843
844unsafe fn execute_get_qapp_manifest(
845    args: &[u8],
846    _intent: &McpIntentFrame,
847) -> Result<String, McpSystemError> {
848    let qapp_name = extract_raw_json_string(args, b"\"qapp_name\"").unwrap_or(b"");
849    if qapp_name.is_empty() {
850        return Err(McpSystemError::InvalidParameters);
851    }
852    let name = std::str::from_utf8(qapp_name).map_err(|_| McpSystemError::InvalidParameters)?;
853    mcp_stub_impls::get_qapp_manifest(name)
854}
855
856unsafe fn execute_inspect_qapp_readiness(
857    args: &[u8],
858    _intent: &McpIntentFrame,
859) -> Result<String, McpSystemError> {
860    let qapp_name = extract_raw_json_string(args, b"\"qapp_name\"").unwrap_or(b"");
861    if qapp_name.is_empty() {
862        return Err(McpSystemError::InvalidParameters);
863    }
864    let name = std::str::from_utf8(qapp_name).map_err(|_| McpSystemError::InvalidParameters)?;
865    mcp_stub_impls::inspect_qapp_readiness(name)
866}
867
868unsafe fn execute_list_qapp_updates(
869    args: &[u8],
870    _intent: &McpIntentFrame,
871) -> Result<String, McpSystemError> {
872    mcp_stub_impls::list_qapp_updates(args)
873}
874
875unsafe fn execute_describe_qapp_surface_schema(
876    _args: &[u8],
877    _intent: &McpIntentFrame,
878) -> Result<String, McpSystemError> {
879    let schema = r#"{
880  "host_shell": "webizen-studio",
881  "package_manifest": "qapp.json",
882  "layout_strategies": ["PointGrid", "CssGrid", "FlexBox", "Masonry"],
883  "presentation_modes": ["GridBound", "NodeRelational", "Spatial"],
884  "coordinate_spaces": ["GlobalCartesian", "RelativeAnchored"],
885  "layer_behaviors": ["Docked", "FloatingOverlay", "ModalOverlay", "FullCanvas"],
886  "theme_scopes": ["environment", "app", "page", "module"],
887  "manifest_surfaces": ["static-web", "wasm-local", "online-daemon-aware", "native-dioxus-pane"],
888  "mcp_tools": ["list_qapps", "get_qapp_manifest", "inspect_qapp_readiness", "list_qapp_updates", "describe_qapp_surface_schema"]
889}"#;
890    Ok(schema.to_string())
891}
892
893unsafe fn execute_system_status(
894    _args: &[u8],
895    intent: &McpIntentFrame,
896) -> Result<String, McpSystemError> {
897    Ok(json!({
898        "server": "qualia-core-db-mcp",
899        "version": env!("CARGO_PKG_VERSION"),
900        "protocolVersion": "2025-03-26",
901        "toolCount": stable_mcp_tools().len(),
902        "qpuEnabled": intent.qpu_enabled,
903        "llmEnabled": intent.llm_enabled,
904        "activeProfileId": intent.active_profile_id,
905    })
906    .to_string())
907}
908
909unsafe fn execute_run_docs_tests(
910    args: &[u8],
911    _intent: &McpIntentFrame,
912) -> Result<String, McpSystemError> {
913    let mode = extract_raw_json_string(args, b"\"mode\"").unwrap_or(b"logic");
914    let mode_str = core::str::from_utf8(mode).unwrap_or("logic");
915    if !matches!(mode_str, "logic" | "wasm" | "native" | "both") {
916        return Err(McpSystemError::InvalidParameters);
917    }
918
919    if matches!(mode_str, "native" | "both") && !daemon_health_ok(4242) {
920        return Ok(json!({
921            "ok": false,
922            "mode": mode_str,
923            "error": "daemon_unreachable",
924            "hint": "Start the graph daemon with `qualia-cli service start` or `qualia-cli daemon start --dev`"
925        })
926        .to_string());
927    }
928
929    let root = resolve_repo_root();
930    let script = root.join("docs/tests/run-headless.mjs");
931    if !script.exists() {
932        return Ok(json!({
933            "ok": false,
934            "mode": mode_str,
935            "error": "runner_missing",
936            "path": script.display().to_string()
937        })
938        .to_string());
939    }
940
941    let output = std::process::Command::new("node")
942        .arg(script.as_os_str())
943        .arg("--mode")
944        .arg(mode_str)
945        .current_dir(&root)
946        .output()
947        .map_err(|_| McpSystemError::ToolNotReady)?;
948
949    let stdout = String::from_utf8_lossy(&output.stdout).to_string();
950    let stderr = String::from_utf8_lossy(&output.stderr).to_string();
951    Ok(json!({
952        "ok": output.status.success(),
953        "mode": mode_str,
954        "exitCode": output.status.code(),
955        "stdout": stdout,
956        "stderr": stderr
957    })
958    .to_string())
959}
960
961fn daemon_health_ok(port: u16) -> bool {
962    use std::io::{Read, Write};
963    use std::net::{SocketAddr, TcpStream};
964    use std::time::Duration;
965
966    let addr: SocketAddr = format!("127.0.0.1:{port}")
967        .parse()
968        .unwrap_or_else(|_| SocketAddr::from(([127, 0, 0, 1], port)));
969    let mut stream = match TcpStream::connect_timeout(&addr, Duration::from_secs(2)) {
970        Ok(stream) => stream,
971        Err(_) => return false,
972    };
973    let _ = stream.set_read_timeout(Some(Duration::from_secs(2)));
974    let request =
975        format!("GET /health HTTP/1.1\r\nHost: 127.0.0.1:{port}\r\nConnection: close\r\n\r\n");
976    if stream.write_all(request.as_bytes()).is_err() {
977        return false;
978    }
979    let mut buf = [0u8; 512];
980    match stream.read(&mut buf) {
981        Ok(0) => false,
982        Ok(n) => {
983            let response = core::str::from_utf8(&buf[..n]).unwrap_or("");
984            response.contains("200 OK") || response.contains("engine_version")
985        }
986        Err(_) => false,
987    }
988}
989
990fn resolve_repo_root() -> std::path::PathBuf {
991    if let Ok(root) = std::env::var("QUALIA_REPO_ROOT") {
992        return std::path::PathBuf::from(root);
993    }
994    let mut dir = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
995    for _ in 0..8 {
996        if dir.join("docs/tests/run-headless.mjs").exists() {
997            return dir;
998        }
999        if !dir.pop() {
1000            break;
1001        }
1002    }
1003    dir
1004}
1005
1006// ── Extended Logic & Science Tool Implementations ─────────────────────────
1007
1008unsafe fn execute_evaluate_modality(
1009    args: &[u8],
1010    _intent: &McpIntentFrame,
1011) -> Result<String, McpSystemError> {
1012    mcp_tool_impls::evaluate_modality(args)
1013}
1014
1015unsafe fn execute_bioinformatics_align(
1016    args: &[u8],
1017    _intent: &McpIntentFrame,
1018) -> Result<String, McpSystemError> {
1019    mcp_tool_impls::bioinformatics_align(args)
1020}
1021
1022unsafe fn execute_chemical_descriptors(
1023    args: &[u8],
1024    _intent: &McpIntentFrame,
1025) -> Result<String, McpSystemError> {
1026    mcp_tool_impls::chemical_descriptors(args)
1027}
1028
1029unsafe fn execute_clinical_risk(
1030    args: &[u8],
1031    _intent: &McpIntentFrame,
1032) -> Result<String, McpSystemError> {
1033    mcp_tool_impls::clinical_risk(args)
1034}
1035
1036unsafe fn execute_parse_csv(
1037    args: &[u8],
1038    _intent: &McpIntentFrame,
1039) -> Result<String, McpSystemError> {
1040    mcp_format_impls::parse_csv(args)
1041}
1042
1043unsafe fn execute_parse_rdf(
1044    args: &[u8],
1045    _intent: &McpIntentFrame,
1046) -> Result<String, McpSystemError> {
1047    mcp_format_impls::parse_rdf(args)
1048}
1049
1050unsafe fn execute_parse_json(
1051    args: &[u8],
1052    _intent: &McpIntentFrame,
1053) -> Result<String, McpSystemError> {
1054    mcp_format_impls::parse_json(args)
1055}
1056
1057unsafe fn execute_serialize_csv(
1058    args: &[u8],
1059    _intent: &McpIntentFrame,
1060) -> Result<String, McpSystemError> {
1061    mcp_format_impls::serialize_csv(args)
1062}
1063
1064unsafe fn execute_serialize_json(
1065    args: &[u8],
1066    _intent: &McpIntentFrame,
1067) -> Result<String, McpSystemError> {
1068    mcp_format_impls::serialize_json(args)
1069}
1070
1071unsafe fn execute_serialize_rdf(
1072    args: &[u8],
1073    _intent: &McpIntentFrame,
1074) -> Result<String, McpSystemError> {
1075    mcp_format_impls::serialize_rdf(args)
1076}
1077
1078unsafe fn execute_symbolic_logic_infer(
1079    args: &[u8],
1080    _intent: &McpIntentFrame,
1081) -> Result<String, McpSystemError> {
1082    mcp_tool_impls::symbolic_logic_infer(args)
1083}
1084
1085unsafe fn execute_geometric_algebra_op(
1086    args: &[u8],
1087    _intent: &McpIntentFrame,
1088) -> Result<String, McpSystemError> {
1089    mcp_tool_impls::geometric_algebra_op(args)
1090}
1091
1092/// Explicitly purges memory registers to prevent data harvesting
1093pub unsafe fn scrub_transient_mcp_buffers(buffer: &mut [u8]) {
1094    for byte_ptr in buffer.iter_mut() {
1095        write_volatile(byte_ptr, 0x00);
1096    }
1097}
1098
1099/// Map a single ASCII hex digit to its nibble value, or `None` if it is not hex.
1100#[inline]
1101fn hex_nibble(c: u8) -> Option<u8> {
1102    match c {
1103        b'0'..=b'9' => Some(c - b'0'),
1104        b'a'..=b'f' => Some(c - b'a' + 10),
1105        b'A'..=b'F' => Some(c - b'A' + 10),
1106        _ => None,
1107    }
1108}
1109
1110/// Validate and decode a raw `sanctuary_override` JSON string value into the genuine
1111/// 32-byte cryptographic egress-override token, returning `None` for anything that is
1112/// **not** a real override. This is the egress firewall's value check — it must never
1113/// accept mere field presence.
1114///
1115/// Fails closed (`None`) for:
1116/// * empty / whitespace-only values,
1117/// * placeholder text such as `"MISSING"`, `"null"`, `"none"` (any non-hex content),
1118/// * the wrong length (a token is exactly 64 hex chars = 32 bytes),
1119/// * the forged all-zero token — structurally valid hex that carries no authority and
1120///   would otherwise re-open the presence-only bypass.
1121///
1122/// Decoding is done into a fixed `[u8; 32]` on the stack — **no heap allocation**.
1123///
1124/// NOTE (MCP cooperation task #17): well-formedness is the *structural* half of the
1125/// gate. The token is the seam for binding egress to the caller's *verified* typed
1126/// standpoint — cryptographic verification against the standpoint/deontic registry is
1127/// performed by that layer once a call carries a verified calling-agent identifier.
1128/// This parser deliberately does not forge that check; it only guarantees that an
1129/// override which reaches the dispatch gate is a genuine, non-empty token.
1130fn parse_sanctuary_override(value: &[u8]) -> Option<[u8; 32]> {
1131    if value.len() != 64 {
1132        return None;
1133    }
1134    let mut token = [0u8; 32];
1135    for (byte, pair) in token.iter_mut().zip(value.chunks_exact(2)) {
1136        let hi = hex_nibble(pair[0])?;
1137        let lo = hex_nibble(pair[1])?;
1138        *byte = (hi << 4) | lo;
1139    }
1140    if token.iter().all(|&b| b == 0) {
1141        return None;
1142    }
1143    Some(token)
1144}
1145
1146fn build_intent_frame(arguments: &[u8], qpu_enabled: bool, llm_enabled: bool) -> McpIntentFrame {
1147    let sanctuary_override = extract_raw_json_string(arguments, b"\"sanctuary_override\"")
1148        .and_then(parse_sanctuary_override);
1149
1150    McpIntentFrame {
1151        purpose_hash: crate::q_hash("purpose:General"),
1152        active_deontic_constraints: Vec::new(),
1153        active_profile_id: None,
1154        session_nonce: 0,
1155        sanctuary_override,
1156        qpu_enabled,
1157        llm_enabled,
1158    }
1159}
1160
1161fn tool_list_json() -> Vec<Value> {
1162    stable_mcp_tools()
1163        .iter()
1164        .map(|tool| {
1165            let input_schema = serde_json::from_str::<Value>(tool.input_schema)
1166                .unwrap_or_else(|_| json!({"type":"object"}));
1167            json!({
1168                "name": tool.name,
1169                "description": tool.description,
1170                "inputSchema": input_schema,
1171            })
1172        })
1173        .collect()
1174}
1175
1176fn system_resource_json() -> Value {
1177    json!({
1178        "uri": "qualia://qapp-surface-schema",
1179        "name": "Qapp Surface Schema",
1180        "description": "Static description of the current Qualia qapp host surface.",
1181        "mimeType": "application/json",
1182    })
1183}
1184
1185fn error_message(err: McpSystemError) -> (&'static str, i64) {
1186    match err {
1187        McpSystemError::SanctuaryGateTriggered => ("Sanctuary gate triggered", -32001),
1188        McpSystemError::ToolNotFound => ("Tool not found", -32601),
1189        McpSystemError::ToolNotReady => ("Tool not implemented on the current MCP surface", -32004),
1190        McpSystemError::ParseError => ("Parse error", -32700),
1191        McpSystemError::IntentFrameViolation => ("Intent frame violation", -32002),
1192        McpSystemError::FeatureNotEnabled => ("Feature not enabled", -32003),
1193        McpSystemError::InvalidParameters => ("Invalid parameters", -32602),
1194    }
1195}
1196
1197fn dispatch_tool_call(
1198    tool_name: &[u8],
1199    arguments_raw: &[u8],
1200    qpu_enabled: bool,
1201    llm_enabled: bool,
1202) -> Result<String, McpSystemError> {
1203    let intent_frame = build_intent_frame(arguments_raw, qpu_enabled, llm_enabled);
1204    let payload = RawToolPayload {
1205        tool_name,
1206        arguments_raw,
1207    };
1208    unsafe { enforce_fiduciary_tool_dispatch(payload, &intent_frame) }
1209}
1210
1211/// The legacy raw-byte parser retained for compatibility with older tool-call callers.
1212pub unsafe fn parse_and_evaluate_mcp_stream(stream_chunk: &[u8]) -> Result<String, McpSystemError> {
1213    if !stream_chunk.windows(12).any(|w| w == b"\"tools/call\"") {
1214        return Err(McpSystemError::ParseError);
1215    }
1216    let tool_name = extract_raw_json_string(stream_chunk, b"\"name\"").unwrap_or(b"");
1217    dispatch_tool_call(tool_name, stream_chunk, true, true)
1218}
1219
1220pub fn handle_jsonrpc_message(
1221    message: &str,
1222    qpu_enabled: bool,
1223    llm_enabled: bool,
1224) -> Option<String> {
1225    let request: Value = serde_json::from_str(message).ok()?;
1226    let id = request.get("id").cloned().unwrap_or(Value::Null);
1227    let method = request.get("method").and_then(Value::as_str).or_else(|| {
1228        if message.contains("\"tools/call\"") {
1229            Some("tools/call")
1230        } else {
1231            None
1232        }
1233    })?;
1234
1235    let response = match method {
1236        "initialize" => json!({
1237            "jsonrpc": "2.0",
1238            "id": id,
1239            "result": {
1240                "protocolVersion": "2025-03-26",
1241                "capabilities": {
1242                    "tools": { "listChanged": false },
1243                    "resources": { "listChanged": false, "subscribe": false },
1244                    "prompts": { "listChanged": false }
1245                },
1246                "serverInfo": {
1247                    "name": "qualia-core-db-mcp",
1248                    "version": env!("CARGO_PKG_VERSION")
1249                }
1250            }
1251        }),
1252        "notifications/initialized" => return None,
1253        "ping" => json!({
1254            "jsonrpc": "2.0",
1255            "id": id,
1256            "result": {}
1257        }),
1258        "tools/list" => json!({
1259            "jsonrpc": "2.0",
1260            "id": id,
1261            "result": {
1262                "tools": tool_list_json()
1263            }
1264        }),
1265        "resources/list" => json!({
1266            "jsonrpc": "2.0",
1267            "id": id,
1268            "result": {
1269                "resources": [system_resource_json()]
1270            }
1271        }),
1272        "resources/read" => {
1273            let uri = request
1274                .get("params")
1275                .and_then(|params| params.get("uri"))
1276                .and_then(Value::as_str)
1277                .unwrap_or("");
1278            if uri != "qualia://qapp-surface-schema" {
1279                json!({
1280                    "jsonrpc": "2.0",
1281                    "id": id,
1282                    "error": {
1283                        "code": -32602,
1284                        "message": "Unknown resource URI"
1285                    }
1286                })
1287            } else {
1288                let content = unsafe {
1289                    execute_describe_qapp_surface_schema(
1290                        b"{}",
1291                        &build_intent_frame(b"{}", qpu_enabled, llm_enabled),
1292                    )
1293                }
1294                .unwrap_or_else(|_| "{}".to_string());
1295                json!({
1296                    "jsonrpc": "2.0",
1297                    "id": id,
1298                    "result": {
1299                        "contents": [{
1300                            "uri": uri,
1301                            "mimeType": "application/json",
1302                            "text": content
1303                        }]
1304                    }
1305                })
1306            }
1307        }
1308        "prompts/list" => json!({
1309            "jsonrpc": "2.0",
1310            "id": id,
1311            "result": {
1312                "prompts": []
1313            }
1314        }),
1315        "tools/call" => {
1316            let params = request.get("params").unwrap_or(&request);
1317            let name = params
1318                .get("name")
1319                .and_then(Value::as_str)
1320                .or_else(|| request.get("name").and_then(Value::as_str))
1321                .unwrap_or("");
1322            let arguments = params
1323                .get("arguments")
1324                .cloned()
1325                .unwrap_or_else(|| json!({}));
1326            let arguments_raw = serde_json::to_vec(&arguments).unwrap_or_else(|_| b"{}".to_vec());
1327            match dispatch_tool_call(name.as_bytes(), &arguments_raw, qpu_enabled, llm_enabled) {
1328                Ok(data) => json!({
1329                    "jsonrpc": "2.0",
1330                    "id": id,
1331                    "result": {
1332                        "content": [{
1333                            "type": "text",
1334                            "text": data
1335                        }],
1336                        "isError": false
1337                    }
1338                }),
1339                Err(err) => {
1340                    let (message, code) = error_message(err);
1341                    json!({
1342                        "jsonrpc": "2.0",
1343                        "id": id,
1344                        "error": {
1345                            "code": code,
1346                            "message": message
1347                        }
1348                    })
1349                }
1350            }
1351        }
1352        _ => json!({
1353            "jsonrpc": "2.0",
1354            "id": id,
1355            "error": {
1356                "code": -32601,
1357                "message": "Method not found"
1358            }
1359        }),
1360    };
1361
1362    Some(response.to_string())
1363}
1364
1365// -----------------------------------------------------------------------------
1366// stdio Transport Logic (Allocations permitted only for handshake/metadata)
1367// -----------------------------------------------------------------------------
1368
1369#[cfg(not(target_arch = "wasm32"))]
1370pub async fn start_mcp_listener() {
1371    start_mcp_listener_with_flags(true, true).await;
1372}
1373
1374#[cfg(not(target_arch = "wasm32"))]
1375pub async fn start_mcp_listener_with_flags(qpu_enabled: bool, llm_enabled: bool) {
1376    use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
1377
1378    eprintln!("[MCP Server] Starting stdio MCP server...");
1379    eprintln!(
1380        "[MCP Server] Advertised tool count: {}",
1381        stable_mcp_tools().len()
1382    );
1383
1384    let mut stdin = BufReader::new(tokio::io::stdin());
1385    let mut stdout = tokio::io::stdout();
1386    let mut line = String::new();
1387
1388    loop {
1389        line.clear();
1390        match stdin.read_line(&mut line).await {
1391            Ok(0) => break,
1392            Ok(_) => {
1393                let request = line.trim_end_matches(['\r', '\n']);
1394                if request.is_empty() {
1395                    continue;
1396                }
1397                if let Some(reply) = handle_jsonrpc_message(request, qpu_enabled, llm_enabled) {
1398                    let _ = stdout.write_all(reply.as_bytes()).await;
1399                    let _ = stdout.write_all(b"\n").await;
1400                }
1401            }
1402            Err(_) => break,
1403        }
1404    }
1405}
1406
1407#[cfg(test)]
1408mod tests {
1409    use super::*;
1410
1411    #[test]
1412    fn initialize_returns_server_info() {
1413        let reply = handle_jsonrpc_message(
1414            r#"{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}"#,
1415            true,
1416            true,
1417        )
1418        .expect("reply");
1419        let json: Value = serde_json::from_str(&reply).expect("valid json");
1420        assert_eq!(json["result"]["serverInfo"]["name"], "qualia-core-db-mcp");
1421        assert_eq!(json["result"]["protocolVersion"], "2025-03-26");
1422    }
1423
1424    #[test]
1425    fn tools_list_returns_curated_surface() {
1426        let reply = handle_jsonrpc_message(
1427            r#"{"jsonrpc":"2.0","id":"tools","method":"tools/list"}"#,
1428            true,
1429            true,
1430        )
1431        .expect("reply");
1432        let json: Value = serde_json::from_str(&reply).expect("valid json");
1433        let tools = json["result"]["tools"].as_array().expect("tool array");
1434        assert!(tools.iter().any(|tool| tool["name"] == "get_system_status"));
1435        assert!(tools.iter().any(|tool| tool["name"] == "run_docs_tests"));
1436        assert!(tools.iter().all(|tool| tool.get("inputSchema").is_some()));
1437    }
1438
1439    #[test]
1440    fn parse_rdf_tool_call_returns_quins() {
1441        let reply = handle_jsonrpc_message(
1442            r#"{"jsonrpc":"2.0","id":"rdf","method":"tools/call","params":{"name":"parse_rdf","arguments":{"format":"nt","rdf_data":"<http://example.org/Alice> <http://example.org/knows> <http://example.org/Bob> .\n"}}}"#,
1443            false,
1444            false,
1445        )
1446        .expect("reply");
1447        let json: Value = serde_json::from_str(&reply).expect("valid json");
1448        let text = json["result"]["content"][0]["text"]
1449            .as_str()
1450            .expect("text payload");
1451        let payload: Value = serde_json::from_str(text).expect("embedded json");
1452        assert_eq!(payload["quinCount"], 1);
1453    }
1454
1455    #[test]
1456    fn parse_csv_tool_call_returns_quins() {
1457        let reply = handle_jsonrpc_message(
1458            r#"{"jsonrpc":"2.0","id":"csv","method":"tools/call","params":{"name":"parse_csv","arguments":{"csv_data":"v,n\n1,2\n","field_mappings":[{"source_key":"v","predicate":"ex:v","datatype":"integer"}]}}}"#,
1459            false,
1460            false,
1461        )
1462        .expect("reply");
1463        let json: Value = serde_json::from_str(&reply).expect("valid json");
1464        let text = json["result"]["content"][0]["text"]
1465            .as_str()
1466            .expect("text payload");
1467        let payload: Value = serde_json::from_str(text).expect("embedded json");
1468        assert_eq!(payload["quinCount"], 1);
1469    }
1470
1471    #[test]
1472    fn get_graph_stats_tool_call_returns_json_payload() {
1473        let reply = handle_jsonrpc_message(
1474            r#"{"jsonrpc":"2.0","id":"graph","method":"tools/call","params":{"name":"get_graph_stats","arguments":{}}}"#,
1475            false,
1476            false,
1477        )
1478        .expect("reply");
1479        let json: Value = serde_json::from_str(&reply).expect("valid json");
1480        let text = json["result"]["content"][0]["text"]
1481            .as_str()
1482            .expect("text payload");
1483        let payload: Value = serde_json::from_str(text).expect("embedded json");
1484        assert!(payload.get("quinCount").is_some());
1485    }
1486
1487    #[test]
1488    fn get_did_info_tool_call_parses_q42() {
1489        let reply = handle_jsonrpc_message(
1490            r#"{"jsonrpc":"2.0","id":"did","method":"tools/call","params":{"name":"get_did_info","arguments":{"did":"did:q42:z6MkpTHR8VNs"}}}"#,
1491            false,
1492            false,
1493        )
1494        .expect("reply");
1495        let json: Value = serde_json::from_str(&reply).expect("valid json");
1496        let text = json["result"]["content"][0]["text"]
1497            .as_str()
1498            .expect("text payload");
1499        let payload: Value = serde_json::from_str(text).expect("embedded json");
1500        assert_eq!(payload["msbSet"], true);
1501    }
1502
1503    #[test]
1504    fn tools_list_includes_newly_public_stubs() {
1505        let reply = handle_jsonrpc_message(
1506            r#"{"jsonrpc":"2.0","id":"tools","method":"tools/list"}"#,
1507            true,
1508            true,
1509        )
1510        .expect("reply");
1511        let json: Value = serde_json::from_str(&reply).expect("valid json");
1512        let tools = json["result"]["tools"].as_array().expect("tool array");
1513        assert!(tools.iter().any(|tool| tool["name"] == "query_sparql"));
1514        assert!(tools.iter().any(|tool| tool["name"] == "parse_rdf"));
1515        assert!(tools.iter().any(|tool| tool["name"] == "list_qapps"));
1516        assert!(tools.iter().any(|tool| tool["name"] == "list_capabilities"));
1517        assert!(tools
1518            .iter()
1519            .any(|tool| tool["name"] == "computational_geometry"));
1520        assert_eq!(tools.len(), stable_mcp_tools().len());
1521    }
1522
1523    #[test]
1524    fn computational_geometry_tool_routes_hull() {
1525        let reply = handle_jsonrpc_message(
1526            r#"{"jsonrpc":"2.0","id":"geometry","method":"tools/call","params":{"name":"computational_geometry","arguments":{"op":"convex_hull_2","points":[[0,0],[1,0],[0.5,0.5],[1,1],[0,1]]}}}"#,
1527            false,
1528            false,
1529        )
1530        .expect("reply");
1531        let json: Value = serde_json::from_str(&reply).expect("valid json");
1532        let text = json["result"]["content"][0]["text"]
1533            .as_str()
1534            .expect("text payload");
1535        let payload: Value = serde_json::from_str(text).expect("embedded json");
1536        assert_eq!(payload["vertex_count"], 4);
1537        assert_eq!(payload["indices"], json!([0, 1, 3, 4]));
1538    }
1539
1540    #[test]
1541    fn computer_vision_tool_list_and_sigma() {
1542        let reply = handle_jsonrpc_message(
1543            r#"{"jsonrpc":"2.0","id":"cv","method":"tools/call","params":{"name":"computer_vision","arguments":{"op":"list"}}}"#,
1544            false,
1545            false,
1546        )
1547        .expect("reply");
1548        let json: Value = serde_json::from_str(&reply).expect("valid json");
1549        let text = json["result"]["content"][0]["text"]
1550            .as_str()
1551            .expect("text payload");
1552        let payload: Value = serde_json::from_str(text).expect("embedded json");
1553        assert_eq!(payload["library"], "specialized_libs::computer_vision");
1554        let reply2 = handle_jsonrpc_message(
1555            r#"{"jsonrpc":"2.0","id":"cv2","method":"tools/call","params":{"name":"computer_vision","arguments":{"op":"class_score_to_sigma","class_hash":4,"score":1.0}}}"#,
1556            false,
1557            false,
1558        )
1559        .expect("reply2");
1560        let json2: Value = serde_json::from_str(&reply2).expect("valid json");
1561        let text2 = json2["result"]["content"][0]["text"]
1562            .as_str()
1563            .expect("text");
1564        let payload2: Value = serde_json::from_str(text2).expect("json");
1565        assert!(payload2["sigma"].as_f64().unwrap() > 0.0);
1566    }
1567
1568    #[test]
1569    fn inference_capability_tools_are_registered() {
1570        let registered: Vec<&str> = stable_mcp_tools().iter().map(|tool| tool.name).collect();
1571        for capability in crate::CAPABILITY_DESCRIPTORS {
1572            for tool in capability.mcp_tools {
1573                assert!(
1574                    registered.contains(tool),
1575                    "{} routes to missing MCP tool {}",
1576                    capability.name,
1577                    tool
1578                );
1579            }
1580        }
1581    }
1582
1583    #[test]
1584    fn capability_catalog_is_complete_filterable_and_honest() {
1585        let all = mcp_tool_impls::list_capabilities(br#"{}"#).expect("catalogue");
1586        let all: Value = serde_json::from_str(&all).expect("catalogue json");
1587        assert_eq!(
1588            all["capability_count"].as_u64().unwrap() as usize,
1589            crate::CAPABILITY_DESCRIPTORS.len()
1590        );
1591        assert!(all["operation_group_count"].as_u64().unwrap() > 50);
1592
1593        let filtered =
1594            mcp_tool_impls::list_capabilities(br#"{"domain":"statistics"}"#).expect("filtered");
1595        let filtered: Value = serde_json::from_str(&filtered).expect("filtered json");
1596        assert_eq!(filtered["capability_count"], 1);
1597        assert_eq!(filtered["capabilities"][0]["name"], "Statistics");
1598
1599        let ml = all["capabilities"]
1600            .as_array()
1601            .unwrap()
1602            .iter()
1603            .find(|capability| capability["name"] == "MachineLearning")
1604            .expect("machine learning capability");
1605        assert_eq!(ml["maturity"], "fail-closed");
1606        assert_eq!(ml["operational"], false);
1607    }
1608
1609    #[test]
1610    fn capability_catalogue_metadata_has_no_silent_gaps() {
1611        let allowed_maturity = ["stable", "partial", "experimental", "fail-closed"];
1612        let mut names = std::collections::BTreeSet::new();
1613        for capability in crate::CAPABILITY_DESCRIPTORS {
1614            assert!(
1615                names.insert(capability.name),
1616                "duplicate {}",
1617                capability.name
1618            );
1619            assert!(
1620                !capability.operations.is_empty(),
1621                "{} has no operations",
1622                capability.name
1623            );
1624            assert!(
1625                allowed_maturity.contains(&capability.maturity),
1626                "{} has unknown maturity {}",
1627                capability.name,
1628                capability.maturity
1629            );
1630            assert!(
1631                !capability.surfaces.is_empty(),
1632                "{} has no runtime surface",
1633                capability.name
1634            );
1635        }
1636    }
1637
1638    #[test]
1639    fn get_system_status_tool_call_returns_json_payload() {
1640        let reply = handle_jsonrpc_message(
1641            r#"{"jsonrpc":"2.0","id":"status","method":"tools/call","params":{"name":"get_system_status","arguments":{}}}"#,
1642            false,
1643            true,
1644        )
1645        .expect("reply");
1646        let json: Value = serde_json::from_str(&reply).expect("valid json");
1647        let text = json["result"]["content"][0]["text"]
1648            .as_str()
1649            .expect("text payload");
1650        let payload: Value = serde_json::from_str(text).expect("embedded json");
1651        assert_eq!(payload["server"], "qualia-core-db-mcp");
1652        assert_eq!(payload["qpuEnabled"], false);
1653    }
1654
1655    #[test]
1656    fn geometry_manifests_tool_list_round_trips() {
1657        let reply = handle_jsonrpc_message(
1658            r#"{"jsonrpc":"2.0","id":"gm","method":"tools/call","params":{"name":"geometry_manifests","arguments":{}}}"#,
1659            false,
1660            false,
1661        )
1662        .expect("reply");
1663        let json: Value = serde_json::from_str(&reply).expect("valid json");
1664        let text = json["result"]["content"][0]["text"]
1665            .as_str()
1666            .expect("text payload");
1667        let payload: Value = serde_json::from_str(text).expect("embedded json");
1668        assert!(payload["op_count"].as_u64().unwrap() > 0);
1669        let ops = payload["ops"].as_array().unwrap();
1670        for op in ops {
1671            assert!(
1672                op["backends"].as_array().unwrap().len() > 0,
1673                "every op must have non-empty backends"
1674            );
1675        }
1676    }
1677
1678    #[test]
1679    fn geometry_manifests_budget_query_no_gpu() {
1680        let reply = handle_jsonrpc_message(
1681            r#"{"jsonrpc":"2.0","id":"bq","method":"tools/call","params":{"name":"geometry_manifests","arguments":{"op":"vr_filtration","device":{"cpu":true,"simd":true,"wgpu":false,"cuda":false,"wasm":true,"exact":true}}}}"#,
1682            false,
1683            false,
1684        )
1685        .expect("reply");
1686        let json: Value = serde_json::from_str(&reply).expect("valid json");
1687        let text = json["result"]["content"][0]["text"]
1688            .as_str()
1689            .expect("text payload");
1690        let payload: Value = serde_json::from_str(text).expect("embedded json");
1691        assert_eq!(payload["op"], "vr_filtration");
1692        assert!(payload["backend_count"].as_u64().unwrap() > 0);
1693        let backends = payload["runnable_backends"].as_array().unwrap();
1694        assert!(
1695            !backends.iter().any(|b| b == "wgpu"),
1696            "wgpu should not be runnable when device.wgpu=false"
1697        );
1698    }
1699}