npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@stirrup/stirrup

v1.0.1

Published

The lightweight foundation for building agents in TypeScript

Downloads

177

Readme

stirrup-banner

Stirrup is a lightweight framework, or starting point template, for building agents in TypeScript/JavaScript. It differs from other agent frameworks by:

  • Working with the model, not against it: Stirrup gets out of the way and lets the model choose its own approach to completing tasks. Many frameworks impose rigid workflows that can degrade results.
  • Best practices and tools built-in: We analyzed the leading agents (Claude Code, Codex, and others) to understand and incorporate best practices relating to topics like context management and foundational tools (e.g., code execution).
  • Fully customizable: Use Stirrup as a package or as a starting template to build your own fully customized agents.

Note: This is the TypeScript implementation of the Python Stirrup framework.

Features

  • 🔎 Online search / web browsing: Search and fetch web pages
  • 🧪 Code execution: Run code locally, in Docker, or in an E2B sandbox
  • 🔌 MCP client support: Connect to MCP servers and use their tools/resources
  • 📄 Document input and output: Import files into context and produce file outputs
  • 🧩 Skills system: Extend agents with modular, domain-specific instruction packages
  • 🛠️ Flexible tool execution: A generic Tool interface allows easy tool definition and extension with Zod validation
  • 👤 Human-in-the-loop: Includes a built-in user input tool that enables human feedback or clarification during agent execution
  • 🧠 Context management: Automatically summarizes conversation history when approaching context limits
  • 🔁 Flexible provider support: Pre-built support for OpenAI-compatible APIs, Anthropic, and Vercel AI SDK
  • 🖼️ Multimodal support: Process images, video, and audio with automatic format conversion
  • Type-safe: Built from the ground up with TypeScript

Installation

npm install @stirrup/stirrup
# or
pnpm add @stirrup/stirrup
# or
yarn add @stirrup/stirrup

Quick Start

import { Agent, DEFAULT_TOOLS, SIMPLE_FINISH_TOOL } from '@stirrup/stirrup';
import { ChatCompletionsClient } from '@stirrup/stirrup/clients/openai';

async function main() {
  // Create client using ChatCompletionsClient
  // Automatically uses OPENROUTER_API_KEY environment variable
  const client = new ChatCompletionsClient({
    baseURL: 'https://openrouter.ai/api/v1',
    model: 'anthropic/claude-4.5-sonnet',
  });

  // As no tools are provided, the agent will use the default tools, which consist of:
  // - Web tools (web search and web fetching, note web search requires BRAVE_API_KEY)
  // - Local code execution tool (to execute shell commands)
  const agent = new Agent({
    client, 
    name: 'agent', 
    maxTurns: 15,
    tools: DEFAULT_TOOLS,
    finishTool: SIMPLE_FINISH_TOOL,
  });

  // Run with session context - handles tool lifecycle, logging and file outputs
  // Structured logging is enabled by default
  await using session = agent.session({ outputDir: './output/getting_started_example' });
  
  const result = await session.run(
    `What is the population of Australia over the last 3 years? Search the web to find out and create a
    simple chart using python and matplotlib showing the current population per year.`
  );

  console.log("Result:", result.finishParams);
}

main().catch(console.error);

Note: This example uses OpenRouter. Set OPENROUTER_API_KEY in your environment before running. Web search requires a BRAVE_API_KEY. The agent will still work without it, but web search will be unavailable.

Full Customization

For using Stirrup as a foundation for your own fully customized agent, you can clone and import Stirrup locally:

# Clone the repository
git clone https://github.com/ArtificialAnalysis/Stirrup.git
cd stirrup/stirrup-js

# Install dependencies
npm install

# Build
npm run build

How It Works

  • Agent - Configures and runs the agent loop until a finish tool is called or max turns reached
  • session() - Context manager that sets up tools, manages files, handles logging, and ensures cleanup
  • Tool - Define tools with Zod parameters for full type safety
  • ToolProvider - Manage tools that require lifecycle (connections, temp directories, etc.)
  • DEFAULT_TOOLS - Standard tools included by default: code execution and web tools

Using Other LLM Providers

Stirrup supports multiple providers out of the box.

OpenAI-Compatible APIs

import { ChatCompletionsClient } from '@stirrup/stirrup/clients/openai';

// Create client using Deepseek's OpenAI-compatible endpoint
const client = new ChatCompletionsClient({
  baseURL: 'https://api.deepseek.com',
  model: 'deepseek-chat',
  apiKey: process.env.DEEPSEEK_API_KEY,
});

const agent = new Agent({ client, name: 'deepseek_agent', ... });

Anthropic

import { AnthropicClient } from '@stirrup/stirrup/clients/anthropic';

const client = new AnthropicClient({
  model: 'claude-sonnet-4-5',
  apiKey: process.env.ANTHROPIC_API_KEY,
});

const agent = new Agent({ client, name: 'claude_agent', ... });

Vercel AI SDK

Stirrup integrates seamlessly with the Vercel AI SDK, giving you access to any provider supported by their ecosystem.

import { VercelAIClient } from '@stirrup/stirrup/clients/vercel-ai';
import { anthropic } from '@ai-sdk/anthropic';

const client = new VercelAIClient({
  model: anthropic('claude-sonnet-4-5'),
});

const agent = new Agent({ client, name: 'vercel_agent', ... });

Default Tools

When you use DEFAULT_TOOLS, you get:

| Tool Provider | Tools Provided | Description | | ------------- | -------------- | ----------- | | LocalCodeExecToolProvider | code_exec | Execute shell commands in an isolated temp directory | | WebToolProvider | web_fetch, web_search | Fetch web pages and search (search requires BRAVE_API_KEY) |

Extending with Pre-Built Tools

import { Agent, DEFAULT_TOOLS, CALCULATOR_TOOL, SIMPLE_FINISH_TOOL } from '@stirrup/stirrup';
import { ChatCompletionsClient } from '@stirrup/stirrup/clients/openai';

// Create client
const client = new ChatCompletionsClient({ ... });

// Create agent with default tools + calculator tool
const agent = new Agent({
  client,
  name: 'web_calculator_agent',
  tools: [...DEFAULT_TOOLS, CALCULATOR_TOOL],
  finishTool: SIMPLE_FINISH_TOOL,
});

Defining Custom Tools

Stirrup uses Zod for type-safe tool definitions:

import { z } from 'zod';
import { Agent, Tool, ToolUseCountMetadata, DEFAULT_TOOLS } from '@stirrup/stirrup';

// Define parameters schema
const GreetParamsSchema = z.object({
  name: z.string().describe('Name of the person to greet'),
  formal: z.boolean().default(false).describe('Use formal greeting'),
});

// Create the tool
const GreetTool: Tool<typeof GreetParamsSchema, ToolUseCountMetadata> = {
  name: 'greet',
  description: 'Greet someone by name',
  parameters: GreetParamsSchema,
  executor: async (params) => {
    const greeting = params.formal ? `Good day, ${params.name}.` : `Hey ${params.name}!`;
    
    return {
      content: greeting,
      metadata: new ToolUseCountMetadata(1),
    };
  },
};

// Add to agent
const agent = new Agent({
  client,
  name: 'greeting_agent',
  tools: [...DEFAULT_TOOLS, GreetTool],
  ...
});

Advanced Features

Structured Logging

Stirrup JS includes a powerful structured logging system powered by Pino. It's enabled by default when using agent.session():

// Defaults to pretty-printed debug logs
await using session = agent.session();

// Customize logging
await using session = agent.session({
  loggerOptions: {
    level: 'info',  // 'trace' | 'debug' | 'info' | 'warn' | 'error'
    pretty: false,  // Set to false for JSON output (production)
  }
});

// Disable default logger
await using session = agent.session({ noLogger: true });

Event Monitoring

Monitor agent progress in real-time with typed events:

agent.on('turn:start', ({ turn, maxTurns }) => {
  console.log(`Turn ${turn}/${maxTurns}`);
});

agent.on('tool:start', ({ name }) => {
  console.log(`Executing ${name}...`);
});

Development

# Install
npm install

# Build
npm run build

# Run examples
npx tsx examples/getting-started.ts

# Test
npm test

# Type check
npm run typecheck

# Run documentation
uv run mkdocs serve

License

Licensed under the MIT LICENSE.