Skip to main content
Glama
Arindam200

Reddit MCP Server

reply_to_comment

Post a reply to an existing Reddit comment by providing the comment ID and your response content.

Instructions

Post a reply to an existing Reddit comment.

Args:
    comment_id: The ID of the comment to reply to (can be full URL, permalink, or just ID)
    content: The content of the reply (1-10000 characters)

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

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
comment_idYes
contentYes

Implementation Reference

  • The primary handler implementation for the 'reply_to_comment' MCP tool. This function handles replying to a specific Reddit comment by fetching the comment object via PRAW, performing validations (e.g., length, accessibility), checking parent post status, and executing the reply operation. It returns formatted information about the new reply and parent comment.
    @mcp.tool()
    @require_write_access
    def reply_to_comment(
        comment_id: str, content: str
    ) -> Dict[str, Any]:
        """Post a reply to an existing Reddit comment.
    
        Args:
            comment_id: The ID of the comment to reply to (can be full URL, permalink, or just ID)
            content: The content of the reply (1-10000 characters)
    
        Returns:
            Dictionary containing information about the created reply and parent comment
    
        Raises:
            ValueError: If input validation fails or comment is not found
            RuntimeError: For other errors during reply creation
        """
        manager = RedditClientManager()
        if not manager.client:
            raise RuntimeError("Reddit client not initialized")
    
        # Input validation
        if not comment_id or not isinstance(comment_id, str):
            raise ValueError("Comment ID is required")
        if not content or not isinstance(content, str):
            raise ValueError("Reply content is required")
        if len(content) < 1 or len(content) > 10000:
            raise ValueError("Reply must be between 1 and 10000 characters")
    
        try:
            # Clean up the comment_id if it's a full URL or permalink
            clean_comment_id = _extract_reddit_id(comment_id)
            logger.info(f"Creating reply to comment ID: {clean_comment_id}")
    
            # Get the comment object
            comment = manager.client.comment(id=clean_comment_id)
    
            # Verify the comment exists by accessing its attributes
            try:
                # Force fetch to verify existence
                _ = comment.body
                comment_author = getattr(comment, "author", None)
                comment_subreddit = comment.subreddit
    
                logger.info(
                    f"Replying to comment: "
                    f"Author: {comment_author}, "
                    f"Subreddit: r/{comment_subreddit.display_name}"
                )
    
            except Exception as e:
                logger.exception(f"Failed to access comment {clean_comment_id}: {e}")
                raise ValueError(f"Comment {clean_comment_id} not found or inaccessible") from e
    
            # Check if the parent submission is archived or locked
            try:
                submission = comment.submission
                if getattr(submission, "archived", False):
                    raise ValueError("Cannot reply to a comment in an archived thread")
                if getattr(submission, "locked", False):
                    raise ValueError("Cannot reply to a comment in a locked thread")
            except ValueError:
                raise
            except Exception as check_error:
                logger.debug(f"Could not check submission status: {check_error}")
    
            # Create the reply
            logger.info(f"Posting reply with content length: {len(content)} characters")
            try:
                reply = comment.reply(body=content)
                logger.info(f"Reply created successfully: {reply.id}")
    
                return {
                    "reply": _format_comment(reply),
                    "parent_comment": _format_comment(comment),
                    "metadata": {
                        "created_at": _format_timestamp(time.time()),
                        "reply_id": reply.id,
                        "parent_id": clean_comment_id,
                        "subreddit": comment_subreddit.display_name,
                    },
                }
    
            except Exception as reply_error:
                logger.exception(f"Failed to create reply: {reply_error}")
                if "RATELIMIT" in str(reply_error).upper():
                    raise RuntimeError(
                        "You're doing that too much. Please wait before replying again."
                    ) from reply_error
                if "TOO_OLD" in str(reply_error):
                    raise RuntimeError(
                        "This thread is archived and cannot be replied to"
                    ) from reply_error
                raise RuntimeError(f"Failed to post reply: {reply_error}") from reply_error
    
        except Exception as e:
            logger.exception(f"Error in reply_to_comment for ID {comment_id}: {e}")
            if isinstance(e, (ValueError, RuntimeError)):
                raise
            raise RuntimeError(f"Failed to create comment reply: {e}") from e
  • server.py:1394-1395 (registration)
    The @mcp.tool() decorator registers the reply_to_comment function as an MCP tool in the FastMCP server. The @require_write_access decorator ensures write permissions are available.
    @mcp.tool()
    @require_write_access
  • Helper function used by reply_to_comment to extract the clean comment ID from potentially full URLs or permalinks.
    def _extract_reddit_id(reddit_id: str) -> str:
        """Extract the base ID from a Reddit URL or ID.
    
        Args:
            reddit_id: Either a Reddit ID or a URL containing the ID
    
        Returns:
            The extracted Reddit ID
        """
        if not reddit_id:
            raise ValueError("Empty ID provided")
    
        # If it's a URL, extract the ID part
        if "/" in reddit_id:
            # Handle both standard URLs and permalinks
            parts = [p for p in reddit_id.split("/") if p]
            # The ID is typically the last non-empty part
            reddit_id = parts[-1]
            logger.debug(f"Extracted ID {reddit_id} from URL")
    
        return reddit_id
  • Helper function used to format comment details for the response, including analysis, called for both parent and new reply.
    def _format_comment(comment: praw.models.Comment) -> str:
        """Format comment information with AI-driven insights."""
        flags = []
        if comment.edited:
            flags.append("Edited")
        if hasattr(comment, "is_submitter") and comment.is_submitter:
            flags.append("OP")
    
        return f"""
            • Author: u/{str(comment.author)}
            • Content: {comment.body}
            • Stats:
            - Score: {comment.score:,}
            - Controversiality: {comment.controversiality if hasattr(comment, "controversiality") else "Unknown"}
            • Context:
            - Subreddit: r/{str(comment.subreddit)}
            - Thread: {comment.submission.title}
            • Metadata:
            - Posted: {_format_timestamp(comment.created_utc)}
            - Flags: {", ".join(flags) if flags else "None"}
            • Link: https://reddit.com{comment.permalink}
    
            💬 Comment Analysis:
            - {_analyze_comment_impact(comment.score, bool(comment.edited), hasattr(comment, "is_submitter"))}
            """
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden. It discloses the mutation nature ('Post a reply'), character limits (1-10000 characters), return format (dictionary with reply and parent info), and error conditions. However, it doesn't mention authentication requirements, rate limits, or whether replies are editable/deletable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear sections (Args, Returns, Raises) and front-loaded purpose statement. The parameter explanations are efficient but could be slightly more concise by combining format options for comment_id into a single phrase.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and no output schema, the description does well by covering purpose, parameters, return format, and error cases. It could improve by mentioning authentication needs or whether this creates publicly visible content, but overall provides substantial context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description fully compensates by explaining both parameters: comment_id accepts multiple formats (URL, permalink, or ID) and content has character constraints (1-10000). This adds crucial semantic information beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Post a reply') and target resource ('to an existing Reddit comment'), distinguishing it from sibling tools like 'reply_to_post' which targets posts instead of comments. The verb+resource combination is precise and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by specifying it's for replying to comments, but doesn't explicitly state when to use this versus alternatives like 'reply_to_post' or other comment-related tools. It provides clear prerequisites (needs comment_id and content) but lacks explicit exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Arindam200/reddit-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server