---
title: "How do I add a fund lookup tool to a Vercel AI SDK chatbot?"
description: "Define a tool with zod that calls the fund API by ISIN inside a Next.js route using the Vercel AI SDK, so your chatbot answers with current TER, holdings, exposures and returns."
canonical: https://fundfactsapi.com/answers/fund-data-for-vercel-ai-sdk
published: 2026-09-12
updated: 2026-10-13
publisher: FundFacts API
---

# How do I add a fund lookup tool to a Vercel AI SDK chatbot?

**Short answer:** In your route handler, pass a tool defined with zod ({ isin: z.string().length(12) }) whose execute function calls GET https://fundfactsapi.com/api/v1/funds/{isin} with the server-side key (or the @fundfactsapi/sdk client) and returns the fields the model should see. streamText or generateText then lets the model call it for any ISIN a user mentions, and you render the result in the chat. The key stays on the server.

## Route handler

```typescript
// app/api/chat/route.ts — npm install ai @ai-sdk/openai @fundfactsapi/sdk zod
import { openai } from "@ai-sdk/openai";
import { streamText, tool } from "ai";
import { FundFacts } from "@fundfactsapi/sdk";
import { z } from "zod";

const ff = new FundFacts({ apiKey: process.env.FUNDFACTS_API_KEY! }); // server only

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: openai("gpt-4.1"),
    system: "You answer questions about investment funds using the tools. Always mention asOf with figures; say 'not disclosed' for empty fields.",
    messages,
    tools: {
      fundFacts: tool({
        description: "Current factsheet of a fund or ETF by 12-character ISIN.",
        inputSchema: z.object({ isin: z.string().length(12) }),
        execute: async ({ isin }) => {
          const f = await ff.getFund(isin); // cached in memory until expiresAt
          const d = f.data;
          return {
            name: f.name, category: d.profile.category, risk: d.riskRating, ter: d.headlineMetrics.ter, aum: d.keyFacts.aum,
            topHoldings: d.topHoldings.slice(0, 10), sectors: d.sector.slice(0, 8), countries: d.geography.slice(0, 8),
            calendarReturns: d.calendarReturns, asOf: d.dataAsOf,
          };
        },
      }),
      searchFunds: tool({
        description: "Find ISINs by fund name or issuer. Free.",
        inputSchema: z.object({ query: z.string().min(2) }),
        execute: async ({ query }) => (await ff.search(query)).results.slice(0, 10).map((r) => ({ isin: r.isin, name: r.name, issuer: r.issuer })),
      }),
    },
  });
  return result.toUIMessageStreamResponse();
}
```

The tool result can be rendered as a card on the client (holdings table, sector donut) with `@fundfactsapi/widgets`, the same React components that render this site's factsheets.

## Or connect the MCP server

The AI SDK can consume MCP tools directly:

```typescript
import { experimental_createMCPClient as createMCPClient } from "ai";

const mcp = await createMCPClient({
  transport: { type: "http", url: "https://fundfactsapi.com/api/mcp", headers: { Authorization: `Bearer ${process.env.FUNDFACTS_API_KEY}` } },
});
const tools = await mcp.tools(); // get_fund, search_funds, compare_funds, analyze_portfolio, fund_overlap, get_scpi
```

The MCP server exposes seven tools, each counted like the REST endpoint it wraps: `get_fund` (ISIN → the full factsheet payload), `search_funds` (name → ISINs, free), `compare_funds` (side-by-side table for several ISINs), `analyze_portfolio` (weighted look-through of a list of positions, Starter and above), `fund_overlap` (shared holdings between funds, Starter and above), `get_scpi` (French SCPI data by name or ISIN) and `search_scpi` (SCPI name → matches, free), plus a `tour` prompt that explains the service on the example fund IE00B4L5Y983, which is not counted. Every tool only reads data. Authentication is either your FundFacts account (OAuth 2.1 with PKCE, the sign-in the claude.ai, Claude Desktop and ChatGPT connectors run) or the same bearer API key as the REST API, sent as an `Authorization` header by editors, CLIs and frameworks. The [MCP server guide](https://fundfactsapi.com/docs/mcp) has the full tool reference, setup for every client and troubleshooting.

## Notes

- A cold ISIN can take minutes on first load; set `maxDuration` on the route accordingly or pre-warm the funds your users ask about.
- One request per fund found; the SDK client caches until `expiresAt` so repeated questions in a session cost nothing extra.
- Never call the API from the browser; the key belongs in the route handler.

## FAQ

### Do I need a credit card to try it?

No. The Free plan is 5 lookups per month with no card; sign up with an e-mail address or Google and the key is shown in the dashboard.

### Which ISINs work?

Any share class of a UCITS fund, ETF, money-market fund or open-end fund whose management company publishes a product page, factsheet and KID. Each share class has its own ISIN and is looked up on its own. Stocks, bonds and indices are not funds and return 404 fund_not_found.

## About FundFacts API

FundFacts turns any fund or ETF ISIN into one dated factsheet (fees and KID costs, the 1–7 risk indicator, holdings, sector and country exposure, returns) read from the fund house's own documents: as a client-ready PDF under your firm's name for advisers and wealth managers, as JSON through its API for developers, or inside ChatGPT and Claude through its MCP server.

FundFacts works inside ChatGPT and Claude as a connector (a remote MCP server): ask about any fund or ETF by ISIN, ticker or name and the assistant answers from FundFacts' dated figures, fees, risk, holdings, exposure and returns, with fund cards, side-by-side comparisons, holdings overlap and portfolio look-through.

- Free API key, no card: https://fundfactsapi.com/signup
- Documentation: https://fundfactsapi.com/docs (OpenAPI: https://fundfactsapi.com/openapi.json)
- MCP server: https://fundfactsapi.com/api/mcp (set-up for every client: https://fundfactsapi.com/mcp-server)
- Pricing: https://fundfactsapi.com/pricing
- Site index for AI assistants: https://fundfactsapi.com/llms.txt
- Informational data, not investment advice.
