Skip to main content
Glama
Arindam200

Reddit MCP Server

who_am_i

Retrieve authenticated user profile data including karma scores, account status, verification details, and metadata from Reddit.

Instructions

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • server.py:2180-2181 (registration)
    Registration of the 'who_am_i' tool using the @mcp.tool() decorator on the handler function.
    @mcp.tool()
    @require_write_access
  • The handler function for the 'who_am_i' tool that retrieves detailed profile information about the currently authenticated Reddit user, including karma, preferences, subreddit info, and metadata.
    def who_am_i() -> Dict[str, Any]:
        """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
        """
        manager = RedditClientManager()
        if not manager.client:
            raise RuntimeError("Reddit client not initialized")
    
        try:
            logger.info("Getting information about the current authenticated user")
    
            # Check if user is authenticated
            if not manager.check_user_auth():
                raise ValueError(
                    "User authentication required. Please provide valid credentials."
                )
    
            # Get the current user
            current_user = manager.client.user.me()
            if not current_user:
                raise ValueError("Failed to retrieve current user information")
    
            username = getattr(current_user, "name", "unknown")
            logger.info(f"Retrieved information for user: {username}")
    
            # Get user preferences and other attributes with safe defaults
            prefs = getattr(current_user, "prefs", {}) or {}
            subreddit = getattr(current_user, "subreddit", {}) or {}
    
            # Build the user info dictionary
            user_info = {
                "id": getattr(current_user, "id", ""),
                "name": username,
                "created_utc": getattr(current_user, "created_utc", 0),
                "comment_karma": getattr(current_user, "comment_karma", 0),
                "link_karma": getattr(current_user, "link_karma", 0),
                "total_karma": getattr(current_user, "total_karma", 0),
                "awardee_karma": getattr(current_user, "awardee_karma", 0),
                "awarder_karma": getattr(current_user, "awarder_karma", 0),
                "has_verified_email": getattr(current_user, "has_verified_email", False),
                "is_employee": getattr(current_user, "is_employee", False),
                "is_friend": getattr(current_user, "is_friend", False),
                "is_gold": getattr(current_user, "is_gold", False),
                "is_mod": getattr(current_user, "is_mod", False),
                "is_suspended": getattr(current_user, "is_suspended", False),
                "verified": getattr(current_user, "verified", False),
                "has_subscribed": getattr(current_user, "has_subscribed", False),
                "snoovatar_img": getattr(current_user, "snoovatar_img", ""),
                "icon_img": getattr(current_user, "icon_img", ""),
                "pref_show_snoovatar": prefs.get("show_snoovatar", False),
                "snoovatar_size": getattr(current_user, "snoovatar_size", None),
                "subreddit": {
                    "display_name": subreddit.get("display_name", ""),
                    "name": subreddit.get("display_name_prefixed", ""),
                    "public_description": subreddit.get("public_description", ""),
                    "subscribers": subreddit.get("subscribers", 0),
                    "created_utc": subreddit.get("created_utc", 0),
                    "over18": subreddit.get("over18", False),
                    "suggested_comment_sort": subreddit.get(
                        "suggested_comment_sort", "best"
                    ),
                    "title": subreddit.get("title", ""),
                    "url": subreddit.get("url", ""),
                }
                if subreddit
                else None,
                "metadata": {
                    "fetched_at": time.time(),
                    "is_authenticated": True,
                    "is_moderator": getattr(current_user, "is_mod", False),
                    "has_verified_email": getattr(
                        current_user, "has_verified_email", False
                    ),
                    "has_mail": getattr(current_user, "has_mail", False),
                    "has_mod_mail": getattr(current_user, "has_mod_mail", False),
                    "has_subscribed": getattr(current_user, "has_subscribed", False),
                    "in_chat": getattr(current_user, "in_chat", False),
                    "in_redesign_beta": prefs.get("in_redesign_beta", False),
                    "new_modmail_exists": getattr(
                        current_user, "new_modmail_exists", False
                    ),
                    "pref_no_profanity": prefs.get("no_profanity", True),
                    "suspension_expiration_utc": getattr(
                        current_user, "suspension_expiration_utc", None
                    ),
                },
            }
    
            return user_info
    
        except Exception as e:
            logger.error(f"Error in who_am_i: {e}")
            if "401" in str(e) or "unauthorized" in str(e).lower():
                raise ValueError(
                    "Authentication failed. Please check your credentials."
                ) from e
            if isinstance(e, (ValueError, RuntimeError)):
                raise
            raise RuntimeError(f"Failed to retrieve user information: {e}") from e
  • Helper decorator '@require_write_access' applied to the who_am_i handler to enforce write access and user authentication requirements.
    def require_write_access(func: F) -> F:
        """Decorator to ensure write access is available."""
    
        @functools.wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            reddit_manager = RedditClientManager()
            if reddit_manager.is_read_only:
                raise ValueError(
                    "Write operation not allowed in read-only mode. Please provide valid credentials."
                )
            if not reddit_manager.check_user_auth():
                raise Exception(
                    "Authentication required for write operations. "
                    "Please provide valid REDDIT_USERNAME and REDDIT_PASSWORD environment variables."
                )
            return func(*args, **kwargs)
Behavior4/5

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

With no annotations provided, the description carries full burden and does an excellent job disclosing behavioral traits. It specifies authentication requirements through the 'Raises' section, describes the complete return structure in detail, and documents error conditions. The only minor gap is lack of rate limit or performance characteristics.

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

Conciseness3/5

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

The description is appropriately front-loaded with the core purpose, but the extensive return value documentation (25+ fields) could be considered verbose for a description. While valuable, it might be better placed in an output schema. The structure is logical but not maximally concise.

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

Completeness5/5

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

For a zero-parameter read operation with no annotations and no output schema, the description provides exceptional completeness. It covers purpose, authentication requirements, detailed return structure, and error conditions - everything an agent needs to understand and invoke this tool correctly.

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

Parameters4/5

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

The tool has zero parameters with 100% schema description coverage, so the baseline is 4. The description correctly states no parameters are needed ('currently authenticated user' implies no input required), which aligns perfectly with the empty input 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 ('Get information about') and resource ('currently authenticated user'), distinguishing it from sibling tools like get_user_info which presumably fetches information about other users. The purpose is immediately apparent in the first sentence.

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 through 'currently authenticated user' and the error handling section mentioning authentication requirements, providing clear when-to-use guidance. However, it doesn't explicitly contrast with alternatives like get_user_info or state when not to use this tool.

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