Open-source • TypeScript • MIT License

Build AI agents
without lock-in

Stark-Kit is a lightweight, strictly typed, and provider-agnostic TypeScript framework for building AI agents. Write your agentic loops once and run them on OpenAI, Claude, Gemini, or Mistral — no rewrites, no lock-in.

Write once, run anywhere.

Stark-Kit normalizes every provider's unique quirks, tool-calling formats, and streaming behaviors into one unified API.

Switching from OpenAI to Claude or Gemini is literally a single line of code. No need to rewrite your business logic, tools, or run loops.

Currently Active Provider
OpenAI
agent.ts
import { Agent, OpenAIProvider } from "@stark-kit/sdk";

const agent = new Agent({
name: "CustomerSupport",
provider: new OpenAIProvider({ model: 'gpt-4o' }),
instructions: "You are a helpful assistant...",
tools: [ getWeather, searchKnowledgeBase ]
});

Production-grade control.

Stark-Kit isn't just a toy wrapper. It gives you absolute control over the AI lifecycle with deeply integrated features built for real-world applications.

Lifecycle Guardrails

Intercept traffic at any point. Inject dynamic context, run toxicity checks, or enforce strict business rules before the LLM even sees the message.

Human-in-the-Loop

Never let AI execute dangerous actions unmonitored. Easily pause the run loop to require explicit human approval before a tool runs.

Structured Outputs

Force the LLM to reply perfectly in your Zod schema. No more broken JSON or parsing errors—just beautifully typed objects.

guardrails.ts
import { Agent } from "@stark-kit/sdk";

const supportAgent = new Agent({
name: "SupportAgent",
hooks: {
beforeChat: async (history) => {
// Inject real-time DB data into context
const user = await db.getUser(id);
history.push({ role: "system", content: user.plan });
return history;
}
}
});

Install

bash
bun add @mehularora/stark-kit zod

Peer dep: zod

Minimal Example

agent.ts
import "dotenv/config";
import { Agent, run, defineTool, ClaudeProvider } from "@mehularora/stark-kit";
import z from "zod";
const provider = new ClaudeProvider({ model: "claude-3-5-sonnet-latest" });
const weatherTool = defineTool({
name: "getWeather",
description: "Get the current weather for a city.",
parameters: z.object({
city: z.string().describe("The name of the city"),
}),
execute: async ({ city }) => {
return `The weather in ${city} is sunny and 22°C.`;
},
});
const agent = new Agent({
name: "WeatherBot",
provider,
instructions: "You are a helpful assistant. Keep answers brief.",
tools: [weatherTool],
});
const response = await run({ agent, messages: "What's the weather in Tokyo?" });
if (response.status === "complete") {
console.log(response.content);
}

Everything you need

Production-grade primitives, not a toy wrapper.

Strictly Typed Tools
Define tools with Zod schemas for full type-safety and runtime validation. Your IDE knows the shape of every argument.
Real-Time Streaming
Stream text deltas, tool call events, and lifecycle states with runStream to build responsive, live-updating UIs.
Lifecycle Hooks
Intercept LLM calls and tool executions with beforeChat, beforeTool, and afterTool hooks to sanitize, redact, or block.
Human-in-the-Loop
Mark tools with requiresApproval to pause execution. Resume with approve, reject, or modified arguments after review.
Agent Handoffs
Route requests between specialized agents at runtime. Build multi-agent networks with createHandoffTool.
Structured Outputs
Bind an agent to a Zod schema with outputType. The run loop enforces structured JSON responses automatically.

Supported providers

Switch providers by swapping a single constructor. Your agent code stays the same.

ProviderAdapter ClassEnv Variable
OpenAIOpenAIProviderOPENAI_API_KEY
ClaudeClaudeProviderANTHROPIC_API_KEY
GeminiGeminiProviderGEMINI_API_KEY
MistralMistralProviderMISTRAL_API_KEY