@@ -10,6 +10,7 @@ import {
1010 MCP_TOOL_RESULT_CONTENT_COUNT_ATTRIBUTE ,
1111 MCP_TOOL_RESULT_IS_ERROR_ATTRIBUTE ,
1212} from './attributes' ;
13+ import { isValidContentItem } from './validation' ;
1314
1415/**
1516 * Build attributes for tool result content items
@@ -22,11 +23,10 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
2223 } ;
2324
2425 for ( const [ i , item ] of content . entries ( ) ) {
25- if ( typeof item !== 'object' || item === null ) {
26+ if ( ! isValidContentItem ( item ) ) {
2627 continue ;
2728 }
2829
29- const contentItem = item as Record < string , unknown > ;
3030 const prefix = content . length === 1 ? 'mcp.tool.result' : `mcp.tool.result.${ i } ` ;
3131
3232 const safeSet = ( key : string , value : unknown ) : void => {
@@ -35,13 +35,13 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
3535 }
3636 } ;
3737
38- safeSet ( 'content_type' , contentItem . type ) ;
39- safeSet ( 'mime_type' , contentItem . mimeType ) ;
40- safeSet ( 'uri' , contentItem . uri ) ;
41- safeSet ( 'name' , contentItem . name ) ;
38+ safeSet ( 'content_type' , item . type ) ;
39+ safeSet ( 'mime_type' , item . mimeType ) ;
40+ safeSet ( 'uri' , item . uri ) ;
41+ safeSet ( 'name' , item . name ) ;
4242
43- if ( typeof contentItem . text === 'string' ) {
44- const text = contentItem . text ;
43+ if ( typeof item . text === 'string' ) {
44+ const text = item . text ;
4545 const maxLength = 500 ;
4646 if ( text . length > maxLength ) {
4747 attributes [ `${ prefix } .content` ] = `${ text . slice ( 0 , maxLength - 3 ) } ...` ;
@@ -50,15 +50,14 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
5050 }
5151 }
5252
53- if ( typeof contentItem . data === 'string' ) {
54- attributes [ `${ prefix } .data_size` ] = contentItem . data . length ;
53+ if ( typeof item . data === 'string' ) {
54+ attributes [ `${ prefix } .data_size` ] = item . data . length ;
5555 }
5656
57- const resource = contentItem . resource ;
58- if ( typeof resource === 'object' && resource !== null ) {
59- const res = resource as Record < string , unknown > ;
60- safeSet ( 'resource_uri' , res . uri ) ;
61- safeSet ( 'resource_mime_type' , res . mimeType ) ;
57+ const resource = item . resource ;
58+ if ( isValidContentItem ( resource ) ) {
59+ safeSet ( 'resource_uri' , resource . uri ) ;
60+ safeSet ( 'resource_mime_type' , resource . mimeType ) ;
6261 }
6362 }
6463
@@ -72,16 +71,15 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
7271 */
7372export function extractToolResultAttributes ( result : unknown ) : Record < string , string | number | boolean > {
7473 let attributes : Record < string , string | number | boolean > = { } ;
75- if ( typeof result !== 'object' || result === null ) {
74+ if ( ! isValidContentItem ( result ) ) {
7675 return attributes ;
7776 }
7877
79- const resultObj = result as Record < string , unknown > ;
80- if ( typeof resultObj . isError === 'boolean' ) {
81- attributes [ MCP_TOOL_RESULT_IS_ERROR_ATTRIBUTE ] = resultObj . isError ;
78+ if ( typeof result . isError === 'boolean' ) {
79+ attributes [ MCP_TOOL_RESULT_IS_ERROR_ATTRIBUTE ] = result . isError ;
8280 }
83- if ( Array . isArray ( resultObj . content ) ) {
84- attributes = { ...attributes , ...buildAllContentItemAttributes ( resultObj . content ) } ;
81+ if ( Array . isArray ( result . content ) ) {
82+ attributes = { ...attributes , ...buildAllContentItemAttributes ( result . content ) } ;
8583 }
8684 return attributes ;
8785}
@@ -93,26 +91,23 @@ export function extractToolResultAttributes(result: unknown): Record<string, str
9391 */
9492export function extractPromptResultAttributes ( result : unknown ) : Record < string , string | number | boolean > {
9593 const attributes : Record < string , string | number | boolean > = { } ;
96- if ( typeof result !== 'object' || result === null ) {
94+ if ( ! isValidContentItem ( result ) ) {
9795 return attributes ;
9896 }
9997
100- const resultObj = result as Record < string , unknown > ;
101-
102- if ( typeof resultObj . description === 'string' ) {
103- attributes [ MCP_PROMPT_RESULT_DESCRIPTION_ATTRIBUTE ] = resultObj . description ;
98+ if ( typeof result . description === 'string' ) {
99+ attributes [ MCP_PROMPT_RESULT_DESCRIPTION_ATTRIBUTE ] = result . description ;
104100 }
105101
106- if ( Array . isArray ( resultObj . messages ) ) {
107- attributes [ MCP_PROMPT_RESULT_MESSAGE_COUNT_ATTRIBUTE ] = resultObj . messages . length ;
102+ if ( Array . isArray ( result . messages ) ) {
103+ attributes [ MCP_PROMPT_RESULT_MESSAGE_COUNT_ATTRIBUTE ] = result . messages . length ;
108104
109- const messages = resultObj . messages ;
105+ const messages = result . messages ;
110106 for ( const [ i , message ] of messages . entries ( ) ) {
111- if ( typeof message !== 'object' || message === null ) {
107+ if ( ! isValidContentItem ( message ) ) {
112108 continue ;
113109 }
114110
115- const messageObj = message as Record < string , unknown > ;
116111 const prefix = messages . length === 1 ? 'mcp.prompt.result' : `mcp.prompt.result.${ i } ` ;
117112
118113 const safeSet = ( key : string , value : unknown ) : void => {
@@ -122,10 +117,10 @@ export function extractPromptResultAttributes(result: unknown): Record<string, s
122117 }
123118 } ;
124119
125- safeSet ( 'role' , messageObj . role ) ;
120+ safeSet ( 'role' , message . role ) ;
126121
127- if ( typeof messageObj . content === 'object' && messageObj . content !== null ) {
128- const content = messageObj . content as Record < string , unknown > ;
122+ if ( isValidContentItem ( message . content ) ) {
123+ const content = message . content ;
129124 if ( typeof content . text === 'string' ) {
130125 const attrName = messages . length === 1 ? `${ prefix } .message_content` : `${ prefix } .content` ;
131126 attributes [ attrName ] = content . text ;
0 commit comments