reddit-research-mcp
Provides read-only tools for researching Reddit, including searching posts, browsing and discovering subreddits, reading full threads and hidden comments, accessing subreddit rules and wikis, inspecting user activity, and finding crossposts or other discussions of links.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@reddit-research-mcpsearch Reddit for the best budget mechanical keyboards"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
reddit-readonly-mcp
A read-only Model Context Protocol server for researching Reddit. It lets an MCP client such as Claude Code or Claude Desktop search posts, browse and discover communities, read whole threads including the comments Reddit hides behind "load more" links, read subreddit rules and wikis, and check who is posting.
It never posts, votes, edits or deletes anything. Every tool is marked read-only, and every
Reddit API request it sends is a GET (the only other request is the OAuth token fetch).
Why not the client's built-in web search or fetch? This server calls Reddit's API, so results come back as compact text with stable ids, dates, scores and comment counts, filters by subreddit, sort and time window, and a coverage line that says how much of a thread the model has read and how to load the rest.
The command and package are called reddit-readonly-mcp (renamed from reddit-research-mcp, which still works as an alias so existing setups keep running).
Example prompts
"What do data engineers on Reddit say about migrating from Hive to Iceberg? Read the most discussed threads, including the comments, and tell me where opinions split."
"Find communities about Kubernetes cost optimization, check their rules, and summarise the top posts of the last year."
"Has anyone discussed this article on Reddit? Read the threads and list the objections."
Related MCP server: Reddit MCP Server
Highlights
Ten tools covering search, browsing, community discovery, full threads, hidden-comment expansion, bulk post bodies, user history and "other discussions" of a link.
Thread coverage is explicit: every "load more" stub that fits the response budget is listed with its comment ids, and each thread ends with
Shown X of Y comments; ~Z more in N stubs -> expand_comments(...). When the budget cuts comments, the line says how many stubs sit inside them and lists the cut comments' ids instead.Compact text output: one header line per item with id, subreddit, UTC date, score, upvote ratio, comment count, author, flair, post type and flags. Every response has a size budget and says how to get the rest when it is cut.
Accepts the identifiers people paste: post ids,
t3_fullnames, reddit.com and old.reddit.com permalinks, comment permalinks, redd.it links,r/name,u/name.Errors say what went wrong and what to do next, for example
r/dremio does not exist or is private; use search_subreddits to find the right name; similar names: r/dremio_lakehouse.NSFW (18+) posts, comments and communities are hidden by default; every tool takes
include_nsfw=trueto show them, and a server setting can block them outright.Works without credentials. Optional Reddit app credentials give the server its own quota.
Never stalls a tool call on rate limits: short waits (up to 15 s) are absorbed, longer ones fail fast with
Reddit rate limit reached; retry after N s. Every tool call ends within 45 s.
Requirements
uv (provides
uvx). Python 3.11 or newer is fetched by uv if needed.
Install
Claude Code
claude mcp add --scope user reddit -- uvx --from git+https://github.com/jordanallenlewis/reddit-research-mcp reddit-readonly-mcpWith your own Reddit app credentials (see Authentication):
claude mcp add --scope user reddit \
-e REDDIT_CLIENT_ID=your_client_id -e REDDIT_CLIENT_SECRET=your_client_secret \
-- uvx --from git+https://github.com/jordanallenlewis/reddit-research-mcp reddit-readonly-mcpClaude Desktop
Add this to claude_desktop_config.json (Settings, Developer, Edit Config) and restart the app:
{
"mcpServers": {
"reddit": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/jordanallenlewis/reddit-research-mcp",
"reddit-readonly-mcp"
],
"env": {}
}
}
}If the app cannot find uvx, use its full path (which uvx, often ~/.local/bin/uvx).
Put REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET in env to use your own app.
Other MCP clients
The server speaks MCP over stdio by default. Run it with:
uvx --from git+https://github.com/jordanallenlewis/reddit-research-mcp reddit-readonly-mcpFor clients that connect over HTTP, serve streamable HTTP instead. It binds to 127.0.0.1 unless you pass --host, and the endpoint is http://127.0.0.1:8000/mcp:
uvx --from git+https://github.com/jordanallenlewis/reddit-research-mcp reddit-readonly-mcp --transport http --port 8000There is no authentication on the HTTP endpoint, so only bind it to an address you trust.
From a local checkout
git clone https://github.com/jordanallenlewis/reddit-research-mcp
cd reddit-research-mcp
uv sync
uv run reddit-readonly-mcp --version
claude mcp add --scope user reddit -- uv run --directory "$PWD" reddit-readonly-mcpTools
Tool | What it does | Reddit requests |
| Search post titles and bodies, site-wide or in | 1 |
|
| 1 |
| Find communities by description, plus names that start with the query, with subscribers, NSFW flag, creation date and description. | 1 to 3 |
| Size, age, type, description, rules, sidebar and wiki page list. For a private or Premium-only community it shows the public listing data and says what needs membership. | 1 to 3 |
| Read a wiki page (FAQs, guides), or list pages with | 2 (1 with |
| The post and its comment tree in one request, with the "more" stubs and a coverage line. The body shows its first 6,000 characters by default so long posts leave room for comments; | 1 (2 when a |
| Load the comments behind "more" stubs, as reply trees. Up to 500 ids per call; the rest are listed for the next call. | 1 per 100 ids, plus 1 for the NSFW check unless |
| Full headers and bodies of many posts at once (no comments). Up to 300 posts per call; the rest are listed. An entry that is not a post id or link is skipped and listed, and the valid ones are still read. | 1 per 100 posts |
| Account age and karma, recent posts and comments, and which subreddits the activity is concentrated in (from the last 100 items, whatever | 2 |
| Crossposts and other submissions of a post's link, or every thread that submitted an external URL. | 1 to 2 |
Every tool also takes include_nsfw=False (see NSFW content); it is left out of
the signatures above.
Numeric arguments are clamped to the ranges the tool descriptions state (for example limit 1 to
100, comment_limit 1 to 500, comment_depth 1 to 10), and the output says when a value was
clamped. Text arguments have limits too: search queries up to 512 characters, find_other_discussions
URLs up to 2,048, and at most 50 subreddits in one a+b list. Anything longer is refused with a
message that says so and no request is sent. A refused argument is quoted back in the error only in
shortened form.
get_posts and expand_comments send one progress update per Reddit request when the client asks for progress and the call needs more than one request.
Prompt
The server also offers one MCP prompt, reddit_research(question). It walks the assistant through a cited research pass: find the communities, check their rules, search, read the most discussed threads, check who is talking, and write findings grouped by theme where every claim quotes a comment with its author, subreddit, score and permalink. In Claude Code it shows up as a slash command.
Output format
A listing item looks like this:
[1abc234] r/dataengineering 2024-10-02 31(91%) 54c u/example_author [Discussion] self edited
Title of the post
First 400 characters of the body ... [+1234 chars]That is: [id] r/subreddit date score(upvote ratio) comments author [flair] type flags.
Types are self, link, image, video, gallery, poll and crosspost. Flags are nsfw,
spoiler, pinned, locked, deleted or removed(...), edited, mod (or admin),
score-hidden and, in get_post/get_posts, archived. score-hidden means the subreddit
hides the score of new posts on its site; the API still returns it, and the number shown is that
value. A score of ? means Reddit sent none (comments with hidden scores). Link posts add a
url: line, galleries an item count, polls their options, crossposts the original post id and
subreddit. Listings end with next: after=<cursor> or next: none (end of results).
Comments in get_post are indented by depth:
[k2x9a1b] 2024-10-03 12 u/example_user (OP) (edited) [flair text]
Comment body
[k2x9c3d] 2024-10-03 4 u/another_user
Reply body
[more: 7 comments; ids: k2xa001,k2xa002]
[k2x9z9z] 2024-10-04 [removed]
[more top-level: 1,552 comments; 540 ids: ...]
Shown 180 of 2,849 comments; ~2,669 more in 45 stubs -> expand_comments(post="1abc234", comment_ids=[ids from the [more ...] lines])
[1 Reddit request, 0.6 s]Stub counts carry a ~ because Reddit counts removed comments in them, so shown plus stub
comments can add up to slightly more than the thread's comment count.
When max_chars cuts the thread, stubs inside the comments that were not shown cannot be listed.
The coverage line then splits the count, for example
~2,468 more in 336 stubs: 50 stubs listed with ids -> expand_comments(...); 286 stubs (~1,268 comments) inside the loaded comments not shown, ids not listed,
and the next line (Output budget reached: 40 loaded comments in 12 threads not shown) lists
the top id of each cut thread, which expand_comments accepts too. Loaded comments take
priority over stub id lists, so a small max_chars shortens the id lists first. Raising
max_chars or lowering body_chars shows more in one call.
expand_comments reports any requested id Reddit did not return, grouped by reason, for
example Not returned (2): removed: pc1uss9; not found: abc1234.
Every result ends with a line such as [2 Reddit requests, 0.4 s]. The count is that call's own requests, even when several tool calls run at once.
A comment's permalink is the post permalink plus the comment id; the thread header prints the template once instead of repeating it on every comment.
NSFW content
Every tool takes include_nsfw (default false). With the default:
Posts, comments and crossposts that Reddit marks 18+ (
over_18), and communities marked 18+ (over18), are removed before formatting. Search and community search do not request them (include_over_18is sent only when NSFW is allowed).Each result says how many items were hidden, for example
25 posts (3 NSFW posts hidden; include_nsfw=true shows them).get_post,expand_comments,get_subreddit_info,get_subreddit_wikiandfind_other_discussionson an 18+ post or community return a short notice instead of the content.get_postslists the hidden ids.get_user_activityleaves 18+ items out of the listing and the subreddit summary, and hides the profile description of an 18+ profile.Community name suggestions (in errors and
search_subreddits) are checked first, because Reddit's name lookup returns 18+ communities; names whose status cannot be checked are not shown.
Pass include_nsfw=true to show everything. Set REDDIT_RESEARCH_MCP_BLOCK_NSFW=1 (true, yes and on also work) in the
server's environment to keep NSFW hidden whatever the tool call asks:
claude mcp add --scope user reddit -e REDDIT_RESEARCH_MCP_BLOCK_NSFW=1 \
-- uvx --from git+https://github.com/jordanallenlewis/reddit-research-mcp reddit-readonly-mcpThe filter relies on Reddit's own 18+ flags. Posts that Reddit does not flag, in communities that are not marked 18+, are shown.
Search tips
Reddit's search is loose. Unquoted multi-word queries match posts containing any of the words
and rank by popularity, so dremio reflections tips returns unrelated posts about game
graphics and tipping. What works:
Use one to three specific words and drop generic ones such as tips, best or help.
Quote the rare or exact term:
"dremio" reflections.Require terms with
AND:dremio AND iceberg.Field operators:
subreddit:dataengineering,flair:Discussion,title:benchmark,selftext:kubernetes,author:name, and-subreddit:nameto exclude a community. Product names attract job-bot spam;-subreddit:jobboardsearchremoves most of it.Search several communities in one call with
subreddit="dataengineering+dremio_lakehouse".Reddit's API cannot search comment text. To find advice inside threads, search with
sort="comments"(most discussed), then read the threads withget_postand expand stubs.Not sure of a community name?
search_subredditsmatches descriptions and name prefixes.
Authentication
Variables set | Mode |
none | Anonymous. Uses the public installed-app client id that ships with the redditwarp library. No account needed. |
| App-only OAuth (client credentials). Gives the server its own rate-limit quota. |
both of the above and | User OAuth with a refresh token issued to that app. |
Any other combination (for example a client id without a secret) is a configuration error. The server still starts, logs the problem to stderr, and every tool call returns the message.
To create credentials, sign in at https://www.reddit.com/prefs/apps, choose "create another
app", pick the "script" type, and use the string under the app name as REDDIT_CLIENT_ID and
the "secret" as REDDIT_CLIENT_SECRET.
Anonymous mode shares one public client id, and therefore one rate-limit quota, with every other
installation of this server (and of anything else using that id) worldwide. Anyone installing this
for a team should create their own app and set REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET.
Reddit's Data API terms apply to your use of Reddit data through this server; read them before
you rely on it.
Other settings:
Variable | Default | Purpose |
|
| User-Agent sent to Reddit. Reddit asks for a descriptive one that names you. |
|
| Set |
| unset | Set |
Rate limits
Reddit allows about 100 requests per minute per OAuth client, counted over a 10-minute window (1,000 requests per 600 s). In anonymous mode the client id is shared with other installations worldwide, so the window can already be partly used when the server starts; set your own credentials (see Authentication) for a team or for heavy use.
The server reads Reddit's x-ratelimit-* headers on every response. When the window is used
up it waits if the reset is at most 15 s away and otherwise fails at once with
Reddit rate limit reached; retry after N s. A 429 response is retried once when
Retry-After is at most 15 s. Network errors and 5xx responses are retried once after 1 s.
A request times out after 15 s, and its retry after 10 s, so a dead network fails a request in
about 26 s. Tools that send several requests (get_posts, expand_comments) start no new batch
after 15 s and list what they did not fetch, and every tool call is cut off after 45 s with an
error. Comment expansion calls are sent one at a time, as Reddit requires.
Troubleshooting
Message | Meaning and fix |
| Reddit redirected the name to its search page. Check the spelling or call |
| The community cannot be read with this server's access. |
| Use |
| Deleted, removed or a wrong id. Pass the |
| The |
| Wait, or set your own |
| Connectivity problem or a slow Reddit; it was already retried once. |
| Reddit was too slow for the whole call (including rate-limit waits). Retry later or ask for less. |
| Reddit refused the anonymous token. Retry later or configure your own app. |
| Fix the |
HTML | Reddit may be blocking the network or user agent. Set credentials and a descriptive |
| The checkout is in a folder synced by iCloud Drive (such as Desktop or Documents). iCloud marks files inside |
Reddit content is untrusted user-generated text. The server returns it verbatim as data; the client and model should treat it as material to evaluate, not as instructions.
Development
uv sync # create the environment with dev dependencies
uv run pytest -q # offline tests with synthetic fixtures
uv run ruff check . # lint (settings in pyproject.toml)
uv run python scripts/smoke.py # live end-to-end check over stdio, about 30 requestsscripts/smoke.py starts the server as a subprocess, runs initialize and tools/list, calls
every tool against live Reddit, and prints latency, output size and Reddit request count per
call. Pass --server-cmd to test another command, such as the uvx install.
Code layout:
src/reddit_research_mcp/server.py: tool definitions and error messages.src/reddit_research_mcp/reddit.py: HTTP, OAuth (via redditwarp), rate limiting, retries.src/reddit_research_mcp/format.py: text rendering of posts, comments and listings.src/reddit_research_mcp/refs.py: parsing of ids, URLs, subreddit and user names.
redditwarp is used for OAuth token handling and the HTTP transport only. Endpoints are called directly and their JSON parsed here, because redditwarp 1.3.0's model loaders fail on some current API responses.
Credits
Started from adhikasp/mcp-reddit (MIT), which exposed hot threads and single posts. This project rewrites it with the tools above.
License
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Reddit MCP server: search posts, subreddit feeds, comments & user profiles as JSON. No API key.
Search public Reddit posts, browse subreddit feeds, and read posts, comments, and profiles.
Reddit API as MCP tools: search, subreddits, posts, comments, users, monitors, webhooks, feedback.
Read-only Reddit search API for AI agents: posts, comments, comment trees, subreddit rules.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables fetching and reading Reddit content such as posts, comments, and subreddit listings via the MCP protocol.5 npmMIT
- AlicenseNot gradedqualityDmaintenanceProvides read-only access to Reddit through 8 tools for searching, browsing, and retrieving posts, comments, and user data, compatible with any MCP client.MIT
- FlicenseNot gradedqualityCmaintenanceMCP server for researching community discussions, with a focus on Reddit. It enables searching Reddit posts and reading threads/comments, providing structured JSON output for LLM consumption.-
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to scan, search, and read Reddit posts and comments using Reddit's public JSON endpoints, with no API credentials required.5 npmMIT