File size: 10,818 Bytes
3d23b0f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { safeToolHandler } from "./base";
import * as userService from "../../leetcode/services/user";
import * as contestService from "../../leetcode/services/contest";
import * as problemService from "../../leetcode/services/problem";
import * as discussionService from "../../leetcode/services/discussion";
export function register(mcp: McpServer): void {
// ==================== USER TOOLS ====================
// Get user contest rating
mcp.tool(
"leetcode_get_rating",
"Fetches the LeetCode contest rating for a user, including their global ranking, attended contests count, and rating percentile.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserRating(username))
);
// Get user profile
mcp.tool(
"leetcode_get_profile",
"Fetches the complete LeetCode profile for a user, including basic info, company, school, skills, and social links.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserProfile(username))
);
// Get user details
mcp.tool(
"leetcode_get_details",
"Fetches detailed user information from LeetCode including profile data, submission stats, and problem solving summary.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserDetails(username))
);
// Get user badges
mcp.tool(
"leetcode_get_badges",
"Fetches all badges earned by a LeetCode user, including annual badges and special achievements.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserBadges(username))
);
// Get user solved problems
mcp.tool(
"leetcode_get_solved",
"Fetches the solved problems count for a LeetCode user, broken down by difficulty (Easy, Medium, Hard).",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserSolved(username))
);
// Get user contest ranking
mcp.tool(
"leetcode_get_contest_ranking",
"Fetches detailed contest ranking information for a LeetCode user, including rating, ranking, and top percentage.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserContest(username))
);
// Get user contest history
mcp.tool(
"leetcode_get_contest_history",
"Fetches the complete contest participation history for a LeetCode user, including each contest's ranking and rating changes.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserContestHistory(username))
);
// Get user submissions
mcp.tool(
"leetcode_get_submissions",
"Fetches recent submissions for a LeetCode user, including problem title, status, language, and timestamp.",
{
username: z.string().describe("The LeetCode username to look up"),
limit: z.number().optional().default(20).describe("Maximum number of submissions to return (default: 20)")
},
safeToolHandler(({ username, limit }) => userService.getUserSubmission(username, limit))
);
// Get user accepted submissions
mcp.tool(
"leetcode_get_ac_submissions",
"Fetches recent accepted (AC) submissions for a LeetCode user, filtered to only show successful solutions.",
{
username: z.string().describe("The LeetCode username to look up"),
limit: z.number().optional().default(20).describe("Maximum number of AC submissions to return (default: 20)")
},
safeToolHandler(({ username, limit }) => userService.getUserAcSubmission(username, limit))
);
// Get user calendar/activity
mcp.tool(
"leetcode_get_calendar",
"Fetches the submission calendar/heatmap data for a LeetCode user for a specific year, showing daily activity.",
{
username: z.string().describe("The LeetCode username to look up"),
year: z.number().describe("The year to fetch calendar data for (e.g., 2024)")
},
safeToolHandler(({ username, year }) => userService.getUserCalendar(username, year))
);
// Get user skill stats
mcp.tool(
"leetcode_get_skill_stats",
"Fetches the skill/tag statistics for a LeetCode user, showing proficiency in different problem categories like DP, Graph, etc.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserSkill(username))
);
// Get user language stats
mcp.tool(
"leetcode_get_languages",
"Fetches the programming language statistics for a LeetCode user, showing problems solved per language.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserLanguage(username))
);
// Get user progress
mcp.tool(
"leetcode_get_progress",
"Fetches the overall problem-solving progress for a LeetCode user across all categories.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => userService.getUserProgress(username))
);
// ==================== CONTEST TOOLS ====================
// Get contest ranking info
mcp.tool(
"leetcode_get_contest_ranking_info",
"Fetches detailed contest ranking information including rating, global rank, and percentile for a user.",
{ username: z.string().describe("The LeetCode username to look up") },
safeToolHandler(({ username }) => contestService.getContestRankingInfo(username))
);
// Get contest histogram
mcp.tool(
"leetcode_get_contest_histogram",
"Fetches the contest rating distribution histogram showing how many users are at each rating level.",
{},
safeToolHandler(() => contestService.getContestHistogram())
);
// Get all contests
mcp.tool(
"leetcode_get_all_contests",
"Fetches a list of all LeetCode contests including past weekly and biweekly contests with their details.",
{},
safeToolHandler(() => contestService.getAllContests())
);
// Get upcoming contests
mcp.tool(
"leetcode_get_upcoming_contests",
"Fetches a list of upcoming LeetCode contests that haven't started yet.",
{},
safeToolHandler(() => contestService.getUpcomingContests())
);
// ==================== PROBLEM TOOLS ====================
// Get daily problem
mcp.tool(
"leetcode_get_daily_problem",
"Fetches today's LeetCode Daily Challenge problem with its details, difficulty, and constraints.",
{
raw: z.boolean().optional().default(false).describe("Return raw API response if true (default: false)")
},
safeToolHandler(({ raw }) => problemService.getDailyProblem(raw))
);
// Get specific problem by slug
mcp.tool(
"leetcode_get_problem",
"Fetches detailed information about a specific LeetCode problem by its title slug (e.g., 'two-sum').",
{
titleSlug: z.string().describe("The URL slug of the problem (e.g., 'two-sum', 'add-two-numbers')"),
raw: z.boolean().optional().default(false).describe("Return raw API response if true (default: false)")
},
safeToolHandler(({ titleSlug, raw }) => problemService.getSelectProblem(titleSlug, raw))
);
// Get problems list
mcp.tool(
"leetcode_get_problems",
"Fetches a filtered list of LeetCode problems with pagination, difficulty filter, and category support.",
{
limit: z.number().optional().default(20).describe("Number of problems to return"),
skip: z.number().optional().default(0).describe("Number of problems to skip (for pagination)"),
categorySlug: z.string().optional().describe("Category slug to filter by (e.g., 'algorithms', 'database')"),
filters: z.object({
difficulty: z.string().optional().describe("Difficulty filter: 'EASY', 'MEDIUM', or 'HARD'"),
tags: z.array(z.string()).optional().describe("Array of tag slugs to filter by")
}).optional().describe("Optional filters object")
},
safeToolHandler((params) => problemService.getProblems(params))
);
// Get official solution
mcp.tool(
"leetcode_get_official_solution",
"Fetches the official LeetCode solution/editorial for a specific problem.",
{
titleSlug: z.string().describe("The URL slug of the problem (e.g., 'two-sum')")
},
safeToolHandler(({ titleSlug }) => problemService.getOfficialSolution(titleSlug))
);
// ==================== DISCUSSION TOOLS ====================
// Get trending discussions
mcp.tool(
"leetcode_get_trending_discussions",
"Fetches the top trending discussions from LeetCode's discussion forum.",
{
first: z.number().optional().default(10).describe("Number of trending discussions to return (default: 10)")
},
safeToolHandler(({ first }) => discussionService.getTrendingDiscuss(first))
);
// Get specific discussion topic
mcp.tool(
"leetcode_get_discussion_topic",
"Fetches a specific discussion topic by its ID, including the full content and metadata.",
{
topicId: z.number().describe("The numeric ID of the discussion topic")
},
safeToolHandler(({ topicId }) => discussionService.getDiscussTopic(topicId))
);
// Get discussion comments
mcp.tool(
"leetcode_get_discussion_comments",
"Fetches comments/replies on a specific LeetCode discussion topic.",
{
topicId: z.number().describe("The numeric ID of the discussion topic"),
orderBy: z.string().optional().default("hot").describe("Order by: 'hot', 'newest', or 'oldest'"),
pageNo: z.number().optional().default(1).describe("Page number for pagination"),
numPerPage: z.number().optional().default(10).describe("Number of comments per page")
},
safeToolHandler((params) => discussionService.getDiscussComments(params))
);
}
|