15分钟开发一个周报生成mcp,再也不用为写周报发愁了

前言

相信大部分程序员都有这样的经历:周一到周五忙的天昏地暗但是到了周五下班前写周报时又回忆不起来具体干了点啥,像是做了很多事但好像又什么也没做。为了应对这种情况我会在每天完成一件任务或需求时将其记录下来,但是有时候忘记了就不得不再去需求池里翻了。

与其他职业不同,程序员的工作大部分还是和代码打交道的,我们一周内的具体工作内容都反映在项目中的git提交记录里,所以我们可以基于一周内的git提交记录按照周报模版promp生成周报,先给大家看下效果:

开发准备

安装python3.12uv,使用Homebrew安装非常简单,执行两个命令即可:

  • 安装python

    brew install python@3.12

  • 安装uv

    brew install uv

  • 新建项目 mcp-git-weekly-report并创建weekly_report.py文件

  • 在weekly_report.py中安装fastmcp依赖并创建mcp

    使用 uv pip install fastmcppip install fastmcp 安装依赖后创建mcp:

    from fastmcp import FastMCP
    #默认是Stdio协议,所以我们这个mcp服务器实际上是在本地运行的
    mcp = FastMCP("weekly-report")

这里简单的介绍下FastMCP框架,FastMCP 是一个 Python 框架,它极大地简化了 MCP 服务器的开发过程。 它的名字中的 "Fast" 就暗示了其目标:让开发者能够快速构建 MCP 服务器。

FastMCP 的核心特点和优势

  • 极简的 API:使用装饰器(如 @mcp.tool)将普通的 Python 函数直接"变成" MCP 工具。你几乎不需要关心底层的协议细节。

  • 基于 Pydantic:天然支持使用 Pydantic 模型来定义工具输入输出的数据类型,确保类型安全和清晰的文档。

  • 资源管理:提供了简单的方式来管理资源(如数据库连接),可以在服务器启动时建立连接,并在结束时自动关闭。

  • 内置常用功能:它预置了许多常见的 MCP 服务器功能,例如:

    复制代码
    文件系统访问:让 AI 可以读写指定目录的文件。
    
    SQL 数据库查询:让 AI 可以直接查询数据库。
    
    代码执行:提供安全的代码执行环境。
    
    HTTP 请求:简化了对外部 API 的调用。
  • 开发友好:支持简单的命令行指令来运行和测试服务器。

如果你想要对mcp服务做出更精准的控制和定制,可以使用官方提供的更底层的sdk,详情请见官方文档:https://github.com/modelcontextprotocol/python-sdk?tab=readme-ov-file#tools

开发

设计思路

我们使用git log命令获取提交记录,完整的指令格式形如:

复制代码
git log --author=cube.li --since='3 days ago' --pretty='format:%ad|%s' --date=short

为了能够成功执行这条指令,我们需要知道以下参数:

1、 项目地址,由于周报mcp服务是运行在本地的,所以项目地址是一个本地绝对路径,项目地址要做成可配置的且能够灵活更改,所以我们将其作为mcp服务器的环境变量注入,并使用"|"作为分隔符以支持多项目

2、git 用户名称 ,用户名可通过git config user.name获取,不需要传入

3、日期范围,周报默认是当前周(7天内),但是我们也支持指定日期范围内的工作总结,例如:写3天内的工作总结,写15天内的工作总结,所以我们将其使用大模型识别作为参数传递到mcp服务器中

当我们具备以上信息后就能够成功获取到git提交记录并返回到AI应用了,但是只做到这一步还无法对周报内容、格式、字数进行限制,AI应用获取到提交记录后会自己发挥生成周报,当然我们可以在要求写周报时再输入特定的要求,但这样使用不够方便,所以我们要在mcp服务器中预制好周报模版prompt,返回AI应用时将 周报模版prompt+提交记录 一并返回给AI应用,这样既不用每次输入周报要求也能够生成符合要求的周报了。

周报模版prompt内容如下:

复制代码
你是一个专业的周报生成器,根据 Git 提交记录生成一份专业的工作周报。

## 📋 要求
1. **分类整理**:将提交按功能开发、Bug修复、性能优化、文档更新等分类,如果提交记录不涉及某一个分类则周报不需要体现出该分类
2. **提炼要点**:从 commit message 中提炼关键工作内容,如果多个commit message内容相似,你需要使用简洁、清晰的语言对其进行汇总而不是使用冗余的方式表达
3. **专业表述**:使用专业的技术语言,简洁明了
4. **格式规范**:使用清晰的 Markdown 格式
5. **跨项目视角**:总结跨项目的技术积累和工作思路
6. **字数限制**:字数控制在100-300字,务必要使用简洁、精炼但明确的方式进行总结


输出格式如下:
## 一、工作概述
[用2-3句话总结本周主要工作内容和成果]

## 二、详细工作内容

### 2.1 功能开发
- [功能1]:[详细描述功能内容和技术实现]
- [功能2]:[详细描述]

### 2.2 Bug修复
- [问题1]:[问题描述] → [解决方案]
- [问题2]:[问题描述] → [解决方案]

### 2.3 性能优化
- [优化项1]:[优化内容和效果]

### 2.4 其他工作
- [文档更新、代码重构等]

## 三、技术总结
[本周工作中的技术亮点、经验总结或遇到的技术挑战]


##git提交记录:

为了方便调试开发中的mcp,可以安装官方提供的MCP Inspector,也可以使用Claude Desktop cursor进行调试。由于我是cursor的重度用户,所以后面我会基于cursor给出周报mcp的效果展示及使用示例。

代码实现

  • 从环境变量中获取项目地址

    def get_projects() -> List[Dict[str, str]]:
    """
    从环境变量读取项目配置

    复制代码
      Returns:
          项目列表,每个项目包含 name 和 path
      """
      paths_str = os.getenv("PROJECT_PATHS", "")
      if not paths_str:
          return []
    
      projects = []
      for path in paths_str.split("|"):
          path = path.strip()
          if not path:
              continue
    
          # 验证路径存在且是 Git 仓库
          if os.path.exists(path) and os.path.exists(os.path.join(path, ".git")):
              projects.append({
                  "name": os.path.basename(path),
                  "path": path
              })
          else:
              print(f"Warning: {path} 不是有效的 Git 仓库", file=sys.stderr)
    
      return projects
  • 获取提交记录

    def get_git_commits(repo_path: str, days: int = 7) -> Dict[str, str]:
    """
    获取指定仓库的 Git 提交记录

    复制代码
      Args:
          repo_path: 仓库路径
          days: 查询最近几天的提交
          
      Returns:
          包含 author, commits, repo_path 的字典
      """
      # 获取作者名
      result = subprocess.run(
          ["git", "config", "user.name"],
          cwd=repo_path,
          capture_output=True,
          text=True,
          check=False
      )
      author = result.stdout.strip() or "Unknown"
    
      # 获取提交记录
      result = subprocess.run(
          ["git", "log", f"--author={author}",
           f"--since='{days} days ago'",
           "--pretty=format:%ad|%s", "--date=short"],
          cwd=repo_path,
          capture_output=True,
          text=True,
          check=False
      )
    
      commits = result.stdout.strip()
    
      # 统计提交次数
      commit_count = len([line for line in commits.split('\n') if line.strip()]) if commits else 0
    
      return {
          "author": author,
          "commits": commits or "(无提交记录)",
          "commit_count": commit_count,
          "repo_path": repo_path
      }
  • 定义git_commits_report方法并将其作为mcp.tool暴露

    #注意这个装饰器,使用@mcp.tool()修饰后将其作为mcp的tool暴露给AI应用
    @mcp.tool()
    def git_commits_report(days: int = 7) -> str:
    """根据指定项目的git提交记录生成周报

    复制代码
          Args:
              days: 统计最近几天的工作(默认为当前天往过去推6天也就是days=7,如果用户明确了时间例如三天内则days=3)
          """
      projects: List[Dict[str, str]] = get_projects()
      commit_str: str = ''
      for proj in projects:
          commit_str += get_git_commits(proj['path'], days).get('commits', '')
      return f"{report_prompt_template}\n{commit_str}"

这里需要注意的有两点:

1、方法注释一定要写详细 ,这样在AI应用中就能够看到关于这个mcp工具的详细信息,在cursor中的效果如下:

2、@mcp.tool()

实际上,MCP服务器有三种对外暴露能力的方式:

  • tool 允许模型执行操作或检索信息的可执行函数,使用装饰器@mcp.tool(),一般而言,涉及到数据处理的能力适合作为tool对外暴露

  • prompt 预设模板或指令,引导语言模型互动,使用装饰器@mcp.prompt(),例如我们可以使用@mcp.prompt()装饰git_commits_report,当我们重启mcp服务时,在cursor对话框中输入 /cursor会自动给出已有的mcp prompt列表:

通过使用@mcp.prompt(),一方面提高了人与AI应用的交互效率,另一方面为 AI 应用提供可组合、可管理、可解释的提示上下文机制

  • resource 为模型提供额外上下文的结构化数据或内容 ,使用装饰器@mcp.resource()

需要注意的是,一个mcp服务器可以提供多种类型多个mcp工具(tool、prompt、resource)

配置

在cursor中的mcp.json中添加以下配置:

复制代码
{
    "mcpServers": {
        "weekly-report": {
            "command": "uv",
            "args": [
                "run",
                "--directory",
                "/Users/ltb/PycharmProjects/mcp-git-weekly-report/src/mcp_git_weekly_report",
                "weekly_report.py"
            ],
            "env": {
                "PROJECT_PATHS": "/Users/ltb/PycharmProjects/mcp-git-weekly-report"
            }
        }
    }
}

将其中的mcp_git_weekly_report绝对路径改成自己本地项目地址,将PROJECT_PATHS环境变量改成自己的项目地址即可,如果是多个项目使用|分割。

使用示例:

完整代码地址:https://gitee.com/li-cube/mcp-git-weekly-report

当然你也可以使用如下配置,从远端自动拉取代码启动mcp服务:

复制代码
{
  "mcpServers": {
    "weekly-report": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://gitee.com/li-cube/mcp-git-weekly-report.git",
        "mcp-git-weekly-report"
      ],
      "env": {
        "PROJECT_PATHS": "项目1绝对路径|项目2绝对路径"
      }
    }
  }
}