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

openforge

v0.1.1

Published

Open-source AI Agent Builder — create, share, and run AI agents with MCP, tool-calling, and custom provider support

Readme


Build AI agents that use tools, connect to MCP servers, and work with any AI provider (OpenAI, Anthropic, Gemini, Groq, local models). Each agent is a portable JSON manifest that anyone can share, install, and run.

✨ Features

  • 🔌 Full MCP Support — stdio, SSE, and WebSocket transports
  • 🔧 Built-in Tools — HTTP fetch, JSON parse, text transform, date/time
  • 🎨 Custom Tools — Write JS handlers, sandboxed via VM
  • 🤖 Any AI Provider — Bring your own: OpenAI, Anthropic, Gemini, Ollama, anything
  • 📦 Portable Agents — JSON manifests that anyone can share and install
  • Event Streaming — Real-time execution tracking via EventEmitter
  • 🖥️ CLI Included — Create, run, and manage agents from the terminal

🚀 Quick Start

Use OpenForge from the CLI with no other app — just Node.js and an OpenAI API key.

# Install globally
npm install -g openforge

# Or run without installing: npx openforge generate "description"
# Or from a clone: git clone ... && cd openforge && node bin/openforge.js generate "description"

# Set your API key
export OPENAI_API_KEY=sk-xxx

# Build an agent from a description (AI designs, tests, and delivers it)
openforge generate "an agent that checks my calendar and sends a daily summary"

# Or create from template, then run
openforge create my-agent "A helpful assistant"
openforge run my-agent "What's the weather in NYC?"

📦 Programmatic Usage

const { AgentBuilder } = require('openforge');

const builder = new AgentBuilder({
  aiProvider: async (messages, model, tools) => {
    // Use any AI provider — OpenAI, Anthropic, Gemini, etc.
    const { OpenAI } = require('openai');
    const client = new OpenAI();
    return await client.chat.completions.create({
      model: model || 'gpt-4o-mini',
      messages,
      tools: tools?.length > 0 ? tools : undefined,
    });
  },
});

await builder.initialize();

// Run an agent
const result = await builder.runAgent('my-agent', 'Hello!');
console.log(result.output);

// Stream execution events
const { runtime, resultPromise } = await builder.runAgentStreaming('my-agent', 'Hello!');
runtime.on('tool_call', (data) => console.log(`🔧 ${data.tool}`));
runtime.on('agent_response', (data) => console.log(`💬 ${data.content}`));
const finalResult = await resultPromise;

await builder.shutdown();

🏗️ Architecture

┌──────────────────────────────────────────┐
│              OpenForge                    │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│  │ Runtime   │ │ Registry │ │  Loader  │ │
│  │(executor) │ │ (tools)  │ │ (agents) │ │
│  └─────┬─────┘ └─────┬────┘ └────┬─────┘ │
│        │              │           │        │
│  ┌─────┴──────────────┴───────────┤       │
│  │         Tool Registry          │       │
│  ├────────┬────────┬──────────────┤       │
│  │  MCP   │Built-in│   Custom     │       │
│  │ Client │ Tools  │  JS/VM       │       │
│  └──┬─────┘────────┘──────────────┘       │
└─────┼─────────────────────────────────────┘
      │
  MCP Servers (any!)
  - stdio (spawn local process)
  - SSE (HTTP streaming)
  - WebSocket (persistent)

📋 Agent Manifest

Every agent is defined by a .agent.json file:

{
  "name": "my-agent",
  "version": "1.0.0",
  "description": "What this agent does",
  "systemPrompt": "You are a helpful assistant...",
  "runtime": {
    "model": "gpt-4o-mini",
    "maxLoops": 10,
    "timeoutMs": 60000
  },
  "tools": {
    "require": ["builtin:http_fetch", "builtin:json_parse"],
    "optional": ["mcp:calendar"]
  },
  "ui": {
    "icon": "🤖"
  }
}

🔌 MCP Support

Full Model Context Protocol support — connect to any MCP server:

// stdio — spawn a local MCP server
await builder.addMcpServer('calculator', {
  transport: 'stdio',
  command: 'npx',
  args: ['-y', '@example/mcp-calculator'],
});

// SSE — connect to an HTTP MCP server
await builder.addMcpServer('api', {
  transport: 'sse',
  url: 'http://localhost:3001/sse',
});

// WebSocket — persistent connection
await builder.addMcpServer('realtime', {
  transport: 'websocket',
  url: 'ws://localhost:8080',
});

🔧 Tool Providers

| Provider | Prefix | Description | |----------|--------|-------------| | Built-in | builtin: | http_fetch, json_parse, text_transform, date_time, wait | | MCP | mcp: | Any MCP-compliant server (stdio, SSE, WebSocket) | | Custom | custom: | Agent-local JS handlers (sandboxed via VM) |

🎨 Creating Custom Tools

Define custom tools in your agent manifest:

{
  "tools": {
    "custom": [
      {
        "name": "analyze_data",
        "description": "Analyze data from a CSV",
        "parameters": {
          "type": "object",
          "properties": {
            "data": { "type": "string" }
          }
        },
        "handler": "./tools/analyzeData.js"
      }
    ]
  }
}

Handler file (tools/analyzeData.js):

module.exports = async function(args, context) {
  const { data } = args;
  // Your analysis logic here
  return { success: true, result: 'Analysis complete' };
};

🏗️ Build agents from natural language

Generate a full agent (manifest + system prompt + tools) from a short description. The AI designs the agent, runs validation tests, fixes issues, and saves it to ~/.openforge/agents/.

export OPENAI_API_KEY=sk-xxx

# One-shot: describe what you want
openforge generate "an agent that monitors GitHub PRs and sends Slack summaries"
openforge generate "a browser agent that checks LinkedIn messages daily"

# Optional: skip browser/mac probes if you don't need those tools
OPENFORGE_SKIP_BROWSER=1 OPENFORGE_SKIP_MAC=1 openforge generate "an agent that fetches JSON from an API and summarizes it"

After generation you can run and test the agent:

openforge run <agent-name> "your request"
openforge test <agent-name>

🖥️ CLI Reference

openforge generate <description>        # AI-build an agent from natural language (needs OPENAI_API_KEY)
openforge test <name>                    # Run validation tests on an agent
openforge list                          # List installed agents
openforge info <name>                   # Show agent details
openforge create <name> [description]   # Create from template
openforge run <name> <input>            # Run (needs OPENAI_API_KEY)
openforge tools                         # List available tools
openforge validate <path>               # Validate manifest
openforge help                          # Show all commands

⚡ Event Streaming

The runtime emits events during execution for real-time tracking:

const { runtime, resultPromise } = await builder.runAgentStreaming('my-agent', input);

runtime.on('execution_started', (data) => { /* { id, agent } */ });
runtime.on('loop_iteration', (data) => { /* { id, loop, maxLoops } */ });
runtime.on('tool_call', (data) => { /* { id, tool, args } */ });
runtime.on('tool_result', (data) => { /* { id, tool, result } */ });
runtime.on('agent_response', (data) => { /* { id, content } */ });
runtime.on('execution_completed', (data) => { /* { id, agent, duration, loops } */ });

const result = await resultPromise;

📖 API Reference

new AgentBuilder(options)

| Option | Type | Required | Description | |--------|------|----------|-------------| | aiProvider | Function | ✅ | async (messages, model, tools, meta) => OpenAI-format response | | agentDir | string | | Custom agent directory (default: ~/.openforge/agents/) | | mcpServers | Object | | Initial MCP server configs | | additionalAgentDirs | string[] | | Extra directories to scan for agents |

Methods

| Method | Returns | Description | |--------|---------|-------------| | initialize() | Promise | Must be called before any operations | | runAgent(name, input, ctx) | Promise<Result> | Run an agent synchronously | | runAgentStreaming(name, input, ctx) | { runtime, resultPromise } | Run with event streaming | | createAgent(config) | AgentManifest | Create a new agent | | deleteAgent(name) | boolean | Delete an agent | | listAgents(filter) | Agent[] | List all agents | | addMcpServer(name, config) | Promise<Server> | Connect MCP server | | removeMcpServer(name) | Promise | Disconnect MCP server | | listTools() | Tool[] | List all available tools | | shutdown() | Promise | Graceful shutdown |

🤝 Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines.

📄 License

MIT — build whatever you want.