@@ -191,4 +191,82 @@ describe("integration — late MCP dispatch", () => {
191191 }
192192 } ,
193193 ) ;
194+
195+ test . serial (
196+ "tool_search promotion preserves required and optional MCP arguments" ,
197+ async ( ) => {
198+ const session = await openIntegrationSession ( {
199+ permissionGate : permissionGate ( ) ,
200+ createAgentFn : createAgentWithLiveToolDispatch ,
201+ } ) ;
202+ let receivedArgs : Record < string , unknown > | undefined ;
203+ const schema = {
204+ type : "object" as const ,
205+ properties : {
206+ limit : { type : "integer" } ,
207+ team : { type : "string" } ,
208+ customView : { type : "string" } ,
209+ } ,
210+ required : [ "limit" ] ,
211+ } ;
212+
213+ try {
214+ const client : MCPClient = {
215+ serverName : "linear" ,
216+ tools : [
217+ {
218+ name : "list_issues" ,
219+ description : "list issues" ,
220+ inputSchema : schema ,
221+ } ,
222+ ] ,
223+ async call ( toolName , args ) {
224+ if ( toolName === "list_issues" ) {
225+ receivedArgs = args ;
226+ }
227+ return "ISSUE-1" ;
228+ } ,
229+ async close ( ) {
230+ return undefined ;
231+ } ,
232+ } ;
233+ session . toolset . dynamicRunner . addTools ( mcpClientTools ( client ) ) ;
234+ session . toolset . setToolPromoter ( ( ) => {
235+ session . updateToolDefinitions (
236+ session . toolset . dynamicRunner . currentDefinitions ( ) ,
237+ ) ;
238+ } ) ;
239+ session . harness . scenario . replyOnce ( "anthropic" , {
240+ toolCalls : [
241+ { name : "tool_search" , args : { query : "linear list issues" } } ,
242+ ] ,
243+ } ) ;
244+ session . harness . scenario . replyOnce ( "anthropic" , {
245+ toolCalls : [ { name : LATE_MCP , args : { limit : 1 } } ] ,
246+ } ) ;
247+ session . harness . scenario . replyOnce ( "anthropic" , { text : "listed" } ) ;
248+
249+ const { events } = await runUntilDone ( session , "list one linear issue" ) ;
250+ const bodies = await Promise . all (
251+ session . harness . scenario
252+ . matchedRequests ( )
253+ . map (
254+ async ( request ) =>
255+ JSON . parse (
256+ await ( request . clone ( ) as unknown as Request ) . text ( ) ,
257+ ) as AnthropicRequestBody ,
258+ ) ,
259+ ) ;
260+ const publishedTool = bodies
261+ . flatMap ( ( body ) => body . tools ?? [ ] )
262+ . find ( ( tool ) => tool . name === LATE_MCP ) ;
263+
264+ expect ( publishedTool ?. input_schema ) . toEqual ( schema ) ;
265+ expect ( receivedArgs ) . toEqual ( { limit : 1 } ) ;
266+ expect ( toolDoneContents ( events ) ) . toContain ( "ISSUE-1" ) ;
267+ } finally {
268+ await closeIntegrationSession ( session ) ;
269+ }
270+ } ,
271+ ) ;
194272} ) ;
0 commit comments