Skip to content

generateHelpers

generateHelpers is a factory function that creates fully typed versions of useCallTool and useToolInfo hooks with end-to-end type inference from your MCP server definition. Inspired by TRPC and Hono, it provides a type-safe, developer-friendly API that eliminates the need for manual type annotations.

If you’re familiar with TRPC or Hono, generateHelpers provides a similar developer experience:

  • Full type inference: Tool names, inputs, and outputs are automatically inferred from your server
  • Autocomplete: Get IntelliSense suggestions for all available tools
  • Type safety: Catch errors at compile time, not runtime

Instead of manually typing each hook call:

// ❌ Without generateHelpers - manual type annotations required
const { callTool } = useCallTool<
{ destination: string },
{ structuredContent: { results: string[] } }
>("search-trip");

You get automatic type inference:

// ✅ With generateHelpers - fully typed, zero annotations needed
const { callTool } = useCallTool("search-trip");
// TypeScript knows everything: tool name, input shape, output shape

Your MCP server must use method chaining for type inference to work. See Type Safety: Method Chaining for details.

// ✅ Works — chain registerTool calls
const server = new McpServer({ name: "my-app", version: "1.0" }, {})
.registerTool(
{
name: "search-trip",
inputSchema: { destination: z.string() },
view: { component: "search-trip" },
},
async ({ destination }) => {
return { content: `Found trips to ${destination}` };
},
);
export type AppType = typeof server;

Export your server type so it can be imported in your view code:

src/server.ts
export type AppType = typeof server;

Create a bridge file that connects your server types to your views:

src/helpers.ts
import type { AppType } from "./server"; // type-only import
import { generateHelpers } from "@usefractal/frac/web";
export const { useCallTool, useToolInfo } = generateHelpers<AppType>();

Import and use the typed hooks throughout your app:

src/views/search-trip.tsx
import { useCallTool, useToolInfo } from "../helpers";
export default function SearchTrip() {
const { callTool, isPending } = useCallTool("search-trip");
// ^ autocomplete for tool names
const toolInfo = useToolInfo<"search-trip">();
// ^ autocomplete for view names
const handleSearch = () => {
callTool({ destination: "Spain" });
// ^ autocomplete for input fields
};
return (
<div>
<button onClick={handleSearch} disabled={isPending}>
Search
</button>
{toolInfo.isSuccess && (
<div>Found {toolInfo.output.structuredContent.totalCount} results</div>
// ^ typed output
)}
</div>
);
}
const { useCallTool, useToolInfo } = generateHelpers<T>();
T extends McpServer<AnyToolRegistry>

Required

The type of your MCP server instance. Use typeof server to get the type:

The server type must be defined using method chaining for type inference to work correctly. See Prerequisites for more details.

An object containing typed versions of useCallTool and useToolInfo hooks:

A typed version of the useCallTool hook that provides autocomplete for tool names and full type inference for inputs and outputs.

const {
data,
error,
isError,
isIdle,
isPending,
isSuccess,
status,
callTool,
callToolAsync,
} = useCallTool<K extends Names>(name);
name: K extends Names

Required

The name of the tool to call. This must match a tool name from your server’s registry. TypeScript will provide autocomplete suggestions based on all registered tools and views.

The typed useCallTool returns the same structure as the untyped version, but with automatically inferred types. See the useCallTool API reference for detailed documentation on all return properties.

A typed version of the useToolInfo hook that provides autocomplete for tool names and full type inference for inputs, outputs, and response metadata.

const toolInfo = useToolInfo<K extends Names>();
K extends Names

Required

The name of the tool/view. This must match a tool name from your server’s registry. TypeScript will provide autocomplete suggestions based on all registered tools and views.

  • Chaining Required: Server must use method chaining for type inference to work
  • Runtime Types: Types are inferred at compile time; runtime validation still uses Zod schemas
  • Callback Return Type: Output types are inferred from the callback’s return value, not outputSchema