The lightweight framework for building agents
# Add to your Claude Code skills
git clone https://github.com/ArtificialAnalysis/StirrupLast scanned: 5/25/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-05-25T08:22:59.680Z",
"semgrepRan": false,
"npmAuditRan": true,
"pipAuditRan": true
}Stirrup is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by ArtificialAnalysis. The lightweight framework for building agents. It has 493 GitHub stars.
Yes. Stirrup passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/ArtificialAnalysis/Stirrup" and add it to your Claude Code skills directory (see the Installation section above).
Stirrup is primarily written in Python. It is open-source under ArtificialAnalysis on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh Stirrup against similar tools.
No comments yet. Be the first to share your thoughts!
Stirrup is a lightweight framework, or starting point template, for building agents. It differs from other agent frameworks by:
Note: This is the Python implementation, StirrupJS is the Typescript implementation.
Tool interface allows easy tool definition# Core framework
pip install stirrup # or: uv add stirrup
# With all optional components
pip install 'stirrup[all]' # or: uv add 'stirrup[all]'
# Individual extras
pip install 'stirrup[litellm]' # or: uv add 'stirrup[litellm]'
pip install 'stirrup[docker]' # or: uv add 'stirrup[docker]'
pip install 'stirrup[e2b]' # or: uv add 'stirrup[e2b]'
pip install 'stirrup[mcp]' # or: uv add 'stirrup[mcp]'
pip install 'stirrup[browser]' # or: uv add 'stirrup[browser]'
import asyncio
from stirrup import Agent
from stirrup.clients.chat_completions_client import ChatCompletionsClient
async def main() -> None:
"""Run an agent that searches the web and creates a chart."""
# Create client using ChatCompletionsClient
# Automatically uses OPENROUTER_API_KEY environment variable
client = ChatCompletionsClient(
base_url="https://openrouter.ai/api/v1",
model="anthropic/claude-sonnet-4.5",
)
# 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)
agent = Agent(client=client, name="agent", max_turns=15)
# Run with session context - handles tool lifecycle, logging and file outputs
async with agent.session(output_dir="./output/getting_started_example") as session:
finish_params, history, metadata = 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 matplotlib showing the current population per year."""
)
print("Finish params: ", finish_params)
print("History: ", history)
print("Metadata: ", metadata)
if __name__ == "__main__":
asyncio.run(main())
Note: This example uses OpenRouter. Set
OPENROUTER_API_KEYin your environment before running. Web search requires aBRAVE_API_KEY. The agent will still work without it, but web search will be unavailable.
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
# Install in editable mode
pip install -e . # or: uv venv && uv pip install -e .
# Or with all optional dependencies
pip install -e '.[all]' # or: uv venv && uv pip install -e '.[all]'
See the Full Customization guide for more details.
Agent - Configures and runs the agent loop until a finish tool is called or max turns reachedsession() - Context manager that sets up tools, manages files, and handles cleanupTool - Define tools with Pydantic parametersToolProvider - Manage tools that require lifecycle (connections, temp directories, etc.)DEFAULT_TOOLS - Standard tools included by default: code execution and web toolsFor non-OpenAI providers, change the base URL of the ChatCompletionsClient, use the LiteLLMClient (requires installation of optional stirrup[litellm] dependencies), or create your own client.
# Create client using Deepseek's OpenAI-compatible endpoint
client = ChatCompletionsClient(
base_url="https://api.deepseek.com",
model="deepseek-chat", # or "deepseek-reasoner" for R1
api_key=os.environ["DEEPSEEK_API_KEY"],
)
agent = Agent(client=client, name="deepseek_agent")
# Ensure LiteLLM is added with: pip install 'stirrup[litellm]' # or: uv add 'stirrup[litellm]'
# Create LiteLLM client for Anthropic Claude
# See https://docs.litellm.ai/docs/providers for all supported providers
client = LiteLLMClient(
model_slug="anthropic/claude-sonnet-4-5",
max_tokens=200_000,
)
# Pass client to Agent - model info comes from client.model_slug
agent = Agent(
client=client,
name="claude_agent",
)
See LiteLLM Example or Deepseek Example for complete examples.
When you create an Agent without specifying tools, it uses DEFAULT_TOOLS:
| 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) |
import asyncio
from stirrup import Agent
from stirrup.clients.chat_completions_client import ChatCompletionsClient
from stirrup.tools import CALCULATOR_TOOL, DEFAULT_TOOLS
# Create client for OpenRouter
client = ChatCompletionsClient(
base_url="https://openrouter.ai/api/v1",
model="anthropic/claude-sonnet-4.5",
)
# Create agent with default tools + calculator tool
agent = Agent(
client=client,
name="web_calculator_agent",
tools=[*DEFAULT_TOOLS, CALCULATOR_TOOL],
)
from pydantic import BaseModel, Field
from stirrup import Agent, Tool, ToolResult, ToolUseCountMetadata
from stirrup.clients.chat_completions_client import ChatCompletionsClient
from stirrup.tools import DEFAULT_TOOLS
class GreetParams(BaseModel):
"""Parameters for the greet tool."""
name: str = Field(description="Name of the person to greet")
formal: bool = Field(default=False, description="Use formal greeting")
def greet(params: GreetParams) -> ToolResult[ToolUseCountMetadata]:
greeting = f"Good day, {params.name}." if params.formal else f"Hey {params.name}!"
return ToolResult(
content=greeting,
metadata=ToolUseCountMetadata(),
)
GREET_TOOL = Tool(
name="greet",
description="Greet someone by name",
parameters=GreetParams,
executor=greet,
)
# Create client for OpenRouter
client = ChatCompletionsClient(
base_url="https://openrouter.ai/api/v1",
model="anthropic/claude-sonnet-4.5",
)
# Add custom tool to default tools
agent = Agent(
client=client,
name="greeting_agent",
tools=[*DEFAULT_TOOLS, GREET_TOOL],
)
Full documentation: artificialanalysis.github.io/Stirrup
Build and serve loca