@@ -53,9 +53,38 @@ import {
5353 isReservedMetaKey ,
5454} from "@/utils/metaUtils" ;
5555
56+ /**
57+ * Extended Tool type that includes optional fields used by the inspector.
58+ */
59+ export interface ExtendedTool extends Tool , WithIcons {
60+ _meta ?: Record < string , unknown > ;
61+ execution ?: {
62+ taskSupport ?: "forbidden" | "required" | "optional" ;
63+ } ;
64+ }
65+
5666// Type guard to safely detect the optional _meta field without using `any`
57- const hasMeta = ( tool : Tool ) : tool is Tool & { _meta : unknown } =>
58- typeof ( tool as { _meta ?: unknown } ) . _meta !== "undefined" ;
67+ const hasMeta = (
68+ tool : Tool ,
69+ ) : tool is ExtendedTool & { _meta : Record < string , unknown > } =>
70+ typeof ( tool as ExtendedTool ) . _meta !== "undefined" ;
71+
72+ // Returns the execution.taskSupport value for a tool, defaulting to "forbidden" per MCP spec
73+ const getTaskSupport = (
74+ tool : Tool | null ,
75+ ) : "forbidden" | "required" | "optional" => {
76+ if ( ! tool ) return "forbidden" ;
77+ const extendedTool = tool as ExtendedTool ;
78+ const taskSupport = extendedTool . execution ?. taskSupport ;
79+ if (
80+ taskSupport === "forbidden" ||
81+ taskSupport === "required" ||
82+ taskSupport === "optional"
83+ ) {
84+ return taskSupport ;
85+ }
86+ return "forbidden" ;
87+ } ;
5988
6089// Type guard to safely detect the optional annotations field
6190const hasAnnotations = (
@@ -148,6 +177,7 @@ const ToolsTab = ({
148177 error,
149178 resourceContent,
150179 onReadResource,
180+ serverSupportsTaskRequests,
151181} : {
152182 tools : Tool [ ] ;
153183 listTools : ( ) => void ;
@@ -166,6 +196,7 @@ const ToolsTab = ({
166196 error : string | null ;
167197 resourceContent : Record < string , string > ;
168198 onReadResource ?: ( uri : string ) => void ;
199+ serverSupportsTaskRequests : boolean ;
169200} ) => {
170201 const [ params , setParams ] = useState < Record < string , unknown > > ( { } ) ;
171202 const [ runAsTask , setRunAsTask ] = useState ( false ) ;
@@ -210,14 +241,17 @@ const ToolsTab = ({
210241 ] ;
211242 } ) ;
212243 setParams ( Object . fromEntries ( params ) ) ;
213- setRunAsTask ( false ) ;
244+ const toolTaskSupport = serverSupportsTaskRequests
245+ ? getTaskSupport ( selectedTool )
246+ : "forbidden" ;
247+ setRunAsTask ( toolTaskSupport === "required" ) ;
214248
215249 // Reset validation errors when switching tools
216250 setHasValidationErrors ( false ) ;
217251
218252 // Clear form refs for the previous tool
219253 formRefs . current = { } ;
220- } , [ selectedTool ] ) ;
254+ } , [ selectedTool , serverSupportsTaskRequests ] ) ;
221255
222256 const hasReservedMetadataEntry = metadataEntries . some ( ( { key } ) => {
223257 const trimmedKey = key . trim ( ) ;
@@ -234,6 +268,10 @@ const ToolsTab = ({
234268 return trimmedKey !== "" && ! hasValidMetaName ( trimmedKey ) ;
235269 } ) ;
236270
271+ const taskSupport = serverSupportsTaskRequests
272+ ? getTaskSupport ( selectedTool )
273+ : "forbidden" ;
274+
237275 return (
238276 < TabsContent value = "tools" >
239277 < div className = "grid grid-cols-2 gap-4" >
@@ -249,7 +287,7 @@ const ToolsTab = ({
249287 renderItem = { ( tool ) => (
250288 < div className = "flex items-start w-full gap-2" >
251289 < div className = "flex-shrink-0 mt-1" >
252- < IconDisplay icons = { ( tool as WithIcons ) . icons } size = "sm" />
290+ < IconDisplay icons = { ( tool as ExtendedTool ) . icons } size = "sm" />
253291 </ div >
254292 < div className = "flex flex-col flex-1 min-w-0" >
255293 < span className = "truncate" > { tool . title || tool . name } </ span >
@@ -270,7 +308,7 @@ const ToolsTab = ({
270308 < div className = "flex items-center gap-2" >
271309 { selectedTool && (
272310 < IconDisplay
273- icons = { ( selectedTool as WithIcons ) . icons }
311+ icons = { ( selectedTool as ExtendedTool ) . icons }
274312 size = "md"
275313 />
276314 ) }
@@ -747,21 +785,24 @@ const ToolsTab = ({
747785 </ div >
748786 </ div >
749787 ) }
750- < div className = "flex items-center space-x-2" >
751- < Checkbox
752- id = "run-as-task"
753- checked = { runAsTask }
754- onCheckedChange = { ( checked : boolean ) =>
755- setRunAsTask ( checked )
756- }
757- />
758- < Label
759- htmlFor = "run-as-task"
760- className = "text-sm font-medium text-gray-700 dark:text-gray-300 cursor-pointer"
761- >
762- Run as task
763- </ Label >
764- </ div >
788+ { taskSupport !== "forbidden" && (
789+ < div className = "flex items-center space-x-2" >
790+ < Checkbox
791+ id = "run-as-task"
792+ checked = { runAsTask }
793+ onCheckedChange = { ( checked : boolean ) =>
794+ setRunAsTask ( checked )
795+ }
796+ disabled = { taskSupport === "required" }
797+ />
798+ < Label
799+ htmlFor = "run-as-task"
800+ className = "text-sm font-medium text-gray-700 dark:text-gray-300 cursor-pointer"
801+ >
802+ Run as task
803+ </ Label >
804+ </ div >
805+ ) }
765806 < Button
766807 onClick = { async ( ) => {
767808 // Validate JSON inputs before calling tool
0 commit comments