{
  "markdown": "# anylens\n\n**Any link, any lens.** Paste a URL — a conference talk, a product demo, a\ndense PDF, an article — and get it back as understanding shaped for who's\nasking, with every claim linked to the exact second or page it came from.\n\nAgents can read text. anylens lets them read everything else — and lets you\ncheck their work.\n\n```\nanalyze(url)  →  one cached Understanding  →  lens(source, \"student\")\n                                           →  lens(source, \"spec\")\n                                           →  lens(source, \"uiux\")   …\n```\n\n## Why not just ask a chatbot to summarize it?\n\nA summary is a dead end. You can't verify it, you can't get a different cut of\nit without paying for it again, it's blind to what was on screen, and no agent\ncan act on it. anylens fixes those four things:\n\n- **Verifiable** — every claim carries its timestamp or page. `stated` is never\n  blurred with `inferred`. Missing analysis is named, not hidden.\n- **Many readers, one extraction** — the expensive pass runs once and is cached\n  forever; a second lens is cheap and instant.\n- **Reads what was *shown*** — on-screen code, slides, UI states, demos, not\n  just the words. A silent ten-second screen recording still produces a full\n  analysis.\n- **Built for agents too** — the `spec` lens turns any source into\n  implementable requirements with acceptance criteria, over MCP.\n- **Knows how it was made** — for video, a production pass captures the music,\n  the sound design, the shot rhythm, the motion and typography, and turns it\n  into a recipe you (or a generator) can rebuild from. Content lenses let an\n  agent *know*; the `blueprint` lens lets it *make*.\n\n## Lenses\n\n| Lens | For | Gives you |\n|---|---|---|\n| `student` | learning without watching | layered explainer, concept map, flashcards |\n| `developer` | building from it | code shown on screen, decisions, implementation steps |\n| `uiux` | design study | screens, flows, interaction patterns |\n| `researcher` | citable notes | claims + evidence, every one anchored |\n| `teardown` | competitive analysis | features (shown vs claimed), flows, positioning |\n| `spec` | **coding agents** | requirements, acceptance criteria, ambiguities |\n| `blueprint` | remaking it | music, sound design, shot rhythm, motion, typography — as a production recipe |\n| `design` | \"make it look like this\" | measured colour tokens, spacing and type rhythm, components — as paste-ready CSS |\n| `ask` | one specific question | an anchored answer — or an honest \"the source doesn't answer this\" |\n| `raw` | agents, debugging | the Understanding Object itself — no LLM, no cost |\n\nLenses are single markdown files in `src/lenses/`. Adding one is adding a\nfile — no code.\n\nBeyond lenses: anylens can learn a reusable **style** from analyzed videos —\nthe pacing, structure, look, motion, and sound as portable rules, every rule\ncarrying the timestamp it was learned from — then plan new work in that style\n(`style_extract` / `style_apply` over MCP, or \"Learn this style\" in the web UI).\n\n## Quickstart\n\n**Prerequisites**: [Bun](https://bun.sh) 1.3+, `yt-dlp`, and `ffmpeg`\n(`brew install yt-dlp ffmpeg` on macOS).\n\n```sh\ngit clone https://github.com/Slowper/anylens && cd anylens\nbun install\n```\n\n**Keys** — run `bun run web` and paste them on the **Your keys** page (they're\nvalidated as you save), or create `~/.anylens/env` (mode 600) yourself:\n\n```\nGOOGLE_API_KEY=...      # required: analysis, structuring, lens rendering\nGROQ_API_KEY=...        # optional: Whisper transcripts for sources without captions\nANTHROPIC_API_KEY=...   # optional: run the writing on Claude instead\nOPENAI_API_KEY=...      # optional: run the writing on an OpenAI model instead\n```\n\nGet them at [aistudio.google.com](https://aistudio.google.com/apikey) and\n[console.groq.com](https://console.groq.com/keys). Nothing leaves your machine\nexcept the calls you make to those APIs. The text layer is provider-agnostic:\nset `ANYLENS_TEXT_MODEL=anthropic` (or `groq`, or `openai/<model>`) to choose\nwho writes the lenses and answers — the media passes stay on Gemini, which is\nwhat it's genuinely best at.\n\n**Try it** — from the terminal:\n\n```sh\nbun bin/anylens.ts \"https://www.youtube.com/watch?v=...\"              # student explainer\nbun bin/anylens.ts ./screenshot.png --lens design --export css        # tokens you can paste\nbun bin/anylens.ts ~/Desktop/demo.mov --lens blueprint                # files on your machine work too\nbun bin/anylens.ts \"<url>\" --lens spec                                # any lens\nbun bin/anylens.ts \"<url>\" --ask \"does this cover error handling?\"    # one anchored answer\nbun bin/anylens.ts \"<url>\" --clip \"where they demo the CLI\"           # cut that segment to mp4\nbun bin/anylens.ts \"<url>\" --export anki                              # flashcard deck (or markdown/json/html)\nbun bin/anylens.ts \"<url>\" --audio                                    # narrate it to an mp3\nbun bin/anylens.ts \"<url>\" --open                                     # render the page and open it\n```\n\nAnalysis takes a few minutes the first time and is cached forever after, so\nevery later lens on the same link returns instantly. Pass a `source_id`\ninstead of a URL to re-lens something already analyzed.\n\nOr use the web UI:\n\n```sh\nbun run web        # → http://127.0.0.1:4517 — paste a link, pick a lens\n```\n\n## Use it from an agent — any MCP client\n\nanylens speaks standard MCP over stdio, so Claude Code, Codex, Cursor, Gemini\nCLI, and anything else MCP-capable can use it the same way.\n\n```sh\n# Claude Code\nclaude mcp add --scope user anylens -- bun /absolute/path/to/anylens/bin/anylens.ts mcp\n```\n\n```toml\n# Codex CLI — ~/.codex/config.toml\n[mcp_servers.anylens]\ncommand = \"bun\"\nargs = [\"/absolute/path/to/anylens/bin/anylens.ts\", \"mcp\"]\n```\n\n```json\n// Gemini CLI (~/.gemini/settings.json), Cursor (~/.cursor/mcp.json), or any other client\n{ \"mcpServers\": { \"anylens\": { \"command\": \"bun\", \"args\": [\"/absolute/path/to/anylens/bin/anylens.ts\", \"mcp\"] } } }\n```\n\nOnce published to npm, `npx anylens mcp` replaces the path form everywhere.\n\nTools: `analyze(url)` → `status(job_id)` → `lens(source_id, lens)` ·\n`ask(source_id, question)` · `clip(source_id, query)` ·\n`export(source_id, format)` · `audio(source_id)` ·\n`style_extract` / `style_apply` / `style_list` · `lenses()`.\n`lens` returns `{ data, markdown }` —\ntyped JSON for the agent, readable markdown for the human, plus a full HTML\npage with `include_html`. `ask` answers from the cache without re-analyzing.\n\n## What it reads\n\nVideo (YouTube, X, LinkedIn, Vimeo, Twitch, Loom, direct files — anything\n`yt-dlp` reaches), audio, PDFs (including scanned and figure-heavy ones, read\npage by page with vision), web articles, and images.\n\nFull inventory: [docs/FEATURES.md](docs/FEATURES.md) ·\nWhere it's going: [docs/ROADMAP.md](docs/ROADMAP.md) ·\nArchitecture and invariants: [AI_INDEX.md](AI_INDEX.md)\n\n## Contributing\n\nNew lenses are the easiest and most valuable contribution — see\n[CONTRIBUTING.md](CONTRIBUTING.md). The codebase is deliberately small files\nwith one concern each, so a change rarely touches more than one place.\n\nMIT licensed.\n",
  "bytes": 7125,
  "sha": "adf3af9a869697c32931f52de79664b2d8439a174d2e964a1276302d839140f2",
  "repo_slug": "slowper/anylens",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_slowper_anylens_c4e23a73/readme"
}