Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

News Monitor

v1.0.0

Real-time news aggregator with Discord & Telegram push. Manage Jin10, BlockBeats, RSS, X KOLs, Polymarket, OpenNews via REST API.

0· 460·5 current·5 all-time
Security Scan
VirusTotalVirusTotal
Suspicious
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
Name/description (news aggregator with Discord/Telegram push) align with the runtime instructions (clone repo, npm install, run server, configure sources and webhooks). Required binaries (node, npm) are appropriate for the stated purpose.
!
Instruction Scope
SKILL.md tells the user/agent to git clone https://github.com/zxcnny930/buzz.git, run npm install and npm start, then manage the running service via local HTTP endpoints. The API allows hot updates to config (including API keys, webhooks, bot tokens) and examples omit the password parameter; the doc explicitly says a blank password => no authentication. Running this service therefore grants an external repo code execution on your system and exposes an admin API that can be unauthenticated — both are scope/risk concerns relative to a typical 'skill' install.
!
Install Mechanism
There is no install spec in the registry bundle; instead SKILL.md instructs cloning and running a third‑party GitHub repository and running npm install (arbitrary remote code). While GitHub is a common host, fetching and executing upstream code at runtime is higher risk than an instruction-only skill that contains no external downloads.
Credentials
The skill declares no required env vars, which is reasonable, but the API and docs show it will store and use many sensitive values (discord webhookUrl, telegram botToken/chatId, grok/apiKey, etc.) in config.json. The package.json metadata references agent tools like exec/read, indicating the skill expects shell execution abilities. Requiring secrets at runtime (in config) is proportionate to the service, but the registry does not explicitly require or limit these credentials — review before providing them.
!
Persistence & Privilege
The instructions run a long‑running local server (default port 3848) that accepts configuration changes via HTTP. Although always:false (not force-installed), the service persists while running and can be left reachable. Because the server can operate without a password if misconfigured, it may be remotely or locally manipulated. This persistent network presence increases attack surface.
What to consider before installing
This skill appears to be what it claims (a node-based news aggregator) but it asks you to fetch and run code from an external GitHub repo and to host an HTTP admin API that can be left unauthenticated. Before installing: (1) review the upstream repository source code yourself (or request the code be bundled into the skill) to check for concealed network exfiltration or privileged operations; (2) run it inside an isolated environment (container or VM) with limited network and file access; (3) set a strong dashboard.password and avoid leaving it blank; (4) do not supply production credentials (Discord webhooks, Telegram bot tokens, API keys) until you trust the code; (5) if you must run on a host, bind the service to localhost only and firewall the port; (6) prefer a skill that includes audited code in the bundle or is published from a known/verified source. If you want, I can list exact files or code locations to inspect next (e.g., startup scripts, config handling, outgoing request logic).

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

📰 Clawdis
OSmacOS · Linux · Windows
Binsnode, npm
latestvk97ecq56enw676ggfv2tvg4nfn823zfd
460downloads
0stars
1versions
Updated 19h ago
v1.0.0
MIT-0
macOS, Linux, Windows

Buzz Skill

Install, run, and manage a real-time news aggregator with Discord & Telegram push notifications. All configuration is done via REST API with hot-reload — no restarts needed.

Base URL: http://localhost:3848 (default, configurable via dashboard.port)

Quick Setup

git clone https://github.com/zxcnny930/buzz.git
cd buzz
npm install
cp config.example.json config.json
npm start

The dashboard is at http://localhost:3848, settings page at /settings.html?lang=en.

Authentication

If a dashboard password is set, all /api/* endpoints require ?pw=PASSWORD:

curl -s "http://localhost:3848/api/config?pw=YOUR_PASSWORD"

If password is empty string, no authentication is needed.

IMPORTANT: All curl examples below omit ?pw= for brevity. If the server has a password configured, append ?pw=PASSWORD to every URL.

Auth failure response (HTTP 401):

{ "ok": false, "error": "Unauthorized" }

API Endpoints

1. Get Current Config

curl -s http://localhost:3848/api/config

Returns the full configuration JSON. Sensitive fields (apiKey, token, botToken, password) are redacted as "••••••" in the response.

2. Update Config (Partial, Hot-Reload)

POST /api/config accepts partial updates. Only send the sections you want to change.

Enable Jin10 with 10-second polling:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"jin10": {"enabled": true, "pollIntervalMs": 10000}}'

Disable Polymarket:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"polymarket": {"enabled": false}}'

Set Discord webhook:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"discord": {"webhookUrl": "https://discord.com/api/webhooks/..."}}'

Enable Telegram:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"telegram": {"enabled": true, "botToken": "123456:ABC-DEF", "chatId": "-1001234567890"}}'

Add an RSS source:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"rssFeeds": [{"enabled": true, "name": "CoinDesk", "feedUrl": "https://www.coindesk.com/arc/outboundfeeds/rss/?outputType=xml", "pollIntervalMs": 300000, "color": 3447003}]}'

Note: rssFeeds is an array — sending it replaces the entire array, not appends.

Configure OpenNews AI filtering:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"opennews": {"enabled": true, "pollIntervalMs": 60000, "minScore": 70, "signals": ["long"], "coins": ["BTC", "ETH"], "engineTypes": ["news", "listing"]}}'

Configure Polymarket alerts:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"polymarket": {"enabled": true, "minChangePp": 5, "zThreshold": 2.5, "volSpikeThreshold": 2.0, "minLiquidity": 10000, "tagIds": [21, 120], "excludeTagIds": [100639]}}'

Set AI translation model:

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"grok": {"apiKey": "xai-...", "model": "grok-4.1-fast", "baseUrl": "https://api.x.ai/v1"}}'

Success response:

{ "ok": true }

Validation error response:

{
  "ok": false,
  "errors": ["polymarket.zThreshold must be > 0", "dashboard.port must be 1024-65535"]
}

3. Get Source Status

curl -s http://localhost:3848/api/status

Response:

{
  "jin10": { "active": true, "interval": 15000 },
  "blockbeats": { "active": true, "interval": 30000 },
  "polymarket": { "active": true, "interval": 180000 },
  "x6551": { "active": true, "interval": 3600000 },
  "opennews": { "active": false, "interval": 60000 },
  "rss:https://www.blocktempo.com/feed/": { "active": true, "interval": 300000 }
}

Each key is a source identifier. RSS sources are prefixed with rss: followed by their feed URL.

4. Manage KOL Tracking List

List all tracked accounts:

curl -s -X POST http://localhost:3848/api/kols \
  -H "Content-Type: application/json" \
  -d '{"action": "list"}'

Response:

{ "ok": true, "kols": ["elonmusk", "VitalikButerin"] }

Add a KOL:

curl -s -X POST http://localhost:3848/api/kols \
  -H "Content-Type: application/json" \
  -d '{"action": "add", "username": "caboronli"}'

Response:

{ "ok": true, "kols": ["elonmusk", "VitalikButerin", "caboronli"] }

If already exists:

{ "ok": true, "message": "already exists", "kols": ["elonmusk", "VitalikButerin", "caboronli"] }

Remove a KOL:

curl -s -X POST http://localhost:3848/api/kols \
  -H "Content-Type: application/json" \
  -d '{"action": "remove", "username": "elonmusk"}'

Response:

{ "ok": true, "kols": ["VitalikButerin", "caboronli"] }

If username not found:

{ "ok": false, "error": "not found", "kols": ["VitalikButerin", "caboronli"] }

Username strings are trimmed and @ prefix is automatically stripped.

5. Health Check

curl -s http://localhost:3848/health

Response:

{ "ok": true, "clients": 2, "history": 150 }
  • clients: number of active SSE connections
  • history: number of events in memory

No authentication required.

6. Server-Sent Events (Live Stream)

curl -s -N http://localhost:3848/sse

Streams real-time news events as SSE. On connection, all historical events are sent first, then new events arrive in real-time. Heartbeat every 15 seconds.


Full Configuration Schema

jin10

FieldTypeDefaultValidationDescription
enabledbooleantrueEnable Jin10 flash news
pollIntervalMsnumber15000>= 5000Poll interval in milliseconds
onlyImportantbooleantrueOnly push important items

blockbeats

FieldTypeDefaultValidationDescription
enabledbooleantrueEnable BlockBeats
pollIntervalMsnumber30000>= 5000Poll interval
onlyImportantbooleantrueOnly push important items
langstring"cht"Language: cht (Trad. Chinese), en, cn (Simp. Chinese)

rssFeeds (array)

FieldTypeDefaultValidationDescription
enabledbooleantrueEnable this feed
namestringDisplay name
feedUrlstringmust start with http(s)://RSS/Atom feed URL
pollIntervalMsnumber300000>= 5000Poll interval
colornumberDiscord embed color as integer (e.g. 3447003 = #3498DB)

x6551

FieldTypeDefaultValidationDescription
enabledbooleantrueEnable X tweet monitoring
apiBasestring"https://ai.6551.io"must start with http(s)://API base URL
tokenstringAPI token from 6551.io/mcp
pollIntervalMsnumber3600000>= 5000Poll interval
kolSyncIntervalMsnumber300000KOL list refresh interval
kolsstring[][]Usernames to monitor (without @)

opennews

FieldTypeDefaultValidationDescription
enabledbooleanfalseEnable OpenNews AI news
pollIntervalMsnumber60000>= 5000Poll interval
minScorenumber700-100Minimum AI score to push
signalsstring[][]Filter: "long", "short", "neutral" (empty = all)
coinsstring[][]Filter by coin symbols, e.g. ["BTC","ETH"] (empty = all). OpenNews-only — other sources (Jin10, BlockBeats, RSS, Polymarket) cannot be coin-filtered.
engineTypesstring[][]Filter: "news", "listing", "onchain", "meme", "market" (empty = all). OpenNews-only.

polymarket

FieldTypeDefaultValidationDescription
enabledbooleantrueEnable Polymarket monitoring
pollIntervalMsnumber180000>= 5000Price check interval
marketRefreshMsnumber600000>= 60000Market list refresh interval
minChangePpnumber5Min percentage point change to alert
zThresholdnumber2.5> 0Z-Score anomaly threshold (0 = off)
volSpikeThresholdnumber2.0> 0Volume spike multiplier
minLiquiditynumber10000>= 0Min market liquidity in USD
rollingWindowMinutesnumber30Window for price change calculation
cooldownMsnumber900000>= 60000Min interval before re-alerting same market
tagIdsnumber[][]Only track these categories (empty = all)
excludeTagIdsnumber[][]Exclude these categories

Polymarket Tag IDs:

IDCategory
21Crypto
2Politics
120Finance
1401Tech
596Culture
100265Geopolitics
100639Sports

grok (AI Translation)

FieldTypeDefaultValidationDescription
apiKeystringAPI key for translation
modelstring"grok-4.1-fast"Model name (any OpenAI-compatible)
baseUrlstring"https://api.x.ai/v1"must start with http(s)://API endpoint

Supported models: grok-4.1-fast, gpt-4o-mini, gpt-4.1-mini, claude-sonnet-4-6, claude-haiku-4-5-20251001, gemini-2.0-flash, or any OpenAI-compatible model.

discord

FieldTypeDefaultDescription
webhookUrlstring""Discord webhook URL (simple mode)
botTokenstring""Discord bot token (advanced mode)
channelIdstring""Discord channel ID (required for bot mode)

Use either webhookUrl or botToken + channelId, not both.

telegram

FieldTypeDefaultDescription
enabledbooleanfalseEnable Telegram notifications
botTokenstring""Telegram bot token from @BotFather
chatIdstring""Target chat/group/channel ID

dashboard

FieldTypeDefaultValidationDescription
portnumber38481024-65535HTTP server port (restart required)
passwordstring""Access password (empty = no auth)

Common Workflows

Check what's currently running

curl -s http://localhost:3848/api/status | jq 'to_entries[] | select(.value.active) | .key'

Enable a source and verify

# Enable Jin10
curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"jin10": {"enabled": true, "pollIntervalMs": 15000}}'

# Verify it's active
curl -s http://localhost:3848/api/status | jq '.jin10'

Set up Discord + Telegram dual push

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{
    "discord": {"webhookUrl": "https://discord.com/api/webhooks/..."},
    "telegram": {"enabled": true, "botToken": "123456:ABC-DEF", "chatId": "-1001234567890"}
  }'

Add a new RSS feed (without losing existing ones)

IMPORTANT: rssFeeds is an array. POSTing it replaces the entire list. You must GET first, append, then POST back.

Step 1 — Get current feeds:

curl -s http://localhost:3848/api/config | jq '.rssFeeds'

Step 2 — POST the full array with the new feed appended:

# Example: existing feeds are BlockTempo and PTS News, adding CoinDesk
curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"rssFeeds": [
    {"enabled": true, "name": "BlockTempo", "feedUrl": "https://www.blocktempo.com/feed/", "pollIntervalMs": 300000, "color": 16746496},
    {"enabled": true, "name": "PTS News", "feedUrl": "https://news.pts.org.tw/xml/newsfeed.xml", "pollIntervalMs": 300000, "color": 3447003},
    {"enabled": true, "name": "CoinDesk", "feedUrl": "https://www.coindesk.com/arc/outboundfeeds/rss/?outputType=xml", "pollIntervalMs": 300000, "color": 2067276}
  ]}'

Same pattern applies when removing or editing an RSS feed — always send the complete updated array.

Remove an RSS feed

GET current list, remove the target, POST back the remaining array.

# Get current feeds, then POST without the one you want to remove
curl -s http://localhost:3848/api/config | jq '.rssFeeds'
# POST back the array minus the removed feed
curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"rssFeeds": [
    {"enabled": true, "name": "BlockTempo", "feedUrl": "https://www.blocktempo.com/feed/", "pollIntervalMs": 300000, "color": 16746496}
  ]}'

Add an item to any array field (general pattern)

When the user says "also add X", always follow GET → modify → POST:

# Step 1: GET current value
CURRENT=$(curl -s http://localhost:3848/api/config | jq '.polymarket.tagIds')
# Example result: [21, 120]

# Step 2: Append and POST back
# Adding Sports (100639) to existing [21, 120]
curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"polymarket": {"tagIds": [21, 120, 100639]}}'

Same pattern applies to opennews.signals, opennews.coins, opennews.engineTypes, polymarket.excludeTagIds.

Monitor high-impact crypto news only

curl -s -X POST http://localhost:3848/api/config \
  -H "Content-Type: application/json" \
  -d '{"opennews": {"enabled": true, "minScore": 80, "signals": ["long", "short"], "coins": ["BTC", "ETH", "SOL"], "engineTypes": ["news", "listing"]}}'

Track new KOL and verify

# Add
curl -s -X POST http://localhost:3848/api/kols \
  -H "Content-Type: application/json" \
  -d '{"action": "add", "username": "VitalikButerin"}'

# List all
curl -s -X POST http://localhost:3848/api/kols \
  -H "Content-Type: application/json" \
  -d '{"action": "list"}'

Important Rules

Array fields are REPLACED, never merged

The config deep-merge only merges plain objects. All array fields are completely replaced when you POST them. If the user wants to add an item to an existing list, you MUST GET the current config first, modify the array, then POST back.

Array fields that require GET-first when adding/removing items:

FieldExample "add" intent
rssFeeds"Add CoinDesk RSS" — GET current feeds, append, POST full array
polymarket.tagIds"Also track Sports" — GET current tagIds, append 100639, POST
polymarket.excludeTagIds"Also exclude Culture" — same pattern
opennews.signals"Also show long signals" — GET, append "long", POST
opennews.coins"Also track SOL" — GET, append "SOL", POST
opennews.engineTypes"Also include listings" — GET, append "listing", POST

Exception — KOLs have a safe endpoint: Use POST /api/kols with action: "add" or "remove". This does NOT require GET-first. Do NOT modify x6551.kols via POST /api/config — use the dedicated endpoint instead.

When the user says "set to" (replace entire list) instead of "add", you can POST directly without GET-first. Example: "I only want Crypto and Finance" → {"polymarket": {"tagIds": [21, 120]}} is fine.

Other rules

  1. Object sections support partial update. You can POST just {"jin10": {"enabled": false}} without affecting other jin10 fields or other sections.
  2. Sensitive fields are redacted in GET responses as "••••••". When POSTing, redacted values are automatically preserved (not overwritten).
  3. All changes are hot-reloaded — no restart needed, except dashboard.port.
  4. The x6551.token is shared between X tweet monitor and OpenNews.
  5. Get your 6551 API token at https://6551.io/mcp

Error Responses

HTTP StatusBodyCause
401{ "ok": false, "error": "Unauthorized" }Missing or wrong ?pw= password
400{ "ok": false, "errors": [...] }Validation failed (array of error strings)
400{ "ok": false, "error": "Invalid JSON" }Malformed request body
404{ "error": "Not found" }Unknown API route

Comments

Loading comments...