1. 项目概述与核心价值
最近在折腾AI应用开发,特别是想让大语言模型(LLM)能更“接地气”地操作我的电脑和软件,比如让它帮我整理桌面文件、自动生成周报PPT,甚至控制音乐播放器。这听起来像是科幻电影里的场景,但实现起来,核心难题在于如何让LLM安全、可控地调用本地系统的各种功能。直接给模型开放系统API?那无异于敞开大门,安全风险巨大。正是在这个背景下,我深度体验并拆解了GitHub上一个名为“classmcp”的开源项目。这个项目提供了一种全新的思路,它不是简单地封装几个工具,而是构建了一套基于“类”的、可扩展的模型控制协议(MCP)服务器框架。
简单来说,classmcp让你能用定义Python类这种极其自然和强大的方式,来为LLM(比如ChatGPT、Claude等通过MCP协议对话的AI助手)创建工具(Tools)。你不需要去手动编写复杂的JSON Schema来描述工具的参数,也不需要去维护繁琐的请求-响应适配逻辑。你只需要像平时写业务逻辑一样,定义一个类,这个类的方法就会自动变成AI可以调用的工具。这极大地降低了开发门槛,让开发者能更专注于工具本身的功能实现,而非协议对接的细枝末节。
这个项目适合谁呢?首先,是像我一样的AI应用开发者或爱好者,希望快速构建功能丰富的AI智能体(Agent)。其次,是那些已经在使用MCP协议(例如与Claude Desktop配合)的进阶用户,想要扩展自定义工具但苦于原生MCP开发稍显繁琐。最后,它也适合任何对Python和AI自动化感兴趣的人,通过这个框架,你能以一种非常直观的方式,教会AI助手帮你处理各种重复性电脑操作。
2. 核心设计思路与架构拆解
2.1 从问题出发:为什么需要classmcp?
在接触classmcp之前,我尝试过几种方式为LLM添加本地能力。最原始的是用LangChain或LlamaIndex的Tool抽象,需要定义工具名称、描述,并手动编写一个接收字典参数、返回字符串的函数。这种方式在工具不多时还行,但随着工具数量增长,维护成本急剧上升。每个工具的参数校验、类型转换、错误处理都需要重复劳动。
后来,我接触到了模型控制协议(Model Control Protocol, MCP)。MCP是一个新兴的开放协议,旨在标准化LLM与外部工具、数据源之间的通信。它通过一个独立的服务器进程来提供工具和数据,客户端(如AI助手)通过标准化的JSON-RPC协议与服务器交互。这解决了安全隔离和协议统一的问题。然而,开发一个MCP服务器,尤其是工具(Tools)和资源(Resources)部分,需要严格遵循MCP的规范定义,手动编写大量的list_tools、call_tool等接口实现,以及复杂的参数模式(JSON Schema)定义。这个过程虽然规范,但不够高效和直观。
classmcp正是瞄准了这个痛点。它的核心设计思想是:“约定优于配置”和“类即工具集”。开发者只需要用Python的@tool装饰器来标记一个类方法,框架就会自动完成以下几件繁重的工作:
- 工具发现与注册:自动扫描所有被装饰的方法,无需手动维护工具列表。
- 参数模式生成:利用Python的类型注解(Type Hints),自动生成符合MCP规范的、精确的JSON Schema。这意味着你的工具参数类型(
str,int,List[str], 甚至是自定义的Pydantic模型)会被自动转换成AI能理解的格式。 - 调用路由与执行:当MCP客户端发起工具调用请求时,框架能自动将传入的JSON参数反序列化成对应的Python类型,并调用正确的方法。
- 依赖注入与管理:支持在工具类中声明依赖(如数据库连接、配置对象),框架会在工具调用时自动注入,这大大提升了代码的可测试性和组织性。
这种设计让开发体验产生了质的飞跃。你写工具的逻辑,和你写一个普通Python库的业务逻辑,几乎没有区别。
2.2 架构总览:三层抽象与运行流程
classmcp的架构清晰,可以理解为三个层次:
第一层:工具定义层(开发者主要交互层)这是开发者编写代码的地方。你创建普通的Python类,并使用@tool()装饰器来标记哪些方法应该暴露为MCP工具。你可以通过装饰器的参数来定制工具的名称、描述等元信息。类的初始化方法(__init__)可以用来接收和保存一些共享的状态或依赖。
第二层:框架适配层(classmcp核心)这一层是classmcp的魔法发生地。它主要包含:
- 装饰器(
@tool):负责收集被装饰方法的元数据(函数签名、类型注解、文档字符串)。 - 类扫描器:在服务器启动时,扫描所有注册的类,收集被
@tool装饰的方法。 - 模式生成器:将Python类型注解转换为标准的JSON Schema。
- MCP协议适配器:实现MCP服务器必需的接口,如
list_tools、call_tool、list_resources等。它将外部的MCP请求映射到内部对应的类和方法上。
第三层:协议传输层(MCP标准)这一层负责与外部AI客户端进行通信。classmcp通常构建在标准的MCP服务器SDK(如mcp库)之上,使用stdio(标准输入输出)或SSE(服务器发送事件)等传输方式。这意味着任何兼容MCP协议的客户端(如Claude Desktop、支持MCP的IDE插件)都能无缝连接到你的classmcp服务器。
整个运行流程可以概括为:你编写工具类并启动服务器 -> classmcp框架扫描并注册工具 -> MCP客户端连接并获取工具列表 -> 用户通过自然语言指示AI -> AI根据你的工具描述和参数模式生成调用请求 -> 请求通过MCP协议发送到服务器 -> classmcp框架解析请求,调用对应方法并注入依赖 -> 方法执行后返回结果 -> 结果通过MCP协议返回给AI -> AI将结果整合后回复用户。
3. 核心细节解析与实操要点
3.1@tool装饰器的深度解析
@tool装饰器是classmcp的灵魂,它的参数配置直接决定了工具在AI眼中的“人设”和行为。
from classmcp import tool, Server from pydantic import BaseModel from typing import List # 示例1:基本用法 class FileManager: @tool(name="list_directory", description="列出指定目录下的文件和文件夹") def list_dir(self, path: str) -> List[str]: import os return os.listdir(path) # 示例2:使用Pydantic模型定义复杂参数 class SearchQuery(BaseModel): keywords: List[str] max_results: int = 10 filter_by_date: bool = False class WebSearcher: @tool(description="在互联网上搜索相关信息") def search_web(self, query: SearchQuery) -> str: # query 现在是一个SearchQuery实例,可以直接使用 query.keywords, query.max_results results = f"模拟搜索 {query.keywords}, 最多 {query.max_results} 条结果。" if query.filter_by_date: results += " (已按日期过滤)" return results # 示例3:自定义工具名称和忽略某些参数 class SystemInfo: @tool(name="get_system_stats", description="获取当前系统状态", exclude_self=True) def get_stats(self, detail_level: str = "basic") -> dict: # 当exclude_self=True时,AI调用时不需要(也无法)传递`self`参数。 import psutil # ... 获取系统信息 return {"cpu": psutil.cpu_percent(), "memory": psutil.virtual_memory().percent}关键参数解读:
name: 指定工具在MCP中的名称。如果不提供,默认使用方法名。一个好的名称应该清晰、动宾结构,如send_email而非email_sender。description: 这是给AI看的“工具说明书”。描述的质量直接决定了AI调用工具的准确度。务必清晰说明工具的功能、适用场景以及各个参数的意义。例如,“保存文本到文件”就不如“将给定的文本内容追加到指定路径的文件末尾,如果文件不存在则创建它”来得精确。exclude_self: 默认为False。如果设置为True,则工具签名中不会包含self参数。这对于一些不需要访问类实例状态的工具函数(类似于静态方法)非常有用,能让AI看到的工具接口更简洁。
实操心得:描述即契约为工具编写描述时,要站在AI的视角思考。AI没有上下文,它完全依赖你的描述来理解何时以及如何使用这个工具。我的经验是采用“角色-动作-对象-约束”的句式。例如,对于文件重命名工具:“rename_file工具:将指定路径(old_path)的文件移动到新路径(new_path)。如果new_path已存在,则操作失败。old_path必须是已存在的文件路径。”
3.2 类型注解与自动Schema生成
这是classmcp最强大的特性之一。它深度依赖Python的类型注解来生成JSON Schema。
- 基础类型:
str,int,float,bool会被直接映射为对应的JSON Schema类型。 - 复合类型:
List[int],Dict[str, str]会被正确映射为数组和对象模式。 - 可选与默认值:
param: str = “default”会生成一个可选参数,并带有默认值。param: Optional[str] = None也是如此。 - Pydantic模型:如上例所示,使用Pydantic的
BaseModel来定义复杂、嵌套的参数结构是最佳实践。这不仅能生成清晰的Schema,还能在工具方法内部享受到Pydantic带来的数据验证和自动补全。 - 枚举(Enum):使用
enum.Enum可以明确告知AI该参数的可选值范围,极大提高调用准确性。
from enum import Enum class FileOperation(Enum): COPY = "copy" MOVE = "move" DELETE = "delete" class AdvancedFileManager: @tool(description="对文件执行高级操作") def operate_file(self, path: str, operation: FileOperation) -> str: # AI在调用时,operation参数只能从“copy", "move", "delete”中选择。 return f"执行 {operation.value} 操作于 {path}"注意事项:循环导入问题如果你的工具类方法参数或返回值类型引用了其他在同一项目中定义的复杂类或Pydantic模型,需要注意Python的循环导入问题。一个常见的模式是将所有的Pydantic模型定义在一个独立的文件(如models.py)中,然后在工具类文件中导入。
3.3 依赖注入与状态管理
工具类通常需要访问一些共享资源,比如数据库连接池、配置字典、API客户端实例或日志记录器。classmcp通过依赖注入(Dependency Injection, DI)来优雅地解决这个问题。
你可以在工具类的__init__方法中声明这些依赖,然后在创建服务器实例时,通过instances参数将这些依赖的实例“注入”进去。
# 假设我们有一个配置和数据库连接 app_config = {"api_key": "xxx", "log_level": "INFO"} database_pool = SomeDatabasePool() class DataProcessor: # 依赖通过__init__注入 def __init__(self, config: dict, db): self.config = config self.db = db @tool(description="根据用户ID查询处理数据") def process_user_data(self, user_id: int) -> dict: # 在这里可以安全地使用 self.config 和 self.db api_key = self.config.get("api_key") user_data = self.db.query(f"SELECT * FROM users WHERE id = {user_id}") return {"processed": True, "data": user_data} # 创建服务器时注入依赖实例 server = Server( instances=[ DataProcessor(config=app_config, db=database_pool), # 可以注入多个工具类的实例 ] )实操心得:依赖的生命周期通过instances注入的类实例,其生命周期与服务器进程相同。这意味着它非常适合用来管理长效连接(如数据库、网络会话)或只读配置。对于需要每次调用都创建新会话的场景,可以在工具方法内部临时创建。避免在工具类中保存与单次请求强相关的状态。
4. 完整项目搭建与核心环节实现
4.1 环境准备与项目初始化
首先,创建一个新的项目目录并设置虚拟环境,这是保持环境清洁的好习惯。
mkdir my-mcp-tools && cd my-mcp-tools python -m venv .venv # 在Windows上激活:.venv\Scripts\activate # 在macOS/Linux上激活:source .venv/bin/activate接下来,安装核心依赖。classmcp本身依赖mcp这个官方SDK,以及用于类型处理和序列化的pydantic。
pip install classmcp # classmcp会自动安装mcp和pydantic等依赖现在,我们来规划一个实用的项目:一个个人效率增强MCP服务器,包含文件管理、系统信息查询和简单的网络请求工具。
创建项目结构:
my-mcp-tools/ ├── .venv/ ├── tools/ # 存放所有工具类模块 │ ├── __init__.py │ ├── file_tools.py │ ├── system_tools.py │ └── web_tools.py ├── models.py # 存放共享的Pydantic模型 ├── config.py # 配置文件 ├── server.py # 服务器主入口 └── requirements.txt在requirements.txt中,我们可以固定版本:
classmcp>=0.1.0 # 根据工具需要,添加其他库,例如: # requests>=2.31.0 # psutil>=5.9.04.2 工具类模块编写实战
我们先从models.py开始,定义一些共享的数据结构。
# models.py from pydantic import BaseModel, HttpUrl from typing import List, Optional from enum import Enum class FileAction(str, Enum): LIST = "list" READ = "read" WRITE = "write" DELETE = "delete" class FileRequest(BaseModel): """文件操作请求模型""" path: str action: FileAction content: Optional[str] = None # 仅在WRITE操作时需要 class SearchRequest(BaseModel): """网络搜索请求模型""" query: str site: Optional[str] = None limit: int = 5接下来,编写具体的工具类。首先是tools/file_tools.py:
# tools/file_tools.py import os import shutil from pathlib import Path from typing import List from classmcp import tool from ..models import FileRequest, FileAction # 注意相对导入 class FileOperations: """一组用于基础文件操作的工具""" def __init__(self, base_dir: str = None): # 可以设置一个安全的基础目录,限制所有文件操作在其下进行 self.base_dir = Path(base_dir).resolve() if base_dir else None def _safe_path(self, user_path: str) -> Path: """将用户提供的路径解析为安全绝对路径""" path = Path(user_path).expanduser() # 支持 ~ if not path.is_absolute() and self.base_dir: path = self.base_dir / path abs_path = path.resolve() # 安全检查:如果设置了base_dir,确保路径在其下 if self.base_dir: try: abs_path.relative_to(self.base_dir) except ValueError: raise ValueError(f"访问路径 {abs_path} 超出了允许的范围 {self.base_dir}") return abs_path @tool(name="manage_file", description="执行文件或目录的核心管理操作,包括列出内容、读取、写入(覆盖)和删除。对于写入操作,需要提供`content`参数。") def manage_file(self, request: FileRequest) -> str: """统一的文件操作入口,使用Pydantic模型接收参数""" path = self._safe_path(request.path) if request.action == FileAction.LIST: if not path.exists(): return f"错误:路径 '{path}' 不存在。" if not path.is_dir(): return f"错误:'{path}' 不是一个目录。" items = list(path.iterdir()) return f"目录 '{path}' 下的内容:\n" + "\n".join([f"- {item.name} ({'文件夹' if item.is_dir() else '文件'})" for item in items]) elif request.action == FileAction.READ: if not path.exists(): return f"错误:文件 '{path}' 不存在。" if not path.is_file(): return f"错误:'{path}' 不是一个文件。" try: return path.read_text(encoding='utf-8') except Exception as e: return f"读取文件时出错:{e}" elif request.action == FileAction.WRITE: if request.content is None: return "错误:写入操作必须提供 `content` 参数。" try: path.parent.mkdir(parents=True, exist_ok=True) # 确保父目录存在 path.write_text(request.content, encoding='utf-8') return f"成功将内容写入文件:{path}" except Exception as e: return f"写入文件时出错:{e}" elif request.action == FileAction.DELETE: if not path.exists(): return f"错误:路径 '{path}' 不存在,无法删除。" try: if path.is_file(): path.unlink() else: # is_dir shutil.rmtree(path) return f"成功删除:{path}" except Exception as e: return f"删除时出错:{e}" return f"未知的操作类型:{request.action}"这个FileOperations类展示了一些重要技巧:
- 统一入口:使用一个
manage_file工具配合FileRequest模型,代替了list_dir,read_file,write_file,delete_file四个独立工具。这减少了工具数量,让AI的决策更简单,也更容易维护参数一致性。 - 路径安全:
_safe_path方法处理了相对路径、用户目录(~)并进行了基础的路径限制检查,这是生产环境必须考虑的安全措施。 - 详细的错误反馈:返回的字符串信息尽可能具体,这能帮助AI(和用户)理解操作失败的原因。
然后是tools/system_tools.py:
# tools/system_tools.py import platform import psutil from datetime import datetime from classmcp import tool class SystemMonitor: """获取当前计算机系统状态信息的工具""" @tool(description="获取详细的系统概览信息,包括操作系统、CPU使用率、内存使用率、磁盘空间和启动时间。") def get_system_overview(self) -> dict: """返回系统状态的字典摘要""" boot_time = datetime.fromtimestamp(psutil.boot_time()) return { "os": f"{platform.system()} {platform.release()}", "architecture": platform.machine(), "cpu_percent": psutil.cpu_percent(interval=0.5), "memory": { "total_gb": round(psutil.virtual_memory().total / (1024**3), 2), "available_gb": round(psutil.virtual_memory().available / (1024**3), 2), "percent_used": psutil.virtual_memory().percent }, "disk_usage": { "total_gb": round(psutil.disk_usage('/').total / (1024**3), 2), "free_gb": round(psutil.disk_usage('/').free / (1024**3), 2), "percent_used": psutil.disk_usage('/').percent }, "system_boot_time": boot_time.strftime("%Y-%m-%d %H:%M:%S"), "uptime_seconds": int(datetime.now().timestamp() - psutil.boot_time()) } @tool(description="列出当前正在运行的、占用CPU或内存较高的前N个进程。") def get_top_processes(self, n: int = 10, sort_by: str = "cpu") -> List[dict]: """获取资源占用最高的进程列表""" valid_sorts = ["cpu", "memory"] if sort_by not in valid_sorts: return [{"error": f"sort_by 必须是 {valid_sorts} 之一"}] procs = [] for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']): try: proc.info['cpu_percent'] = proc.info['cpu_percent'] or 0.0 proc.info['memory_percent'] = proc.info['memory_percent'] or 0.0 procs.append(proc.info) except (psutil.NoSuchProcess, psutil.AccessDenied): continue key = 'cpu_percent' if sort_by == 'cpu' else 'memory_percent' sorted_procs = sorted(procs, key=lambda p: p[key], reverse=True)[:n] return sorted_procs注意事项:外部依赖SystemMonitor使用了psutil库,记得在requirements.txt中添加它,并在运行前pip install psutil。返回字典或列表等结构化数据,AI通常能很好地理解和呈现它们。
4.3 服务器集成与启动
最后,在server.py中,我们将所有工具类实例化并集成到Server中。
# server.py import asyncio from classmcp import Server, ServerParameters from tools.file_tools import FileOperations from tools.system_tools import SystemMonitor # 假设我们还有 web_tools # from tools.web_tools import WebTools from config import BASE_DIRECTORY # 从配置文件导入 async def main(): # 1. 创建工具类的实例,并注入依赖(如基础目录) file_ops = FileOperations(base_dir=BASE_DIRECTORY) system_monitor = SystemMonitor() # web_tools = WebTools(api_key=os.getenv("SOME_API_KEY")) # 2. 创建Server,传入所有工具实例 server = Server( instances=[ file_ops, system_monitor, # web_tools, ], # 可以配置服务器参数,如名称 parameters=ServerParameters( name="My Productivity MCP Server", version="0.1.0" ) ) # 3. 运行服务器(使用标准输入输出,这是与MCP客户端通信的常见方式) await server.run() if __name__ == "__main__": asyncio.run(main())在config.py中,我们可以放置配置:
# config.py import os from pathlib import Path # 限制文件操作在用户主目录下的某个安全区域,例如 ~/mcp_workspace HOME = Path.home() BASE_DIRECTORY = HOME / "mcp_workspace" # 确保目录存在 BASE_DIRECTORY.mkdir(exist_ok=True)现在,一个功能完整的MCP服务器就搭建好了。你可以使用python server.py来启动它,但它现在只是在等待标准输入。要真正使用它,你需要一个MCP客户端。
4.4 与Claude Desktop集成(实战演示)
目前,最流行的MCP客户端之一是Anthropic的Claude Desktop应用。你需要创建一个服务器配置文件来告诉Claude如何连接你的classmcp服务器。
在Claude的配置目录下(通常是~/Library/Application Support/Claude/claude_desktop_config.jsonon macOS,或%APPDATA%\Claude\claude_desktop_config.jsonon Windows),添加你的服务器配置:
{ "mcpServers": { "my-productivity-tools": { "command": "/path/to/your/python", "args": [ "/full/path/to/your/project/server.py" ], "env": { "PYTHONPATH": "/full/path/to/your/project" } } } }关键点解析:
command: 是你Python解释器的完整路径。在虚拟环境中,最好使用虚拟环境内的Python路径(如/path/to/project/.venv/bin/python)。args: 是你的服务器主脚本的完整路径。env: 设置了PYTHONPATH,确保你的工具模块可以被正确导入。这对于项目结构复杂的场景很重要。
配置完成后,重启Claude Desktop。在聊天界面,你应该能看到Claude的回复中开始提及你定义的工具,比如“我可以帮你管理文件、查看系统状态……”。现在,你就可以尝试用自然语言指挥Claude了,例如:“帮我列出~/mcp_workspace目录下所有的文件”,或者“现在我的电脑CPU占用最高的进程是什么?”
5. 常见问题与排查技巧实录
在实际开发和集成过程中,我踩过不少坑。这里把最常见的问题和解决方法整理出来,希望能帮你节省时间。
5.1 工具未在客户端显示
问题描述:服务器启动似乎正常,但Claude Desktop里看不到新添加的工具。
- 检查点1:服务器日志。在
server.py的main()函数开始处添加import logging; logging.basicConfig(level=logging.DEBUG)。查看启动时是否输出了类似Registered tool: manage_file的日志。如果没有,说明工具类没有被正确扫描或实例化。 - 检查点2:MCP配置。确认Claude的配置文件路径和格式完全正确。JSON格式非常严格,多一个逗号或少一个引号都会导致整个配置被忽略。可以使用在线JSON校验工具检查。
- 检查点3:命令路径。
command和args中的路径必须是绝对路径。特别是虚拟环境中的Python,其路径可能不是直观的。可以在终端中进入虚拟环境,执行which python(或where pythonon Windows)来获取准确路径。 - 检查点4:环境变量。如果工具依赖环境变量(如API密钥),确保在
env字段中正确设置,或者在启动Claude Desktop的系统环境中设置。
5.2 工具调用失败或参数错误
问题描述:AI尝试调用工具,但返回错误,如“Invalid parameters”或调用后无反应。
- 检查点1:参数模式(Schema)。这是最可能出问题的地方。使用一个简单的测试脚本,手动检查工具生成的Schema。
仔细查看输出的JSON Schema,检查每个参数的from classmcp import Server from your_tools import YourToolClass import json server = Server(instances=[YourToolClass()]) # 获取工具列表的Schema tools = server._get_tools() # 注意:这是探查内部方法,仅用于调试 print(json.dumps(tools, indent=2, ensure_ascii=False))type,description是否正确。特别注意enum类型和嵌套的Pydantic模型是否被正确转换。 - 检查点2:类型注解。确保所有工具方法的参数和返回值都有清晰的类型注解。即使是返回
str,也最好明确标注-> str。使用Optional和默认值来定义可选参数。 - 检查点3:描述清晰度。AI依赖工具描述。如果描述模糊,AI可能错误理解工具用途或传错参数。回顾并优化你的
@tool(description=“...”)。
5.3 依赖注入失败或状态异常
问题描述:工具类中self.config、self.db等依赖为None,或在多次调用间状态混乱。
- 检查点1:实例化顺序。确保在创建
Server时,传入的instances列表中的对象是已经实例化好的。Server(instances=[FileOperations(base_dir=“/tmp”)])是正确的,而Server(instances=[FileOperations])(传入类本身)是错误的。 - 检查点2:线程安全。MCP服务器可能是异步或多线程处理请求的。如果你的工具类方法修改了实例变量(如
self.counter += 1),需要考虑线程安全问题。对于需要共享的可变状态,建议使用线程安全的数据结构(如threading.Lock)或将其移到外部依赖(如Redis)。 - 检查点3:资源泄漏。对于数据库连接、网络会话等资源,避免在
__init__中创建并在工具方法中频繁开关。更好的模式是使用连接池,或者在工具方法内部使用上下文管理器(with语句)来管理资源生命周期。
5.4 性能与调试建议
- 懒加载与缓存:如果工具初始化或某些操作非常耗时,可以考虑懒加载。例如,在
__init__中只保存配置,在第一次调用工具方法时才建立重量级连接。 - 结构化日志:为你的工具类添加日志记录,记录入参、出参和关键步骤。这比
print语句更利于生产环境调试。可以使用Python的logging模块,并配置不同的级别(INFO, DEBUG, ERROR)。 - 单元测试:由于工具类本质上是普通的Python类,你可以非常方便地为它们编写单元测试,模拟MCP调用,确保核心逻辑正确。
# test_file_tools.py def test_manage_file_list(): ops = FileOperations(base_dir="/tmp/test_mcp") test_dir = Path("/tmp/test_mcp/subdir") test_dir.mkdir(parents=True, exist_ok=True) (test_dir / "test.txt").write_text("hello") from models import FileRequest, FileAction req = FileRequest(path="./subdir", action=FileAction.LIST) result = ops.manage_file(req) assert "test.txt" in result
开发classmcp项目的体验,就像是在为AI编写一个高度智能的插件系统。它把开发者从繁琐的协议细节中解放出来,让我们能回归到最本质的业务逻辑实现上。这种“定义类即创建工具”的范式,不仅提升了开发效率,也让代码结构更加清晰、易于维护。当你看到自己用几十行代码定义的工具,被AI流畅地调用并完成复杂任务时,那种成就感是非常直接的。这个框架目前仍在活跃发展中,我期待未来它能支持更复杂的资源(Resources)定义、更强大的生命周期钩子,以及更完善的生态工具。对于任何想要深入AI智能体开发,特别是专注于让AI与本地环境深度交互的开发者来说,classmcp绝对是一个值得投入时间学习和使用的利器。