Type Utilities
TypeScript utilities for extracting types from your MCP server.
Import
Section titled “Import”import type { InferTools, ToolNames, ToolInput, ToolOutput, ToolResponseMetadata,} from "@usefractal/frac/server";InferTools
Section titled “InferTools”Extract the full tool registry from a server type:
import type { InferTools } from "@usefractal/frac/server";import type { AppType } from "./server";
type Tools = InferTools<AppType>;// { "search-hotels": ToolDef<...>, "hotel-details": ToolDef<...> }ToolNames
Section titled “ToolNames”Get a union of all tool names:
import type { ToolNames } from "@usefractal/frac/server";import type { AppType } from "./server";
type Names = ToolNames<AppType>;// "search-hotels" | "hotel-details"Use for type-safe tool name parameters:
function logToolCall(name: ToolNames<AppType>) { console.log(`Called: ${name}`);}
logToolCall("search-hotels"); // OKlogToolCall("invalid-tool"); // Type errorToolInput
Section titled “ToolInput”Get the input type for a specific tool:
import type { ToolInput } from "@usefractal/frac/server";import type { AppType } from "./server";
type SearchInput = ToolInput<AppType, "search-hotels">;// { city: string; checkIn: string; checkOut: string; guests?: number }ToolOutput
Section titled “ToolOutput”Get the output type for a specific tool:
import type { ToolOutput } from "@usefractal/frac/server";import type { AppType } from "./server";
type SearchOutput = ToolOutput<AppType, "search-hotels">;// { hotels: Array<{ id: string; name: string; price: number }> }ToolResponseMetadata
Section titled “ToolResponseMetadata”Get the response metadata type for a specific tool:
import type { ToolResponseMetadata } from "@usefractal/frac/server";import type { AppType } from "./server";
type SearchMeta = ToolResponseMetadata<AppType, "search-hotels">;// { searchId: string; cached: boolean } | undefinedUsage Examples
Section titled “Usage Examples”Type-safe Component Props
Section titled “Type-safe Component Props”import type { ToolOutput } from "@usefractal/frac/server";import type { AppType } from "./server";
type HotelData = ToolOutput<AppType, "search-hotels">;
function HotelList({ hotels }: { hotels: HotelData["hotels"] }) { return ( <ul> {hotels.map(hotel => ( <li key={hotel.id}>{hotel.name}</li> ))} </ul> );}Type-safe API Wrapper
Section titled “Type-safe API Wrapper”import type { ToolInput, ToolOutput, ToolNames } from "@usefractal/frac/server";import type { AppType } from "./server";
async function callServerTool<T extends ToolNames<AppType>>( name: T, input: ToolInput<AppType, T>): Promise<ToolOutput<AppType, T>> { // Implementation}
// Usage - fully typedconst result = await callServerTool("search-hotels", { city: "Paris", checkIn: "2025-01-01", checkOut: "2025-01-05",});// result is typed as SearchOutputConditional Types Based on Tool
Section titled “Conditional Types Based on Tool”import type { ToolNames, ToolOutput } from "@usefractal/frac/server";import type { AppType } from "./server";
function renderToolResult<T extends ToolNames<AppType>>( toolName: T, output: ToolOutput<AppType, T>) { switch (toolName) { case "search-hotels": // TypeScript knows output shape return <HotelList hotels={output.hotels} />; case "hotel-details": return <HotelDetails hotel={output} />; }}How It Works
Section titled “How It Works”The type system uses TypeScript’s conditional types and mapped types:
// Simplified version of how InferTools workstype InferTools<ServerType> = ServerType extends { $types: McpServerTypes<infer Registry>;} ? Registry : never;
// The $types property carries type information without runtime costclass McpServer<Registry = {}> { $types!: McpServerTypes<Registry>;
registerTool<Name, Input, Output>(...): McpServer< Registry & { [K in Name]: ToolDef<Input, Output> } > { // Each call returns a new type with the tool added }}Related
Section titled “Related”- generateHelpers - Generate typed hooks
- Type Safety concept - Understanding the type system
- McpServer - Server class with $types