Back to skills
SKILL.md
Ops Discord
BSecurityTOS-compliant Discord notification monitor. Watches YOUR Discord server for security content forwarded by researchers, matches keywords, and pushes to create-paper/dogpile via webhooks. Persists to graph-memory for semantic search.
- 6 stars
- 0 votes
- 0 copies
- 3 views
- Added September 11, 2026
Works with
Security analysis
75/100- Modifies startup scripts or system services for persistence
Pro scans all 18 files and shows the line behind each finding
npx -y skills add grahama1970/agent-skills --skill ops-discord --agent claude-codeAre you the author of Ops Discord?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/grahama1970-ops-discord)---
name: ops-discord
description: >
TOS-compliant Discord notification monitor. Watches YOUR Discord server for
security content forwarded by researchers, matches keywords, and pushes to
create-paper/dogpile via webhooks. Persists to graph-memory for semantic search.
allowed-tools:
- Bash
- Read
- Write
triggers:
- discord
- discord monitor
- discord notifications
- discord keywords
- security discord
- discord webhook
metadata:
short-description: Discord keyword monitor with webhook + memory integration
provides:
- ops-discord
composes:
- task-monitor
- agentic-evals
disciplines:
- observability-operations
- research-retrieval
---
# Discord Operations - Notification Monitor Model
**TOS-compliant** approach to Discord security intelligence gathering.
## Transports — read this FIRST before claiming Discord is unconfigured
This skill has **two independent delivery transports**. A caller (human or
agent) must check both before concluding Discord notification is unavailable:
| Transport | Command form | Configured by | Check with |
| --- | --- | --- | --- |
| **Webhook** | `notify --webhook <name>` | `OPS_DISCORD_WEBHOOK_<NAME>_URL` / `DISCORD_WEBHOOK_URL` / `SLACK_WEBHOOK_URL` (env or `~/.zshrc`) or `config.json` | `./run.sh webhook list` |
| **Discord bot** | `notify --discord-bot --channel-name <name>` | `DISCORD_BOT_TOKEN` (+ guild) in env, `~/.zshrc`, or clawdbot `.env` | `./run.sh setup` |
Rules that prevent the 2026-09-03 mistake (an agent reported "no Discord
webhook configured, human must create one" while `DISCORD_BOT_TOKEN` in
`~/.zshrc` could already deliver to `#horus`):
- **`NO_WEBHOOK` means that one named webhook is missing, nothing more.** It is
NOT evidence that Discord delivery is unconfigured. Always try or check the
bot transport before escalating to the human.
- **Verify transport availability with a dry-run, not an assumption:**
`./run.sh notify --discord-bot --channel-name horus --content probe --dry-run --json`
resolves the real guild + channel id without posting (`status: DRY_RUN`,
`ok: true`).
- **Live delivery proof is the returned `message_id`/`message_url`**, read from
the `ops_discord.notification_receipt.v1` receipt — not the exit code.
- Composing skills (e.g. `$project-watchdog` alerting) should prefer the
webhook when its env var exists and fall back to `--discord-bot` otherwise.
Both transports go through one command: `notify` (see below).
## The Key Insight
**OLD (Broken):** Try to search external servers where you're not admin → TOS violation, impossible
**NEW (Works):** Monitor YOUR OWN server for content forwarded by researchers → 100% compliant
## Architecture
```
┌───────────────────────────────────────────────────────────────────────────────┐
│ TOS-Compliant Discord Pipeline + Memory │
├───────────────────────────────────────────────────────────────────────────────┤
│ │
│ External Sources Your Server (Admin) Consumers │
│ ──────────────── ──────────────────── ───────── │
│ │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ Researchers │──DM/forward──▶│ #security-intel │ │
│ │ share │ │ │ │
│ │ insights │ │ Your Bot │──webhook──▶ create-paper │
│ └─────────────┘ │ (keyword watch) │ │
│ │ │──webhook──▶ dogpile │
│ ┌─────────────┐ │ Keywords: │ │
│ │ Telegram │──bridge──▶ │ CVE, DARPA, │ │
│ │ bridges │ (social- │ HTB, 0-day... │ │
│ └─────────────┘ bridge) └────────┬─────────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ matches │ │ graph-memory │ │ dogpile │ │
│ │ .jsonl │ │ (ArangoDB) │ │ search │ │
│ │ (local) │ │ lessons │ │ │ │
│ └──────────┘ └──────┬───────┘ └─────┬──────┘ │
│ │ │ │
│ └────────────────┘ │
│ (semantic recall) │
│ │
└───────────────────────────────────────────────────────────────────────────────┘
```
## Quick Start
```bash
# 1. Check setup
./run.sh setup
# 2. Add your Discord server to monitor
./run.sh guild add "Security Intel" 1234567890123456789
# 3. Add webhook for forwarding matches
./run.sh webhook add alerts "https://discord.com/api/webhooks/..."
# 4. Start monitoring
./run.sh monitor start --webhook alerts
```
## Commands
### `setup` - Check Configuration
```bash
./run.sh setup
```
Shows status of:
- Bot token (from env or clawdbot)
- discord.py library
- httpx for webhooks
- Current configuration
### `keywords` - Manage Watch Patterns
```bash
# List all keywords (regex patterns)
./run.sh keywords list
# Add a keyword pattern
./run.sh keywords add "CVE-2025-\d+"
./run.sh keywords add "supply.?chain"
# Remove a pattern
./run.sh keywords remove "HTB"
# Reset to defaults
./run.sh keywords reset
```
**Default Keywords:**
- Vulnerabilities: `CVE-\d{4}-\d+`, `0-?day`, `exploit`, `RCE`, `LPE`, `privesc`
- Programs: `DARPA`, `IARPA`, `BAA`, `grants?\.gov`
- Platforms: `HTB`, `TryHackMe`, `CTF`
- Threat Intel: `APT\d+`, `malware`, `ransomware`, `C2`, `cobalt.?strike`
- Techniques: `MITRE`, `ATT&CK`, `T\d{4}`
### `guild` - Manage Monitored Servers
```bash
# List monitored guilds
./run.sh guild list
# Add a guild to monitor
./run.sh guild add "My Server" 1234567890123456789
# Remove a guild
./run.sh guild remove "My Server"
```
### `webhook` - Manage Output Webhooks
```bash
# List webhooks
./run.sh webhook list
# Add a webhook
./run.sh webhook add alerts "https://discord.com/api/webhooks/..."
./run.sh webhook add create-paper "http://localhost:8000/paperwriter/discord"
# Remove a webhook
./run.sh webhook remove alerts
# Test a webhook
./run.sh webhook test alerts
# Send one operational notification; dry-run resolves the webhook without posting
./run.sh notify --webhook alerts --content "self-repair entered" --dry-run --json
# Send through the Discord bot into an owned server channel; returns message_id/url
./run.sh notify --discord-bot --channel-name horus --content "self-repair entered" --json
```
### `monitor` - Run the Monitor
```bash
# Check status
./run.sh monitor status
# Start monitoring (foreground)
./run.sh monitor start --webhook alerts
# Start in dry-run mode (log only, don't forward)
./run.sh monitor start --dry-run
# Stop the monitor
./run.sh monitor stop
```
### `matches` - View Logged Matches
```bash
# Show recent matches
./run.sh matches
# Show more matches
./run.sh matches --limit 50
# Filter by keyword
./run.sh matches --keyword CVE
# Output as JSON
./run.sh matches --json
```
### `memory` - Knowledge Graph Integration
```bash
# Check memory integration status
./run.sh memory status
# Search stored matches in memory
./run.sh memory search "CVE-2024"
# Search with JSON output
./run.sh memory search "ransomware" --json --k 20
# Ingest existing matches from log file to memory
./run.sh memory ingest --limit 100
```
**Auto-Persistence:**
The monitor automatically persists matches to memory by default:
```bash
# Start with memory persistence (default)
./run.sh monitor start --webhook alerts
# Start without memory persistence
./run.sh monitor start --webhook alerts --no-persist
```
## Webhook Payload Formats
### Discord Webhook (auto-detected by URL)
```json
{
"embeds": [{
"title": "Keyword Match: CVE-2024-1234, exploit",
"description": "New RCE exploit for CVE-2024-1234...",
"url": "https://discord.com/channels/...",
"color": 5793266,
"author": {"name": "researcher#1234"},
"footer": {"text": "Security Intel #cve-alerts"},
"timestamp": "2026-01-28T12:00:00Z"
}]
}
```
### Generic Webhook (create-paper/dogpile)
```json
{
"source": "discord",
"content": "New RCE exploit for CVE-2024-1234...",
"author": "researcher#1234",
"channel": "Security Intel/#cve-alerts",
"url": "https://discord.com/channels/...",
"keywords": ["CVE-2024-1234", "exploit"],
"timestamp": "2026-01-28T12:00:00Z"
}
```
## Setup Your Security Intel Server
### Step 1: Create Server
Create a Discord server for aggregating security intel:
- `#cve-alerts` - CVE announcements
- `#research-feed` - General security research
- `#threat-intel` - APT/malware news
- `#darpa-baa` - Funding opportunities
### Step 2: Add Your Bot
1. Use the bot from clawdbot or create a new one
2. Required permissions: `Read Messages`, `Read Message History`, `View Channels`
3. Get guild ID: Server Settings → Widget → Server ID
### Step 3: Invite Researchers
- Researchers can forward content from other servers to your channels
- Or set up Telegram bridges (see social-bridge skill)
- Bot watches for keywords in YOUR server only
### Step 4: Configure Webhooks
Create webhooks in your destination channels or endpoints:
- Discord webhook for alerts channel
- HTTP webhook for create-paper integration
- Generic webhook for ArangoDB logging
## Integration with create-paper
```bash
# create-paper endpoint receives Discord matches
POST /paperwriter/discord
{
"source": "discord",
"content": "...",
"keywords": ["CVE-...", "exploit"],
...
}
# Gets auto-indexed alongside arXiv/SAM.gov pulls
```
## Integration with social-bridge
The social-bridge skill can forward Telegram content to your Discord server:
```
Telegram Public Channels → social-bridge → Your Discord → ops-discord → create-paper
```
## Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| `DISCORD_BOT_TOKEN` | Bot token | Yes (or in clawdbot .env) |
| `CLAWDBOT_DIR` | Path to clawdbot | No (default: ~/workspace/experiments/clawdbot) |
| `OPS_DISCORD_WEBHOOK_URL` | Default output webhook URL loaded without writing `config.json` | No |
| `OPS_DISCORD_WEBHOOK_<NAME>_URL` | Named output webhook URL; `<NAME>` becomes the webhook name | No |
| `DISCORD_WEBHOOK_URL` | Discord-specific default webhook alias | No |
| `SLACK_WEBHOOK_URL` | Slack-compatible webhook alias named `slack` | No |
| `OPS_DISCORD_ZSHRC` | Alternate zshrc file to parse for known webhook exports | No |
`webhook list` redacts token-bearing URL paths. Supported webhook env vars are
also read from `~/.zshrc` without executing shell code, which lets cron-like
callers discover the same configured names even when they are not interactive
shells.
## Files
```
.pi/skills/ops-discord/
├── discord_ops.py # Main CLI
├── run.sh # Runner script
├── config.json # Guilds and webhooks config
├── keywords.json # Watched keyword patterns
├── matches.jsonl # Logged keyword matches
└── monitor.pid # PID file when running
```
## Why This Works
| Aspect | This Approach |
|--------|---------------|
| **TOS** | Compliant - monitoring YOUR server |
| **Admin access** | Only needed on YOUR server |
| **Real-time** | Yes - event-driven via Gateway |
| **Scalable** | Limited by webhook rate limits |
| **Reliable** | Uses official Discord API |
## Comparison with Old Approach
| Feature | Old (Search) | New (Monitor) |
|---------|--------------|---------------|
| Search external servers | Attempted | Not needed |
| Requires admin on target | Yes (impossible) | No |
| TOS compliant | No | Yes |
| Real-time | No | Yes |
| Works | No | Yes |
Files in this skill
- SKILL.md
- discord_ops.py
- discord_ops/__init__.py
- discord_ops/compliance_bot.py
- discord_ops/config.py
- discord_ops/graph_persistence.py
- discord_ops/keyword_matcher.py
- discord_ops/notifications.py
- discord_ops/utils.py
- discord_ops/webhook_monitor.py
- fixtures/agentic_eval.json
- local/unlazy/ops-discord-env-webhook-GATES.md
- pyproject.toml
- run.sh
- sanity.sh
- tests/__init__.py
- tests/test_compliance_bot.py
- tests/test_env_webhooks.py
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.