
Auditreach
io.github.RudrenduPaul由 GitHub 账号 RudrenduPaul 发布v0.2.5更新于 Oct 24, 2026
BYOK Reddit/YouTube research CLI with a tamper-evident audit log and an MCP server.
概览
本地 MCP 服务器,让助手用自备密钥通过官方 API 检索 Reddit 和 YouTube,并写入防篡改审计日志。
- 可以做什么
- 通过官方 API 检索 Reddit 和 YouTube,可按子版块、频道、日期和结果数量筛选,返回结构化结果或写入 JSON 文件。检查某平台已保存的凭据是否有效,无需实际执行检索。校验本地哈希链审计日志,报告是否有条目被编辑、删除或重排。凭据的设置与清除刻意不开放为工具。
- 适用场景
- 适合需要基于官方 API 做 Reddit 或 YouTube 调研、并留下可验证查询记录与同意依据的场景,例如合规敏感的报告。不适合需要多平台广泛抓取,或不愿自行申请 API 凭据的用户。
- 运行要求
- 以 stdio 在本地运行,通过 npx 或 uvx 从 auditreach-cli 包启动(分别需要 Node.js 或 Python)。需先通过本地 CLI 配置自己的 Reddit script-app 凭据(客户端 ID、客户端密钥、用户名、密码)或 YouTube Data API 密钥;凭据保存在操作系统钥匙串中。需要访问平台 API 的网络,并受其速率限制和配额约束。
安装
在 SourceWeft 中
- 打开 控制台中的 Auditreach,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
auditreach
[CI] [npm version] [PyPI version] [License: Apache 2.0] [Node]
Install • What it does • Getting started • Commands • Security • FAQ
Research Reddit and YouTube from your AI agent using only official APIs, your own keys, and a log that proves exactly what you queried and why it was allowed.
Install
auditreach ships as two independent, equally first-class packages: an npm
package (this repo, JavaScript/TypeScript) and a
PyPI package (python/,
Python). Both implement the same hash-chain algorithm and BYOK model
against the same official Reddit/YouTube APIs. Pick whichever fits your
toolchain, or install both.
npm:
Or install it globally:
pip:
See python/README.md for Python-specific usage, including this distribution's added env-var BYOK credential path (useful for headless CI/agent sandboxes) -- the npm package stores credentials in the OS keychain only.
Building from source works the same way, if you want to read or modify the code first:
What it does
Every entry in auditreach.log.jsonl is hash-chained -- each entry's hash is computed from its own content, and the next entry references it. Editing, deleting, or reordering an entry breaks the chain:
How it compares
Numbers measured directly against each repo's public GitHub metadata and, for the dependency comparison, against snoowrap's own published package.json as of this writing -- reproducible by anyone with gh api repos/<owner>/<repo>.
We started building auditreach's Reddit client on top of snoowrap, the most-used Reddit API wrapper in the Node ecosystem. Installing it pulls in request, request-promise, form-data, and har-validator -- a dependency chain that currently carries 2 CRITICAL, 2 HIGH, and 5 moderate severity advisories (9 total, per npm audit), none of which snoowrap can fix because the project has been archived since 2023. We rewrote the Reddit client as a direct fetch-based OAuth2 client against Reddit's own documented REST endpoints instead: same functionality, none of those CVEs, zero extra runtime dependencies for that client. See Security for auditreach's own current npm audit status.
Why auditreach exists
A consultancy we talked to had an AI research agent pulling social sentiment for a client report. It worked well until the client's legal team asked, in writing, what authority the data collection was under. The honest answer was "a browser cookie session," because the tool they were using authenticates by importing a logged-in session and scraping as if it were a real user. That works. It is also not an answer you can put in a compliance memo, and it is the exact pattern Reddit sued Anthropic and SerpApi over in 2025, and the same pattern that got Pushshift's public API access shut down by Reddit back in 2024.
Agent-Reach is not a bad tool. It has real traction (65k+ stars) because cookie-based scraping genuinely covers more ground than any official API does today, at zero API cost. But "covers more ground" and "an agency's client can pass a compliance review" are two different bars, and nothing was built specifically to clear the second one.
auditreach is the CLI we wished existed instead. It talks to Reddit and YouTube only through their official, documented APIs, using your own API keys -- never a shared pool -- and every single query writes a hash-chained entry to a local audit log: which platform, which endpoint, which scope, and a plain-language line explaining the consent/ToS basis for that specific call. No cookie import. No session-token reuse. No code path that could even pretend to be a logged-in human.
We are not trying to out-cover Agent-Reach's six platforms. auditreach is narrower on purpose, for the buyer who structurally can't use a cookie-based tool at all.
Getting started
1. Install: see Install above -- npx auditreach-cli, npm install -g auditreach-cli, or clone and build from source.
2. Set up credentials for the platform you want to search (BYO-key -- your own, never ours):
All credentials are stored in your OS keychain (@napi-rs/keyring), never in a config file, never transmitted anywhere except the platform's own official auth endpoint. Once credentials are set, verify them without running a real search:
3. Search:
Honest note on setup time: getting your own API credentials from Reddit and Google takes a few minutes the first time -- this is slower than Agent-Reach's cookie-import flow (which just reuses a browser session you already have) by design. BYOK means the setup cost is real, not hidden.
Commands
auditreach has four subcommands. Every flag below is pulled directly from the CLI's own --help output, not from memory of what it used to support.
auditreach search
Search a platform using its official API only.
auditreach auth
Set up, verify, or clear BYOK credentials for a platform (stored in your OS keychain).
auditreach verify-log
Verify the local hash-chained audit log has not been tampered with.
auditreach mcp
Run a Model Context Protocol server over stdio (built on the official @modelcontextprotocol/sdk), exposing exactly 3 tools so an AI agent can call this CLI directly instead of shelling out and parsing stdout:
Add it to your MCP client's config (for Claude Desktop, claude_desktop_config.json). Either
distribution works since both ship the same mcp subcommand:
or, from the PyPI package:
Setting up or clearing BYOK credentials (auditreach auth --platform <p> / --clear) is deliberately not exposed over MCP -- that stays a local-CLI-only, human-driven action, so a calling agent can check whether credentials work but can never provision or wipe them itself. See .well-known/agent.json for the machine-readable manifest (auth requirements, tool schemas, invocation commands) that an agent or agent registry can read to discover this server without a human reading the README first.
Run auditreach <command> --help any time to see the exact flags your installed version supports.
Library API reference
auditreach-cli doubles as an importable library. Every export below comes straight from dist/index.d.ts in the published package.
Clients
new RedditClient(credentials: RedditCredentials)-- talks to Reddit's official OAuth API only, using the password grant ("script app" flow)..search(options: RedditSearchOptions): Promise<SearchOutcome>,.verifyCredentials(): Promise<void>.new YoutubeClient(credentials: YoutubeCredentials)-- wraps the official YouTube Data API v3..search(options: YoutubeSearchOptions): Promise<SearchOutcome>,.verifyCredentials(): Promise<void>(a 1-quota-unit call, no query needed).
Credentials (setCredential / getCredential / deleteCredential / getRedditCredentials / getYoutubeCredentials) -- all credential I/O goes through this module. It's the one place allowed to touch a raw secret; values come back only to hand directly to a client's constructor, never to log or print.
Audit log
appendAuditLogEntry(entryWithoutHash: UnhashedAuditLogEntry, logPath?: string): Promise<AuditLogEntry>-- the only write path into the log; entries are never edited or deleted in place.getLastEntryHash(logPath?: string): Promise<string | null>computeEntryHash(entry: UnhashedAuditLogEntry): stringverifyAuditLogChain(logPath?: string): Promise<ChainVerificationResult>-- re-derives every entry's hash and checks the chain end to end.DEFAULT_AUDIT_LOG_PATH--"./auditreach.log.jsonl"
Crypto utilities
canonicalJson(value: unknown): string-- recursively sorts object keys so the same logical entry always serializes to the same bytes, which the hash chain depends on to verify deterministically.sha256Hex(input: string): stringcredentialFingerprint(secret: string): string-- keeps only the last 6 hex characters of a scrypt-derived hash (emitted in the audit log asscrypt:<6 hex>), enough to distinguish rotated keys in a local audit log, never enough to be a partial credential leak.
Command cores and MCP
executeSearch(args),checkAuthStatus(platform),executeVerifyLog(path?)-- the same programmatic cores thesearch/auth --verify/verify-logCLI commands and the MCP tools both call into; none of them write to console/stdout, so they're safe to call from any host, including one sharing stdout with an MCP transport.SearchCommandError-- the error classexecuteSearchthrows for an expected, user-actionable failure: no BYOK credentials stored yet for the target platform, or a Reddit search called without--query. Catch it specifically to distinguish "you called this wrong" from a real network/API failure.buildMcpServer({ version }): McpServer-- constructs the MCP server (from@modelcontextprotocol/sdk) with thesearch/auth_status/verify_logtools registered, without starting a transport -- useful for testing or embedding in a larger MCP server.runMcpServerCommand({ version })-- whatauditreach mcpruns: builds the server and connects it over stdio. Never returns while the server is running.
No generated API docs site exists yet (no TypeDoc build wired into CI) -- the exports above are the complete public surface. Check dist/index.d.ts in the published package for exact types.
The Python package (auditreach-cli on PyPI) exposes the same surface with snake_case names -- from auditreach import RedditClient, YoutubeClient, get_reddit_credentials, verify_audit_log_chain, ... -- see python/README.md for the full Python API reference.
Platform coverage
Result limits
--max-results <n> controls how many items a single search call returns. Leave it off and auditreach silently applies a default of 25 -- the same shape of surprise PRAW's get_comments() had for years (praw#119): a caller who does not already know to pass the flag gets a quietly truncated result set.
[!NOTE] A search that returns exactly the applied limit (25 by default, or your
--max-resultsvalue) may not be the full result set. auditreach prints a stderr warning when this happens, but scripts that only parse stdout/--jsonoutput won't see it -- check for the warning or pass an explicit--max-resultsif completeness matters.
Values above the cap are silently clamped to it. For Reddit, --before/--after let you page through a search's result set using the real cursor Reddit's own response returns, up to Reddit's own ~1,000-item search cap (see Success stories for why cursor pagination alone can't go further than that); YouTube has no equivalent yet. Whenever the number of items returned equals the limit that was actually applied, whether that is the silent default or an explicit --max-results value, auditreach prints a warning to stderr telling you more results may exist and how to raise --max-results (up to the platform cap).
What is a "consent basis," honestly
The consent_basis field on every audit-log entry names the specific platform API terms and auth mechanism used for that query. It certifies that the request went through the platform's official, documented API surface under the credentials you supplied. It does not certify that your specific use case is legally sufficient for your jurisdiction or contract -- that determination is yours to make, informed by an accurate, complete, tamper-evident record of what actually happened.
Self-hosting / local-only by default
Nothing about auditreach requires a hosted account or server. Every command runs entirely on your machine; the audit log is a plain file you own. This is the same flow as Install above:
Development
TypeScript (this package):
Python (python/):
See CONTRIBUTING.md for the rules on adding a new platform client -- the short version: official API only, honest rate-limit disclosure, tests that mock the network boundary, never anything that reads or writes a raw credential outside src/auth/credential-store.ts (or python/src/auditreach/auth/credential_store.py on the Python side).
Security
See SECURITY.md for the vulnerability disclosure policy. A pre-launch OWASP/STRIDE review found zero CRITICAL/HIGH findings in auditreach's own code. ip-address and hono -- both pulled in transitively by the official @modelcontextprotocol/sdk dependency's HTTP-transport code, a path auditreach mcp never runs (it only ever starts the SDK's stdio transport, StdioServerTransport) -- previously carried advisories; package.json's overrides field now pins both to patched versions. As of this writing, npm audit --audit-level=high on a fresh install reports 0 vulnerabilities. GitHub secret scanning and push protection are enabled on this repo.
Success stories
Four real issues reported against praw-dev/praw -- PRAW, Reddit's official Python API
wrapper, and the closest thing this project has to prior art -- root-caused against
auditreach's own source and used to close genuine gaps in this tool before it had a
single outside user. Each line below is tied to the actual report that prompted it.
- praw#614 (@mananwason) -- asked how
to page past Reddit's ~1,000-result search cap. The real fix is narrower than that:
Reddit's own API returns no before/after cursor at all once you're past that cap,
cursor-based paging or not -- confirmed directly in the issue thread. What
search()actually does now is extract the real cursor from Reddit's response (SearchOutcome.nextCursor) and expose--before/--afterflags so you can page through the results within a single search's capped result set, instead of only ever seeing the first page. Going past the 1,000-item cap itself needs cloudsearch timestamp-window re-querying, which isn't built yet. - praw#1939 (@Auditormadness9) -- hit
an undiagnosed 400 error caused by a subreddit name that still carried a leading
r/prefix. Search errors now name that specific cause when it's the likely culprit: previously the CLI just returned a bare status code and left the guessing to you. - praw#984 (@MaxMatti) -- asked for a
simple way to check whether Reddit bot credentials were still valid, without PRAW's
confusing
getMe()-recursion workaround.auditreach auth --platform reddit --verifydoes exactly that now: one lightweight check, no search required, nothing written to disk. - praw#119 (@nsp) -- hit PRAW's
historic silent 25-result default, discoverable only by reading an unrelated base
class's docstring; PRAW's own maintainer admitted he "wasn't sure the best way to make
this clear."
--helpand this README now state the real default and per-platform caps, and a runtime warning fires whenever a search actually got truncated.
FAQ
What is auditreach, and what makes it different from other Reddit/YouTube research tools? It is a BYOK CLI (and MCP server) that talks to Reddit and YouTube only through their official, documented APIs, using your own API keys, and writes a hash-chained audit-log entry for every query -- platform, endpoint, scope, and the specific consent/ToS basis for that call. The differentiator is what it refuses to do: no cookie import, no shared-session scraping, no code path that pretends to be a logged-in human. See Why auditreach exists for the full reasoning and How it compares for the table against named alternatives.
What platforms and versions does auditreach run on?
The npm package (auditreach-cli) requires Node.js 20 or newer (engines field in package.json). The PyPI package (also auditreach-cli) requires Python 3.10+ (requires-python in python/pyproject.toml), which also carries the Operating System :: OS Independent classifier. Credentials go into your OS keychain through @napi-rs/keyring (npm) or keyring (PyPI) instead of a config file, so there is no platform-specific setup beyond having Node or Python installed.
Does auditreach store my Reddit or YouTube credentials anywhere?
No. Credentials go straight into your OS keychain through @napi-rs/keyring (src/auth/credential-store.ts). There is no config file, no environment variable, and no code path that writes a raw credential to disk.
How many results does a search return by default, and can I get more?
25, silently, unless you pass --max-results -- see Result limits. The hard cap is 100 for Reddit and 50 for YouTube. A stderr warning fires whenever a search actually hits the applied limit, whether that's the silent default or an explicit value you passed.
How do I check my credentials are still valid without running a real search?
node dist/cli.js auth --platform reddit --verify (or --platform youtube). It performs the minimal authenticated check and reports pass or fail, with no --query needed, no results file written, and no audit-log entry appended.
Is the audit log actually tamper-evident, or just a log file?
Tamper-evident: each entry's hash is computed from its own content and the next entry references it, so verify-log can point to the exact entry a hand-edit broke. See the demo under What it does.
What are auditreach's current limitations?
Two worth knowing up front. First, X (Twitter) is not shipped -- X API v2's pricing and post-volume caps have been prohibitive for small teams doing real research since the 2023 changes; see Platform coverage. Second, Reddit paging: search() reads the real after/before cursor out of Reddit's own response and exposes --before/--after flags to page through a single search's result set, but that does not get you past Reddit's own ~1,000-item search cap -- see the praw#614 success story for what the fix covers and doesn't.
How does the MCP server mode work?
auditreach mcp (npm) or pipx run auditreach-cli mcp (PyPI) starts a Model Context Protocol server over stdio, built on the official @modelcontextprotocol/sdk / mcp SDKs. It exposes exactly 3 tools -- search, auth_status (read-only, cannot set or clear credentials), and verify_log -- each a thin wrapper around the same programmatic core the CLI commands use, so nothing is reimplemented for the agent path. See auditreach mcp above for the full tool table and .well-known/agent.json for the machine-readable manifest an agent registry can read directly.
How does auditreach compare to Agent-Reach specifically? Agent-Reach covers more platforms (six, versus auditreach's two) by importing a logged-in browser session and scraping as that user, at zero API cost. auditreach only calls official, documented APIs with your own keys and writes a hash-chained consent/audit entry per query; it has no session-import code path at all. Neither approach is strictly better -- they're built for different buyers. See How it compares for the full side-by-side.
Is auditreach free to use commercially, and what does the license actually require?
Yes. auditreach is Apache 2.0 (see LICENSE), which permits commercial use, modification, and redistribution, including as part of a closed-source product. The conditions are: include a copy of the license with anything you redistribute, mark any files you modified, and keep the existing copyright/attribution notices. It does not grant rights to auditreach's name or trademarks.
Contributing
See CONTRIBUTING.md for the rules on adding a new platform client. Short version: official API only, honest rate-limit disclosure, tests that mock the network boundary, never a code path that reads or writes a raw credential outside src/auth/credential-store.ts.
License
Apache 2.0. See LICENSE.
来源:README.md,提交 569faec
工具
0版本历史
1- v0.2.5最新Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分