Skip to main content
Glama
reddit-readonly-mcp

reddit-readonly-mcp

by bestnite

English | 简体中文

reddit-readonly-mcp

An unofficial Model Context Protocol (MCP) server designed to fetch public Reddit content reliably from datacenter and VPS IPs without any Reddit API credentials or user accounts.

By emulating Reddit's official Android application token exchange (based on the technique from redlib), reddit-readonly-mcp acquires anonymous application-only tokens to query oauth.reddit.com directly with high resilience.


✨ Features

  • 🔑 Zero Credentials Required: No Reddit Developer app approval, API secrets, or account credentials required.

  • 🌐 VPS & Datacenter Friendly: Listings, subreddit metadata, user feeds and single posts keep working from cloud IPs, where Reddit's anonymous JSON endpoints return 403.

  • 💬 GraphQL for comments, search and profiles: Reddit closed the anonymous REST comment, search and profile endpoints in October 2026, so those tools use the persisted operations the official Android app calls on gql-fed.reddit.com.

  • 🛡️ Strictly Read-Only & Privacy-First: Queries public data exclusively; contains zero write paths or credential-handling logic.

  • 🔄 3-Tier Resilient Fallback: Automatic cascade: Mobile Token → Installed Client Token → RSS Fallback.

  • ⚡ Smart Rate-Limit & Token Rollover: Proactively rotates tokens when remaining requests drop to $\le 5$, handles 429 backoff gracefully, and caches responses via an in-memory LRU cache.

  • 🔌 Dual Transports: Ready for both stdio (local MCP clients like Claude Desktop, Cursor, Hermes) and streamable HTTP (remote/container environments).

Upstream status (November 2026). Reddit is moving to a logged-in-only experience (announcement, Q3'26 shareholder letter). Anonymous tokens can still read listings, subreddit metadata, user feeds and single posts (via /by_id); comments, search and user profiles are served by the GraphQL channel described below instead of the REST endpoints, which now answer HTTP 403. The GraphQL persisted-query hashes are an external dependency that Reddit can change at any time, so treat this as a moving target.


Related MCP server: Reddit Buddy MCP

🚀 Quick Start

Prerequisites

1. Run it

Published on npm as reddit-readonly-mcp:

npx -y reddit-readonly-mcp          # stdio, what MCP clients launch

Or install it globally:

npm i -g reddit-readonly-mcp
reddit-readonly-mcp

Or run the latest main from the Gitea repository:

npx --allow-git=all -y "git+https://git.nite07.com/nite/reddit-readonly-mcp.git"

2. Configure Your MCP Client

Standard MCP Client Configuration (stdio)

Add this to your MCP configuration file (e.g. claude_desktop_config.json or Cursor mcp.json):

{
  "mcpServers": {
    "reddit": {
      "command": "npx",
      "args": ["-y", "reddit-readonly-mcp"]
    }
  }
}

Hermes Agent (~/.hermes/config.yaml)

mcp_servers:
  reddit:
    command: npx
    args:
      - "-y"
      - reddit-readonly-mcp

Streamable HTTP Mode

For Docker, MetaMCP, or remote gateway deployments:

npx -y reddit-readonly-mcp --http --port 3000 --host 127.0.0.1
  • Endpoint: http://127.0.0.1:3000/mcp

  • Health check: GET http://127.0.0.1:3000/health

  • Note: The HTTP server binds to 127.0.0.1 by default and enforces Host-header validation to prevent DNS rebinding. It has no built-in authentication; place it behind a secure proxy if exposing externally.

3. From Source (development)

git clone https://git.nite07.com/nite/reddit-readonly-mcp.git
cd reddit-readonly-mcp
npm install && npm run build
node dist/cli.js

The compiled entry point is dist/cli.js.


🛠️ Available Tools

The server provides 12 strictly read-only tools (annotated with readOnlyHint: true). Output fields are sanitized and trimmed (id, title, author, subreddit, score, created timestamp, permalink, truncated selftext/body) instead of returning raw Reddit JSON dumps.

Posts & Feeds

Tool

Description

Key Arguments

browse_subreddit

Browse subreddit feeds sorted by hot, new, top, rising, or controversial. (Works over RSS)

subreddit?, sort, time_filter, limit, after

get_top_posts

Get top posts of a subreddit or the front page over a time window. (Works over RSS)

subreddit?, time_filter (day, week, month, year, all), limit, after

get_reddit_post

Retrieve full details of a single post.

id (base36 ID, t3_ fullname, or permalink URL)

get_trending_subreddits

List currently popular subreddits (/subreddits/popular).

limit, after

Comments & Discussions

Tool

Description

Key Arguments

get_post_comments

Retrieve a structured nested comment tree, with after pagination over top-level comments.

post_id, sort (confidence, top, new, etc.), limit, depth, after

How comments are fetched (October 2026 change). Reddit now answers the anonymous REST comment endpoints (/r/<sub>/comments/..., /comments/..., /api/info, /api/morechildren) with an HTML 403 page, and the %2F path-encoding workaround that redlib shipped in v0.40.0 stopped working within two weeks. This server therefore reads comments through the same persisted GraphQL operation the official Android client uses (POST https://gql-fed.reddit.com/, operationName: PostComments), with the same anonymous token and device headers. A single request returns at most 200 comments; pass the returned after cursor to page through top-level comments and raise limit/depth to see more replies. Collapsed branches are still listed as more stubs (parent_id, count) and cannot be expanded individually.

Tool

Description

Key Arguments

search_reddit

Search posts, subreddits or users through Reddit's Android GraphQL search API (the REST /search endpoint now answers 403). Supports Reddit search operators.

query (or q), subreddit?, sort, time_filter, type (link, sr, user), limit, after (opaque cursor)

Community & Users

Tool

Description

Key Arguments

get_subreddit_info

Fetch subreddit metadata, description, subscriber count, and settings.

subreddit

get_subreddit_rules

Fetch community rules and submission guidelines.

subreddit

get_user_info

Fetch a user's public profile through GraphQL: name, id, creation time, total karma, avatar, description. The post/comment karma split and account flags are not exposed by this channel.

username

get_user_posts

List public posts submitted by a user.

username, sort, time_filter, limit, after

get_user_comments

List public comments authored by a user.

username, sort, time_filter, limit, after

Diagnostics

Tool

Description

Key Arguments

doctor

Inspect active auth backend, degradation status, token expiration, remaining rate-limits, and cache statistics.

None


⚙️ Architecture & Fallback Cascade

reddit-readonly-mcp utilizes a multi-tiered failover pipeline to maintain high availability:

[Request]
   │
   ▼
1. Mobile OAuth Token ──── (5 consecutive failures) ───► 2. Installed Client Grant
   │ (Default: auth/v2/oauth/access-token/loid)                 │
   │                                                            ▼ (5 consecutive failures)
   └─────────────────────────────────────────────────────► 3. Public RSS Fallback
                                                                (browse_subreddit & get_top_posts)
  1. Mobile Token (mobile): Emulates Reddit's Android application handshake with random real device characteristics, acquiring a 24-hour bearer token.

  2. Installed Client Token (installed): Automatically activates if the mobile token endpoint experiences 5 consecutive failures.

  3. RSS Fallback (rss): Emergency read-only mode for feeds (browse_subreddit and get_top_posts) if OAuth endpoints are unreachable.

  4. Auto-Recovery: The server checks primary backends every 30 minutes and automatically restores higher-tier access once available.

GraphQL channel (comments, search, profiles)

Reddit closed the anonymous REST comment, search and profile endpoints in October 2026, so those three tools talk to POST https://gql-fed.reddit.com/ with the Android app's persisted operations:

Tool

Operation

get_post_comments

PostComments (post metadata still comes from /by_id/t3_<id>)

search_reddit (type: link / sr / user)

SearchPosts / SearchCommunities / SearchPeople

get_user_info

ProfileDetailsByName + a SearchPeople exact-name match for karma

They reuse the same anonymous token, device headers and rate-limit handling: on 401 the token is refreshed once, on 429 it is rolled over and the request retried once, and identical requests are cached. Responses are converted back into Reddit's JSON shapes before trimming, so the tool output format is unchanged; doctor reports the channel under graphql_backend. The persisted-query hashes come from Amqx/reddit-gql and are an external dependency.

Token & Rate-Limit Management

  • Proactive Token Refresh: Automatically renews the OAuth token 2 minutes prior to expiration.

  • Quota Rollover: Monitors x-ratelimit-remaining; rolls over to a clean token window when remaining requests drop to $\le 5$.

  • Backoff & Retries: Handles HTTP 429 by triggering token rollover followed by exponential retry respecting Retry-After.

  • In-Memory Cache: Bounded LRU cache reduces redundant upstream calls.


🔧 Environment Variables

All configuration is optional. No credential variables (client secret, password, etc.) exist or are accepted.

Variable

Default

Description

REDDIT_AUTH_MODE

auto

Backend mode: auto (cascade enabled), mobile, installed, or rss.

REDDIT_MOBILE_CLIENT_ID

ohXpoqrZYub1kg

Android client ID override point if upstream revokes the default constant.

REDDIT_CACHE

on

In-memory read cache (on / off).

REDDIT_CACHE_MAX_MB

50

Maximum memory limit for LRU cache in megabytes.

REDDIT_MAX_RETRIES

3

Maximum retry attempts upon encountering HTTP 429 rate limits.

REDDIT_TIMEOUT_MS

20000

HTTP request timeout in milliseconds.

REDDIT_LOG_LEVEL

info

Logging verbosity to stderr: debug, info, warn, error, silent.


📋 Scope & Design Boundaries

  • Read-Only by Design: Write actions (submitting posts, comments, voting, private messages) are intentionally excluded. They require user-specific OAuth scopes and accounts, which are out of scope.

  • Public Data Only: Private subreddits, banned users, and authenticated user endpoints (e.g. saved items, inbox) are not accessible.

  • Comments, search and profiles depend on internal endpoints: those three tools use the Android app's GraphQL persisted operations, which are not a documented public API. If Reddit changes a query hash or starts requiring a session there, the affected tool fails with a clear error instead of silently falling back to a blocked REST route.

  • Known anonymous refusals (November 2026): the REST comment endpoints, /search and /user/<name>/about return HTTP 403 to anonymous tokens; the server routes those features through GraphQL instead. The GraphQL profile channel exposes total karma only (no post/comment split and no account flags).


🧪 Development & Testing

# Build TypeScript to dist/
npm run build

# Type check
npm run typecheck

# Unit tests (mocked, offline)
npm test

# Protocol wire verification (stdio & HTTP check)
npm run wire

# Live integration test against real Reddit endpoints
npm run smoke

As of November 2026 the live smoke test passes against real Reddit: all 12 tools, including search_reddit, get_user_info and get_post_comments, go through the GraphQL channel where the REST endpoints are refused.


📄 License

MIT.

Credits

  • Android device metadata in src/auth/android-app-versions.ts is sourced from redlib (MIT).

  • The GraphQL persisted-operation names, sha256 hashes and variable shapes used for comments, search and user profiles (PostComments, SearchPosts, SearchCommunities, SearchPeople, ProfileDetailsByName) were taken from Amqx/reddit-gql (GPL-3.0). Only those protocol identifiers and observed variable shapes are used; no code from that project is copied into this repository.

Available Tools

12 tools
browse_subredditBrowse SubredditA
Read-only

Browse a subreddit feed sorted by hot/new/top/rising/controversial. Read-only, anonymous. Returns {"data": [...], "after": cursor|null}. Also works in RSS fallback mode for hot/new/top/rising (max ~25 posts, no score/comment counts, no pagination).

Inputs: sort, after, limit, subreddit, +1 more.

doctorDoctor (diagnostics)A
Read-only

Diagnostics, no arguments: which read backend is live (mobile / installed / rss), whether it has degraded, token expiry, Reddit rate-limit remaining/reset, and cache/request stats. Call this first when other tools fail.

Inputs: no named parameters.

get_post_commentsGet Post CommentsA
Read-only

The comment tree of a post. Returns {"post": {...}, "data": [comments with nested "replies"], "more": [stubs], "after": null}. Collapsed branches are listed in "more" (parent_id, count, children ids) and counted on the parent comment as "more_replies". These "more" stubs CANNOT be expanded by this server: Reddit answers /api/morechildren with HTTP 403 for anonymous tokens, so do not expect a follow-up call to retrieve them. To see more of a thread, call get_post_comments again with a larger limit/depth or a different sort. Read-only, anonymous.

Inputs: post_id (required), sort, depth, limit, +1 more.

get_reddit_postGet Reddit PostA
Read-only

Fetch a single Reddit post by id: title, author, subreddit, score, comment count, created time, permalink, link URL and body text (truncated if very long). Read-only, anonymous. Use get_post_comments for the discussion.

Inputs: post_id (required), subreddit.

get_subreddit_infoGet Subreddit InfoB
Read-only

Subreddit metadata: title, public description, subscribers, active users, creation time, NSFW flag, submission type. Read-only, anonymous.

Inputs: subreddit_name (required).

get_subreddit_rulesGet Subreddit RulesB
Read-only

The posting rules of a subreddit (short name, description, which content kinds they apply to). Read-only, anonymous.

Inputs: subreddit_name (required).

get_top_postsGet Top PostsA
Read-only

Top posts of a subreddit (or the anonymous front page) over a time window (default week). Read-only, anonymous. Returns {"data": [...], "after": cursor|null}. Also works in RSS fallback mode (max ~25 posts, no score/comment counts, no pagination).

Inputs: after, limit, subreddit, time_filter.

get_user_commentsGet User CommentsA
Read-only

Comments written by a user, with the title of the post each one belongs to. Read-only, anonymous. Returns {"data": [...], "after": cursor|null}.

Inputs: username (required), sort, after, limit, +1 more.

get_user_infoGet User InfoA
Read-only

Public profile of a Reddit user: karma, account creation time, employee/mod/verified flags, profile description. Read-only, anonymous; private account data is never available.

Inputs: username (required).

get_user_postsGet User PostsA
Read-only

Posts submitted by a user. Read-only, anonymous. Returns {"data": [...], "after": cursor|null}.

Inputs: username (required), sort, after, limit, +1 more.

search_redditSearch RedditA
Read-only

Search Reddit posts (or subreddits/users via 'type'), optionally restricted to one subreddit. Read-only, anonymous. Returns {"data": [...], "after": cursor|null}.

Inputs: q, sort, type, after, +4 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 12 tools

    Disambiguation4/5

    Most tools target clearly different resources (posts, comments, subreddits, users), so an agent can usually select without confusion. However, get_top_posts and browse_subreddit both return subreddit post feeds, and get_subreddit_info and get_subreddit_rules both return subreddit metadata, creating minor overlap.

    Naming Consistency4/5

    All names use snake_case with predictable verb prefixes like get_, browse_, and search_, making the pattern easy to follow. The lone exception is 'doctor', which lacks a verb_noun structure, though its diagnostic purpose is clear.

    Tool Count5/5

    With 12 tools, the surface is well-scoped for a read-only Reddit client; each tool maps to a distinct read operation and none feels redundant or gratuitous. The count sits comfortably in the ideal 3–15 range.

    Completeness4/5

    The server covers core read-only workflows: browsing and searching posts, fetching comments, viewing subreddit metadata and rules, and inspecting user profiles, posts, and comments, plus diagnostics. Minor gaps like wiki pages or post awards exist, but they are outside the core scope and the comment-expansion limitation is explicitly documented.

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Provides AI assistants with read-only access to Reddit's API for browsing subreddits, reading posts and comments, searching Reddit, and retrieving user/subreddit information. Enables safe exploration of Reddit content without posting capabilities through natural language interactions.
      -
    • A
      license
      A
      quality
      A
      maintenance
      Enables AI assistants to browse Reddit, search posts, analyze user activity, and fetch comments without requiring API keys. Features smart caching, clean data responses, and optional authentication for higher rate limits.
      5
      4,436 npm
      890
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Provides AI assistants with access to Reddit data for searching, browsing subreddits, and retrieving post details or user activity without requiring API keys. It enables tools to fetch content, nested comment trees, and public user feeds directly through the Model Context Protocol.
      6
      381 PyPI
      167
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables searching Reddit posts, fetching subreddit content, and retrieving post comments without requiring an API key. It uses public JSON endpoints to provide seamless access to Reddit data for LLM-based applications.
      3 npm
      MIT