# Directory Structure
```
├── .gitignore
├── Dockerfile
├── index.js
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── smithery.yaml
├── src
│   ├── graphql
│   │   └── queries.ts
│   ├── index.ts
│   ├── resources
│   │   ├── problem-resources.ts
│   │   └── user-resources.ts
│   ├── services
│   │   └── leetcode-service.ts
│   └── tools
│       ├── contest-tools.ts
│       ├── problem-tools.ts
│       └── user-tools.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
# Node.js
node_modules/
npm-debug.log
yarn-debug.log
yarn-error.log
# TypeScript
dist/
*.tsbuildinfo
# Environment
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# IDE and editors
.idea/
.vscode/
*.swp
*.swo
.DS_Store
# Logs
logs/
*.log
# Testing
coverage/
.nyc_output/
# Misc
.cache/
.temp/
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
# MCP Server LeetCode
[](https://www.npmjs.com/package/@mcpfun/mcp-server-leetcode)
[](https://github.com/doggybee/mcp-server-leetcode/blob/main/LICENSE)
[](https://github.com/doggybee/mcp-server-leetcode/releases)
[](https://smithery.ai/server/@doggybee/mcp-server-leetcode)
A Model Context Protocol (MCP) server for LeetCode that enables AI assistants to access LeetCode problems, user information, and contest data.
## Features
- 🚀 Fast access to LeetCode API
- 🔍 Search problems, retrieve daily challenges, and check user profiles
- 🏆 Query contest data and rankings
- 🧩 Full support for MCP tools and resources
- 📦 Provides both CLI and programmable API
## Installation
### Installing via Smithery
To install mcp-server-leetcode for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@doggybee/mcp-server-leetcode):
```bash
npx -y @smithery/cli install @doggybee/mcp-server-leetcode --client claude
```
### Global Installation
```bash
npm install -g @mcpfun/mcp-server-leetcode
```
Once installed, you can run it directly from the command line:
```bash
mcp-server-leetcode
```
### Local Installation
```bash
npm install @mcpfun/mcp-server-leetcode
```
## Usage
### Integration with Claude for Desktop
Add the following to your Claude for Desktop `claude_desktop_config.json` file:
```json
{
  "mcpServers": {
    "leetcode": {
      "command": "mcp-server-leetcode"
    }
  }
}
```
For local development:
```json
{
  "mcpServers": {
    "leetcode": {
      "command": "node",
      "args": ["/path/to/dist/index.js"]
    }
  }
}
```
### Use as a Library
```javascript
import { LeetCodeService } from '@mcpfun/mcp-server-leetcode';
// Initialize the service
const leetcodeService = new LeetCodeService();
// Get daily challenge
const dailyChallenge = await leetcodeService.getDailyChallenge();
// Search problems
const problems = await leetcodeService.searchProblems({
  difficulty: 'MEDIUM',
  tags: 'array+dynamic-programming'
});
```
## Available Tools
### Problem-related Tools
| Tool Name | Description | Parameters |
|--------|------|------|
| `get-daily-challenge` | Get the daily challenge | None |
| `get-problem` | Get details for a specific problem | `titleSlug` (string) |
| `search-problems` | Search for problems based on criteria | `tags` (optional), `difficulty` (optional), `limit` (default 20), `skip` (default 0) |
### User-related Tools
| Tool Name | Description | Parameters |
|--------|------|------|
| `get-user-profile` | Get user information | `username` (string) |
| `get-user-submissions` | Get user submission history | `username` (string), `limit` (optional, default 20) |
| `get-user-contest-ranking` | Get user contest rankings | `username` (string) |
### Contest-related Tools
| Tool Name | Description | Parameters |
|--------|------|------|
| `get-contest-details` | Get contest details | `contestSlug` (string) |
## Available Resources
### Problem Resources
- `leetcode://daily-challenge`: Daily challenge
- `leetcode://problem/{titleSlug}`: Problem details
- `leetcode://problems{?tags,difficulty,limit,skip}`: Problem list
### User Resources
- `leetcode://user/{username}/profile`: User profile
- `leetcode://user/{username}/submissions{?limit}`: User submissions
- `leetcode://user/{username}/contest-ranking`: User contest ranking
## Local Development
Clone the repository and install dependencies:
```bash
git clone https://github.com/doggybee/mcp-server-leetcode.git
cd mcp-server-leetcode
npm install
```
Run in development mode:
```bash
npm run dev
```
Build the project:
```bash
npm run build
```
## License
MIT
## Related Projects
- [Model Context Protocol](https://modelcontextprotocol.io) - MCP specifications and documentation
- [Claude for Desktop](https://claude.ai/download) - AI assistant with MCP support
## Acknowledgements
- This project was inspired by [alfa-leetcode-api](https://github.com/alfaarghya/alfa-leetcode-api)
```
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
```javascript
#!/usr/bin/env node
export * from './dist/index.js';
```
--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------
```yaml
# Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
startCommand:
  type: stdio
  configSchema:
    # JSON Schema defining the configuration options for the MCP.
    {}
  commandFunction:
    # A JS function that produces the CLI command based on the given config to start the MCP on stdio.
    |-
    (config) => ({ command: 'node', args: ['dist/index.js'] })
  exampleConfig: {}
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
    "sourceMap": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
```
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
# Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
FROM node:lts-alpine
# Create app directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install --ignore-scripts
# Copy the rest of the files
COPY . .
# Build the project
RUN npm run build
# Expose port if needed (optional) 
# EXPOSE 3000
# Start the MCP server
CMD [ "node", "dist/index.js" ]
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { LeetCodeService } from "./services/leetcode-service.js";
import { registerProblemTools } from "./tools/problem-tools.js";
import { registerUserTools } from "./tools/user-tools.js";
import { registerContestTools } from "./tools/contest-tools.js";
import { registerProblemResources } from "./resources/problem-resources.js";
import { registerUserResources } from "./resources/user-resources.js";
async function main() {
  // Create the MCP Server
  const server = new McpServer({
    name: "LeetCode MCP Server",
    version: "1.0.0"
  });
  // Initialize the LeetCode service
  const leetcodeService = new LeetCodeService();
  // Register tools
  registerProblemTools(server, leetcodeService);
  registerUserTools(server, leetcodeService);
  registerContestTools(server, leetcodeService);
  // Register resources
  registerProblemResources(server, leetcodeService);
  registerUserResources(server, leetcodeService);
  // Connect with stdio transport
  const transport = new StdioServerTransport();
  await server.connect(transport);
  
  console.error("LeetCode MCP Server running");
}
main().catch(error => {
  console.error("Fatal error:", error);
  process.exit(1);
});
```
--------------------------------------------------------------------------------
/src/tools/contest-tools.ts:
--------------------------------------------------------------------------------
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { LeetCodeService } from "../services/leetcode-service.js";
import { z } from "zod";
export function registerContestTools(server: McpServer, leetcodeService: LeetCodeService) {
  // Get contest details
  server.tool(
    "get-contest-details",
    {
      contestSlug: z.string().describe("The URL slug of the contest")
    },
    async ({ contestSlug }) => {
      try {
        const data = await leetcodeService.fetchContestDetails(contestSlug);
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(data, null, 2)
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
      }
    }
  );
  // Get user contest ranking
  server.tool(
    "get-user-contest-ranking",
    {
      username: z.string().describe("LeetCode username")
    },
    async ({ username }) => {
      try {
        const data = await leetcodeService.fetchUserContestRanking(username);
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(data, null, 2)
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
      }
    }
  );
}
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
{
  "name": "@mcpfun/mcp-server-leetcode",
  "version": "1.0.1",
  "description": "Model Context Protocol server for LeetCode using GraphQL",
  "type": "module",
  "main": "index.js",
  "bin": {
    "mcp-server-leetcode": "./dist/index.js"
  },
  "files": [
    "dist",
    "index.js",
    "README.md",
    "LICENSE"
  ],
  "scripts": {
    "build": "tsc && chmod +x dist/index.js",
    "start": "node dist/index.js",
    "dev": "tsc-watch --onSuccess \"node dist/index.js\"",
    "lint": "eslint src --ext .ts",
    "test": "jest",
    "prepublishOnly": "npm run build",
    "prepare": "npm run build"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.7.0",
    "axios": "^1.7.2",
    "apicache": "^1.6.3",
    "zod": "^3.22.4",
    "glob": "^10.3.10",
    "rimraf": "^5.0.5"
  },
  "devDependencies": {
    "@types/apicache": "^1.6.6",
    "@types/node": "^20.11.27",
    "@typescript-eslint/eslint-plugin": "^7.3.1",
    "@typescript-eslint/parser": "^7.3.1",
    "eslint": "^8.56.0",
    "jest": "^29.7.0",
    "ts-jest": "^29.1.2",
    "tsc-watch": "^6.0.4",
    "typescript": "^5.4.3"
  },
  "keywords": [
    "leetcode",
    "mcp",
    "model-context-protocol",
    "ai",
    "tools",
    "llm"
  ],
  "author": "",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/doggybee/mcp-server-leetcode.git"
  },
  "bugs": {
    "url": "https://github.com/doggybee/mcp-server-leetcode/issues"
  },
  "homepage": "https://github.com/doggybee/mcp-server-leetcode#readme",
  "publishConfig": {
    "access": "public"
  },
  "engines": {
    "node": ">=18"
  }
}
```
--------------------------------------------------------------------------------
/src/tools/user-tools.ts:
--------------------------------------------------------------------------------
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { LeetCodeService } from "../services/leetcode-service.js";
import { z } from "zod";
export function registerUserTools(server: McpServer, leetcodeService: LeetCodeService) {
  // Get user profile
  server.tool(
    "get-user-profile",
    {
      username: z.string().describe("LeetCode username")
    },
    async ({ username }) => {
      try {
        const data = await leetcodeService.fetchUserProfile(username);
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(data, null, 2)
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
      }
    }
  );
  // Get user submissions
  server.tool(
    "get-user-submissions",
    {
      username: z.string().describe("LeetCode username"),
      limit: z.number().min(1).max(100).optional().default(20).describe("Maximum number of submissions to return")
    },
    async ({ username, limit }) => {
      try {
        const data = await leetcodeService.fetchUserSubmissions(username, limit);
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(data, null, 2)
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
      }
    }
  );
}
```
--------------------------------------------------------------------------------
/src/tools/problem-tools.ts:
--------------------------------------------------------------------------------
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { LeetCodeService } from "../services/leetcode-service.js";
import { z } from "zod";
export function registerProblemTools(server: McpServer, leetcodeService: LeetCodeService) {
  // Get daily challenge
  server.tool(
    "get-daily-challenge",
    {},
    async () => {
      try {
        const data = await leetcodeService.fetchDailyChallenge();
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(data, null, 2)
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
      }
    }
  );
  // Get problem details
  server.tool(
    "get-problem",
    {
      titleSlug: z.string().describe("The URL slug of the problem (e.g., 'two-sum')")
    },
    async ({ titleSlug }) => {
      try {
        const data = await leetcodeService.fetchProblem(titleSlug);
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(data, null, 2)
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
      }
    }
  );
  // Search problems
  server.tool(
    "search-problems",
    {
      tags: z.string().optional().describe("Tags to filter by, separated by '+' (e.g., 'array+dynamic-programming')"),
      difficulty: z.enum(["EASY", "MEDIUM", "HARD"]).optional().describe("Difficulty level"),
      limit: z.number().min(1).max(100).optional().default(20).describe("Maximum number of problems to return"),
      skip: z.number().optional().default(0).describe("Number of problems to skip")
    },
    async ({ tags, difficulty, limit, skip }) => {
      try {
        const data = await leetcodeService.searchProblems(tags, difficulty, limit, skip);
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(data, null, 2)
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
      }
    }
  );
}
```
--------------------------------------------------------------------------------
/src/resources/user-resources.ts:
--------------------------------------------------------------------------------
```typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { LeetCodeService } from "../services/leetcode-service.js";
export function registerUserResources(server: McpServer, leetcodeService: LeetCodeService) {
  // User profile resource
  server.resource(
    "user-profile",
    new ResourceTemplate("leetcode://user/{username}/profile", { list: undefined }),
    async (uri, variables) => {
      const username = variables.username as string;
      try {
        const data = await leetcodeService.fetchUserProfile(username);
        return {
          contents: [{
            uri: uri.href,
            text: JSON.stringify(data, null, 2),
            mimeType: "application/json"
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to fetch user profile: ${errorMessage}`);
      }
    }
  );
  // User submissions resource
  server.resource(
    "user-submissions",
    new ResourceTemplate("leetcode://user/{username}/submissions{?limit}", { list: undefined }),
    async (uri, variables) => {
      const username = variables.username as string;
      const limit = variables.limit as string | undefined;
      try {
        const data = await leetcodeService.fetchUserSubmissions(
          username, 
          parseInt(limit as string || "20")
        );
        return {
          contents: [{
            uri: uri.href,
            text: JSON.stringify(data, null, 2),
            mimeType: "application/json"
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to fetch user submissions: ${errorMessage}`);
      }
    }
  );
  // User contest ranking resource
  server.resource(
    "user-contest-ranking",
    new ResourceTemplate("leetcode://user/{username}/contest-ranking", { list: undefined }),
    async (uri, variables) => {
      const username = variables.username as string;
      try {
        const data = await leetcodeService.fetchUserContestRanking(username);
        return {
          contents: [{
            uri: uri.href,
            text: JSON.stringify(data, null, 2),
            mimeType: "application/json"
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to fetch user contest ranking: ${errorMessage}`);
      }
    }
  );
}
```
--------------------------------------------------------------------------------
/src/resources/problem-resources.ts:
--------------------------------------------------------------------------------
```typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { LeetCodeService } from "../services/leetcode-service.js";
export function registerProblemResources(server: McpServer, leetcodeService: LeetCodeService) {
  // Daily challenge resource
  server.resource(
    "daily-challenge",
    "leetcode://daily-challenge",
    async (uri) => {
      try {
        const data = await leetcodeService.fetchDailyChallenge();
        return {
          contents: [{
            uri: uri.href,
            text: JSON.stringify(data, null, 2),
            mimeType: "application/json"
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to fetch daily challenge: ${errorMessage}`);
      }
    }
  );
  // Problem details resource
  server.resource(
    "problem-details",
    new ResourceTemplate("leetcode://problem/{titleSlug}", { list: undefined }),
    async (uri, variables) => {
      const titleSlug = variables.titleSlug as string;
      try {
        const data = await leetcodeService.fetchProblem(titleSlug);
        return {
          contents: [{
            uri: uri.href,
            text: JSON.stringify(data, null, 2),
            mimeType: "application/json"
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to fetch problem details: ${errorMessage}`);
      }
    }
  );
  // Problems list resource
  server.resource(
    "problems-list",
    new ResourceTemplate("leetcode://problems{?tags,difficulty,limit,skip}", { list: undefined }),
    async (uri, variables) => {
      const tags = variables.tags as string | undefined;
      const difficulty = variables.difficulty as string | undefined;
      const limit = variables.limit as string | undefined;
      const skip = variables.skip as string | undefined;
      try {
        const data = await leetcodeService.searchProblems(
          tags as string | undefined, 
          difficulty as string | undefined, 
          parseInt(limit as string || "20"),
          parseInt(skip as string || "0")
        );
        return {
          contents: [{
            uri: uri.href,
            text: JSON.stringify(data, null, 2),
            mimeType: "application/json"
          }]
        };
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to fetch problems list: ${errorMessage}`);
      }
    }
  );
}
```
--------------------------------------------------------------------------------
/src/services/leetcode-service.ts:
--------------------------------------------------------------------------------
```typescript
import axios, { AxiosInstance } from "axios";
import {
  userProfileQuery,
  userSubmissionsQuery,
  dailyChallengeQuery,
  problemDetailsQuery,
  searchProblemsQuery,
  contestDetailsQuery,
  userContestRankingQuery
} from "../graphql/queries.js";
export class LeetCodeService {
  private readonly API_URL = "https://leetcode.com/graphql";
  private readonly http: AxiosInstance;
  
  constructor() {
    this.http = axios.create({
      headers: {
        "Content-Type": "application/json",
        "Referer": "https://leetcode.com"
      }
    });
  }
  /**
   * Execute a GraphQL query against the LeetCode API
   */
  private async executeQuery(query: string, variables: Record<string, any> = {}) {
    try {
      const response = await this.http.post(this.API_URL, {
        query,
        variables
      });
      
      if (response.data.errors) {
        throw new Error(response.data.errors[0].message);
      }
      
      return response.data.data;
    } catch (error: unknown) {
      if (error && typeof error === 'object' && 'response' in error && error.response) {
        const axiosError = error as { response: { status: number, data?: any } };
        throw new Error(`API Error: ${axiosError.response.status} - ${axiosError.response.data?.message || JSON.stringify(axiosError.response.data)}`);
      } else if (error && typeof error === 'object' && 'request' in error) {
        throw new Error("Network Error: No response received from LeetCode API");
      }
      // 如果是其他类型的错误,转换为Error类型
      if (error instanceof Error) {
        throw error;
      }
      throw new Error(String(error));
    }
  }
  /**
   * Fetch user profile data
   */
  async fetchUserProfile(username: string) {
    return this.executeQuery(userProfileQuery, { username });
  }
  /**
   * Fetch user submissions
   */
  async fetchUserSubmissions(username: string, limit: number = 20) {
    return this.executeQuery(userSubmissionsQuery, { username, limit });
  }
  /**
   * Fetch the daily challenge
   */
  async fetchDailyChallenge() {
    return this.executeQuery(dailyChallengeQuery);
  }
  /**
   * Fetch details about a specific problem
   */
  async fetchProblem(titleSlug: string) {
    return this.executeQuery(problemDetailsQuery, { titleSlug });
  }
  /**
   * Search for problems matching criteria
   */
  async searchProblems(tags?: string, difficulty?: string, limit: number = 20, skip: number = 0) {
    return this.executeQuery(searchProblemsQuery, { 
      categorySlug: "",
      limit,
      skip,
      filters: {
        tags: tags ? tags.split("+") : [],
        difficulty: difficulty || null
      }
    });
  }
  /**
   * Fetch contest details
   */
  async fetchContestDetails(contestSlug: string) {
    return this.executeQuery(contestDetailsQuery, { contestSlug });
  }
  /**
   * Fetch user contest ranking
   */
  async fetchUserContestRanking(username: string) {
    return this.executeQuery(userContestRankingQuery, { username });
  }
}
```
--------------------------------------------------------------------------------
/src/graphql/queries.ts:
--------------------------------------------------------------------------------
```typescript
export const userProfileQuery = `
  query getUserProfile($username: String!) {
    matchedUser(username: $username) {
      username
      submitStats: submitStatsGlobal {
        acSubmissionNum {
          difficulty
          count
          submissions
        }
        totalSubmissionNum {
          difficulty
          count
          submissions
        }
      }
      profile {
        ranking
        reputation
        starRating
        realName
        aboutMe
        userAvatar
        skillTags
        country
        company
        school
        websites
        countryName
        location
        contestCount
        asciiCode
        socialAccounts
        skillSet {
          langLevels {
            langName
            langVerboseName
            level
          }
          topics {
            slug
            name
            level
          }
        }
      }
    }
  }
`;
export const userSubmissionsQuery = `
  query recentSubmissions($username: String!, $limit: Int!) {
    recentSubmissionList(username: $username, limit: $limit) {
      id
      title
      titleSlug
      timestamp
      statusDisplay
      lang
      __typename
    }
  }
`;
export const dailyChallengeQuery = `
  query questionOfToday {
    activeDailyCodingChallengeQuestion {
      date
      userStatus
      link
      question {
        acRate
        difficulty
        freqBar
        frontendQuestionId: questionFrontendId
        isFavor
        paidOnly: isPaidOnly
        status
        title
        titleSlug
        hasVideoSolution
        hasSolution
        topicTags {
          name
          id
          slug
        }
      }
    }
  }
`;
export const problemDetailsQuery = `
  query questionData($titleSlug: String!) {
    question(titleSlug: $titleSlug) {
      questionId
      questionFrontendId
      boundTopicId
      title
      titleSlug
      content
      translatedTitle
      difficulty
      likes
      dislikes
      isLiked
      similarQuestions
      exampleTestcases
      contributors {
        username
        profileUrl
        avatarUrl
      }
      topicTags {
        name
        slug
      }
      companyTagStats
      codeSnippets {
        lang
        langSlug
        code
      }
      stats
      hints
      solution {
        id
        canSeeDetail
        paidOnly
        hasVideoSolution
      }
      status
      sampleTestCase
      metaData
      judgerAvailable
      judgeType
      mysqlSchemas
      enableRunCode
      enableTestMode
      enableDebugger
      envInfo
    }
  }
`;
export const searchProblemsQuery = `
  query problemsetQuestionList($categorySlug: String, $limit: Int, $skip: Int, $filters: QuestionListFilterInput) {
    problemsetQuestionList: questionList(
      categorySlug: $categorySlug
      limit: $limit
      skip: $skip
      filters: $filters
    ) {
      total: totalNum
      questions: data {
        acRate
        difficulty
        freqBar
        frontendQuestionId: questionFrontendId
        isFavor
        paidOnly: isPaidOnly
        status
        title
        titleSlug
        topicTags {
          name
          id
          slug
        }
        hasSolution
        hasVideoSolution
      }
    }
  }
`;
export const contestDetailsQuery = `
  query contestData($contestSlug: String!) {
    contest(titleSlug: $contestSlug) {
      title
      titleSlug
      description
      startTime
      duration
      originStartTime
      isVirtual
      questions {
        questionId
        title
        titleSlug
        difficulty
      }
    }
  }
`;
export const userContestRankingQuery = `
  query userContestRankingInfo($username: String!) {
    userContestRanking(username: $username) {
      attendedContestsCount
      rating
      globalRanking
      totalParticipants
      topPercentage
      badge {
        name
      }
    }
    userContestRankingHistory(username: $username) {
      attended
      trendDirection
      problemsSolved
      totalProblems
      finishTimeInSeconds
      rating
      ranking
      contest {
        title
        startTime
      }
    }
  }
`;
```