@@ -234,16 +234,10 @@ inline bool isPromptMessageItem(const JSONValue& v) {
234234 return false ;
235235 }
236236 auto contentIt = obj.find (" content" );
237- if (contentIt == obj.end () || !contentIt->second || !std::holds_alternative<JSONValue::Array>(contentIt-> second -> value ) ) {
237+ if (contentIt == obj.end () || !contentIt->second ) {
238238 return false ;
239239 }
240- const auto & arr = std::get<JSONValue::Array>(contentIt->second ->value );
241- for (const auto & item : arr) {
242- if (!item || !isContentItem (*item)) {
243- return false ;
244- }
245- }
246- return true ;
240+ return isContentItem (*contentIt->second );
247241}
248242
249243// ------------------------------ JSON validators (for client-side raw JSON) ------------------------------
@@ -300,7 +294,19 @@ inline bool validateReadResourceResultJson(const JSONValue& v) {
300294 if (!p) {
301295 return false ;
302296 }
303- if (!isContentItem (*p)) {
297+ if (!std::holds_alternative<JSONValue::Object>(p->value )) {
298+ return false ;
299+ }
300+ const auto & item = std::get<JSONValue::Object>(p->value );
301+ const bool isChunkText = isTextContentItem (*p);
302+ const bool hasUri = isStringField (item, " uri" );
303+ const bool hasText = isStringField (item, " text" );
304+ const bool hasBlob = isStringField (item, " blob" );
305+ const bool isResourceContents =
306+ hasUri &&
307+ (hasText != hasBlob) &&
308+ isOptionalStringField (item, " mimeType" );
309+ if (!isChunkText && !isResourceContents) {
304310 return false ;
305311 }
306312 }
@@ -648,15 +654,19 @@ inline bool validateCreateMessageParamsJson(const JSONValue& v) {
648654 if (!m || !std::holds_alternative<JSONValue::Object>(m->value )) return false ;
649655 const auto & mo = std::get<JSONValue::Object>(m->value );
650656 auto c = mo.find (" content" );
651- if (c != mo.end ()) {
652- if (!c->second || !std::holds_alternative<JSONValue::Array>(c->second ->value )) return false ;
657+ if (c != mo.end ()) {
658+ if (!c->second ) return false ;
659+ if (std::holds_alternative<JSONValue::Array>(c->second ->value )) {
653660 const auto & carr = std::get<JSONValue::Array>(c->second ->value );
654661 for (const auto & ci : carr) {
655662 if (!ci) return false ;
656663 if (!isContentItem (*ci)) return false ;
657664 }
665+ } else if (!isContentItem (*c->second )) {
666+ return false ;
658667 }
659668 }
669+ }
660670 // modelPreferences/systemPrompt/includeContext are optional, any JSON types accepted
661671 return true ;
662672}
@@ -666,11 +676,15 @@ inline bool validateCreateMessageResultJson(const JSONValue& v) {
666676 const auto & o = std::get<JSONValue::Object>(v.value );
667677 auto mdl = o.find (" model" ); if (mdl == o.end () || !mdl->second || !std::holds_alternative<std::string>(mdl->second ->value )) return false ;
668678 auto role = o.find (" role" ); if (role == o.end () || !role->second || !std::holds_alternative<std::string>(role->second ->value )) return false ;
669- auto cont = o.find (" content" ); if (cont == o.end () || !cont->second || !std::holds_alternative<JSONValue::Array>(cont->second ->value )) return false ;
670- const auto & arr = std::get<JSONValue::Array>(cont->second ->value );
671- for (const auto & ci : arr) {
672- if (!ci) return false ;
673- if (!isContentItem (*ci)) return false ;
679+ auto cont = o.find (" content" ); if (cont == o.end () || !cont->second ) return false ;
680+ if (std::holds_alternative<JSONValue::Array>(cont->second ->value )) {
681+ const auto & arr = std::get<JSONValue::Array>(cont->second ->value );
682+ for (const auto & ci : arr) {
683+ if (!ci) return false ;
684+ if (!isContentItem (*ci)) return false ;
685+ }
686+ } else if (!isContentItem (*cont->second )) {
687+ return false ;
674688 }
675689 // stopReason optional
676690 return true ;
@@ -682,7 +696,24 @@ inline bool validateCallToolResult(const CallToolResult& r) {
682696}
683697
684698inline bool validateReadResourceResult (const ReadResourceResult& r) {
685- return isContentArray (r.contents );
699+ for (const auto & item : r.contents ) {
700+ if (!std::holds_alternative<JSONValue::Object>(item.value )) {
701+ return false ;
702+ }
703+ const auto & objectValue = std::get<JSONValue::Object>(item.value );
704+ const bool isChunkText = isTextContentItem (item);
705+ const bool hasUri = isStringField (objectValue, " uri" );
706+ const bool hasText = isStringField (objectValue, " text" );
707+ const bool hasBlob = isStringField (objectValue, " blob" );
708+ const bool isResourceContents =
709+ hasUri &&
710+ (hasText != hasBlob) &&
711+ isOptionalStringField (objectValue, " mimeType" );
712+ if (!isChunkText && !isResourceContents) {
713+ return false ;
714+ }
715+ }
716+ return true ;
686717}
687718
688719inline bool validateGetPromptResult (const GetPromptResult& r) {
0 commit comments