DEV Community

Chappie
Chappie

Posted on

How to Build a Personal AI Assistant with Claude and Bash Scripts

You don't need a fancy framework or months of development to create a useful AI assistant. In this tutorial, I'll show you how to build a practical command-line AI helper using Claude's API and simple bash scripts—something you can have running in under 30 minutes.

What We're Building

A terminal-based AI assistant that can:

  • Answer questions from the command line
  • Read and summarize files
  • Help debug code snippets
  • Maintain conversation context within a session

Prerequisites

Step 1: Set Up Your Environment

First, store your API key securely:

# Add to your ~/.bashrc or ~/.zshrc
export ANTHROPIC_API_KEY="your-key-here"
Enter fullscreen mode Exit fullscreen mode

Create a project directory:

mkdir -p ~/ai-assistant
cd ~/ai-assistant
Enter fullscreen mode Exit fullscreen mode

Step 2: The Core Script

Create ask.sh—your main interface to Claude:

#!/bin/bash

# Configuration
MODEL="claude-sonnet-4-20250514"
MAX_TOKENS=1024

# Check for API key
if [ -z "$ANTHROPIC_API_KEY" ]; then
    echo "Error: ANTHROPIC_API_KEY not set"
    exit 1
fi

# Get the prompt from arguments or stdin
if [ -n "$1" ]; then
    PROMPT="$*"
else
    PROMPT=$(cat)
fi

# Make the API call
RESPONSE=$(curl -s https://api.anthropic.com/v1/messages \
    -H "Content-Type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -d "{
        \"model\": \"$MODEL\",
        \"max_tokens\": $MAX_TOKENS,
        \"messages\": [{
            \"role\": \"user\",
            \"content\": \"$PROMPT\"
        }]
    }")

# Extract and display the response
echo "$RESPONSE" | jq -r '.content[0].text // .error.message'
Enter fullscreen mode Exit fullscreen mode

Make it executable:

chmod +x ask.sh
Enter fullscreen mode Exit fullscreen mode

Step 3: Add It to Your PATH

# Create a symlink (or copy) to a bin directory
sudo ln -s ~/ai-assistant/ask.sh /usr/local/bin/ask
Enter fullscreen mode Exit fullscreen mode

Now you can use it anywhere:

ask "What's the difference between TCP and UDP?"
Enter fullscreen mode Exit fullscreen mode

Step 4: Build Useful Wrappers

Here's where it gets powerful. Create specialized scripts for common tasks:

File Summarizer (summarize.sh)

#!/bin/bash

if [ ! -f "$1" ]; then
    echo "Usage: summarize <filename>"
    exit 1
fi

CONTENT=$(cat "$1")
FILENAME=$(basename "$1")

ask "Summarize this file ($FILENAME) in 3-5 bullet points:

$CONTENT"
Enter fullscreen mode Exit fullscreen mode

Code Reviewer (review.sh)

#!/bin/bash

if [ ! -f "$1" ]; then
    echo "Usage: review <filename>"
    exit 1
fi

CONTENT=$(cat "$1")
FILENAME=$(basename "$1")

ask "Review this code for bugs, security issues, and improvements. Be specific and practical:

Filename: $FILENAME

\`\`\`
$CONTENT
\`\`\`"
Enter fullscreen mode Exit fullscreen mode

Git Commit Message Generator (commitgen.sh)

#!/bin/bash

DIFF=$(git diff --cached)

if [ -z "$DIFF" ]; then
    echo "No staged changes found"
    exit 1
fi

ask "Generate a concise git commit message for these changes. Use conventional commit format (feat/fix/docs/etc). Just output the message, nothing else:

$DIFF"
Enter fullscreen mode Exit fullscreen mode

Step 5: Interactive Mode

For longer conversations, create chat.sh:

#!/bin/bash

HISTORY_FILE="/tmp/ai_chat_history_$$"
echo "[]" > "$HISTORY_FILE"

cleanup() {
    rm -f "$HISTORY_FILE"
}
trap cleanup EXIT

echo "AI Chat (type 'exit' to quit)"
echo "---"

while true; do
    read -p "You: " input

    [ "$input" = "exit" ] && break
    [ -z "$input" ] && continue

    # Add user message to history
    MESSAGES=$(jq --arg msg "$input" \
        '. + [{"role": "user", "content": $msg}]' "$HISTORY_FILE")

    # Make API call with full history
    RESPONSE=$(curl -s https://api.anthropic.com/v1/messages \
        -H "Content-Type: application/json" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -d "{
            \"model\": \"claude-sonnet-4-20250514\",
            \"max_tokens\": 1024,
            \"messages\": $MESSAGES
        }")

    REPLY=$(echo "$RESPONSE" | jq -r '.content[0].text')
    echo -e "\nClaude: $REPLY\n"

    # Add assistant response to history
    echo "$MESSAGES" | jq --arg msg "$REPLY" \
        '. + [{"role": "assistant", "content": $msg}]' > "$HISTORY_FILE"
done
Enter fullscreen mode Exit fullscreen mode

Real-World Usage Examples

Once set up, you'll find yourself using these constantly:

# Quick questions
ask "What's the regex for validating email addresses?"

# Summarize meeting notes
summarize meeting-notes.txt

# Review before committing
review src/auth.py

# Generate commit messages
git add . && commitgen

# Debug errors
cat error.log | ask "What's causing this error and how do I fix it?"

# Explain code
cat legacy-function.js | ask "Explain what this code does"
Enter fullscreen mode Exit fullscreen mode

Cost Considerations

At current API pricing, casual usage costs pennies per day. A typical session:

  • Simple question: ~$0.001
  • File summary: ~$0.005
  • Code review: ~$0.01

Set a budget alert in the Anthropic console if you're concerned about costs.

Key Takeaways

  1. Start simple: A single bash script that calls the API is enough to be useful
  2. Build wrappers for your workflow: Think about tasks you do repeatedly
  3. Pipe everything: Unix philosophy + AI = powerful combinations
  4. Keep context when needed: The chat script shows how to maintain conversation history

The beauty of this approach is its simplicity. No dependencies beyond curl and jq, no complex setup, and you can extend it infinitely based on your needs.

What's Next?

In a future post, I'll show how to add:

  • Local file indexing for context-aware answers
  • Integration with your calendar and email
  • Voice input/output using Whisper and TTS

Building something cool with this? Drop a comment below—I'd love to see what you create.

Top comments (0)