pub fn normalize_schema_param(
schema: Option<&Value>,
) -> Result<Option<Map<String, Value>>, McpError>Expand description
Normalize a raw MCP schema parameter value into the column-name → type
map expected by apply_schema_override and parse_schema_override.
The MCP tool parameter is declared as Option<serde_json::Value> so the
rmcp / schemars pipeline emits a permissive true JSON Schema. In
practice some MCP clients forward this field as a JSON-encoded string
rather than a raw JSON object — e.g. Windsurf/Cascade serializes
{"postal_code": "TEXT"} as "\"{\\\"postal_code\\\": \\\"TEXT\\\"}\"".
If we only accepted Value::Object (the old v.as_object().cloned()
pattern) the override was silently dropped and ingest would fail with a
confusing 22P02 invalid input syntax error from hyperd when a column that
the user explicitly wanted TEXT stayed INT.
Accepted shapes:
None/Some(Value::Null)— no override.Some(Value::Object(m))— used directly.Some(Value::String(s))—sis parsed as JSON; must decode to an object. A non-object payload (array, number, etc.) is rejected withSchemaMismatchso the caller gets a clear error rather than a silent no-op.
Any other shape is rejected with SchemaMismatch for the same reason.
§Errors
- Returns
ErrorCode::SchemaMismatchif aValue::Stringpayload is non-empty but not valid JSON, or if it decodes to anything other than an object or null. - Returns
ErrorCode::SchemaMismatchfor any otherValueshape (boolean, number, array, etc.).