reddit-mcp

Arindam200/reddit-mcp

4.2

reddit-mcp is hosted online, so all tools can be tested directly either in theInspector tabor in theOnline Client.

If you are the rightful owner of reddit-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

This repository contains a Model Context Protocol server implementation for Reddit that allows AI assistants to access and interact with Reddit content through PRAW (Python Reddit API Wrapper).

Try reddit-mcp with chat:

Tools

Functions exposed to the LLM to take actions

get_user_info

Get information about a Reddit user.

Args:
    username: The username of the Reddit user to get info for

Returns:
    Dictionary containing user information with the following structure:
    {
        'username': str,  # User's username
        'created_utc': float,  # Account creation timestamp
        'comment_karma': int,  # User's comment karma
        'link_karma': int,  # User's post/link karma
        'has_verified_email': bool,  # Whether email is verified
        'is_mod': bool,  # Whether user is a moderator
        'is_gold': bool,  # Whether user has Reddit premium
        'has_subscribed': bool,  # Whether user has subscribed to premium
        'is_employee': bool,  # Whether user is a Reddit employee
        'over_18': bool,  # Whether user is marked as NSFW
        'is_suspended': bool,  # Whether account is suspended
        'suspension_expiration_utc': Optional[float],  # When suspension ends if suspended
        'total_karma': int,  # Total karma (comments + posts)
        'subreddit': Optional[Dict],  # User's profile subreddit info if exists
    }

Raises:
    ValueError: If the username is invalid or not found
    RuntimeError: For other errors during the operation

get_top_posts

Get top posts from a subreddit.

Args:
    subreddit: Name of the subreddit (with or without 'r/' prefix)
    time_filter: Time period to filter posts (e.g. "day", "week", "month", "year", "all")
    limit: Number of posts to fetch (1-100)

Returns:
    Dictionary containing structured post information with the following structure:
    {
        'subreddit': str,  # Subreddit name
        'time_filter': str,  # The time period used for filtering
        'posts': [  # List of posts, each with the following structure:
            {
                'id': str,  # Post ID
                'title': str,  # Post title
                'author': str,  # Author's username
                'score': int,  # Post score (upvotes - downvotes)
                'upvote_ratio': float,  # Ratio of upvotes to total votes
                'num_comments': int,  # Number of comments
                'created_utc': float,  # Post creation timestamp
                'url': str,  # URL to the post
                'permalink': str,  # Relative URL to the post
                'is_self': bool,  # Whether it's a self (text) post
                'selftext': str,  # Content of self post (if any)
                'link_url': str,  # URL for link posts (if any)
                'over_18': bool,  # Whether marked as NSFW
                'spoiler': bool,  # Whether marked as spoiler
                'stickied': bool,  # Whether stickied in the subreddit
                'locked': bool,  # Whether comments are locked
                'distinguished': Optional[str],  # Distinguishing type (e.g., 'moderator')
                'flair': Optional[Dict],  # Post flair information if any
            },
            ...
        ],
        'metadata': {
            'fetched_at': float,  # Timestamp when data was fetched
            'post_count': int,  # Number of posts returned
        }
    }

Raises:
    ValueError: If subreddit is invalid or time_filter is not valid
    RuntimeError: For other errors during the operation

get_subreddit_info

Get information about a subreddit.

Args:
    subreddit_name: Name of the subreddit (with or without 'r/' prefix)

Returns:
    Dictionary containing subreddit information

Raises:
    ValueError: If subreddit_name is invalid or subreddit not found
    RuntimeError: For other errors during the operation

get_trending_subreddits

Get currently trending subreddits.

Args:
    limit: Maximum number of trending subreddits to return (1-50)

Returns:
    Dictionary containing list of trending subreddits with their basic info

Raises:
    ValueError: If limit is invalid
    RuntimeError: For errors during the operation

get_subreddit_stats

Get statistics and information about a subreddit.

Args:
    subreddit: Name of the subreddit (with or without 'r/' prefix)

Returns:
    Dictionary containing structured subreddit information with the following structure:
    {
        'id': str,  # Subreddit ID (e.g., '2qgzt')
        'display_name': str,  # Subreddit display name (without r/ prefix)
        'title': str,  # Subreddit title
        'public_description': str,  # Public description
        'description': str,  # Full description (can include markdown)
        'subscribers': int,  # Number of subscribers
        'active_user_count': Optional[int],  # Currently active users if available
        'created_utc': float,  # Creation timestamp (UTC)
        'over18': bool,  # Whether marked as NSFW
        'submission_type': str,  # Allowed submission types (any, link, self)
        'allow_images': bool,  # Whether image uploads are allowed
        'allow_videos': bool,  # Whether video uploads are allowed
        'allow_polls': bool,  # Whether polls are allowed
        'spoilers_enabled': bool,  # Whether spoiler tags are enabled
        'wikienabled': bool,  # Whether wiki is enabled
        'user_is_banned': bool,  # Whether current user is banned
        'user_is_moderator': bool,  # Whether current user is a moderator
        'user_is_subscriber': bool,  # Whether current user is a subscriber
        'mod_permissions': List[str],  # Moderator permissions if applicable
        'metadata': {
            'fetched_at': float,  # Timestamp when data was fetched
            'url': str,  # Full URL to the subreddit
            'moderators_count': int,  # Number of moderators
            'rules': List[Dict],  # Subreddit rules if available
            'features': Dict[str, bool],  # Enabled subreddit features
        }
    }

Raises:
    ValueError: If subreddit is invalid or not found
    RuntimeError: For other errors during the operation

create_post

Create a new post in a subreddit.

Args:
    subreddit: Name of the subreddit to post in (with or without 'r/' prefix)
    title: Title of the post (max 300 characters)
    content: Content of the post (text for self posts, URL for link posts)
    flair: Flair to add to the post. Must be an available flair in the subreddit
    is_self: Whether this is a self (text) post (True) or link post (False)

Returns:
    Dictionary containing information about the created post

Raises:
    ValueError: If input validation fails or flair is invalid
    RuntimeError: For other errors during post creation

reply_to_post

Post a reply to an existing Reddit post.

Args:
    post_id: The ID of the post to reply to (can be full URL, permalink, or just ID)
    content: The content of the reply (1-10000 characters)
    subreddit: The subreddit name if known (for validation, with or without 'r/' prefix)

Returns:
    Dictionary containing information about the created reply and parent post

Raises:
    ValueError: If input validation fails or post is not found
    RuntimeError: For other errors during reply creation

get_submission_by_url

Get a Reddit submission by its URL.

Args:
    url: The URL of the Reddit submission to retrieve

Returns:
    Dictionary containing structured submission information with the following structure:
    {
        'id': str,  # Submission ID (e.g., 'abc123')
        'title': str,  # Submission title
        'author': str,  # Author's username or '[deleted]' if deleted
        'subreddit': str,  # Subreddit name
        'score': int,  # Post score (upvotes - downvotes)
        'upvote_ratio': float,  # Ratio of upvotes to total votes
        'num_comments': int,  # Number of comments
        'created_utc': float,  # Post creation timestamp (UTC)
        'url': str,  # Full URL to the post
        'permalink': str,  # Relative URL to the post
        'is_self': bool,  # Whether it's a self (text) post
        'selftext': str,  # Content of self post (if any)
        'selftext_html': Optional[str],  # HTML formatted content
        'link_url': str,  # URL for link posts (if any)
        'domain': str,  # Domain of the linked content
        'over_18': bool,  # Whether marked as NSFW
        'spoiler': bool,  # Whether marked as spoiler
        'stickied': bool,  # Whether stickied in the subreddit
        'locked': bool,  # Whether comments are locked
        'archived': bool,  # Whether the post is archived
        'distinguished': Optional[str],  # Distinguishing type (e.g., 'moderator')
        'flair': Optional[Dict],  # Post flair information if any
        'media': Optional[Dict],  # Media information if any
        'preview': Optional[Dict],  # Preview information if available
        'awards': List[Dict],  # List of awards received
        'metadata': {
            'fetched_at': float,  # Timestamp when data was fetched
            'subreddit_id': str,  # Subreddit full ID
            'author_id': str,  # Author's full ID if available
            'is_original_content': bool,  # Whether marked as OC
            'is_meta': bool,  # Whether marked as meta
            'is_crosspostable': bool,  # Whether can be crossposted
            'is_reddit_media_domain': bool,  # Whether media is hosted on Reddit
            'is_robot_indexable': bool,  # Whether search engines should index
            'is_created_from_ads_ui': bool,  # Whether created via ads UI
            'is_video': bool,  # Whether the post is a video
            'pinned': bool,  # Whether the post is pinned in the subreddit
            'gilded': int,  # Number of times gilded
            'total_awards_received': int,  # Total number of awards received
            'view_count': Optional[int],  # View count if available
            'visited': bool,  # Whether the current user has visited
        }
    }

Raises:
    ValueError: If URL is invalid or submission not found
    RuntimeError: For other errors during the operation

get_submission_by_id

Get a Reddit submission by its ID.

Args:
    submission_id: The ID of the Reddit submission to retrieve (can be full URL or just ID)

Returns:
    Dictionary containing structured submission information with the following structure:
    {
        'id': str,  # Submission ID (e.g., 'abc123')
        'title': str,  # Submission title
        'author': str,  # Author's username or '[deleted]' if deleted
        'subreddit': str,  # Subreddit name
        'score': int,  # Post score (upvotes - downvotes)
        'upvote_ratio': float,  # Ratio of upvotes to total votes
        'num_comments': int,  # Number of comments
        'created_utc': float,  # Post creation timestamp (UTC)
        'url': str,  # Full URL to the post
        'permalink': str,  # Relative URL to the post
        'is_self': bool,  # Whether it's a self (text) post
        'selftext': str,  # Content of self post (if any)
        'selftext_html': Optional[str],  # HTML formatted content
        'link_url': str,  # URL for link posts (if any)
        'domain': str,  # Domain of the linked content
        'over_18': bool,  # Whether marked as NSFW
        'spoiler': bool,  # Whether marked as spoiler
        'stickied': bool,  # Whether stickied in the subreddit
        'locked': bool,  # Whether comments are locked
        'archived': bool,  # Whether the post is archived
        'distinguished': Optional[str],  # Distinguishing type (e.g., 'moderator')
        'flair': Optional[Dict],  # Post flair information if any
        'media': Optional[Dict],  # Media information if any
        'preview': Optional[Dict],  # Preview information if available
        'awards': List[Dict],  # List of awards received
        'metadata': {
            'fetched_at': float,  # Timestamp when data was fetched
            'subreddit_id': str,  # Subreddit full ID
            'author_id': str,  # Author's full ID if available
            'is_original_content': bool,  # Whether marked as OC
            'is_meta': bool,  # Whether marked as meta
            'is_crosspostable': bool,  # Whether can be crossposted
            'is_reddit_media_domain': bool,  # Whether media is hosted on Reddit
            'is_robot_indexable': bool,  # Whether search engines should index
            'is_created_from_ads_ui': bool,  # Whether created via ads UI
            'is_video': bool,  # Whether the post is a video
            'pinned': bool,  # Whether the post is pinned in the subreddit
            'gilded': int,  # Number of times gilded
            'total_awards_received': int,  # Total number of awards received
            'view_count': Optional[int],  # View count if available
            'visited': bool,  # Whether the current user has visited
        }
    }

Raises:
    ValueError: If submission_id is invalid or submission not found
    RuntimeError: For other errors during the operation

who_am_i

Get information about the currently authenticated user.

Returns:
    Dictionary containing structured user information with the following structure:
    {
        'id': str,  # Full user ID (e.g., 't2_abc123')
        'name': str,  # Username
        'created_utc': float,  # Account creation timestamp
        'comment_karma': int,  # Comment karma
        'link_karma': int,  # Post/link karma
        'total_karma': int,  # Total karma (comments + posts)
        'awardee_karma': int,  # Karma from awards received
        'awarder_karma': int,  # Karma from awards given
        'has_verified_email': bool,  # Whether email is verified
        'is_employee': bool,  # Whether user is a Reddit employee
        'is_friend': bool,  # Whether user is a friend
        'is_gold': bool,  # Whether user has Reddit Premium
        'is_mod': bool,  # Whether user is a moderator
        'is_suspended': bool,  # Whether account is suspended
        'verified': bool,  # Whether account is verified
        'has_subscribed': bool,  # Whether user has subscribed to Premium
        'snoovatar_img': str,  # URL to snoovatar image
        'icon_img': str,  # URL to user's icon
        'pref_show_snoovatar': bool,  # Whether to show snoovatar
        'snoovatar_size': Optional[List[int]],  # Snoovatar dimensions
        'subreddit': Optional[Dict],  # User's profile subreddit info
        'metadata': {
            'fetched_at': float,  # Timestamp when data was fetched
            'is_authenticated': bool,  # Whether user is authenticated
            'is_moderator': bool,  # Whether user is a moderator
            'has_verified_email': bool,  # Whether email is verified
            'has_mail': bool,  # Whether user has unread messages
            'has_mod_mail': bool,  # Whether user has mod mail
            'has_subscribed': bool,  # Whether user has subscribed to Premium
            'in_chat': bool,  # Whether user is in chat
            'in_redesign_beta': bool,  # Whether user is in redesign beta
            'new_modmail_exists': bool,  # Whether user has new modmail
            'pref_no_profanity': bool,  # Whether to filter profanity
            'suspension_expiration_utc': Optional[float],  # When suspension ends if suspended
        }
    }

Raises:
    ValueError: If user authentication is not available
    RuntimeError: For other errors during the operation

Prompts

Interactive templates invoked by user choice

No prompts

Resources

Contextual data attached and managed by the client

No resources