Problem
MCP-driven SQON generation produces inconsistent results. LLMs infer SQON structure from training data that is incomplete or out of date relative to the current spec. Operator names, value schemas, combination nesting rules, and property names like fieldName drift between spec versions and what models were trained on.
A concrete example: the current SQON spec uses content.fieldName as the property name for field references. An LLM trained on older Arranger documentation may generate content.field instead: a silent mismatch that produces invalid queries with no clear error at the generation site. This kind of training-data staleness cannot be corrected by prompting alone; it reappears every time the spec evolves.
Solution
Add a build_sqon MCP tool that delegates SQON construction to a deterministic code path (SqonBuilder), removing the LLM from the JSON synthesis loop.
The LLM selects the field name, operator, and value from the available catalogue schema. The tool produces and validates the SQON. The LLM is the selector; the tool is the generator.
Example:
build_sqon(fieldName: "age", operator: "gt", value: 30)
→ { "op": "gt", "content": { "fieldName": "age", "value": 30 } }
This makes SQON construction:
- Deterministic: the same inputs always produce the same valid SQON regardless of model version or prompt variation
- Validated at construction: the builder rejects impossible operator/field-type combinations before they reach Elasticsearch
- Spec-tracked: as the SQON schema evolves, only the tool implementation changes; the LLM does not need retraining or re-prompting
- Token-efficient: cheaper than injecting SQON documentation into every prompt or routing through the
/introspection endpoint as a runtime guide
Scope
build_sqon tool in apps/mcp-server/src/mcp/tools.ts: accepts fieldName, operator, value, and optional combination type; calls SqonBuilder internally; returns a validated SQON object
- Agent-optimized tool description: the tool schema carries descriptions that guide the LLM toward correct parameter selection: valid operators per field type and value type constraints; the tool's own description is the spec, no SQON documentation needed in the system prompt
- Versioned changelog: as the SQON schema evolves, the tool interface version and changelog are machine-readable so agent behaviour decouples from model training data
Prerequisites
Depends on sqon-builder being integrated into the Arranger monorepo; see the sqon-builder absorption into modules/sqon section of the roadmap.
Problem
MCP-driven SQON generation produces inconsistent results. LLMs infer SQON structure from training data that is incomplete or out of date relative to the current spec. Operator names, value schemas, combination nesting rules, and property names like
fieldNamedrift between spec versions and what models were trained on.A concrete example: the current SQON spec uses
content.fieldNameas the property name for field references. An LLM trained on older Arranger documentation may generatecontent.fieldinstead: a silent mismatch that produces invalid queries with no clear error at the generation site. This kind of training-data staleness cannot be corrected by prompting alone; it reappears every time the spec evolves.Solution
Add a
build_sqonMCP tool that delegates SQON construction to a deterministic code path (SqonBuilder), removing the LLM from the JSON synthesis loop.The LLM selects the field name, operator, and value from the available catalogue schema. The tool produces and validates the SQON. The LLM is the selector; the tool is the generator.
Example:
This makes SQON construction:
/introspectionendpoint as a runtime guideScope
build_sqontool inapps/mcp-server/src/mcp/tools.ts: acceptsfieldName,operator,value, and optionalcombinationtype; callsSqonBuilderinternally; returns a validated SQON objectPrerequisites
Depends on
sqon-builderbeing integrated into the Arranger monorepo; see the sqon-builder absorption into modules/sqon section of the roadmap.