Skip to main content
Glama
sunil-gumatimath

reddit-mcp

README.md
# Local Reddit MCP

[![CI](https://github.com/sunil-gumatimath/reddit-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/sunil-gumatimath/reddit-mcp/actions/workflows/ci.yml)
[![License: Unlicense](https://img.shields.io/badge/license-Unlicense-blue.svg)](LICENSE)
[![Node](https://img.shields.io/badge/node-%E2%89%A522.9.0-brightgreen)](https://nodejs.org)

A local, single-user, read-only Reddit MCP (Model Context Protocol) server. It exposes five tools that retrieve public Reddit content through the official Reddit Data API with OAuth 2.0. Retrieved content is cached locally in SQLite with full-text search and TTL expiry.

## Key properties

- **Read-only**: No write actions to Reddit. No scraping. Uses the official Reddit Data API.
- **Local & single-user**: Runs on your machine via stdio. No remote HTTP transport.
- **Privacy-conscious**: Secrets stored in OS-backed encrypted storage (Windows DPAPI). No secrets in logs, commits, or tool results. Cache is local and purgeable.
- **Bounded**: Every tool enforces input/output caps. No arbitrary URL fetching.
- **Honest**: Deleted, restricted, and NSFW content represented honestly. Every result carries provenance, timestamps, expiry, stale flag, and truncation markers.
- **Secure**: SSRF prevention via host allowlist. Rate-limit handling with backoff. Circuit breaker. Untrusted content marked.

## Tools

1. `search_reddit` — search public posts/subreddits by query with bounded pagination
2. `get_post` — retrieve a single post by ID or permalink
3. `get_post_comments` — retrieve comments for a post with bounded depth/count
4. `get_subreddit_info` — retrieve subreddit metadata
5. `get_user_content` — retrieve a user's public posts/comments with bounds

## Prerequisites

- Node.js ≥ 22.9.0 (requires the built-in `node:sqlite` module and the `--env-file-if-exists` flag)
- A Reddit developer application (<https://www.reddit.com/prefs/apps>) with OAuth credentials

## Quick start

```bash
npm install
cp .env.example .env    # then add your Reddit credentials
npm run build
npm run auth -- login   # complete OAuth in browser
npm run start           # start MCP stdio server
```

## MCP client configuration

Add the server to your MCP client configuration, e.g.:

```json
{
  "mcpServers": {
    "reddit": {
      "command": "node",
      "args": ["/path/to/RedditMCP/dist/index.js"],
      "env": {
        "REDDIT_CLIENT_ID": "your_client_id",
        "REDDIT_REDIRECT_URI": "http://127.0.0.1:8888/callback",
        "REDDIT_USER_AGENT": "RedditMCP/1.0 (by your_username)",
        "CACHE_DB_PATH": "./data/reddit-cache.db"
      }
    }
  }
}
```

Store `REDDIT_CLIENT_SECRET` in your MCP client's secure/secret mechanism rather than committing it or placing it in a shared config file.

## Environment variables

| Variable                    | Required | Default                          | Description                              |
| --------------------------- | -------- | -------------------------------- | ---------------------------------------- |
| `REDDIT_CLIENT_ID`          | yes      | —                                | Reddit app client ID                     |
| `REDDIT_CLIENT_SECRET`      | no       | —                                | Reddit app secret; empty = PKCE flow     |
| `REDDIT_REDIRECT_URI`       | yes      | `http://127.0.0.1:8888/callback` | Loopback redirect URI                    |
| `REDDIT_USER_AGENT`         | yes      | —                                | Descriptive User-Agent (Reddit requires) |
| `CACHE_DB_PATH`             | no       | `./data/reddit-cache.db`         | SQLite cache location                    |
| `CACHE_TTL_SECONDS`         | no       | `3600`                           | Cache TTL in seconds                     |
| `CACHE_MAX_ITEMS`           | no       | `10000`                          | Max cached items (oldest evicted)        |
| `LOG_LEVEL`                 | no       | `info`                           | Log level                                |
| `HTTP_TIMEOUT_MS`           | no       | `10000`                          | Outbound HTTP timeout                    |
| `HTTP_MAX_RETRIES`          | no       | `3`                              | Retries on transient failures            |
| `CIRCUIT_BREAKER_THRESHOLD` | no       | `5`                              | Failures before circuit opens            |
| `MAX_REQUESTS_PER_MINUTE`   | no       | `45`                             | Outbound rate limit                      |

## Commands

| Command                  | Description                        |
| ------------------------ | ---------------------------------- |
| `npm run start`          | Start the MCP stdio server         |
| `npm run auth -- login`  | Authenticate with Reddit OAuth     |
| `npm run auth -- status` | Check authentication status        |
| `npm run auth -- logout` | Revoke and delete stored tokens    |
| `npm run doctor`         | Run health checks (config/db/auth) |
| `npm run cache:status`   | Show cache statistics              |
| `npm run cache:purge`    | Purge all cached data              |

The npm scripts load a local `.env` file automatically when run from the project directory.

## Development

```bash
npm run quality       # format check, lint, typecheck, tests, audit
npm test              # unit + integration tests
npm run test:e2e      # end-to-end MCP tests (vitest.e2e.config.ts)
npm run format        # format sources
npm run lint          # eslint
npm run typecheck     # tsc --noEmit
```

CI (`.github/workflows/ci.yml`) runs format check, lint, typecheck, tests, build, e2e tests, and `npm audit` on push/PR to `main`/`master`.

## Documentation

- `docs/install.md` — installation and MCP client setup
- `docs/oauth-setup.md` — OAuth app registration, scopes, and token storage
- `docs/operations.md` — operations, privacy, retention, and troubleshooting
- `docs/decisions.md` — design decisions

## License

MIT

Maintenance

ActivityMaintained
ResponsivenessSyncing