calorie-counter
Track daily calorie and protein intake, set goals, and log weight. Use when user mentions food they ate, wants to know remaining calories, or needs to track weight. Stores data in SQLite with automatic daily totals.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-calorie-counter
Repository
Skill path: skills/cnqso/calorie-counter
Track daily calorie and protein intake, set goals, and log weight. Use when user mentions food they ate, wants to know remaining calories, or needs to track weight. Stores data in SQLite with automatic daily totals.
Open repositoryBest for
Primary workflow: Analyze Data & AI.
Technical facets: Full Stack, Data / AI.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install calorie-counter into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding calorie-counter to shared team environments
- Use calorie-counter for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: calorie-counter
description: Track daily calorie and protein intake, set goals, and log weight. Use when user mentions food they ate, wants to know remaining calories, or needs to track weight. Stores data in SQLite with automatic daily totals.
metadata: { "openclaw": { "emoji": "š", "requires": { "python": ">=3.7" } } }
---
# Calorie Counter
Simple, reliable calorie and protein tracking with SQLite database.
## Features
- **Manual Entry**: Add food with calories and protein
- **Protein Tracking**: Monitor daily protein intake
- **Daily Goals**: Set custom calorie targets
- **Weight Tracking**: Log weight in pounds
- **Instant Feedback**: See totals immediately after adding food
- **History**: View past days and trends
## Usage
### Adding Food
```bash
python scripts/calorie_tracker.py add "chicken breast" 165 31
python scripts/calorie_tracker.py add "banana" 100 1
```
Shows immediate feedback with today's totals and remaining calories.
### Viewing Today's Summary
```bash
python scripts/calorie_tracker.py summary
```
Shows:
- All entries for today
- Total calories and protein consumed
- Daily goal and remaining calories
- Progress percentage
### Setting Goals
```bash
python scripts/calorie_tracker.py goal 2000
```
Sets the daily calorie goal (persists).
### Weight Tracking
```bash
python scripts/calorie_tracker.py weight 175
python scripts/calorie_tracker.py weight-history
```
Weight is in pounds (decimals allowed: 175.5).
### Viewing History
```bash
# Last 7 days
python scripts/calorie_tracker.py history
# Last 30 days
python scripts/calorie_tracker.py history 30
```
### Deleting Entries
```bash
# List entries to get ID
python scripts/calorie_tracker.py list
# Delete by ID
python scripts/calorie_tracker.py delete 42
```
## Database
SQLite database: `calorie_data.db`
### Tables
**entries** - Food log
- id (INTEGER) - Auto-increment
- date (TEXT) - YYYY-MM-DD
- food_name (TEXT)
- calories (INTEGER)
- protein (INTEGER)
- created_at (TIMESTAMP) - Automatic
**daily_goal** - Single calorie target
- id (INTEGER) - Always 1
- calorie_goal (INTEGER)
**weight_log** - Weight tracking
- id (INTEGER) - Auto-increment
- date (TEXT) - YYYY-MM-DD
- weight_lbs (REAL) - Pounds with decimals
- created_at (TIMESTAMP) - Automatic
## Agent Instructions
**Important:** The skill is located at `workspace/calorie-counter/` in your agent's workspace. All commands should use this path prefix.
### When user mentions food:
1. Extract food name, calories, and protein (estimate if not provided)
2. Run: `python3 workspace/calorie-counter/scripts/calorie_tracker.py add "food" CALORIES PROTEIN`
3. The command outputs immediate totals (no need to run summary separately)
Example:
- User: "I had a chicken breast for lunch, about 165 calories"
- Estimate protein (chicken is ~30g per 165 cal)
- Run: `python3 workspace/calorie-counter/scripts/calorie_tracker.py add "chicken breast" 165 30`
### When user wants remaining calories:
1. Run: `python3 workspace/calorie-counter/scripts/calorie_tracker.py summary`
### When user sets a goal:
1. Run: `python3 workspace/calorie-counter/scripts/calorie_tracker.py goal CALORIES`
### When user logs weight:
1. Convert to pounds if needed (1 kg ā 2.205 lbs)
2. Run: `python3 workspace/calorie-counter/scripts/calorie_tracker.py weight POUNDS`
### When user wants to delete entry:
1. Run: `python3 workspace/calorie-counter/scripts/calorie_tracker.py list` to show IDs
2. Run: `python3 workspace/calorie-counter/scripts/calorie_tracker.py delete ID`
### Protein Estimation Guide
If user doesn't specify protein, estimate based on food type:
- **Lean meats** (chicken, turkey): ~0.30g per calorie
- **Fish**: ~0.25g per calorie
- **Red meat**: ~0.20g per calorie
- **Eggs**: ~0.12g per calorie (1 egg = 70 cal, 6g protein)
- **Greek yogurt**: ~0.10g per calorie
- **Nuts**: ~0.04g per calorie
- **Bread/pasta**: ~0.03g per calorie
- **Fruits**: ~0.01g per calorie or less
- **Vegetables**: ~0.02-0.04g per calorie
When uncertain, estimate conservatively or ask the user.
## Notes
- Calories and protein are integers (no decimals)
- Weight is in pounds (decimals allowed)
- Database created automatically on first use
- All times in local timezone
- Dates in YYYY-MM-DD format
- Time shown in lists is from created_at timestamp (HH:MM format)
## Example Session
```bash
# Set goal
$ python scripts/calorie_tracker.py goal 2000
ā Set daily goal: 2000 cal
# Add breakfast
$ python scripts/calorie_tracker.py add "oatmeal" 150 5
ā Added: oatmeal (150 cal, 5g protein)
Entry ID: 1
Today: 150 / 2000 cal (remaining: 1850) | Protein today: 5g | Entries: 1
# Add lunch
$ python scripts/calorie_tracker.py add "grilled chicken salad" 350 45
ā Added: grilled chicken salad (350 cal, 45g protein)
Entry ID: 2
Today: 500 / 2000 cal (remaining: 1500) | Protein today: 50g | Entries: 2
# Check summary
$ python scripts/calorie_tracker.py summary
============================================================
DAILY SUMMARY - 2026-02-05
============================================================
Entries: 2
Total consumed: 500 cal | 50g protein
Daily goal: 2000 cal
Remaining: 1500 cal
25.0% of goal consumed
============================================================
# Log weight
$ python scripts/calorie_tracker.py weight 175.5
ā Logged weight: 175.5 lbs
```
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### scripts/calorie_tracker.py
```python
#!/usr/bin/env python3
"""
Calorie Counter - Simple, reliable calorie tracking with SQLite
"""
import sqlite3
import sys
from datetime import date
from pathlib import Path
# Database path relative to skill directory
SKILL_DIR = Path(__file__).parent.parent
DB_PATH = SKILL_DIR / "calorie_data.db"
def init_db():
"""Initialize database with schema"""
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
# Food entries table - simplified
c.execute('''
CREATE TABLE IF NOT EXISTS entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
food_name TEXT NOT NULL,
calories INTEGER NOT NULL,
protein INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# Daily goal - single value
c.execute('''
CREATE TABLE IF NOT EXISTS daily_goal (
id INTEGER PRIMARY KEY CHECK (id = 1),
calorie_goal INTEGER NOT NULL
)
''')
# Weight log - pounds, no notes
c.execute('''
CREATE TABLE IF NOT EXISTS weight_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
weight_lbs REAL NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# Create indexes
c.execute('CREATE INDEX IF NOT EXISTS idx_entries_date ON entries(date)')
c.execute('CREATE INDEX IF NOT EXISTS idx_weight_date ON weight_log(date)')
conn.commit()
conn.close()
def get_db():
"""Get database connection"""
if not DB_PATH.exists():
init_db()
return sqlite3.connect(DB_PATH)
def add_entry(food_name, calories, protein):
"""Add a food entry"""
try:
calories = int(calories)
protein = int(protein)
if calories < 0 or protein < 0:
print("Error: Calories and protein cannot be negative")
return False
except ValueError:
print("Error: Calories and protein must be numbers")
return False
conn = get_db()
c = conn.cursor()
today = date.today().isoformat()
c.execute('''
INSERT INTO entries (date, food_name, calories, protein)
VALUES (?, ?, ?, ?)
''', (today, food_name, calories, protein))
entry_id = c.lastrowid
conn.commit()
# Totals + goal (so callers don't need to do math)
c.execute('''
SELECT COALESCE(SUM(calories), 0), COALESCE(SUM(protein), 0), COUNT(*)
FROM entries
WHERE date = ?
''', (today,))
total_calories, total_protein, entry_count = c.fetchone()
c.execute('SELECT calorie_goal FROM daily_goal WHERE id = 1')
goal_row = c.fetchone()
goal = goal_row[0] if goal_row else None
conn.close()
print(f"ā Added: {food_name} ({calories} cal, {protein}g protein)")
print(f" Entry ID: {entry_id}")
if goal is not None:
remaining = goal - total_calories
print(
f" Today: {total_calories} / {goal} cal (remaining: {remaining})"
f" | Protein today: {total_protein}g | Entries: {entry_count}"
)
else:
print(
f" Today: {total_calories} cal"
f" | Protein today: {total_protein}g | Entries: {entry_count} | Goal: not set"
)
return True
def delete_entry(entry_id):
"""Delete an entry"""
try:
entry_id = int(entry_id)
except ValueError:
print("Error: Entry ID must be a number")
return False
conn = get_db()
c = conn.cursor()
# Check if entry exists
c.execute('SELECT food_name, calories, protein FROM entries WHERE id = ?', (entry_id,))
row = c.fetchone()
if not row:
print(f"Error: Entry ID {entry_id} not found")
conn.close()
return False
food_name, calories, protein = row
c.execute('DELETE FROM entries WHERE id = ?', (entry_id,))
conn.commit()
conn.close()
print(f"ā Deleted entry {entry_id}: {food_name} ({calories} cal, {protein}g protein)")
return True
def set_goal(calories):
"""Set calorie goal"""
try:
calories = int(calories)
if calories <= 0:
print("Error: Goal must be positive")
return False
except ValueError:
print("Error: Calories must be a number")
return False
conn = get_db()
c = conn.cursor()
c.execute('''
INSERT OR REPLACE INTO daily_goal (id, calorie_goal)
VALUES (1, ?)
''', (calories,))
conn.commit()
conn.close()
print(f"ā Set daily goal: {calories} cal")
return True
def get_goal():
"""Get calorie goal"""
conn = get_db()
c = conn.cursor()
c.execute('SELECT calorie_goal FROM daily_goal WHERE id = 1')
row = c.fetchone()
conn.close()
return row[0] if row else None
def list_entries(target_date=None):
"""List entries for a date"""
if target_date is None:
target_date = date.today().isoformat()
conn = get_db()
c = conn.cursor()
c.execute('''
SELECT id, food_name, calories, protein,
strftime('%H:%M', created_at) as time
FROM entries
WHERE date = ?
ORDER BY created_at
''', (target_date,))
rows = c.fetchall()
conn.close()
if not rows:
print(f"No entries for {target_date}")
return []
print(f"\nEntries for {target_date}:")
print("-" * 60)
for entry_id, food_name, calories, protein, time in rows:
print(f"ID {entry_id:3d} | {time} | {food_name:20s} | {calories:4d} cal | {protein:3d}g protein")
print("-" * 60)
return rows
def summary(target_date=None):
"""Show daily summary"""
if target_date is None:
target_date = date.today().isoformat()
conn = get_db()
c = conn.cursor()
# Get entries
c.execute('''
SELECT SUM(calories), SUM(protein), COUNT(*)
FROM entries
WHERE date = ?
''', (target_date,))
result = c.fetchone()
total_calories = result[0] or 0
total_protein = result[1] or 0
entry_count = result[2] or 0
# Get goal
goal = get_goal()
conn.close()
print(f"\n{'='*60}")
print(f"DAILY SUMMARY - {target_date}")
print(f"{'='*60}")
print(f"Entries: {entry_count}")
print(f"Total consumed: {total_calories} cal | {total_protein}g protein")
if goal:
remaining = goal - total_calories
print(f"Daily goal: {goal} cal")
print(f"Remaining: {remaining} cal")
if remaining < 0:
print(f" ā ļø Over goal by {abs(remaining)} cal")
elif remaining == 0:
print(f" ā Goal reached exactly!")
else:
percent = (total_calories / goal) * 100
print(f" {percent:.1f}% of goal consumed")
else:
print("Daily goal: Not set (use 'goal' command)")
print(f"{'='*60}\n")
# Show entries if any
if entry_count > 0:
list_entries(target_date)
def log_weight(weight_lbs):
"""Log weight"""
try:
weight_lbs = float(weight_lbs)
if weight_lbs <= 0:
print("Error: Weight must be positive")
return False
except ValueError:
print("Error: Weight must be a number")
return False
conn = get_db()
c = conn.cursor()
today = date.today().isoformat()
c.execute('''
INSERT INTO weight_log (date, weight_lbs)
VALUES (?, ?)
''', (today, weight_lbs))
conn.commit()
conn.close()
print(f"ā Logged weight: {weight_lbs} lbs")
return True
def weight_history(days=30):
"""Show weight history"""
conn = get_db()
c = conn.cursor()
c.execute('''
SELECT date, weight_lbs
FROM weight_log
ORDER BY date DESC
LIMIT ?
''', (days,))
rows = c.fetchall()
conn.close()
if not rows:
print("No weight log entries")
return
print(f"\nWeight History (last {days} days):")
print("-" * 40)
for date_str, weight_lbs in rows:
print(f"{date_str} | {weight_lbs:.1f} lbs")
# Calculate change
if len(rows) >= 2:
first_weight = rows[-1][1]
last_weight = rows[0][1]
change = last_weight - first_weight
print("-" * 40)
if change > 0:
print(f"Change: +{change:.1f} lbs")
elif change < 0:
print(f"Change: {change:.1f} lbs")
else:
print(f"Change: No change")
print()
def history(days=7):
"""Show calorie history"""
conn = get_db()
c = conn.cursor()
c.execute('''
SELECT date, SUM(calories) as total, SUM(protein) as total_protein
FROM entries
WHERE date >= date('now', '-' || ? || ' days')
GROUP BY date
ORDER BY date DESC
''', (days,))
rows = c.fetchall()
conn.close()
if not rows:
print(f"No entries in last {days} days")
return
print(f"\nCalorie History (last {days} days):")
print("-" * 60)
goal = get_goal()
for date_str, total, total_protein in rows:
if goal:
remaining = goal - total
status = f"({remaining:+d} remaining)" if remaining != 0 else "(goal met)"
else:
status = "(no goal)"
goal_str = str(goal) if goal else "N/A"
print(f"{date_str} | {total:4d} cal | {total_protein:3d}g protein | Goal: {goal_str:>4s} {status}")
print()
def usage():
"""Print usage information"""
print("""
Calorie Counter - Usage
Commands:
add <food> <calories> <protein> Add food entry
delete <id> Delete entry
list List today's entries
summary Show today's summary
goal <calories> Set daily goal
weight <lbs> Log weight in pounds
weight-history [days] Show weight history (default 30)
history [days] Show calorie history (default 7)
Examples:
add "chicken breast" 165 31
delete 42
goal 2000
weight 165.5
""")
def main():
if len(sys.argv) < 2:
usage()
sys.exit(1)
command = sys.argv[1]
try:
if command == "add":
if len(sys.argv) < 5:
print("Error: add requires <food> <calories> <protein>")
sys.exit(1)
food = sys.argv[2]
calories = sys.argv[3]
protein = sys.argv[4]
add_entry(food, calories, protein)
elif command == "delete":
if len(sys.argv) < 3:
print("Error: delete requires <id>")
sys.exit(1)
delete_entry(sys.argv[2])
elif command == "list":
list_entries()
elif command == "summary":
summary()
elif command == "goal":
if len(sys.argv) < 3:
print("Error: goal requires <calories>")
sys.exit(1)
set_goal(sys.argv[2])
elif command == "weight":
if len(sys.argv) < 3:
print("Error: weight requires <lbs>")
sys.exit(1)
log_weight(sys.argv[2])
elif command == "weight-history":
days = int(sys.argv[2]) if len(sys.argv) > 2 else 30
weight_history(days)
elif command == "history":
days = int(sys.argv[2]) if len(sys.argv) > 2 else 7
history(days)
else:
print(f"Error: Unknown command '{command}'")
usage()
sys.exit(1)
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### README.md
```markdown
# Calorie Counter š
Simple, reliable calorie and protein tracking for OpenClaw agents.
## Features
- **Manual calorie entry** - No unreliable nutrition APIs
- **Protein tracking** - Monitor daily protein intake
- **Weight logging** - Track weight in pounds
- **Instant feedback** - See totals immediately after adding food
- **SQLite database** - Reliable, local storage
- **History & trends** - View past days and progress
## Installation
```bash
clawhub install calorie-counter
```
Or manually clone to your workspace directory.
## Requirements
- Python 3.7+
- No external dependencies (uses only Python stdlib)
## Quick Start
### Set Your Daily Goal
```bash
python scripts/calorie_tracker.py goal 2000
```
### Add Food
```bash
python scripts/calorie_tracker.py add "chicken breast" 165 31
```
### Check Progress
```bash
python scripts/calorie_tracker.py summary
```
### Log Weight
```bash
python scripts/calorie_tracker.py weight 175
```
## Agent Usage
When installed, your agent will automatically use this skill when you mention food or ask about calories.
Example conversation:
```
You: "I just ate a turkey sandwich, about 450 calories and 30g protein"
Agent: [runs add command]
"ā Added - you've consumed 450 cal today, 1550 remaining"
You: "How many calories do I have left?"
Agent: [runs summary command]
"You have 1550 calories remaining (22.5% of goal consumed)"
```
## Database
Data stored in `calorie_data.db` (SQLite):
- **entries** - Food log with calories and protein
- **daily_goal** - Your calorie target
- **weight_log** - Weight measurements in pounds
## Commands
```bash
add <food> <calories> <protein> # Add food entry
delete <id> # Delete entry
list # List today's entries
summary # Show daily summary
goal <calories> # Set daily goal
weight <lbs> # Log weight
weight-history [days] # Show weight history
history [days] # Show calorie history
```
## Why This Skill?
**vs. Other calorie trackers:**
- ā
No API keys or external services
- ā
Works offline
- ā
Simple manual entry (you control accuracy)
- ā
Protein tracking included
- ā
Instant feedback on food entry
- ā
Clean, portable SQLite storage
- ā
No security vulnerabilities
**vs. diet-tracker skill:**
- ā
Actually works (no broken APIs)
- ā
Portable (no hardcoded paths)
- ā
English language
- ā
Secure (parameterized SQL)
- ā
Simpler, cleaner code
## Documentation
See `SKILL.md` for full documentation and agent instructions.
## License
MIT
## Author
Built with Claude Code for OpenClaw
```
### _meta.json
```json
{
"owner": "cnqso",
"slug": "calorie-counter",
"displayName": "Calorie Counter",
"latest": {
"version": "1.0.0",
"publishedAt": 1770303569341,
"commit": "https://github.com/clawdbot/skills/commit/267a4e212a9cdbd9a3b2255559003f39fb4e32c0"
},
"history": []
}
```