I've been experimenting with a workflow that feels like the right way to use AI coding assistants: build small, focused CLI tools, then let Claude run them.
The Setup
I built a simple Python script that creates YouTube playlists. It:
- Takes a list of songs via stdin
- Searches YouTube for each song
- Creates a playlist using the YouTube Data API
- Returns the playlist URL
Nothing fancy. About 100 lines of Python.
The Interesting Part
Instead of running the script myself, I just tell Claude what I want:
Me: "Make a playlist with Kasoor by Prateek Kuhad,
Aaromale from the Malayalam film, and similar soft songs"
Claude then:
- Formats the input correctly
- Runs the script with proper stdin handling
- Handles edge cases (wrong movie names, songs not found)
- Returns the playlist URL
Here's what Claude actually executes:
python3 main.py << 'EOF'
Kasoor - Prateek Kuhad
Aaromale - Ormayundo Ee Mukham
Nee Himamazhayayi - Edakkad Battalion 06
Quiet Corners & Soft Echoes
y
EOF
Why This Works
The tool has a simple contract. Stdin in, URL out. Claude doesn't need to understand YouTube APIs or OAuth flows. It just needs to format text correctly.
Debugging happens conversationally. When playlist names weren't being set correctly, I said "playlist name shows as My Playlist instead of the custom name." Claude traced it to stdin buffering, figured out the script needs two consecutive empty lines to end song input, and fixed the invocation.
Edge cases get handled on the fly. One song had the wrong movie name in my list. Claude searched manually, found the correct attribution, and added it.
The Pattern
┌─────────────────────────────────────────────┐
│ You: High-level intent │
│ "Make a playlist with songs like X" │
└─────────────────┬───────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Claude: Translate to CLI invocation │
│ - Format stdin correctly │
│ - Handle heredocs, escaping, etc. │
│ - Run the command │
└─────────────────┬───────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Tool: Do the actual work │
│ - API calls │
│ - Data processing │
│ - Return structured output │
└─────────────────┬───────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Claude: Interpret results │
│ - Handle errors │
│ - Retry with fixes │
│ - Present output │
└─────────────────────────────────────────────┘
What I Learned
Keep tools simple. The YouTube playlist script just does one thing. No flags, no modes, no configuration files. Stdin and stdout. Claude can work with that.
Let Claude handle the messy parts. Stdin formatting, heredocs, escaping special characters, figuring out that the script needs two empty lines—these are exactly the things that are tedious to remember but trivial for Claude to figure out.
Build incrementally. The song parser had a bug where "Song - Movie" format wasn't handled correctly. Instead of going back to fix the script properly, Claude patched it mid-session and we kept going. The fix got committed, the playlist got made.
You end up with reusable tools. The playlist maker now exists. Next time I want a playlist, I just ask. The tool doesn't care if I'm running it or Claude is.
The Bigger Picture
This feels like a glimpse of how AI assistants should work. Not replacing programming, but changing what we program. Instead of writing code that does everything, write small tools that do one thing well. Let the AI handle orchestration, formatting, error recovery.
The AI becomes an operator of your tools, not a replacement for them.