Skip to main content
Glama
xinmu-wyb

Resume Filter MCP Server

by xinmu-wyb

简历筛选 MCP 服务器

基于 Nest.js 开发的 Model Context Protocol (MCP) 服务器,用于从邮箱中智能筛选和排序简历。

功能特性

  • 📧 邮件集成: 自动从邮箱中提取简历附件

  • 📄 多格式支持: 支持 PDF、DOC、DOCX 格式的简历解析

  • 🔍 智能搜索: 基于关键词、职位、技能、经验等多维度搜索

  • 📊 智能排序: 支持按相关性、日期、经验、姓名排序

  • 📈 数据分析: 提供简历统计信息(按职位、经验、教育背景分布)

  • 🛠️ MCP 协议: 与 AI 助手(Claude、ChatGPT)无缝集成

  • 📝 完整日志: 文件日志和控制台日志

Related MCP server: boss-zhipin-mcp

技术栈

  • 框架: Nest.js + TypeScript

  • MCP 协议: @modelcontextprotocol/sdk

  • 邮件处理: imap-simple

  • 文件解析: pdf-parse + mammoth

  • 数据验证: class-validator + class-transformer

  • 配置管理: @nestjs/config

安装

# 安装依赖
npm install

# 或使用 yarn
yarn install

配置

  1. 复制环境变量示例文件:

cp .env.example .env
  1. 编辑 .env 文件,配置邮件服务器信息:

# 邮件服务器配置
IMAP_HOST=imap.163.com
IMAP_PORT=993
IMAP_SECURE=true
IMAP_USER=your-email@163.com
IMAP_PASS=your-authorization-code
IMAP_MAILBOX=INBOX

# 其他配置...

163 邮箱配置说明

如果使用 163 邮箱,需要:

  1. 登录 163 邮箱网页版:https://mail.163.com

  2. 进入"设置" → "POP3/SMTP/IMAP"

  3. 开启"IMAP/SMTP服务"

  4. 生成授权码(不是登录密码)

  5. 使用授权码作为 IMAP_PASS,邮箱地址作为 IMAP_USER

部署

详细的部署指南请参考 DEPLOYMENT.md,包含以下部署方式:

  • 直接部署:适用于快速测试和开发

  • PM2 部署:推荐用于生产环境,支持进程管理和自动重启

  • Docker 部署:容器化部署,便于管理和扩展

  • 系统服务部署:使用 systemd 实现开机自启

使用

开发模式

npm run start:dev

生产模式

# 构建
npm run build

# 运行
npm run start:prod

作为 MCP 服务器使用

在 Claude Desktop 或其他支持 MCP 的客户端中配置:

{
  "mcpServers": {
    "resume-filter": {
      "command": "node",
      "args": ["/path/to/mcp-resume/dist/src/main.js"]
    }
  }
}

注意: NestJS 构建后的文件在 dist/src/ 目录下,路径应该是 dist/src/main.js

MCP 工具

服务器提供以下工具供 AI 助手调用:

1. fetch_resumes_from_email

从邮箱中获取新的简历。

参数:

  • since (可选): ISO 8601 格式的日期,获取此日期之后的邮件

  • limit (可选): 最多获取的邮件数量,默认 50

示例:

{
  "since": "2024-01-01T00:00:00Z",
  "limit": 20
}

2. search_resumes

根据条件搜索和排序简历。

参数:

  • keyword (可选): 搜索关键词

  • position (可选): 职位名称

  • skills (可选): 技能数组

  • minYearsOfExperience (可选): 最低工作年限

  • maxYearsOfExperience (可选): 最高工作年限

  • education (可选): 教育背景

  • sortBy (可选): 排序方式 (relevance/date/experience/name)

  • sortOrder (可选): 排序顺序 (asc/desc)

  • limit (可选): 返回结果数量

  • offset (可选): 分页偏移量

示例:

{
  "keyword": "Java",
  "position": "后端工程师",
  "skills": ["Spring", "MySQL"],
  "minYearsOfExperience": 3,
  "sortBy": "relevance",
  "limit": 20
}

3. get_resume_by_id

根据 ID 获取单个简历的详细信息。

参数:

  • id (必需): 简历 ID

4. get_all_resumes

获取所有简历的列表。

5. delete_resume

根据 ID 删除简历及其文件。

参数:

  • id (必需): 要删除的简历 ID

6. get_statistics

获取简历统计信息。

MCP 资源

服务器提供以下资源:

  • resume://all: 所有简历列表

  • resume://statistics: 简历统计信息

项目结构

src/
├── common/           # 通用模块
│   ├── dto/         # 数据传输对象
│   ├── interfaces/  # 接口定义
│   └── logger/      # 日志服务
├── config/           # 配置
├── email/            # 邮件服务
├── mcp/              # MCP 服务器
├── parser/           # 文件解析
├── resume/           # 简历服务
├── search/           # 搜索服务
├── app.module.ts     # 应用模块
└── main.ts           # 入口文件

搜索算法

搜索使用多维度评分系统:

  • 关键词匹配 (30%): 在姓名、职位、摘要、技能中搜索

  • 职位匹配 (25%): 职位名称匹配

  • 技能匹配 (20%): 技能列表匹配

  • 经验匹配 (15%): 工作年限匹配

  • 教育背景 (10%): 教育背景匹配

最终分数在 0-1 之间,分数越高表示匹配度越高。

日志

日志文件保存在 ./logs 目录下,按日期命名(例如:app-2024-01-01.log)。

可以通过环境变量配置日志级别和文件设置。

开发

# 代码格式化
npm run format

# 代码检查
npm run lint

# 运行测试
npm test

许可证

MIT

贡献

欢迎提交 Issue 和 Pull Request!

Available Tools

6 tools
delete_resumeC

根据ID删除简历及其文件。

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes要删除的简历ID

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It states this is a deletion operation but doesn't mention whether this is permanent, if files are also deleted, what permissions are required, or what happens on success/failure. For a destructive tool with zero annotation coverage, this is inadequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that communicates the core functionality without any wasted words. It's appropriately sized for a simple deletion tool and gets straight to the point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive deletion tool with no annotations and no output schema, the description is insufficient. It doesn't explain what '及其文件' (and its files) entails, doesn't mention error conditions or success responses, and provides no safety warnings despite this being an irreversible operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the single parameter 'id' clearly documented as '要删除的简历ID' (resume ID to delete). The description adds no additional parameter semantics beyond what the schema already provides, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('删除' - delete) and resource ('简历及其文件' - resume and its files), making the purpose immediately understandable. It doesn't specifically differentiate from sibling tools like 'fetch_resumes_from_email' or 'get_resume_by_id', but the destructive nature is clear from the verb 'delete'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to use this tool versus alternatives. The description doesn't mention prerequisites (like needing the resume ID first), nor does it warn about irreversible deletion or suggest using read-only sibling tools for verification before deletion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_resumes_from_emailC

从邮箱中获取新的简历。可以指定时间范围和数量限制。

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo获取此日期之后的邮件(ISO 8601格式,例如:2024-01-01T00:00:00Z)
limitNo最多获取的邮件数量,默认50

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It states the tool fetches 'new' resumes from email, implying it might only retrieve recent or unprocessed items, but doesn't clarify what 'new' means (e.g., unread, recent arrivals). It lacks details on authentication needs, rate limits, error handling, or what constitutes a 'resume' in this context (e.g., attachments, parsed content).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise—two sentences that directly state the purpose and key parameters. It is front-loaded with the core function, and every sentence adds value without redundancy. No wasted words or unnecessary details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no annotations and no output schema, the description is incomplete. It doesn't explain what the tool returns (e.g., list of resumes, raw emails, parsed data), error conditions, or behavioral traits like how 'new' is determined. For a tool that interacts with email and resumes, more context on output and constraints is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description mentions time range and quantity limits, which align with the two parameters in the schema (since and limit). Since schema description coverage is 100%, the schema already documents these parameters well (e.g., ISO 8601 format, default limit of 50). The description adds minimal value beyond what the schema provides, meeting the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: '从邮箱中获取新的简历' (fetch new resumes from email). It specifies the verb (fetch/获取) and resource (resumes/简历) with the source (email/邮箱). However, it doesn't explicitly differentiate from sibling tools like 'get_all_resumes' or 'search_resumes' in terms of source or newness criteria.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It mentions time range and quantity limits as parameters, but doesn't explain scenarios where this tool is preferred over siblings like 'get_all_resumes' (which might fetch from a database) or 'search_resumes' (which might allow filtering). No exclusions or prerequisites are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_all_resumesC

获取所有简历的列表。

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the action ('获取所有简历的列表') but doesn't add context on traits like pagination, rate limits, permissions, or response format. For a tool with zero annotation coverage, this is a significant gap in transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence ('获取所有简历的列表') that directly states the purpose without waste. It's appropriately sized for a simple tool, though it could be slightly more structured if it included brief usage notes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (0 parameters, no output schema), the description is minimal but incomplete. It lacks behavioral context (e.g., how 'all' is handled, potential limitations) and doesn't leverage the absence of annotations to provide necessary usage or transparency details. For a list retrieval tool, more completeness is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description doesn't add parameter details, which is appropriate here. Baseline is 4 for zero parameters, as the schema fully covers the absence of inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the purpose ('获取所有简历的列表' translates to 'Get a list of all resumes'), which is a clear verb+resource combination. However, it doesn't differentiate from sibling tools like 'fetch_resumes_from_email' or 'search_resumes', leaving ambiguity about scope or filtering. It's not tautological but lacks specificity about what 'all' entails.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The description doesn't mention contexts like unfiltered retrieval, prerequisites, or comparisons to siblings such as 'search_resumes' for filtered queries or 'get_resume_by_id' for single records. This leaves the agent without explicit usage instructions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_resume_by_idC

根据ID获取单个简历的详细信息。

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes简历ID

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It states this is a retrieval operation ('获取'), which implies read-only behavior, but doesn't disclose any behavioral traits like authentication requirements, rate limits, error conditions, or what happens if the ID doesn't exist. For a tool with zero annotation coverage, this is inadequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded with the core purpose. No wasted words, though it could be slightly more informative given the lack of annotations. Appropriately sized for a simple retrieval tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations and no output schema, the description is incomplete. It doesn't explain what '详细信息' (detailed information) includes, potential response formats, error handling, or behavioral constraints. Given the simplicity (1 parameter, 100% schema coverage), it's minimally adequate but leaves significant gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the single parameter 'id' documented as '简历ID' (resume ID). The description adds minimal value beyond the schema, only reinforcing that retrieval is '根据ID' (by ID). Baseline 3 is appropriate when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('获取' - get/retrieve) and resource ('简历' - resume), specifying it's for a single resume by ID. It distinguishes from siblings like 'get_all_resumes' by specifying '单个' (single) and '根据ID' (by ID), though it doesn't explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives like 'get_all_resumes' or 'search_resumes'. The description implies usage when you have a specific resume ID, but doesn't state when not to use it or name specific alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_statisticsB

获取简历统计信息,包括总数、按职位分布、按经验分布、按教育背景分布。

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. While '获取' (get) implies a read operation, the description doesn't specify whether this requires authentication, has rate limits, returns paginated results, or provides real-time vs. cached data. For a tool with zero annotation coverage, this leaves significant behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that lists the statistical breakdowns (total, by position, by experience, by education). It's appropriately sized for a no-parameter tool and front-loads the core purpose. However, it could be slightly more structured by explicitly separating the core function from the breakdown details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (simple read operation with no parameters) and the absence of both annotations and an output schema, the description is minimally adequate. It states what statistics are returned but doesn't explain the format, units, or any limitations. For a statistical tool, more detail on output structure would be helpful, but the lack of parameters reduces the burden.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and schema description coverage is 100% (since there are no parameters to describe). The description doesn't need to compensate for any parameter gaps, so a baseline of 4 is appropriate. No parameter semantics are needed beyond what the empty schema already indicates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: '获取简历统计信息' (get resume statistics) with specific breakdowns by position, experience, and education background. It uses a specific verb ('获取') and resource ('简历统计信息'), but doesn't explicitly distinguish it from sibling tools like 'get_all_resumes' or 'search_resumes' in terms of statistical vs. data retrieval functions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention when to prefer statistical summaries over fetching individual resumes or searching, nor does it specify any prerequisites or exclusions for usage. The agent must infer usage from the tool name and description alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_resumesC

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

ParametersJSON 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

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions searching and sorting but doesn't describe what the tool returns (e.g., list of resumes with specific fields), pagination behavior (implied by limit/offset but not explained), error conditions, rate limits, or authentication requirements. For a search tool with 10 parameters, this leaves significant gaps in understanding its operational behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence in Chinese that directly states the tool's core functionality. It's appropriately front-loaded with the main action and covers the essential search dimensions without unnecessary elaboration. Every word contributes to understanding the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with 10 parameters and no output schema, the description is insufficient. It doesn't explain what constitutes a search result, the format of returned data, how multiple criteria combine (AND/OR logic), or performance characteristics. Without annotations and with complex filtering options, users need more context to use this tool effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all parameters are well-documented in the schema itself. The description adds minimal value beyond the schema by listing the search criteria types (keywords, position, skills, experience) but doesn't provide additional context about how these parameters interact, their relative importance, or search logic. This meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as searching and sorting resumes based on specific criteria (keywords, position, skills, experience). It uses the verb '搜索和排序' (search and sort) with the resource '简历' (resumes). However, it doesn't explicitly differentiate from sibling tools like 'get_all_resumes' or 'fetch_resumes_from_email', which would require more specific scope definition.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'get_all_resumes' (which might retrieve all resumes without filtering) or 'fetch_resumes_from_email' (which appears to source from a specific channel). There's no mention of prerequisites, performance considerations, or typical use cases beyond the basic functionality.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updates
    • First observeddelete_resume
    • First observedfetch_resumes_from_email
    • First observedget_all_resumes
    • First observedget_resume_by_id
    • First observedget_statistics
    • First observedsearch_resumes

TDQS

A3.5/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose with no overlap: delete, fetch from email, list all, get by ID, get statistics, and search. The descriptions reinforce distinct actions on the resume domain, making misselection unlikely.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case (e.g., delete_resume, fetch_resumes_from_email, get_all_resumes). This predictability aids agent understanding and tool selection.

Tool Count5/5

With 6 tools, this server is well-scoped for resume management. Each tool serves a clear function (CRUD-like operations, fetching, searching, statistics), and the count is appropriate for the domain without being too sparse or bloated.

Completeness4/5

The tool set covers core operations for resume management: create (implied via fetch from email), read (get all, get by ID, search), delete, and analytics (statistics). A minor gap is the lack of an explicit update tool for modifying resumes, but agents can work around this by re-fetching or using other methods.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers