submit_flag
Submit a flag for a challenge ID in CTFd Capture The Flag competitions to verify your solution and earn points.
Instructions
Submit a flag for a challenge ID.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| challenge_id | Yes | ||
| flag | Yes |
Implementation Reference
- src/ctfd_mcp/server.py:93-99 (registration)MCP tool registration and handler for submit_flag. Decorated with @mcp.tool, accepts challenge_id (int) and flag (str), delegates to CTFdClient.submit_flag, and wraps errors.
@mcp.tool(description="Submit a flag for a challenge ID.") async def submit_flag(challenge_id: int, flag: str): client = await _get_client() try: return await client.submit_flag(challenge_id, flag) except Exception as exc: # noqa: BLE001 - map to user-friendly MCP error raise _format_error(exc) - src/ctfd_mcp/ctfd_client.py:218-229 (handler)Core handler implementation in CTFdClient class. Sends POST to /api/v1/challenges/attempt with challenge_id and submission, returns status and message from response.
async def submit_flag(self, challenge_id: int, flag: str) -> dict[str, Any]: """Attempt a flag submission for a challenge.""" payload = await self._request( "POST", "/api/v1/challenges/attempt", json={"challenge_id": challenge_id, "submission": flag}, ) data = payload.get("data") or {} return { "status": data.get("status"), "message": data.get("message"), } - src/ctfd_mcp/server.py:93-99 (schema)Schema definition: takes challenge_id (int) and flag (str) as parameters, no explicit return typing but returns dict with status and message.
@mcp.tool(description="Submit a flag for a challenge ID.") async def submit_flag(challenge_id: int, flag: str): client = await _get_client() try: return await client.submit_flag(challenge_id, flag) except Exception as exc: # noqa: BLE001 - map to user-friendly MCP error raise _format_error(exc) - src/ctfd_mcp/server.py:21-39 (helper)Error formatting helper used by submit_flag to convert exceptions to RuntimeError with user-friendly messages.
def _format_error(exc: Exception) -> RuntimeError: if isinstance(exc, ConfigError): message = f"Configuration error: {exc}" elif isinstance(exc, AuthError): message = f"Auth failed: {exc}" elif isinstance(exc, NotFoundError): message = f"Not found: {exc}" elif isinstance(exc, RateLimitError): retry = ( f" Retry-After={exc.retry_after}." if getattr(exc, "retry_after", None) else "" ) message = f"Rate limited.{retry}".strip() elif isinstance(exc, CTFdClientError): message = f"CTFd API error: {exc}" else: message = f"Unexpected error: {exc}" return RuntimeError(message)