← Back to BlogTutorial

How to Build Custom AI Agent Skills in OpenClaw

H.··7 min read

Out of the box, OpenClaw connects to email, Slack, calendar, and a handful of other tools. That covers maybe 60% of what most businesses need.

The other 40%? That's where custom skills come in.

A skill is a packaged capability you give your agent. It could be as simple as "check the weather" or as complex as "monitor our Stripe dashboard, flag any refund over $500, draft an email to the customer, and create a task in Linear for the support team."

This guide walks through building both.

What Is a Skill?

In OpenClaw, a skill is a directory containing:

That's it. No SDK. No special framework. No dependency on a specific programming language. If you can write a markdown file and a script, you can build a skill.

The agent reads SKILL.md to understand what the skill does, when to use it, and how to execute it. The scripts do the actual work.

Your First Skill: A Simple API Check

Let's build a skill that checks whether your website is up and reports the response time.

Create a directory:

~/.openclaw/skills/site-monitor/

Create SKILL.md:

---
name: site-monitor
description: Check if a website is responding and report the response time.
  Use when asked about site status, uptime, or performance.
---

# Site Monitor

## When to Use
When the user asks about website status, uptime, or response time.

## How to Use
Run the check script with the target URL:

./scripts/check.sh https://example.com

## Output
Reports: status code, response time in ms, and whether the site is healthy.

Create scripts/check.sh:

#!/bin/bash
URL="${1:-https://openclawsetup.dev}"
START=$(date +%s%N)
STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$URL")
END=$(date +%s%N)
MS=$(( (END - START) / 1000000 ))

if [ "$STATUS" -eq 200 ]; then
  echo "HEALTHY | $URL | Status: $STATUS | Response: ${MS}ms"
else
  echo "UNHEALTHY | $URL | Status: $STATUS | Response: ${MS}ms"
fi

Make it executable: chmod +x scripts/check.sh

That's a complete skill. Your agent can now check any website's status when you ask "Is our site up?" or "How's the response time on openclawsetup.dev?"

Building Something Real: Stripe Refund Monitor

Let's build something production-grade. A skill that monitors Stripe for refunds over a threshold and takes action.

Directory: ~/.openclaw/skills/stripe-monitor/

SKILL.md:

---
name: stripe-monitor
description: Monitor Stripe for refunds over a specified threshold.
  Use when asked about refunds, Stripe activity, or payment issues.
allowed-tools: Bash(./scripts/*.sh:*)
---

# Stripe Refund Monitor

## When to Use
- When checking for recent refunds
- When monitoring payment activity
- Triggered by heartbeat (periodic check every 30 minutes)

## Commands

### Check recent refunds

./scripts/check-refunds.sh --threshold 500 --hours 24

### Get refund details

./scripts/refund-detail.sh <refund_id>

## Response Protocol
If a refund over threshold is found:
1. Report the refund amount, customer email, and reason
2. Draft a customer follow-up email (empathetic, solution-oriented)
3. Create a task for the support team to review

## Environment
Requires STRIPE_SECRET_KEY in the agent's environment.

scripts/check-refunds.sh:

#!/bin/bash
THRESHOLD=${2:-500}
HOURS=${4:-24}
SINCE=$(date -d "${HOURS} hours ago" +%s 2>/dev/null || date -v-${HOURS}H +%s)

curl -s "https://api.stripe.com/v1/refunds?limit=20&created[gte]=$SINCE" \
  -u "$STRIPE_SECRET_KEY:" | \
python3 -c "
import json, sys
data = json.load(sys.stdin)
threshold = int($THRESHOLD) * 100
for r in data.get('data', []):
    amt = r['amount']
    if amt >= threshold:
        print(f\"ALERT | Refund {r['id']} | \${amt/100:.2f} | Reason: {r.get('reason', 'none')} | Status: {r['status']}\")
if not any(r['amount'] >= threshold for r in data.get('data', [])):
    print('No refunds over threshold in the last ${HOURS}h.')
"

The skill is more sophisticated, but the pattern is identical: markdown instructions plus executable scripts.

Skill Design Principles

After building dozens of skills for clients, here's what separates good skills from frustrating ones:

Be specific about when to trigger. "Use when asked about payments" is vague. "Use when the user asks about refunds over $500 in the last 24 hours, or during the 30-minute heartbeat check" is precise. Vague triggers cause the agent to use the wrong skill at the wrong time.

Keep scripts single-purpose. One script per action. check-refunds.sh checks. refund-detail.sh gets details. Don't build a monolith script with 15 flags. The agent handles orchestration. Your scripts handle execution.

Handle errors in the script, not the prompt. If the Stripe API is down, your script should output a clear error message, not a Python traceback. The agent reads the output and decides what to do next. Clean output means better agent decisions.

Use environment variables for secrets. Never hardcode API keys in scripts. Not even for testing. Not even "just for now." Use $STRIPE_SECRET_KEY in the script and configure it in OpenClaw's environment. Keys in code end up in git. Keys in git end up on the internet.

Include example outputs in SKILL.md. The agent uses examples to understand what normal output looks like. If your skill outputs "HEALTHY | 200 | 142ms" then include that as an example. The agent will know what to expect and how to interpret it.

Multi-Step Skills

Some skills need to chain multiple actions. The agent handles this naturally if you structure your SKILL.md as a decision tree:

## Workflow

1. Run check-refunds.sh --threshold 500 --hours 24
2. If refunds found:
   a. Run refund-detail.sh <refund_id> for each
   b. Draft customer email using the detail
   c. Post summary to #finance in Slack
3. If no refunds: log "All clear" and continue

The agent follows these steps like a checklist. Each step uses a different script or a different tool (Slack, email). The skill provides the logic. The agent provides the execution.

Testing Your Skills

Before trusting a skill in production:

  1. Run scripts manually. Execute each script from the command line with test inputs. Verify the output format.
  2. Ask the agent to use it. Tell your agent: "Check for recent Stripe refunds." Watch what it does. Does it pick the right skill? Does it interpret the output correctly?
  3. Test the error path. What happens when the API is down? When the threshold finds nothing? When the input is malformed?
  4. Run it on the heartbeat. If the skill should run periodically, add it to your HEARTBEAT.md and let it run for 24 hours. Check the logs.

Skills We Build for Clients

Every OpenClaw Setup deployment includes custom skills tailored to the client's business:

Each one follows the same pattern: markdown instructions, focused scripts, clean output.

The Power of Simple Architecture

There's a reason OpenClaw skills are just markdown and shell scripts. No SDK means no version conflicts. No framework means no breaking changes. No lock-in means you can inspect, modify, and debug everything.

Your agent reads instructions and runs scripts. That's all it needs to do. Everything else is complexity you don't need.

If you want custom skills built for your specific business workflows, book a call. We'll map your operations and build the skills that automate the parts of your day that don't need you.

Related Reading

Get Your AI Agent Running

We handle the entire setup — deploy, configure, and secure OpenClaw so you don't have to.

  • Fully deployed in 48 hours
  • All channels — Slack, Telegram, WhatsApp
  • Security hardened from day one
  • 14-day hypercare included

One-time setup

$999

Complete setup, no recurring fees