Module 4: Topcoder Challenge Steward Agent - Finalized Use Case & Design
Problem Definition
Real-World Problem: Topcoder members miss out on relevant challenges because there's no personalized notification system to alert them when new challenges matching their skills and interests are published.
Current Pain Points:
- Members must manually check the Topcoder website regularly for new challenges
- No filtering mechanism based on personal preferences or skills
- Time-sensitive challenges may be missed, reducing earning opportunities
- High-value challenges in preferred domains go unnoticed
- Members lose engagement with the platform due to information overload
Why This Matters:
- For Members: Increased earnings potential through timely participation in relevant challenges
- For Topcoder: Higher engagement rates and challenge participation
- For Community: Better matching of skills to challenges improves overall solution quality
Target User & Audience
Primary Users:
- Active Topcoder Members who participate in challenges regularly but want to optimize their time
- Occasional Participants who want to stay informed about high-value opportunities in their expertise areas
- New Members who need guidance on which challenges align with their skill set
User Personas:
- "The Specialist" - Expert in specific domains (AI, Development, Design) looking for high-value challenges
- "The Opportunist" - Generalist who wants to be notified of any challenge above a certain prize threshold
- "The Learner" - Developing skills and wants challenges that help them grow in specific areas
Solution & Value Proposition
Core Solution
An intelligent AI agent that continuously monitors Topcoder challenges and sends personalized email notifications when relevant opportunities arise, based on user-defined preferences.
Value Proposition
- Save Time: No more manual checking of challenge listings
- Increase Earnings: Never miss high-value challenges in your expertise area
- Smart Filtering: AI-powered matching based on skills, preferences, and historical performance
- Personalized Experience: Customizable criteria including prize amounts, domains, and difficulty levels
Key Features
- Preference Management: Users define their interests through natural language preferences
- Smart Matching: AI agent analyzes challenges against user preferences
- Email Notifications: Timely alerts with challenge details and registration links
- Scheduling: Automated daily scanning and notification delivery
- User Control: Easy start/stop functionality for notifications
MCP Tools & Integration Strategy
Primary MCP Tools (Topcoder Server)
Based on Module 3 exploration, the agent will utilize:
query-tc-challenges- Returns a list of Topcoder challenges based on query parameters- Includes full challenge descriptions
- Status filtering (Active, Draft, etc.)
- Date range filtering
- Challenge type filtering
- Prize information
- Timeline and deadlines
- Required skills and technologies
query-tc-skills- Returns standardized skills from Topcoder platform- Filtered and sorted based on provided parameters
- Technology skills (Java, Python, React, etc.)
- Domain skills (AI/ML, Web Development, Mobile, etc.)
- Used for preference matching and validation
Custom Email Tool Implementation
A simple email notification tool using SendGrid API:
@tool
def send_email(to: str, html_content: str, subject: str) -> str:
"""Send an email notification about relevant Topcoder challenges"""
print(f"Sending to {to} content {html_content} and subject {subject}.")
# Get SendGrid API key from environment variable
sendgrid_api_key = os.getenv("SENDGRID_API_KEY")
if not sendgrid_api_key:
raise ValueError("SENDGRID_API_KEY environment variable is not set")
message = Mail(
from_email='kavukcu.tolga@gmail.com',
to_emails=to,
subject=subject,
html_content=html_content
)
try:
sg = SendGridAPIClient(sendgrid_api_key)
response = sg.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
return f"Mail is sent to {to}"
except Exception as e:
print(f"Error sending email: {str(e)}")
return f"Failed to send email to {to}: {str(e)}"
Integration Flow
- Daily Schedule: Agent runs automatically for each active user
- Challenge Retrieval: Fetch new/updated challenges using
query-tc-challenges - Skills Reference: Use
query-tc-skillsfor preference validation and matching - AI Matching: Compare challenge details against user preferences using LLM
- Notification: Send formatted email using custom
send_emailtool - Tracking: Log notifications sent to avoid duplicates
User Journey & Experience Flow
User provides email and preferences.
Runs agent once to get relevant challanges.
If user happy about results, schedules the agent to run daily basis.
Technical Architecture
Frontend (User Management)
- Framework: Material UI + React
- Features: Preference input, agent control, notification history
- User Actions: Start/stop agent, modify preferences, view past notifications
Backend (Agent Logic)
- Framework: FastAPI (Python)
- Components:
- REST API for frontend communication
- Background scheduler for agent execution
- Supabase integration for data persistence
- MCP client integration for Topcoder tools
- Email service integration with SendGrid
Database (Supabase)
- Database: PostgreSQL via Supabase
- Benefits:
- Free tier with generous limits
- Real-time subscriptions
- Built-in authentication (if needed)
- REST API auto-generation
- Dashboard for data management
- Persistent storage for Hugging Face Spaces deployment
Database Schema (Supabase Tables)
-- Users table
CREATE TABLE users (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
preferences_text TEXT,
active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Notifications table
CREATE TABLE notifications (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
challenge_id VARCHAR(255),
sent_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
challenge_title VARCHAR(500),
challenge_url TEXT,
prize_amount DECIMAL(10,2),
challenge_track VARCHAR(100)
);
-- Agent runs log
CREATE TABLE agent_runs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
run_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
challenges_found INTEGER DEFAULT 0,
notifications_sent INTEGER DEFAULT 0,
status VARCHAR(50) DEFAULT 'completed',
error_message TEXT
);
-- Indexes for performance
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_active ON users(active);
CREATE INDEX idx_notifications_user_id ON notifications(user_id);
CREATE INDEX idx_notifications_sent_at ON notifications(sent_at);
CREATE INDEX idx_agent_runs_user_id ON agent_runs(user_id);
CREATE INDEX idx_agent_runs_run_at ON agent_runs(run_at);
Supabase Integration
# Supabase configuration
import os
from supabase import create_client, Client
class SupabaseManager:
def __init__(self):
url = os.getenv("SUPABASE_URL")
key = os.getenv("SUPABASE_ANON_KEY")
self.supabase: Client = create_client(url, key)
async def get_user_preferences(self, email: str):
"""Get all users with active notifications"""
response = self.supabase.table("users").select({"email": email}).execute()
return response.data
async def save_user_preferences(self, email: str, preferences: str):
"""Save or update user preferences"""
response = self.supabase.table("users").upsert({
"email": email,
"preferences_text": preferences,
"updated_at": "now()"
}).execute()
return response.data
async def log_notification(self, user_id: str, challenge_data: dict):
"""Log sent notification"""
self.supabase.table("notifications").insert({
"user_id": user_id,
"challenge_id": challenge_data.get("id"),
"challenge_title": challenge_data.get("title"),
"challenge_url": challenge_data.get("url"),
"prize_amount": challenge_data.get("prize"),
"challenge_track": challenge_data.get("track")
}).execute()
async def log_agent_run(self, user_id: str, challenges_found: int, notifications_sent: int):
"""Log agent execution"""
self.supabase.table("agent_runs").insert({
"user_id": user_id,
"challenges_found": challenges_found,
"notifications_sent": notifications_sent
}).execute()
MCP Tool Usage Details
query-tc-challenges Parameters
The agent will use this tool with various parameters to find relevant challenges:
- status: Filter by challenge status (Active, Draft, etc.)
- fromDate/toDate: Limit to recently published challenges
- track: Filter by challenge track (Development, Design, AI, etc.)
- subTrack: More specific filtering within tracks
- prize: Minimum prize amount filtering
query-tc-skills Usage
Used for:
- Preference Validation: Ensure user preferences align with available skills
- Skill Mapping: Match free-text preferences to standardized skill categories
- Enhanced Filtering: Combine with challenge data for more accurate matching
Conclusion
The Topcoder Challenge Steward Agent addresses a clear market need by providing intelligent, personalized notifications for challenge opportunities. By leveraging:
- Topcoder MCP tools (
query-tc-challengesandquery-tc-skills) for comprehensive challenge data access - Custom
send_emailtool with SendGrid for reliable notification delivery - Supabase database for persistent user configuration and notification history storage
The solution creates significant value for both individual members and the broader Topcoder ecosystem. The use of Supabase ensures data persistence even when deployed on Hugging Face Spaces, while providing real-time capabilities and easy data management through its dashboard interface.
The agent's success relies on accurate preference matching, reliable delivery using SendGrid, persistent state management via Supabase, and continuous refinement based on user feedback and behavior patterns stored in the database.




