TypeScript SDK
The official TypeScript client for SkillRouter. Full type safety, tree-shakable, and works in Node.js, Deno, and edge runtimes.
View on GitHubInstallation
Install the SDK using your preferred package manager. Requires Node.js 18+ or a compatible runtime.
npm i @skillrouter/sdkOr with other package managers:yarn add @skillrouter/sdk / pnpm add @skillrouter/sdk
Quick Start
Initialize the client and start discovering skills with full type inference out of the box.
import { SkillRouter } from "@skillrouter/sdk";
// Initialize the client
const client = new SkillRouter({ apiKey: "sr_your_api_key" });
// Discover the best skill for a task
const result = await client.discover("Send a welcome email to new users");
console.log(result.skill.name); // "sendgrid-send-email"
console.log(result.confidence); // 0.97
// Execute the skill
const response = await client.execute(result.skill.id, {
to: "user@example.com",
subject: "Welcome!",
body: "Thanks for signing up.",
});
console.log(response.status); // "success"Client Initialization
The client constructor accepts a typed configuration object. All options except apiKey are optional.
import { SkillRouter } from "@skillrouter/sdk";
const client = new SkillRouter({
apiKey: "sr_your_api_key", // Required
baseUrl: "https://api.skillrouter.dev", // Optional
timeout: 30_000, // Optional, ms
maxRetries: 3, // Optional
});
// Or read the API key from SKILLROUTER_API_KEY env var
const client = new SkillRouter();Full Type Safety
Every method, parameter, and response is fully typed. Use generics to get precise types for skill execution results.
import type { Skill, DiscoverResult, ExecuteResponse } from "@skillrouter/sdk";
// Typed discovery results
const result: DiscoverResult = await client.discover("Send an email");
// Generic execute for typed responses
interface PaymentResult {
paymentId: string;
status: "succeeded" | "pending" | "failed";
amount: number;
}
const response = await client.execute<PaymentResult>(
"stripe-checkout",
{ amount: 2999, currency: "usd" }
);
// response.data is fully typed as PaymentResult
console.log(response.data.paymentId); // string
console.log(response.data.status); // "succeeded" | "pending" | "failed"
// Skill type includes all metadata
const skills: Skill[] = (await client.listSkills()).items;
skills.forEach((s) => {
s.id; // string
s.name; // string
s.provider; // string
s.category; // SkillCategory
});Core Methods
discover(query, options?)
Finds the best matching skill for a natural language query using semantic matching.
const result = await client.discover("Process a credit card payment", {
category: "payments", // Optional filter
topK: 3, // Return top 3 matches
threshold: 0.8, // Minimum confidence
});
console.log(result.skill.id); // "stripe-checkout"
console.log(result.confidence); // 0.95
// Multiple matches
result.matches.forEach((match) => {
console.log(`${match.skill.name}: ${match.confidence}`);
});execute<T>(skillId, params)
Executes a skill with the given parameters. Supports generics for typed responses.
const response = await client.execute("stripe-checkout", {
amount: 2999,
currency: "usd",
customerEmail: "buyer@example.com",
});
console.log(response.status); // "success"
console.log(response.data); // { paymentId: "pi_abc123", ... }
console.log(response.latencyMs); // 230listSkills(options?)
Returns a paginated list of available skills with optional filters.
const skills = await client.listSkills({
category: "payments",
provider: "stripe",
page: 1,
perPage: 20,
});
skills.items.forEach((skill) => {
console.log(`${skill.id}: ${skill.name}`);
});
console.log(`Total: ${skills.total}`);Error Handling
The SDK throws typed error classes that you can catch and narrow using instanceof.
import {
SkillRouterError, // Base error class
AuthenticationError, // Invalid or missing API key
RateLimitError, // Rate limit exceeded
SkillNotFoundError, // Skill ID does not exist
ExecutionError, // Skill execution failed
ValidationError, // Invalid parameters
} from "@skillrouter/sdk";
try {
const response = await client.execute("stripe-checkout", {
amount: 2999,
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error("Check your API key");
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}ms`);
} else if (error instanceof ValidationError) {
// Typed validation errors
error.errors.forEach((e) => {
console.error(`${e.field}: ${e.message}`);
});
} else if (error instanceof ExecutionError) {
console.error(`Execution failed: ${error.message}`);
} else if (error instanceof SkillRouterError) {
console.error(`Unexpected error: ${error.message}`);
}
}Tip: All error classes extend SkillRouterError, which itself extends Error. Each error includes a code property for programmatic handling.