tool_upload_submission
Upload files to a Gradescope assignment by providing course ID, assignment ID, and file paths. Optionally set a leaderboard name and confirm the upload.
Instructions
Upload files as a submission to a Gradescope assignment.
Args:
course_id: The Gradescope course ID.
assignment_id: The assignment ID.
file_paths: List of absolute file paths to upload.
leaderboard_name: Optional leaderboard display name.
confirm_write: Must be True to perform the upload.Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes | ||
| assignment_id | Yes | ||
| file_paths | Yes | ||
| leaderboard_name | No | ||
| confirm_write | No |
Implementation Reference
- The function `upload_submission` handles the file uploading logic to a Gradescope assignment, including validation of file paths and confirmation requirements.
def upload_submission( course_id: str, assignment_id: str, file_paths: list[str], leaderboard_name: str | None = None, confirm_write: bool = False, ) -> str: """Upload files as a submission to a Gradescope assignment. Args: course_id: The Gradescope course ID. assignment_id: The assignment ID. file_paths: List of absolute file paths to upload. leaderboard_name: Optional leaderboard display name. confirm_write: Must be True to perform the upload. """ if not course_id or not assignment_id: return "Error: both course_id and assignment_id are required." if not file_paths: return "Error: at least one file path is required." # Validate file paths validated_paths = [] for fp in file_paths: original_path = pathlib.Path(fp) if not original_path.is_absolute(): return f"Error: file path must be absolute: {fp}" path = original_path.resolve() if not path.exists(): return f"Error: file not found: {fp}" if not path.is_file(): return f"Error: not a file: {fp}" validated_paths.append(path) if not confirm_write: details = [ f"course_id=`{course_id}`", f"assignment_id=`{assignment_id}`", f"files={', '.join(str(path) for path in validated_paths)}", ] if leaderboard_name: details.append(f"leaderboard_name={leaderboard_name}") return write_confirmation_required("upload_submission", details) try: conn = get_connection() file_handles = [] try: for path in validated_paths: file_handles.append(open(path, "rb")) result_url = upload_assignment( session=conn.session, course_id=course_id, assignment_id=assignment_id, *file_handles, leaderboard_name=leaderboard_name, ) finally: for fh in file_handles: fh.close() except AuthError as e: return f"Authentication error: {e}" except Exception as e: return f"Error uploading submission: {e}" if result_url: filenames = [p.name for p in validated_paths] return ( f"✅ Submission uploaded successfully!\n" f"- **Files:** {', '.join(filenames)}\n" f"- **Submission URL:** {result_url}" ) else: return ( "❌ Upload failed. Possible reasons:\n" "- Assignment is past the due date\n" "- You don't have permission to submit\n" "- Invalid course or assignment ID" ) - src/gradescope_mcp/server.py:117-135 (registration)The `tool_upload_submission` function registers the tool with the MCP server and calls the implementation in `submissions.py`.
def tool_upload_submission( course_id: str, assignment_id: str, file_paths: list[str], leaderboard_name: str | None = None, confirm_write: bool = False, ) -> str: """Upload files as a submission to a Gradescope assignment. Args: course_id: The Gradescope course ID. assignment_id: The assignment ID. file_paths: List of absolute file paths to upload. leaderboard_name: Optional leaderboard display name. confirm_write: Must be True to perform the upload. """ return upload_submission( course_id, assignment_id, file_paths, leaderboard_name, confirm_write )