Repository navigation
v2.2.0
YouTube reads keep yt-dlp first and gain a keyed Data API fallback with a route record on every
item; Reddit arrives on its official Data API; cited reports from a local model get a code check
on every citation; and scope filters can write a recomputable ledger of what they dropped.
- Add
gather reddit: subreddit listings and post threads through Reddit's official Data API, with your own app's id and secret fromREDDIT_CLIENT_IDandREDDIT_CLIENT_SECRET. Application-only OAuth, read-only, at most one request per second, and a wait for the window reset when Reddit says none remain. The contract (environment names, User-Agent form, sorts, limits, fields) matches the Telos reach reader. Items carry agather.route/1record. On MCP aredditjob needs the network grant and credential grants bound towww.reddit.com. - Add
gather.http_call: one request returning status, body and headers through the same host and redirect guards ashttp_get, for APIs that report rate limits in headers. - Add
gather report: a short cited report from a question and fixed excerpts, written by a model served on your own machine (loopback endpoints only), with every citation checked in code against the excerpt it names. The report item issynthesizedwithderived_fromset to the excerpt hashes; the check result rides inmeta.citation_check. Addgather cite-checkto run the check alone on any report text. - Add filter ledgers:
--ledger DIRon every intake command, and"ledger"in a command-linegather runconfig, writeledger.json(one row per dropped item with its reason code, counts by reason, the input digest) andinput.jsonl.gather ledger verify DIRrecomputes every count from the two files and reruns the scope filter. - YouTube reads keep yt-dlp as the primary path and gain a fallback: when yt-dlp is throttled or failing and you set your own key in
GATHER_YOUTUBE_API_KEY, the video's metadata comes from the official Data API v3. A reason about the video itself (private, removed, geo-blocked) never triggers it. The key travels only in a request header.--no-api-fallbackturns it off; run configs opt in withapi_key_env. - Every YouTube item carries a
gather.route/1record inmeta.routeand in its catalog row: the path that served it, whether a credential was used, the wall seconds, requests and bytes of the serving calls, and the rates. - Add
gather video-probe: a throttle check that reads three fixed public videos through yt-dlp at a single user's pace and reports seconds per call, calls per minute, caption bytes per second and a verdict. - Vendor only the modules the client server can import: 28 files instead of the whole package's 77.
scripts/client_closure.pyfollows every import fromserve.py, including imports inside functions and relative imports, and the source ZIP and the drift check use the same selection. The client now takesgather.docsfrom the newgather.docs_toolmodule, and the run-config and pilot-manifest grant checks move togather.grant_checks, so the plugin carries no code that namesGATHER_API_TOKEN. The full server behaves as before. - Commit the client server code inside the plugin folder at
client-plugin/server/src/, so a plugin installed from the folder alone starts.python scripts/build_client_package.py --sync-vendoredrewrites it fromsrc/, and a test fails when the two drift. The launcher no longer falls back to the repository'ssrc/; a missing copy stops with a one-line message. - The skill now says that
gather.fetchreads allowed origins, matching what the plugin offers. - Give the Claude plugin its directory listing: display name, keywords, homepage, documentation, support, privacy and terms links, and a 1024 px icon.
- Claude Code now asks for the readable workspace and the two optional origin lists when you enable the plugin. The Claude
.mcp.jsonpasses them as${user_config.*}launch arguments with the same defaults as the MCPB, so[]still grants no network access. Portable and Codex manifests keep their placeholders. - Document every network destination of the client profile in its README and privacy notes: DNS lookups and GET requests to the origins you grant, and nothing else.
- Add a "What this plugin runs and handles" section to the client README and privacy notes: hooks, the exact launch command, network destinations and headers, files written, and every environment variable read. A test runs a served session and fails if it reads an environment variable the section does not name.