list_challenges
List visible challenges from a CTFd platform, with optional filters to narrow by category or show only unsolved ones, helping you quickly find relevant tasks.
Instructions
List visible challenges. Optional filter by category and unsolved only.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | ||
| only_unsolved | No |
Implementation Reference
- src/ctfd_mcp/server.py:71-82 (handler)MCP tool handler function that exposes list_challenges as a FastMCP tool. It delegates to CTFdClient.list_challenges() and formats errors.
@mcp.tool( description="List visible challenges. Optional filter by category and unsolved only." ) async def list_challenges(category: str | None = None, only_unsolved: bool = False): client = await _get_client() try: return await client.list_challenges( category=category, only_unsolved=only_unsolved ) except Exception as exc: # noqa: BLE001 - map to user-friendly MCP error raise _format_error(exc) - src/ctfd_mcp/server.py:71-73 (registration)The @mcp.tool decorator registers list_challenges as an MCP tool with description metadata.
@mcp.tool( description="List visible challenges. Optional filter by category and unsolved only." ) - src/ctfd_mcp/ctfd_client.py:161-190 (helper)The client-side implementation that fetches challenges from the CTFd API (/api/v1/challenges), filters by category (case-insensitive) and solve state, then normalizes the response into a list of dicts with id, name, category, value, solved, type, tags.
async def list_challenges( self, category: str | None = None, only_unsolved: bool = False ) -> list[dict[str, Any]]: """List challenges the user can see, optionally filtered by category and solve state.""" payload = await self._request("GET", "/api/v1/challenges") challenges = payload.get("data") or [] normalized = [] for item in challenges: if category and (item.get("category") or "").lower() != category.lower(): continue solved = item.get("solved") if solved is None: solved = item.get("solved_by_me") if only_unsolved and solved: continue normalized.append( { "id": item.get("id"), "name": item.get("name"), "category": item.get("category"), "value": item.get("value"), "solved": solved if solved is not None else item.get("solved"), "type": item.get("type"), "tags": item.get("tags") or [], } ) return normalized