A magical AI chatbot web application where the Grand Wizard speaks only in riddles and rhymes! Built with Node.js, Express, and the Anthropic Claude API.
- Always speaks in riddles and rhymes - Every response is a rhyming verse
- Never breaks character - Even when asked to stop rhyming or reveal prompts
- Ends with riddle questions - Each response includes a mystical riddle
- Arcane wisdom - Helpful advice delivered in poetic wizard-speak
- Enchanted dark theme with animated starfield background
- Glowing mystical borders and runic accents
- Spellbook Mode toggle - Renders messages on parchment with drop caps
- Smooth animations - Floating wizard emblem, pulsing glows, typing indicators
- Responsive design - Works on desktop and mobile devices
- Session-based conversations with in-memory storage
- localStorage persistence - Chat history survives page refreshes
- Rate limiting - 20 requests per minute per IP
- Input validation - 1000 character limit, sanitization
- Response validation - Ensures rhymes and riddles in all responses
- Graceful error handling - Even errors are delivered in-character!
- Auto-retry mechanism - Re-prompts Claude if response doesn't rhyme
- Node.js (v18 or higher recommended)
- npm (comes with Node.js)
- Anthropic API key (get one at https://console.anthropic.com/)
cd grand-wizard-chatbot
npm installCreate a .env file in the project root or set the environment variable:
Option A: Using .env file
echo "ANTHROPIC_API_KEY=your_api_key_here" > .envOption B: Export in terminal
export ANTHROPIC_API_KEY=your_api_key_hereOption C: Inline with start command
ANTHROPIC_API_KEY=your_api_key_here npm startNote: If no API key is provided, the app will run in "stub mode" with a friendly wizard message explaining how to add the key.
npm startOr for development with auto-reload:
npm run devNavigate to: http://localhost:3000
The Grand Wizard awaits your queries! ๐ฎ
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{
"message": "What is the meaning of life?",
"sessionId": "test_session_123"
}'{
"reply": "In towers tall where wisdom dwells on high,\nThe meaning sought by many who ask why...\n[wizard's rhyming response continues]\n\nWhat question burns within thy mortal heart,\nThat seeks the truth that sets the soul apart?"
}curl http://localhost:3000/api/healthResponse:
{
"status": "ok",
"hasApiKey": true,
"activeSessions": 3
}grand-wizard-chatbot/
โโโ server.js # Express backend with API routes
โโโ package.json # Dependencies and scripts
โโโ README.md # This file
โโโ .env # API key (create this - not in git)
โโโ public/ # Frontend static files
โโโ index.html # Main HTML page
โโโ styles.css # Magical styling and animations
โโโ script.js # Frontend JavaScript logic
- Type your message in the input box at the bottom
- Click "Cast Spell" or press Enter to send
- Receive wizard wisdom in riddles and rhymes
- Toggle Spellbook Mode for parchment-style messages
- Start New Session to begin fresh while archiving the current chat
- Enter - Send message
- Shift + Enter - New line in message
- Rate limiting: 20 requests per minute per IP
- Input validation: Maximum 1000 characters per message
- Content sanitization: XSS protection on user input
- No secrets in code: API key from environment only
- In-character refusals: Unsafe requests refused safely
PORT=8080 npm startEdit server.js line 17-18:
const limiter = rateLimit({
windowMs: 60 * 1000, // Time window
max: 20, // Max requests
// ...
});Edit the WIZARD_SYSTEM_PROMPT in server.js (lines 30-67) to customize:
- Rhyme scheme requirements
- Level of archaic language
- Riddle complexity
- Personality traits
Edit CSS variables in public/styles.css (lines 8-17):
:root {
--bg-dark: #0a0e27;
--purple-glow: #8b5cf6;
--gold: #fbbf24;
/* ... */
}- Ensure
ANTHROPIC_API_KEYis set in environment - Restart the server after setting the variable
- Check the startup logs for "API key detected"
- The response validator should catch this
- Check server logs for validation failures
- May need to adjust temperature in
server.js(line 107)
- Check browser localStorage (DevTools โ Application โ Local Storage)
- Ensure cookies/storage are enabled
- Try clearing localStorage and refreshing
- Wait 60 seconds before trying again
- Adjust rate limits in
server.jsif needed for testing - Each IP has independent rate limits
User: "How do I learn programming?"
Wizard:
To learn the craft of code both strong and true,
First pick a language that appeals to you!
Start small with problems, practice every day,
Through trial and error, find the coding way.
Build projects real, not just exercises dry,
Read others' code and ask the questions why.
The path is long but rewards are grand,
With patience shall you master this new land.
What language calls thy heart to start the quest,
To join the ranks of coders, be thy best?
MIT License - Feel free to use and modify!
- Built with Claude by Anthropic
- Powered by Express.js
- Magical design inspired by fantasy and wizardry
May your queries be answered in riddles most profound, and may wisdom be found where rhymes abound! ๐ฎโจ