Documentation Index
Fetch the complete documentation index at: https://docs-staging.skybridge.tech/llms.txt
Use this file to discover all available pages before exploring further.
TypeScript utilities for extracting types from your MCP server.
Import
import type {
InferTools,
ToolNames,
ToolInput,
ToolOutput,
ToolResponseMetadata,
} from "skybridge/server";
Extract the full tool registry from a server type:
import type { InferTools } from "skybridge/server";
import type { AppType } from "./server";
type Tools = InferTools<AppType>;
// { "search-hotels": ToolDef<...>, "hotel-details": ToolDef<...> }
Get a union of all tool names:
import type { ToolNames } from "skybridge/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"); // OK
logToolCall("invalid-tool"); // Type error
Get the input type for a specific tool:
import type { ToolInput } from "skybridge/server";
import type { AppType } from "./server";
type SearchInput = ToolInput<AppType, "search-hotels">;
// { city: string; checkIn: string; checkOut: string; guests?: number }
Get the output type for a specific tool:
import type { ToolOutput } from "skybridge/server";
import type { AppType } from "./server";
type SearchOutput = ToolOutput<AppType, "search-hotels">;
// { hotels: Array<{ id: string; name: string; price: number }> }
Get the response metadata type for a specific tool:
import type { ToolResponseMetadata } from "skybridge/server";
import type { AppType } from "./server";
type SearchMeta = ToolResponseMetadata<AppType, "search-hotels">;
// { searchId: string; cached: boolean } | undefined
Usage Examples
Type-safe Component Props
import type { ToolOutput } from "skybridge/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
import type { ToolInput, ToolOutput, ToolNames } from "skybridge/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 typed
const result = await callServerTool("search-hotels", {
city: "Paris",
checkIn: "2025-01-01",
checkOut: "2025-01-05",
});
// result is typed as SearchOutput
import type { ToolNames, ToolOutput } from "skybridge/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
The type system uses TypeScript’s conditional types and mapped types:
// Simplified version of how InferTools works
type InferTools<ServerType> = ServerType extends {
$types: McpServerTypes<infer Registry>;
}
? Registry
: never;
// The $types property carries type information without runtime cost
class 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
}
}