File size: 6,911 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 |
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { safeToolHandler } from "./base";
import * as service from "../../codeforces/service";
/**
* Registers all Codeforces-related MCP tools.
*/
export function register(mcp: McpServer): void {
// Get user rating
mcp.tool(
"codeforces_get_rating",
"Fetches a Codeforces user's current rating, rank, max rating, contribution score, and avatar URL.",
{ username: z.string().describe("The Codeforces handle (username)") },
safeToolHandler(({ username }) => service.getUserRating(username))
);
// Get contest history
mcp.tool(
"codeforces_get_contest_history",
"Fetches the complete contest participation history for a Codeforces user, including rating changes after each contest.",
{ username: z.string().describe("The Codeforces handle (username)") },
safeToolHandler(({ username }) => service.getContestHistory(username))
);
// Get user status (submissions)
mcp.tool(
"codeforces_get_user_status",
"Fetches recent submissions for a Codeforces user with verdict, problem info, and submission details.",
{
username: z.string().describe("The Codeforces handle (username)"),
from: z.number().optional().default(1).describe("1-based index of the first submission to return (default: 1)"),
count: z.number().optional().default(10).describe("Number of submissions to return (default: 10)")
},
safeToolHandler(({ username, from, count }) => service.getUserStatus(username, from, count))
);
// Get user blog entries
mcp.tool(
"codeforces_get_user_blogs",
"Fetches all blog entries authored by a Codeforces user, including titles, ratings, and creation times.",
{ username: z.string().describe("The Codeforces handle (username)") },
safeToolHandler(({ username }) => service.getUserBlogs(username))
);
// Get solved problems
mcp.tool(
"codeforces_get_solved_problems",
"Fetches all problems solved by a Codeforces user, including problem ratings, tags, and direct links.",
{ username: z.string().describe("The Codeforces handle (username)") },
safeToolHandler(({ username }) => service.getSolvedProblems(username))
);
// Get contests list
mcp.tool(
"codeforces_get_contests",
"Fetches the list of all Codeforces contests (past and upcoming), optionally including gym contests.",
{ gym: z.boolean().optional().default(false).describe("If true, include gym contests (default: false)") },
safeToolHandler(({ gym }) => service.getContests(gym))
);
// Get recent actions
mcp.tool(
"codeforces_get_recent_actions",
"Fetches recent actions on Codeforces such as new blog entries and comments.",
{ maxCount: z.number().optional().default(20).describe("Maximum number of actions to return (default: 20, max: 100)") },
safeToolHandler(({ maxCount }) => service.getRecentActions(maxCount))
);
// Get problemset problems
mcp.tool(
"codeforces_get_problems",
"Fetches all problems from the Codeforces problemset, optionally filtered by tags.",
{ tags: z.string().optional().describe("Semicolon-separated tags to filter problems (e.g., 'dp;greedy')") },
safeToolHandler(({ tags }) => service.getProblems(tags))
);
// Get contest standings
mcp.tool(
"codeforces_get_contest_standings",
"Fetches the standings/leaderboard for a specific Codeforces contest with participant rankings and scores.",
{
contestId: z.number().describe("The numeric ID of the contest"),
from: z.number().optional().describe("1-based index of the first standing row"),
count: z.number().optional().describe("Number of standings rows to return"),
handles: z.string().optional().describe("Semicolon-separated handles to filter the standings"),
room: z.number().optional().describe("Room number to filter standings"),
showUnofficial: z.boolean().optional().describe("Include unofficial participants")
},
safeToolHandler(({ contestId, from, count, handles, room, showUnofficial }) =>
service.getContestStandings(contestId, from, count, handles, room, showUnofficial)
)
);
// Get contest rating changes
mcp.tool(
"codeforces_get_contest_rating_changes",
"Fetches the rating changes for all participants in a specific Codeforces contest.",
{ contestId: z.number().describe("The numeric ID of the contest") },
safeToolHandler(({ contestId }) => service.getContestRatingChanges(contestId))
);
// Get contest hacks
mcp.tool(
"codeforces_get_contest_hacks",
"Fetches all successful and unsuccessful hacks that occurred during a Codeforces contest.",
{ contestId: z.number().describe("The numeric ID of the contest") },
safeToolHandler(({ contestId }) => service.getContestHacks(contestId))
);
// Get contest status (submissions)
mcp.tool(
"codeforces_get_contest_status",
"Fetches submissions made in a specific Codeforces contest, optionally filtered by a handle.",
{
contestId: z.number().describe("The numeric ID of the contest"),
handle: z.string().optional().describe("Optional handle to filter submissions"),
from: z.number().optional().describe("1-based index of the first submission"),
count: z.number().optional().describe("Number of submissions to return")
},
safeToolHandler(({ contestId, handle, from, count }) =>
service.getContestStatus(contestId, handle, from, count)
)
);
// Get problemset recent status
mcp.tool(
"codeforces_get_problemset_recent_status",
"Fetches the most recent submissions across the entire Codeforces problemset.",
{ count: z.number().describe("Number of recent submissions to return (max: 1000)") },
safeToolHandler(({ count }) => service.getProblemsetRecentStatus(count))
);
// Get blog entry
mcp.tool(
"codeforces_get_blog_entry",
"Fetches the full content of a specific Codeforces blog entry by its ID.",
{ blogEntryId: z.number().describe("The numeric ID of the blog entry") },
safeToolHandler(({ blogEntryId }) => service.getBlogEntry(blogEntryId))
);
// Get blog comments
mcp.tool(
"codeforces_get_blog_comments",
"Fetches all comments on a specific Codeforces blog entry.",
{ blogEntryId: z.number().describe("The numeric ID of the blog entry") },
safeToolHandler(({ blogEntryId }) => service.getBlogComments(blogEntryId))
);
}
|