Claude Code 源码分析Claude Code 源码分析
首页
源码统计
系统架构
UML 图表
工具系统
CodeGraph
首页
源码统计
系统架构
UML 图表
工具系统
CodeGraph
  • 概览

    • Claude Code 源码分析
    • 源码统计
    • CodeGraph 图谱
  • 架构

    • 系统架构
    • UML 图表索引
    • 查询引擎
    • 核心流程
    • 消息系统
    • 状态管理
  • 功能模块

    • 工具系统
    • 斜杠命令
    • 服务层
    • MCP 协议
    • Skills 技能
    • 子代理系统
  • 分层深度

    • 入口层
    • UI / Ink 层
    • utils 基础设施
    • 桥接 / 远程
    • 上下文压缩
  • 原理与安全

    • 底层原理
    • 技术难点
    • 权限与安全
    • 内部机制
    • 遥测与分析
  • 深度专题

    • Hooks 系统
    • 插件系统
    • 记忆系统
    • API 通信层
    • Ink 终端 UI
    • 认证系统
    • 构建与发布
    • 术语表
  • 调用分析

    • 调用链分析
    • 核心文件索引
  • 模块详解

    • utils

      • 模块: utils
      • messages · 消息工厂与规范化
      • session-storage · JSONL 会话持久化
      • permissions · 工具权限决策
      • shell-hooks · 用户 Shell Hook 系统
    • components

      • 模块: components
      • REPL · 主屏编排
      • messages · 消息行渲染
      • PermissionRequest · 权限弹窗
      • PromptInput · 底部输入
    • services

      • 模块: services
      • api-claude · Anthropic API 流式与重试
      • mcp-client · MCP 连接与工具调用
      • compact · 上下文压缩与自动触发
      • analytics · GrowthBook、Datadog 与 1P 事件
    • tools

      • 模块: tools
      • tool-interface · Tool 契约与注册表
      • bash-tool · Shell 执行与权限
      • streaming-executor · 流式工具并发调度
      • agent-tool · 子 Agent 委派
    • commands

      • 模块: commands
      • command-registry · commands.ts 注册与分派
      • model-command · /model 模型选择
      • mcp-commands · /mcp 服务器管理
      • compact-memory-commands · /compact 与 /memory
    • ink

      • 模块: ink
      • Ink 渲染管线 · Screen 与终端输出
      • 终端事件 · resize、paste、stdin
      • Ink Hooks · 输入、搜索、终端状态
      • Ink 组件 · Box、Text、ScrollBox 原语
    • hooks

      • 模块: hooks
      • useCanUseTool · 权限 UI 接缝
      • 输入与快捷键 Hook
      • 合并态 Hook(MCP + 本地)
      • notifs 通知 Hook
    • bridge

      • 模块: bridge
      • repl-bridge · REPL 桥初始化与传输
      • bridge-messaging · 桥消息路由与入站处理
      • remote-bridge-core · env-less 核心与守护主循环
      • bridge-permissions-ui · 权限、API 与 TUI
    • cli

      • 模块: cli
      • Structured IO · NDJSON SDK 协议
      • CLI Transports · Session Ingress 传输层
      • CLI Handlers · 子命令懒加载实现
      • Update & Upload · 自更新与串行上传原语
    • screens

      • 模块: screens
      • REPL 屏 · Screen 类型与顶层路由
      • ResumeConversation · 会话恢复选择器
      • Doctor · 安装诊断全屏
    • entrypoints

      • 模块: entrypoints
      • cli-entrypoint · Bootstrap 与快路径
      • sdk-types · core / control / runtime 类型体系
      • mcp-entrypoint · MCP stdio 服务器
      • sandbox-types · 沙箱配置单一真相源
    • skills

      • 模块: skills
      • skills-loading · 磁盘加载与 bundled 注册表
      • bundled-skills · 内置 skill 与 initBundledSkills
      • mcp-skills · MCP prompt 转 skill
      • skill-tool-integration · SkillTool 与命令注册
    • types

      • 模块: types
      • message-types · Message 联合与 content blocks
      • tool-permission-types · Tool、Permission、Command 类型
      • api-sdk-types · API 与 Hooks 协议类型
      • misc-types · ids、plugin、generated 与其余类型
    • tasks

      • 模块: tasks
      • local-agent-task · 本地 Agent 与主会话后台化
      • remote-agent-task · 远程 CCR 与 In-Process Teammate
      • shell-workflow-tasks · Bash 后台、Workflow 与 stopTask
      • dream-monitor-tasks · Dream、Monitor MCP 与 pill 文案
    • keybindings

      • 模块: keybindings
      • keybinding-registry · 注册、Provider 与 useKeybinding
      • default-bindings · 默认键位表与平台差异
      • command-bindings · command:* 动态斜杠命令绑定
      • vim-bindings · Vim 模式与 keybindings 边界
    • memdir

      • 模块: memdir
      • memdir-core · 路径、加载与 MEMORY.md
      • memory-extraction · extractMemories 与 SessionMemory
      • memdir-commands · /memory、/remember 与命令集成
    • state

      • 模块: state
      • app-state-core · store、AppState 类型与 Provider
      • app-state-selectors · selectors 与 onChangeAppState
      • teammate-state · 队友视图与 swarm 状态
      • state-boundaries · bootstrap、sessionStorage、FileStateCache
    • query

      • 模块: query
      • query config 与 deps · 配置快照与依赖注入
      • query tokenBudget · +500k 自动续跑
      • query transitions · Continue / Terminal 状态机
      • query stopHooks · Stop 事件与 turn 结束编排
  • 模块详解(扩展)

    • messages · 消息工厂与规范化
    • session-storage · JSONL 会话持久化
    • permissions · 工具权限决策
    • shell-hooks · 用户 Shell Hook 系统
    • REPL · 主屏编排
    • messages · 消息行渲染
    • PermissionRequest · 权限弹窗
    • PromptInput · 底部输入
    • api-claude · Anthropic API 流式与重试
    • mcp-client · MCP 连接与工具调用
    • compact · 上下文压缩与自动触发
    • analytics · GrowthBook、Datadog 与 1P 事件
    • tool-interface · Tool 契约与注册表
    • bash-tool · Shell 执行与权限
    • streaming-executor · 流式工具并发调度
    • agent-tool · 子 Agent 委派
    • command-registry · commands.ts 注册与分派
    • model-command · /model 模型选择
    • mcp-commands · /mcp 服务器管理
    • compact-memory-commands · /compact 与 /memory
    • Ink 渲染管线 · Screen 与终端输出
    • 终端事件 · resize、paste、stdin
    • Ink Hooks · 输入、搜索、终端状态
    • Ink 组件 · Box、Text、ScrollBox 原语
    • useCanUseTool · 权限 UI 接缝
    • 输入与快捷键 Hook
    • 合并态 Hook(MCP + 本地)
    • notifs 通知 Hook
    • repl-bridge · REPL 桥初始化与传输
    • bridge-messaging · 桥消息路由与入站处理
    • remote-bridge-core · env-less 核心与守护主循环
    • bridge-permissions-ui · 权限、API 与 TUI
    • Structured IO · NDJSON SDK 协议
    • CLI Transports · Session Ingress 传输层
    • CLI Handlers · 子命令懒加载实现
    • Update & Upload · 自更新与串行上传原语
    • REPL 屏 · Screen 类型与顶层路由
    • ResumeConversation · 会话恢复选择器
    • Doctor · 安装诊断全屏
    • cli-entrypoint · Bootstrap 与快路径
    • sdk-types · core / control / runtime 类型体系
    • mcp-entrypoint · MCP stdio 服务器
    • sandbox-types · 沙箱配置单一真相源
    • skills-loading · 磁盘加载与 bundled 注册表
    • bundled-skills · 内置 skill 与 initBundledSkills
    • mcp-skills · MCP prompt 转 skill
    • skill-tool-integration · SkillTool 与命令注册
    • message-types · Message 联合与 content blocks
    • tool-permission-types · Tool、Permission、Command 类型
    • api-sdk-types · API 与 Hooks 协议类型
    • misc-types · ids、plugin、generated 与其余类型
    • local-agent-task · 本地 Agent 与主会话后台化
    • remote-agent-task · 远程 CCR 与 In-Process Teammate
    • shell-workflow-tasks · Bash 后台、Workflow 与 stopTask
    • dream-monitor-tasks · Dream、Monitor MCP 与 pill 文案
    • keybinding-registry · 注册、Provider 与 useKeybinding
    • default-bindings · 默认键位表与平台差异
    • command-bindings · command:* 动态斜杠命令绑定
    • vim-bindings · Vim 模式与 keybindings 边界
    • memdir-core · 路径、加载与 MEMORY.md
    • memory-extraction · extractMemories 与 SessionMemory
    • memdir-commands · /memory、/remember 与命令集成
    • app-state-core · store、AppState 类型与 Provider
    • app-state-selectors · selectors 与 onChangeAppState
    • teammate-state · 队友视图与 swarm 状态
    • state-boundaries · bootstrap、sessionStorage、FileStateCache
    • query config 与 deps · 配置快照与依赖注入
    • query tokenBudget · +500k 自动续跑
    • query transitions · Continue / Terminal 状态机
    • query stopHooks · Stop 事件与 turn 结束编排
  • 工具详解

    • tool-interface · Tool 契约与注册表
    • tool-permission-types · Tool、Permission、Command 类型
    • 工具: Bash
    • 工具: PowerShell
    • 工具: Agent
    • 工具: LSP
    • 工具: FileEdit
    • 工具: FileRead
    • 工具: Skill
    • 工具: WebFetch
    • 工具: MCP
    • 工具: SendMessage
    • 工具: FileWrite
    • 工具: Config
    • 工具: Grep
    • 工具: Brief
    • 工具: ExitPlanMode
    • 工具: ToolSearch
    • 工具: NotebookEdit
    • 工具: TaskOutput
    • 工具: WebSearch
    • 工具: ScheduleCron

本章总览

MCP server 暴露的 prompts 可转换为 Claude Code slash skill(loadedFrom: mcp)。mcpSkillBuilders.ts 提供无环依赖的 builder 注册表;mcpSkills.ts 在 client 连接后 fetch 并构建 Command。fetchMcpSkillsForClient 在当前树中 stub 返回 [],但架构接缝完整。本章重点解释 builder 模式与 SkillTool 对 mcp skill 的过滤。

学完本章你应该能

  • 解释 mcpSkillBuilders 为何存在(Bun bunfs + dependency-cruiser)
  • 说明 registerMCPSkillBuilders 与 getMCPSkillBuilders 契约
  • 理解 MCP prompt → createSkillCommand 字段映射
  • 掌握 SkillTool getAllCommands 中 loadedFrom===mcp 过滤
  • 区分 MCP prompt 与 MCP tool 在 SkillTool 可达性

核心概念(先读懂这些)

MCP skill 进入 AppState.mcp.commands

MCP client 连接后 discovery 写入 AppState;prompt 类型经 mcpSkills 路径转为 PromptCommand 并标记 loadedFrom=mcp。getCommands() 只 merge local+bundled;SkillTool 额外合并 mcp.commands 中 prompt 且 loadedFrom===mcp 的项。

builder registry 是 dependency-graph leaf

mcpSkillBuilders.ts 只 import type from loadSkillsDir,零 runtime 依赖 loadSkillsDir。loadSkillsDir 模块 eval 末尾 register 实现函数指针。client.ts 可 import mcpSkills 而不形成环。

建议学习步骤

  1. 阅读 mcpSkillBuilders 头注释(源码块 A)
  2. 阅读 register/getMCPSkillBuilders(源码块 B)
  3. 阅读 fetchMcpSkillsForClient stub(源码块 C)
  4. 阅读 SkillTool getAllCommands mcp 过滤(源码块 D)
  5. 阅读 loadSkillsDir register 末尾(源码块 E)
  6. grep loadedFrom mcp 赋值点(源码块 F)
  7. 确认 disconnect 时 AppState.mcp.commands 清理

常见误区

注意

MCP plain prompt 不应被 SkillTool 猜测名调用——filter 是为收窄可达性

注意

动态 import 非字面量在 bundled binary 失败——勿改 builder 注册方式

注意

mcpSkills stub 不代表生产无逻辑——阅读 client discovery 路径

注意

AppState.mcp.commands 与 getCommands 列表 intentionally 不同

注意

hot-plug MCP server 后下一 turn SkillTool 才见新 skill

注意

createSkillCommand 保证 MCP 与 disk skill frontmatter 语义一致

MCP skill 在命令体系中的位置

MCP Server (external)
  → services/mcp/client connect
  → list prompts / tools
  → AppState.mcp.commands[]

mcpSkills.ts + getMCPSkillBuilders()
  → createSkillCommand({ ..., loadedFrom: 'mcp' })
  → merge into command list for UI / SkillTool

用户 /mcp__server__promptname
模型 SkillTool(command: '...')

LoadedFrom 枚举(loadSkillsDir)含 mcp 第五源。

commands.ts 静态 import loadSkillsDir → 保证 registerMCPSkillBuilders 在任意 MCP 连接前完成。

源码引用: src/skills/loadSkillsDir.ts · 第 67–73 行(共 1087 行)

  67| export type LoadedFrom =
  68|   | 'commands_DEPRECATED'
  69|   | 'skills'
  70|   | 'plugin'
  71|   | 'managed'
  72|   | 'bundled'
  73|   | 'mcp'

源码缺失

File not found: c:\Users\123\Desktop\jd\Claude code源码\claude-code-complete\claude-code-complete\src-readable\services\mcp-client.mjs

mcpSkillBuilders 设计

文件头注释(必读)总结三类失败方案:

  1. 非字面量 dynamic import — Bun bunfs 路径解析失败
  2. 字面量 dynamic import loadSkillsDir — dependency-cruiser 报大量环
  3. 静态 import 互引 — client → mcpSkills → loadSkillsDir → … → client

解决方案:write-once registry

export type MCPSkillBuilders = {
  createSkillCommand: typeof createSkillCommand
  parseSkillFrontmatterFields: typeof parseSkillFrontmatterFields
}

mcpSkills 调用 getMCPSkillBuilders().createSkillCommand(...) 无需 import loadSkillsDir。

源码引用: src/skills/mcpSkillBuilders.ts · 第 6–44 行(共 45 行)

   6| /**
   7|  * Write-once registry for the two loadSkillsDir functions that MCP skill
   8|  * discovery needs. This module is a dependency-graph leaf: it imports nothing
   9|  * but types, so both mcpSkills.ts and loadSkillsDir.ts can depend on it
  10|  * without forming a cycle (client.ts → mcpSkills.ts → loadSkillsDir.ts → …
  11|  * → client.ts).
  12|  *
  13|  * The non-literal dynamic-import approach ("await import(variable)") fails at
  14|  * runtime in Bun-bundled binaries — the specifier is resolved against the
  15|  * chunk's /$bunfs/root/… path, not the original source tree, yielding "Cannot
  16|  * find module './loadSkillsDir.js'". A literal dynamic import works in bunfs
  17|  * but dependency-cruiser tracks it, and because loadSkillsDir transitively
  18|  * reaches almost everything, the single new edge fans out into many new cycle
  19|  * violations in the diff check.
  20|  *
  21|  * Registration happens at loadSkillsDir.ts module init, which is eagerly
  22|  * evaluated at startup via the static import from commands.ts — long before
  23|  * any MCP server connects.
  24|  */
  25| 
  26| export type MCPSkillBuilders = {
  27|   createSkillCommand: typeof createSkillCommand
  28|   parseSkillFrontmatterFields: typeof parseSkillFrontmatterFields
  29| }
  30| 
  31| let builders: MCPSkillBuilders | null = null
  32| 
  33| export function registerMCPSkillBuilders(b: MCPSkillBuilders): void {
  34|   builders = b
  35| }
  36| 
  37| export function getMCPSkillBuilders(): MCPSkillBuilders {
  38|   if (!builders) {
  39|     throw new Error(
  40|       'MCP skill builders not registered — loadSkillsDir.ts has not been evaluated yet',
  41|     )
  42|   }
  43|   return builders
  44| }

registerMCPSkillBuilders 时机

loadSkillsDir.ts 模块末尾(约 1083 行):

registerMCPSkillBuilders({
  createSkillCommand,
  parseSkillFrontmatterFields,
})

注册发生在 loadSkillsDir.ts module init,通过 commands.ts 静态 import 在 startup 早期 eager eval。

getMCPSkillBuilders() 若 builders 为 null throw Error——诊断 load order regression。

MCP server 连接发生在 REPL 运行期,远晚于 registration。

源码引用: src/skills/loadSkillsDir.ts · 第 65–65 行(共 1087 行)

  65| import { registerMCPSkillBuilders } from './mcpSkillBuilders.js'

源码引用: src/skills/mcpSkillBuilders.ts · 第 33–44 行(共 45 行)

  33| export function registerMCPSkillBuilders(b: MCPSkillBuilders): void {
  34|   builders = b
  35| }
  36| 
  37| export function getMCPSkillBuilders(): MCPSkillBuilders {
  38|   if (!builders) {
  39|     throw new Error(
  40|       'MCP skill builders not registered — loadSkillsDir.ts has not been evaluated yet',
  41|     )
  42|   }
  43|   return builders
  44| }

fetchMcpSkillsForClient

当前 mcpSkills.ts 全文极短:

export async function fetchMcpSkillsForClient() {
  return []
}

表明 v2.1.88 反编译树中 MCP skill fetch 可能:

  • 移至 services/mcp/client.ts inline
  • 或 feature gate 剥离

架构接缝保留:export 函数名、builder registry、SkillTool mcp merge 仍完整。

阅读生产逻辑应 grep loadedFrom === 'mcp' 与 createSkillCommand 调用点。

源码引用: src/skills/mcpSkills.ts · 第 1–3 行(共 4 行)

   1| export async function fetchMcpSkillsForClient() {
   2|   return []
   3| }

SkillTool 对 MCP skill 的合并

getAllCommands(context)(SkillTool.ts):

const mcpSkills = context.getAppState().mcp.commands.filter(
  cmd => cmd.type === 'prompt' && cmd.loadedFrom === 'mcp',
)
if (mcpSkills.length === 0) return getCommands(getProjectRoot())
return uniqBy([...localCommands, ...mcpSkills], 'name')

注释:Before this filter, model could invoke MCP prompts via SkillTool if it guessed mcp__server__prompt name。

仅 loadedFrom === 'mcp' 的 prompt 进入 SkillTool 发现列表;plain MCP prompt 不可达。

源码引用: src/tools/SkillTool/SkillTool.ts · 第 77–94 行(共 1109 行)

  77| /**
  78|  * Gets all commands including MCP skills/prompts from AppState.
  79|  * SkillTool needs this because getCommands() only returns local/bundled skills.
  80|  */
  81| async function getAllCommands(context: ToolUseContext): Promise<Command[]> {
  82|   // Only include MCP skills (loadedFrom === 'mcp'), not plain MCP prompts.
  83|   // Before this filter, the model could invoke MCP prompts via SkillTool
  84|   // if it guessed the mcp__server__prompt name — they weren't discoverable
  85|   // but were technically reachable.
  86|   const mcpSkills = context
  87|     .getAppState()
  88|     .mcp.commands.filter(
  89|       cmd => cmd.type === 'prompt' && cmd.loadedFrom === 'mcp',
  90|     )
  91|   if (mcpSkills.length === 0) return getCommands(getProjectRoot())
  92|   const localCommands = await getCommands(getProjectRoot())
  93|   return uniqBy([...localCommands, ...mcpSkills], 'name')
  94| }

createSkillCommand 统一 MCP 与 disk

MCP prompt 转 skill 时复用 createSkillCommand,保证:

  • 相同 frontmatter 语义(allowed-tools、model、context:fork)
  • 相同 getPromptForCommand 执行链(argument substitution、shell)
  • 相同 telemetry skillLoadedEvent

parseSkillFrontmatterFields 允许 MCP metadata 映射到 skill 字段而不重复 parser。

MCP server 断开 → client 从 AppState 移除 commands → SkillTool 下次 getAllCommands 不再包含。

源码引用: src/skills/loadSkillsDir.ts · 第 270–285 行(共 1087 行)

 270| export function createSkillCommand({
 271|   skillName,
 272|   displayName,
 273|   description,
 274|   hasUserSpecifiedDescription,
 275|   markdownContent,
 276|   allowedTools,
 277|   argumentHint,
 278|   argumentNames,
 279|   whenToUse,
 280|   version,
 281|   model,
 282|   disableModelInvocation,
 283|   userInvocable,
 284|   source,
 285|   baseDir,

源码引用: src/utils/telemetry/skillLoadedEvent.ts · 第 1–20 行(共 40 行)

   1| import { getSkillToolCommands } from '../../commands.js'
   2| import {
   3|   type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
   4|   type AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
   5|   logEvent,
   6| } from '../../services/analytics/index.js'
   7| import { getCharBudget } from '../../tools/SkillTool/prompt.js'
   8| 
   9| /**
  10|  * Logs a tengu_skill_loaded event for each skill available at session startup.
  11|  * This enables analytics on which skills are available across sessions.
  12|  */
  13| export async function logSkillsLoaded(
  14|   cwd: string,
  15|   contextWindowTokens: number,
  16| ): Promise<void> {
  17|   const skills = await getSkillToolCommands(cwd)
  18|   const skillBudget = getCharBudget(contextWindowTokens)
  19| 
  20|   for (const skill of skills) {

AppState.mcp.commands 生命周期

MCP server connect → discovery 写入 commands;disconnect → 移除该 server 条目。

SkillTool 每次 call 读 fresh AppState,故 hot-plug MCP server 后模型下一 turn 可见新 skill。

loadedFrom === 'mcp' 标记是 SkillTool 与 slash 补全分界的唯一可靠字段——勿仅用 name 前缀 mcp__ 判断。

源码引用: src/state/AppStateStore.ts · 第 1–30 行(共 570 行)

   1| import type { Notification } from 'src/context/notifications.js'
   2| import type { TodoList } from 'src/utils/todo/types.js'
   3| import type { BridgePermissionCallbacks } from '../bridge/bridgePermissionCallbacks.js'
   4| import type { Command } from '../commands.js'
   5| import type { ChannelPermissionCallbacks } from '../services/mcp/channelPermissions.js'
   6| import type { ElicitationRequestEvent } from '../services/mcp/elicitationHandler.js'
   7| import type {
   8|   MCPServerConnection,
   9|   ServerResource,
  10| } from '../services/mcp/types.js'
  11| import { shouldEnablePromptSuggestion } from '../services/PromptSuggestion/promptSuggestion.js'
  12| import {
  13|   getEmptyToolPermissionContext,
  14|   type Tool,
  15|   type ToolPermissionContext,
  16| } from '../Tool.js'
  17| import type { TaskState } from '../tasks/types.js'
  18| import type { AgentColorName } from '../tools/AgentTool/agentColorManager.js'
  19| import type { AgentDefinitionsResult } from '../tools/AgentTool/loadAgentsDir.js'
  20| import type { AllowedPrompt } from '../tools/ExitPlanModeTool/ExitPlanModeV2Tool.js'
  21| import type { AgentId } from '../types/ids.js'
  22| import type { Message, UserMessage } from '../types/message.js'
  23| import type { LoadedPlugin, PluginError } from '../types/plugin.js'
  24| import type { DeepImmutable } from '../types/utils.js'
  25| import {
  26|   type AttributionState,
  27|   createEmptyAttributionState,
  28| } from '../utils/commitAttribution.js'
  29| import type { EffortValue } from '../utils/effort.js'
  30| import type { FileHistoryState } from '../utils/fileHistory.js'

client.ts discovery 接缝

MCP client 连接 server 后 listPrompts/listTools 写入 AppState.mcp。mcpSkills 层(或 inline client 逻辑)应把 prompt 转为 createSkillCommand 输出。

当前树 fetchMcpSkillsForClient stub 返回 [],但 SkillTool getAllCommands 仍读 AppState——说明 fetch 可能在 client connect handler 内联。

排查:grep loadedFrom: 'mcp' 赋值点与 mcp.commands.push。

源码引用: src/services/mcp/client.ts · 第 1–30 行(共 3349 行)

   1| import { feature } from 'bun:bundle'
   2| import type {
   3|   Base64ImageSource,
   4|   ContentBlockParam,
   5|   MessageParam,
   6| } from '@anthropic-ai/sdk/resources/index.mjs'
   7| import { Client } from '@modelcontextprotocol/sdk/client/index.js'
   8| import {
   9|   SSEClientTransport,
  10|   type SSEClientTransportOptions,
  11| } from '@modelcontextprotocol/sdk/client/sse.js'
  12| import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
  13| import {
  14|   StreamableHTTPClientTransport,
  15|   type StreamableHTTPClientTransportOptions,
  16| } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
  17| import {
  18|   createFetchWithInit,
  19|   type FetchLike,
  20|   type Transport,
  21| } from '@modelcontextprotocol/sdk/shared/transport.js'
  22| import {
  23|   CallToolResultSchema,
  24|   ElicitRequestSchema,
  25|   type ElicitRequestURLParams,
  26|   type ElicitResult,
  27|   ErrorCode,
  28|   type JSONRPCMessage,
  29|   type ListPromptsResult,
  30|   ListPromptsResultSchema,

MCP prompt 命名与 mcp__ 前缀

磁盘 skill 与 MCP skill 在 Command.name 命名空间共存。uniqBy name 以 local 优先。

MCP server prompt 名常带 server 前缀;SkillTool 过滤 loadedFrom===mcp 确保仅「skill 化」prompt 可模型调用。

用户 slash 补全由 PromptInput 查询 getCommands,MCP prompt 若未 skill 化可能不可见——与 SkillTool 列表 intentionally 不同。

与 mcp-entrypoint server 侧对比

entrypoints/mcp.ts — Claude Code 作为 MCP server 暴露 tools。

skills/mcpSkills — Claude Code 作为 MCP client 消费 外部 server prompts。

方向相反,共用 MCP SDK 类型(agentSdkTypes CallToolResult 等)。

REPL useMergedClients 管理 MCP 连接;skills 模块消费连接产物,不处理 transport。

源码引用: src/entrypoints/mcp.ts · 第 1–10 行(共 197 行)

   1| import { Server } from '@modelcontextprotocol/sdk/server/index.js'
   2| import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
   3| import {
   4|   CallToolRequestSchema,
   5|   type CallToolResult,
   6|   ListToolsRequestSchema,
   7|   type ListToolsResult,
   8|   type Tool,
   9| } from '@modelcontextprotocol/sdk/types.js'
  10| import { getDefaultAppState } from 'src/state/AppStateStore.js'

源码引用: src/screens/REPL.tsx · 第 727–727 行(共 7050 行)

 727|   // cost — otherwise setSearchQuery fills the cache first and warm

本章小结与延伸

mcp-skills = MCP prompt 与 disk skill 的桥梁。builder registry 稳定;fetch 实现随 client 演进。SkillTool 仅 merge loadedFrom===mcp 的 prompt,防止猜测名调用 raw MCP prompt。disconnect 应移除 AppState 条目。 继续学习:

  • skill-tool-integration
  • services mcp-client
Prev
bundled-skills · 内置 skill 与 initBundledSkills
Next
skill-tool-integration · SkillTool 与命令注册