The Anatomy of a SmartTool
Every SmartTool is just a YAML file with a secret superpower: it turns plain English instructions into Unix commands. In the next 10 minutes, you'll understand exactly how that magic works.
What You'll Learn
- The 5 essential parts of every tool config
- How variables flow through your tool like water through pipes
- The one YAML gotcha that trips up everyone (and how to avoid it)
The Simplest Tool That Actually Works
Let's start with something real. Here's a complete, working tool in just 8 lines:
name: shout
version: "1.0.0"
description: Makes text LOUD
steps:
- type: prompt
provider: claude
prompt: "Convert this to ALL CAPS with enthusiasm: {input}"
output_var: result
output: "{result}"
Save this to ~/.smarttools/shout/config.yaml and you've got a working command:
$ echo "hello world" | shout
HELLO WORLD!!!
That's it. Everything else is just adding features to this basic pattern.
The Five Parts of Every Tool
Think of a SmartTool config like a recipe card:
1. Identity
name, version, description
Who is this tool?
2. Arguments
Custom flags like --format
What options does it accept?
3. Steps
Prompts and code blocks
What does it do?
4. Output
The final template
What comes out?
Let's see all five in action:
# 1. IDENTITY - Who is this tool?
name: translate
version: "1.0.0"
description: Translate text to any language
# 2. ARGUMENTS - What knobs can users turn?
arguments:
- flag: --lang
variable: language
default: "Spanish"
description: Target language
# 3. STEPS - The actual work
steps:
- type: prompt
provider: claude
prompt: |
Translate this text to {language}:
{input}
output_var: translation
# 4. OUTPUT - What comes out the other end
output: "{translation}"
Variables Are Pipes
Here's the mental model that makes everything click: variables are pipes that carry data through your tool.
# The user runs:
echo "Hello" | translate --lang French
Inside your tool, three pipes are now flowing:
| Variable | Contains | Source |
|---|---|---|
{input} |
"Hello" | Piped in from stdin |
{language} |
"French" | From --lang flag |
{translation} |
"Bonjour" | Created by the AI step |
You can use any variable in any step that comes after it's created. They flow downstream, never up.
The YAML Trap Everyone Falls Into
Warning: Unquoted Numbers
YAML is helpful in ways that will hurt you. Watch out for versions:
# WRONG - YAML sees this as the number 1.0
version: 1.0
# RIGHT - YAML sees this as the string "1.0.0"
version: "1.0.0"
Always quote your version numbers. Always. Even if they look fine. Future you will thank present you.
Try It Yourself
Exercise: Build a Tone Shifter
Create a tool that rewrites text in different tones. It should:
- Accept a
--toneflag (default: "professional") - Rewrite the input in that tone
- Output just the rewritten text
Click to see the solution
name: tone-shift
version: "1.0.0"
description: Rewrite text in a different tone
arguments:
- flag: --tone
variable: tone
default: "professional"
description: "Target tone (casual, professional, enthusiastic, formal)"
steps:
- type: prompt
provider: claude
prompt: |
Rewrite this text with a {tone} tone.
Keep the meaning but change the style.
Text: {input}
output_var: result
output: "{result}"
Naming Your Tools
Tool names become Unix commands, so they follow Unix conventions:
# GOOD - lowercase, hyphens
name: code-review
name: fix-grammar
name: json2csv
# BAD - these won't work
name: CodeReview # No uppercase
name: fix_grammar # No underscores
name: fix grammar # No spaces
Pick names that complete the sentence: "I need to _____ this file."
Where To Next?
You now understand the structure. Time to add superpowers:
- Custom Arguments - Add flags like a pro
- Multi-Step Workflows - Chain AI calls together
- Code Steps - Mix Python into your tools