Give your AI agent access to your health and fitness data from RUNSTR. Fetches workouts, habits, journal entries, mood, steps, and more from Nostr. Use when the user asks about their workouts, fitness history, health habits, mood tracking, or wants AI fitness coaching based on real data.
数据来源:ClawHub。 在 ClawSkills 查看
选择你使用的 Agent
方法一:命令行安装(推荐)
推荐(无需提前安装 clawhub)
npx clawhub@latest --dir ~/.claude/skills install runstr-fitness或使用 clawhub CLI(需提前安装)
clawhub --dir ~/.claude/skills install runstr-fitness⚠️ 需要 Node.js 18+,没有 Node?请使用下方方法二直接下载 ZIP。 安装 Node.js →
方法二:手动下载安装(无需 Node)
下载 ZIP,解压后将文件夹放到以下路径,重启 Agent 即可:
安装路径
~/.claude/skills/runstr-fitness/💡解压后将文件夹放到上方路径,重启 Agent 即可生效
--- name: runstr-fitness description: Give your AI agent access to your health and fitness data from RUNSTR. Fetches workouts, habits, journal entries, mood, steps, and more from Nostr. Use when the user asks about their workouts, fitness history, health habits, mood tracking, or wants AI fitness coaching based on real data. metadata: {"openclaw":{"emoji":"\ud83c\udfc3","requires":{"bins":["nak"]},"install":[{"id":"go","kind":"go","package":"github.com/fiatjaf/nak@latest","bins":["nak"],"label":"Install nak via Go"}]}} ---
Give your AI agent access to your real health and fitness data. RUNSTR is a free fitness app that tracks workouts, habits, journal entries, mood, and steps — and stores encrypted backups on the Nostr protocol. This skill lets your bot read that data so it can help with fitness coaching, habit accountability, mood tracking, and health insights.
What your bot gets access to:
If you're already a RUNSTR user with backups enabled, skip to step 3.
RUNSTR is free. You earn Bitcoin (sats) for working out.
This encrypts all your fitness data and publishes it to Nostr relays. Only you (with your private key) can read it.
Your nsec is your Nostr private key. Find it in RUNSTR under Settings > Keys (or your Nostr key manager).
Tell your bot: "Here's my RUNSTR nsec: nsec1..."
Your bot uses the nsec to decrypt your encrypted fitness backup from Nostr. The nsec is never stored, logged, or transmitted — it's used only for the decryption step in your current session.
Why nsec and not npub? Your fitness data is encrypted. The public key (npub) can only see old public workout posts (if any). The private key (nsec) is needed to decrypt your habits, journals, mood, steps, and current workout history.
Privacy note: If you want a dedicated identity just for fitness data, create a new Nostr account in RUNSTR. Your fitness nsec doesn't have to be your main Nostr identity.
Your bot sees whatever was in your last backup. After a week of new workouts, go to Settings > Backup in RUNSTR and tap backup again to sync the latest data to Nostr.
---
Everything below is instructions for the AI agent, not the user.
nak (Nostr Army Knife) must be installed:
go install github.com/fiatjaf/nak@latest
Always query these four relays (RUNSTR defaults):
wss://relay.damus.io wss://relay.primal.net wss://nos.lol wss://relay.nostr.band
hex_sk=$(nak decode nsec1...)
hex_pk=$(nak key public $hex_sk)
nak req -k 0 -a $hex_pk -l 1 \
wss://relay.damus.io wss://nos.lol | \
jq -r '.content | fromjson | {name, about, lud16, picture}'
This is the primary data source.
nak req -k 30078 -a $hex_pk -t d=runstr-workout-backup -l 1 \
wss://relay.damus.io wss://relay.primal.net wss://nos.lol wss://relay.nostr.band
If no backup found: Tell the user: "No backup found on Nostr. Open RUNSTR on your phone, go to Settings > Backup, and create one. Then try again."
If backup found but exportedAt is old: Warn the user that their backup is stale and recent data may be missing. Suggest they re-backup in the app.
The backup is NIP-44 self-encrypted and gzip-compressed.
Method 1: Using nak
content=$(nak req -k 30078 -a $hex_pk -t d=runstr-workout-backup -l 1 \
wss://relay.damus.io wss://nos.lol | jq -r '.content')
# Decrypt (NIP-44 self-decryption: user to own pubkey)
decrypted=$(echo "$content" | nak encrypt --sec $hex_sk $hex_pk --decrypt)
# Decompress (check for ["compression", "gzip"] tag first)
echo "$decrypted" | base64 -d | gunzip | jq .
Method 2: Node.js fallback
// /tmp/decrypt-runstr.mjs — run with: node /tmp/decrypt-runstr.mjs <hex_sk> '<content>'
import { gunzipSync } from 'zlib';
import NDK, { NDKPrivateKeySigner } from '@nostr-dev-kit/ndk';
const signer = new NDKPrivateKeySigner(process.argv[2]);
const user = await signer.user();
const decrypted = await signer.decrypt(user, process.argv[3]);
try {
console.log(gunzipSync(Buffer.from(decrypted, 'base64')).toString());
} catch {
console.log(decrypted);
}
{
"version": 1,
"exportedAt": "2025-01-15T10:30:00Z",
"appVersion": "1.6.5",
"workouts": [
{
"id": "uuid",
"type": "running",
"startTime": "2025-01-15T07:00:00Z",
"endTime": "2025-01-15T07:35:00Z",
"duration": 2100,
"distance": 5200,
"calories": 312
}
],
"habits": [
{
"id": "id",
"name": "No Smoking",
"type": "abstinence",
"currentStreak": 45,
"longestStreak": 45,
"checkIns": ["2025-01-15", "2025-01-14"]
}
],
"journal": [
{
"id": "uuid",
"date": "2025-01-15",
"content": "Great morning run today.",
"mood": "great",
"energy": 4,
"tags": ["morning", "outdoors"]
}
],
"stepHistory": [
{ "date": "2025-01-15", "steps": 12450, "source": "healthkit" }
],
"preferences": {
"unitSystem": "imperial",
"selectedCharity": "hrf"
}
}
Field reference:
workouts[].type: running, walking, cycling, hiking, strength, meditation, yoga, diet, swimming, rowingworkouts[].duration: secondsworkouts[].distance: metershabits[].type: "abstinence" (quitting something) or "positive" (building something)journal[].mood: great, good, neutral, low, badjournal[].energy: 1-5 scalestepHistory[].source: healthkit, health_connect, nativeOlder users may have public workout events. Always check:
nak req -k 1301 -a $hex_pk -l 50 \
wss://relay.damus.io wss://relay.primal.net wss://nos.lol wss://relay.nostr.band
If found, parse tags array:
| Tag | Example | |-----|---------| | exercise | ["exercise", "running"] | | distance | ["distance", "5.2", "km"] | | duration | ["duration", "00:30:45"] | | calories | ["calories", "312"] | | avg_pace | ["avg_pace", "05:39", "min/km"] | | steps | ["steps", "8432"] | | team | ["team", "hrf"] |
Merge with backup data. Deduplicate by matching workout start times or IDs.
Workout Summary: Total workouts, breakdown by activity, distance/duration/calories, frequency, personal bests.
Trends: Frequency changes, pace improvement, gaps, active days of week.
Habits: Current streaks, longest streaks, consistency rate.
Journal & Mood: Mood trend, energy averages, workout-mood correlation.
Steps: Daily average, weekly totals, trends.
Charity: Which team/charity, reward routing (user vs charity).
Save a structured summary for future conversations so you don't re-query every time:
# Health & Fitness Summary
Last updated: YYYY-MM-DD
Source: RUNSTR (Nostr encrypted backup)
User: <name or npub>
...安装 RUNSTR Fitness 后,可以对 AI 说这些话来触发它
Help me get started with RUNSTR Fitness
Explains what RUNSTR Fitness does, walks through the setup, and runs a quick demo based on your current project
Use RUNSTR Fitness to agent access to your health and fitness data from RUNSTR
Invokes RUNSTR Fitness with the right parameters and returns the result directly in the conversation
What can I do with RUNSTR Fitness in my data & analytics workflow?
Lists the top use cases for RUNSTR Fitness, with example commands for each scenario
将技能文件夹放到 ~/.claude/skills/runstr-fitness/ 目录(个人级,所有项目可用),或 .claude/skills/runstr-fitness/(项目级)。重启 AI 客户端后,用 /runstr-fitness 主动调用,或让 AI 根据上下文自动发现并使用。
RUNSTR Fitness 支持 Claude、Cursor、OpenClaw,可与这些 AI 平台无缝集成,扩展其能力。
RUNSTR Fitness 可免费安装使用。请查阅仓库了解许可证信息。
Give your AI agent access to your health and fitness data from RUNSTR. Fetches workouts, habits, journal entries, mood, steps, and more from Nostr. Use when the user asks about their workouts, fitness history, health habits, mood tracking, or wants AI fitness coaching based on real data.
RUNSTR Fitness 属于「Data & Analytics」分类,该分类的技能帮助 AI 智能体在此领域执行专业任务。
Automate my data & analytics tasks using RUNSTR Fitness
Identifies repetitive steps in your workflow and sets up RUNSTR Fitness to handle them automatically