Skip to main content
Glama
jaipandya

product-hunt-mcp

by jaipandya

check_server_status

Verify the Product Hunt MCP server's operational status and authentication, returning server readiness, user details, and rate limit information.

Instructions

    Check the status of the Product Hunt MCP server and authentication.

    Returns:
    - status (str): "Ready", "Not initialized", "Token invalid", or "Error".
    - authenticated (bool, optional): True if authenticated, False otherwise.
    - user (dict, optional): User details if authenticated.
    - rate_limits (dict, optional): API rate limit information.
    - message (str, optional): Additional status or error message.
    

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The handler function that implements the check_server_status tool. It verifies the authentication token, executes a GraphQL viewer query to check API connectivity, handles errors, and returns a status dictionary with details like status, authenticated flag, user info, and rate limits.
    def check_server_status() -> Dict[str, Any]:
        """
        Check the status of the Product Hunt MCP server and authentication.
    
        Returns:
        - status (str): "Ready", "Not initialized", "Token invalid", or "Error".
        - authenticated (bool, optional): True if authenticated, False otherwise.
        - user (dict, optional): User details if authenticated.
        - rate_limits (dict, optional): API rate limit information.
        - message (str, optional): Additional status or error message.
        """
        logger.info("server.check_server_status called")
    
        # 1. Check if token exists
        token_error = check_token() # Uses relative import from ..utils.token
        if token_error:
            # Use format_response for consistency, but keep specific status/message
            response = format_response(False, error=token_error)
            response["status"] = "Not initialized"
            response["message"] = token_error["message"]
            return response
    
        # 2. Try a simple query to check if token is valid
        try:
            # Uses relative imports from ..api.client and ..api.queries
            result, rate_limits, error = execute_graphql_query(VIEWER_QUERY)
    
            if error:
                response = format_response(False, error=error, rate_limits=rate_limits)
                response["status"] = "Error"
                response["message"] = f"Unable to authenticate with Product Hunt API: {error.get('message', 'Unknown error')}"
                return response
    
            # Check if viewer data is present (indicates successful auth)
            from ..utils.common import check_data_exists # Local import to avoid circular dependency at module level
            is_valid = check_data_exists(result.get("data", {}), "viewer")
            viewer_data = result.get("data", {}).get("viewer") if is_valid else None
    
            response = format_response(True, data=viewer_data, rate_limits=rate_limits)
            response["status"] = "Ready" if is_valid else "Token invalid"
            response["authenticated"] = is_valid
            if not is_valid:
                response["message"] = "Authentication successful, but no viewer data returned."
            if viewer_data and "user" in viewer_data: # Handle nested user structure if present
                response["user"] = viewer_data["user"]
            elif viewer_data:
                response["user"] = viewer_data # Assume viewer is the user object
    
            return response
    
        except Exception as e:
            logger.error(f"Unexpected error in check_server_status: {str(e)}", exc_info=True)
            response = format_response(False, error={"code": "INTERNAL_ERROR", "message": str(e)})
            response["status"] = "Error"
            response["message"] = f"Unexpected error checking API connection: {str(e)}"
            return response
  • The registration function for server tools, which uses the @mcp.tool() decorator to register the check_server_status handler with the MCP server instance.
    def register_server_tools(mcp):
        """Register server-related tools with the MCP server."""
    
        @mcp.tool()
        # No @handle_errors here as we want to return specific status messages
        def check_server_status() -> Dict[str, Any]:
            """
            Check the status of the Product Hunt MCP server and authentication.
    
            Returns:
            - status (str): "Ready", "Not initialized", "Token invalid", or "Error".
            - authenticated (bool, optional): True if authenticated, False otherwise.
            - user (dict, optional): User details if authenticated.
            - rate_limits (dict, optional): API rate limit information.
            - message (str, optional): Additional status or error message.
            """
            logger.info("server.check_server_status called")
    
            # 1. Check if token exists
            token_error = check_token() # Uses relative import from ..utils.token
            if token_error:
                # Use format_response for consistency, but keep specific status/message
                response = format_response(False, error=token_error)
                response["status"] = "Not initialized"
                response["message"] = token_error["message"]
                return response
    
            # 2. Try a simple query to check if token is valid
            try:
                # Uses relative imports from ..api.client and ..api.queries
                result, rate_limits, error = execute_graphql_query(VIEWER_QUERY)
    
                if error:
                    response = format_response(False, error=error, rate_limits=rate_limits)
                    response["status"] = "Error"
                    response["message"] = f"Unable to authenticate with Product Hunt API: {error.get('message', 'Unknown error')}"
                    return response
    
                # Check if viewer data is present (indicates successful auth)
                from ..utils.common import check_data_exists # Local import to avoid circular dependency at module level
                is_valid = check_data_exists(result.get("data", {}), "viewer")
                viewer_data = result.get("data", {}).get("viewer") if is_valid else None
    
                response = format_response(True, data=viewer_data, rate_limits=rate_limits)
                response["status"] = "Ready" if is_valid else "Token invalid"
                response["authenticated"] = is_valid
                if not is_valid:
                    response["message"] = "Authentication successful, but no viewer data returned."
                if viewer_data and "user" in viewer_data: # Handle nested user structure if present
                    response["user"] = viewer_data["user"]
                elif viewer_data:
                    response["user"] = viewer_data # Assume viewer is the user object
    
                return response
    
            except Exception as e:
                logger.error(f"Unexpected error in check_server_status: {str(e)}", exc_info=True)
                response = format_response(False, error={"code": "INTERNAL_ERROR", "message": str(e)})
                response["status"] = "Error"
                response["message"] = f"Unexpected error checking API connection: {str(e)}"
                return response
  • Invocation of the server tools registration in the main CLI entrypoint, adding the check_server_status tool to the FastMCP server.
    register_server_tools(mcp)
  • Docstring defining the expected input (none) and output schema/format of the check_server_status tool.
    """
    Check the status of the Product Hunt MCP server and authentication.
    
    Returns:
    - status (str): "Ready", "Not initialized", "Token invalid", or "Error".
    - authenticated (bool, optional): True if authenticated, False otherwise.
    - user (dict, optional): User details if authenticated.
    - rate_limits (dict, optional): API rate limit information.
    - message (str, optional): Additional status or error message.
    """
Behavior3/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It adds value by detailing the return structure and possible status outcomes, which helps the agent understand what to expect. However, it lacks information on error handling, latency, or side effects, leaving some behavioral aspects unclear.

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

Conciseness5/5

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

The description is well-structured and concise, with a clear purpose statement followed by a bulleted list of return values. Every sentence earns its place by providing essential information without redundancy, making it easy for the agent to parse and understand.

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?

Given the tool's simplicity (0 parameters, no annotations, no output schema), the description is largely complete. It explains the purpose and return values adequately. However, it could improve by addressing usage context or error scenarios, slightly limiting completeness for optimal agent guidance.

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 input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description appropriately focuses on output semantics, listing return values and their types, which compensates for the lack of an output schema, adding meaningful context beyond the empty input schema.

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

Purpose4/5

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

The description clearly states the tool's purpose: 'Check the status of the Product Hunt MCP server and authentication.' It uses specific verbs ('check') and identifies the resource ('server and authentication'), though it doesn't explicitly differentiate from sibling tools like 'get_viewer' which might also relate to authentication status.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites, context for invocation, or compare it to sibling tools such as 'get_viewer' that might overlap in functionality, leaving the agent with no usage direction.

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/jaipandya/producthunt-mcp-server'

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