MEME
by renniyy
README.md
<div align="center">
<img src="brand/exports/meme-logo-primary-dark.png" width="480" alt="MEME — the Internet Culture Agent" />
# MEME
**The Internet Culture Agent — trending dev discourse in, genuinely funny memes out.**
[](https://www.npmjs.com/package/meme-agent)
[](LICENSE)
[](package.json)
[](tsconfig.json)
[](#-testing)
[](CHANGELOG.md)
An MCP server that watches what the developer internet is actually talking
about — live from **Hacker News** and **GitHub**, no API keys required — ranks
it with a transparent multi-factor engine, and turns the discourse into
original, shareable memes: moderated, fact-checked, reproducible.
`demo mode works with zero credentials — clone and run it in 60 seconds ↓`
</div>
---
## 🎬 Product demonstration
Real session, real output (run it yourself after the Quick Start):
```text
$ meme demo
[1/6] Discovering & ranking trends (demo source, 2 snapshots for acceleration)…
#1 Team ships Friday 5pm deploy because the ticket said so
score 0.781 · confidence 90% · 1520 pts · 640 comments
#2 Junior developer asks what the build server does; build server retaliates
score 0.766 · confidence 90% · 760 pts · 340 comments
#3 AI pair programmer confidently suggests deleting the database
score 0.739 · confidence 90% · 2190 pts · 860 comments
[2/6] Generating meme concepts (mock LLM provider, seeded)…
✅ ships Friday — two buttons [two-buttons]
[buttonA] ship ships Friday right now
[buttonB] write one more test first
[bottom] the build was already running
quality 0.74 · Heuristic quality signals for iteration — not a judgment of humor…
[5/6] Editing demo: retitling a caption and re-rendering…
edited → meme-427403043f8b (v2)
[6/6] Exporting memes (SVG + manifest)…
meme-output/ships-friday-two-buttons-meme-6ed97c3cde5a.svg
sha256 88162574ced870389ae49988… · manifest ✔
```
An asciinema recording of this session ships at
[`docs/assets/demo.cast`](docs/assets/demo.cast) — `npx asciinema play docs/assets/demo.cast`.
| Generated memes (real renders) | Local gallery (real screenshot) |
| --- | --- |
|  |  |
More screenshots: [`docs/assets/screenshots/`](docs/assets/screenshots/)
## ✨ What MEME does
- **🔍 Intelligent trend discovery & ranking** — not raw popularity. Velocity,
acceleration, engagement quality, recency, developer relevance,
cross-platform signals, source diversity and discussion authenticity, each
with a weight, an explanation and a confidence score. If the data is
missing a factor, the confidence drops — visibly.
- **🌐 Live sources without keys** — Hacker News (public Firebase API) and
GitHub (public search API, `GITHUB_TOKEN` optional) via authorized APIs
only, with token-bucket rate limits, ETag conditional requests and 5-minute
efficient polling. Demo mode is fully deterministic for offline/CI use.
- **🧠 Context-aware meme concepts** — an LLM provider layer (deterministic
mock built in; OpenAI/Anthropic adapters included) that only sees external
text inside untrusted-content delimiters, and whose output is validated
against injection patterns before it can render.
- **🎨 Original vector memes** — six built-in templates drawn from scratch
(no copyrighted photo memes), CJK-aware text wrapping, Unicode-safe
rendering, PNG export via the optional `sharp` dependency.
- **🛡️ Moderation & factuality safeguards** — every concept passes a
rules-based moderation policy; version-like technical claims are checked
against the source text so the LLM can't invent a release for a joke.
- **📊 Meme Quality Evaluation** — technical accuracy, contextual relevance,
originality, humor *heuristics*, readability, composition and audience fit —
with a benchmark dataset and regression tests. Explicitly **never** claims a
meme is objectively funny or guaranteed to go viral.
- **💸 Cost management** — token/cost tracking, daily + per-generation
budgets, cache-efficiency metrics, graceful fallback to the free mock
provider when a budget is exhausted.
- **⚖️ Platform Compliance Registry** — a versioned, data-driven registry of
per-provider permissions, attribution and retention. **Reddit and X are
disabled** — Reddit user content requires a completed legal review before
any AI transfer, and no authorized X API is configured.
- **🔒 Security by construction** — outbound fetches only to allowlisted
provider domains (per-hop redirect validation, private-IP blocking, size
caps), credentials never accepted via tool arguments, credential redaction
in all logs, localhost-only gallery with Origin/Host validation.
- **🔁 Resilient background processing** — idempotent jobs, bounded
concurrency, exponential backoff with jitter, circuit breakers,
Retry-After-aware rate limiting, dead-letter queue, journal durability.
- **🧾 Reproducibility metadata** — every meme records provider, model,
prompt-template version, seed hint and asset hashes; demo mode is
byte-identical on regeneration.
- **🌍 i18n** — configurable generation language (en + zh-CN phrasebooks
today), script-aware typography, multilingual captions.
- **🧰 Developer UX** — history, favorites, ratings, content reporting with
deletion records, editable memes, SVG/PNG export with attribution
manifests, `meme doctor` readiness checks, accessible local gallery.
## ⏱️ Quick Start in 60 Seconds
```bash
git clone https://github.com/renniyy/meme.git # or your fork
cd meme
npm install
npm run build
npm run demo
```
That's the whole demo pipeline: **discover → rank → generate → moderate →
render → edit → export**, with deterministic mock providers and zero API
credentials. You'll find exported SVG memes + manifests in `./meme-output`.
Want **live trends** instead? Nothing to configure either (HN needs no key):
```bash
MEME_MODE=live npm run demo
```
## 📦 Installation
**From source (v0.1.0 release channel):**
```bash
git clone https://github.com/renniyy/meme.git && cd meme
npm install && npm run build
node dist/cli.js doctor # readiness check
```
**As a global CLI (after we publish — see docs/naming-review.md):**
```bash
npm install -g meme-agent
meme doctor
```
Requirements: Node.js ≥ 20. Optional: `GITHUB_TOKEN` (higher rate limits),
`OPENAI_API_KEY` or `ANTHROPIC_API_KEY` (real LLM concepts), `sharp` ships as
an optional dependency for PNG export (SVG works everywhere).
## 🔌 Using MEME with MCP clients (local stdio)
MEME is an MCP **stdio** server. Point any MCP client at the built CLI:
```json
{
"mcpServers": {
"meme": {
"command": "node",
"args": ["/absolute/path/to/meme/dist/cli.js", "serve"],
"env": {
"MEME_MODE": "auto",
"MEME_DATA_DIR": "/absolute/path/to/meme/.meme-data",
"GITHUB_TOKEN": "ghp_…optional…"
}
}
}
}
```
Then ask your client: *"use the meme server: discover trends and make a meme
about the top one"*. The tool catalogue (`meme_discover_trends`,
`meme_generate_meme`, `meme_preview_meme`, `meme_edit_meme`,
`meme_export_meme`, …) is documented in [docs/mcp.md](docs/mcp.md), including
the protocol-version compatibility matrix.
**Remote MCP + OAuth:** not implemented in v0.1.0 — see
[ROADMAP.md](ROADMAP.md) (`mcp-remote-auth`). We won't publish instructions
for a transport that doesn't exist yet; local stdio is fully supported today.
## 🏗️ Architecture
```mermaid
flowchart LR
subgraph Sources["Authorized sources"]
HN["Hacker News API"]
GH["GitHub Search API"]
DEMO["Demo source\n(deterministic, fictional)"]
end
subgraph Core["MEME core (Node.js ≥20)"]
REG["Compliance Registry\n(versioned, data-driven)"]
TS["Trend store\n(snapshots, retention, deletion records)"]
RANK["Ranking engine\n(8 factors + explanations + confidence)"]
LLM["Concept providers\nmock / OpenAI / Anthropic"]
MOD["Moderation +\nfactuality safeguards"]
REN["SVG renderer\n(original templates, CJK-aware)"]
QUAL["Quality evaluation\n+ benchmark"]
COST["Cost tracker\n+ budgets + fallback"]
Q["Job queue\n(backoff, breaker, DLQ)"]
end
subgraph Surface["Surfaces"]
MCP["MCP stdio server\n(tools + resources)"]
GAL["Local gallery\n(127.0.0.1, read-only)"]
CLI["CLI\nserve/demo/gallery/doctor/report"]
end
HN --> REG --> TS
GH --> REG
DEMO --> TS
TS --> RANK --> LLM --> MOD --> REN --> QUAL
LLM --> COST
Q --> LLM
MCP --> Core
CLI --> MCP
GAL --> TS
```
End-to-end workflow, from trend to shareable file:
```mermaid
sequenceDiagram
participant U as You (MCP client / CLI)
participant S as MEME server
participant P as Providers (HN/GitHub/LLM)
U->>S: meme_discover_trends
S->>P: guarded fetch (allowlist, rate limit, ETag)
S-->>U: ranked trends + explanations + confidence + freshness
U->>S: meme_generate_meme (trendId)
S->>S: concept (LLM) → injection validation → moderation → factuality
S->>S: render (original SVG template) → re-moderate → quality score
S-->>U: meme record + reproducibility metadata
U->>S: meme_preview_meme / meme_edit_meme
U->>S: meme_export_meme (svg|png)
S-->>U: file path + SHA-256 + attribution manifest
```
## 🌐 Supported provider matrix
| Provider | Live today | Auth | Compliance status | Notes |
| --- | --- | --- | --- | --- |
| **Hacker News** | ✅ | none | enabled | Titles/metadata only; links never followed; 24 h raw retention |
| **GitHub** | ✅ | optional token | enabled | Public repo search; ETag conditional requests |
| **Demo (built-in)** | ✅ | none | enabled | Fictional evergreen dev-culture trends, deterministic |
| Reddit | ❌ | OAuth (unimplemented) | **disabled — legal review required** | User content must not reach external AI providers before a recorded legal/policy review |
| X (Twitter) | ❌ | paid API (none) | disabled | No authorized access configured; will not be simulated |
| OpenAI | ✅ adapter | `OPENAI_API_KEY` | enabled | JSON-mode chat completions, untrusted-content delimiters |
| Anthropic | ✅ adapter | `ANTHROPIC_API_KEY` | enabled | Messages API |
| Mock (built-in) | ✅ | none | enabled | Deterministic; powers demo mode and CI |
The matrix mirrors `data/compliance-registry.json` — the registry is the
source of truth, and `meme_doctor` verifies it at runtime.
## ⚙️ Configuration (examples)
```bash
MEME_MODE=auto # demo | live | auto (live sources, demo fallback)
MEME_LLM_PROVIDER=auto # auto | mock | openai | anthropic
OPENAI_API_KEY=sk-… # or ANTHROPIC_API_KEY
OPENAI_MODEL=gpt-4o-mini # defaults are configurable
MEME_LANGUAGE=en # generation language (en, zh-CN, …)
MEME_MAX_DAILY_USD=5 # budget guard; exhausted → mock fallback
MEME_MAX_PER_GEN_USD=0.25 # per-generation cost cap
MEME_DATA_DIR=./.meme-data # workspace data (trends, profiles, memes)
MEME_EXPORT_DIR=./meme-output
MEME_SOURCE_RPM=30 # outbound rate limit per source
MEME_WORKSPACE=local # tenant isolation scope
```
Full reference: [docs/configuration.md](docs/configuration.md) · personalization
profiles: [docs/mcp.md](docs/mcp.md) · prices: `data/price-table.json`.
## 🔒 Security & privacy
- **Local-first**: stdio server, no network listener; the gallery binds
127.0.0.1 only and validates Origin/Host headers.
- **SSRF controls**: outbound requests are allowlist-only, with per-hop
redirect validation, private/loopback/link-local IP blocking, response size
caps and timeouts.
- **Prompt-injection defense**: external text is sanitized, length-capped and
wrapped in `<<<EXTERNAL_CONTENT …>>>` data-only delimiters; LLM output is
re-validated before rendering.
- **Secrets hygiene**: credentials only via environment/config — tool
arguments carrying secret-like keys are rejected; logs redact token
patterns (`ghp_…`, `sk-…`, `Bearer …`, `api_key=…`).
- **Retention & deletion**: provider TTLs enforced; deletion records contain
ids and reasons, never content.
- Details & threat model: [docs/security.md](docs/security.md) ·
vulnerability disclosure: [SECURITY.md](SECURITY.md)
## 🧪 Testing
150 automated tests across 17 files cover the areas the spec calls out:
```bash
npm test # full suite (vitest)
npm run typecheck # strict TypeScript, noEmit
```
| Area | Test file |
| --- | --- |
| Authentication boundaries (credentials via tool args) | `tests/mcp.test.ts`, `tests/security.test.ts` |
| Tenant isolation (workspaces) | `tests/retention.test.ts`, `tests/demo-e2e.test.ts` |
| Content retention & deletion records | `tests/retention.test.ts` |
| Moderation decisions | `tests/moderation.test.ts` |
| Prompt-injection defenses | `tests/security.test.ts`, `tests/mcp.test.ts` |
| Provider failures & rate limits | `tests/sources.test.ts`, `tests/queue.test.ts` |
| Job retries, backoff, circuit breaker, DLQ | `tests/queue.test.ts` |
| Trend ranking & explanations | `tests/ranking.test.ts` |
| Compliance registry incl. Reddit legal gate | `tests/compliance.test.ts` |
| Cost/budget fallback | `tests/cost.test.ts` |
| Factuality safeguards | `tests/factuality.test.ts` |
| Quality benchmark regression | `tests/quality-benchmark.test.ts` |
| Renderer (CJK, escaping, overflow) | `tests/render.test.ts` |
| Gallery (headers, origin, traversal) | `tests/gallery.test.ts` |
| Log redaction | `tests/logger.test.ts` |
| End-to-end demo pipeline (Definition of Done) | `tests/demo-e2e.test.ts`, `tests/mcp.test.ts` |
| v0.1.0 audit regressions (traversal, blocked derivatives, queue config) | `tests/audit-regressions.test.ts` |
| Brand palette & assets | `tests/brand.test.ts` |
## 🧭 Roadmap
Statuses are honest: **implemented** (shipped, tested), **experimental**
(behind flags), **planned** (design exists), **unavailable** (blocked).
See [ROADMAP.md](ROADMAP.md) for the full matrix — headline items: Reddit
adapter (blocked on legal review), X adapter (blocked on API access), remote
MCP + OAuth, hosted offering, human-rating review workflow, GIF/animated
memes.
## 🤝 Contributing
PRs welcome — read [CONTRIBUTING.md](CONTRIBUTING.md) first (commit style,
test requirements, brand-change policy). Security issues: [SECURITY.md](SECURITY.md), never public issues.
## 📄 License
[MIT](LICENSE) © MEME contributors. Brand assets are original works shipped
under the same license — see [brand/BRAND-GUIDELINES.md](brand/BRAND-GUIDELINES.md).
Built on the official [Model Context Protocol TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) (MIT) — see [docs/repo-selection.md](docs/repo-selection.md).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo recent community issues