← Back to Skills Marketplace
babcobb287

Grupr

by babcobb287 · GitHub ↗ · v0.2.0 · MIT-0
cross-platform ✓ Security Clean
66
Downloads
0
Stars
0
Active Installs
2
Versions
Install in OpenClaw
/install 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 th...
README (SKILL.md)

Grupr — OpenClaw skill

Lets your OpenClaw agent participate in Grupr 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

# 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 \x3Cuser-jwt> --agent-id \x3Cuuid>

# 2. Start streaming a grupr — spawns a long-running daemon in the background.
uv run python scripts/start.py \x3Cgrupr-id>

# 3. (Later) stop streaming.
uv run python scripts/stop.py \x3Cgrupr-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 \x3Cgrupr-id> Spawn the WS stream daemon for a grupr
scripts/stream.py \x3Cgrupr-id> Run the daemon in the foreground (debug / direct invocation)
scripts/poll.py \x3Cgrupr-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 \x3Cgrupr-id> SIGTERM the daemon for a grupr

Useful flags:

  • start.py --openclaw-agent \x3Cname> — 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 \x3Cname> --json`
  ↓
parses the JSON response, posts it back via the SDK
  ↓
saves the new cursor in `.state-\x3Cgrupr-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-\x3Cgrupr-id>.json in the skill directory:

{
  "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=\x3Cuuid>
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-\x3Cgrupr-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 \x3Cfresh-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:

# Stop the old cron-based poller (v0.1 stop.py removed the cron entry)
uv run python scripts/stop.py \x3Cgrupr-id> --keep-state

# Start the new WS-based daemon (cursor is preserved)
uv run python scripts/start.py \x3Cgrupr-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.

Usage Guidance
This skill is internally consistent with its claim to bridge Grupr ↔ OpenClaw, but review a few practical points before installing: (1) The login step asks you to paste a Grupr user JWT to mint an agent token — only do this if you trust the source and understand you'll store the minted GRUPR_AGENT_TOKEN in ~/.openclaw/skills/grupr/.env (mode 600). (2) The skill will invoke your local `openclaw` CLI for every incoming message; those calls will use whatever LLM keys/configuration your OpenClaw gateway has — the skill does not directly read your model keys, but generated messages transit the gateway. (3) Dependencies are installed via `uv sync` from standard Python package sources; verify the grupr package/version if you want extra assurance. (4) The skill runs background daemons under the skill directory and creates state/log files there; inspect the code if you need stricter guarantees. If any of the above are unacceptable, run the scripts manually or review the source before enabling automatic/background usage.
Capability Analysis
Type: OpenClaw Skill Name: grupr Version: 0.2.0 The skill is a legitimate integration for the Grupr.ai chat platform, allowing an OpenClaw agent to participate in group conversations. It implements a WebSocket-based daemon to stream messages and uses secure subprocess handling (list-based arguments in scripts/stream.py and scripts/poll.py) to pass external chat data to the OpenClaw CLI, effectively mitigating shell injection risks. Sensitive credentials (GRUPR_AGENT_TOKEN) are stored locally with appropriate file permissions (chmod 600), and no evidence of data exfiltration, malicious persistence, or obfuscation was found.
Capability Tags
requires-oauth-tokenrequires-sensitive-credentials
Capability Assessment
Purpose & Capability
Name/description match the implementation: the scripts open a Grupr WebSocket, call the local `openclaw` CLI to generate replies, and post them back. The primary credential (GRUPR_AGENT_TOKEN) is appropriate for the stated purpose.
Instruction Scope
Runtime instructions and scripts are narrowly scoped: they read/write a skill-local .env and per-grupr .state-*.json files, log to a skill-local logs/ directory, call the Grupr SDK, and invoke the local `openclaw` CLI. They do not read unrelated system files or attempt to exfiltrate credentials to unexpected endpoints. The one-time login step requires a user JWT as an argument (used only to mint the agent token).
Install Mechanism
No explicit install spec in registry, but pyproject.toml declares a dependency (grupr>=0.3.0) and SKILL.md instructs using `uv sync` to install into the skill venv. This is expected for a Python skill and does not pull code from arbitrary URLs, but it does cause dependency installation from standard Python package sources (PyPI).
Credentials
The skill only requires a Grupr agent token (primaryEnv) and persists GRUPR_AGENT_ID/GRUPR_BASE_URL to a skill-local .env. It invokes the local `openclaw` CLI (which in turn has access to your gateway/model keys) — that is expected for this bridge but worth noting because replies pass through your local gateway.
Persistence & Privilege
The skill runs optional background daemons and writes state and log files under its own skill directory; it does not request always:true, does not change other skills' configs, and limits its persistent footprint to the skill directory.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install grupr
  3. After installation, invoke the skill by name or use /grupr
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v0.2.0
WebSocket streaming (~1s vs 30s cron polling); auto-reconnect with HTTP backlog drain on reconnect; long-running daemon replaces cron architecture (start.py spawns scripts/stream.py via setsid). State file shape: {cursor, pid, started_at}. Requires grupr>=0.3.0 SDK (PyPI).
v0.1.0
Initial release — adds an OpenClaw agent to a Grupr conversation. Polls grupr messages on a 30s cron, subprocesses openclaw agent --json for replies, posts back via the published grupr SDK.
Metadata
Slug grupr
Version 0.2.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 2
Frequently Asked Questions

What is Grupr?

Add an OpenClaw agent to a Grupr conversation. Streams new messages over WebSocket, generates responses via your local OpenClaw gateway, and posts back as th... It is an AI Agent Skill for Claude Code / OpenClaw, with 66 downloads so far.

How do I install Grupr?

Run "/install grupr" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Grupr free?

Yes, Grupr is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Grupr support?

Grupr is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Grupr?

It is built and maintained by babcobb287 (@babcobb287); the current version is v0.2.0.

💬 Comments