第 7 章 工具扩展

提示🎧 本章配套播客
重要学习目标
  1. 理解 Tool Use 的核心机制,掌握函数调用原理和工具定义格式
  2. 应用 模型上下文协议(MCP)实现智能体与外部系统的标准化通信
  3. 应用 开发自定义 MCP Server,扩展智能体的工具能力
  4. 理解 Claude Code Plugin 系统的结构与使用方法
  5. 分析 Skill、Agent 与 MCP 三者的协同工作机制
  6. 创建 整合 Plugin、MCP、Skill 的完整金融智能体系统

工具扩展体系全景图

工具扩展是大语言模型智能体与外部世界交互的核心能力。想象一下,如果智能体只能依靠训练数据中的知识回答问题,那它就像一个与世隔绝的学者——博学但与现实脱节。而工具扩展让智能体能够查询实时股价、访问数据库、调用量化分析接口,甚至执行交易指令。

本章将从底层原理讲起,介绍 Claude Code 的工具扩展体系——MCP 协议、Plugin 系统,以及 Skill、Agent 与 MCP 如何协同工作,最后通过金融场景的案例帮助你掌握实际应用。

7.1 Tool Use 核心机制

工具使用(Tool Use)通过函数调用扩展大语言模型的能力边界。本节介绍工具使用的底层工作原理。

Tool Use 函数调用五步流程

7.1.1 函数调用原理

大语言模型的函数调用遵循一个多轮对话流程,包含五个核心步骤。

第一步:定义可用工具

开发者需要向模型提供工具定义,描述每个工具的功能、参数和用途。这就像给模型一份工具说明书。

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_price",
            "description": "获取指定股票的实时价格和基本行情信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "symbol": {
                        "type": "string",
                        "description": "股票代码,如 AAPL 表示苹果公司"
                    },
                    "market": {
                        "type": "string",
                        "enum": ["US", "HK", "CN"],
                        "description": "市场类型:美股、港股或 A 股"
                    }
                },
                "required": ["symbol"]
            }
        }
    }
]

第二步:模型决策是否调用工具

当用户提问时,模型会分析问题,判断是否需要调用工具。例如,当用户问”苹果公司股价多少?“时,模型会识别到这需要实时数据,于是决定调用 get_stock_price 工具。

第三步:应用执行函数逻辑

开发者的代码接收到工具调用请求后,实际执行函数逻辑——比如调用金融数据 API 获取股价。

第四步:返回工具执行结果

将函数执行结果返回给模型,通常以 JSON 格式。

第五步:模型生成最终回复

模型整合工具返回的数据,生成自然语言回复:“苹果公司当前股价为 178.50 美元,较前一交易日上涨 2.3%。”

注记知识卡片

为什么需要工具调用?大语言模型存在三个核心限制:

  1. 知识截止日期:训练数据有时间限制,无法获取最新信息
  2. 无法执行操作:只能生成文本,不能查询数据库或调用 API
  3. 数学计算能力有限:复杂计算容易出错

工具调用通过让模型主动请求外部帮助,突破了这些限制。

7.1.2 工具定义格式

工具定义使用 JSON Schema 规范——一个描述 JSON 数据结构的标准格式。

核心字段说明

字段 必需 说明
type 工具类型,通常为 function
function.name 函数名称,必须与代码中的函数名一致
function.description 功能描述,模型依赖此信息判断何时调用
function.parameters 参数定义,符合 JSON Schema 规范

参数类型系统

JSON Schema 支持丰富的数据类型:

{
    "type": "object",
    "properties": {
        # 字符串类型
        "company_name": {
            "type": "string",
            "description": "公司名称"
        },
        # 整数类型
        "share_count": {
            "type": "integer",
            "description": "持股数量"
        },
        # 浮点数类型
        "portfolio_weight": {
            "type": "number",
            "description": "组合权重(0-1 之间的小数)"
        },
        # 布尔类型
        "is_core_holding": {
            "type": "boolean",
            "description": "是否为核心持仓"
        },
        # 枚举类型:限制只能取特定值
        "order_type": {
            "type": "string",
            "enum": ["market", "limit", "stop"],
            "description": "订单类型:市价单、限价单或止损单"
        },
        # 数组类型
        "symbols": {
            "type": "array",
            "items": {"type": "string"},
            "description": "股票代码列表"
        }
    },
    "required": ["company_name", "share_count"]
}

必需参数与可选参数

通过 required 字段声明必需参数。未列入 required 的参数为可选参数,模型可以选择不填写或使用默认值。

7.1.3 参数验证与错误处理

工具调用过程中需要注意两个关键问题:参数验证和错误处理。

参数验证

即使模型返回了参数,应用代码也应该进行验证,防止恶意输入或边界情况。推荐使用 Pydantic 等数据验证库自动检查数据类型和约束条件。

警告安全提示

永远不要使用 eval() 来解析模型返回的参数。正确做法是使用 json.loads()

错误处理策略

错误类型 示例 处理策略
参数错误 缺少必需参数、类型不匹配 返回详细错误信息,让模型重试
API 调用失败 网络超时、API 限流 重试机制 + 降级方案
业务逻辑错误 余额不足、股票停牌 返回明确的业务错误信息
权限错误 未授权访问数据 拒绝执行并说明原因

对于网络相关的错误,可以使用指数退避重试策略(1 秒、2 秒、4 秒递增)。当主要数据源失败时,尝试备用数据源或返回缓存数据。

7.2 Claude Code 内置工具回顾

Claude Code 提供了一套强大的内置工具,帮助智能体理解和修改代码库。第 3 章已详细介绍过这些工具,本节做简要回顾,为后续工具扩展内容做铺垫。

Claude Code 内置工具分类

7.2.1 工具分类概览

类别 工具 功能 授权
文件操作 Read 读取文件内容(支持图像、PDF、Notebook)
文件操作 Write 创建或覆盖文件
文件操作 Edit 精确字符串替换修改
命令执行 Bash 执行 Shell 命令
搜索 Grep 基于 ripgrep 的内容搜索
搜索 Glob 文件模式匹配
网络 WebSearch 网页搜索
网络 WebFetch 获取网页内容

7.2.2 工具组合模式

Claude Code 的工具设计遵循一个核心权衡:使用频率 vs. 使用精确性。在实际使用中,常见的工具组合模式包括:

模式 1:探索-修改-验证

  1. Glob/Grep - 查找目标文件
  2. Read - 理解现有代码
  3. Edit - 精确修改
  4. Bash - 运行测试验证

模式 2:重构工作流

  1. Grep - 查找所有引用
  2. Read - 理解上下文
  3. Edit(多次) - 批量修改
  4. Bash - 运行测试
提示教学提示

优先使用专用工具而非 Bash:使用 Grep 搜索代码而非 bash grep,使用 Read 读取文件而非 bash cat。专用工具更可靠、输出更规范。

7.3 MCP 协议详解

模型上下文协议(Model Context Protocol, MCP)是 Anthropic 于 2024 年 11 月推出的开源协议标准,为 AI 应用与外部系统之间的连接提供统一接口。

MCP 协议架构图

7.3.1 .mcp.json 配置格式

MCP 配置文件定义了客户端如何连接到服务器。

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/directory"],
      "env": {
        "NODE_ENV": "production"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    },
    "sentry-remote": {
      "url": "https://sentry-mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${SENTRY_API_TOKEN}"
      }
    }
  }
}

配置字段说明

stdio 服务器配置:

  • command:启动服务器的命令(如 npxpython
  • args:命令行参数数组
  • env:环境变量(支持 ${VAR} 展开)

远程服务器配置:

  • url:MCP 端点 URL
  • headers:HTTP 请求头(如 Authorization

配置加载优先级

Claude Code 按以下顺序加载配置(后者覆盖前者):

  1. 用户配置:~/.claude/mcp.json
  2. 项目配置:.mcp.json(可提交到版本控制)
  3. 企业配置:Enterprise MCP
  4. 命令行参数:--mcp-config

7.3.2 Server 类型与连接方式

MCP 支持两种传输机制:

stdio 传输

本地进程间通信,通过标准输入输出流交换 JSON-RPC 消息。

特点:

  • 客户端将服务器作为子进程启动
  • 消息通过 stdin/stdout 传输
  • 零网络开销,性能最优
  • 仅限本地单客户端场景

使用场景:本地文件系统操作、本地数据库查询

Streamable HTTP 传输

远程服务器通信,使用 HTTP POST 和 Server-Sent Events(SSE)。

特点:

  • 支持远程服务器
  • 支持会话管理
  • 支持断线重连
  • 适合跨网络、分布式场景
注记知识卡片

MCP 的核心价值在于解决 M×N 问题。传统方式下,每个 AI 应用需要为每个数据源单独开发集成方案。通过 MCP,开发者只需实现一次协议,就能让 AI 应用访问任意兼容的数据源,将 M×N 问题简化为 M+N。

7.3.3 资源与工具定义

MCP 提供三种核心原语:

Tools(工具)

工具是 AI 可以调用的可执行函数,用于执行具体操作。

工具发现流程:客户端发送 tools/list 请求,服务器返回工具列表。

{
  "tools": [
    {
      "name": "get_stock_price",
      "description": "获取指定股票的实时价格",
      "inputSchema": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string",
            "description": "股票代码"
          }
        },
        "required": ["symbol"]
      }
    }
  ]
}

Resources(资源)

资源是服务器向客户端共享的数据,为语言模型提供上下文信息。

{
  "resources": [
    {
      "uri": "file:///project/src/main.py",
      "name": "主程序文件",
      "description": "Python 应用的主入口文件",
      "mimeType": "text/x-python"
    }
  ]
}

Prompts(提示)

提示是可重用的模板,帮助结构化与语言模型的交互。MCP 的 Prompts 原语允许服务器向客户端暴露预定义的提示词模板。

Prompts 发现流程:客户端发送 prompts/list 请求,服务器返回可用提示列表。

{
  "prompts": [
    {
      "name": "analyze_stock",
      "description": "分析股票的技术面和基本面",
      "arguments": [
        {
          "name": "symbol",
          "description": "股票代码",
          "required": true
        },
        {
          "name": "analysis_depth",
          "description": "分析深度:basic/detailed/comprehensive",
          "required": false
        }
      ]
    }
  ]
}

使用场景:

  • 标准化分析流程:为常见任务提供统一的提示模板
  • 知识封装:将领域专家的分析方法封装为提示
  • 快速启动:用户无需手动编写复杂提示词

调用示例:

{
  "method": "prompts/get",
  "params": {
    "name": "analyze_stock",
    "arguments": {
      "symbol": "AAPL",
      "analysis_depth": "detailed"
    }
  }
}

服务器返回填充后的提示:

{
  "description": "分析 AAPL 股票",
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "text",
        "text": "请对苹果公司(AAPL)进行详细分析,包括:\n1. 技术面分析(RSI、MACD、均线)\n2. 基本面分析(PE、PB、ROE)\n3. 行业对比\n4. 投资建议"
      }
    }
  ]
}

Prompts vs. Tools 区别

特性 Prompts Tools
目的 提供提示模板 执行具体操作
执行方 客户端(模型使用提示) 服务器(执行函数)
适用场景 标准化分析流程 数据查询、计算

7.3.4 安全边界与权限控制

MCP 安全最佳实践:

身份认证

  • 所有 MCP Server 访问都需要适当的认证
  • 推荐使用 OAuth 2.0 with PKCE
  • 访问令牌应短期有效(15-30 分钟)

权限控制

  • 基于角色的访问控制(RBAC)
  • 只读角色:仅用于数据消费
  • 写入权限:仅限特定数据源
  • 管理员访问:完整审计日志

输入验证

  • 对所有工具输入进行严格验证
  • 使用 JSON Schema 验证参数
  • 避免直接执行用户提供的代码或 SQL

人在回路

  • 清晰展示即将调用的工具
  • 在敏感操作前弹出确认提示
  • 实现操作超时和审计日志

7.4 MCP Server 开发

掌握 MCP Server 开发,你就能将任意数据源和服务集成到 Claude Code 中。

7.4.1 Python MCP Server 开发

环境准备

# 创建项目目录
mkdir stock-mcp-server
cd stock-mcp-server

# 使用 uv 初始化(推荐)
uv init
uv venv
source .venv/bin/activate

# 安装 MCP SDK
uv add "mcp[cli]" httpx

使用 FastMCP 构建服务器

FastMCP 是 MCP Python SDK 提供的高级接口,相比低级接口 StdioServer,FastMCP 的优势在于:

  1. 自动生成工具定义:通过类型注解和文档字符串自动生成 JSON Schema
  2. 简化错误处理:内置异常捕获和格式化
  3. 代码简洁:无需手动注册处理器
特性 FastMCP StdioServer
工具定义 自动生成 手动编写 JSON
代码量 少(约 20 行) 多(约 50 行)
适用场景 快速开发、简单工具 复杂逻辑、精细控制

对于金融应用,推荐使用 FastMCP 快速原型开发,待系统成熟后再考虑迁移到低级接口以优化性能。

# server.py
from mcp.server.fastmcp import FastMCP
import httpx

# 创建 FastMCP 实例
mcp = FastMCP("StockDataServer")

@mcp.tool()
async def get_stock_price(symbol: str, market: str = "US") -> str:
    """获取股票实时价格

    Args:
        symbol: 股票代码,如 AAPL、TSLA
        market: 市场类型,可选 US、HK、CN

    Returns:
        股票价格信息的格式化文本
    """
    try:
        # 调用外部 API 获取数据
        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"https://api.example.com/quote/{symbol}",
                timeout=10.0
            )
            data = response.json()

        return f"""
**{symbol} 股票信息**
- 当前价格:${data['price']:.2f}
- 涨跌幅:{data['change_percent']:.2f}%
- 成交量:{data['volume']:,}
"""
    except Exception as e:
        return f"获取股价失败:{str(e)}"

# 主函数
if __name__ == "__main__":
    mcp.run(transport="stdio")
提示教学提示

工具定义的最佳实践:

  1. 使用清晰的函数名和文档字符串
  2. 使用类型注解定义参数类型
  3. 提供详细的 Args 和 Returns 说明
  4. 实现完善的错误处理
  5. 返回格式化的、易读的结果

7.4.2 TypeScript MCP Server 开发

环境准备

# 创建项目目录
mkdir stock-server-ts
cd stock-server-ts

# 初始化项目
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx

基础服务器结构

// src/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
  { name: "stock-server", version: "1.0.0" },
  { capabilities: { tools: {} } }
);

// 工具定义
const tools = [
  {
    name: "get_stock_price",
    description: "获取股票实时价格",
    inputSchema: {
      type: "object",
      properties: {
        symbol: { type: "string", description: "股票代码" },
      },
      required: ["symbol"],
    },
  },
];

// 注册工具列表处理器
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));

// 注册工具调用处理器
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  if (name === "get_stock_price") {
    const { symbol } = args as { symbol: string };
    // 实现股价查询逻辑...
    return {
      content: [{ type: "text", text: `${symbol} 当前价格:$178.50` }],
    };
  }

  throw new Error(`未知工具:${name}`);
});

// 主函数
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

main();

7.4.3 工具实现与测试

使用 MCP Inspector 调试

MCP Inspector 是官方调试工具,提供交互式界面。

# Python
npx @modelcontextprotocol/inspector python server.py

# TypeScript
npx @modelcontextprotocol/inspector node build/index.js

Inspector 界面功能:

  • Tools:调用工具并查看结果
  • Resources:查看和测试资源
  • Prompts:测试提示词模板
警告重要规则

永远不要写入 stdout(标准输出),这会破坏 JSON-RPC 消息。

# 错误:会破坏协议
print("Debug info")

# 正确:写入 stderr
import sys
print("Debug info", file=sys.stderr)

7.4.4 调试与部署

配置到 Claude Code

在项目的 .mcp.json 中添加服务器配置:

{
  "mcpServers": {
    "stock-data": {
      "command": "python",
      "args": ["/path/to/server.py"]
    }
  }
}

常见问题排查

服务器未显示在 Claude:

  • 检查配置文件路径是否为绝对路径
  • 确认配置文件 JSON 格式正确
  • 重启 Claude Code

工具调用失败:

  • 检查日志中的错误信息
  • 验证服务器单独运行正常
  • 使用 Inspector 测试服务器响应

7.5 Claude Code Plugin 系统

Plugin 是 Claude Code 的模块化扩展机制,将 Skill、Agent、MCP Server 和 Hooks 打包成可分发、可复用的能力包。2025 年 10 月,Anthropic 正式发布了 Plugin 系统,目前已有 200+ 生产级插件覆盖 15 个类别。

7.5.1 Plugin 结构

Plugin 是包含 .claude-plugin/plugin.json 清单文件的目录:

my-plugin/
├── .claude-plugin/
│   └── plugin.json          # 必需:插件清单
├── skills/                  # 可选:Agent Skills
│   └── stock-analyzer/
│       └── SKILL.md
├── agents/                  # 可选:自定义子智能体
├── commands/                # 可选:斜杠命令
├── hooks/                   # 可选:事件钩子
│   └── hooks.json
├── .mcp.json               # 可选:MCP Server 配置
└── .lsp.json               # 可选:LSP Server 配置

plugin.json 清单格式

{
  "name": "finance-toolkit",
  "description": "金融数据分析工具包,含股票查询、技术分析、组合管理等功能",
  "version": "1.0.0",
  "author": {
    "name": "Your Name"
  }
}

关键字段说明:

  • name:插件唯一标识符,同时作为 Skill 命名空间(如 /finance-toolkit:analyze
  • description:在插件管理器中显示的描述
  • version:语义化版本号

7.5.2 Plugin 与 Standalone 配置对比

对比维度 Standalone(.claude/ Plugin
作用范围 单个项目 跨项目共享
Skill 命名 /hello /plugin-name:hello
适用场景 个人工作流、实验性配置 团队共享、市场分发
分发方式 手动复制 插件市场安装
版本控制 随项目提交 独立版本管理

何时使用 Standalone

  • 为单个项目定制 Claude Code 配置
  • 个人专属的工作流程
  • 正式打包前的实验

何时使用 Plugin

  • 需要在多个项目中复用
  • 与团队或社区共享
  • 通过市场分发

7.5.3 Plugin 安装与管理

本地开发测试

# 加载本地插件进行测试
claude --plugin-dir ./my-plugin

# 测试多个插件
claude --plugin-dir ./plugin-one --plugin-dir ./plugin-two

插件市场安装

/plugin install finance-toolkit
/plugin enable finance-toolkit
/plugin disable finance-toolkit
/plugin list
注记知识卡片

Plugin 系统要求 Claude Code v1.0.33 或更高版本。可通过 claude --version 检查当前版本。

7.5.4 从 Standalone 迁移到 Plugin

如果你已在项目中创建了 .claude/ 配置,可以按以下步骤迁移为 Plugin:

  1. 创建插件目录结构
mkdir -p my-plugin/.claude-plugin
  1. 创建清单文件my-plugin/.claude-plugin/plugin.json

  2. 复制配置文件

cp -r .claude/skills my-plugin/
cp -r .claude/agents my-plugin/
cp -r .claude/commands my-plugin/
  1. 迁移 Hooks:从 .claude/settings.json 提取到 my-plugin/hooks/hooks.json

  2. 测试claude --plugin-dir ./my-plugin

7.6 Skill、Agent 与 MCP 协同工作

Skill、Agent(子智能体)和 MCP 是 Claude Code 工具扩展体系的三大支柱。理解它们如何协同工作,是构建复杂金融智能体系统的关键。

Skill、Agent 与 MCP 协同架构

7.7.1 三者的角色定位

用一个硬件店类比来理解三者的关系:

组件 类比 核心功能
MCP 货架通道 提供工具连接层——访问外部数据源和 API
Skill 店员专业知识 提供流程知识层——教 Claude 如何使用工具完成任务
Agent 专业技术员 提供任务隔离层——独立执行上下文,专注特定领域

MCP 提供能力,Skill 提供智慧

MCP 连接 Claude 与第三方工具,Skill 教 Claude 如何善用这些工具。单独使用 MCP,Claude 知道可以调用什么;结合 Skill,Claude 知道应该如何调用、按什么流程组合调用。

7.7.2 协同工作机制

场景:投资组合分析

假设用户请求”分析我的投资组合”,三者协同工作如下:

  1. Skill 触发:Claude 识别请求匹配 portfolio-analyzer Skill,加载分析流程
  2. MCP 调用:Skill 指导 Claude 调用 MCP 工具获取实时股价
  3. Agent 委派(可选):对于并行计算任务,主会话可委派子智能体处理
用户请求

Skill 匹配 → 加载分析流程

MCP 调用 → 获取实时数据

Skill 指导 → 执行计算逻辑

生成报告

7.7.3 何时使用哪个组件

场景 推荐组件 原因
访问外部数据库 MCP 标准化的数据连接
封装分析流程 Skill 可复用的专业知识
并行执行任务 Agent 独立上下文,防止污染
简单快捷操作 Slash 命令 用户手动触发
自动质量检查 Hooks 事件驱动的自动化

组合使用示例

一个完整的金融分析系统可能这样组合:

  • MCP Server:连接 Yahoo Finance、AKShare 等数据源
  • Skill:封装技术分析流程、基本面分析流程
  • Agent:专门的”技术分析师”、“基本面分析师”子智能体
  • Hooks:在生成报告后自动保存到指定目录

7.7.4 渐进式披露与上下文管理

三者共同遵循渐进式披露原则,优化上下文使用:

层级 加载时机 内容
第一层 启动时 所有 Skill 的 name 和 description(约 100 tokens/skill)
第二层 匹配时 SKILL.md 主体内容(<5k tokens)
第三层 需要时 references/ 中的详细文档、脚本

MCP 工具列表也采用类似机制:启动时只加载工具名称和描述,实际调用时才传递完整参数。

提示教学提示

对于金融专业学生,可以这样理解三者关系:

  • MCP 像是你的彭博终端——提供数据访问能力
  • Skill 像是你的分析方法论——告诉你如何解读数据
  • Agent 像是你的研究助理——可以独立完成特定任务

7.7 金融工具扩展实践

本节将理论知识应用于实际金融场景,展示如何配置金融数据 MCP Server 并开发自定义工具。

金融智能体工具整合架构

7.7.1 MCP 配置与连接

配置金融数据 MCP Server

{
  "mcpServers": {
    "yfinance": {
      "command": "python",
      "args": ["/path/to/yfinance-mcp-server/server.py"]
    },
    "a-stock": {
      "command": "python",
      "args": ["/path/to/akshare-mcp-server/server.py"]
    }
  }
}

常用金融 MCP Server

服务器 数据源 功能 验证状态
yfinance-mcp Yahoo Finance 美股实时数据、历史数据、财务指标 需自行开发
alpha-vantage-mcp Alpha Vantage 技术指标、外汇、加密货币 需 API Key
akshare-mcp AKShare A 股数据、财务报表、新闻 案例 7B 提供
tushare-mcp Tushare A 股行情、指数、宏观数据 需 Token
注记说明

需自行开发的 MCP Server 需要额外配置或参照本章案例 7B 实现。案例 7B 提供了 akshare-mcp 的完整代码,可作为开发其他 MCP Server 的参考模板。

7.7.2 金融 MCP Server 开发

A 股数据服务器示例

# a_stock_server.py
from mcp.server.fastmcp import FastMCP
import akshare as ak

mcp = FastMCP("A-Stock-Server")

@mcp.tool()
async def get_stock_quote_cn(symbol: str) -> str:
    """获取 A 股实时行情

    Args:
        symbol: 股票代码,如 000001、600519
    """
    try:
        df = ak.stock_zh_a_spot_em()
        stock = df[df['代码'] == symbol]

        if stock.empty:
            return f"未找到股票 {symbol}"

        row = stock.iloc[0]
        return f"""
**{row['名称']}{symbol})实时行情**

- 最新价:{row['最新价']:.2f}
- 涨跌幅:{row['涨跌幅']:.2f}%
- 成交量:{row['成交量']/10000:.2f} 万手
- 成交额:{row['成交额']/100000000:.2f} 亿元
- 市盈率:{row['市盈率-动态']:.2f}
"""
    except Exception as e:
        return f"获取数据失败:{str(e)}"

@mcp.tool()
async def get_kline_data(symbol: str, start_date: str,
                         end_date: str, period: str = "daily") -> str:
    """获取 A 股历史 K 线数据

    Args:
        symbol: 股票代码
        start_date: 开始日期(YYYY-MM-DD)
        end_date: 结束日期(YYYY-MM-DD)
        period: 周期(daily/weekly/monthly)
    """
    try:
        df = ak.stock_zh_a_hist(
            symbol=symbol,
            period=period,
            start_date=start_date.replace("-", ""),
            end_date=end_date.replace("-", "")
        )

        if df.empty:
            return f"未找到 {symbol} 在指定时间段的数据"

        # 格式化输出最近 5 条
        result = f"**{symbol} K 线数据**\n\n"
        for _, row in df.tail(5).iterrows():
            result += f"{row['日期']}:开 {row['开盘']:.2f} "
            result += f"高 {row['最高']:.2f}{row['最低']:.2f} "
            result += f"收 {row['收盘']:.2f}\n"

        return result
    except Exception as e:
        return f"获取数据失败:{str(e)}"

if __name__ == "__main__":
    mcp.run(transport="stdio")

案例 7A:股票信息查询工具

本案例演示如何使用 Claude Code 和 MCP 工具进行股票数据查询和分析。

案例信息

要素 说明
演示模式 工具使用(Tool Use)
案例简述 使用 MCP 工具查询实时股价、历史数据和财务指标,体验工具调用与数据分析流程
经济学映射 信息获取——通过工具获取实时市场数据,降低信息不对称
应用衔接 第 11 章舆情分析、第 12 章交易信号分析均需实时数据查询

场景描述

你正在进行投资研究,需要快速获取苹果公司(AAPL)的实时行情、技术指标和基本面数据。

操作步骤

步骤 1:配置 MCP Server

首先,创建 yfinance MCP Server。新建 yfinance-server.py 文件:

# yfinance-server.py
from mcp.server.fastmcp import FastMCP
import yfinance as yf

mcp = FastMCP("YFinance-Server")

@mcp.tool()
async def get_stock_price(symbol: str) -> str:
    """获取美股实时价格

    Args:
        symbol: 股票代码,如 AAPL、TSLA、MSFT
    """
    try:
        ticker = yf.Ticker(symbol)
        info = ticker.info

        return f"""
**{info.get('shortName', symbol)}{symbol})股票信息**

- 当前价格:${info.get('currentPrice', 'N/A'):.2f}
- 今日涨跌:{info.get('regularMarketChangePercent', 0):.2f}%
- 成交量:{info.get('volume', 0):,}
- 市值:${info.get('marketCap', 0)/1e9:.2f} 十亿
- 市盈率:{info.get('trailingPE', 'N/A')}
"""
    except Exception as e:
        return f"获取数据失败:{str(e)}"

@mcp.tool()
async def get_historical_data(symbol: str, period: str = "3mo") -> str:
    """获取历史价格数据

    Args:
        symbol: 股票代码
        period: 时间周期(1mo/3mo/6mo/1y)
    """
    try:
        ticker = yf.Ticker(symbol)
        hist = ticker.history(period=period)

        result = f"**{symbol} 近期价格走势**\n\n"
        for date, row in hist.tail(5).iterrows():
            result += f"{date.strftime('%Y-%m-%d')}:收盘 ${row['Close']:.2f}\n"
        return result
    except Exception as e:
        return f"获取历史数据失败:{str(e)}"

if __name__ == "__main__":
    mcp.run(transport="stdio")

安装依赖并配置:

# 安装依赖
pip install "mcp[cli]" yfinance

# 测试服务器
npx @modelcontextprotocol/inspector python yfinance-server.py

在项目的 .mcp.json 中配置:

{
  "mcpServers": {
    "yfinance": {
      "command": "python",
      "args": ["/absolute/path/to/yfinance-server.py"]
    }
  }
}
提示教学提示

如果不想自己开发,也可以直接使用案例 7B 中的 A 股 MCP Server 进行测试,将美股代码改为 A 股代码即可。

步骤 2:基础查询

你:帮我查询苹果公司(AAPL)的当前股价

Claude:我将使用股票数据工具查询苹果公司的实时行情。

[调用 MCP 工具:get_stock_price(symbol="AAPL")]

**苹果公司(AAPL)股票信息**

- 当前价格:$178.50
- 今日涨跌:+$2.30(+1.31%)
- 成交量:65,432,100 股
- 市值:$2.83 万亿
- 市盈率:28.5

步骤 3:多维度分析

你:请提供完整的技术面和基本面分析

Claude:我将从多个维度分析苹果公司。

[调用工具:get_historical_data(symbol="AAPL", period="3mo")]
[调用工具:get_stock_metric(symbol="AAPL", metric="all")]

**技术面分析**

近 3 个月价格走势:
- 20 日均线:$175.20
- 价格相对均线:+1.88%(突破)
- RSI (14):58.5(中性区域)
- MACD:正值,趋势向上

技术信号:短期趋势积极,价格突破均线。

**基本面分析**

财务指标:
- 市盈率(P/E):28.5
- 市净率(P/B):45.2
- 净资产收益率(ROE):147%
- 毛利率:44.1%

基本面评价:盈利能力优秀,ROE 远超行业平均。

步骤 4:生成投资建议

你:基于分析,给出投资建议

Claude:综合技术面和基本面分析,我的建议如下:

**投资建议:买入**

理由:
1. 技术面显示短期向上动能,突破均线确认趋势
2. 基本面优秀,盈利能力和现金流稳定
3. 虽估值略高,但与增长潜力匹配

风险提示:
- 市盈率较高,市场情绪转弱时可能承压
- 建议设置止损位于 $172(跌破 50 日均线)

配置建议:
- 持仓比例:10-15%
- 可分批建仓

学习要点

  1. 工具自动选择:Claude 根据请求自动选择合适的工具
  2. 参数推断:Claude 从对话中推断所需参数
  3. 结果整合:多个工具调用的结果被整合成连贯分析
  4. 自然语言交互:无需编写代码即可完成复杂分析

案例 7B:自定义 MCP Server 开发

本案例演示如何开发自定义 MCP Server,将 A 股数据集成到 Claude Code。

案例信息

要素 说明
演示模式 MCP 协议开发
案例简述 开发自定义 A 股数据 MCP Server,实现实时行情、K 线数据和财务报表查询
经济学映射 能力扩展——通过标准化协议扩展智能体的数据访问能力
应用衔接 第 13 章研报生成系统将使用自定义 MCP Server 获取多源数据

场景描述

现有的 MCP Server 主要支持美股数据,你需要开发一个支持 A 股市场的数据服务器。

开发步骤

步骤 1:项目初始化

mkdir a-stock-mcp
cd a-stock-mcp
uv init
uv add "mcp[cli]" akshare pandas

步骤 2:实现 Server

# server.py
from mcp.server.fastmcp import FastMCP
import akshare as ak

mcp = FastMCP("A-Stock-Data-Server")

@mcp.tool()
async def get_stock_quote_cn(symbol: str) -> str:
    """获取 A 股实时行情

    Args:
        symbol: 股票代码,如 000001(平安银行)、600519(贵州茅台)
    """
    try:
        df = ak.stock_zh_a_spot_em()
        stock_data = df[df['代码'] == symbol]

        if stock_data.empty:
            return f"未找到股票代码 {symbol}"

        row = stock_data.iloc[0]
        return f"""
**{row['名称']}{symbol})实时行情**

- 最新价:{row['最新价']:.2f}
- 涨跌额:{row['涨跌额']:.2f}
- 涨跌幅:{row['涨跌幅']:.2f}%
- 成交量:{row['成交量']/10000:.2f} 万手
- 成交额:{row['成交额']/100000000:.2f} 亿元
- 换手率:{row['换手率']:.2f}%
- 市盈率:{row['市盈率-动态']:.2f}
- 总市值:{row['总市值']/100000000:.2f} 亿元
"""
    except Exception as e:
        return f"获取数据失败:{str(e)}"

@mcp.tool()
async def get_market_index(index_code: str) -> str:
    """获取 A 股市场指数

    Args:
        index_code: 指数代码
            - sh000001: 上证指数
            - sz399001: 深证成指
            - sz399006: 创业板指
    """
    try:
        index_map = {
            "sh000001": ("上证指数", "000001"),
            "sz399001": ("深证成指", "399001"),
            "sz399006": ("创业板指", "399006")
        }

        index_name, code = index_map[index_code]
        df = ak.stock_zh_index_spot_em()
        index_data = df[df['代码'] == code].iloc[0]

        return f"""
**{index_name}**

- 最新点位:{index_data['最新价']:.2f}
- 涨跌幅:{index_data['涨跌幅']:.2f}%
- 成交额:{index_data['成交额']/100000000:.2f} 亿元
"""
    except Exception as e:
        return f"获取指数数据失败:{str(e)}"

if __name__ == "__main__":
    mcp.run(transport="stdio")

步骤 3:测试 Server

# 使用 MCP Inspector 测试
npx @modelcontextprotocol/inspector python server.py

在 Inspector 界面中:

  1. 点击 Tools 标签
  2. 选择 get_stock_quote_cn
  3. 输入参数:{"symbol": "600519"}
  4. 点击 Call Tool
  5. 验证返回结果:若返回正确的股票行情数据(如贵州茅台的价格、涨跌幅等),则测试通过

步骤 4:集成到 Claude Code

{
  "mcpServers": {
    "a-stock": {
      "command": "python",
      "args": ["/absolute/path/to/server.py"]
    }
  }
}

步骤 5:使用测试

你:查询贵州茅台的实时行情

Claude:我将使用 A 股数据服务器查询。

[调用工具:get_stock_quote_cn(symbol="600519")]

**贵州茅台(600519)实时行情**

- 最新价:1680.50 元
- 涨跌幅:+0.91%
- 成交量:12.35 万手
- 成交额:20.78 亿元
- 市盈率:35.6
- 总市值:2.11 万亿元

开发要点

  1. 工具设计:每个工具职责单一,参数清晰
  2. 错误处理:捕获异常并返回友好的错误信息
  3. 数据格式化:返回结构清晰、易读的文本
  4. 文档完善:工具描述和参数说明要详尽
提示扩展建议

可以继续添加以下工具:

  • get_financial_statements:获取财务报表
  • calculate_technical_indicators:计算技术指标
  • get_industry_comparison:行业对比分析

本章小结

本章系统介绍了工具扩展的核心机制和 Claude Code 的完整工具扩展体系。

核心要点

  1. 工具扩展的本质:通过标准化的函数调用协议,让模型能够访问外部数据和执行实际操作,突破训练数据的限制。

  2. 工具扩展体系

    • MCP 协议:标准化的外部系统集成方案,提供工具连接层
    • Plugin 系统:模块化的能力扩展包,可跨项目共享和分发
    • Skill/Agent/MCP 协同:三者协作构建完整智能体能力
  3. 三者协同关系

    • MCP 提供工具访问能力(货架通道)
    • Skill 提供流程专业知识(店员经验)
    • Agent 提供任务隔离执行(专业技术员)
  4. 设计原则

    • 清晰的工具定义(详细描述、完整参数说明)
    • 完善的错误处理(重试、降级、友好提示)
    • 渐进式披露(按需加载,优化上下文)

实践建议

对于非编程背景的学生:

  • 理解工具扩展的作用和能力边界
  • 学会用清晰的自然语言描述需求
  • 让 Claude 自动选择合适的工具组合

对于有编程兴趣的学生:

  • 从安装和使用现成的 Plugin 开始
  • 尝试创建简单的 Skill 封装专业知识
  • 逐步学习开发自定义 MCP Server
提示教学建议

教师可根据学生背景调整实践深度:

  • 文科背景为主的班级:重点讲解工具扩展的概念和使用场景,案例以演示为主
  • 有编程基础的班级:可增加 MCP Server 开发和 Plugin 打包的实操练习
  • 混合背景班级:分组协作,让编程能力强的学生负责技术实现,其他学生负责需求设计和测试

与后续章节的联系

  • 第 8 章(RAG):MCP Server 可以作为 RAG 的数据源
  • 第 9 章(多智能体):工具可以在多个智能体之间共享,Agent 可调用共享的 MCP 工具
  • 第 11-13 章(应用篇):将综合运用本章介绍的工具扩展体系构建完整系统