@@ -10,6 +10,7 @@ import {
10
10
MCP_TOOL_RESULT_CONTENT_COUNT_ATTRIBUTE ,
11
11
MCP_TOOL_RESULT_IS_ERROR_ATTRIBUTE ,
12
12
} from './attributes' ;
13
+ import { isValidContentItem } from './validation' ;
13
14
14
15
/**
15
16
* Build attributes for tool result content items
@@ -22,11 +23,10 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
22
23
} ;
23
24
24
25
for ( const [ i , item ] of content . entries ( ) ) {
25
- if ( typeof item !== 'object' || item === null ) {
26
+ if ( ! isValidContentItem ( item ) ) {
26
27
continue ;
27
28
}
28
29
29
- const contentItem = item as Record < string , unknown > ;
30
30
const prefix = content . length === 1 ? 'mcp.tool.result' : `mcp.tool.result.${ i } ` ;
31
31
32
32
const safeSet = ( key : string , value : unknown ) : void => {
@@ -35,13 +35,13 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
35
35
}
36
36
} ;
37
37
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 ) ;
42
42
43
- if ( typeof contentItem . text === 'string' ) {
44
- const text = contentItem . text ;
43
+ if ( typeof item . text === 'string' ) {
44
+ const text = item . text ;
45
45
const maxLength = 500 ;
46
46
if ( text . length > maxLength ) {
47
47
attributes [ `${ prefix } .content` ] = `${ text . slice ( 0 , maxLength - 3 ) } ...` ;
@@ -50,15 +50,14 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
50
50
}
51
51
}
52
52
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 ;
55
55
}
56
56
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 ) ;
62
61
}
63
62
}
64
63
@@ -72,16 +71,15 @@ function buildAllContentItemAttributes(content: unknown[]): Record<string, strin
72
71
*/
73
72
export function extractToolResultAttributes ( result : unknown ) : Record < string , string | number | boolean > {
74
73
let attributes : Record < string , string | number | boolean > = { } ;
75
- if ( typeof result !== 'object' || result === null ) {
74
+ if ( ! isValidContentItem ( result ) ) {
76
75
return attributes ;
77
76
}
78
77
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 ;
82
80
}
83
- if ( Array . isArray ( resultObj . content ) ) {
84
- attributes = { ...attributes , ...buildAllContentItemAttributes ( resultObj . content ) } ;
81
+ if ( Array . isArray ( result . content ) ) {
82
+ attributes = { ...attributes , ...buildAllContentItemAttributes ( result . content ) } ;
85
83
}
86
84
return attributes ;
87
85
}
@@ -93,26 +91,23 @@ export function extractToolResultAttributes(result: unknown): Record<string, str
93
91
*/
94
92
export function extractPromptResultAttributes ( result : unknown ) : Record < string , string | number | boolean > {
95
93
const attributes : Record < string , string | number | boolean > = { } ;
96
- if ( typeof result !== 'object' || result === null ) {
94
+ if ( ! isValidContentItem ( result ) ) {
97
95
return attributes ;
98
96
}
99
97
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 ;
104
100
}
105
101
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 ;
108
104
109
- const messages = resultObj . messages ;
105
+ const messages = result . messages ;
110
106
for ( const [ i , message ] of messages . entries ( ) ) {
111
- if ( typeof message !== 'object' || message === null ) {
107
+ if ( ! isValidContentItem ( message ) ) {
112
108
continue ;
113
109
}
114
110
115
- const messageObj = message as Record < string , unknown > ;
116
111
const prefix = messages . length === 1 ? 'mcp.prompt.result' : `mcp.prompt.result.${ i } ` ;
117
112
118
113
const safeSet = ( key : string , value : unknown ) : void => {
@@ -122,10 +117,10 @@ export function extractPromptResultAttributes(result: unknown): Record<string, s
122
117
}
123
118
} ;
124
119
125
- safeSet ( 'role' , messageObj . role ) ;
120
+ safeSet ( 'role' , message . role ) ;
126
121
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 ;
129
124
if ( typeof content . text === 'string' ) {
130
125
const attrName = messages . length === 1 ? `${ prefix } .message_content` : `${ prefix } .content` ;
131
126
attributes [ attrName ] = content . text ;
0 commit comments