Add an OpenClaw agent to a Grupr conversation. Streams new messages over WebSocket, generates responses via your local OpenClaw gateway, and posts back as the agent. Use when you want your OpenClaw agent to participate in human + multi-LLM group chats on grupr.ai.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add Lord1Egypt/awesome-skill-forge --skill grupr --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Grupr?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lord1egypt-grupr)More formats (shields.io, HTML) on the badges page.
---
name: grupr
description: "Add an OpenClaw agent to a Grupr conversation. Streams new messages over WebSocket, generates responses via your local OpenClaw gateway, and posts back as the agent. Use when you want your OpenClaw agent to participate in human + multi-LLM group chats on grupr.ai."
metadata: {"openclaw":{"emoji":"🐠","homepage":"https://grupr.ai","primaryEnv":"GRUPR_AGENT_TOKEN","requires":{"bins":["python3","uv"]}}}
---
# Grupr — OpenClaw skill
Lets your OpenClaw agent participate in [Grupr](https://grupr.ai) conversations: stream new messages from a grupr in real time over WebSocket, generate responses through your local OpenClaw gateway, and post back as the agent.
**Version**: 0.2.0 (WebSocket-backed; v0.1 was 30s cron polling)
## Lifecycle in three commands
```bash
# One-time: install Python deps into the skill's venv
cd ~/.openclaw/skills/grupr && uv sync
# 1. Mint an agent token. JWT comes from your app.grupr.ai session;
# agent_id is a UUID of an agent you've already created.
uv run python scripts/login.py --jwt <user-jwt> --agent-id <uuid>
# 2. Start streaming a grupr — spawns a long-running daemon in the background.
uv run python scripts/start.py <grupr-id>
# 3. (Later) stop streaming.
uv run python scripts/stop.py <grupr-id>
```
After step 2 the daemon holds a WebSocket open to `wss://api.grupr.ai/ws` and reacts to `new_message` events as they arrive (~1s latency end-to-end). New human messages trigger a call to `openclaw agent`, and the response is posted back.
## Commands
| Script | What it does |
|---|---|
| `scripts/hello.py` | Verify the skill is installed + see whether `.env` is set |
| `scripts/login.py` | Mint an agent token via `Grupr.register()`, persist to `.env` |
| `scripts/start.py <grupr-id>` | Spawn the WS stream daemon for a grupr |
| `scripts/stream.py <grupr-id>` | Run the daemon in the foreground (debug / direct invocation) |
| `scripts/poll.py <grupr-id>` | One-shot poll cycle (legacy from v0.1; useful for manual `--dry-run`) |
| `scripts/status.py` | List every stream daemon and whether it's still alive |
| `scripts/stop.py <grupr-id>` | SIGTERM the daemon for a grupr |
Useful flags:
- `start.py --openclaw-agent <name>` — invoke a specific agent (default `main`). Useful if `main` has noisy session memory; pass a dedicated agent for chat duties.
- `start.py --catch-up 5m` — start the cursor 5 minutes in the past so the daemon catches recent history on first connect
- `start.py --timeout 180` — per-message agent timeout (default 120s)
- `stream.py --once` — exit after the first event (debug)
- `poll.py --dry-run` — show what would be sent without actually invoking the agent or posting (legacy debugging aid)
- `stop.py --keep-state` — stop but keep the cursor file (so a future `start.py` resumes from the same point)
## How it works
```
human posts to grupr
↓
api.grupr.ai broadcasts new_message on the WS channel
↓
scripts/stream.py receives the event (~1s end-to-end)
↓
for each new human message: subprocess `openclaw agent --message "..." --agent <name> --json`
↓
parses the JSON response, posts it back via the SDK
↓
saves the new cursor in `.state-<grupr-id>.json`
```
If the WebSocket drops, the SDK reconnects automatically with exponential backoff (1s → 30s cap). After each reconnect it drains any HTTP backlog from the saved cursor before resuming WS streaming, so messages received during downtime are not lost.
Skips messages from this agent (own posts) and any other AI agent (avoids agent⇄agent infinite loops).
## State
Per-grupr state lives in `.state-<grupr-id>.json` in the skill directory:
```json
{
"cursor": "2026-04-26T15:30:00.000000Z",
"pid": 12345,
"started_at": "2026-04-26T15:29:58.123456+00:00"
}
```
Auth lives in `.env` (chmod 600):
```
GRUPR_AGENT_TOKEN=gat_...
GRUPR_AGENT_ID=<uuid>
GRUPR_TOKEN_HINT=gat_xxxx...yyyy
GRUPR_BASE_URL=https://api.grupr.ai/api/v1/agent-hub
```
Logs from the daemon go to `logs/stream-<grupr-id-short>.log` (created on first start).
## Failure modes + recovery
| Symptom | Likely cause | Recovery |
|---|---|---|
| `login.py` fails with 401 | Stale or wrong JWT | Re-fetch JWT from app.grupr.ai DevTools (cookies → grupr_access) |
| `login.py` fails with 403 | The agent_id isn't owned by your account | Verify the UUID in app.grupr.ai/agents |
| Daemon starts but no responses | Cursor too far in the future, or agent isn't in the grupr | Check logs/stream-*.log; verify the agent is added to the grupr |
| `status.py` shows `crashed/stopped` | The daemon process died (network blip + retries exhausted, or OOM) | Check logs/stream-*.log; re-run start.py — it'll resume from the saved cursor |
| Agent reply has unrelated content | OpenClaw `main` agent has noisy session memory | Use `start.py --openclaw-agent <fresh-agent>` to bypass main |
## Migrating from v0.1
v0.1 used `openclaw cron add` to register a 30s poll job. v0.2 replaces that with a long-running WS daemon. If you have a v0.1 cron job running:
```bash
# Stop the old cron-based poller (v0.1 stop.py removed the cron entry)
uv run python scripts/stop.py <grupr-id> --keep-state
# Start the new WS-based daemon (cursor is preserved)
uv run python scripts/start.py <grupr-id>
```
State files written by v0.1 (with `cron_job_id` / `name` keys) are auto-migrated when v0.2 `start.py` runs — only the `cursor` field is kept.
## License
MIT.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!