MCPcopy
hub / github.com/codeaashu/claude-code / call

Function call

src/tools/ToolSearchTool/ToolSearchTool.ts:328–434  ·  view source on GitHub ↗
(input, { options: { tools }, getAppState })

Source from the content-addressed store, hash-verified

326 return outputSchema()
327 },
328 async call(input, { options: { tools }, getAppState }) {
329 const { query, max_results = 5 } = input
330
331 const deferredTools = tools.filter(isDeferredTool)
332 maybeInvalidateCache(deferredTools)
333
334 // Check for MCP servers still connecting
335 function getPendingServerNames(): string[] | undefined {
336 const appState = getAppState()
337 const pending = appState.mcp.clients.filter(c => c.type === 'pending')
338 return pending.length > 0 ? pending.map(s => s.name) : undefined
339 }
340
341 // Helper to log search outcome
342 function logSearchOutcome(
343 matches: string[],
344 queryType: 'select' | 'keyword',
345 ): void {
346 logEvent('tengu_tool_search_outcome', {
347 query:
348 query as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
349 queryType:
350 queryType as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
351 matchCount: matches.length,
352 totalDeferredTools: deferredTools.length,
353 maxResults: max_results,
354 hasMatches: matches.length > 0,
355 })
356 }
357
358 // Check for select: prefix — direct tool selection.
359 // Supports comma-separated multi-select: `select:A,B,C`.
360 // If a name isn't in the deferred set but IS in the full tool set,
361 // we still return it — the tool is already loaded, so "selecting" it
362 // is a harmless no-op that lets the model proceed without retry churn.
363 const selectMatch = query.match(/^select:(.+)$/i)
364 if (selectMatch) {
365 const requested = selectMatch[1]!
366 .split(',')
367 .map(s => s.trim())
368 .filter(Boolean)
369
370 const found: string[] = []
371 const missing: string[] = []
372 for (const toolName of requested) {
373 const tool =
374 findToolByName(deferredTools, toolName) ??
375 findToolByName(tools, toolName)
376 if (tool) {
377 if (!found.includes(tool.name)) found.push(tool.name)
378 } else {
379 missing.push(toolName)
380 }
381 }
382
383 if (found.length === 0) {
384 logForDebugging(
385 `ToolSearchTool: select failed — none found: ${missing.join(', ')}`,

Callers

nothing calls this directly

Calls 8

maybeInvalidateCacheFunction · 0.85
findToolByNameFunction · 0.85
logForDebuggingFunction · 0.85
logSearchOutcomeFunction · 0.85
getPendingServerNamesFunction · 0.85
buildSearchResultFunction · 0.85
searchToolsWithKeywordsFunction · 0.85
pushMethod · 0.45

Tested by

no test coverage detected