Skip to main content
Glama

MEME — Internet Culture Agent

MEME is an always-online internet comedian for developers: it discovers what the dev world is actually talking about right now — through authorized APIs — and turns it into original, well-crafted memes you'll want to share.

MEME runs as an MCP (Model Context Protocol) server over stdio, built on the official modelcontextprotocol/typescript-sdk (vendored at tag v2.4.0 — see vendor/ and docs/SDK_AUDIT.md).

npm install && npm run demo          # full pipeline, zero credentials
npm run serve                        # MCP stdio server (Claude/any MCP client)

MEME never claims a meme is objectively funny or guaranteed to go viral. Quality scores are heuristic aids with honest confidence bounds, and source freshness is reported truthfully (live / cached / stale) — never "real-time" when it isn't.

What it does

  1. Discovers trends from authorized sources: GitHub (REST search), Hacker News (Algolia front page), and a deterministic offline demo source. Reddit is implemented but hard-gated pending a dedicated legal & policy review; X/Twitter is unavailable (no API access in this build). See the Platform Compliance Registry.

  2. Ranks trends intelligently — not by raw popularity, but by velocity, acceleration, engagement quality, recency, developer relevance, cross-platform signals, source diversity, and discussion authenticity. Every score ships with a transparent per-factor explanation and a confidence value.

  3. Generates original meme concepts with an LLM (deterministic offline "mockbrain" in demo mode; any OpenAI-compatible API in live mode), personalized to your humor style, languages, favorite formats and content exclusions. External content is framed as untrusted data (prompt-injection defense), and every string passes moderation.

  4. Renders memes as original vector compositions (6 formats, editable templates, overflow-safe captions) → SVG + PNG (via sharp, when available).

  5. Evaluates quality across 7 dimensions (technical accuracy, contextual relevance, originality, humor proxy, caption readability, visual composition, audience relevance) with a benchmark dataset and regression tests, plus optional 1–5 star human ratings.

  6. Manages cost — provider-independent price book, token/call accounting, cache-efficiency stats, per-user daily quotas, workspace budgets, atomic reservations, and graceful fallback to the free provider when a budget is exhausted.

  7. Survives failure — durable job queue (JSONL journal, idempotency keys, lease recovery), bounded concurrency, exponential backoff with full jitter, Retry-After awareness, circuit breakers, timeouts, cancellation, DLQ + replay.

  8. Observes itself — structured JSON logs (stderr, secrets auto-redacted), trace/span context propagation, latency/failure/moderation/cost metrics.

Related MCP server: memewright

Quickstart

git clone <this-repo> meme-agent && cd meme-agent
npm install            # installs the vendored MCP SDK from vendor/*.tgz
npm test               # 502 tests
npm run demo           # discover → rank → generate → evaluate → render → export

Output lands in .meme/output/local/ (SVG + PNG + a sidecar JSON with attribution and license).

Run as an MCP server (stdio)

npm run serve
# or after `npm run build`:
node dist/index.js serve

Then add to any MCP client config:

{
  "mcpServers": {
    "meme": { "command": "node", "args": ["/absolute/path/to/meme-agent/dist/index.js", "serve"] }
  }
}

Live mode (real GitHub + Hacker News)

MEME_MODE=live GITHUB_TOKEN=ghp_xxx npm run serve

Without OPENAI_API_KEY, live mode still works — the LLM gracefully falls back to the deterministic mock provider (with a logged notice).

The 27 MCP tools

Area

Tools

Trends

get_trends, get_trend

Creation

generate_meme (sync or durable-queue async), render_meme

Library

list_memes, get_meme, get_history, edit_meme, delete_meme, export_meme

Quality

evaluate_meme, rate_meme

Engagement

favorite_meme, list_favorites, submit_feedback, report_content

Personalization

get_preferences, set_preferences, list_templates, edit_template

Cost

get_cost_report, get_cost_report-all (admin)

Ops

get_health, get_metrics (admin), enforce_retention (admin), review_moderation_queue (admin), get_compliance (admin)

Authorization is enforced in application code (src/security/authz.ts): role allowlists, JSON-safe argument checks, and an injection screen on every tool argument — never by asking the LLM nicely.

Platform Compliance Registry

src/compliance/registry.ts is the versioned source of truth. Highlights:

Provider

Status

Key constraints

GitHub

active

official REST API; conditional requests; content retention 7 days; training on fetched content prohibited; attribution required

Hacker News

active

public Algolia API; same content rules

Reddit

gated

requires a completed legal & policy review (signed override file) and REDDIT_ENABLED=1; user content must not be passed to external AI providers or transformed before that review; no storage; deletion on request; commercial use prohibited

X/Twitter

unavailable

no authorized API access in v0.1.0 — disabled, never simulated

OpenAI-compatible LLM

active

only receives pre-sanitized, injection-screened context blocks; zero retention expectation documented

Publicly accessible content is not assumed to be freely processable, transformable, storable or redistributable. No training on third-party content, ever.

Security model (summary)

  • Prompt injection: obfuscation-resistant scanner (NFKC + zero-width/Bidi stripping); external text framed in unclosable <external-content> DATA blocks with an explicit preamble; hostile content in tool arguments is hard-blocked; hostile trend content is framed + flagged (a trend about prompt injection is legitimate meme material).

  • SSRF: all outbound traffic flows through GuardedNetworkClient — dot-boundary host allowlist, private/reserved/mapped IP rejection (including 169.254.169.254 cloud metadata), IP-literal and hex/octal/decimal host rejection, manual redirects re-validated per hop, size caps, timeouts. Known residual: DNS-rebinding race (documented in SECURITY.md, mitigation on the roadmap).

  • Media: magic-byte validation, SVG script/handler/javascript:/bomb screening before any processing.

  • Tenancy: store-level authz boundary; cross-tenant access throws (AUTHZ_DENIED), path-traversal-safe names.

  • Secrets: env-only, never persisted, auto-redacted in logs (key patterns and value shapes: ghp_…, sk-…, Bearer …, JWTs).

See SECURITY.md for the full model and residual risks.

Cost controls

Defaults (env-overridable): user $1/day, workspace $20/month, global $50/day, onExhaustion=fallback (falls back to the free deterministic provider). Reservations are atomic — 20 concurrent requests against a $1 budget admit exactly 15 × $1/15 (regression-tested). get_cost_report shows spend, per-provider breakdown and cache hit-rate.

Definition of Done — v0.1.0 (all proven by tests/dod.test.ts)

  • Fresh install runs locally with zero manual configuration

  • Launches the MCP stdio server (real child process, real pipe)

  • Connects to at least one functioning authorized live source (real api.github.com test via MEME_LIVE_GITHUB=1; a real-socket local HTTP test always runs)

  • Discovers and ranks trends (transparent explanations + confidence)

  • Generates context-aware meme concepts

  • Renders images (SVG always; PNG via sharp when available)

  • Executes moderation on every visible string

  • Previews (inline PNG) and edits results

  • Exports a completed meme (image + sidecar with attribution/license)

  • stdout stays protocol-clean (asserted line-by-line)

  • Demo mode: deterministic trends + mock providers, no credentials needed

Spec-mandated test areas → suites:

Spec area

Where proven

authentication boundaries

src/security/authz.test.ts, tests/security-e2e.test.ts

tenant isolation

src/core/core.test.ts, tests/security-e2e.test.ts

content retention

src/retention/retention.test.ts, tests/audit-regressions.test.ts

moderation decisions

src/moderation/moderator.test.ts, e2e blocks

prompt-injection defenses

src/security/injection.test.ts (17-attack corpus), tests/security-e2e.test.ts

provider failures

src/providers/*, tests/live-source.test.ts (failure isolation)

rate-limit handling

src/queue/worker.test.ts (Retry-After), src/trends/sources/* (403/429)

job retries

src/queue/durable.test.ts, worker.test.ts (backoff, DLQ, lease recovery)

Configuration

All via environment (see .env.example): MEME_MODE (demo|live), MEME_HOME, GITHUB_TOKEN, OPENAI_API_KEY, OPENAI_MODEL, MEME_LLM_PROVIDER, MEME_IMAGE_PROVIDER, MEME_LOG_LEVEL, budget vars (MEME_BUDGET_*), retention vars (MEME_RETENTION_*), REDDIT_ENABLED (+ signed compliance-overrides.json).

Repository layout

src/core/         foundation: config+flags, store (authz boundary), logger,
                  metrics, tracer, clock/rng injection, shared ports
src/trends/       sources (github/hackernews/reddit-gated/demo), dedupe,
                  ranking engine, HTTP cache
src/personalization/  user humor profiles
src/security/     injection screen, SSRF guard, authz
src/compliance/   versioned Platform Compliance Registry
src/moderation/   rule-based moderator + pipeline gate
src/retention/    retention enforcer + user-data deletion
src/queue/        durable queue, worker (backoff/breaker/DLQ)
src/cost/         price book, tracker, budget manager
src/memes/        formats, templates, captions, mockbrain, generator,
                  renderer, library (history/favorites/feedback/reports/export)
src/quality/      rubric, evaluator, benchmark
src/providers/    LLM providers (mock + OpenAI-compatible) + router
src/server/       composition root, pipeline, 27 MCP tools
tests/            e2e (InMemory), DoD (stdio), live-source, security, audit
vendor/           the MCP SDK tarballs this project is built on
benchmark/        meme-quality benchmark dataset (18 items)
docs/SDK_AUDIT.md upstream audit with evidence
FINDINGS.md       engineering audit: demonstrated bugs + fixes (one commit each)
ROADMAP.md        implemented / experimental / planned / unavailable

Honest limitations

  • Trend "velocity/acceleration" in demo mode are synthetic by design.

  • The humor "score" is a structural proxy — MEME will never tell you a meme is objectively funny.

  • Moderation seed lists are placeholder-grade; extend extraTerms per deployment.

  • Single-process storage (JSON files + JSONL journal); multi-node queues and remote MCP auth are roadmap items.

License

MIT. Meme compositions are original vector art (CC0-style dedication for generated output — see the export sidecar); quoted trend headlines are attributed per-source in every export.

Available Tools

27 tools
delete_memeDelete a memeB

Deletes a meme you own (admins may delete any).

Inputs: memeId (required).

edit_memeEdit meme texts and re-renderB

Edits the caption texts of a rendered meme and re-renders it. Texts are validated against format slots and re-moderated. The previous version is kept in the revision history.

Inputs: texts (required), memeId (required), title.

edit_templateEdit a templateB

Edit a template's name, palette (hex colors) or default texts. Built-in templates cannot be deleted but can be customized.

Inputs: templateId (required), name, palette, defaults.

enforce_retentionEnforce retention (admin)C

Runs the retention enforcer: deletes expired history/feedback/reports/raw signals per policy.

Inputs: tenants.

evaluate_memeEvaluate meme qualityB

Runs the Meme Quality Evaluation System on a meme: technical accuracy, contextual relevance, originality, humor (heuristic proxy), caption readability, visual composition, audience relevance — merged with any human ratings. Heuristic evaluation aid. NOT a claim that a meme is objectively funny or guaranteed to go viral.

Inputs: memeId (required).

export_memeExport a memeB

Exports a meme as SVG or PNG plus a sidecar JSON (concept, sources, attribution, license, disclaimer).

Inputs: memeId (required), format.

favorite_memeFavorite a memeC

Adds (or updates the note on) a favorite.

Inputs: memeId (required), note.

generate_memeGenerate meme concepts for a trendA

Generates original meme concepts for a trend, personalized to the user's humor style, languages and exclusions. Runs moderation on every string and attaches a provisional quality report (heuristic aid — never a guarantee of humor or virality). Pass async=true to enqueue a durable background job instead of waiting.

Inputs: trendId (required), async, count.

get_compliancePlatform Compliance Registry (admin)B

The versioned compliance registry: per-provider permitted operations, auth, rate limits, content-processing permissions, attribution, retention, deletion obligations, commercial-use limits — and the Reddit legal-review gate status.

Inputs: no named parameters.

get_cost_reportYour cost reportC

Your token usage, estimated costs, cache efficiency and remaining budget.

Inputs: no named parameters.

get_cost_report-allWorkspace cost report (admin)B

Cost report across all users in this workspace, with budget posture.

Inputs: no named parameters.

get_healthHealth & freshness checkA

Operational status: enabled sources with honest freshness (live / cached / stale — MEME never claims real-time coverage it cannot guarantee), feature flags, queue depth, moderation stats and configuration notices.

Inputs: no named parameters.

get_historyYour generation historyB

Your own rendered memes, newest first.

Inputs: limit.

get_memeGet a memeC

Full meme record: concept, texts, quality, sources, attribution.

Inputs: memeId (required).

get_metricsMetrics (admin)C

Counters and histograms: tool latency, generation latency, API failures, moderation decisions, cost.

Inputs: no named parameters.

get_preferencesGet your preferencesC

Your humor styles, languages, categories, formats, caption tone and exclusions.

Inputs: no named parameters.

get_trendGet trend contextB

Full context for one trend: signals, cultural references, developer relevance analysis, and the sanitized context block used for generation.

Inputs: trendId (required).

list_favoritesList favoritesA

Lists your favorite memes with notes, newest first (tenant-scoped).

Inputs: no named parameters.

list_memesList rendered memesB

Lists rendered memes (newest first), optionally filtered by user.

Inputs: limit, userId.

list_templatesList meme templatesB

Editable meme templates (built-ins + custom).

Inputs: no named parameters.

rate_memeRate a meme (human rating)B

Submit a 1–5 star human rating. Ratings are subjective opinions; they complement, never define, the heuristic scores.

Inputs: memeId (required), rating (required).

render_memeRender a concept into a meme imageA

Renders a generated concept into an original vector meme (SVG, plus PNG when sharp is available). Every text is moderated again before rendering. Returns the meme id, file paths, and an inline PNG preview.

Inputs: conceptId (required), title, templateId.

report_contentReport a memeB

Report a meme for review. Reasons: offensive, inaccurate, copyright, spam, other. Reports are always filed; hostile details are redacted by moderation.

Inputs: memeId (required), reason (required), details.

review_moderation_queueReview moderation queue (admin)C

Open content reports and moderation statistics.

Inputs: no named parameters.

set_preferencesSet your preferencesC

Updates personalization. All fields optional; omitted fields keep their current values.

Inputs: formats, languages, categories, exclusions, +3 more.

submit_feedbackSubmit feedbackC

Thumbs up / down feedback with optional note. Feeds the quality dataset.

Inputs: memeId (required), rating (required), note.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.8/5.0

    Scored across 27 tools

    Disambiguation3/5

    Most tools target distinct resource+action pairs (get_trend vs get_trends, evaluate_meme vs rate_meme vs render_meme), but list_memes and get_history describe nearly the same thing ('your rendered memes, newest first'), and get_cost_report vs get_cost_report-all differ only by scope. An agent must guess which of the duplicate pairs to call.

    Naming Consistency4/5

    A clear verb_noun snake_case convention dominates (get_meme, render_meme, edit_template, report_content). Minor deviations: get_cost_report-all uses a hyphen instead of a scope parameter, and get_history reads like a synonym for list_memes rather than a distinct resource.

    Tool Count2/5

    27 tools exceeds a reasonable scope for a meme generation server, with the surface inflated by ops/admin concerns (get_metrics, enforce_retention, get_compliance, two cost reports, get_health). Several of these could be collapsed into fewer tools or a single status endpoint.

    Completeness3/5

    Meme lifecycle is well covered (generate, render, list, get, edit, delete, export, evaluate, rate, report, favorite), but favorites have no unfavorite/remove operation, templates support list+edit but no create or delete for custom templates, and history has no delete for individual entries.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      A Model Context Protocol server for managing, searching, and retrieving local meme images. It automatically hosts memes via a built-in HTTP server to ensure images can be displayed within chat applications.
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to create memes by selecting from a library of templates and rendering captions with proper typesetting.
      AGPL 3.0
    • A
      license
      Not graded
      quality
      C
      maintenance
      Provides hosted trend data MCP server for querying Google, TikTok, Amazon, Reddit, YouTube, Steam, npm and 30+ trend sources in natural language from any MCP-compatible AI.
      MIT