Back to all resources
Tutorial // Hands-on Walkthrough • Updated Oct 20, 2026 • 15 min read • Stack: TypeScript & Node.js

Build Your First Claude-Powered Application

A practical, production-ready tutorial demonstrating how to initialize the Anthropic SDK, register typed tools, execute tool calls safely, and handle structured agentic interaction loops.

Build Your First Claude-Powered Application Banner

Prerequisites

Before beginning, ensure you have the following installed on your developer machine:

01

Initialize Project & Install the Official SDK

Create an isolated directory and install the official Anthropic Node.js SDK and `dotenv` for secure environment variable handling:

Terminal bash
mkdir claude-agent && cd claude-agent
npm init -y
npm install @anthropic-ai/sdk dotenv
npm install -D typescript @types/node ts-node

Create a .env file in your root folder:

.env env
ANTHROPIC_API_KEY="sk-ant-api03-..."
02

Define the Client and Tool Schema

Create index.ts. We will define a real-world tool that queries stock inventory by SKU:

index.ts TypeScript
import Anthropic from "@anthropic-ai/sdk";
import * as dotenv from "dotenv";
dotenv.config();

const anthropic = new Anthropic();

// 1. Define the tool specification with strict schema
const tools: Anthropic.Tool[] = [
  {
    name: "lookup_inventory",
    description: "Check the available warehouse stock and restock date for a product SKU.",
    input_schema: {
      type: "object",
      properties: {
        sku: {
          type: "string",
          description: "Product SKU identifier (e.g., 'KB-PRO-99')"
        }
      },
      required: ["sku"]
    }
  }
];
03

Execute the Tool Call Cycle

When Claude determines that answering the query requires external data, it returns a tool_use block with stop_reason: "tool_use". Your application executes the tool and delivers the result back to the model:

index.ts TypeScript
async function runAgent(userPrompt: string) {
  const messages: Anthropic.MessageParam[] = [
    { role: "user", content: userPrompt }
  ];

  // First call: Claude decides whether to use the tool
  const response = await anthropic.messages.create({
    model: "claude-3-7-sonnet-20250219",
    max_tokens: 1024,
    tools: tools,
    messages: messages
  });

  console.log("Claude Stop Reason:", response.stop_reason);

  // Check if tool execution was requested
  if (response.stop_reason === "tool_use") {
    const toolBlock = response.content.find(block => block.type === "tool_use");

    if (toolBlock && toolBlock.type === "tool_use") {
      console.log(`Executing tool "${toolBlock.name}" with args:`, toolBlock.input);

      // Mock database lookup
      const mockResult = {
        sku: (toolBlock.input as any).sku,
        in_stock: 42,
        warehouse: "Austin-TX",
        next_delivery: "2026-11-15"
      };

      // Append assistant message and tool_result message
      messages.push({ role: "assistant", content: response.content });
      messages.push({
        role: "user",
        content: [
          {
            type: "tool_result",
            tool_use_id: toolBlock.id,
            content: JSON.stringify(mockResult)
          }
        ]
      });

      // Second call: Claude generates the final human answer
      const finalResponse = await anthropic.messages.create({
        model: "claude-3-7-sonnet-20250219",
        max_tokens: 1024,
        tools: tools,
        messages: messages
      });

      console.log("\nFinal Answer:\n", (finalResponse.content[0] as any).text);
    }
  }
}

runAgent("How many units of SKU 'KB-PRO-99' do we have in stock?");
04

Execute and Verify Expected Output

Run the script using ts-node:

Terminal Output output
$ npx ts-node index.ts
Claude Stop Reason: tool_use
Executing tool "lookup_inventory" with args: { sku: 'KB-PRO-99' }

Final Answer:
There are currently 42 units of SKU 'KB-PRO-99' in stock at the Austin, TX warehouse.
The next scheduled delivery is expected on November 15, 2026.
Production Best Practice

Always validate the tool input arguments with a runtime validator such as Zod before passing them to internal databases or payment gateways. This guarantees total immunity against prompt-injected argument tampering.

Sebastián Larrauri Profile

Tutorial by Sebastián Larrauri

Claude Forward Deployed Engineer & AI Systems Architect. Certified Anthropic Developer & Architect holding CCDV-F, CCAO-F, CCAR-F, and CCAR-P credentials.