A Next.js application that converts natural language queries into SQL using Claude AI (Anthropic) and LangChain. The agent uses tool calling to autonomously generate and execute SQL queries against a persistent SQLite database containing customer and order data.
- AI-Powered SQL Generation: Uses Claude Sonnet 4.5 to convert natural language to SQL queries
- Tool-Based Agent: LangGraph ReAct agent with database query tool for autonomous SQL execution
- Interactive Chat Interface: Real-time conversation with the AI agent
- Persistent SQLite Database: File-based database (data.db) with sample customer and order data
- Message History: Maintains full conversation context across queries
- TypeScript: Full type safety throughout the application
- Framework: Next.js 16
- AI/LLM: Anthropic Claude (via @langchain/anthropic)
- Agent Framework: LangGraph
- Database: SQLite3
- Styling: Tailwind CSS
- Language: TypeScript
text-to-sql/
├── src/
│ ├── app/ # Next.js app directory
│ │ ├── actions.ts # Server actions for AI agent
│ │ └── page.tsx # Main chat interface
│ └── lib/ # Shared libraries
│ ├── constants.ts # Database table schemas
│ └── database.ts # SQLite database setup
├── scripts/
│ └── seed.ts # Database seeding script
├── .env.local # Environment variables (not in repo)
├── .env.local.dist # Environment template
└── package.json
- Node.js 20.9.0 or higher
- npm, yarn, or pnpm
- Anthropic API key
-
Clone the repository
git clone https://github.com/marac19901990/text-to-sql.git cd text-to-sql -
Install dependencies
npm install
-
Set up environment variables
Copy the template and add your API key:
cp .env.local.dist .env.local
Edit
.env.localand add your Anthropic API key:ANTHROPIC_API_KEY=sk-ant-api03-xxxxxxxxxxxxxGet your API key from: https://console.anthropic.com/settings/keys
-
Seed the database
npm run seed
This creates
data.dband populates it with 10 customers and 20 orders. -
Run the development server
npm run dev
-
Open the application
Navigate to http://localhost:3000
Simply type natural language questions about the data in the chat interface:
- "Show me all customers"
- "Which customer has the most orders?"
- "What are the total shipping costs by customer?"
- "Find orders created in August 2024"
The AI agent will:
- Analyze your natural language question
- Use the
get_from_dbtool to generate and execute SQL queries - Return the results in a readable format
The application includes two tables:
Customer Table:
id- Customer IDemail- Customer emailname- Customer name
Order Table:
id- Order IDcreatedate- Order creation dateshippingcost- Shipping costcustomerid- Foreign key to customercarrier- Shipping carriertrackingid- Tracking number
npm run dev- Start development servernpm run build- Build for productionnpm start- Start production servernpm run seed- Seed the database with sample datanpm run lint- Run ESLint
The project includes VSCode settings for:
- Format on save
- Format on paste
Settings are in .vscode/settings.json
ANTHROPIC_API_KEY- Your Anthropic API key (required)
- Define the schema in
src/lib/constants.ts - Add seed data in
src/lib/database.ts - Run
npm run seedto populate
The agent configuration is in src/app/actions.ts:
- Model:
claude-sonnet-4-20250514(Claude Sonnet 4.5) - Temperature: 0 (deterministic)
- Tools:
get_from_db- executes SQL queries against the database - System prompt: Defined in
src/app/page.tsx
The get_from_db tool:
- Receives SQL query as input
- Validates schema using Zod
- Executes query via
execute()function - Returns JSON stringified results
Execute SQL queries using the execute function from src/lib/database.ts
- User sends message from
page.tsx(client component) - Message serialized to
StoredMessageformat - Server action in
actions.tsprocesses with Claude - Response serialized and sent back to client
- Client updates UI with new messages
User Input → HumanMessage → serialize → Server Action
↓
Claude Agent (ReAct)
↓
Tool: get_from_db
↓
Execute SQL Query
↓
AI Response ← deserialize ← StoredMessage ← Agent Response
- User sends a message: Natural language question typed in the chat
- Message serialization: Converted to LangChain's
StoredMessageformat - Server action invoked:
message()function inactions.tsreceives the message history - Agent reasoning: Claude analyzes the question and determines it needs database data
- Tool calling: Agent calls
get_from_dbtool with generated SQL query - Query execution: SQL query runs against the SQLite database
- Tool response: Results returned to the agent as JSON
- Final response: Agent formulates natural language response with the data
- UI update: Response displayed in the chat interface
- Ensure
.env.localexists and containsANTHROPIC_API_KEY - Restart the dev server after adding the key
- Update to Node.js 20.9.0 or higher
- Use nvm:
nvm install 20 && nvm use 20
- Ensure
data.dbfile was created (check withls -lh data.db) - Check that
src/lib/constants.tsexports table schemas - Run
npm run seedmanually - Check console for error messages
- Verify the database has data:
sqlite3 data.db "SELECT COUNT(*) FROM customer;"
- The
seed()function must properly wait for async operations - Ensure all
db.run()calls use callbacks and resolve/reject appropriately - Re-run
npm run seedafter fixing async issues
MIT
- Built with Next.js
- Powered by Anthropic Claude
- Agent framework by LangChain