@@ -32,7 +32,14 @@ function sanitizeName(name: string) {
3232 return name . replace ( / [ ^ a - z A - Z 0 - 9 . _ - ] / g, "_" ) . slice ( 0 , 64 ) ;
3333}
3434
35- async function listServerTools ( server : McpServerConfig ) {
35+ type ListedTool = {
36+ name ?: string ;
37+ inputSchema ?: Record < string , unknown > ;
38+ description ?: string ;
39+ annotations ?: { title ?: string } ;
40+ } ;
41+
42+ async function listServerTools ( server : McpServerConfig ) : Promise < ListedTool [ ] > {
3643 const url = new URL ( server . url ) ;
3744 const client = new Client ( { name : "chat-ui-mcp" , version : "0.1.0" } ) ;
3845 try {
@@ -49,7 +56,7 @@ async function listServerTools(server: McpServerConfig) {
4956 }
5057
5158 const response = await client . listTools ( { } ) ;
52- return Array . isArray ( response ?. tools ) ? response . tools : [ ] ;
59+ return Array . isArray ( response ?. tools ) ? ( response . tools as ListedTool [ ] ) : [ ] ;
5360 } finally {
5461 try {
5562 await client . close ?.( ) ;
@@ -71,59 +78,64 @@ export async function getOpenAiToolsForMcp(
7178 const tools : OpenAiTool [ ] = [ ] ;
7279 const mapping : Record < string , McpToolMapping > = { } ;
7380
74- const seenNames = new Set < string > ( ) ;
75-
76- const pushToolDefinition = (
77- name : string ,
78- description : string | undefined ,
79- parameters : Record < string , unknown > | undefined ,
80- ) => {
81- if ( seenNames . has ( name ) ) return ;
82- tools . push ( {
83- type : "function" ,
84- function : {
85- name,
86- description,
87- parameters,
88- } ,
89- } ) ;
90- seenNames . add ( name ) ;
91- } ;
92-
93- for ( const server of servers ) {
94- try {
95- const serverTools = await listServerTools ( server ) ;
96- for ( const tool of serverTools as any [ ] ) {
97- const parameters =
98- tool . inputSchema && typeof tool . inputSchema === "object" ? tool . inputSchema : undefined ;
99- const description = tool . description ?? tool ?. annotations ?. title ;
100-
101- const primaryName = sanitizeName ( `${ server . name } .${ tool . name } ` ) ;
102- pushToolDefinition ( primaryName , description , parameters ) ;
103- mapping [ primaryName ] = {
104- fnName : primaryName ,
105- server : server . name ,
106- tool : tool . name ,
107- } ;
108-
109- const plainName = sanitizeName ( tool . name ) ;
110- if ( ! ( plainName in mapping ) ) {
111- pushToolDefinition ( plainName , description , parameters ) ;
112- mapping [ plainName ] = {
113- fnName : plainName ,
114- server : server . name ,
115- tool : tool . name ,
116- } ;
117- }
118- }
119- } catch {
120- // Ignore individual server failures
121- continue ;
122- }
123- }
124-
125- cache = { fetchedAt : now , ttlMs, tools, mapping } ;
126- return { tools, mapping } ;
81+ const seenNames = new Set < string > ( ) ;
82+
83+ const pushToolDefinition = (
84+ name : string ,
85+ description : string | undefined ,
86+ parameters : Record < string , unknown > | undefined
87+ ) => {
88+ if ( seenNames . has ( name ) ) return ;
89+ tools . push ( {
90+ type : "function" ,
91+ function : {
92+ name,
93+ description,
94+ parameters,
95+ } ,
96+ } ) ;
97+ seenNames . add ( name ) ;
98+ } ;
99+
100+ for ( const server of servers ) {
101+ try {
102+ const serverTools = await listServerTools ( server ) ;
103+ for ( const tool of serverTools ) {
104+ if ( typeof tool . name !== "string" || tool . name . trim ( ) . length === 0 ) {
105+ continue ;
106+ }
107+
108+ const parameters =
109+ tool . inputSchema && typeof tool . inputSchema === "object" ? tool . inputSchema : undefined ;
110+ const description = tool . description ?? tool . annotations ?. title ;
111+ const toolName = tool . name ;
112+
113+ const primaryName = sanitizeName ( `${ server . name } .${ toolName } ` ) ;
114+ pushToolDefinition ( primaryName , description , parameters ) ;
115+ mapping [ primaryName ] = {
116+ fnName : primaryName ,
117+ server : server . name ,
118+ tool : toolName ,
119+ } ;
120+
121+ const plainName = sanitizeName ( toolName ) ;
122+ if ( ! ( plainName in mapping ) ) {
123+ pushToolDefinition ( plainName , description , parameters ) ;
124+ mapping [ plainName ] = {
125+ fnName : plainName ,
126+ server : server . name ,
127+ tool : toolName ,
128+ } ;
129+ }
130+ }
131+ } catch {
132+ // Ignore individual server failures
133+ continue ;
134+ }
135+ }
136+
137+ cache = { fetchedAt : now , ttlMs, tools, mapping } ;
138+ return { tools, mapping } ;
127139}
128140
129141export function resetMcpToolsCache ( ) {
0 commit comments