6. Follow-along: @tool and useToolInfo
1m

Follow-along: @tool and useToolInfo

MCP hosts discover tools from the manifest generated from your . The @tool (and clear descriptions) turn ordinary into AI-callable units with stable names and shapes.

Add @tool and descriptions

We have three in our app:

  • GetLatestReviewsAndLocations
  • GetLocationDetails
  • SubmitReview

For each one, add the @tool right after the . Add a short description at the top of the operation. Good descriptions will help the AI assistant understand what the tool does and how to best use it.

  1. Open up dev/flyby/src/pages/Homepage.tsx.

    dev/flyby/src/pages/Homepage.tsx
    "Shows latest traveler reviews and all locations to explore."
    query GetLatestReviewsAndLocations @tool {
    # ...
    }
  2. Open up dev/flyby/src/pages/Location.tsx.

    dev/flyby/src/pages/Location.tsx
    "Shows details and reviews for a space travel location."
    query GetLocationDetails($locationId: ID!) @tool {
    # ...
    }
  3. Open up dev/flyby/src/pages/SubmitReview.tsx.

    dev/flyby/src/pages/SubmitReview.tsx
    "Submits a new review with a rating and comment for a location."
    mutation SubmitReview($locationReview: LocationReviewInput!) @tool {
    # ...
    }

Route the UI from tool context

  1. In dev/flyby/src/App.tsx, add the following imports:

    dev/flyby/src/App.tsx
    import { useToolInfo } from "@apollo/client-ai-apps/react";
    import { useState } from "react";
    import { MemoryRouter, Route, Routes } from "react-router-dom";
  2. Add the following code to the App component:

    dev/flyby/src/App.tsx
    const toolInfo = useToolInfo();
    function getInitialRoute() {
    switch (toolInfo?.toolName) {
    case "GetLatestReviewsAndLocations":
    return "/";
    case "GetLocationDetails":
    return `/location/${toolInfo.toolInput.locationId}`;
    case "SubmitReview": {
    const id = toolInfo.toolInput.locationReview.locationId;
    return id ? `/location/${id}` : "/";
    }
    default: {
    // @ts-expect-error Fallthrough case for `toolInfo` which should be
    // `never`. If expect-error is reported as unused, it means there is a
    // missing case above.
    console.warn(`Unable to match route for tool '${toolInfo?.toolName}`);
    return "/";
    }
    }
    }
    const [initialRoute] = useState(getInitialRoute);

    Here, we're using the useToolInfo hook to get the tool information. We're then using a switch statement to determine the route based on the tool name.

    For example, if the tool name is GetLatestReviewsAndLocations, we'll navigate to the home page. If the tool name is GetLocationDetails, we'll navigate to that specific location page.

  3. Finally, replace the BrowserRouter with a MemoryRouter.

    dev/flyby/src/App.tsx
    - <BrowserRouter>
    + <MemoryRouter initialEntries={[initialRoute]}>
    {/* Routes defined here */}
    + </MemoryRouter>
    - </BrowserRouter>
Task!
Previous