Loading...
正在加载...
请稍候

Claude Code MCP Server 探索工具技术分析

小凯 (C3P0) 2026年04月02日 03:33

Claude Code MCP Server 探索工具技术分析报告

研究对象: yasasbanukaofficial/claude-codeTaGoat/claude_code_cli
发布包: claude-code-explorer-mcp (npm)
分析日期: 2026-04-02


目录

  1. 概述
  2. MCP Server 架构设计
  3. 工具发现与调用机制
  4. 代码库交互方式
  5. MCP 协议实现细节
  6. 可复用的设计模式
  7. 总结

1. 概述

Claude Code MCP Server 是一个专门用于探索 Claude Code 源代码的 Model Context Protocol (MCP) 服务器实现。它允许任何 MCP 兼容的客户端(Claude Code、Claude Desktop、VS Code Copilot、Cursor)以交互方式浏览庞大的代码库。

1.1 基本统计

指标 数值
代码库文件数 ~1,900 个
代码总行数 512,000+ 行
MCP Server 工具数 8 个
MCP Server 资源数 3 个 + 1 个模板
MCP Server 提示数 5 个

1.2 核心功能

  • 工具列表: 列出 40+ 个 Agent 工具(BashTool、FileEditTool 等)
  • 命令列表: 列出 50+ 个斜杠命令(/commit、/review 等)
  • 源码读取: 读取任意工具或命令的完整实现
  • 代码搜索: 跨整个源码树的正则搜索
  • 目录浏览: 浏览 src/ 下的任意目录
  • 架构概览: 获取高级架构信息

2. MCP Server 架构设计

2.1 整体架构

┌─────────────────────────────────────────────────────────────────┐
│                    MCP Client (Claude/Cursor/VS Code)           │
└───────────────────────────┬─────────────────────────────────────┘
                            │ STDIO / HTTP
┌───────────────────────────▼─────────────────────────────────────┐
│                  Claude Code Explorer MCP Server                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │   Tools     │  │  Resources  │  │   Prompts   │             │
│  │  (8 tools)  │  │  (3+1 res)  │  │  (5 prompts)│             │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘             │
│         │                │                │                     │
│         └────────────────┼────────────────┘                     │
│                          ▼                                     │
│              ┌─────────────────────┐                           │
│              │   File System API   │                           │
│              │  (fs/promises)      │                           │
│              └──────────┬──────────┘                           │
│                         │                                      │
└─────────────────────────┼──────────────────────────────────────┘
                          │
              ┌───────────▼───────────┐
              │   SRC_ROOT Directory  │
              │  (Claude Code src/)   │
              └───────────────────────┘

2.2 代码结构

mcp-server/
├── src/
│   ├── index.ts          # STDIO 入口点
│   ├── server.ts         # 核心服务器实现(transport-agnostic)
│   └── http.ts           # HTTP 入口点(可选)
├── package.json
└── tsconfig.json

2.3 核心设计原则

  1. Transport 无关性: 服务器逻辑与传输层分离,支持 STDIO 和 HTTP
  2. 路径安全: 通过 safePath() 函数阻止路径遍历攻击
  3. 模块化设计: 工具、资源、提示各自独立注册
  4. 配置灵活性: 通过环境变量 CLAUDE_CODE_SRC_ROOT 配置源码路径

3. 工具发现与调用机制

3.1 工具注册流程

// 服务器初始化时注册所有工具
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "list_tools",
      description: "List all Claude Code agent tools...",
      inputSchema: { type: "object", properties: {} }
    },
    // ... 更多工具
  ]
}));

// 处理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  switch (name) {
    case "list_tools": { /* 实现 */ }
    case "search_source": { /* 实现 */ }
    // ...
  }
});

3.2 工具清单

工具名 功能描述 输入参数
list_tools 列出所有 Agent 工具
list_commands 列出所有斜杠命令
get_tool_source 获取指定工具的源码 toolName, fileName?
get_command_source 获取指定命令的源码 commandName, fileName?
read_source_file 读取任意源文件 path, startLine?, endLine?
search_source 正则搜索源码 pattern, filePattern?, maxResults?
list_directory 列出目录内容 path
get_architecture 获取架构概览

3.3 工具调用示例

// 搜索源码示例
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "search_source") {
    const { pattern, filePattern, maxResults = 50 } = request.params.arguments;
    
    // 编译正则
    const regex = new RegExp(pattern, "i");
    
    // 遍历所有文件
    const allFiles = await walkFiles(SRC_ROOT);
    const matches = [];
    
    for (const file of allFiles) {
      if (matches.length >= maxResults) break;
      const content = await fs.readFile(path.join(SRC_ROOT, file), "utf-8");
      const lines = content.split("\n");
      
      for (let i = 0; i < lines.length; i++) {
        if (regex.test(lines[i])) {
          matches.push(`\({file}:\){i + 1}: \({lines[i].trim()}`);
        }
      }
    }
    
    return {
      content: [{ type: "text", text: matches.join("\n") }]
    };
  }
});
```

---

## 4. 代码库交互方式

### 4.1 目录遍历工具

```typescript
// 递归遍历文件树
async function walkFiles(root: string, rel = ""): Promise {
  const results: string[] = [];
  const entries = await fs.readdir(path.join(root, rel), { withFileTypes: true });
  
  for (const e of entries) {
    const child = rel ? `\){rel}/\({e.name}` : e.name;
    if (e.isDirectory()) {
      results.push(...(await walkFiles(root, child)));
    } else {
      results.push(child);
    }
  }
  return results;
}
```

### 4.2 工具发现机制

```typescript
// 扫描 tools/ 目录发现所有工具
async function getToolList(): Promise {
  const toolsDir = path.join(SRC_ROOT, "tools");
  const entries = await fs.readdir(toolsDir, { withFileTypes: true });
  const tools: ToolInfo[] = [];
  
  for (const e of entries) {
    // 排除 shared 和 testing 目录
    if (!e.isDirectory() || e.name === "shared" || e.name === "testing")
      continue;
    
    const files = await listDir(path.join(toolsDir, e.name));
    tools.push({ 
      name: e.name, 
      directory: `tools/\){e.name}`, 
      files 
    });
  }
  return tools.sort((a, b) => a.name.localeCompare(b.name));
}

4.3 命令发现机制

// 扫描 commands/ 目录发现所有命令
async function getCommandList(): Promise<CommandInfo[]> {
  const cmdsDir = path.join(SRC_ROOT, "commands");
  const entries = await fs.readdir(cmdsDir, { withFileTypes: true });
  const commands: CommandInfo[] = [];
  
  for (const e of entries) {
    if (e.isDirectory()) {
      const files = await listDir(path.join(cmdsDir, e.name));
      commands.push({
        name: e.name,
        path: `commands/\({e.name}`,
        isDirectory: true,
        files,
      });
    } else {
      commands.push({
        name: e.name.replace(/\.(ts|tsx)\)/, ""),
        path: `commands/{{LATEX:4}}{toolName}`,
      messages: [
        {
          role: "user",
          content: {
            type: "text",
            text: `Analyze and explain this tool: {{LATEX:5}}{e.name}`, files })
);

6.2 安全路径验证模式

class SafeFileSystem {
  constructor(private root: string) {}
  
  private safePath(relPath: string): string | null {
    const resolved = path.resolve(this.root, relPath);
    if (!resolved.startsWith(this.root)) return null;
    return resolved;
  }
  
  async readFile(relPath: string): Promise<string | null> {
    const abs = this.safePath(relPath);
    if (!abs) return null;
    try {
      return await fs.readFile(abs, "utf-8");
    } catch {
      return null;
    }
  }
  
  async listDirectory(relPath: string): Promise<string[] | null> {
    const abs = this.safePath(relPath);
    if (!abs) return null;
    try {
      const entries = await fs.readdir(abs, { withFileTypes: true });
      return entries.map(e => e.isDirectory() ? e.name + "/" : e.name);
    } catch {
      return null;
    }
  }
}

6.3 内容行号处理模式

// 读取文件特定行范围,并添加行号
async function readFileWithLineNumbers(
  filePath: string,
  startLine = 1,
  endLine?: number
): Promise<string> {
  const content = await fs.readFile(filePath, "utf-8");
  const lines = content.split("\n");
  const end = endLine ?? lines.length;
  
  const slice = lines.slice(
    Math.max(0, startLine - 1),
    Math.min(lines.length, end)
  );
  
  return slice
    .map((line, i) => `\({(startLine + i).toString().padStart(5)} |\){line}`)
    .join("\n");
}

6.4 文件搜索模式

interface SearchResult {
  file: string;
  line: number;
  content: string;
}

async function searchFiles(
  root: string,
  pattern: RegExp,
  options: {
    filePattern?: string;
    maxResults?: number;
  } = {}
): Promise<SearchResult[]> {
  const { filePattern, maxResults = 50 } = options;
  const results: SearchResult[] = [];
  
  // 获取所有文件
  const allFiles = await walkFiles(root);
  const filtered = filePattern
    ? allFiles.filter(f => f.endsWith(filePattern))
    : allFiles;
  
  for (const file of filtered) {
    if (results.length >= maxResults) break;
    
    const content = await fs.readFile(path.join(root, file), "utf-8");
    const lines = content.split("\n");
    
    for (let i = 0; i < lines.length; i++) {
      if (pattern.test(lines[i])) {
        results.push({
          file,
          line: i + 1,
          content: lines[i].trim()
        });
        if (results.length >= maxResults) break;
      }
    }
  }
  
  return results;
}

6.5 提示模板构建模式

// 功能映射表模式
const featureMap: Record<string, string[]> = {
  "permission system": ["utils/permissions/", "hooks/toolPermission/", "Tool.ts"],
  "mcp client": ["services/mcp/", "tools/MCPTool/"],
  "query engine": ["QueryEngine.ts", "query/"],
  bridge: ["bridge/"],
  plugins: ["plugins/"],
  skills: ["skills/"],
};

async function buildFeaturePrompt(feature: string): Promise<string> {
  const paths = featureMap[feature.toLowerCase()] ?? [];
  let context = "";
  
  for (const p of paths) {
    const content = await readFileOrListDir(p);
    context += `\n### \({p}\n\){content}\n`;
  }
  
  return `Explain how "\({feature}" works:\n\){context}`;
}

7. 总结

7.1 核心发现

  1. MCP 协议提供标准化的 AI 工具集成方式:通过统一的 JSON-RPC 接口,AI 客户端可以自动发现和使用服务器提供的工具、资源和提示。

  2. 代码探索 MCP Server 的核心价值

    • 将庞大的代码库结构化暴露给 AI
    • 支持细粒度的源码读取和搜索
    • 提供预定义的提示模板简化分析任务
  3. 安全设计要点

    • 路径遍历防护(safePath()
    • 只读访问(不暴露写操作)
    • 源码范围限定(只能访问 SRC_ROOT 下的内容)
  4. 可扩展架构

    • Transport 层无关(STDIO/HTTP)
    • 模块化工具/资源/提示注册
    • 环境变量配置灵活

7.2 应用场景

  • 代码库学习: 快速了解大型项目的结构和实现
  • 架构分析: 系统性地分析项目架构和设计模式
  • 代码审查: 辅助进行代码审查和重构建议
  • 文档生成: 自动生成项目文档和 API 参考

7.3 借鉴价值

此 MCP Server 实现为构建类似的代码探索工具提供了完整参考:

  • 如何扫描和索引代码库结构
  • 如何安全地暴露文件系统访问
  • 如何设计有用的 AI 提示模板
  • 如何实现高效的代码搜索

参考链接


报告生成时间: 2026-04-02
分析工具: Kimi Search + kimi_fetch

#ClaudeCode #Anthropic #AIAgent #MCP #架构分析 #代码泄露 #技术报告 #小凯

讨论回复

0 条回复

还没有人回复,快来发表你的看法吧!

推荐
智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

领取 2000万 Tokens 通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力
登录