
Research
/Security News
Malicious Chrome and Firefox Extensions Steal Crypto Traders’ Session and Wallet Data
Malicious Chrome and Firefox extensions target Axiom Trade and Padre users, stealing session tokens and wallet data.
Centralized beta tester update system — automated weekly emails with per-product voice powered by LLM drafts
Automated weekly email updates for beta testers, with per-product voice powered by LLM-drafted content.
Website: cryyer.dev GitHub: atriumn/cryyer Issues: Report a bug
Cryyer follows a two-stage pipeline:
npm install -g cryyer # or: npx cryyer
Run the interactive setup to create a product config and scaffold your .env:
npx cryyer init
This walks you through product name, GitHub repo, email subject template, and voice/tone — then writes a products/*.yaml file and optionally creates .env from .env.example.
You can also create products/*.yaml files manually — see Product Configuration for all fields.
Fill in your .env (or copy .env.example if you didn't scaffold it above):
cp .env.example .env
At minimum you need:
GITHUB_TOKEN=ghp_...
RESEND_API_KEY=re_...
FROM_EMAIL=updates@yourdomain.com
LLM_PROVIDER=anthropic # or openai, gemini
ANTHROPIC_API_KEY=sk-ant-... # key for your chosen provider
See .env.example for all variables and their descriptions.
Choose a subscriber store — the simplest for local dev is JSON:
export SUBSCRIBER_STORE=json
Create subscribers.json (see subscribers.example.json):
[
{ "email": "alice@example.com", "name": "Alice", "productIds": ["my-app"] },
{ "email": "bob@example.com", "productIds": ["my-app"] }
]
npx cryyer check
This verifies your product configs, GitHub token, LLM provider API key, subscriber store, and email (Resend) configuration — and reports what's missing or misconfigured.
Preview your first draft without sending:
npx cryyer run --dry-run
When you're ready to run for real:
npx cryyer run # full pipeline: gather → draft → send
Or run the two stages separately:
npx cryyer draft # generate drafts → create GitHub issues
npx cryyer send # send emails when a draft issue is closed
Set SUBSCRIBER_STORE to choose your backend. Default is supabase.
SUBSCRIBER_STORE=json
| Variable | Default | Description |
|---|---|---|
SUBSCRIBERS_JSON_PATH | ./subscribers.json | Path to subscriber data |
EMAIL_LOG_JSON_PATH | ./email-log.json | Path to email send log |
File format — array of objects with email, optional name, and productIds:
[
{ "email": "alice@example.com", "name": "Alice", "productIds": ["my-app", "other-app"] }
]
SUBSCRIBER_STORE=supabase # or just don't set it
| Variable | Description |
|---|---|
SUPABASE_URL | Your Supabase project URL (https://[project-id].supabase.co) |
SUPABASE_SERVICE_KEY | Supabase service role key |
Expects a beta_testers table with columns: email, name, product, unsubscribed_at.
SUBSCRIBER_STORE=google-sheets
| Variable | Description |
|---|---|
GOOGLE_SHEETS_SPREADSHEET_ID | The ID from your spreadsheet URL |
GOOGLE_SERVICE_ACCOUNT_EMAIL | Service account email |
GOOGLE_PRIVATE_KEY | Service account private key (PEM format) |
Cryyer looks for a sheet tab named after the product ID (e.g. my-app), falling back to the first sheet. Expected columns: email, name (optional), unsubscribed (optional, set to true to exclude).
Email send logging is a no-op with this backend (read-only).
cryyer-sheets-reader) and click DoneFrom the downloaded JSON file, grab client_email and private_key:
GOOGLE_SERVICE_ACCOUNT_EMAIL=cryyer-sheets-reader@your-project.iam.gserviceaccount.com
GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----\n"
From the spreadsheet URL:
https://docs.google.com/spreadsheets/d/SPREADSHEET_ID_HERE/edit
^^^^^^^^^^^^^^^^^^^^
GOOGLE_SHEETS_SPREADSHEET_ID=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms
Share the spreadsheet with your service account email (from step 4) as an Editor (required for add/remove subscriber support; Viewer is sufficient for read-only use).
Row 1 should have these headers:
| name | unsubscribed | |
|---|---|---|
| alice@example.com | Alice | |
| bob@example.com | Bob | |
| charlie@example.com | true |
Name the sheet tab after your product ID (e.g. my-app), or just use the default first sheet if you have one product.
Set LLM_PROVIDER to choose your LLM backend. Default is anthropic.
| Variable | Default | Description |
|---|---|---|
LLM_PROVIDER | anthropic | anthropic, openai, or gemini |
LLM_MODEL | Per-provider default | Override the default model |
ANTHROPIC_API_KEY | — | Required when LLM_PROVIDER=anthropic |
OPENAI_API_KEY | — | Required when LLM_PROVIDER=openai |
GEMINI_API_KEY | — | Required when LLM_PROVIDER=gemini |
Default models: Anthropic claude-sonnet-4-5-20250514, OpenAI gpt-4o, Gemini gemini-1.5-flash.
Products are defined as YAML files in products/. Each file represents one product.
| Field | Required | Description |
|---|---|---|
id | Yes | Unique identifier, also used as GitHub issue label |
name | Yes | Display name |
voice | Yes | LLM voice/tone instructions (injected into the draft prompt) |
repo | Yes | owner/repo for GitHub activity gathering |
emailSubjectTemplate | Yes | Subject line template — use {{weekOf}} for the date |
tagline | No | Product tagline |
from_name | No | Override sender name for this product |
from_email | No | Override sender email for this product |
reply_to | No | Reply-to address |
weekly-draft.ymlRuns every Monday at 1pm UTC. Gathers GitHub activity and creates draft issues.
Secrets needed: GITHUB_TOKEN, CRYYER_REPO, and the API key for your chosen LLM_PROVIDER.
send-update.ymlFires when an issue with the draft label is closed. Sends emails to subscribers.
Secrets needed: GITHUB_TOKEN, RESEND_API_KEY, FROM_EMAIL, plus the secrets for your chosen SUBSCRIBER_STORE.
ci.ymlRuns on push/PR to main. Lints, typechecks, and runs tests.
Cryyer includes an MCP server that lets you review, edit, and send drafts conversationally from any MCP client. It also supports subscriber management.
The MCP server uses stdio transport and is available as a separate binary: cryyer-mcp.
npx cryyer-mcp
Or if installed locally:
pnpm run build # compiles dist/mcp.js
node dist/mcp.js
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"cryyer": {
"command": "npx",
"args": ["cryyer-mcp"],
"env": {
"GITHUB_TOKEN": "ghp_...",
"CRYYER_REPO": "owner/repo",
"CRYYER_ROOT": "/path/to/cryyer",
"RESEND_API_KEY": "re_...",
"FROM_EMAIL": "updates@example.com",
"SUBSCRIBER_STORE": "json",
"LLM_PROVIDER": "anthropic",
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}
Any MCP client that supports stdio transport can use Cryyer. The generic config is:
npx cryyer-mcp (or node /path/to/cryyer/dist/mcp.js)Only GITHUB_TOKEN and CRYYER_REPO are needed for read-only tools (list_drafts, get_draft). Other env vars are needed for sending, regenerating, and subscriber management.
Test the server interactively with the MCP Inspector:
npx @modelcontextprotocol/inspector node dist/mcp.js
All log output goes to stderr (stdout is reserved for JSON-RPC). If something isn't working, check stderr for error messages.
| Tool | Description |
|---|---|
list_drafts | List open draft issues |
get_draft | Get full draft content with subscriber count |
update_draft | Save revised subject + body |
send_draft | Send emails, close issue, post stats |
regenerate_draft | Re-gather activity + re-draft via LLM |
list_products | Show configured products |
list_subscribers | Show subscribers for a product |
add_subscriber | Add a subscriber to a product |
remove_subscriber | Unsubscribe someone from a product |
Use the review_weekly_drafts prompt for the Monday morning review workflow — it walks through each pending draft and asks whether to send, edit, regenerate, or skip.
pnpm install # install dependencies
pnpm run build # compile TypeScript
pnpm run init # interactive product setup + .env scaffolding
pnpm run check # validate config, tokens, and connections
pnpm run typecheck # type-check without emitting
pnpm run lint # ESLint
pnpm test # run tests (vitest)
pnpm run test:watch # run tests in watch mode
pnpm run dev # build + run
pnpm run mcp # run MCP server
FAQs
Centralized beta tester update system — automated weekly emails with per-product voice powered by LLM drafts
The npm package cryyer receives a total of 0 weekly downloads. As such, cryyer popularity was classified as not popular.
We found that cryyer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Malicious Chrome and Firefox extensions target Axiom Trade and Padre users, stealing session tokens and wallet data.

Security News
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.

Product
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.