Skip to main content
This guide will walk you through creating your first Thinkwell agent in just a few minutes. Homebrew is the simplest way to install Thinkwell system-wide:
brew install dherman/thinkwell/thinkwell

Manual Installation

mkdir -p ~/.local/bin
curl -L https://github.com/dherman/thinkwell/releases/latest/download/thinkwell-darwin-arm64.tar.gz | tar -xz -C ~/.local/bin
mv ~/.local/bin/thinkwell-darwin-arm64 ~/.local/bin/thinkwell

Zero-Install (Node.js)

If you don’t want to install anything, you can use Thinkwell via npx:
npx -y thinkwell --help

Create Your First Agent

Create a new TypeScript file called greeting.ts:
import { open } from "thinkwell";

/**
 * A friendly greeting.
 * @JSONSchema
 */
export interface Greeting {
  /** The greeting message */
  message: string;
}

async function main() {
  const agent = await open('claude');
  try {
    const greeting = await agent
      .think(Greeting.Schema)
      .text("Create a friendly greeting message.")
      .run();
    console.log(greeting.message);
  } finally {
    agent.close();
  }
}
main();

Run Your Script

The Thinkwell CLI can run TypeScript files directly without any compilation step:
thinkwell greeting.ts
You should see a friendly greeting message printed to your console.

Understanding the Code

Let’s break down the key concepts:

Imports

Thinkwell provides a standard npm package import:
  • thinkwell - The main package, providing open(), Agent, and other APIs

The @JSONSchema Pattern

The @JSONSchema JSDoc tag is central to how Thinkwell works. When you annotate an interface with @JSONSchema, Thinkwell automatically generates a JSON Schema and attaches it as a static Schema property:
/**
 * A friendly greeting.
 * @JSONSchema
 */
export interface Greeting {
  /** The greeting message */
  message: string;
}
This allows you to use Greeting.Schema when calling agent.think(), which tells the agent what structured output to produce. The JSDoc comments on properties become descriptions in the generated schema, helping the AI understand what each field should contain.

Agent Lifecycle

  1. Open - open('claude') connects to the AI backend by name
  2. Think - agent.think(Schema).text(prompt).run() sends your prompt and returns structured output matching your schema
  3. Close - Always close the agent when done to clean up resources

Next Steps

Now that you have a basic agent working, explore:
  • API Overview - Learn about schemas, tools, and the Plan API
  • Sessions - Create multi-turn conversations with persistent context