Toolforge Docs

Introduction

Build AI-powered apps from backend logic using Tool Forge. Turns your server logic into UI, workflows, and HITL.

What is Tool Forge?

Tool Forge is an internal tool builder that eliminates UI development headaches by automatically generating polished web applications from your backend logic. Focus on what you do best—writing code—and let Tool Forge handle the rest.

Build and deploy business applications in minutes, not months. Define your tools in TypeScript, and Tool Forge transforms them into fully interactive web applications with forms, tables, charts, loaders, and more—without writing a single line of frontend code.

Why Tool Forge?

Traditional internal tool development often means juggling frontend frameworks, managing state, designing forms, and maintaining separate codebases. Tool Forge changes this paradigm:

  • Backend-First Development: Write your business logic in TypeScript. Tool Forge generates the UI automatically.
  • Type-Safe by Design: Full TypeScript support with Zod validation schemas ensures your inputs are validated before they reach your logic.
  • Real-Time Collaboration: Tools are instantly available to your team through a shared dashboard.
  • Human-in-the-Loop (HITL): Build workflows that require human approval, confirmation dialogs, and step-by-step interactions.

Core Concepts

Tools

A Tool is the fundamental building block in Tool Forge. It's a TypeScript function that defines what inputs to collect from users and what logic to execute. Tool Forge automatically generates the UI for collecting inputs and displaying results.

import { defineTool } from '@toolforge-js/sdk/components'
import * as z from 'zod'

export default defineTool({
  name: 'Hello World',
  description: 'A simple greeting tool',
  handler: async ({ io }) => {
    const name = await io.textInput({
      label: 'Enter your name',
      validationSchema: z.string().min(1),
    })

    return `Hello, ${name}!`
  },
})

IO Primitives

The io object provides a rich set of input and interaction primitives:

PrimitiveDescription
io.textInput()Collect text from users with optional validation
io.numberInput()Numeric input with min/max constraints
io.selectInput()Dropdowns, radio buttons, or radio cards
io.searchInput()Async search with custom handlers
io.tableInput()Interactive tables for data selection
io.formInput()Multi-field forms with Zod validation
io.confirm()Confirmation dialogs for critical actions
io.dateInput()Date and datetime pickers
io.loader()Show loading states during async operations
io.progressLoader()Track progress of batch operations
io.message()Display informational messages to users

Block Outputs

The block object lets you create rich output components:

  • Charts: Area, bar, line, donut, combo, heatmap, and spark charts
  • Progress Indicators: Progress bars and circles
  • Data Display: KPI cards, tables, and tracker blocks
  • Layout: Flexible grid layouts for combining multiple blocks
return block.layout({
  children: [
    {
      element: block.kpiCard({
        name: 'Total Revenue',
        value: 125000,
        valueFormat: { type: 'currency', currency: 'USD' },
      }),
      colSpan: 6,
    },
    {
      element: block.areaChart({
        title: 'Monthly Trend',
        data: chartData,
        index: 'month',
        categories: ['revenue'],
      }),
      colSpan: 6,
    },
  ],
})

Agents

Agents extend tools with multi-step workflows and context management. Define steps that can update shared context and transition between states—perfect for complex business processes like refund workflows, content generation, or approval chains. Learn more in the Agent documentation.

import { defineAgent } from '@toolforge-js/sdk/components'
import * as z from 'zod'

export default defineAgent({
  name: 'Writer Agent',
  description: 'An agent that helps with writing tasks',
  contextSchema: z.object({
    topic: z.string(),
    wordCount: z.number().default(500),
    content: z.string().optional(),
  }),
  steps: {
    ideaGeneration: {
      name: 'Idea Generation',
      handler: async ({ context, updateContext, io }) => {
        // Generate and select ideas
        const selectedIdea = await io.selectInput({
          /* ... */
        })
        updateContext({ idea: selectedIdea })
        return 'Idea selected!'
      },
    },
    writing: {
      name: 'Writing',
      handler: async ({ context, updateContext }) => {
        // Generate content based on selected idea
        // ...
      },
    },
  },
})

Key Features

Next Steps

On this page