Skip to main content
Glama
xinmu-wyb

Resume Filter MCP Server

by xinmu-wyb

search_resumes

Search and rank resumes by keywords, position, skills, experience, and education to find qualified candidates for specific job requirements.

Instructions

根据关键词、职位、技能、经验等条件搜索和排序简历。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keywordNo搜索关键词,会在姓名、职位、摘要、技能中搜索
positionNo职位名称,例如:前端工程师、Java开发
skillsNo所需技能列表,例如:["Java", "Spring", "MySQL"]
minYearsOfExperienceNo最低工作年限
maxYearsOfExperienceNo最高工作年限
educationNo教育背景,例如:本科、硕士
sortByNo排序方式:relevance(相关性)、date(日期)、experience(经验)、name(姓名)relevance
sortOrderNo排序顺序:asc(升序)、desc(降序)desc
limitNo返回结果数量限制,默认50
offsetNo分页偏移量,默认0

Implementation Reference

  • MCP tool handler for 'search_resumes': maps tool arguments to SearchResumeDto, calls resumeService.searchResumes, formats and returns JSON response.
    case 'search_resumes': {
      const searchDto: SearchResumeDto = {
        keyword: args.keyword as string | undefined,
        position: args.position as string | undefined,
        skills: args.skills as string[] | undefined,
        minYearsOfExperience: args.minYearsOfExperience as number | undefined,
        maxYearsOfExperience: args.maxYearsOfExperience as number | undefined,
        education: args.education as string | undefined,
        sortBy: (args.sortBy as any) || 'relevance',
        sortOrder: (args.sortOrder as any) || 'desc',
        limit: args.limit as number | undefined,
        offset: args.offset as number | undefined,
      };
    
      const result = await this.resumeService.searchResumes(searchDto);
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(
              {
                success: true,
                total: result.total,
                limit: result.limit,
                offset: result.offset,
                resumes: result.resumes.map((r) => ({
                  id: r.id,
                  name: r.name,
                  position: r.position,
                  email: r.email,
                  phone: r.phone,
                  yearsOfExperience: r.yearsOfExperience,
                  skills: r.skills,
                  education: r.education,
                  university: r.university,
                  major: r.major,
                  summary: r.summary,
                  score: r.score,
                  receivedDate: r.receivedDate?.toISOString(),
                  // 添加下载相关字段
                  fileName: r.fileName,
                  filePath: r.filePath,
                  downloadUri: r.filePath ? `resume://download/${r.id}` : undefined,
                })),
              },
              null,
              2,
            ),
          },
        ],
      };
    }
  • Input JSON schema for the 'search_resumes' tool defining all search parameters, sorting options, and pagination.
    inputSchema: {
      type: 'object',
      properties: {
        keyword: {
          type: 'string',
          description: '搜索关键词,会在姓名、职位、摘要、技能中搜索',
        },
        position: {
          type: 'string',
          description: '职位名称,例如:前端工程师、Java开发',
        },
        skills: {
          type: 'array',
          items: { type: 'string' },
          description: '所需技能列表,例如:["Java", "Spring", "MySQL"]',
        },
        minYearsOfExperience: {
          type: 'number',
          description: '最低工作年限',
        },
        maxYearsOfExperience: {
          type: 'number',
          description: '最高工作年限',
        },
        education: {
          type: 'string',
          description: '教育背景,例如:本科、硕士',
        },
        sortBy: {
          type: 'string',
          enum: ['relevance', 'date', 'experience', 'name'],
          description:
            '排序方式:relevance(相关性)、date(日期)、experience(经验)、name(姓名)',
          default: 'relevance',
        },
        sortOrder: {
          type: 'string',
          enum: ['asc', 'desc'],
          description: '排序顺序:asc(升序)、desc(降序)',
          default: 'desc',
        },
        limit: {
          type: 'number',
          description: '返回结果数量限制,默认50',
          default: 50,
        },
        offset: {
          type: 'number',
          description: '分页偏移量,默认0',
          default: 0,
        },
      },
    },
  • Registration of 'search_resumes' tool in the ListToolsRequestSchema handler, including name, description, and input schema.
    {
      name: 'search_resumes',
      description: '根据关键词、职位、技能、经验等条件搜索和排序简历。',
      inputSchema: {
        type: 'object',
        properties: {
          keyword: {
            type: 'string',
            description: '搜索关键词,会在姓名、职位、摘要、技能中搜索',
          },
          position: {
            type: 'string',
            description: '职位名称,例如:前端工程师、Java开发',
          },
          skills: {
            type: 'array',
            items: { type: 'string' },
            description: '所需技能列表,例如:["Java", "Spring", "MySQL"]',
          },
          minYearsOfExperience: {
            type: 'number',
            description: '最低工作年限',
          },
          maxYearsOfExperience: {
            type: 'number',
            description: '最高工作年限',
          },
          education: {
            type: 'string',
            description: '教育背景,例如:本科、硕士',
          },
          sortBy: {
            type: 'string',
            enum: ['relevance', 'date', 'experience', 'name'],
            description:
              '排序方式:relevance(相关性)、date(日期)、experience(经验)、name(姓名)',
            default: 'relevance',
          },
          sortOrder: {
            type: 'string',
            enum: ['asc', 'desc'],
            description: '排序顺序:asc(升序)、desc(降序)',
            default: 'desc',
          },
          limit: {
            type: 'number',
            description: '返回结果数量限制,默认50',
            default: 50,
          },
          offset: {
            type: 'number',
            description: '分页偏移量,默认0',
            default: 0,
          },
        },
      },
    },
  • ResumeService.searchResumes helper: retrieves all resumes and delegates search to searchService.search
    async searchResumes(criteria: ISearchCriteria): Promise<ISearchResult> {
      try {
        const allResumes = Array.from(this.resumes.values());
        const results = await this.searchService.search(allResumes, criteria);
    
        return {
          resumes: results.resumes,
          total: results.total,
          limit: criteria.limit || this.configService.get<number>('search.defaultLimit') || 50,
          offset: criteria.offset || 0,
        };
      } catch (error) {
        this.logger.error(`搜索简历失败: ${error.message}`, error.stack, 'ResumeService');
        throw error;
      }
    }
  • Core searchService.search helper: calculates relevance scores, filters, sorts, and paginates resumes based on criteria.
    async search(resumes: IResume[], criteria: ISearchCriteria): Promise<ISearchResult> {
      try {
        // 计算每个简历的评分
        const scoredResumes: ScoredResume[] = resumes.map((resume) => ({
          ...resume,
          score: this.calculateScore(resume, criteria),
        }));
    
        // 过滤掉评分为0的简历
        const filteredResumes = scoredResumes.filter((resume) => resume.score > 0);
    
        // 排序
        const sortedResumes = this.sortResumes(filteredResumes, criteria);
    
        // 分页
        const limit = criteria.limit || 50;
        const offset = criteria.offset || 0;
        const paginatedResumes = sortedResumes.slice(offset, offset + limit);
    
        return {
          resumes: paginatedResumes,
          total: sortedResumes.length,
          limit,
          offset,
        };
      } catch (error) {
        this.logger.error(`搜索失败: ${error.message}`, error.stack, 'SearchService');
        throw error;
      }
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xinmu-wyb/mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server