@@ -1965,6 +1965,80 @@ describe('Zod v4', () => {
19651965 expect ( result . tools [ 0 ] ! . _meta ) . toBeUndefined ( ) ;
19661966 } ) ;
19671967
1968+ test ( 'should include type: object in inputSchema for discriminated union schemas' , async ( ) => {
1969+ const mcpServer = new McpServer ( {
1970+ name : 'test server' ,
1971+ version : '1.0'
1972+ } ) ;
1973+ const client = new Client ( {
1974+ name : 'test client' ,
1975+ version : '1.0'
1976+ } ) ;
1977+
1978+ const schema = z . discriminatedUnion ( 'action' , [
1979+ z . object ( { action : z . literal ( 'create' ) , name : z . string ( ) } ) ,
1980+ z . object ( { action : z . literal ( 'delete' ) , id : z . number ( ) } )
1981+ ] ) ;
1982+
1983+ mcpServer . registerTool (
1984+ 'discriminated-tool' ,
1985+ {
1986+ description : 'A tool with discriminated union input' ,
1987+ inputSchema : schema
1988+ } ,
1989+ async ( args ) => ( {
1990+ content : [ { type : 'text' , text : JSON . stringify ( args ) } ]
1991+ } )
1992+ ) ;
1993+
1994+ const [ clientTransport , serverTransport ] = InMemoryTransport . createLinkedPair ( ) ;
1995+ await Promise . all ( [ client . connect ( clientTransport ) , mcpServer . server . connect ( serverTransport ) ] ) ;
1996+
1997+ const result = await client . request ( { method : 'tools/list' } ) ;
1998+
1999+ expect ( result . tools ) . toHaveLength ( 1 ) ;
2000+ expect ( result . tools [ 0 ] ! . inputSchema ) . toHaveProperty ( 'type' , 'object' ) ;
2001+ expect ( result . tools [ 0 ] ! . inputSchema ) . toHaveProperty ( 'oneOf' ) ;
2002+ } ) ;
2003+
2004+ test ( 'should include type: object in outputSchema for discriminated union schemas' , async ( ) => {
2005+ const mcpServer = new McpServer ( {
2006+ name : 'test server' ,
2007+ version : '1.0'
2008+ } ) ;
2009+ const client = new Client ( {
2010+ name : 'test client' ,
2011+ version : '1.0'
2012+ } ) ;
2013+
2014+ const outputSchema = z . discriminatedUnion ( 'status' , [
2015+ z . object ( { status : z . literal ( 'ok' ) , data : z . string ( ) } ) ,
2016+ z . object ( { status : z . literal ( 'error' ) , message : z . string ( ) } )
2017+ ] ) ;
2018+
2019+ mcpServer . registerTool (
2020+ 'output-union-tool' ,
2021+ {
2022+ description : 'A tool with discriminated union output' ,
2023+ inputSchema : z . object ( { query : z . string ( ) } ) ,
2024+ outputSchema : outputSchema
2025+ } ,
2026+ async ( { query } ) => ( {
2027+ content : [ { type : 'text' , text : query } ] ,
2028+ structuredContent : { status : 'ok' as const , data : query }
2029+ } )
2030+ ) ;
2031+
2032+ const [ clientTransport , serverTransport ] = InMemoryTransport . createLinkedPair ( ) ;
2033+ await Promise . all ( [ client . connect ( clientTransport ) , mcpServer . server . connect ( serverTransport ) ] ) ;
2034+
2035+ const result = await client . request ( { method : 'tools/list' } ) ;
2036+
2037+ expect ( result . tools ) . toHaveLength ( 1 ) ;
2038+ expect ( result . tools [ 0 ] ! . outputSchema ) . toHaveProperty ( 'type' , 'object' ) ;
2039+ expect ( result . tools [ 0 ] ! . outputSchema ) . toHaveProperty ( 'oneOf' ) ;
2040+ } ) ;
2041+
19682042 test ( 'should include execution field in listTools response when tool has execution settings' , async ( ) => {
19692043 const taskStore = new InMemoryTaskStore ( ) ;
19702044
0 commit comments