1. 先搞清楚MCP、Skills、Hooks 到底在解决什么问题Claude Code 原生能力不弱但真到项目里总有些事它自己搞不定。查数据库、调 GitHub API、发 Slack 通知这些需要 MCP让 Claude 遵守一套团队编码规范、按固定流程做 code review这些需要 Skills每次编辑文件后自动跑格式化、拦截对敏感文件的修改这些需要 Hooks。三种机制各管一摊单独看都好理解。但一到实际场景选择困难就来了这个需求到底该用哪个混着用会不会冲突为什么挂了几个 MCP 之后 token 消耗突然暴涨我试过在一个中型项目里同时挂 4 个 MCP Server、6 个 Skill、3 个 Hook结果每轮对话光工具定义就吃掉近万 token有效上下文被挤得所剩无几。后来按确定性规则用 Hooks、领域知识用 Skills、外部连接用 MCP的原则重新梳理token 消耗降了七成响应也快了不少。这篇文章不重复讲每种机制的基础用法而是聚焦三件事三者的本质区别是什么、token 成本模型差多少、什么场景该用哪个。最后给出一份可直接复制的settings.json配置骨架以及逐项验证清单——启动后确认加载日志、触发一次 Hook 观察回调、调用 MCP 工具核对返回。适合已经用过 Claude Code、想把它真正接进工程流程的开发者。如果你还在纠结这个功能该写 Skill 还是 Hook下面的决策表和配置骨架可以直接对号入座。2. 前置准备TaoToken 接入与 Claude Code 环境在动手配settings.json之前先把模型接入这一层理顺。Claude Code 需要一个兼容 Anthropic API 的端点TaoToken 提供了这个能力官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。第一步拿到 API Key。登录后进入控制台在 API Keys 页面创建一个新 Key复制保存。这个 Key 后面要写进环境变量不要直接硬编码到settings.json里。第二步配置环境变量。Claude Code 读取ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY两个变量export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的keyWindows 下用 PowerShell$env:ANTHROPIC_BASE_URLhttps://taotoken.net/api $env:ANTHROPIC_API_KEYsk-你的key第三步验证接入是否通。启动 Claude Code随便问一句能正常返回就说明接入没问题。如果报 401检查 Key 是否复制完整如果报连接超时检查ANTHROPIC_BASE_URL是否写成了https://taotoken.net/api注意结尾没有斜杠。注意环境变量里的 Key 和settings.json里的配置是两套东西。前者管模型接入后者管 MCP、Skills、Hooks 的注册。不要混在一起。接入通了之后再往下配扩展机制。如果你还没创建 Key可以去控制台的 API Keys 页面操作https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。想先体验模型对话效果可以用模型对话页https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。3. 可复制配置settings.json 骨架Claude Code 的扩展配置集中在项目根目录的.claude/settings.json项目级或~/.claude/settings.json用户级。下面这份骨架把 MCP server 注册、Skill 目录声明、Hook 事件绑定三块都放进去了可以直接复制后按需删改。{ mcpServers: { github: { command: npx, args: [-y, modelcontextprotocol/server-github], env: { GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_TOKEN} } }, filesystem: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, ./src] } }, skills: { directory: .claude/skills, autoLoad: true }, hooks: { PostToolUse: [ { matcher: Edit|Write, hooks: [ { type: command, command: npx prettier --write \$CLAUDE_FILE_PATH\ } ] } ], PreToolUse: [ { matcher: Edit|Write, hooks: [ { type: command, command: node .claude/hooks/guard-sensitive.js } ] } ], Stop: [ { hooks: [ { type: command, command: npm test --silent } ] } ] } }逐块说明。mcpServers里每个 key 是一个 Server 名command加args是启动命令env里可以引用系统环境变量。上面挂了两个 Servergithub 和 filesystem。实际用的时候只挂当前任务需要的用完就删。skills.directory指向 Skill 存放目录每个 Skill 是一个子目录里面放SKILL.mdfrontmatter 里写name和description。autoLoad: true表示启动时加载所有 Skill 的描述信息。hooks按事件类型分组。PostToolUse在工具调用成功后触发上面配的是编辑文件后自动跑 prettier。PreToolUse在工具调用前触发上面配的是一个守卫脚本用来拦截对敏感文件的修改。Stop在 Claude 准备结束回答时触发上面配的是跑测试。提示Hook 的matcher支持正则Edit|Write表示匹配编辑和写入两类工具。$CLAUDE_FILE_PATH是 Claude Code 注入的环境变量指向当前操作的文件路径。Skill 目录结构长这样.claude/skills/ api-style/ SKILL.md deploy-flow/ SKILL.mdSKILL.md的 frontmatter 示例--- name: api-style description: 团队 API 命名与错误处理规范写接口时参考 --- # API 风格指南 所有接口路径用 kebab-case错误码统一用 ERR_ 前缀……如果某个 Skill 只想手动触发、不希望 Claude 自动调用在 frontmatter 里加一行disable-model-invocation: true这样连描述都不会加载彻底零开销。4. 验证清单逐项确认配置生效配完不等于生效。下面三个验证动作逐个跑一遍。4.1 确认 MCP 加载日志启动 Claude Code 后输入/mcp命令会列出当前已连接的 Server 和各自暴露的工具数量。如果某个 Server 没出现检查command和args是否能手动跑通——把command和args拼成一条命令在终端执行看是否报错。另一个办法是直接问 Claude帮我数一下当前有多少 MCP 工具。它会列出工具清单。如果数量和你预期不符说明某个 Server 注册失败。4.2 触发一次 Hook 观察回调编辑任意一个.ts或.js文件故意把格式写乱保存。如果PostToolUse的 prettier Hook 生效文件会被自动格式化。你可以在 Hook 命令里加一句echo hook fired: $CLAUDE_FILE_PATH /tmp/claude-hook.log然后tail -f /tmp/claude-hook.log观察是否触发。PreToolUse的守卫脚本验证方式类似尝试让 Claude 修改一个被保护的路径如果 Hook 生效修改会被拒绝Claude 会收到拒绝原因。4.3 调用 MCP 工具核对返回让 Claude 执行一个需要 MCP 的操作比如列出当前仓库最近的 5 个 issue。如果 github Server 正常它会调用mcp__github__list_issues并返回结果。如果报工具不存在说明 Server 没注册成功或工具名不对。核对返回时注意两点一是返回内容是否完整二是调用是否真的走了 MCP 而不是 Claude 自己编的。可以在 Server 启动命令里加日志参数观察是否有实际请求发出。5. 本篇常见错排查报错一MCP server failed to start最常见的原因是npx拉包超时或包名写错。先把command和args拼成完整命令在终端跑一遍确认能启动。如果是网络问题考虑用本地已安装的包路径替代npx。报错二Hook 不触发检查matcher是否匹配到了实际工具名。Claude Code 的工具名是Edit、Write、Bash这类大小写敏感。另外确认 Hook 命令的退出码——非零退出码会被视为 Hook 失败可能导致操作被阻断。报错三Skill 描述没加载检查SKILL.md的 frontmatter 格式name和description必须用---包裹。如果加了disable-model-invocation: true描述本来就不会加载这是预期行为。报错四token 消耗异常高用/mcp看当前挂了多少 Server、多少工具。一个 Server 挂十几个工具每轮对话都要注入全部 Schema。把不用的 Server 断掉或者开启 Tool Searchexport ENABLE_TOOL_SEARCHauto这个模式在工具定义超过上下文 10% 时自动开启只加载工具描述按需拉取完整定义。报错五Hook 和 MCP 冲突比如 Hook 拦截了某个文件修改但 MCP 工具又想写这个文件。这种情况检查PreToolUse的匹配范围把 MCP 相关工具排除掉或者调整守卫脚本的逻辑。6. 选型决策与后续接入三种机制的核心差异可以归到三个维度任务触发方式、上下文开销、可维护性。MCP 由 Claude 判断调用常驻开销最大Skills 由 Claude 或用户决定加载按需开销Hooks 由规则自动触发几乎零开销。选型优先级很简单确定性规则用 Hooks领域知识用 Skills外部连接用 MCP。能用轻量的就不用重量的能按需加载的就不要常驻。配置骨架和验证清单都在上面了。接下来如果要长期做编码和 Agent 任务建议把常用的 Skill 和 Hook 固化下来MCP 按任务临时挂载。Coding Plan 适合这种长期编码场景可以去 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 了解。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里面有各语言的调用示例和参数说明。最后提醒一句定期用/mcp检查 Server 列表那些装了就没用过的每一轮都在消耗你的 token 预算。断开它们把上下文还给真正有用的对话内容。