list_questions
Retrieve and filter prediction questions from Fatebook. Customize results with options like resolved status, search terms, and detailed fields to analyze forecasts and comments.
Instructions
List Fatebook questions with optional filtering
Returns a list of Question objects. By default returns core fields only. Set detailed=True to include all available fields (forecasts, comments, etc.).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| apiKey | No | ||
| cursor | No | ||
| detailed | No | ||
| limit | No | ||
| resolved | No | ||
| searchString | No | ||
| unresolved | No |
Implementation Reference
- main.py:25-89 (handler)Primary handler implementation for the 'list_questions' tool. This @mcp.tool()-decorated function handles API calls to Fatebook's getQuestions endpoint, parses the response using Pydantic models, and returns a structured list of questions. Includes comprehensive logging via ctx.info/debug/error.@mcp.tool() async def list_questions( ctx: Context, apiKey: str = "", resolved: bool = False, unresolved: bool = False, searchString: str = "", limit: int = 100, cursor: str = "", detailed: bool = False, ) -> QuestionsList: """List Fatebook questions with optional filtering Returns a list of Question objects. By default returns core fields only. Set detailed=True to include all available fields (forecasts, comments, etc.). """ await ctx.info( f"list_questions called with resolved={resolved}, unresolved={unresolved}, searchString='{searchString}', limit={limit}, detailed={detailed}" ) api_key = apiKey or os.getenv("FATEBOOK_API_KEY") if not api_key: await ctx.error("API key is required but not provided") raise ValueError( "API key is required (provide as parameter or set FATEBOOK_API_KEY environment variable)" ) params: dict[str, Any] = {"apiKey": api_key} # Add optional parameters if resolved: params["resolved"] = resolved if unresolved: params["unresolved"] = unresolved if searchString: params["searchString"] = searchString params["limit"] = limit if cursor: params["cursor"] = cursor await ctx.debug(f"Making API request with params: {params}") try: async with httpx.AsyncClient() as client: response = await client.get("https://fatebook.io/api/v0/getQuestions", params=params) response.raise_for_status() data = response.json() # Parse response using Pydantic model questions_response = QuestionsResponse(**data) questions = questions_response.items await ctx.info(f"Successfully retrieved {len(questions)} questions") # Return as QuestionsList with 'result' field to match MCP schema expectations return QuestionsList(result=questions) except httpx.HTTPError as e: await ctx.error(f"HTTP error occurred: {e}") raise except Exception as e: await ctx.error(f"Unexpected error occurred: {e}") raise
- src/fatebook_mcp/models.py:194-202 (schema)Pydantic model defining the output schema for the list_questions tool, consisting of a 'result' list of Question objects.class QuestionsList(BaseModel): """List of questions for MCP responses - matches expected MCP schema""" result: List[Question] class Config: populate_by_name = True by_alias = True
- src/fatebook_mcp/models.py:187-192 (schema)Pydantic model used internally by the list_questions handler to parse the raw API response from Fatebook's getQuestions endpoint.class QuestionsResponse(BaseModel): """Response from getQuestions endpoint""" items: List[Question] cursor: Optional[str] = None
- src/fatebook_mcp/__main__.py:20-84 (handler)Alternative or package-version handler for the 'list_questions' tool, nearly identical to the one in main.py but with slightly less logging in later parts of the file.@mcp.tool() async def list_questions( ctx: Context, apiKey: str = "", resolved: bool = False, unresolved: bool = False, searchString: str = "", limit: int = 100, cursor: str = "", detailed: bool = False, ) -> QuestionsList: """List Fatebook questions with optional filtering Returns a list of Question objects. By default returns core fields only. Set detailed=True to include all available fields (forecasts, comments, etc.). """ await ctx.info( f"list_questions called with resolved={resolved}, unresolved={unresolved}, searchString='{searchString}', limit={limit}, detailed={detailed}" ) api_key = apiKey or os.getenv("FATEBOOK_API_KEY") if not api_key: await ctx.error("API key is required but not provided") raise ValueError( "API key is required (provide as parameter or set FATEBOOK_API_KEY environment variable)" ) params: dict[str, Any] = {"apiKey": api_key} # Add optional parameters if resolved: params["resolved"] = resolved if unresolved: params["unresolved"] = unresolved if searchString: params["searchString"] = searchString params["limit"] = limit if cursor: params["cursor"] = cursor await ctx.debug(f"Making API request with params: {params}") try: async with httpx.AsyncClient() as client: response = await client.get("https://fatebook.io/api/v0/getQuestions", params=params) response.raise_for_status() data = response.json() # Parse response using Pydantic model questions_response = QuestionsResponse(**data) questions = questions_response.items await ctx.info(f"Successfully retrieved {len(questions)} questions") # Return as QuestionsList with 'result' field to match MCP schema expectations return QuestionsList(result=questions) except httpx.HTTPError as e: await ctx.error(f"HTTP error occurred: {e}") raise except Exception as e: await ctx.error(f"Unexpected error occurred: {e}") raise
- src/fatebook_mcp/models.py:73-113 (helper)Core Pydantic model for individual Question objects, used within QuestionsList. Defines structure for question data including forecasts, tags, comments, etc.class Question(BaseModel): """Fatebook question model with optional fields for detailed responses""" # Core fields (id is optional since getQuestion doesn't return it) id: Optional[str] = None title: str type: Literal["BINARY", "NUMERIC", "MULTIPLE_CHOICE"] = "BINARY" resolved: bool = False # Timestamps created_at: datetime = Field(alias="createdAt") resolve_by: datetime = Field(alias="resolveBy") resolved_at: Optional[datetime] = Field(None, alias="resolvedAt") # Resolution information resolution: Optional[Literal["YES", "NO", "AMBIGUOUS"]] = None # Additional content (typically in detailed view) notes: Optional[str] = None # Related data (typically in detailed view) forecasts: Optional[List[Forecast]] = Field( default=None, description="List of forecasts on this question" ) tags: Optional[List[Tag]] = Field(default=None, description="Tags associated with the question") comments: Optional[List[Comment]] = Field(default=None, description="Comments on the question") # Visibility settings (typically in detailed view) shared_publicly: Optional[bool] = Field(None, alias="sharedPublicly") unlisted: Optional[bool] = None hide_forecasts_until: Optional[datetime] = Field(None, alias="hideForecastsUntil") share_with_lists: Optional[List[str]] = Field(None, alias="shareWithLists") share_with_email: Optional[List[str]] = Field(None, alias="shareWithEmail") # Additional fields from getQuestion endpoint your_latest_prediction: Optional[str] = Field(None, alias="yourLatestPrediction") question_scores: Optional[List] = Field(None, alias="questionScores") class Config: populate_by_name = True by_alias = True # Use aliases when serializing