MCPcopy Create free account
hub / github.com/TanStack/ai / tools

Method tools

packages/ai-mcp/src/client.ts:122–182  ·  view source on GitHub ↗
(
    defsOrOptions?: ReadonlyArray<AnyToolDefinition> | ToolsOptions,
    maybeOptions: ToolsOptions = {},
  )

Source from the content-addressed store, hash-verified

120 }
121
122 async tools(
123 defsOrOptions?: ReadonlyArray<AnyToolDefinition> | ToolsOptions,
124 maybeOptions: ToolsOptions = {},
125 ): Promise<Array<ServerTool>> {
126 if (this.#closed) throw new MCPConnectionError('MCP client is closed')
127
128 const isDefs = Array.isArray(defsOrOptions)
129 const options: ToolsOptions = isDefs
130 ? maybeOptions
131 : // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
132 ((defsOrOptions as ToolsOptions) ?? {}) // SDK interop: defsOrOptions may be undefined at runtime even though TS types it as ToolsOptions here
133
134 let tools: Array<ServerTool>
135 if (isDefs) {
136 // Explicit path: bind each TanStack toolDefinition to the server by name.
137 const available = new Map(
138 (await this.#client.listTools()).tools.map((t) => [t.name, t]),
139 )
140 tools = (defsOrOptions as ReadonlyArray<AnyToolDefinition>).map((def) => {
141 const serverTool = available.get(def.name)
142 if (!serverTool) throw new MCPToolNotFoundError(def.name)
143 // Explicitly binding a task-required tool is an error (it would fail
144 // on every callTool with -32600) — unlike discovery, which skips them.
145 if (requiresTaskExecution(serverTool))
146 throw new MCPTaskRequiredToolError(def.name)
147 const tool = def.server(
148 makeMcpExecute(this.#client, def.name, Boolean(def.outputSchema)),
149 ) as ServerTool
150 if (this.prefix) tool.name = `${this.prefix}_${def.name}`
151 if (options.lazy) tool.lazy = true
152 // Stamp MCP metadata so `serverToolNameOf` (and the call handler) can
153 // recover the UNPREFIXED native name + serverId — mirror toServerTools.
154 // `metadata.mcp` is `unknown`; only spread it when it's a plain object.
155 const existingMcp = tool.metadata?.mcp
156 const mcpBase =
157 existingMcp !== null && typeof existingMcp === 'object'
158 ? existingMcp
159 : {}
160 tool.metadata = {
161 ...tool.metadata,
162 mcp: { ...mcpBase, serverToolName: def.name, serverId: this.prefix },
163 }
164 return tool
165 })
166 } else {
167 // Auto-discovery path.
168 const defs = (await this.#client.listTools()).tools
169 tools = toServerTools(this.#client, defs, {
170 prefix: this.prefix,
171 lazy: options.lazy,
172 })
173 }
174
175 // Local duplicate guard (within one client's own list — applies to both branches).
176 const seen = new Set<string>()
177 for (const t of tools) {
178 if (seen.has(t.name)) throw new DuplicateToolNameError(t.name)
179 seen.add(t.name)

Callers 12

configMethod · 0.45
configMethod · 0.45
toolsFunction · 0.45
createMcpAppCallHandlerFunction · 0.45
pool.test.tsFile · 0.45
types.test-d.tsFile · 0.45
client.test.tsFile · 0.45
api.mcp-manual.tsFile · 0.45
probeFunction · 0.45
api.mcp-test.tsFile · 0.45

Calls 5

requiresTaskExecutionFunction · 0.90
makeMcpExecuteFunction · 0.90
toServerToolsFunction · 0.90
hasMethod · 0.80
getMethod · 0.65

Tested by

no test coverage detected