openhands-automation
This skill should be used when the user asks to "create an automation", "schedule a task", "set up a cron job", "webhook integration", "event-triggered…
Skill by OpenHands
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/openhands-openhands-automation
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/openhands-automation
What's inside
- Skill name
openhands-automation- Description
- This skill should be used when the user asks to "create an automation", "schedule a task", "set up a cron job", "webhook integration", "event-triggered automation", or mentions automations, scheduled tasks, cron scheduling, or webhook events in OpenHands Cloud.
- License
- MIT
- Instructions
- 1,027 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
Agent Skills spec issues
- body: 1027 lines (spec recommends under 500)
- files: referenced but missing: scripts/setup_webhook.py
Files (10)
- .claude-plugin
- .codex-plugin
- plugin.json · .plugin/
- README.md
- SKILL.md
- automation-create.md · commands/
- ab-testing.md · references/
- custom-automation.md · references/
- security.md · references/
- windows.md · references/
SKILL.md (first lines)
# OpenHands Automations
Create and manage automations that run inside an OpenHands agent server — triggered by cron schedules or webhook events (GitHub, custom services).
Windows PowerShell equivalents for the automation API `curl` examples and shell-variable conventions are in `references/windows.md`.
## Automation Creation Process
The agent must follow these steps when creating an automation:
* Quickly check that you can access the correct automations backend using the auth mechanism below
* Quickly check that you can access any necessary integrations (e.g. GitHub, Slack); if access fails, inform the user and stop
* Ask the user for any necessary information, e.g. if you need the name of a Slack channel or GitHub repo to proceed
* Prefer creating a plugin-spec automation when the task can be packaged as an executable plugin. Before creating it, ask which local git repo or remote git repo should be used as the plugin source; if the user wants a local source and no repo exists yet, help them initialize and commit a local git repo first.
* Write the code, plugin manifest, or prompt that will be sent to the automations backend _inside the current workspace_
* Show the code to the user with the `canvas_ui` tool if available, otherwise present it in a fenced code block in your reply
* Message the user with a concise summary of how the automation will behave, and ask if they are ready to deploy it
## Architecture
Two components work together to run automations:
**Automation Service** (API at `OPENHANDS_HOST/api/automation/v1`)
Manages the *when*: holds automation definitions, schedules cron-triggered runs, dispatches webhook-triggered runs, and receives completion callbacks to mark runs as done. This is the API you call to create, update, and manage automations.
**Agent Server** (accessible as `AGENT_SERVER_URL` inside script runs)
Manages the *what*: the runtime environment where automation scripts execute and where conversations (AI agent interactions with tools, bash, file editing, etc.) run. When a run is triggered, the automation service uploads the automation's tarball to the agent server, which unpacks and runs the entrypoint script. The script connects back to the agent server using `AGENT_SERVER_URL` and a session API key to start, monitor, and stop conversations.
The agent server typically runs inside a **sandbox** (a Docker or Kubernetes container). Some deployments use sandboxless mode, where the agent server runs directly on a host.
**Key environment variables:**
| Variable | Availability | Description |
|---|---|---|
| `RUNTIME_URL` | Ambient in cloud environments | Public-facing URL of the **agent server** sandbox. Use this to determine whether external webhook delivery is possible — if unset or local, webhooks cannot be received. The automation service may run at a separate URL (see Determining the API Host). |
| `AGENT_SERVER_URL` | Injected into scripts at run time, local Agent Canvas only | Internal URL of the agent server. Available inside script execution context; **not** an ambient environment variable outside of a running script, and not set on OpenHands Cloud or Enterprise. |
| `OPENHANDS_HOST` | Shell convention only — set manually | Base URL for the automation service API. **Not a real environment variable.** Set it from an explicit host, a detected local Agent Canvas server, or the cloud default. Used in all `curl` examples throughout this skill. |
> **⚠️ CRITICAL — Agent behavior rules:**
>
> 0. **Does this task need an LLM at all? Check first.** Before picking a preset, ask whether the task actually requires reasoning, judgment, summarization, or open-ended tool use. If it is fully deterministic — fixed data transforms, scheduled HTTP calls, healthcheck pings, file rotation, picking from a known list, posting a templated message — an LLM-driven preset is overkill. Every run will consume LLM tokens, which adds up fast at high frequencies (every 5 min ≈ 288 runs/day). For deterministic code-backed work, prefer a plugin-spec automation with `entrypoint.runner` set to `"script"`; it packages the custom code as part of the plugin and runs without an LLM. Use the custom-script path only when the user explicitly wants raw tarball control. Be especially careful for cron schedules tighter than hourly.
>
> **Instant-recognition patterns — these are always deterministic, never use an LLM preset:**
> - "post a quote / message / fact every N minutes" (rotating from a list)
> - "send a scheduled reminder / standup / digest"
> - "ping a health-check URL on a schedule"
> - "post to Slack / webhook every N minutes"
> - Any task where the full output could be written as a static template right now
>
> 1. **For reusable or code-backed automations, prefer plugin specs.** A plugin-spec automation (`POST /v1/plugin-spec`) is the preferred path when the automation can be packaged as an executable plugin with its own manifest, config schema, runtime profiles, and entrypoint. Before creating it, ask which source repo to use:
> - **Remote git repo** - usually `github:owner/repo` or `https://github.com/owner/repo.git`, plus optional `ref` and `repo_path`. Required for Cloud unless the deployment explicitly supports local sources.
> - **Local git repo** - local Agent Canvas only. Ask for the path. If the user has not created one, help create a directory, run `git init`, add the plugin files, and make an initial commit before calling `/plugin-spec`. Do not point plugin-spec creation at an uncommitted temp directory.
> 2. **Use prompt or plugin presets for one-off LLM work.** They handle SDK boilerplate, tarball packaging, and upload automatically:
> - **Prompt preset** (`POST /v1/preset/prompt`) - for one-off tasks expressed as a natural language prompt that benefit from agent reasoning
> - **Plugin preset** (`POST /v1/preset/plugin`) - when plugins with skills, MCP configs, or commands are needed but no executable plugin-spec contract exists yet
> 3. **Present the options, then build the one the user picks.** Whenever rule 0 applies, or neither plugin spec nor a preset is a clean fit (custom Python dependencies, a non-Python entrypoint, a multi-file project, direct SDK lifecycle control), lay the choices out side by side with a one-line note on cost and reliability for each, and let the user choose:
> - **Plugin spec automation** - preferred for reusable/code-backed and deterministic automations; use `entrypoint.runner: "script"` for custom code and requires a local or remote git repo source
> - **Prompt preset** - natural language prompt execution (LLM-driven)
> - **Plugin preset** - load plugins with extended capabilities (skills, MCP, hooks, commands)
> - **Custom script** - raw tarball control with or without an LLM; see `references/custom-automation.md`
>
> Do not silently fall back to either side. The "ready to deploy?" confirmation in the creation process applies to every path equally; a custom script needs no extra permission beyond it, and a preset gets no pass on it.
> 4. **Building a custom script:** follow `references/custom-automation.md` for tarball packaging, validation, and upload. The *Custom Script Example (No LLM)* below shows the whole flow end to end.
> 5. **Before suggesting event-triggered (webhook) automations, check whether the deployment is publicly reachable.** Check `RUNTIME_URL`. Webhooks require an internet-accessible URL so that external services (GitHub, Slack, Linear, etc.) can deliver events to the automation service. If `RUNTIME_URL` is unset, empty, or resolves to a local or private address (`localhost`, `127.0.0.1`, `0.0.0.0`, or any RFC 1918 range: `10.x.x.x`, `192.168.x.x`, `172.16–31.x.x`), the service cannot receive inbound webhook traffic from the public internet. In that case:
> - **Recommend a cron-based polling automation instead.** Have the automation run on a schedule and call the external service's API (e.g., the GitHub REST API) to check for new events since the last run.
> - Explain the limitation clearly to the user: "Because this is a local deployment, external services can't reach the webhook endpoint. I'll set up a polling automation using a cron schedule instead."
### No-LLM Script Helpers
Prefer plugin-spec automations with `entrypoint.runner: "script"` for deterministic code that can live in a plugin repo. When the user explicitly chooses the raw custom-script path instead, these two stdlib-only functions are required. Copy them verbatim - they use variables injected by the automation service: `SESSION_API_KEY`, plus `AGENT_SERVER_URL` on a local Agent Canvas or `OPENHANDS_CLOUD_API_URL` and `SANDBOX_ID` on OpenHands Cloud and Enterprise.
```python
import json, os, urllib.request
def get_secret(name):
"""Fetch a named secret: from the agent server when AGENT_SERVER_URL is set, else from the OpenHands API."""
url = os.environ.get("AGENT_SERVER_URL", "").rstrip("/")
key = os.environ.get("SESSION_API_KEY") or os.environ.get("OH_SESSION_API_KEYS_0", "")
if url: # local Agent Canvas
url = f"{url}/api/settings/secrets/{name}"
else: # OpenHands Cloud / Enterprise
api = os.environ["OPENHANDS_CLOUD_API_URL"].rstrip("/")
url = f"{api}/api/v1/sandboxes/{os.environ['SANDBOX_ID']}/settings/secrets/{name}"
with urllib.request.urlopen(urllib.request.Request(
url, headers={"X-Session-API-Key": key}
)) as r:
return r.read().decode().strip()
def fire_callback(status="COMPLETED", error=None):
"""Signal run completion. MUST be called on every exit path — success AND error."""
url = os.environ.get("AUTOMATION_CALLBACK_URL", "")
if not url: return
body = {"status": status, "run_id": os.environ.get("AUTOMATION_RUN_ID", "")}
if error: body["error"] = error
try:
urllib.request.urlopen(urllib.request.Request(url, data=json.dumps(body).encode(), headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {os.environ.get('AUTOMATION_CALLBACK_API_KEY', '')}",
}))
except Exception as e: print(f"Callback error: {e}")
```
Entrypoint must be `python3 main.py` (no `setup.sh` needed). Wrap your main logic in `try/except` and call `fire_callback("FAILED", str(e))` in the except block.
**State persistence between runs** — polling automations that track a "last processed" timestamp or active conversation IDs must use the built-in KV store rather than local files. Local files are lost when a run ends on a cloud pod. The KV store is available when `AUTOMATION_KV_TOKEN` is injected into the run environment. See `references/custom-automation.md#state-persistence-kv-store` for ready-to-copy `kv_get` / `kv_set` / `load_state` / `save_state` helpers.
---
## Authentication
All requests require authentication:
- Cloud (default `https://app.all-hands.dev`): Bearer token:
`-H "Authorization: Bearer ${OPENHANDS_API_KEY}"`
- Local Agent Canvas (`http://localhost:8001`): session API key through `X-Session-API-Key`:
`-H "X-Session-API-Key: ${OPENHANDS_AUTOMATION_API_KEY:-${SESSION_API_KEY}}"`
The curl examples below show cloud Bearer authentication. For local Agent Canvas, replace that header with the `X-Session-API-Key` header above.From OpenHands/extensions, MIT.
More from OpenHands/extensions
- 0.721score
deno
OpenHands
If the project uses deno, use this skill.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
discord
OpenHands
Build and automate Discord integrations (bots, webhooks, slash commands, and REST API workflows).
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
code-simplifier
OpenHands
Simplifies and refines code for clarity, consistency, and maintainability while preserving all functionality.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
datadog
OpenHands
Query and analyze Datadog logs, metrics, APM traces, and monitors using the Datadog API.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-skill
OpenHands
Import an existing skill from a GitHub repository URL into the current workspace.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-javadoc
OpenHands
Add comprehensive JavaDoc documentation to Java classes and methods.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
runtime-api-configs
OpenHands
Manage warm sandbox pools on OpenHands Enterprise by driving the runtime-api admin endpoints (list, save, delete warm runtime configurations) from a Python CLI.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
agent-creator
OpenHands
Create file-based sub-agents as Markdown files following the OpenHands SDK format.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
openhands
OpenHands
Unified OpenHands plugin — bundles the OpenHands Cloud CLI, Cloud REST API (openhands-api), Automations (openhands-automation), and Software Agent SDK…
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
agent-readiness-report
OpenHands
Evaluate how well a codebase supports autonomous AI-assisted development.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
release-notes
OpenHands
Generate consistent, well-structured release notes from git history.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
github
OpenHands
Interact with GitHub repositories, pull requests, issues, and workflows using the GITHUB_TOKEN environment variable and GitHub CLI.
SkillAFreshness: A★ 173Claude Code +9
Signals
- Stars
- 173
- Forks
- 118
- Open issues
- 84
- Last commit (this folder)
- Oct 5, 2026 (24 days ago)
- Last release
- Oct 23, 2026 (7 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/OpenHands/extensions
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from OpenHands
- 0.721score
release-notes
OpenHands
Generate consistent, well-structured release notes from git history.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-javadoc
OpenHands
Add comprehensive JavaDoc documentation to Java classes and methods.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
agent-readiness-report
OpenHands
Evaluate how well a codebase supports autonomous AI-assisted development.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
openhands
OpenHands
Unified OpenHands plugin — bundles the OpenHands Cloud CLI, Cloud REST API (openhands-api), Automations (openhands-automation), and Software Agent SDK…
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
runtime-api-configs
OpenHands
Manage warm sandbox pools on OpenHands Enterprise by driving the runtime-api admin endpoints (list, save, delete warm runtime configurations) from a Python CLI.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-skill
OpenHands
Import an existing skill from a GitHub repository URL into the current workspace.
SkillAFreshness: A★ 173Claude Code +9
Cite this page
openhands-automation skill. Agent Mart. https://agentmart.dev/skills/openhands-openhands-automation (last updated 2026-10-24)