reddit-mcp-buddy 1.1.14 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +252 -66
  2. package/dist/cli.js +124 -18
  3. package/dist/cli.js.map +1 -1
  4. package/dist/core/auth.d.ts +16 -0
  5. package/dist/core/auth.d.ts.map +1 -1
  6. package/dist/core/auth.js +76 -21
  7. package/dist/core/auth.js.map +1 -1
  8. package/dist/core/cache.d.ts +12 -0
  9. package/dist/core/cache.d.ts.map +1 -1
  10. package/dist/core/cache.js +30 -8
  11. package/dist/core/cache.js.map +1 -1
  12. package/dist/core/oauth-consent.d.ts +45 -0
  13. package/dist/core/oauth-consent.d.ts.map +1 -0
  14. package/dist/core/oauth-consent.js +207 -0
  15. package/dist/core/oauth-consent.js.map +1 -0
  16. package/dist/core/rate-limiter.js +2 -2
  17. package/dist/core/rate-limiter.js.map +1 -1
  18. package/dist/core/write-gate.d.ts +133 -0
  19. package/dist/core/write-gate.d.ts.map +1 -0
  20. package/dist/core/write-gate.js +263 -0
  21. package/dist/core/write-gate.js.map +1 -0
  22. package/dist/mcp-server.d.ts +28 -3
  23. package/dist/mcp-server.d.ts.map +1 -1
  24. package/dist/mcp-server.js +220 -31
  25. package/dist/mcp-server.js.map +1 -1
  26. package/dist/services/reddit-api.d.ts +135 -0
  27. package/dist/services/reddit-api.d.ts.map +1 -1
  28. package/dist/services/reddit-api.js +420 -37
  29. package/dist/services/reddit-api.js.map +1 -1
  30. package/dist/services/write-errors.d.ts +59 -0
  31. package/dist/services/write-errors.d.ts.map +1 -0
  32. package/dist/services/write-errors.js +202 -0
  33. package/dist/services/write-errors.js.map +1 -0
  34. package/dist/tools/index.d.ts +54 -80
  35. package/dist/tools/index.d.ts.map +1 -1
  36. package/dist/tools/index.js +9 -2
  37. package/dist/tools/index.js.map +1 -1
  38. package/dist/tools/write.d.ts +206 -0
  39. package/dist/tools/write.d.ts.map +1 -0
  40. package/dist/tools/write.js +716 -0
  41. package/dist/tools/write.js.map +1 -0
  42. package/dist/types/reddit.types.d.ts +1 -0
  43. package/dist/types/reddit.types.d.ts.map +1 -1
  44. package/package.json +15 -12
package/README.md CHANGED
@@ -2,7 +2,16 @@
2
2
 
3
3
  ### Reddit Browser for Claude Desktop and AI Assistants
4
4
 
5
- A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that enables Claude Desktop and other AI assistants to browse Reddit, search posts, and analyze user activity. Clean, fast, and actually works - browse subreddits with no API keys; add free Reddit credentials for search, comments, user analysis, and full metrics.
5
+ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for browsing Reddit, searching posts, and analyzing user activity. It needs existing approved Reddit API credentials. Version 1.2.0 added optional posting and commenting with per-process caps and a client-dependent confirmation flow. See [Posting](#posting-v120).
6
+
7
+ > **Reddit is closing the access this server uses.** Only people who already hold approved Reddit API credentials can use it.
8
+ >
9
+ > - **2026-10-31:** Reddit stopped accepting new requests for public API access ([migration post](https://www.reddit.com/r/redditdev/comments/1wubcvf/moving_data_api_apps_to_the_developer_platform/)).
10
+ > - **2026-11-13:** Reddit ends RSS feed support ([changelog, October 8, 2026](https://support.reddithelp.com/hc/en-us/articles/54353370049684-Changelog-October-8-2026)). RSS was the only thing this server could read without credentials, so from this date every call without credentials returns an error saying credentials are needed.
11
+ > - **2027-01-12:** Reddit starts closing API access for apps whose owners have not registered them at [developers.reddit.com/app-registration](https://developers.reddit.com/app-registration) or answered Reddit's outreach ([migration post](https://www.reddit.com/r/redditdev/comments/1wubcvf/moving_data_api_apps_to_the_developer_platform/)).
12
+ > - **March 2027:** Reddit ends the remaining public API access ([migration post](https://www.reddit.com/r/redditdev/comments/1wubcvf/moving_data_api_apps_to_the_developer_platform/)).
13
+ >
14
+ > This project cannot grant API access or register your app for you.
6
15
 
7
16
  [![npm version](https://img.shields.io/npm/v/reddit-mcp-buddy.svg)](https://www.npmjs.com/package/reddit-mcp-buddy)
8
17
  [![npm downloads](https://img.shields.io/npm/dm/reddit-mcp-buddy.svg)](https://www.npmjs.com/package/reddit-mcp-buddy)
@@ -25,7 +34,8 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that en
25
34
  - [Quick Start](#quick-start-30-seconds)
26
35
  - [What can it do?](#what-can-it-do)
27
36
  - [Available Tools](#available-tools)
28
- - [Authentication](#authentication-optional)
37
+ - [Authentication](#authentication)
38
+ - [Posting (v1.2.0)](#posting-v120)
29
39
  - [Installation Options](#installation-options)
30
40
  - [Global Install](#global-install)
31
41
  - [From Source](#from-source)
@@ -39,12 +49,13 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that en
39
49
 
40
50
  ## What makes Reddit MCP Buddy different?
41
51
 
42
- - **🚀 Zero setup** - Browse subreddits instantly, no Reddit API registration needed (search, comments, user analysis, and engagement metrics need free credentials)
43
- - **⚡ Up to 10x more requests** - Three-tier authentication system (10/60/100 requests per minute)
52
+ - **🔑 Built for existing API access** - Uses your approved Reddit app's credentials through Reddit's OAuth API
53
+ - **✍️ Opt-in posting (v1.2.0)** - Create posts and comments with a client-dependent confirmation flow, per-process caps, and duplicate suppression
54
+ - **⚡ Local rate limits** - Configured caps of 10/60/100 requests per minute; Reddit applies its own limits
44
55
  - **🎯 Clean data** - No fake "sentiment analysis" or made-up metrics
45
56
  - **🧠 LLM-optimized** - Built specifically for AI assistants like Claude
46
57
  - **📦 TypeScript** - Fully typed, reliable, and maintainable
47
- - **✅ Proven rate limits** - Thoroughly tested authentication tiers with verification tools
58
+ - **✅ Rate-limit testing** - Verification tools for the server's local authentication tiers
48
59
 
49
60
  ## Quick Start (30 seconds)
50
61
 
@@ -52,18 +63,22 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that en
52
63
 
53
64
  1. **Download**: [reddit-mcp-buddy.mcpb](https://github.com/karanb192/reddit-mcp-buddy/releases/latest/download/reddit-mcp-buddy.mcpb)
54
65
  2. **Install**: Open the downloaded file
55
- 3. **Done!** Reddit tools are now available in Claude
66
+ 3. **Add credentials**: Enter your approved Reddit app's client ID and secret in the extension settings (see [Authentication](#authentication))
56
67
 
57
68
  ### For Claude Desktop - NPM Method (Alternative)
58
69
 
59
- Add this to your `claude_desktop_config.json`:
70
+ Add this to your `claude_desktop_config.json`, with your approved app's credentials (see [Authentication](#authentication)):
60
71
 
61
72
  ```json
62
73
  {
63
74
  "mcpServers": {
64
75
  "reddit": {
65
76
  "command": "npx",
66
- "args": ["-y", "reddit-mcp-buddy"]
77
+ "args": ["-y", "reddit-mcp-buddy"],
78
+ "env": {
79
+ "REDDIT_CLIENT_ID": "your_client_id",
80
+ "REDDIT_CLIENT_SECRET": "your_client_secret"
81
+ }
67
82
  }
68
83
  }
69
84
  }
@@ -74,12 +89,14 @@ Add this to your `claude_desktop_config.json`:
74
89
  Run this command to add the MCP server (user scope):
75
90
 
76
91
  ```bash
77
- claude mcp add --transport stdio reddit-mcp-buddy -s user -- npx -y reddit-mcp-buddy
92
+ claude mcp add --transport stdio reddit-mcp-buddy -s user \
93
+ -e REDDIT_CLIENT_ID=your_client_id -e REDDIT_CLIENT_SECRET=your_client_secret \
94
+ -- npx -y reddit-mcp-buddy
78
95
  ```
79
96
 
80
97
  ### For Other MCP Clients
81
98
 
82
- Use the NPM method: `npx -y reddit-mcp-buddy`
99
+ Run `npx -y reddit-mcp-buddy` with `REDDIT_CLIENT_ID` and `REDDIT_CLIENT_SECRET` set in its environment.
83
100
 
84
101
  ## What can it do?
85
102
 
@@ -90,6 +107,7 @@ Ask your AI assistant to:
90
107
  - 💬 **"Get comments from this Reddit post"** - Fetch post with full comment threads
91
108
  - 👤 **"Analyze user spez"** - Get user history, karma, and activity
92
109
  - 📚 **"Explain Reddit karma"** - Understand Reddit terminology
110
+ - ✍️ **"Post this to r/test"** - Draft, check the sub's rules, and submit after you confirm (opt-in, see [Posting](#posting-v120))
93
111
 
94
112
  ## Available Tools
95
113
 
@@ -105,7 +123,7 @@ Browse posts from any subreddit with sorting options.
105
123
  - Include subreddit info: Optional flag for subreddit metadata (requires credentials)
106
124
  ```
107
125
 
108
- > **No credentials?** Results are served from Reddit's public RSS feed (`data_source: "rss"`): `score`, `num_comments`, `upvote_ratio`, and `nsfw` come back `null`, and the `include_nsfw` filter can't be applied. Add credentials ([Authentication](#authentication-optional)) for full data via the API.
126
+ > **No credentials?** Until 2026-11-13, results come from Reddit's RSS feed (`data_source: "rss"`): `score`, `num_comments`, `upvote_ratio`, and `nsfw` come back `null`, and the `include_nsfw` filter can't be applied. Reddit ends RSS support on 2026-11-13 ([changelog](https://support.reddithelp.com/hc/en-us/articles/54353370049684-Changelog-October-8-2026)); from then on browsing needs credentials too ([Authentication](#authentication)).
109
127
 
110
128
  ### `search_reddit`
111
129
  Search across Reddit or specific subreddits.
@@ -145,25 +163,30 @@ Get explanations of Reddit terms.
145
163
  - Terms: karma, cake day, AMA, ELI5, etc.
146
164
  ```
147
165
 
148
- ## Authentication (Optional)
166
+ ### Write tools (opt-in)
167
+
168
+ `create_post`, `add_comment`, and `subreddit_rules` only appear when you enable posting; read-only installs see exactly the five tools above. Details in [Posting (v1.2.0)](#posting-v120).
169
+
170
+ ## Authentication
149
171
 
150
- Want more requests? Add Reddit credentials to your Claude Desktop config:
172
+ Every tool that reads Reddit needs credentials for a Reddit app whose API access Reddit has already approved. Only `reddit_explain`, which works offline, runs without them.
173
+
174
+ ### Who can use this server
175
+
176
+ - **You already hold approved Reddit API access:** use your app's credentials below.
177
+ - **You do not:** Reddit stopped accepting new requests for public API access on 2026-10-31 ([migration post](https://www.reddit.com/r/redditdev/comments/1wubcvf/moving_data_api_apps_to_the_developer_platform/)), so there is no way to get credentials for this server now. This project cannot grant access, and it does not provide shared API keys or a third-party OAuth service.
178
+ - **Keep your access past 2027-01-12:** Reddit starts closing API access on that date for apps whose owners have not registered them at [developers.reddit.com/app-registration](https://developers.reddit.com/app-registration) or answered Reddit's outreach ([migration post](https://www.reddit.com/r/redditdev/comments/1wubcvf/moving_data_api_apps_to_the_developer_platform/)). Registration is done by each app's owner; this project cannot do it for you.
179
+
180
+ Without credentials, `browse_subreddit` reads Reddit's RSS feeds only until 2026-11-13, when Reddit ends RSS support ([changelog](https://support.reddithelp.com/hc/en-us/articles/54353370049684-Changelog-October-8-2026)). From then on every Reddit tool returns an error that says credentials are needed.
151
181
 
152
182
  ### Setup Steps
153
183
 
154
- 1. **Go to** https://www.reddit.com/prefs/apps
155
- 2. **Click** "Create App" or "Create Another App"
156
- 3. **Fill out the form:**
157
- - **Name**: Any name (e.g., "reddit-mcp-buddy")
158
- - **App type**: Select **"script"** (CRITICAL for 100 rpm!)
159
- - **Description**: Optional
160
- - **About URL**: Leave blank
161
- - **Redirect URI**: `http://localhost:8080` (required but unused)
162
- 4. **Click** "Create app"
163
- 5. **Find your credentials:**
164
- - **Client ID**: The string under "personal use script"
184
+ 1. **Open** https://www.reddit.com/prefs/apps and select your approved app.
185
+ 2. **Check the app type:** **"script"** supports password-grant authentication, **"web app"** supports OAuth consent with a refresh token (see below), and app-only mode works with both.
186
+ 3. **Find your credentials:**
187
+ - **Client ID**: The string beneath the app's name and type
165
188
  - **Client Secret**: The secret string
166
- 6. **Update your Claude Desktop config:**
189
+ 4. **Update your Claude Desktop config:**
167
190
 
168
191
  ```json
169
192
  {
@@ -182,27 +205,112 @@ Want more requests? Add Reddit credentials to your Claude Desktop config:
182
205
  }
183
206
  ```
184
207
 
208
+ ### Web apps with OAuth consent
209
+
210
+ An approved web app can authenticate a user without their Reddit password. `--oauth` runs Reddit's [authorization-code flow](https://github.com/reddit-archive/reddit/wiki/OAuth2#authorization) once and prints a refresh token.
211
+
212
+ 1. **Register the redirect URI.** On [Reddit app preferences](https://www.reddit.com/prefs/apps), the web app's redirect URI must be a loopback address with a port, such as `http://localhost:8080`.
213
+ 2. **Run the consent command** on the machine where your browser is signed in to Reddit:
214
+
215
+ ```bash
216
+ npx -y reddit-mcp-buddy --oauth
217
+ ```
218
+
219
+ It prompts for the web app's client ID and secret, or reads `REDDIT_CLIENT_ID` and `REDDIT_CLIENT_SECRET` from the environment. It requests `identity`, `read`, and `history`, which the read-only tools need. Add `--write` to also request `submit` and `flair` for [posting](#posting-v120). Pass `--redirect-uri http://localhost:<port>` if you registered a different port.
220
+ 3. **Open the printed link and click Allow.** Reddit redirects back to a temporary local server that only listens on your machine. It checks the random `state` value, exchanges the one-time code, and confirms the account with `/api/v1/me`. It waits up to 5 minutes and never posts.
221
+ 4. **Copy the token into your config.** It prints `REDDIT_REFRESH_TOKEN=...`. To keep it off the screen, add `--out ~/reddit-token.env`, a path outside any repository. If that file already exists, the command stops before asking for consent. If writing fails after consent, it prints the token instead. On macOS and Linux the file is readable only by you.
222
+
223
+ Set these variables in the server's environment:
224
+
225
+ ```json
226
+ {
227
+ "REDDIT_CLIENT_ID": "your_client_id",
228
+ "REDDIT_CLIENT_SECRET": "your_client_secret",
229
+ "REDDIT_REFRESH_TOKEN": "your_refresh_token"
230
+ }
231
+ ```
232
+
233
+ Leave `REDDIT_PASSWORD` unset when using a refresh token. Setting both is rejected at startup. The server exchanges the refresh token for access tokens as needed and does not write environment credentials to `auth.json`. Refresh tokens loaded from that file are not used; configure this mode through the environment.
234
+
235
+ Treat a refresh token like a password. Keep it outside version control and revoke access in [Reddit app preferences](https://www.reddit.com/prefs/apps) when it is no longer needed. OAuth consent does not grant Reddit API approval or extend the approved use case.
236
+
185
237
  ### Three-Tier Authentication System
186
238
 
187
- Reddit MCP Buddy supports three authentication levels, each with different rate limits:
239
+ Reddit MCP Buddy enforces these local caps. They are not Reddit API quotas or guaranteed throughput:
188
240
 
189
- | Mode | Rate Limit | Required Credentials | Best For |
241
+ | Mode | Local Cap | Required Credentials | Best For |
190
242
  |------|------------|---------------------|----------|
191
- | **Anonymous** | 10 req/min* | None | Testing, light usage |
243
+ | **No credentials** | 10 req/min* | None | Ends 2026-11-13 |
192
244
  | **App-Only** | 60 req/min | Client ID + Secret | Regular browsing |
193
- | **Authenticated** | 100 req/min | All 4 credentials | Heavy usage, automation |
245
+ | **Authenticated** | 100 req/min | Client ID + Secret, plus refresh token or username/password | Heavy usage, automation |
194
246
 
195
- *\*Server-side cap. Anonymous requests are served from Reddit's logged-out RSS feed, which applies its own stricter per-IP throttle (often one uncached request per 25-60 seconds). The 15-minute cache and automatic retries absorb much of this, but sustained anonymous browsing is effectively slower than 10 req/min.*
247
+ *\*Until 2026-11-13 only. Requests without credentials are served from Reddit's logged-out RSS feed, which applies its own stricter per-IP throttle.*
196
248
 
197
249
  #### How It Works:
198
- - **Anonymous Mode**: Default mode, no setup required. Only `browse_subreddit` (plus the offline `reddit_explain`) works: Reddit blocks the logged-out JSON API, so browse results come from Reddit's public RSS feed (`data_source: "rss"`) with engagement metrics and NSFW flags as `null`. The remaining tools require credentials.
250
+ - **No credentials**: Until 2026-11-13, only `browse_subreddit` (from Reddit's RSS feed, with engagement metrics and NSFW flags as `null`) and the offline `reddit_explain` work. After Reddit ends RSS support that day, every Reddit tool returns an error that says credentials are needed.
199
251
  - **App-Only Mode**: Uses OAuth2 client credentials grant (works with both script and web apps)
200
- - **Authenticated Mode**: Uses OAuth2 password grant (requires script app type)
252
+ - **Authenticated Mode**: Uses OAuth2 refresh-token authentication for an authorized web app, or password grant for a script app
201
253
 
202
254
  **Important Notes**:
203
- - Script apps support BOTH app-only (60 rpm) and authenticated (100 rpm) modes
204
- - Web apps only support app-only mode (60 rpm maximum)
205
- - For 100 requests/minute, you MUST use a script app with username + password
255
+ - Client credentials select app-only mode; a refresh token or username/password selects user authentication.
256
+ - A refresh token carries the scopes granted during consent. Missing scopes can prevent individual tools from working.
257
+ - User authentication changes this server's local cap; it does not grant a larger quota from Reddit.
258
+
259
+ ## Posting (v1.2.0)
260
+
261
+ Since v1.2.0 the server can post for you. Three tools, all opt-in:
262
+
263
+ - **`create_post`** - Submit a text or link post to one subreddit. Checks mechanical rules (title limits, flair required, link vs text allowed) and supports `validate_only: true` as a dry run. Confirmation depends on the client's capabilities as described below.
264
+ - **`add_comment`** - Comment on a post or reply to a specific comment (by id or URL), with the same confirmation flow.
265
+ - **`subreddit_rules`** - Read-only. Fetches a sub's rules, posting requirements, capability flags, and flair choices in one cached call, so drafts fit the sub before anything is submitted.
266
+
267
+ The intended workflow: `subreddit_rules` first, then `create_post` with `validate_only: true`, review the full draft and options with the user, then submit the identical payload.
268
+
269
+ ### Enabling posting
270
+
271
+ Add `REDDIT_BUDDY_WRITE` next to your existing credentials:
272
+
273
+ ```json
274
+ {
275
+ "mcpServers": {
276
+ "reddit": {
277
+ "command": "npx",
278
+ "args": ["-y", "reddit-mcp-buddy"],
279
+ "env": {
280
+ "REDDIT_CLIENT_ID": "your_client_id",
281
+ "REDDIT_CLIENT_SECRET": "your_client_secret",
282
+ "REDDIT_USERNAME": "your_username",
283
+ "REDDIT_PASSWORD": "your_password",
284
+ "REDDIT_BUDDY_WRITE": "true"
285
+ }
286
+ }
287
+ }
288
+ }
289
+ ```
290
+
291
+ Claude Desktop extension users: flip the **Enable posting tools** toggle in the extension settings instead. It maps to the same `REDDIT_BUDDY_WRITE` variable.
292
+
293
+ Alternatively, replace `REDDIT_PASSWORD` with `REDDIT_REFRESH_TOKEN` from the [web-app consent flow](#web-apps-with-oauth-consent); `npx -y reddit-mcp-buddy --oauth --write` requests the posting scopes. Posting requires the granted scopes `identity`, `read`, `submit`, and `flair`. Add `history` if you also use `user_analysis`. `REDDIT_USERNAME` is optional with a refresh token; when provided, it must match the account returned by Reddit.
294
+
295
+ Credentials must come from environment variables (or extension config fields, which become environment variables). The interactive `--auth` file setup does not enable posting. Startup verifies the account through Reddit and checks granted scopes. If any requirement is missing, the server logs the reason and keeps posting tools disabled.
296
+
297
+ ### The safety model, in plain words
298
+
299
+ Posting uses your account. The server enforces registration, rate limits, and duplicate checks; human approval also depends on the client:
300
+
301
+ - **Off by default.** Without `REDDIT_BUDDY_WRITE`, the write tools do not exist: read-only installs see exactly the same 5 tools as before, and pay zero extra context.
302
+ - **stdio only.** The HTTP transport has no authentication, so write tools refuse to register there. No process on your machine or network can turn the HTTP endpoint into a posting proxy.
303
+ - **Confirmation depends on the client.** Clients supporting [MCP elicitation](https://modelcontextprotocol.io/specification/latest) get a confirmation prompt with the target, account, content preview, full content length, and post options. The prompt requires an explicit acceptance. Previews can be truncated, so review the full draft in your client first. Without elicitation, the server requires a preview or successful dry run followed by the identical payload within 15 minutes. It cannot verify that a human approved that repeat: approval depends on the client's tool prompt and the model following instructions. Only enable posting in a client whose approval behavior you trust.
304
+ - **Hourly caps you cannot raise.** At most 5 posts/hour, 30 comments/hour, and 15 seconds between writes, enforced in the server. Environment variables can tighten these, never loosen them. Honest limit: the caps live in the server process (a restart resets the hour, parallel sessions have separate caps, and a fork of this open-source code can remove them). They exist to make casual abuse pointless, not to stop a determined operator.
305
+ - **Duplicate suppression.** Retrying an identical submit within 15 minutes returns the original post instead of posting twice, including the same content re-drafted for the same sub. Posting the same content to a different subreddit is allowed, with a warning naming the earlier post.
306
+ - **Verified after submit.** Reddit happily returns "success" for posts AutoModerator removes seconds later. The server re-checks after submitting and reports `status: "filtered"` with a warning when that happens, instead of telling you it went live.
307
+ - **Conspicuous logging.** Every allowed write is logged to stderr with the kind, the target (subreddit when known), and the acting user.
308
+
309
+ ### Know the trade-off before enabling
310
+
311
+ Reddit's password grant returns a token with **full account scope**. An OAuth refresh token carries the permissions granted during consent. These permissions apply across the account, not just one subreddit. With posting off, the server uses the credentials for reads; enabling posting lets it submit posts and comments. Keep passwords and refresh tokens out of version control and off shared machines.
312
+
313
+ Also worth knowing: Reddit applies its own account-level posting throttles on top of everything above, based on account age and karma. If Reddit says "try again in N minutes", the server surfaces the wait instead of hammering.
206
314
 
207
315
  ## Privacy & Data Handling
208
316
 
@@ -230,7 +338,7 @@ Reddit MCP Buddy is designed with privacy and transparency in mind. Here's how y
230
338
  - **Local Processing**: All data processing happens locally on your machine
231
339
 
232
340
  ### Security Notes
233
- - **Read-Only Operations**: All tools are read-only - the server never posts, comments, or modifies any Reddit content
341
+ - **Read-Only by Default**: Posting requires explicit opt-in. Review the [client-dependent confirmation flow](#the-safety-model-in-plain-words) before enabling it.
234
342
  - **Credential Safety**:
235
343
  - OAuth tokens are refreshed automatically and kept in memory; only `--auth` CLI setups also cache the token in `~/.reddit-mcp-buddy/auth.json` (file mode 600)
236
344
  - Client secrets are treated as sensitive and never logged
@@ -282,6 +390,26 @@ npx -y reddit-mcp-buddy --auth
282
390
 
283
391
  This will prompt you for Reddit app credentials and save them locally. **Note: This does NOT work with Claude Desktop** - use environment variables in your Claude config instead.
284
392
 
393
+ ### Private sandbox posting test
394
+
395
+ Build the checkout, then print the proposed test without making any requests:
396
+
397
+ ```bash
398
+ npm run build
399
+ REDDIT_TEST_SUBREDDIT=your_private_sub node tests/live-write.mjs
400
+ ```
401
+
402
+ The live run requires an approved app, `REDDIT_CLIENT_ID` and `REDDIT_CLIENT_SECRET`, plus either `REDDIT_REFRESH_TOKEN` or the script-app `REDDIT_USERNAME`/`REDDIT_PASSWORD` pair. The account must moderate the private test subreddit. OAuth validation requires all six scopes: `identity`, `read`, `submit`, `flair`, `history` for recovery, and `edit` for cleanup. The harness checks these before connecting any posting client. Keep credentials outside the repository. On Node versions supporting `--env-file`, a local environment file can supply them:
403
+
404
+ ```bash
405
+ RUN_WRITE_TESTS=1 REDDIT_TEST_SUBREDDIT=your_private_sub \
406
+ node --env-file=/path/to/private.env tests/live-write.mjs --run
407
+ ```
408
+
409
+ This command performs real writes. It starts actual stdio MCP connections, declines one post request, accepts one test post, and tests comment preview followed by an identical submission from a client without elicitation. The harness supplies the confirmation responses automatically; running it authorizes these test actions. It creates one post and one comment, verifies their content, then attempts deletion of both even after a failure.
410
+
411
+ The unique marker and any cleanup failures are printed for manual inspection. Lost responses trigger a search of the test user's newest posts and comments; an unresolved outcome or unverified deletion fails the run. Cleanup cannot be guaranteed if the process is killed or Reddit is unavailable. Ordinary unit tests use an offline API fixture, and normal integration runs skip posting unless explicitly enabled.
412
+
285
413
  ### Testing with HTTP Mode
286
414
 
287
415
  To test the server directly in your terminal:
@@ -313,20 +441,31 @@ npm link
313
441
  ```
314
442
 
315
443
  ### Using Docker
444
+
445
+ The Docker image and CI workflows use Node.js 26. To build and run the image:
446
+
316
447
  ```bash
317
448
  git clone https://github.com/karanb192/reddit-mcp-buddy.git
318
449
  cd reddit-mcp-buddy
319
- docker build -t reddit-mcp-buddy .
320
- docker run -it reddit-mcp-buddy
450
+ docker build --pull -t reddit-mcp-buddy .
451
+ docker run -it -e REDDIT_CLIENT_ID=your_client_id -e REDDIT_CLIENT_SECRET=your_client_secret reddit-mcp-buddy
452
+ ```
453
+
454
+ Run the container smoke test with Docker, curl, and jq installed:
455
+
456
+ ```bash
457
+ bash tests/test-docker.sh reddit-mcp-buddy
321
458
  ```
322
459
 
460
+ The test checks container health, MCP initialization, tool discovery, and shutdown without Reddit credentials.
461
+
323
462
  ### Claude Desktop Extension
324
463
 
325
464
  For one-click installation in Claude Desktop, download the pre-built extension:
326
465
 
327
466
  **📦 [Download reddit-mcp-buddy.mcpb](https://github.com/karanb192/reddit-mcp-buddy/releases/latest/download/reddit-mcp-buddy.mcpb)**
328
467
 
329
- **Installation:** Simply open the downloaded `.mcpb` file - Claude Desktop will automatically install the extension and the Reddit tools will be immediately available.
468
+ **Installation:** Open the downloaded `.mcpb` file and Claude Desktop installs the extension. Then enter your approved Reddit app's credentials in the extension settings (see [Authentication](#authentication)).
330
469
 
331
470
  #### Build from Source (Optional)
332
471
 
@@ -343,10 +482,9 @@ cd reddit-mcp-buddy
343
482
 
344
483
  | Feature | Reddit MCP Buddy | Other MCP Tools |
345
484
  |---------|-------------|----------------|
346
- | **Zero Setup** | ✅ Browse instantly; free keys unlock the rest | ❌ Keys required for everything |
347
- | **Max Rate Limit** | ✅ 100 req/min proven | ❓ Unverified claims |
485
+ | **Credentials** | Existing approved Reddit API access required | Varies by server |
348
486
  | **Language** | TypeScript/Node.js | Python (most) |
349
- | **Tools Count** | 5 (focused) | 8-10 (redundant) |
487
+ | **Tools Count** | 5 read + 3 opt-in write | 8-10 (redundant) |
350
488
  | **Fake Metrics** | ✅ Real data only | ❌ "Sentiment scores" |
351
489
  | **Search** | ✅ Full search | Limited or none |
352
490
  | **Caching** | ✅ Smart caching | Usually none |
@@ -357,17 +495,16 @@ cd reddit-mcp-buddy
357
495
 
358
496
  | Mode | Requests/Minute | Cache TTL | Setup Required |
359
497
  |------|----------------|-----------|----------------|
360
- | Anonymous | 10 | 15 min | None |
498
+ | No credentials (until 2026-11-13) | 10 | 15 min | None |
361
499
  | App-only | 60 | 5 min | Client ID + Secret |
362
500
  | Authenticated | 100 | 5 min | All credentials |
363
501
 
364
- *Cache TTL applies to subreddit listings. Post details (10 min), search results (10 min), and user profiles (15 min) use fixed TTLs in all modes. Anonymous throughput is additionally bounded by Reddit's own per-IP RSS throttle, which is stricter than 10/min for uncached requests.*
502
+ *Cache TTL applies to subreddit listings. Post details (10 min), search results (10 min), and user profiles (15 min) use fixed TTLs in all modes.*
365
503
 
366
504
  ## Why Reddit MCP Buddy?
367
505
 
368
506
  ### What others do wrong:
369
507
  - ❌ **Fake metrics** - "sentiment scores" that are just keyword counting
370
- - ❌ **Complex setup** - Requiring API keys just to start
371
508
  - ❌ **Bloated responses** - Returning 100+ fields of Reddit's raw API
372
509
  - ❌ **Poor LLM integration** - Confusing parameters and unclear descriptions
373
510
 
@@ -415,11 +552,18 @@ cd reddit-mcp-buddy
415
552
 
416
553
  ### Common Issues
417
554
 
555
+ **"Reddit ended logged-out RSS access on 2026-11-13"**
556
+ - The server has no credentials, and Reddit no longer serves the RSS feeds it used without them ([changelog](https://support.reddithelp.com/hc/en-us/articles/54353370049684-Changelog-October-8-2026)). The subreddit, post, or user you asked for is not the problem
557
+ - Add your approved app's credentials (see [Authentication](#authentication)). Reddit stopped accepting new API access requests on 2026-10-31, so this only helps people who already hold access
558
+
559
+ **"Cannot create an app" or "API approval required"**
560
+ - Reddit stopped accepting new requests for public API access on 2026-10-31 ([migration post](https://www.reddit.com/r/redditdev/comments/1wubcvf/moving_data_api_apps_to_the_developer_platform/)); this project cannot approve an app or remove Reddit's restrictions
561
+ - Use credentials only for an app and use case Reddit has approved
562
+
418
563
  **"Can't achieve 100 requests/minute"**
419
- - Ensure your app type is **"script"** not "web" or "installed"
420
- - Script apps created by one account can only authenticate as that same account
421
- - Run `npm run test:rate-limit:auth` to verify (requires cloning the repo)
422
- - If still failing, create a new script app while logged into the authenticating account
564
+ - The 10/60/100 tiers are this server's local caps, not guaranteed throughput from Reddit
565
+ - Respect Reddit's rate-limit responses; adding account credentials does not increase Reddit's granted quota
566
+ - Run `npm run test:rate-limit:app` or `npm run test:rate-limit:auth` to inspect the corresponding local mode (requires cloning the repo)
423
567
 
424
568
  **"Command not found" error**
425
569
  ```bash
@@ -432,15 +576,20 @@ $(npm prefix -g)/bin/reddit-mcp-buddy
432
576
  ```
433
577
 
434
578
  **Browsing works but search / comments / user analysis fail**
435
- - Without credentials only `browse_subreddit` (served from Reddit's public RSS feed, no scores or comment counts) and the offline `reddit_explain` work
436
- - Anonymous browsing can also hit Reddit's own RSS rate limit (HTTP 429); the server retries automatically, but sustained throttling can still fail
437
- - Solution: Add Reddit credentials (see [Authentication](#authentication-optional))
579
+ - Without credentials, only `browse_subreddit` (from Reddit's RSS feed, until 2026-11-13) and the offline `reddit_explain` work
580
+ - Solution: Add your approved app's credentials (see [Authentication](#authentication))
438
581
 
439
582
  **Rate limit errors**
440
- - Without auth: 10 requests/minute server cap, and Reddit's own RSS feed throttles harder per IP (the server retries automatically)
441
- - With app credentials only: 60 requests/minute
442
- - With full authentication: 100 requests/minute
443
- - Solution: Add Reddit credentials (see [Authentication](#authentication-optional))
583
+ - Local caps: 60 requests/minute with app credentials and 100 with full authentication (10 without credentials, until 2026-11-13)
584
+ - Reddit applies its own API limits; the server retries transient failures, but sustained throttling can still fail
585
+ - Reduce request frequency and respect Reddit's rate-limit responses
586
+ - If an error says `Retry in Ns`, wait that long before retrying. The server returns long upstream waits immediately instead of sleeping through the client's request timeout.
587
+
588
+ **Write tools don't show up**
589
+ - All of these must hold: `REDDIT_BUDDY_WRITE=true`, client credentials plus a refresh token or username/password via environment variables, stdio transport, a verified user identity, and granted `identity`/`read`/`submit`/`flair` scopes
590
+ - The startup log (stderr) names exactly which condition failed
591
+ - `--auth` file setups cannot write: the password is never saved, so restarts fall back to app-only tokens. Move credentials into your MCP client config's `env` block
592
+ - HTTP mode never registers write tools, by design (the HTTP endpoint has no authentication)
444
593
 
445
594
  **"Subreddit not found"**
446
595
  - Check spelling (case-insensitive)
@@ -457,10 +606,11 @@ $(npm prefix -g)/bin/reddit-mcp-buddy
457
606
  #### Authentication Variables
458
607
  | Variable | Description | Required | Rate Limit |
459
608
  |----------|-------------|----------|------------|
460
- | `REDDIT_CLIENT_ID` | Reddit app client ID | No | 60 req/min (with secret) |
461
- | `REDDIT_CLIENT_SECRET` | Reddit app secret | No | 60 req/min (with ID) |
462
- | `REDDIT_USERNAME` | Reddit account username | No | 100 req/min (with all 4) |
463
- | `REDDIT_PASSWORD` | Reddit account password | No | 100 req/min (with all 4) |
609
+ | `REDDIT_CLIENT_ID` | Reddit app client ID | Yes (from 2026-11-13) | Local cap: 60 req/min (with secret) |
610
+ | `REDDIT_CLIENT_SECRET` | Reddit app secret | Yes (from 2026-11-13) | Local cap: 60 req/min (with ID) |
611
+ | `REDDIT_USERNAME` | Reddit account username | No | Local cap: 100 req/min (with all 4) |
612
+ | `REDDIT_PASSWORD` | Reddit account password | No | Local cap: 100 req/min (with all 4) |
613
+ | `REDDIT_REFRESH_TOKEN` | OAuth refresh token; leave password unset | No | Local cap: 100 req/min with client ID + secret |
464
614
  | `REDDIT_USER_AGENT` | Custom user agent string (applies when credentials are configured) | No | - |
465
615
 
466
616
  #### Server Configuration
@@ -473,8 +623,47 @@ $(npm prefix -g)/bin/reddit-mcp-buddy
473
623
  | `REDDIT_BUDDY_ALLOWED_HOSTS` | Comma-separated `host:port` values accepted in the Host header (DNS-rebinding protection) | loopback values when bound to localhost |
474
624
  | `REDDIT_BUDDY_NO_CACHE` | Disable caching (always fetch fresh) | `false` |
475
625
 
626
+ #### Posting (v1.2.0)
627
+ | Variable | Description | Default |
628
+ |----------|-------------|---------|
629
+ | `REDDIT_BUDDY_WRITE` | Register the [posting tools](#posting-v120); requires env user credentials, verified identity and scopes, and stdio | `false` |
630
+ | `REDDIT_BUDDY_MAX_POSTS_PER_HOUR` | Posts per hour; only values from 1 to 4 are honored (0 and invalid values are ignored) | `5` |
631
+ | `REDDIT_BUDDY_MAX_COMMENTS_PER_HOUR` | Comments per hour; only values from 1 to 29 are honored (0 and invalid values are ignored) | `30` |
632
+ | `REDDIT_BUDDY_MIN_WRITE_INTERVAL_S` | Seconds between writes; only values ABOVE 15 are honored | `15` |
633
+
634
+ The three rate-floor variables can only tighten the built-in caps. Setting them looser than the defaults does nothing, on purpose, and 0 does not mean "pause posting": it falls back to the default cap.
635
+
476
636
  > **HTTP mode has no authentication.** It binds to localhost so only your machine can reach it, and rejects Host headers outside the loopback set. Setting `REDDIT_BUDDY_HOST=0.0.0.0` exposes it to your whole network - only do that on a trusted network (e.g. inside Docker, which sets it deliberately). On a non-loopback bind the Host check is off by default, since clients legitimately arrive with a container IP or service name; set `REDDIT_BUDDY_ALLOWED_HOSTS` to restrict it. Browser requests are rejected unless their origin is listed in `REDDIT_BUDDY_ALLOWED_ORIGINS`; non-browser clients like Postman are unaffected.
477
637
 
638
+ ### HTTP and HTTPS Proxies
639
+
640
+ On Node 22.21.0+ in the 22.x line, or Node 24 and newer, enable Node's built-in proxy support before starting the server. The project's Node 26 Docker image supports this. Check `node --version` first: unsupported versions can ignore these settings and connect directly. Node currently marks this feature as under active development.
641
+
642
+ ```json
643
+ {
644
+ "mcpServers": {
645
+ "reddit": {
646
+ "command": "npx",
647
+ "args": ["-y", "reddit-mcp-buddy"],
648
+ "env": {
649
+ "NODE_USE_ENV_PROXY": "1",
650
+ "HTTP_PROXY": "http://proxy.example.com:8080",
651
+ "HTTPS_PROXY": "http://proxy.example.com:8080",
652
+ "NO_PROXY": "localhost,127.0.0.1"
653
+ }
654
+ }
655
+ }
656
+ }
657
+ ```
658
+
659
+ `HTTP_PROXY` routes HTTP requests; `HTTPS_PROXY` routes HTTPS requests, including Reddit API and RSS calls. `NO_PROXY` excludes matching hosts. Export these variables in your shell for CLI use, or pass them with Docker's `-e` options. Set them in the process environment before startup; the server does not load a project `.env` file automatically.
660
+
661
+ Inside Docker, `localhost` refers to the container. On Docker Desktop, use `host.docker.internal` to reach a proxy running on the host.
662
+
663
+ Proxy authentication can be included in the proxy URL as `http://username:password@proxy.example.com:8080`. Treat that value as a credential and redact it from shared logs and configuration. For a network that uses a private certificate authority, use `NODE_EXTRA_CA_CERTS` with your organization's PEM certificate file instead of disabling TLS verification.
664
+
665
+ See [Node's proxy and certificate configuration guide](https://nodejs.org/learn/http/enterprise-network-configuration). Proxy support routes network traffic; it does not grant Reddit API approval or bypass Reddit's access rules.
666
+
478
667
  ## Technical Details
479
668
 
480
669
  ### Smart Caching System
@@ -482,7 +671,7 @@ $(npm prefix -g)/bin/reddit-mcp-buddy
482
671
  Reddit MCP Buddy includes intelligent caching to improve performance and reduce API calls:
483
672
 
484
673
  - **Memory Safe**: Hard limit of 50MB - won't affect your system performance
485
- - **Per-Content TTLs**: Post details (10min), user profiles (15min), search results (10min); subreddit listings use the mode default (15min anonymous, 5min with credentials)
674
+ - **Per-Content TTLs**: Post details (10min), user profiles (15min), search results (10min); subreddit listings use the mode default (5min with credentials)
486
675
  - **LRU Eviction**: Automatically removes least-used data when approaching limits
487
676
  - **Hit Tracking**: Optimizes cache based on actual usage patterns
488
677
 
@@ -511,15 +700,12 @@ npm run test:rate-limit:anon # Test anonymous mode (10 rpm)
511
700
  npm run test:rate-limit:app # Test app-only mode (60 rpm)
512
701
  npm run test:rate-limit:auth # Test authenticated mode (100 rpm)
513
702
 
514
- # Lint
515
- npm run lint
516
-
517
703
  # Type check
518
704
  npm run typecheck
519
705
  ```
520
706
 
521
707
  ### Requirements
522
- - Node.js >= 18.0.0
708
+ - Node.js >= 20.0.0
523
709
  - npm or yarn
524
710
  - TypeScript 5.5+
525
711
 
@@ -572,4 +758,4 @@ MIT - Use it however you want!
572
758
 
573
759
  Made with ❤️ for the MCP community. No venture capital, no tracking, just a good MCP server.
574
760
 
575
- Built by [Karan Bansal](https://karanbansal.in) (Head of AI at ArmorCode). I write about Claude Code, MCP, and production agentic AI at [karanbansal.in/blog](https://karanbansal.in/blog/).
761
+ Built by [Karan Bansal](https://karanbansal.in) (Head of AI at ArmorCode). I write about Claude Code, MCP, and production agentic AI at [karanbansal.in/blog](https://karanbansal.in/blog/).