[{"data":1,"prerenderedAt":6500},["ShallowReactive",2],{"search-docs":3,"doc-\u002Fai\u002Fmcp\u002Fclient":886},[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,159,162,165,169,172,175,178,182,186,190,194,198,202,206,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,269,273,277,281,285,288,291,294,298,301,304,307,310,313,316,319,322,325,329,332,336,340,344,348,352,356,359,362,365,368,371,374,377,380,383,386,389,393,396,399,402,405,408,411,414,417,420,424,428,432,435,438,442,446,450,454,458,462,466,470,474,477,480,483,487,491,494,497,500,504,507,511,515,518,521,524,527,530,533,536,539,542,545,548,551,554,557,560,563,566,569,572,575,579,583,587,591,595,599,603,606,610,614,617,620,623,626,629,633,637,640,643,646,649,652,655,658,661,664,667,670,673,676,679,682,685,688,691,694,697,700,703,706,709,712,716,720,724,728,732,736,740,744,748,752,756,760,764,768,772,775,779,783,787,790,793,796,799,802,805,808,811,814,818,822,825,829,832,835,838,841,844,848,851,854,858,862,865,869,873,876,879,882],{"path":5,"title":6,"description":7},"\u002Fabout\u002Fauthor","作者相关","只想纯粹的做一个程序员...",{"path":9,"title":10,"description":11},"\u002Fabout\u002Fjourney","心路历程","",{"path":13,"title":14,"description":15},"\u002Fai\u002Fagent\u002Fframeworks","Agent 框架","主流 Agent 框架：LangChain、LlamaIndex、AutoGen、CrewAI",{"path":17,"title":18,"description":19},"\u002Fai\u002Fagent\u002Fhooks","Agent Hooks 与自动化","Claude Agent 的 Hooks 生命周期、事件类型、典型自动化场景",{"path":21,"title":22,"description":23},"\u002Fai\u002Fagent\u002Fintroduction","AI Agent 概述","AI Agent 核心概念：感知、规划、执行、记忆",{"path":25,"title":26,"description":27},"\u002Fai\u002Fagent\u002Fpractice","Agent 实战","AI Agent 实战：构建自主任务执行系统",{"path":29,"title":30,"description":31},"\u002Fai\u002Fagent\u002Fsdk","Claude Agent SDK 开发","使用 Claude Agent SDK 构建自定义 AI Agent：架构、API、生命周期",{"path":33,"title":34,"description":35},"\u002Fai\u002Fagent\u002Fsubagents","Subagents 子代理","用 Subagents 分解复杂任务、并发执行、隔离上下文",{"path":37,"title":38,"description":39},"\u002Fai\u002Fagent\u002Ftool-use","工具调用","AI Agent 工具调用：Function Calling、Tool Use 原理与实践",{"path":41,"title":42,"description":43},"\u002Fai\u002Ffundamentals\u002Fdeep-learning","深度学习入门","深度学习基础知识：前向传播、反向传播、损失函数、优化器",{"path":45,"title":46,"description":47},"\u002Fai\u002Ffundamentals\u002Fml-basics","机器学习基础","机器学习核心概念：监督学习、无监督学习、强化学习",{"path":49,"title":50,"description":51},"\u002Fai\u002Ffundamentals\u002Fneural-networks","神经网络原理","神经网络架构：CNN、RNN、注意力机制",{"path":53,"title":54,"description":55},"\u002Fai\u002Fgetting-started","AI 学习路线","AI 技术学习路线图，从基础到实战的完整指南",{"path":57,"title":58,"description":59},"\u002Fai\u002Fllm\u002Ffine-tuning","模型微调","大模型微调技术：LoRA、QLoRA、全量微调、RLHF",{"path":61,"title":62,"description":63},"\u002Fai\u002Fllm\u002Fintroduction","大模型概述","大语言模型发展历程、核心能力与主流模型对比",{"path":65,"title":66,"description":67},"\u002Fai\u002Fllm\u002Flocal-deploy","本地部署","大模型本地部署：Ollama、vLLM、llama.cpp",{"path":69,"title":70,"description":71},"\u002Fai\u002Fllm\u002Ftransformer","Transformer 架构","Transformer 架构详解：自注意力机制、位置编码、多头注意力",{"path":73,"title":74,"description":75},"\u002Fai\u002Fmcp\u002Fclient","MCP Client 开发","MCP Client 开发指南：连接、调用、集成",{"path":77,"title":78,"description":79},"\u002Fai\u002Fmcp\u002Fdebugging","MCP 调试与排错","MCP Server 开发与集成过程中的常见问题、日志分析、诊断工具",{"path":81,"title":82,"description":83},"\u002Fai\u002Fmcp\u002Fintroduction","MCP 概述","Model Context Protocol 协议概述：架构、核心概念、应用场景",{"path":85,"title":86,"description":87},"\u002Fai\u002Fmcp\u002Fserver","MCP Server 开发","MCP Server 开发指南：资源、工具、提示词的实现",{"path":89,"title":90,"description":91},"\u002Fai\u002Fmcp\u002Ftools","MCP Tools 深入","深入理解 MCP Tools：与 Resources\u002FPrompts 的差异、Schema 设计、Annotations 与权限控制",{"path":93,"title":94,"description":95},"\u002Fai\u002Fprompt\u002Fadvanced","高级 Prompt 模式","高级 Prompt 设计模式：Tree-of-Thought、自我反思、多轮对话策略",{"path":97,"title":98,"description":99},"\u002Fai\u002Fprompt\u002Fbasics","Prompt 基础","Prompt Engineering 入门：基本概念、角色设定、输出格式控制",{"path":101,"title":102,"description":103},"\u002Fai\u002Fprompt\u002Ftechniques","提示词技巧","常用提示词技巧：Few-shot、Chain-of-Thought、ReAct",{"path":105,"title":106,"description":107},"\u002Fai\u002Frag\u002Fembedding","文本嵌入","文本嵌入模型：Embedding 原理、模型选择、相似度计算",{"path":109,"title":110,"description":111},"\u002Fai\u002Frag\u002Fintroduction","RAG 概述","检索增强生成（RAG）架构原理、优势与应用场景",{"path":113,"title":114,"description":115},"\u002Fai\u002Frag\u002Fpractice","RAG 实战","RAG 应用实战：文档问答系统、知识库搭建",{"path":117,"title":118,"description":119},"\u002Fai\u002Frag\u002Fvector-database","向量数据库","主流向量数据库对比：Milvus、Pinecone、Chroma、Weaviate",{"path":121,"title":122,"description":123},"\u002Fai\u002Fskills\u002Fbest-practices","Skill 最佳实践","编写高质量 Skill 的设计原则、常见陷阱与优化技巧",{"path":125,"title":126,"description":127},"\u002Fai\u002Fskills\u002Fcreating","创建自定义 Skill","从零编写一个可被 Agent 自动发现和调用的 Skill",{"path":129,"title":130,"description":131},"\u002Fai\u002Fskills\u002Fintroduction","Agent Skills 概述","Claude Agent Skills 概念、工作原理、与 Tools\u002FMCP 的区别",{"path":133,"title":134,"description":135},"\u002Fgolang\u002Fadvanced\u002Fconcurrency","Go - 并发深入","深入理解 Go 并发编程的核心机制。",{"path":137,"title":138,"description":139},"\u002Fgolang\u002Fadvanced\u002Fgc","Go - 垃圾回收","理解 Go 的垃圾回收机制，掌握 GC 调优方法。",{"path":141,"title":142,"description":143},"\u002Fgolang\u002Fadvanced\u002Fgmp","Go - GMP 调度模型","GMP 是 Go 运行时调度器的核心模型，理解它对于编写高性能 Go 程序至关重要。",{"path":145,"title":146,"description":147},"\u002Fgolang\u002Fadvanced\u002Fgo-concurrency","Go - 并发编程","Go 的并发是其核心特性之一，通过 Goroutine 和 Channel 实现。",{"path":149,"title":150,"description":151},"\u002Fgolang\u002Fadvanced\u002Fmemory","Go - 内存模型","理解 Go 的内存分配机制和内存模型。",{"path":153,"title":154,"description":155},"\u002Fgolang\u002Fadvanced\u002Fprofiling","Go - 性能分析","掌握 Go 的性能分析工具：pprof、trace、benchmark。",{"path":157,"title":158,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-basic","Go - 基础语法",{"path":160,"title":161,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-composite","Go - 复合类型",{"path":163,"title":164,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-control","Go - 流程控制",{"path":166,"title":167,"description":168},"\u002Fgolang\u002Fcore\u002Fgo-error","Go - 错误处理","Go 使用显式的错误返回值来处理错误，而不是异常机制。",{"path":170,"title":171,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-function","Go - 函数",{"path":173,"title":174,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-install","Go - 环境搭建",{"path":176,"title":177,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-interface","Go - 接口",{"path":179,"title":180,"description":181},"\u002Fgolang\u002Fcore\u002Fgo-module","Go - 包管理","Go Modules 是 Go 1.11 引入的官方依赖管理方案，Go 1.16 后成为默认模式。",{"path":183,"title":184,"description":185},"\u002Fgolang\u002Fdistributed\u002Fgrpc","Go - gRPC","gRPC 是 Google 开发的高性能 RPC 框架，使用 Protocol Buffers 作为序列化协议。",{"path":187,"title":188,"description":189},"\u002Fgolang\u002Fdistributed\u002Fmicroservice","Go - 微服务","微服务架构的核心组件：服务发现、负载均衡、熔断降级。",{"path":191,"title":192,"description":193},"\u002Fgolang\u002Fdistributed\u002Fmq","Go - 消息队列","使用 Go 操作 Kafka 和 RabbitMQ。",{"path":195,"title":196,"description":197},"\u002Fgolang\u002Fdistributed\u002Fredis","Go - Redis","使用 go-redis 操作 Redis，实现缓存、分布式锁等功能。",{"path":199,"title":200,"description":201},"\u002Fgolang\u002Fengineering\u002Fconfig","Go - 配置管理","使用 viper 进行配置管理，支持多种配置格式和配置中心。",{"path":203,"title":204,"description":205},"\u002Fgolang\u002Fengineering\u002Fdocker","Go - Docker 部署","使用 Docker 容器化部署 Go 应用。",{"path":207,"title":208,"description":209},"\u002Fgolang\u002Fengineering\u002Fkubernetes","Go - Kubernetes 部署","在 Kubernetes 上部署和管理 Go 应用。",{"path":211,"title":212,"description":213},"\u002Fgolang\u002Fengineering\u002Flogging","Go - 日志系统","使用 zap 和 logrus 构建高性能结构化日志系统。",{"path":215,"title":216,"description":217},"\u002Fgolang\u002Fengineering\u002Ftesting","Go - 单元测试","Go 内置了强大的测试框架，掌握测试是编写高质量代码的基础。",{"path":219,"title":220,"description":221},"\u002Fgolang\u002Fstdlib\u002Fbufio","bufio","在 Go 语言中，bufio 包提供了带缓冲的 I\u002FO 操作，能够提高读写性能。以下是一些常用的 bufio 包 API 及其详细说明：",{"path":223,"title":224,"description":225},"\u002Fgolang\u002Fstdlib\u002Fcontainer","container","在Go语言标准库中，container 包提供了几种常用的数据结构实现，这些数据结构对于高效地管理和操作数据非常有用。以下是 container 包中主要的数据结构：",{"path":227,"title":228,"description":229},"\u002Fgolang\u002Fstdlib\u002Fcrypto","crypto","在 Go 语言中，crypto 包提供了一组用于加密和解密的功能。以下是一些常用的 crypto 包及其子包的 API 及其详细说明：",{"path":231,"title":232,"description":233},"\u002Fgolang\u002Fstdlib\u002Fencoding-csv","encoding\u002Fcsv","在 Go 语言中，encoding\u002Fcsv 包提供了对 CSV（逗号分隔值）文件进行读写的功能。以下是一些常用的 encoding\u002Fcsv 包的 API 及其详细说明：",{"path":235,"title":236,"description":237},"\u002Fgolang\u002Fstdlib\u002Fencoding-json","encoding\u002Fjson","在 Go 语言中，encoding\u002Fjson 包提供了对 JSON 数据进行编码和解码的功能。以下是一些常用的 encoding\u002Fjson 包的 API 及其详细说明：",{"path":239,"title":240,"description":241},"\u002Fgolang\u002Fstdlib\u002Fencoding-xml","encoding\u002Fxml","在 Go 语言中，encoding\u002Fxml 包提供了对 XML 数据进行编码和解码的功能。以下是一些常用的 encoding\u002Fxml 包的 API 及其详细说明：",{"path":243,"title":244,"description":245},"\u002Fgolang\u002Fstdlib\u002Fflag","flag","在Go语言中，flag 包是用于处理命令行参数的标准库，它提供了一种简单而直接的方式来解析和使用命令行参数。下面是关于 flag 包的一些基本介绍和常用功能：",{"path":247,"title":248,"description":249},"\u002Fgolang\u002Fstdlib\u002Ffmt","fmt","在 Go 语言的标准库中，fmt 包是非常重要的，它提供了处理格式化输入和输出的基本工具。以下是一些 fmt 包内常用的API：",{"path":251,"title":252,"description":253},"\u002Fgolang\u002Fstdlib\u002Fhttp","net\u002Fhttp","在 Go 语言中，net\u002Fhttp 包提供了用于构建 HTTP 客户端和服务器的强大工具。以下是一些常用的 net\u002Fhttp 包的 API 及其详细说明：",{"path":255,"title":256,"description":257},"\u002Fgolang\u002Fstdlib\u002Fio","io","在 Go 语言中，io 包提供了基本的输入输出功能。以下是一些常用的 io 包的 API 及其详细说明：",{"path":259,"title":260,"description":261},"\u002Fgolang\u002Fstdlib\u002Flog","log","在 Go 语言中，log 包提供了简单的日志记录功能。以下是一些常用的 log 包的 API 及其详细说明：",{"path":263,"title":264,"description":265},"\u002Fgolang\u002Fstdlib\u002Fmath","math","在 Go 语言中，math 包提供了基本的数学函数和常量。以下是一些常用的 math 包的 API 及其详细说明：",{"path":267,"title":268,"description":11},"\u002Fgolang\u002Fstdlib\u002Fnet","net",{"path":270,"title":271,"description":272},"\u002Fgolang\u002Fstdlib\u002Fos","os","在Go语言中，os 包是一个非常重要且常用的标准库，它提供了与操作系统交互的功能，包括文件操作、环境变量管理、进程管理等。下面是一些 os 包中常用的功能和API：",{"path":274,"title":275,"description":276},"\u002Fgolang\u002Fstdlib\u002Fsort","order","在 Go 语言中，sort 包提供了对切片和用户定义的集合进行排序的函数。它实现了常见的排序算法，如快速排序（Quicksort）和堆排序（Heapsort），并且为自定义集合提供了接口，使得用户可以根据特定的需求进行排序。",{"path":278,"title":279,"description":280},"\u002Fgolang\u002Fstdlib\u002Fstrconv","strconv","在 Go 语言中，strconv 包提供了字符串和基本数据类型之间的转换函数，例如将整数转换为字符串、字符串转换为整数，以及其他类型之间的转换。这些功能非常有用，特别是在处理用户输入或从外部数据源读取数据时。",{"path":282,"title":283,"description":284},"\u002Fgolang\u002Fstdlib\u002Ftime","time","在 Go 语言中，time 包提供了处理时间和日期的功能。以下是一些常用的 time 包的 API 及其详细说明：",{"path":286,"title":287,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Ferror","Gin - 错误处理",{"path":289,"title":290,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Ffile","Gin - 文件处理",{"path":292,"title":293,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fmiddleware","Gin - 中间件",{"path":295,"title":296,"description":297},"\u002Fgolang\u002Fweb\u002Fgin\u002Fquickstart","Gin - 快速开始","Gin 是目前最流行的 Go Web 框架，以高性能和简洁 API 著称。",{"path":299,"title":300,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Frequest","Gin - 请求处理",{"path":302,"title":303,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fresponse","Gin - 响应处理",{"path":305,"title":306,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Frouter","Gin - 路由",{"path":308,"title":309,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fvalidation","Gin - 参数校验",{"path":311,"title":312,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fassociation","GORM - 关联关系",{"path":314,"title":315,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fcrud","GORM - CRUD 操作",{"path":317,"title":318,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fmodel","GORM - 模型定义",{"path":320,"title":321,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fperformance","GORM - 日志与性能",{"path":323,"title":324,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fquery","GORM - 高级查询",{"path":326,"title":327,"description":328},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fquickstart","GORM - 快速开始","GORM 是 Go 语言最流行的 ORM 库，功能强大，使用简单。",{"path":330,"title":331,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Ftransaction","GORM - 事务与 Hook",{"path":333,"title":334,"description":335},"\u002Finterview\u002Fbasic","计算机基础面经","本章节汇总了面试中常见的通用技术概念，不局限于特定语言或数据库，是考察技术内功的关键考点。",{"path":337,"title":338,"description":339},"\u002Finterview\u002Fgolang","Golang 面试题","Go 语言面试高频考点，覆盖基础语法、数据结构、并发编程、内存管理、GC、调度器等核心知识。",{"path":341,"title":342,"description":343},"\u002Finterview\u002Fk8s","Kubernetes 面试题","Kubernetes（K8s）面试高频考点，覆盖架构原理、核心资源、网络存储、调度策略、运维监控等核心知识。",{"path":345,"title":346,"description":347},"\u002Finterview\u002Fmysql","MySQL 面试题","MySQL 数据库面试高频考点，覆盖索引、事务、锁、优化、主从复制等核心知识。",{"path":349,"title":350,"description":351},"\u002Finterview\u002Fredis","Redis 面试题","Redis 面试高频考点，覆盖数据结构、持久化、集群、缓存一致性、性能优化等核心知识。",{"path":353,"title":354,"description":355},"\u002Finterview\u002Frocketmq","RocketMQ 面试题","RocketMQ 面试高频考点，覆盖消息模型、可靠性、顺序消息、事务消息、存储与高可用等核心知识。",{"path":357,"title":358,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-arraylist","List - ArrayList 源码解析",{"path":360,"title":361,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-linkedlist","List - LinkedList 源码解析",{"path":363,"title":364,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-stack","List - Satck源码解析",{"path":366,"title":367,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-vectore","List - Vector 源码解析",{"path":369,"title":370,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-hashmap","Map - HashMap 源码解析",{"path":372,"title":373,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-linkedhashmap","Map - LinkedHashMap 源码解析",{"path":375,"title":376,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-treemap","Map - TreeMap 源码解析",{"path":378,"title":379,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fqueue-deque","Queue - Deque 接口解析",{"path":381,"title":382,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fqueue-queue","Queue - Queue 接口解析",{"path":384,"title":385,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-hashset","Set - HashSet源码解析",{"path":387,"title":388,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-linkedhashset","Set - LinkedHashSet 源码解析",{"path":390,"title":391,"description":392},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-treeset","Set - TreeSet源码解析","TreeSet 是一个 Set 集合接口的实现类，与 HashSet 类似，其底层也是通过维护了一个 TreeMap 对象来封装了一些实现方法，故本篇不再对 TreeSet 的底层原理进行详细说明，仅对常用 API 做简单介绍，如需了解 TreeMap 的底层实现原理，请移步 Map - HashMap 源码解析",{"path":394,"title":395,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fannotation","Java核心 - 注解",{"path":397,"title":398,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fbasic-grammar","Java核心 - 基础语法",{"path":400,"title":401,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fclass-and-object","Java核心 - 面向对象",{"path":403,"title":404,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fcommon-classes","Java核心 - 常用类",{"path":406,"title":407,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fexception","Java核心 - 异常处理",{"path":409,"title":410,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fgenerics","Java核心 - 泛型",{"path":412,"title":413,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fjdk-env-path","Java核心 - 环境搭建",{"path":415,"title":416,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Freflection","Java核心 - 反射",{"path":418,"title":419,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fstring","Java核心 - String 字符串",{"path":421,"title":422,"description":423},"\u002Fother\u002Fjava\u002Fio\u002Fbuffer-stream","Java IO - 缓冲流","缓冲流是对基本流的包装，通过内置缓冲区减少系统调用次数，大幅提升读写效率。",{"path":425,"title":426,"description":427},"\u002Fother\u002Fjava\u002Fio\u002Fbyte-stream","Java IO - 字节流","字节流是 Java IO 中最基本的流类型，以字节（byte）为单位进行数据读写，可以处理任意类型的文件。",{"path":429,"title":430,"description":431},"\u002Fother\u002Fjava\u002Fio\u002Fchar-stream","Java IO - 字符流","字符流以字符为单位进行读写，专门用于处理文本文件。相比字节流，字符流能够正确处理字符编码，避免中文乱码问题。",{"path":433,"title":434,"description":11},"\u002Fother\u002Fjava\u002Fio\u002Ffile","Java IO - File 类",{"path":436,"title":437,"description":11},"\u002Fother\u002Fjava\u002Fio\u002Fio-stream-system","Java IO - IO流概述",{"path":439,"title":440,"description":441},"\u002Fother\u002Fjava\u002Fio\u002Fnio","Java IO - NIO","NIO（New IO）是 JDK 1.4 引入的新 IO 模型，提供了更高效的 IO 操作方式，支持非阻塞 IO 和多路复用。",{"path":443,"title":444,"description":445},"\u002Fother\u002Fjava\u002Fjvm\u002Fclass-loading","类加载机制","类加载机制是 JVM 将 .class 文件加载到内存，并对数据进行校验、转换解析和初始化，最终形成可被 JVM 直接使用的 Java 类型的过程。",{"path":447,"title":448,"description":449},"\u002Fother\u002Fjava\u002Fjvm\u002Fgarbage-collection","垃圾回收","垃圾回收（Garbage Collection，GC）是 JVM 自动管理内存的机制，负责回收不再使用的对象所占用的内存。",{"path":451,"title":452,"description":453},"\u002Fother\u002Fjava\u002Fjvm\u002Fjvm-memory","JVM 内存结构","JVM 在执行 Java 程序时，会把它管理的内存划分为若干个不同的数据区域。这些区域有各自的用途、创建和销毁时间。",{"path":455,"title":456,"description":457},"\u002Fother\u002Fjava\u002Fjvm\u002Fjvm-tuning","JVM 调优","JVM 调优是优化 Java 应用性能的重要手段，主要包括参数配置、性能监控和问题排查。",{"path":459,"title":460,"description":461},"\u002Fother\u002Fjava\u002Fthread\u002Fatomic","原子类","Java 原子类（Atomic Classes）提供了一种无锁的线程安全方式，基于 CAS（Compare-And-Swap）操作实现。",{"path":463,"title":464,"description":465},"\u002Fother\u002Fjava\u002Fthread\u002Fcompletable-future","CompletableFuture","CompletableFuture 是 JDK 8 引入的异步编程工具，实现了 Future 和 CompletionStage 接口，支持函数式编程和链式调用。",{"path":467,"title":468,"description":469},"\u002Fother\u002Fjava\u002Fthread\u002Fconcurrent-collections","并发集合","Java 并发包提供了多种线程安全的集合类，用于替代传统的同步集合（如 Collections.synchronizedList）。",{"path":471,"title":472,"description":473},"\u002Fother\u002Fjava\u002Fthread\u002Fconcurrent-utils","并发工具类","Java 并发包提供了多种实用的并发工具类，用于控制线程之间的协调与同步。",{"path":475,"title":476,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fsynchronized-lock","同步机制",{"path":478,"title":479,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fthread-basic","线程基础",{"path":481,"title":482,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fthread-pool","线程池",{"path":484,"title":485,"description":486},"\u002Fother\u002Fspring-series\u002Fspring\u002Fannotations-beans","Spring - 基于注解管理Bean","从 Java 5 开始，Java 增加了对注解（Annotation）的支持，它是代码中的一种特殊标记，可以在编译、类加载和运行时被读取，执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下，在源代码中嵌入补充信息。",{"path":488,"title":489,"description":490},"\u002Fother\u002Fspring-series\u002Fspring\u002Fimplement-ioc","Spring - 原理手写IoC","Spring 框架的 IOC 是基于 Java 反射机制实现的，在学习手写 IoC 之前，你需要具备一定的 Java 反射相关的知识，参考本站内的 Java 教程。",{"path":492,"title":493,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fintroduction-case","Spring - 入门案例",{"path":495,"title":496,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-aop","Spring - 面向切面AOP",{"path":498,"title":499,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-aot","Spring - AOT提前编译",{"path":501,"title":502,"description":503},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-data-validation","Spring - 数据校验","在开发中，我们经常遇到参数校验的需求，比如用户注册的时候，要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。如果使用普通方式，我们会把校验的代码和真正的业务处理逻辑耦合在一起，而且如果未来要新增一种校验逻辑也需要在修改多个地方。而spring validation允许通过注解的方式来定义对象校验规则，把校验和业务逻辑分离开，让代码编写更加方便。Spring Validation其实就是对Hibernate Validator进一步的封装，方便在Spring中使用。",{"path":505,"title":506,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-i18n","Spring - 国际化i18n",{"path":508,"title":509,"description":510},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-ioc","Spring - IOC容器","IoC 是 Inversion of Control 的简写，译为“控制反转”，它不是一门技术，而是一种设计思想，是一个重要的面向对象编程法则，能够指导我们如何设计出松耦合、更优良的程序。",{"path":512,"title":513,"description":514},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-junit","Spring - 单元测试JUnit","在之前的测试方法中，几乎都能看到以下的两行代码：",{"path":516,"title":517,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-resources","Spring - 资源操作",{"path":519,"title":520,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-summarize","Spring - Spring概述",{"path":522,"title":523,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-transaction","Spring - 事务",{"path":525,"title":526,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fxml-beans","Spring - 基于XML管理Bean",{"path":528,"title":529,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-config","SpringBoot - 配置详解",{"path":531,"title":532,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-data","SpringBoot - 数据访问",{"path":534,"title":535,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-quickstart","SpringBoot - 快速入门",{"path":537,"title":538,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-web","SpringBoot - Web 开发",{"path":540,"title":541,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-config","SpringCloud - 配置中心",{"path":543,"title":544,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-discovery","SpringCloud - 服务注册与发现",{"path":546,"title":547,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-feign","SpringCloud - 服务调用",{"path":549,"title":550,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-gateway","SpringCloud - 服务网关",{"path":552,"title":553,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-introduction","SpringCloud - 微服务概述",{"path":555,"title":556,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-sentinel","SpringCloud - 服务保护",{"path":558,"title":559,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-databind","SpringMVC - 数据绑定与转换",{"path":561,"title":562,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-exception","SpringMVC - 异常处理",{"path":564,"title":565,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-interceptor","SpringMVC - 拦截器",{"path":567,"title":568,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-introduction","SpringMVC - 简介与环境搭建",{"path":570,"title":571,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-request","SpringMVC - 请求处理",{"path":573,"title":574,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-response","SpringMVC - 响应处理",{"path":576,"title":577,"description":578},"\u002Fproject\u002Frocket-leaf\u002Farchitecture","项目架构","Rocket-Leaf 的目录结构、模块划分、数据流向，以及各层之间的依赖关系。",{"path":580,"title":581,"description":582},"\u002Fproject\u002Frocket-leaf\u002Fbackend-layers","后端分层设计","Rocket-Leaf 的 model \u002F rocketmq \u002F service 三层结构，以及服务之间的依赖关系与设计取舍。",{"path":584,"title":585,"description":586},"\u002Fproject\u002Frocket-leaf\u002Fclient-manager","RocketMQ 客户端管理器","AdminClientManager 的多客户端池、默认连接懒加载、自动重连重试的设计与实现。",{"path":588,"title":589,"description":590},"\u002Fproject\u002Frocket-leaf\u002Fencryption","连接信息加密存储","AES-256-GCM + SHA-256 字段级派生密钥的实现，以及如何在不破坏兼容性的前提下为历史明文数据做透明迁移。",{"path":592,"title":593,"description":594},"\u002Fproject\u002Frocket-leaf\u002Ffrontend","前端结构与类型绑定","React + Vite 目录组织、自动生成的 Wails 绑定、api 薄封装与自定义 hooks 的职责划分。",{"path":596,"title":597,"description":598},"\u002Fproject\u002Frocket-leaf","项目简介","Rocket-Leaf 是一款基于 Wails v3 构建的跨平台 RocketMQ 桌面管理客户端，Go 后端 + React 前端。本文档系列拆解它的架构与关键实现。",{"path":600,"title":601,"description":602},"\u002Fproject\u002Frocket-leaf\u002Fwails-v3","Wails v3 入门","Wails v3 的核心概念、Service 绑定机制，以及 Rocket-Leaf 是如何用它把 Go 后端和 React 前端打通的。",{"path":604,"title":605,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-basic","Docker - 入门基础",{"path":607,"title":608,"description":609},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-compose","Docker - Compose","在部署应用时，常常使用到不止一个容器，那么在部署容器的时候就需要一个一个进行部署，这样的部署过程也相对来说比较繁琐复杂，也容易出问题，那么有没有一种更为简单的方法呢？",{"path":611,"title":612,"description":613},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-container-connection","Docker - 容器互联","在上一个章节中我们学习了 Docker 容器的端口映射，可以将 Docker 容器和本地以及网络中的端口进行连接起来。",{"path":615,"title":616,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-dockerfile","Docker - Dockerfile",{"path":618,"title":619,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-helloworld","Docker - HelloWorld",{"path":621,"title":622,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-install","Docker - 安装",{"path":624,"title":625,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-introduce","Docker - 简介",{"path":627,"title":628,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-object","Docker - 镜像、容器、仓库",{"path":630,"title":631,"description":632},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-warehouse","Docker - 仓库管理","仓库是集中存放资源的地方，代码仓库是存放代码的，那么Docker 中的仓库就是存放 Docker 镜像的。",{"path":634,"title":635,"description":636},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-web-containers","Docker - WEB应用实例","在之前的章节中，仅对普通容器进行了演示，但在实际中常常使用到 Docker 容器中的 WEB 应用程序。",{"path":638,"title":639,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-config","Kubernetes - ConfigMap 与 Secret",{"path":641,"title":642,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-helm","Kubernetes - Helm 包管理",{"path":644,"title":645,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-install","Kubernetes - 集群安装",{"path":647,"title":648,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-introduction","Kubernetes - 简介与架构",{"path":650,"title":651,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-kubectl","Kubernetes - kubectl 命令行工具",{"path":653,"title":654,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-monitoring","Kubernetes - 监控与日志",{"path":656,"title":657,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-network-security","Kubernetes - 网络与安全",{"path":659,"title":660,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-service","Kubernetes - Service 与 Ingress",{"path":662,"title":663,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-storage","Kubernetes - 持久化存储",{"path":665,"title":666,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-workload","Kubernetes - 工作负载资源",{"path":668,"title":669,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-bash","Linux - Bash 基础语法",{"path":671,"title":672,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-file-directory","Linux - 文件与目录操作",{"path":674,"title":675,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-network","Linux - 网络配置",{"path":677,"title":678,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-package","Linux - 软件包管理",{"path":680,"title":681,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-process","Linux - 进程管理",{"path":683,"title":684,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-scripts","Linux - 常用脚本示例",{"path":686,"title":687,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-service","Linux - 服务管理",{"path":689,"title":690,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-user-permission","Linux - 用户与权限管理",{"path":692,"title":693,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-https","Nginx - HTTPS 配置",{"path":695,"title":696,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-install","Nginx - 安装与配置",{"path":698,"title":699,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-loadbalance","Nginx - 负载均衡",{"path":701,"title":702,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-optimization","Nginx - 性能优化",{"path":704,"title":705,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-proxy","Nginx - 反向代理",{"path":707,"title":708,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-static","Nginx - 静态资源服务",{"path":710,"title":711,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-vhost","Nginx - 虚拟主机配置",{"path":713,"title":714,"description":715},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-architecture","MySQL 高可用架构","主从复制、读写分离、分库分表。",{"path":717,"title":718,"description":719},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-index","MySQL 索引","索引是帮助 MySQL 高效获取数据的有序数据结构。",{"path":721,"title":722,"description":723},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-lock","MySQL 锁","锁用于解决并发访问时的数据一致性问题。",{"path":725,"title":726,"description":727},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-optimize","MySQL 性能优化","SQL 优化是后端开发必备技能。",{"path":729,"title":730,"description":731},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-transaction","MySQL 事务","事务是一组不可分割的操作，要么全部成功，要么全部失败。",{"path":733,"title":734,"description":735},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fsql-advanced","SQL 进阶","多表查询、子查询、函数、视图、存储过程。",{"path":737,"title":738,"description":739},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fsql-basic","SQL 基础","SQL（Structured Query Language）是操作关系型数据库的标准语言。",{"path":741,"title":742,"description":743},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-advanced","Redis 进阶功能","事务、发布订阅、Lua 脚本、Pipeline。",{"path":745,"title":746,"description":747},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-basic","Redis 基础","Redis 安装配置与基本命令。",{"path":749,"title":750,"description":751},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-cluster","Redis 高可用","主从复制、哨兵、Cluster 集群。",{"path":753,"title":754,"description":755},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-datatype","Redis 数据类型","Redis 5 种基本数据类型 + 4 种特殊类型。",{"path":757,"title":758,"description":759},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-optimize","Redis 性能优化","内存优化、缓存问题、最佳实践。",{"path":761,"title":762,"description":763},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-persistence","Redis 持久化","Redis 提供 RDB 和 AOF 两种持久化方式。",{"path":765,"title":766,"description":767},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-principle","Redis 底层原理","数据结构、线程模型、网络模型。",{"path":769,"title":770,"description":771},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fbehaiver-patterns\u002Fobserver-pattern","观察者模式","观察者模式属于行为型模式，定义了对象之间的一对多的依赖关系，在这种模式中，当一个对象的状态发生变化时，所有依赖于它的对象都会得到通知，并且执行相关操作。观察者模式又被成为“发布—订阅模式”，即发布者发生改变后，会通知所有订阅者。",{"path":773,"title":774,"description":11},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fcreate-patterns\u002Ffactory-pattern","工厂模式",{"path":776,"title":777,"description":778},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fcreate-patterns\u002Fsingleton-pattern","单例模式","单例模式是最常用的设计模式之一，他可以保证在整个应用中，某个类只存在一个实例化对象，即全局使用到该类的只有一个对象，这种模式在需要限制某些类的实例数量时非常有用，通常全局只需要一个该对象即可，如一些配置文件映射对象、数据库连接对象等。",{"path":780,"title":781,"description":782},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fstructural-patterns\u002Fadapter-pattern","适配器模式","适配器模式是一种结构型模式，可以将一个类的接口转换成客户端所期望的另一种接口，适配器模式可以帮助开发人员在不修改现有代码的情况下，将不兼容的类组合在一起。",{"path":784,"title":785,"description":786},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-basic-operations","Git 创建版本库","在 Git 上创建版本库有两种方式，一种是直接拷贝远程 Git 仓库到本地，另外一种是我们自己创建本地的版本库。",{"path":788,"title":789,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-branch-manage","Git 分支管理",{"path":791,"title":792,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-content-operations","Git 仓库内容操作",{"path":794,"title":795,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-introduce-install","Git 介绍和安装",{"path":797,"title":798,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-remote-manage","Git 远程管理",{"path":800,"title":801,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-workspace-index-repo","Git 工作原理",{"path":803,"title":804,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fhomebrew","HomeBrew 教程",{"path":806,"title":807,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fidea\u002Fshortcuts","快捷键",{"path":809,"title":810,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fmaven\u002Fintroduce-install-config","Maven - 介绍、安装、配置",{"path":812,"title":813,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fbasic-knowledge","2. 基础知识",{"path":815,"title":816,"description":817},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcomponent-communication","9. 组件通信","在前面的章节内，介绍了 Vue 中最核心的内容——组件的介绍和使用，和 Java 等编程语言相反，组件并不近似于这些变成语言中的类，类可以通过类或者其实例化的对象来相互交互，但 Vue 组件之间的作用域是相互独立的，这就意味着不同组件之间的数据无法相互引用。",{"path":819,"title":820,"description":821},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcomputed","4. 计算属性","虽然直接在模板中使用表达式方便，但是如果在模板中添加很多逻辑，会让模板变的臃肿且难维护，耦合度较高。有没有一种简单的方式来实现呢？答案是有的。",{"path":823,"title":824,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcreate-vue-project","1. 环境搭建及安装",{"path":826,"title":827,"description":828},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Flife-cycle","6. 生命周期","生命周期是指组件从创建、挂载、更新到销毁的整个过程中所经历的一系列阶段。在 Vue 中，每个组件都有自己的生命周期，可以通过生命周期钩子函数来监听和处理组件在不同阶段的行为和状态。",{"path":830,"title":831,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fother-api","10. 其他 API",{"path":833,"title":834,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fpinia","8. Pinia",{"path":836,"title":837,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Frouter","7. 路由",{"path":839,"title":840,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Ftemplate-grammar","3. 指令及模板语法",{"path":842,"title":843,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fvue3-new-component","11. Vue3 新组件",{"path":845,"title":846,"description":847},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fwatch","5. 监视","Watch 是 Vue 提供的一个用于监视响应式数据变化并执行相应操作的 API，能够对响应式数据的变化做出一些操作的功能。Vue3 中的 Watch 支持多种用法，包括监视响应式对象、ref 对象、数组、函数等。",{"path":849,"title":850,"description":11},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-introduction","Kafka 简介与安装",{"path":852,"title":853,"description":11},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-producer-consumer","Kafka 生产者与消费者",{"path":855,"title":856,"description":857},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-springboot","Spring Boot 整合 Kafka","Spring Kafka 提供了对 Apache Kafka 的便捷集成。",{"path":859,"title":860,"description":861},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-exchange","RabbitMQ Exchange 详解","Exchange（交换机）是 RabbitMQ 的核心组件，负责接收生产者发送的消息，并根据规则将消息路由到一个或多个队列。",{"path":863,"title":864,"description":11},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-introduction","RabbitMQ 简介与安装",{"path":866,"title":867,"description":868},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-reliability","RabbitMQ 消息可靠性","消息可靠性是消息队列的核心要求，RabbitMQ 提供了多种机制来保证消息不丢失。",{"path":870,"title":871,"description":872},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-springboot","Spring Boot 整合 RabbitMQ","Spring AMQP 提供了对 RabbitMQ 的便捷集成，大大简化了开发工作。",{"path":874,"title":875,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-client","RocketMQ 客户端使用",{"path":877,"title":878,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-concepts","RocketMQ 核心概念",{"path":880,"title":881,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-installation","RocketMQ 安装部署",{"path":883,"title":884,"description":885},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-message-type","RocketMQ 消息类型","RocketMQ 支持多种消息类型，满足不同业务场景需求。",{"id":887,"title":74,"body":888,"description":75,"extension":6495,"meta":6496,"navigation":954,"path":73,"seo":6497,"stem":6498,"__hash__":6499},"docs\u002Fai\u002Fmcp\u002Fclient.md",{"type":889,"value":890,"toc":6458},"minimark",[891,895,899,903,908,1140,1144,1148,1239,1243,1402,1406,1409,1412,1553,1556,1670,1673,1775,1778,1781,1950,1954,2092,2095,2231,2234,2381,2385,2388,3649,3653,3656,3659,3663,3754,3757,3844,3847,4075,4079,4082,4085,4088,4269,4272,4431,4434,4824,4828,4831,5221,5225,5228,5994,5997,6001,6004,6217,6221,6224,6237,6241,6268,6272,6300,6420,6423,6426,6429,6454],[892,893,894],"h2",{"id":894},"概述",[896,897,898],"p",{},"MCP Client 是 AI 应用（Host）与 MCP Server 之间的桥梁。如果你正在构建自己的 AI 应用并希望接入 MCP 生态，就需要实现 MCP Client。本文将详细介绍如何使用 Python 和 TypeScript SDK 开发 MCP Client，以及如何将 MCP 集成到你的 AI 应用中。",[892,900,902],{"id":901},"连接到-mcp-server","连接到 MCP Server",[904,905,907],"h3",{"id":906},"python-client-基本示例","Python Client 基本示例",[909,910,914],"pre",{"className":911,"code":912,"language":913,"meta":11,"style":11},"language-python shiki shiki-themes github-light github-light github-dark","from mcp import ClientSession, StdioServerParameters\nfrom mcp.client.stdio import stdio_client\n\nasync def main():\n    # 定义 Server 启动参数\n    server_params = StdioServerParameters(\n        command=\"python\",\n        args=[\"path\u002Fto\u002Fserver.py\"],\n        env={\"MCP_ROOT_DIR\": \"\u002Ftmp\u002Fdata\"},\n    )\n\n    # 建立连接\n    async with stdio_client(server_params) as (read, write):\n        async with ClientSession(read, write) as session:\n            # 初始化连接（协议握手）\n            await session.initialize()\n\n            # 现在可以与 Server 交互了\n            print(\"已连接到 MCP Server\")\n","python",[915,916,917,936,949,956,972,979,991,1007,1024,1047,1053,1058,1064,1082,1098,1104,1113,1118,1124],"code",{"__ignoreMap":11},[918,919,922,926,930,933],"span",{"class":920,"line":921},"line",1,[918,923,925],{"class":924},"s8jYJ","from",[918,927,929],{"class":928},"sxrX7"," mcp ",[918,931,932],{"class":924},"import",[918,934,935],{"class":928}," ClientSession, StdioServerParameters\n",[918,937,939,941,944,946],{"class":920,"line":938},2,[918,940,925],{"class":924},[918,942,943],{"class":928}," mcp.client.stdio ",[918,945,932],{"class":924},[918,947,948],{"class":928}," stdio_client\n",[918,950,952],{"class":920,"line":951},3,[918,953,955],{"emptyLinePlaceholder":954},true,"\n",[918,957,959,962,965,969],{"class":920,"line":958},4,[918,960,961],{"class":924},"async",[918,963,964],{"class":924}," def",[918,966,968],{"class":967},"snPdu"," main",[918,970,971],{"class":928},"():\n",[918,973,975],{"class":920,"line":974},5,[918,976,978],{"class":977},"sCsY4","    # 定义 Server 启动参数\n",[918,980,982,985,988],{"class":920,"line":981},6,[918,983,984],{"class":928},"    server_params ",[918,986,987],{"class":924},"=",[918,989,990],{"class":928}," StdioServerParameters(\n",[918,992,994,998,1000,1004],{"class":920,"line":993},7,[918,995,997],{"class":996},"sP4rz","        command",[918,999,987],{"class":924},[918,1001,1003],{"class":1002},"sIIMD","\"python\"",[918,1005,1006],{"class":928},",\n",[918,1008,1010,1013,1015,1018,1021],{"class":920,"line":1009},8,[918,1011,1012],{"class":996},"        args",[918,1014,987],{"class":924},[918,1016,1017],{"class":928},"[",[918,1019,1020],{"class":1002},"\"path\u002Fto\u002Fserver.py\"",[918,1022,1023],{"class":928},"],\n",[918,1025,1027,1030,1032,1035,1038,1041,1044],{"class":920,"line":1026},9,[918,1028,1029],{"class":996},"        env",[918,1031,987],{"class":924},[918,1033,1034],{"class":928},"{",[918,1036,1037],{"class":1002},"\"MCP_ROOT_DIR\"",[918,1039,1040],{"class":928},": ",[918,1042,1043],{"class":1002},"\"\u002Ftmp\u002Fdata\"",[918,1045,1046],{"class":928},"},\n",[918,1048,1050],{"class":920,"line":1049},10,[918,1051,1052],{"class":928},"    )\n",[918,1054,1056],{"class":920,"line":1055},11,[918,1057,955],{"emptyLinePlaceholder":954},[918,1059,1061],{"class":920,"line":1060},12,[918,1062,1063],{"class":977},"    # 建立连接\n",[918,1065,1067,1070,1073,1076,1079],{"class":920,"line":1066},13,[918,1068,1069],{"class":924},"    async",[918,1071,1072],{"class":924}," with",[918,1074,1075],{"class":928}," stdio_client(server_params) ",[918,1077,1078],{"class":924},"as",[918,1080,1081],{"class":928}," (read, write):\n",[918,1083,1085,1088,1090,1093,1095],{"class":920,"line":1084},14,[918,1086,1087],{"class":924},"        async",[918,1089,1072],{"class":924},[918,1091,1092],{"class":928}," ClientSession(read, write) ",[918,1094,1078],{"class":924},[918,1096,1097],{"class":928}," session:\n",[918,1099,1101],{"class":920,"line":1100},15,[918,1102,1103],{"class":977},"            # 初始化连接（协议握手）\n",[918,1105,1107,1110],{"class":920,"line":1106},16,[918,1108,1109],{"class":924},"            await",[918,1111,1112],{"class":928}," session.initialize()\n",[918,1114,1116],{"class":920,"line":1115},17,[918,1117,955],{"emptyLinePlaceholder":954},[918,1119,1121],{"class":920,"line":1120},18,[918,1122,1123],{"class":977},"            # 现在可以与 Server 交互了\n",[918,1125,1127,1131,1134,1137],{"class":920,"line":1126},19,[918,1128,1130],{"class":1129},"sBjJW","            print",[918,1132,1133],{"class":928},"(",[918,1135,1136],{"class":1002},"\"已连接到 MCP Server\"",[918,1138,1139],{"class":928},")\n",[1141,1142,1143],"note",{},"\n`session.initialize()` 是必须的第一步调用。在初始化过程中，Client 和 Server 会交换协议版本和能力信息，完成协议握手。\n",[904,1145,1147],{"id":1146},"连接到-http-sse-server","连接到 HTTP + SSE Server",[909,1149,1151],{"className":911,"code":1150,"language":913,"meta":11,"style":11},"from mcp import ClientSession\nfrom mcp.client.sse import sse_client\n\nasync def connect_remote():\n    async with sse_client(\"http:\u002F\u002Flocalhost:8080\u002Fmcp\") as (read, write):\n        async with ClientSession(read, write) as session:\n            await session.initialize()\n            print(\"已连接到远程 MCP Server\")\n",[915,1152,1153,1164,1176,1180,1191,1210,1222,1228],{"__ignoreMap":11},[918,1154,1155,1157,1159,1161],{"class":920,"line":921},[918,1156,925],{"class":924},[918,1158,929],{"class":928},[918,1160,932],{"class":924},[918,1162,1163],{"class":928}," ClientSession\n",[918,1165,1166,1168,1171,1173],{"class":920,"line":938},[918,1167,925],{"class":924},[918,1169,1170],{"class":928}," mcp.client.sse ",[918,1172,932],{"class":924},[918,1174,1175],{"class":928}," sse_client\n",[918,1177,1178],{"class":920,"line":951},[918,1179,955],{"emptyLinePlaceholder":954},[918,1181,1182,1184,1186,1189],{"class":920,"line":958},[918,1183,961],{"class":924},[918,1185,964],{"class":924},[918,1187,1188],{"class":967}," connect_remote",[918,1190,971],{"class":928},[918,1192,1193,1195,1197,1200,1203,1206,1208],{"class":920,"line":974},[918,1194,1069],{"class":924},[918,1196,1072],{"class":924},[918,1198,1199],{"class":928}," sse_client(",[918,1201,1202],{"class":1002},"\"http:\u002F\u002Flocalhost:8080\u002Fmcp\"",[918,1204,1205],{"class":928},") ",[918,1207,1078],{"class":924},[918,1209,1081],{"class":928},[918,1211,1212,1214,1216,1218,1220],{"class":920,"line":981},[918,1213,1087],{"class":924},[918,1215,1072],{"class":924},[918,1217,1092],{"class":928},[918,1219,1078],{"class":924},[918,1221,1097],{"class":928},[918,1223,1224,1226],{"class":920,"line":993},[918,1225,1109],{"class":924},[918,1227,1112],{"class":928},[918,1229,1230,1232,1234,1237],{"class":920,"line":1009},[918,1231,1130],{"class":1129},[918,1233,1133],{"class":928},[918,1235,1236],{"class":1002},"\"已连接到远程 MCP Server\"",[918,1238,1139],{"class":928},[904,1240,1242],{"id":1241},"typescript-client-基本示例","TypeScript Client 基本示例",[909,1244,1248],{"className":1245,"code":1246,"language":1247,"meta":11,"style":11},"language-typescript shiki shiki-themes github-light github-light github-dark","import { Client } from \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Findex.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Fstdio.js\";\n\nconst transport = new StdioClientTransport({\n  command: \"python\",\n  args: [\"path\u002Fto\u002Fserver.py\"],\n});\n\nconst client = new Client({\n  name: \"my-app\",\n  version: \"1.0.0\",\n});\n\nawait client.connect(transport);\nconsole.log(\"已连接到 MCP Server\");\n","typescript",[915,1249,1250,1265,1279,1283,1303,1312,1321,1326,1330,1346,1356,1366,1370,1374,1388],{"__ignoreMap":11},[918,1251,1252,1254,1257,1259,1262],{"class":920,"line":921},[918,1253,932],{"class":924},[918,1255,1256],{"class":928}," { Client } ",[918,1258,925],{"class":924},[918,1260,1261],{"class":1002}," \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Findex.js\"",[918,1263,1264],{"class":928},";\n",[918,1266,1267,1269,1272,1274,1277],{"class":920,"line":938},[918,1268,932],{"class":924},[918,1270,1271],{"class":928}," { StdioClientTransport } ",[918,1273,925],{"class":924},[918,1275,1276],{"class":1002}," \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Fstdio.js\"",[918,1278,1264],{"class":928},[918,1280,1281],{"class":920,"line":951},[918,1282,955],{"emptyLinePlaceholder":954},[918,1284,1285,1288,1291,1294,1297,1300],{"class":920,"line":958},[918,1286,1287],{"class":924},"const",[918,1289,1290],{"class":1129}," transport",[918,1292,1293],{"class":924}," =",[918,1295,1296],{"class":924}," new",[918,1298,1299],{"class":967}," StdioClientTransport",[918,1301,1302],{"class":928},"({\n",[918,1304,1305,1308,1310],{"class":920,"line":974},[918,1306,1307],{"class":928},"  command: ",[918,1309,1003],{"class":1002},[918,1311,1006],{"class":928},[918,1313,1314,1317,1319],{"class":920,"line":981},[918,1315,1316],{"class":928},"  args: [",[918,1318,1020],{"class":1002},[918,1320,1023],{"class":928},[918,1322,1323],{"class":920,"line":993},[918,1324,1325],{"class":928},"});\n",[918,1327,1328],{"class":920,"line":1009},[918,1329,955],{"emptyLinePlaceholder":954},[918,1331,1332,1334,1337,1339,1341,1344],{"class":920,"line":1026},[918,1333,1287],{"class":924},[918,1335,1336],{"class":1129}," client",[918,1338,1293],{"class":924},[918,1340,1296],{"class":924},[918,1342,1343],{"class":967}," Client",[918,1345,1302],{"class":928},[918,1347,1348,1351,1354],{"class":920,"line":1049},[918,1349,1350],{"class":928},"  name: ",[918,1352,1353],{"class":1002},"\"my-app\"",[918,1355,1006],{"class":928},[918,1357,1358,1361,1364],{"class":920,"line":1055},[918,1359,1360],{"class":928},"  version: ",[918,1362,1363],{"class":1002},"\"1.0.0\"",[918,1365,1006],{"class":928},[918,1367,1368],{"class":920,"line":1060},[918,1369,1325],{"class":928},[918,1371,1372],{"class":920,"line":1066},[918,1373,955],{"emptyLinePlaceholder":954},[918,1375,1376,1379,1382,1385],{"class":920,"line":1084},[918,1377,1378],{"class":924},"await",[918,1380,1381],{"class":928}," client.",[918,1383,1384],{"class":967},"connect",[918,1386,1387],{"class":928},"(transport);\n",[918,1389,1390,1393,1395,1397,1399],{"class":920,"line":1100},[918,1391,1392],{"class":928},"console.",[918,1394,260],{"class":967},[918,1396,1133],{"class":928},[918,1398,1136],{"class":1002},[918,1400,1401],{"class":928},");\n",[892,1403,1405],{"id":1404},"发现-server-能力","发现 Server 能力",[896,1407,1408],{},"连接建立后，Client 可以查询 Server 提供的所有能力：",[904,1410,1411],{"id":1411},"列出可用工具",[909,1413,1415],{"className":911,"code":1414,"language":913,"meta":11,"style":11},"async with ClientSession(read, write) as session:\n    await session.initialize()\n\n    # 获取所有工具列表\n    tools_result = await session.list_tools()\n\n    for tool in tools_result.tools:\n        print(f\"工具: {tool.name}\")\n        print(f\"  描述: {tool.description}\")\n        print(f\"  参数: {tool.inputSchema}\")\n        print()\n",[915,1416,1417,1429,1436,1440,1445,1458,1462,1476,1502,1524,1546],{"__ignoreMap":11},[918,1418,1419,1421,1423,1425,1427],{"class":920,"line":921},[918,1420,961],{"class":924},[918,1422,1072],{"class":924},[918,1424,1092],{"class":928},[918,1426,1078],{"class":924},[918,1428,1097],{"class":928},[918,1430,1431,1434],{"class":920,"line":938},[918,1432,1433],{"class":924},"    await",[918,1435,1112],{"class":928},[918,1437,1438],{"class":920,"line":951},[918,1439,955],{"emptyLinePlaceholder":954},[918,1441,1442],{"class":920,"line":958},[918,1443,1444],{"class":977},"    # 获取所有工具列表\n",[918,1446,1447,1450,1452,1455],{"class":920,"line":974},[918,1448,1449],{"class":928},"    tools_result ",[918,1451,987],{"class":924},[918,1453,1454],{"class":924}," await",[918,1456,1457],{"class":928}," session.list_tools()\n",[918,1459,1460],{"class":920,"line":981},[918,1461,955],{"emptyLinePlaceholder":954},[918,1463,1464,1467,1470,1473],{"class":920,"line":993},[918,1465,1466],{"class":924},"    for",[918,1468,1469],{"class":928}," tool ",[918,1471,1472],{"class":924},"in",[918,1474,1475],{"class":928}," tools_result.tools:\n",[918,1477,1478,1481,1483,1486,1489,1491,1494,1497,1500],{"class":920,"line":1009},[918,1479,1480],{"class":1129},"        print",[918,1482,1133],{"class":928},[918,1484,1485],{"class":924},"f",[918,1487,1488],{"class":1002},"\"工具: ",[918,1490,1034],{"class":1129},[918,1492,1493],{"class":928},"tool.name",[918,1495,1496],{"class":1129},"}",[918,1498,1499],{"class":1002},"\"",[918,1501,1139],{"class":928},[918,1503,1504,1506,1508,1510,1513,1515,1518,1520,1522],{"class":920,"line":1026},[918,1505,1480],{"class":1129},[918,1507,1133],{"class":928},[918,1509,1485],{"class":924},[918,1511,1512],{"class":1002},"\"  描述: ",[918,1514,1034],{"class":1129},[918,1516,1517],{"class":928},"tool.description",[918,1519,1496],{"class":1129},[918,1521,1499],{"class":1002},[918,1523,1139],{"class":928},[918,1525,1526,1528,1530,1532,1535,1537,1540,1542,1544],{"class":920,"line":1049},[918,1527,1480],{"class":1129},[918,1529,1133],{"class":928},[918,1531,1485],{"class":924},[918,1533,1534],{"class":1002},"\"  参数: ",[918,1536,1034],{"class":1129},[918,1538,1539],{"class":928},"tool.inputSchema",[918,1541,1496],{"class":1129},[918,1543,1499],{"class":1002},[918,1545,1139],{"class":928},[918,1547,1548,1550],{"class":920,"line":1055},[918,1549,1480],{"class":1129},[918,1551,1552],{"class":928},"()\n",[904,1554,1555],{"id":1555},"列出可用资源",[909,1557,1559],{"className":911,"code":1558,"language":913,"meta":11,"style":11},"    # 获取所有资源列表\n    resources_result = await session.list_resources()\n\n    for resource in resources_result.resources:\n        print(f\"资源: {resource.name} ({resource.uri})\")\n        print(f\"  描述: {resource.description}\")\n        print(f\"  类型: {resource.mimeType}\")\n",[915,1560,1561,1566,1578,1582,1594,1627,1648],{"__ignoreMap":11},[918,1562,1563],{"class":920,"line":921},[918,1564,1565],{"class":977},"    # 获取所有资源列表\n",[918,1567,1568,1571,1573,1575],{"class":920,"line":938},[918,1569,1570],{"class":928},"    resources_result ",[918,1572,987],{"class":924},[918,1574,1454],{"class":924},[918,1576,1577],{"class":928}," session.list_resources()\n",[918,1579,1580],{"class":920,"line":951},[918,1581,955],{"emptyLinePlaceholder":954},[918,1583,1584,1586,1589,1591],{"class":920,"line":958},[918,1585,1466],{"class":924},[918,1587,1588],{"class":928}," resource ",[918,1590,1472],{"class":924},[918,1592,1593],{"class":928}," resources_result.resources:\n",[918,1595,1596,1598,1600,1602,1605,1607,1610,1612,1615,1617,1620,1622,1625],{"class":920,"line":974},[918,1597,1480],{"class":1129},[918,1599,1133],{"class":928},[918,1601,1485],{"class":924},[918,1603,1604],{"class":1002},"\"资源: ",[918,1606,1034],{"class":1129},[918,1608,1609],{"class":928},"resource.name",[918,1611,1496],{"class":1129},[918,1613,1614],{"class":1002}," (",[918,1616,1034],{"class":1129},[918,1618,1619],{"class":928},"resource.uri",[918,1621,1496],{"class":1129},[918,1623,1624],{"class":1002},")\"",[918,1626,1139],{"class":928},[918,1628,1629,1631,1633,1635,1637,1639,1642,1644,1646],{"class":920,"line":981},[918,1630,1480],{"class":1129},[918,1632,1133],{"class":928},[918,1634,1485],{"class":924},[918,1636,1512],{"class":1002},[918,1638,1034],{"class":1129},[918,1640,1641],{"class":928},"resource.description",[918,1643,1496],{"class":1129},[918,1645,1499],{"class":1002},[918,1647,1139],{"class":928},[918,1649,1650,1652,1654,1656,1659,1661,1664,1666,1668],{"class":920,"line":993},[918,1651,1480],{"class":1129},[918,1653,1133],{"class":928},[918,1655,1485],{"class":924},[918,1657,1658],{"class":1002},"\"  类型: ",[918,1660,1034],{"class":1129},[918,1662,1663],{"class":928},"resource.mimeType",[918,1665,1496],{"class":1129},[918,1667,1499],{"class":1002},[918,1669,1139],{"class":928},[904,1671,1672],{"id":1672},"列出提示词模板",[909,1674,1676],{"className":911,"code":1675,"language":913,"meta":11,"style":11},"    # 获取所有提示词模板\n    prompts_result = await session.list_prompts()\n\n    for prompt in prompts_result.prompts:\n        print(f\"提示词: {prompt.name}\")\n        print(f\"  描述: {prompt.description}\")\n        print(f\"  参数: {prompt.arguments}\")\n",[915,1677,1678,1683,1695,1699,1711,1733,1754],{"__ignoreMap":11},[918,1679,1680],{"class":920,"line":921},[918,1681,1682],{"class":977},"    # 获取所有提示词模板\n",[918,1684,1685,1688,1690,1692],{"class":920,"line":938},[918,1686,1687],{"class":928},"    prompts_result ",[918,1689,987],{"class":924},[918,1691,1454],{"class":924},[918,1693,1694],{"class":928}," session.list_prompts()\n",[918,1696,1697],{"class":920,"line":951},[918,1698,955],{"emptyLinePlaceholder":954},[918,1700,1701,1703,1706,1708],{"class":920,"line":958},[918,1702,1466],{"class":924},[918,1704,1705],{"class":928}," prompt ",[918,1707,1472],{"class":924},[918,1709,1710],{"class":928}," prompts_result.prompts:\n",[918,1712,1713,1715,1717,1719,1722,1724,1727,1729,1731],{"class":920,"line":974},[918,1714,1480],{"class":1129},[918,1716,1133],{"class":928},[918,1718,1485],{"class":924},[918,1720,1721],{"class":1002},"\"提示词: ",[918,1723,1034],{"class":1129},[918,1725,1726],{"class":928},"prompt.name",[918,1728,1496],{"class":1129},[918,1730,1499],{"class":1002},[918,1732,1139],{"class":928},[918,1734,1735,1737,1739,1741,1743,1745,1748,1750,1752],{"class":920,"line":981},[918,1736,1480],{"class":1129},[918,1738,1133],{"class":928},[918,1740,1485],{"class":924},[918,1742,1512],{"class":1002},[918,1744,1034],{"class":1129},[918,1746,1747],{"class":928},"prompt.description",[918,1749,1496],{"class":1129},[918,1751,1499],{"class":1002},[918,1753,1139],{"class":928},[918,1755,1756,1758,1760,1762,1764,1766,1769,1771,1773],{"class":920,"line":993},[918,1757,1480],{"class":1129},[918,1759,1133],{"class":928},[918,1761,1485],{"class":924},[918,1763,1534],{"class":1002},[918,1765,1034],{"class":1129},[918,1767,1768],{"class":928},"prompt.arguments",[918,1770,1496],{"class":1129},[918,1772,1499],{"class":1002},[918,1774,1139],{"class":928},[892,1776,1777],{"id":1777},"调用工具",[896,1779,1780],{},"工具调用是 MCP Client 最核心的操作：",[909,1782,1784],{"className":911,"code":1783,"language":913,"meta":11,"style":11},"from mcp.types import TextContent\n\nasync with ClientSession(read, write) as session:\n    await session.initialize()\n\n    # 调用工具\n    result = await session.call_tool(\n        name=\"query_database\",\n        arguments={\n            \"sql\": \"SELECT * FROM users WHERE age > 18\",\n            \"limit\": 10,\n        },\n    )\n\n    # 处理返回结果\n    for content in result.content:\n        if isinstance(content, TextContent):\n            print(f\"结果: {content.text}\")\n",[915,1785,1786,1798,1802,1814,1820,1824,1829,1841,1853,1863,1875,1887,1892,1896,1900,1905,1917,1928],{"__ignoreMap":11},[918,1787,1788,1790,1793,1795],{"class":920,"line":921},[918,1789,925],{"class":924},[918,1791,1792],{"class":928}," mcp.types ",[918,1794,932],{"class":924},[918,1796,1797],{"class":928}," TextContent\n",[918,1799,1800],{"class":920,"line":938},[918,1801,955],{"emptyLinePlaceholder":954},[918,1803,1804,1806,1808,1810,1812],{"class":920,"line":951},[918,1805,961],{"class":924},[918,1807,1072],{"class":924},[918,1809,1092],{"class":928},[918,1811,1078],{"class":924},[918,1813,1097],{"class":928},[918,1815,1816,1818],{"class":920,"line":958},[918,1817,1433],{"class":924},[918,1819,1112],{"class":928},[918,1821,1822],{"class":920,"line":974},[918,1823,955],{"emptyLinePlaceholder":954},[918,1825,1826],{"class":920,"line":981},[918,1827,1828],{"class":977},"    # 调用工具\n",[918,1830,1831,1834,1836,1838],{"class":920,"line":993},[918,1832,1833],{"class":928},"    result ",[918,1835,987],{"class":924},[918,1837,1454],{"class":924},[918,1839,1840],{"class":928}," session.call_tool(\n",[918,1842,1843,1846,1848,1851],{"class":920,"line":1009},[918,1844,1845],{"class":996},"        name",[918,1847,987],{"class":924},[918,1849,1850],{"class":1002},"\"query_database\"",[918,1852,1006],{"class":928},[918,1854,1855,1858,1860],{"class":920,"line":1026},[918,1856,1857],{"class":996},"        arguments",[918,1859,987],{"class":924},[918,1861,1862],{"class":928},"{\n",[918,1864,1865,1868,1870,1873],{"class":920,"line":1049},[918,1866,1867],{"class":1002},"            \"sql\"",[918,1869,1040],{"class":928},[918,1871,1872],{"class":1002},"\"SELECT * FROM users WHERE age > 18\"",[918,1874,1006],{"class":928},[918,1876,1877,1880,1882,1885],{"class":920,"line":1055},[918,1878,1879],{"class":1002},"            \"limit\"",[918,1881,1040],{"class":928},[918,1883,1884],{"class":1129},"10",[918,1886,1006],{"class":928},[918,1888,1889],{"class":920,"line":1060},[918,1890,1891],{"class":928},"        },\n",[918,1893,1894],{"class":920,"line":1066},[918,1895,1052],{"class":928},[918,1897,1898],{"class":920,"line":1084},[918,1899,955],{"emptyLinePlaceholder":954},[918,1901,1902],{"class":920,"line":1100},[918,1903,1904],{"class":977},"    # 处理返回结果\n",[918,1906,1907,1909,1912,1914],{"class":920,"line":1106},[918,1908,1466],{"class":924},[918,1910,1911],{"class":928}," content ",[918,1913,1472],{"class":924},[918,1915,1916],{"class":928}," result.content:\n",[918,1918,1919,1922,1925],{"class":920,"line":1115},[918,1920,1921],{"class":924},"        if",[918,1923,1924],{"class":1129}," isinstance",[918,1926,1927],{"class":928},"(content, TextContent):\n",[918,1929,1930,1932,1934,1936,1939,1941,1944,1946,1948],{"class":920,"line":1120},[918,1931,1130],{"class":1129},[918,1933,1133],{"class":928},[918,1935,1485],{"class":924},[918,1937,1938],{"class":1002},"\"结果: ",[918,1940,1034],{"class":1129},[918,1942,1943],{"class":928},"content.text",[918,1945,1496],{"class":1129},[918,1947,1499],{"class":1002},[918,1949,1139],{"class":928},[904,1951,1953],{"id":1952},"typescript-中调用工具","TypeScript 中调用工具",[909,1955,1957],{"className":1245,"code":1956,"language":1247,"meta":11,"style":11},"const result = await client.callTool({\n  name: \"query_database\",\n  arguments: {\n    sql: \"SELECT * FROM users WHERE age > 18\",\n    limit: 10,\n  },\n});\n\nfor (const content of result.content) {\n  if (content.type === \"text\") {\n    console.log(`结果: ${content.text}`);\n  }\n}\n",[915,1958,1959,1977,1985,1990,1999,2008,2013,2017,2021,2039,2056,2082,2087],{"__ignoreMap":11},[918,1960,1961,1963,1966,1968,1970,1972,1975],{"class":920,"line":921},[918,1962,1287],{"class":924},[918,1964,1965],{"class":1129}," result",[918,1967,1293],{"class":924},[918,1969,1454],{"class":924},[918,1971,1381],{"class":928},[918,1973,1974],{"class":967},"callTool",[918,1976,1302],{"class":928},[918,1978,1979,1981,1983],{"class":920,"line":938},[918,1980,1350],{"class":928},[918,1982,1850],{"class":1002},[918,1984,1006],{"class":928},[918,1986,1987],{"class":920,"line":951},[918,1988,1989],{"class":928},"  arguments: {\n",[918,1991,1992,1995,1997],{"class":920,"line":958},[918,1993,1994],{"class":928},"    sql: ",[918,1996,1872],{"class":1002},[918,1998,1006],{"class":928},[918,2000,2001,2004,2006],{"class":920,"line":974},[918,2002,2003],{"class":928},"    limit: ",[918,2005,1884],{"class":1129},[918,2007,1006],{"class":928},[918,2009,2010],{"class":920,"line":981},[918,2011,2012],{"class":928},"  },\n",[918,2014,2015],{"class":920,"line":993},[918,2016,1325],{"class":928},[918,2018,2019],{"class":920,"line":1009},[918,2020,955],{"emptyLinePlaceholder":954},[918,2022,2023,2026,2028,2030,2033,2036],{"class":920,"line":1026},[918,2024,2025],{"class":924},"for",[918,2027,1614],{"class":928},[918,2029,1287],{"class":924},[918,2031,2032],{"class":1129}," content",[918,2034,2035],{"class":924}," of",[918,2037,2038],{"class":928}," result.content) {\n",[918,2040,2041,2044,2047,2050,2053],{"class":920,"line":1049},[918,2042,2043],{"class":924},"  if",[918,2045,2046],{"class":928}," (content.type ",[918,2048,2049],{"class":924},"===",[918,2051,2052],{"class":1002}," \"text\"",[918,2054,2055],{"class":928},") {\n",[918,2057,2058,2061,2063,2065,2068,2071,2074,2077,2080],{"class":920,"line":1055},[918,2059,2060],{"class":928},"    console.",[918,2062,260],{"class":967},[918,2064,1133],{"class":928},[918,2066,2067],{"class":1002},"`结果: ${",[918,2069,2070],{"class":928},"content",[918,2072,2073],{"class":1002},".",[918,2075,2076],{"class":928},"text",[918,2078,2079],{"class":1002},"}`",[918,2081,1401],{"class":928},[918,2083,2084],{"class":920,"line":1060},[918,2085,2086],{"class":928},"  }\n",[918,2088,2089],{"class":920,"line":1066},[918,2090,2091],{"class":928},"}\n",[892,2093,2094],{"id":2094},"读取资源",[909,2096,2098],{"className":911,"code":2097,"language":913,"meta":11,"style":11},"async with ClientSession(read, write) as session:\n    await session.initialize()\n\n    # 读取静态资源\n    resource = await session.read_resource(\"db:\u002F\u002Fschema\")\n    for content in resource.contents:\n        print(f\"资源内容: {content.text}\")\n\n    # 读取动态资源（资源模板）\n    resource = await session.read_resource(\"users:\u002F\u002F001\u002Fprofile\")\n    for content in resource.contents:\n        print(f\"用户资料: {content.text}\")\n",[915,2099,2100,2112,2118,2122,2127,2144,2155,2176,2180,2185,2200,2210],{"__ignoreMap":11},[918,2101,2102,2104,2106,2108,2110],{"class":920,"line":921},[918,2103,961],{"class":924},[918,2105,1072],{"class":924},[918,2107,1092],{"class":928},[918,2109,1078],{"class":924},[918,2111,1097],{"class":928},[918,2113,2114,2116],{"class":920,"line":938},[918,2115,1433],{"class":924},[918,2117,1112],{"class":928},[918,2119,2120],{"class":920,"line":951},[918,2121,955],{"emptyLinePlaceholder":954},[918,2123,2124],{"class":920,"line":958},[918,2125,2126],{"class":977},"    # 读取静态资源\n",[918,2128,2129,2132,2134,2136,2139,2142],{"class":920,"line":974},[918,2130,2131],{"class":928},"    resource ",[918,2133,987],{"class":924},[918,2135,1454],{"class":924},[918,2137,2138],{"class":928}," session.read_resource(",[918,2140,2141],{"class":1002},"\"db:\u002F\u002Fschema\"",[918,2143,1139],{"class":928},[918,2145,2146,2148,2150,2152],{"class":920,"line":981},[918,2147,1466],{"class":924},[918,2149,1911],{"class":928},[918,2151,1472],{"class":924},[918,2153,2154],{"class":928}," resource.contents:\n",[918,2156,2157,2159,2161,2163,2166,2168,2170,2172,2174],{"class":920,"line":993},[918,2158,1480],{"class":1129},[918,2160,1133],{"class":928},[918,2162,1485],{"class":924},[918,2164,2165],{"class":1002},"\"资源内容: ",[918,2167,1034],{"class":1129},[918,2169,1943],{"class":928},[918,2171,1496],{"class":1129},[918,2173,1499],{"class":1002},[918,2175,1139],{"class":928},[918,2177,2178],{"class":920,"line":1009},[918,2179,955],{"emptyLinePlaceholder":954},[918,2181,2182],{"class":920,"line":1026},[918,2183,2184],{"class":977},"    # 读取动态资源（资源模板）\n",[918,2186,2187,2189,2191,2193,2195,2198],{"class":920,"line":1049},[918,2188,2131],{"class":928},[918,2190,987],{"class":924},[918,2192,1454],{"class":924},[918,2194,2138],{"class":928},[918,2196,2197],{"class":1002},"\"users:\u002F\u002F001\u002Fprofile\"",[918,2199,1139],{"class":928},[918,2201,2202,2204,2206,2208],{"class":920,"line":1055},[918,2203,1466],{"class":924},[918,2205,1911],{"class":928},[918,2207,1472],{"class":924},[918,2209,2154],{"class":928},[918,2211,2212,2214,2216,2218,2221,2223,2225,2227,2229],{"class":920,"line":1060},[918,2213,1480],{"class":1129},[918,2215,1133],{"class":928},[918,2217,1485],{"class":924},[918,2219,2220],{"class":1002},"\"用户资料: ",[918,2222,1034],{"class":1129},[918,2224,1943],{"class":928},[918,2226,1496],{"class":1129},[918,2228,1499],{"class":1002},[918,2230,1139],{"class":928},[892,2232,2233],{"id":2233},"使用提示词模板",[909,2235,2237],{"className":911,"code":2236,"language":913,"meta":11,"style":11},"async with ClientSession(read, write) as session:\n    await session.initialize()\n\n    # 获取填充后的提示词\n    prompt_result = await session.get_prompt(\n        name=\"code_review\",\n        arguments={\n            \"language\": \"python\",\n            \"code\": \"def add(a, b): return a + b\",\n        },\n    )\n\n    # prompt_result.messages 包含可以直接发送给 AI 模型的消息\n    for message in prompt_result.messages:\n        print(f\"[{message.role}] {message.content.text}\")\n",[915,2238,2239,2251,2257,2261,2266,2278,2289,2297,2308,2320,2324,2328,2332,2337,2349],{"__ignoreMap":11},[918,2240,2241,2243,2245,2247,2249],{"class":920,"line":921},[918,2242,961],{"class":924},[918,2244,1072],{"class":924},[918,2246,1092],{"class":928},[918,2248,1078],{"class":924},[918,2250,1097],{"class":928},[918,2252,2253,2255],{"class":920,"line":938},[918,2254,1433],{"class":924},[918,2256,1112],{"class":928},[918,2258,2259],{"class":920,"line":951},[918,2260,955],{"emptyLinePlaceholder":954},[918,2262,2263],{"class":920,"line":958},[918,2264,2265],{"class":977},"    # 获取填充后的提示词\n",[918,2267,2268,2271,2273,2275],{"class":920,"line":974},[918,2269,2270],{"class":928},"    prompt_result ",[918,2272,987],{"class":924},[918,2274,1454],{"class":924},[918,2276,2277],{"class":928}," session.get_prompt(\n",[918,2279,2280,2282,2284,2287],{"class":920,"line":981},[918,2281,1845],{"class":996},[918,2283,987],{"class":924},[918,2285,2286],{"class":1002},"\"code_review\"",[918,2288,1006],{"class":928},[918,2290,2291,2293,2295],{"class":920,"line":993},[918,2292,1857],{"class":996},[918,2294,987],{"class":924},[918,2296,1862],{"class":928},[918,2298,2299,2302,2304,2306],{"class":920,"line":1009},[918,2300,2301],{"class":1002},"            \"language\"",[918,2303,1040],{"class":928},[918,2305,1003],{"class":1002},[918,2307,1006],{"class":928},[918,2309,2310,2313,2315,2318],{"class":920,"line":1026},[918,2311,2312],{"class":1002},"            \"code\"",[918,2314,1040],{"class":928},[918,2316,2317],{"class":1002},"\"def add(a, b): return a + b\"",[918,2319,1006],{"class":928},[918,2321,2322],{"class":920,"line":1049},[918,2323,1891],{"class":928},[918,2325,2326],{"class":920,"line":1055},[918,2327,1052],{"class":928},[918,2329,2330],{"class":920,"line":1060},[918,2331,955],{"emptyLinePlaceholder":954},[918,2333,2334],{"class":920,"line":1066},[918,2335,2336],{"class":977},"    # prompt_result.messages 包含可以直接发送给 AI 模型的消息\n",[918,2338,2339,2341,2344,2346],{"class":920,"line":1084},[918,2340,1466],{"class":924},[918,2342,2343],{"class":928}," message ",[918,2345,1472],{"class":924},[918,2347,2348],{"class":928}," prompt_result.messages:\n",[918,2350,2351,2353,2355,2357,2360,2362,2365,2367,2370,2372,2375,2377,2379],{"class":920,"line":1100},[918,2352,1480],{"class":1129},[918,2354,1133],{"class":928},[918,2356,1485],{"class":924},[918,2358,2359],{"class":1002},"\"[",[918,2361,1034],{"class":1129},[918,2363,2364],{"class":928},"message.role",[918,2366,1496],{"class":1129},[918,2368,2369],{"class":1002},"] ",[918,2371,1034],{"class":1129},[918,2373,2374],{"class":928},"message.content.text",[918,2376,1496],{"class":1129},[918,2378,1499],{"class":1002},[918,2380,1139],{"class":928},[892,2382,2384],{"id":2383},"将-mcp-集成到-ai-应用","将 MCP 集成到 AI 应用",[896,2386,2387],{},"下面是一个完整的示例，展示如何将 MCP Client 集成到基于 Claude API 的 AI 应用中：",[909,2389,2391],{"className":911,"code":2390,"language":913,"meta":11,"style":11},"import asyncio\nimport json\nfrom anthropic import Anthropic\nfrom mcp import ClientSession, StdioServerParameters\nfrom mcp.client.stdio import stdio_client\n\nclass MCPChatApp:\n    \"\"\"集成了 MCP 的 AI 聊天应用\"\"\"\n\n    def __init__(self):\n        self.anthropic = Anthropic()\n        self.sessions: dict[str, ClientSession] = {}\n        self.available_tools = []\n\n    async def connect_server(self, name: str, command: str, args: list[str]):\n        \"\"\"连接到一个 MCP Server\"\"\"\n        server_params = StdioServerParameters(command=command, args=args)\n\n        # 注意：实际使用中需要管理连接的生命周期\n        read, write = await stdio_client(server_params).__aenter__()\n        session = await ClientSession(read, write).__aenter__()\n        await session.initialize()\n\n        self.sessions[name] = session\n\n        # 获取该 Server 的工具列表\n        tools_result = await session.list_tools()\n        for tool in tools_result.tools:\n            self.available_tools.append({\n                \"name\": tool.name,\n                \"description\": tool.description,\n                \"input_schema\": tool.inputSchema,\n                \"_server\": name,  # 记录工具所属的 Server\n            })\n\n        print(f\"已连接 Server '{name}'，发现 {len(tools_result.tools)} 个工具\")\n\n    def _get_claude_tools(self) -> list[dict]:\n        \"\"\"将 MCP 工具格式转换为 Claude API 的 tools 格式\"\"\"\n        return [\n            {\n                \"name\": tool[\"name\"],\n                \"description\": tool[\"description\"],\n                \"input_schema\": tool[\"input_schema\"],\n            }\n            for tool in self.available_tools\n        ]\n\n    def _find_server_for_tool(self, tool_name: str) -> str:\n        \"\"\"查找工具所属的 Server\"\"\"\n        for tool in self.available_tools:\n            if tool[\"name\"] == tool_name:\n                return tool[\"_server\"]\n        raise ValueError(f\"未找到工具: {tool_name}\")\n\n    async def chat(self, user_message: str) -> str:\n        \"\"\"处理用户消息，支持工具调用\"\"\"\n        messages = [{\"role\": \"user\", \"content\": user_message}]\n\n        while True:\n            # 调用 Claude API\n            response = self.anthropic.messages.create(\n                model=\"claude-sonnet-4-20250514\",\n                max_tokens=4096,\n                tools=self._get_claude_tools(),\n                messages=messages,\n            )\n\n            # 检查是否需要调用工具\n            if response.stop_reason == \"tool_use\":\n                # 提取工具调用请求\n                assistant_content = response.content\n                messages.append({\"role\": \"assistant\", \"content\": assistant_content})\n\n                tool_results = []\n                for block in assistant_content:\n                    if block.type == \"tool_use\":\n                        # 通过 MCP 调用工具\n                        server_name = self._find_server_for_tool(block.name)\n                        session = self.sessions[server_name]\n\n                        result = await session.call_tool(\n                            name=block.name,\n                            arguments=block.input,\n                        )\n\n                        tool_results.append({\n                            \"type\": \"tool_result\",\n                            \"tool_use_id\": block.id,\n                            \"content\": result.content[0].text\n                                if result.content else \"无结果\",\n                        })\n\n                messages.append({\"role\": \"user\", \"content\": tool_results})\n            else:\n                # 模型直接返回了文本回复\n                final_text = \"\"\n                for block in response.content:\n                    if hasattr(block, \"text\"):\n                        final_text += block.text\n                return final_text\n\nasync def main():\n    app = MCPChatApp()\n\n    # 连接 MCP Server\n    await app.connect_server(\n        name=\"filesystem\",\n        command=\"python\",\n        args=[\"filesystem_server.py\"],\n    )\n\n    # 进行对话\n    response = await app.chat(\"请列出 Documents 目录下的所有文件\")\n    print(response)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n",[915,2392,2393,2400,2407,2419,2429,2439,2443,2454,2459,2463,2474,2487,2505,2517,2521,2548,2553,2579,2583,2588,2606,2623,2631,2636,2649,2654,2660,2672,2684,2693,2702,2711,2720,2732,2738,2743,2778,2783,2800,2806,2815,2821,2834,2846,2858,2864,2880,2886,2891,2911,2917,2931,2950,2964,2991,2996,3017,3023,3051,3056,3067,3073,3086,3099,3112,3126,3137,3143,3148,3154,3169,3175,3186,3206,3211,3221,3235,3250,3256,3269,3282,3287,3299,3310,3321,3327,3332,3338,3351,3360,3375,3392,3398,3403,3421,3429,3435,3446,3458,3475,3487,3495,3500,3511,3522,3527,3533,3541,3553,3564,3578,3583,3588,3594,3612,3621,3626,3643],{"__ignoreMap":11},[918,2394,2395,2397],{"class":920,"line":921},[918,2396,932],{"class":924},[918,2398,2399],{"class":928}," asyncio\n",[918,2401,2402,2404],{"class":920,"line":938},[918,2403,932],{"class":924},[918,2405,2406],{"class":928}," json\n",[918,2408,2409,2411,2414,2416],{"class":920,"line":951},[918,2410,925],{"class":924},[918,2412,2413],{"class":928}," anthropic ",[918,2415,932],{"class":924},[918,2417,2418],{"class":928}," Anthropic\n",[918,2420,2421,2423,2425,2427],{"class":920,"line":958},[918,2422,925],{"class":924},[918,2424,929],{"class":928},[918,2426,932],{"class":924},[918,2428,935],{"class":928},[918,2430,2431,2433,2435,2437],{"class":920,"line":974},[918,2432,925],{"class":924},[918,2434,943],{"class":928},[918,2436,932],{"class":924},[918,2438,948],{"class":928},[918,2440,2441],{"class":920,"line":981},[918,2442,955],{"emptyLinePlaceholder":954},[918,2444,2445,2448,2451],{"class":920,"line":993},[918,2446,2447],{"class":924},"class",[918,2449,2450],{"class":967}," MCPChatApp",[918,2452,2453],{"class":928},":\n",[918,2455,2456],{"class":920,"line":1009},[918,2457,2458],{"class":1002},"    \"\"\"集成了 MCP 的 AI 聊天应用\"\"\"\n",[918,2460,2461],{"class":920,"line":1026},[918,2462,955],{"emptyLinePlaceholder":954},[918,2464,2465,2468,2471],{"class":920,"line":1049},[918,2466,2467],{"class":924},"    def",[918,2469,2470],{"class":1129}," __init__",[918,2472,2473],{"class":928},"(self):\n",[918,2475,2476,2479,2482,2484],{"class":920,"line":1055},[918,2477,2478],{"class":1129},"        self",[918,2480,2481],{"class":928},".anthropic ",[918,2483,987],{"class":924},[918,2485,2486],{"class":928}," Anthropic()\n",[918,2488,2489,2491,2494,2497,2500,2502],{"class":920,"line":1060},[918,2490,2478],{"class":1129},[918,2492,2493],{"class":928},".sessions: dict[",[918,2495,2496],{"class":1129},"str",[918,2498,2499],{"class":928},", ClientSession] ",[918,2501,987],{"class":924},[918,2503,2504],{"class":928}," {}\n",[918,2506,2507,2509,2512,2514],{"class":920,"line":1066},[918,2508,2478],{"class":1129},[918,2510,2511],{"class":928},".available_tools ",[918,2513,987],{"class":924},[918,2515,2516],{"class":928}," []\n",[918,2518,2519],{"class":920,"line":1084},[918,2520,955],{"emptyLinePlaceholder":954},[918,2522,2523,2525,2527,2530,2533,2535,2538,2540,2543,2545],{"class":920,"line":1100},[918,2524,1069],{"class":924},[918,2526,964],{"class":924},[918,2528,2529],{"class":967}," connect_server",[918,2531,2532],{"class":928},"(self, name: ",[918,2534,2496],{"class":1129},[918,2536,2537],{"class":928},", command: ",[918,2539,2496],{"class":1129},[918,2541,2542],{"class":928},", args: list[",[918,2544,2496],{"class":1129},[918,2546,2547],{"class":928},"]):\n",[918,2549,2550],{"class":920,"line":1106},[918,2551,2552],{"class":1002},"        \"\"\"连接到一个 MCP Server\"\"\"\n",[918,2554,2555,2558,2560,2563,2566,2568,2571,2574,2576],{"class":920,"line":1115},[918,2556,2557],{"class":928},"        server_params ",[918,2559,987],{"class":924},[918,2561,2562],{"class":928}," StdioServerParameters(",[918,2564,2565],{"class":996},"command",[918,2567,987],{"class":924},[918,2569,2570],{"class":928},"command, ",[918,2572,2573],{"class":996},"args",[918,2575,987],{"class":924},[918,2577,2578],{"class":928},"args)\n",[918,2580,2581],{"class":920,"line":1120},[918,2582,955],{"emptyLinePlaceholder":954},[918,2584,2585],{"class":920,"line":1126},[918,2586,2587],{"class":977},"        # 注意：实际使用中需要管理连接的生命周期\n",[918,2589,2591,2594,2596,2598,2601,2604],{"class":920,"line":2590},20,[918,2592,2593],{"class":928},"        read, write ",[918,2595,987],{"class":924},[918,2597,1454],{"class":924},[918,2599,2600],{"class":928}," stdio_client(server_params).",[918,2602,2603],{"class":1129},"__aenter__",[918,2605,1552],{"class":928},[918,2607,2609,2612,2614,2616,2619,2621],{"class":920,"line":2608},21,[918,2610,2611],{"class":928},"        session ",[918,2613,987],{"class":924},[918,2615,1454],{"class":924},[918,2617,2618],{"class":928}," ClientSession(read, write).",[918,2620,2603],{"class":1129},[918,2622,1552],{"class":928},[918,2624,2626,2629],{"class":920,"line":2625},22,[918,2627,2628],{"class":924},"        await",[918,2630,1112],{"class":928},[918,2632,2634],{"class":920,"line":2633},23,[918,2635,955],{"emptyLinePlaceholder":954},[918,2637,2639,2641,2644,2646],{"class":920,"line":2638},24,[918,2640,2478],{"class":1129},[918,2642,2643],{"class":928},".sessions[name] ",[918,2645,987],{"class":924},[918,2647,2648],{"class":928}," session\n",[918,2650,2652],{"class":920,"line":2651},25,[918,2653,955],{"emptyLinePlaceholder":954},[918,2655,2657],{"class":920,"line":2656},26,[918,2658,2659],{"class":977},"        # 获取该 Server 的工具列表\n",[918,2661,2663,2666,2668,2670],{"class":920,"line":2662},27,[918,2664,2665],{"class":928},"        tools_result ",[918,2667,987],{"class":924},[918,2669,1454],{"class":924},[918,2671,1457],{"class":928},[918,2673,2675,2678,2680,2682],{"class":920,"line":2674},28,[918,2676,2677],{"class":924},"        for",[918,2679,1469],{"class":928},[918,2681,1472],{"class":924},[918,2683,1475],{"class":928},[918,2685,2687,2690],{"class":920,"line":2686},29,[918,2688,2689],{"class":1129},"            self",[918,2691,2692],{"class":928},".available_tools.append({\n",[918,2694,2696,2699],{"class":920,"line":2695},30,[918,2697,2698],{"class":1002},"                \"name\"",[918,2700,2701],{"class":928},": tool.name,\n",[918,2703,2705,2708],{"class":920,"line":2704},31,[918,2706,2707],{"class":1002},"                \"description\"",[918,2709,2710],{"class":928},": tool.description,\n",[918,2712,2714,2717],{"class":920,"line":2713},32,[918,2715,2716],{"class":1002},"                \"input_schema\"",[918,2718,2719],{"class":928},": tool.inputSchema,\n",[918,2721,2723,2726,2729],{"class":920,"line":2722},33,[918,2724,2725],{"class":1002},"                \"_server\"",[918,2727,2728],{"class":928},": name,  ",[918,2730,2731],{"class":977},"# 记录工具所属的 Server\n",[918,2733,2735],{"class":920,"line":2734},34,[918,2736,2737],{"class":928},"            })\n",[918,2739,2741],{"class":920,"line":2740},35,[918,2742,955],{"emptyLinePlaceholder":954},[918,2744,2746,2748,2750,2752,2755,2757,2760,2762,2765,2768,2771,2773,2776],{"class":920,"line":2745},36,[918,2747,1480],{"class":1129},[918,2749,1133],{"class":928},[918,2751,1485],{"class":924},[918,2753,2754],{"class":1002},"\"已连接 Server '",[918,2756,1034],{"class":1129},[918,2758,2759],{"class":928},"name",[918,2761,1496],{"class":1129},[918,2763,2764],{"class":1002},"'，发现 ",[918,2766,2767],{"class":1129},"{len",[918,2769,2770],{"class":928},"(tools_result.tools)",[918,2772,1496],{"class":1129},[918,2774,2775],{"class":1002}," 个工具\"",[918,2777,1139],{"class":928},[918,2779,2781],{"class":920,"line":2780},37,[918,2782,955],{"emptyLinePlaceholder":954},[918,2784,2786,2788,2791,2794,2797],{"class":920,"line":2785},38,[918,2787,2467],{"class":924},[918,2789,2790],{"class":967}," _get_claude_tools",[918,2792,2793],{"class":928},"(self) -> list[",[918,2795,2796],{"class":1129},"dict",[918,2798,2799],{"class":928},"]:\n",[918,2801,2803],{"class":920,"line":2802},39,[918,2804,2805],{"class":1002},"        \"\"\"将 MCP 工具格式转换为 Claude API 的 tools 格式\"\"\"\n",[918,2807,2809,2812],{"class":920,"line":2808},40,[918,2810,2811],{"class":924},"        return",[918,2813,2814],{"class":928}," [\n",[918,2816,2818],{"class":920,"line":2817},41,[918,2819,2820],{"class":928},"            {\n",[918,2822,2824,2826,2829,2832],{"class":920,"line":2823},42,[918,2825,2698],{"class":1002},[918,2827,2828],{"class":928},": tool[",[918,2830,2831],{"class":1002},"\"name\"",[918,2833,1023],{"class":928},[918,2835,2837,2839,2841,2844],{"class":920,"line":2836},43,[918,2838,2707],{"class":1002},[918,2840,2828],{"class":928},[918,2842,2843],{"class":1002},"\"description\"",[918,2845,1023],{"class":928},[918,2847,2849,2851,2853,2856],{"class":920,"line":2848},44,[918,2850,2716],{"class":1002},[918,2852,2828],{"class":928},[918,2854,2855],{"class":1002},"\"input_schema\"",[918,2857,1023],{"class":928},[918,2859,2861],{"class":920,"line":2860},45,[918,2862,2863],{"class":928},"            }\n",[918,2865,2867,2870,2872,2874,2877],{"class":920,"line":2866},46,[918,2868,2869],{"class":924},"            for",[918,2871,1469],{"class":928},[918,2873,1472],{"class":924},[918,2875,2876],{"class":1129}," self",[918,2878,2879],{"class":928},".available_tools\n",[918,2881,2883],{"class":920,"line":2882},47,[918,2884,2885],{"class":928},"        ]\n",[918,2887,2889],{"class":920,"line":2888},48,[918,2890,955],{"emptyLinePlaceholder":954},[918,2892,2894,2896,2899,2902,2904,2907,2909],{"class":920,"line":2893},49,[918,2895,2467],{"class":924},[918,2897,2898],{"class":967}," _find_server_for_tool",[918,2900,2901],{"class":928},"(self, tool_name: ",[918,2903,2496],{"class":1129},[918,2905,2906],{"class":928},") -> ",[918,2908,2496],{"class":1129},[918,2910,2453],{"class":928},[918,2912,2914],{"class":920,"line":2913},50,[918,2915,2916],{"class":1002},"        \"\"\"查找工具所属的 Server\"\"\"\n",[918,2918,2920,2922,2924,2926,2928],{"class":920,"line":2919},51,[918,2921,2677],{"class":924},[918,2923,1469],{"class":928},[918,2925,1472],{"class":924},[918,2927,2876],{"class":1129},[918,2929,2930],{"class":928},".available_tools:\n",[918,2932,2934,2937,2940,2942,2944,2947],{"class":920,"line":2933},52,[918,2935,2936],{"class":924},"            if",[918,2938,2939],{"class":928}," tool[",[918,2941,2831],{"class":1002},[918,2943,2369],{"class":928},[918,2945,2946],{"class":924},"==",[918,2948,2949],{"class":928}," tool_name:\n",[918,2951,2953,2956,2958,2961],{"class":920,"line":2952},53,[918,2954,2955],{"class":924},"                return",[918,2957,2939],{"class":928},[918,2959,2960],{"class":1002},"\"_server\"",[918,2962,2963],{"class":928},"]\n",[918,2965,2967,2970,2973,2975,2977,2980,2982,2985,2987,2989],{"class":920,"line":2966},54,[918,2968,2969],{"class":924},"        raise",[918,2971,2972],{"class":1129}," ValueError",[918,2974,1133],{"class":928},[918,2976,1485],{"class":924},[918,2978,2979],{"class":1002},"\"未找到工具: ",[918,2981,1034],{"class":1129},[918,2983,2984],{"class":928},"tool_name",[918,2986,1496],{"class":1129},[918,2988,1499],{"class":1002},[918,2990,1139],{"class":928},[918,2992,2994],{"class":920,"line":2993},55,[918,2995,955],{"emptyLinePlaceholder":954},[918,2997,2999,3001,3003,3006,3009,3011,3013,3015],{"class":920,"line":2998},56,[918,3000,1069],{"class":924},[918,3002,964],{"class":924},[918,3004,3005],{"class":967}," chat",[918,3007,3008],{"class":928},"(self, user_message: ",[918,3010,2496],{"class":1129},[918,3012,2906],{"class":928},[918,3014,2496],{"class":1129},[918,3016,2453],{"class":928},[918,3018,3020],{"class":920,"line":3019},57,[918,3021,3022],{"class":1002},"        \"\"\"处理用户消息，支持工具调用\"\"\"\n",[918,3024,3026,3029,3031,3034,3037,3039,3042,3045,3048],{"class":920,"line":3025},58,[918,3027,3028],{"class":928},"        messages ",[918,3030,987],{"class":924},[918,3032,3033],{"class":928}," [{",[918,3035,3036],{"class":1002},"\"role\"",[918,3038,1040],{"class":928},[918,3040,3041],{"class":1002},"\"user\"",[918,3043,3044],{"class":928},", ",[918,3046,3047],{"class":1002},"\"content\"",[918,3049,3050],{"class":928},": user_message}]\n",[918,3052,3054],{"class":920,"line":3053},59,[918,3055,955],{"emptyLinePlaceholder":954},[918,3057,3059,3062,3065],{"class":920,"line":3058},60,[918,3060,3061],{"class":924},"        while",[918,3063,3064],{"class":1129}," True",[918,3066,2453],{"class":928},[918,3068,3070],{"class":920,"line":3069},61,[918,3071,3072],{"class":977},"            # 调用 Claude API\n",[918,3074,3076,3079,3081,3083],{"class":920,"line":3075},62,[918,3077,3078],{"class":928},"            response ",[918,3080,987],{"class":924},[918,3082,2876],{"class":1129},[918,3084,3085],{"class":928},".anthropic.messages.create(\n",[918,3087,3089,3092,3094,3097],{"class":920,"line":3088},63,[918,3090,3091],{"class":996},"                model",[918,3093,987],{"class":924},[918,3095,3096],{"class":1002},"\"claude-sonnet-4-20250514\"",[918,3098,1006],{"class":928},[918,3100,3102,3105,3107,3110],{"class":920,"line":3101},64,[918,3103,3104],{"class":996},"                max_tokens",[918,3106,987],{"class":924},[918,3108,3109],{"class":1129},"4096",[918,3111,1006],{"class":928},[918,3113,3115,3118,3120,3123],{"class":920,"line":3114},65,[918,3116,3117],{"class":996},"                tools",[918,3119,987],{"class":924},[918,3121,3122],{"class":1129},"self",[918,3124,3125],{"class":928},"._get_claude_tools(),\n",[918,3127,3129,3132,3134],{"class":920,"line":3128},66,[918,3130,3131],{"class":996},"                messages",[918,3133,987],{"class":924},[918,3135,3136],{"class":928},"messages,\n",[918,3138,3140],{"class":920,"line":3139},67,[918,3141,3142],{"class":928},"            )\n",[918,3144,3146],{"class":920,"line":3145},68,[918,3147,955],{"emptyLinePlaceholder":954},[918,3149,3151],{"class":920,"line":3150},69,[918,3152,3153],{"class":977},"            # 检查是否需要调用工具\n",[918,3155,3157,3159,3162,3164,3167],{"class":920,"line":3156},70,[918,3158,2936],{"class":924},[918,3160,3161],{"class":928}," response.stop_reason ",[918,3163,2946],{"class":924},[918,3165,3166],{"class":1002}," \"tool_use\"",[918,3168,2453],{"class":928},[918,3170,3172],{"class":920,"line":3171},71,[918,3173,3174],{"class":977},"                # 提取工具调用请求\n",[918,3176,3178,3181,3183],{"class":920,"line":3177},72,[918,3179,3180],{"class":928},"                assistant_content ",[918,3182,987],{"class":924},[918,3184,3185],{"class":928}," response.content\n",[918,3187,3189,3192,3194,3196,3199,3201,3203],{"class":920,"line":3188},73,[918,3190,3191],{"class":928},"                messages.append({",[918,3193,3036],{"class":1002},[918,3195,1040],{"class":928},[918,3197,3198],{"class":1002},"\"assistant\"",[918,3200,3044],{"class":928},[918,3202,3047],{"class":1002},[918,3204,3205],{"class":928},": assistant_content})\n",[918,3207,3209],{"class":920,"line":3208},74,[918,3210,955],{"emptyLinePlaceholder":954},[918,3212,3214,3217,3219],{"class":920,"line":3213},75,[918,3215,3216],{"class":928},"                tool_results ",[918,3218,987],{"class":924},[918,3220,2516],{"class":928},[918,3222,3224,3227,3230,3232],{"class":920,"line":3223},76,[918,3225,3226],{"class":924},"                for",[918,3228,3229],{"class":928}," block ",[918,3231,1472],{"class":924},[918,3233,3234],{"class":928}," assistant_content:\n",[918,3236,3238,3241,3244,3246,3248],{"class":920,"line":3237},77,[918,3239,3240],{"class":924},"                    if",[918,3242,3243],{"class":928}," block.type ",[918,3245,2946],{"class":924},[918,3247,3166],{"class":1002},[918,3249,2453],{"class":928},[918,3251,3253],{"class":920,"line":3252},78,[918,3254,3255],{"class":977},"                        # 通过 MCP 调用工具\n",[918,3257,3259,3262,3264,3266],{"class":920,"line":3258},79,[918,3260,3261],{"class":928},"                        server_name ",[918,3263,987],{"class":924},[918,3265,2876],{"class":1129},[918,3267,3268],{"class":928},"._find_server_for_tool(block.name)\n",[918,3270,3272,3275,3277,3279],{"class":920,"line":3271},80,[918,3273,3274],{"class":928},"                        session ",[918,3276,987],{"class":924},[918,3278,2876],{"class":1129},[918,3280,3281],{"class":928},".sessions[server_name]\n",[918,3283,3285],{"class":920,"line":3284},81,[918,3286,955],{"emptyLinePlaceholder":954},[918,3288,3290,3293,3295,3297],{"class":920,"line":3289},82,[918,3291,3292],{"class":928},"                        result ",[918,3294,987],{"class":924},[918,3296,1454],{"class":924},[918,3298,1840],{"class":928},[918,3300,3302,3305,3307],{"class":920,"line":3301},83,[918,3303,3304],{"class":996},"                            name",[918,3306,987],{"class":924},[918,3308,3309],{"class":928},"block.name,\n",[918,3311,3313,3316,3318],{"class":920,"line":3312},84,[918,3314,3315],{"class":996},"                            arguments",[918,3317,987],{"class":924},[918,3319,3320],{"class":928},"block.input,\n",[918,3322,3324],{"class":920,"line":3323},85,[918,3325,3326],{"class":928},"                        )\n",[918,3328,3330],{"class":920,"line":3329},86,[918,3331,955],{"emptyLinePlaceholder":954},[918,3333,3335],{"class":920,"line":3334},87,[918,3336,3337],{"class":928},"                        tool_results.append({\n",[918,3339,3341,3344,3346,3349],{"class":920,"line":3340},88,[918,3342,3343],{"class":1002},"                            \"type\"",[918,3345,1040],{"class":928},[918,3347,3348],{"class":1002},"\"tool_result\"",[918,3350,1006],{"class":928},[918,3352,3354,3357],{"class":920,"line":3353},89,[918,3355,3356],{"class":1002},"                            \"tool_use_id\"",[918,3358,3359],{"class":928},": block.id,\n",[918,3361,3363,3366,3369,3372],{"class":920,"line":3362},90,[918,3364,3365],{"class":1002},"                            \"content\"",[918,3367,3368],{"class":928},": result.content[",[918,3370,3371],{"class":1129},"0",[918,3373,3374],{"class":928},"].text\n",[918,3376,3378,3381,3384,3387,3390],{"class":920,"line":3377},91,[918,3379,3380],{"class":924},"                                if",[918,3382,3383],{"class":928}," result.content ",[918,3385,3386],{"class":924},"else",[918,3388,3389],{"class":1002}," \"无结果\"",[918,3391,1006],{"class":928},[918,3393,3395],{"class":920,"line":3394},92,[918,3396,3397],{"class":928},"                        })\n",[918,3399,3401],{"class":920,"line":3400},93,[918,3402,955],{"emptyLinePlaceholder":954},[918,3404,3406,3408,3410,3412,3414,3416,3418],{"class":920,"line":3405},94,[918,3407,3191],{"class":928},[918,3409,3036],{"class":1002},[918,3411,1040],{"class":928},[918,3413,3041],{"class":1002},[918,3415,3044],{"class":928},[918,3417,3047],{"class":1002},[918,3419,3420],{"class":928},": tool_results})\n",[918,3422,3424,3427],{"class":920,"line":3423},95,[918,3425,3426],{"class":924},"            else",[918,3428,2453],{"class":928},[918,3430,3432],{"class":920,"line":3431},96,[918,3433,3434],{"class":977},"                # 模型直接返回了文本回复\n",[918,3436,3438,3441,3443],{"class":920,"line":3437},97,[918,3439,3440],{"class":928},"                final_text ",[918,3442,987],{"class":924},[918,3444,3445],{"class":1002}," \"\"\n",[918,3447,3449,3451,3453,3455],{"class":920,"line":3448},98,[918,3450,3226],{"class":924},[918,3452,3229],{"class":928},[918,3454,1472],{"class":924},[918,3456,3457],{"class":928}," response.content:\n",[918,3459,3461,3463,3466,3469,3472],{"class":920,"line":3460},99,[918,3462,3240],{"class":924},[918,3464,3465],{"class":1129}," hasattr",[918,3467,3468],{"class":928},"(block, ",[918,3470,3471],{"class":1002},"\"text\"",[918,3473,3474],{"class":928},"):\n",[918,3476,3478,3481,3484],{"class":920,"line":3477},100,[918,3479,3480],{"class":928},"                        final_text ",[918,3482,3483],{"class":924},"+=",[918,3485,3486],{"class":928}," block.text\n",[918,3488,3490,3492],{"class":920,"line":3489},101,[918,3491,2955],{"class":924},[918,3493,3494],{"class":928}," final_text\n",[918,3496,3498],{"class":920,"line":3497},102,[918,3499,955],{"emptyLinePlaceholder":954},[918,3501,3503,3505,3507,3509],{"class":920,"line":3502},103,[918,3504,961],{"class":924},[918,3506,964],{"class":924},[918,3508,968],{"class":967},[918,3510,971],{"class":928},[918,3512,3514,3517,3519],{"class":920,"line":3513},104,[918,3515,3516],{"class":928},"    app ",[918,3518,987],{"class":924},[918,3520,3521],{"class":928}," MCPChatApp()\n",[918,3523,3525],{"class":920,"line":3524},105,[918,3526,955],{"emptyLinePlaceholder":954},[918,3528,3530],{"class":920,"line":3529},106,[918,3531,3532],{"class":977},"    # 连接 MCP Server\n",[918,3534,3536,3538],{"class":920,"line":3535},107,[918,3537,1433],{"class":924},[918,3539,3540],{"class":928}," app.connect_server(\n",[918,3542,3544,3546,3548,3551],{"class":920,"line":3543},108,[918,3545,1845],{"class":996},[918,3547,987],{"class":924},[918,3549,3550],{"class":1002},"\"filesystem\"",[918,3552,1006],{"class":928},[918,3554,3556,3558,3560,3562],{"class":920,"line":3555},109,[918,3557,997],{"class":996},[918,3559,987],{"class":924},[918,3561,1003],{"class":1002},[918,3563,1006],{"class":928},[918,3565,3567,3569,3571,3573,3576],{"class":920,"line":3566},110,[918,3568,1012],{"class":996},[918,3570,987],{"class":924},[918,3572,1017],{"class":928},[918,3574,3575],{"class":1002},"\"filesystem_server.py\"",[918,3577,1023],{"class":928},[918,3579,3581],{"class":920,"line":3580},111,[918,3582,1052],{"class":928},[918,3584,3586],{"class":920,"line":3585},112,[918,3587,955],{"emptyLinePlaceholder":954},[918,3589,3591],{"class":920,"line":3590},113,[918,3592,3593],{"class":977},"    # 进行对话\n",[918,3595,3597,3600,3602,3604,3607,3610],{"class":920,"line":3596},114,[918,3598,3599],{"class":928},"    response ",[918,3601,987],{"class":924},[918,3603,1454],{"class":924},[918,3605,3606],{"class":928}," app.chat(",[918,3608,3609],{"class":1002},"\"请列出 Documents 目录下的所有文件\"",[918,3611,1139],{"class":928},[918,3613,3615,3618],{"class":920,"line":3614},115,[918,3616,3617],{"class":1129},"    print",[918,3619,3620],{"class":928},"(response)\n",[918,3622,3624],{"class":920,"line":3623},116,[918,3625,955],{"emptyLinePlaceholder":954},[918,3627,3629,3632,3635,3638,3641],{"class":920,"line":3628},117,[918,3630,3631],{"class":924},"if",[918,3633,3634],{"class":1129}," __name__",[918,3636,3637],{"class":924}," ==",[918,3639,3640],{"class":1002}," \"__main__\"",[918,3642,2453],{"class":928},[918,3644,3646],{"class":920,"line":3645},118,[918,3647,3648],{"class":928},"    asyncio.run(main())\n",[3650,3651,3652],"warning",{},"\n上面的示例为了简洁省略了连接生命周期管理。在生产环境中，你需要正确处理连接的创建和销毁，建议使用 async context manager 来管理。\n",[892,3654,3655],{"id":3655},"配置文件格式",[896,3657,3658],{},"大多数支持 MCP 的应用（如 Claude Desktop）使用 JSON 配置文件来管理 MCP Server 连接。以下是配置文件的完整格式说明：",[904,3660,3662],{"id":3661},"claude_desktop_configjson","claude_desktop_config.json",[909,3664,3668],{"className":3665,"code":3666,"language":3667,"meta":11,"style":11},"language-json shiki shiki-themes github-light github-light github-dark","{\n  \"mcpServers\": {\n    \"server-name\": {\n      \"command\": \"可执行命令\",\n      \"args\": [\"参数1\", \"参数2\"],\n      \"env\": {\n        \"ENV_VAR\": \"值\"\n      }\n    }\n  }\n}\n","json",[915,3669,3670,3674,3682,3689,3701,3719,3726,3736,3741,3746,3750],{"__ignoreMap":11},[918,3671,3672],{"class":920,"line":921},[918,3673,1862],{"class":928},[918,3675,3676,3679],{"class":920,"line":938},[918,3677,3678],{"class":1129},"  \"mcpServers\"",[918,3680,3681],{"class":928},": {\n",[918,3683,3684,3687],{"class":920,"line":951},[918,3685,3686],{"class":1129},"    \"server-name\"",[918,3688,3681],{"class":928},[918,3690,3691,3694,3696,3699],{"class":920,"line":958},[918,3692,3693],{"class":1129},"      \"command\"",[918,3695,1040],{"class":928},[918,3697,3698],{"class":1002},"\"可执行命令\"",[918,3700,1006],{"class":928},[918,3702,3703,3706,3709,3712,3714,3717],{"class":920,"line":974},[918,3704,3705],{"class":1129},"      \"args\"",[918,3707,3708],{"class":928},": [",[918,3710,3711],{"class":1002},"\"参数1\"",[918,3713,3044],{"class":928},[918,3715,3716],{"class":1002},"\"参数2\"",[918,3718,1023],{"class":928},[918,3720,3721,3724],{"class":920,"line":981},[918,3722,3723],{"class":1129},"      \"env\"",[918,3725,3681],{"class":928},[918,3727,3728,3731,3733],{"class":920,"line":993},[918,3729,3730],{"class":1129},"        \"ENV_VAR\"",[918,3732,1040],{"class":928},[918,3734,3735],{"class":1002},"\"值\"\n",[918,3737,3738],{"class":920,"line":1009},[918,3739,3740],{"class":928},"      }\n",[918,3742,3743],{"class":920,"line":1026},[918,3744,3745],{"class":928},"    }\n",[918,3747,3748],{"class":920,"line":1049},[918,3749,2086],{"class":928},[918,3751,3752],{"class":920,"line":1055},[918,3753,2091],{"class":928},[896,3755,3756],{},"各字段说明：",[3758,3759,3760,3779],"table",{},[3761,3762,3763],"thead",{},[3764,3765,3766,3770,3773,3776],"tr",{},[3767,3768,3769],"th",{},"字段",[3767,3771,3772],{},"类型",[3767,3774,3775],{},"必填",[3767,3777,3778],{},"说明",[3780,3781,3782,3798,3814,3829],"tbody",{},[3764,3783,3784,3789,3792,3795],{},[3785,3786,3787],"td",{},[915,3788,2565],{},[3785,3790,3791],{},"string",[3785,3793,3794],{},"是（stdio）",[3785,3796,3797],{},"启动 Server 的命令",[3764,3799,3800,3804,3808,3811],{},[3785,3801,3802],{},[915,3803,2573],{},[3785,3805,3791,3806],{},[918,3807],{},[3785,3809,3810],{},"否",[3785,3812,3813],{},"命令行参数",[3764,3815,3816,3821,3824,3826],{},[3785,3817,3818],{},[915,3819,3820],{},"env",[3785,3822,3823],{},"object",[3785,3825,3810],{},[3785,3827,3828],{},"环境变量",[3764,3830,3831,3836,3838,3841],{},[3785,3832,3833],{},[915,3834,3835],{},"url",[3785,3837,3791],{},[3785,3839,3840],{},"是（HTTP）",[3785,3842,3843],{},"远程 Server 的 URL",[904,3845,3846],{"id":3846},"常见配置示例",[909,3848,3850],{"className":3665,"code":3849,"language":3667,"meta":11,"style":11},"{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol\u002Fserver-filesystem\", \"\u002FUsers\u002Fme\u002Fdocs\"]\n    },\n    \"github\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol\u002Fserver-github\"],\n      \"env\": {\n        \"GITHUB_PERSONAL_ACCESS_TOKEN\": \"ghp_xxxxxxxxxxxx\"\n      }\n    },\n    \"postgres\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"@modelcontextprotocol\u002Fserver-postgres\",\n        \"postgresql:\u002F\u002Fuser:pass@localhost\u002Fmydb\"\n      ]\n    },\n    \"custom-python-server\": {\n      \"command\": \"python\",\n      \"args\": [\"\u002Fpath\u002Fto\u002Fmy_server.py\"]\n    },\n    \"remote-server\": {\n      \"url\": \"http:\u002F\u002Fmcp.example.com:8080\u002Fmcp\"\n    }\n  }\n}\n",[915,3851,3852,3856,3862,3869,3880,3901,3906,3913,3923,3938,3944,3954,3958,3962,3969,3979,3986,3993,4000,4005,4010,4014,4021,4031,4042,4046,4053,4063,4067,4071],{"__ignoreMap":11},[918,3853,3854],{"class":920,"line":921},[918,3855,1862],{"class":928},[918,3857,3858,3860],{"class":920,"line":938},[918,3859,3678],{"class":1129},[918,3861,3681],{"class":928},[918,3863,3864,3867],{"class":920,"line":951},[918,3865,3866],{"class":1129},"    \"filesystem\"",[918,3868,3681],{"class":928},[918,3870,3871,3873,3875,3878],{"class":920,"line":958},[918,3872,3693],{"class":1129},[918,3874,1040],{"class":928},[918,3876,3877],{"class":1002},"\"npx\"",[918,3879,1006],{"class":928},[918,3881,3882,3884,3886,3889,3891,3894,3896,3899],{"class":920,"line":974},[918,3883,3705],{"class":1129},[918,3885,3708],{"class":928},[918,3887,3888],{"class":1002},"\"-y\"",[918,3890,3044],{"class":928},[918,3892,3893],{"class":1002},"\"@modelcontextprotocol\u002Fserver-filesystem\"",[918,3895,3044],{"class":928},[918,3897,3898],{"class":1002},"\"\u002FUsers\u002Fme\u002Fdocs\"",[918,3900,2963],{"class":928},[918,3902,3903],{"class":920,"line":981},[918,3904,3905],{"class":928},"    },\n",[918,3907,3908,3911],{"class":920,"line":993},[918,3909,3910],{"class":1129},"    \"github\"",[918,3912,3681],{"class":928},[918,3914,3915,3917,3919,3921],{"class":920,"line":1009},[918,3916,3693],{"class":1129},[918,3918,1040],{"class":928},[918,3920,3877],{"class":1002},[918,3922,1006],{"class":928},[918,3924,3925,3927,3929,3931,3933,3936],{"class":920,"line":1026},[918,3926,3705],{"class":1129},[918,3928,3708],{"class":928},[918,3930,3888],{"class":1002},[918,3932,3044],{"class":928},[918,3934,3935],{"class":1002},"\"@modelcontextprotocol\u002Fserver-github\"",[918,3937,1023],{"class":928},[918,3939,3940,3942],{"class":920,"line":1049},[918,3941,3723],{"class":1129},[918,3943,3681],{"class":928},[918,3945,3946,3949,3951],{"class":920,"line":1055},[918,3947,3948],{"class":1129},"        \"GITHUB_PERSONAL_ACCESS_TOKEN\"",[918,3950,1040],{"class":928},[918,3952,3953],{"class":1002},"\"ghp_xxxxxxxxxxxx\"\n",[918,3955,3956],{"class":920,"line":1060},[918,3957,3740],{"class":928},[918,3959,3960],{"class":920,"line":1066},[918,3961,3905],{"class":928},[918,3963,3964,3967],{"class":920,"line":1084},[918,3965,3966],{"class":1129},"    \"postgres\"",[918,3968,3681],{"class":928},[918,3970,3971,3973,3975,3977],{"class":920,"line":1100},[918,3972,3693],{"class":1129},[918,3974,1040],{"class":928},[918,3976,3877],{"class":1002},[918,3978,1006],{"class":928},[918,3980,3981,3983],{"class":920,"line":1106},[918,3982,3705],{"class":1129},[918,3984,3985],{"class":928},": [\n",[918,3987,3988,3991],{"class":920,"line":1115},[918,3989,3990],{"class":1002},"        \"-y\"",[918,3992,1006],{"class":928},[918,3994,3995,3998],{"class":920,"line":1120},[918,3996,3997],{"class":1002},"        \"@modelcontextprotocol\u002Fserver-postgres\"",[918,3999,1006],{"class":928},[918,4001,4002],{"class":920,"line":1126},[918,4003,4004],{"class":1002},"        \"postgresql:\u002F\u002Fuser:pass@localhost\u002Fmydb\"\n",[918,4006,4007],{"class":920,"line":2590},[918,4008,4009],{"class":928},"      ]\n",[918,4011,4012],{"class":920,"line":2608},[918,4013,3905],{"class":928},[918,4015,4016,4019],{"class":920,"line":2625},[918,4017,4018],{"class":1129},"    \"custom-python-server\"",[918,4020,3681],{"class":928},[918,4022,4023,4025,4027,4029],{"class":920,"line":2633},[918,4024,3693],{"class":1129},[918,4026,1040],{"class":928},[918,4028,1003],{"class":1002},[918,4030,1006],{"class":928},[918,4032,4033,4035,4037,4040],{"class":920,"line":2638},[918,4034,3705],{"class":1129},[918,4036,3708],{"class":928},[918,4038,4039],{"class":1002},"\"\u002Fpath\u002Fto\u002Fmy_server.py\"",[918,4041,2963],{"class":928},[918,4043,4044],{"class":920,"line":2651},[918,4045,3905],{"class":928},[918,4047,4048,4051],{"class":920,"line":2656},[918,4049,4050],{"class":1129},"    \"remote-server\"",[918,4052,3681],{"class":928},[918,4054,4055,4058,4060],{"class":920,"line":2662},[918,4056,4057],{"class":1129},"      \"url\"",[918,4059,1040],{"class":928},[918,4061,4062],{"class":1002},"\"http:\u002F\u002Fmcp.example.com:8080\u002Fmcp\"\n",[918,4064,4065],{"class":920,"line":2674},[918,4066,3745],{"class":928},[918,4068,4069],{"class":920,"line":2686},[918,4070,2086],{"class":928},[918,4072,4073],{"class":920,"line":2695},[918,4074,2091],{"class":928},[4076,4077,4078],"tip",{},"\n配置文件中的环境变量建议使用系统的 keychain 或 secrets manager 来管理，避免在配置文件中明文存储密码和 Token。\n",[892,4080,4081],{"id":4081},"错误处理",[896,4083,4084],{},"在与 MCP Server 交互时，可能遇到多种错误情况。良好的错误处理对于构建健壮的 AI 应用至关重要：",[904,4086,4087],{"id":4087},"连接错误",[909,4089,4091],{"className":911,"code":4090,"language":913,"meta":11,"style":11},"from mcp.client.stdio import stdio_client\nimport asyncio\n\nasync def safe_connect(server_params):\n    try:\n        async with stdio_client(server_params) as (read, write):\n            async with ClientSession(read, write) as session:\n                await session.initialize()\n                return session\n    except FileNotFoundError:\n        print(f\"错误：找不到命令 '{server_params.command}'\")\n        print(\"请确认 Server 程序已安装且路径正确\")\n    except ConnectionError as e:\n        print(f\"连接失败: {e}\")\n    except TimeoutError:\n        print(\"连接超时，请检查 Server 是否正常运行\")\n",[915,4092,4093,4103,4109,4113,4125,4132,4144,4157,4164,4170,4180,4203,4214,4227,4249,4258],{"__ignoreMap":11},[918,4094,4095,4097,4099,4101],{"class":920,"line":921},[918,4096,925],{"class":924},[918,4098,943],{"class":928},[918,4100,932],{"class":924},[918,4102,948],{"class":928},[918,4104,4105,4107],{"class":920,"line":938},[918,4106,932],{"class":924},[918,4108,2399],{"class":928},[918,4110,4111],{"class":920,"line":951},[918,4112,955],{"emptyLinePlaceholder":954},[918,4114,4115,4117,4119,4122],{"class":920,"line":958},[918,4116,961],{"class":924},[918,4118,964],{"class":924},[918,4120,4121],{"class":967}," safe_connect",[918,4123,4124],{"class":928},"(server_params):\n",[918,4126,4127,4130],{"class":920,"line":974},[918,4128,4129],{"class":924},"    try",[918,4131,2453],{"class":928},[918,4133,4134,4136,4138,4140,4142],{"class":920,"line":981},[918,4135,1087],{"class":924},[918,4137,1072],{"class":924},[918,4139,1075],{"class":928},[918,4141,1078],{"class":924},[918,4143,1081],{"class":928},[918,4145,4146,4149,4151,4153,4155],{"class":920,"line":993},[918,4147,4148],{"class":924},"            async",[918,4150,1072],{"class":924},[918,4152,1092],{"class":928},[918,4154,1078],{"class":924},[918,4156,1097],{"class":928},[918,4158,4159,4162],{"class":920,"line":1009},[918,4160,4161],{"class":924},"                await",[918,4163,1112],{"class":928},[918,4165,4166,4168],{"class":920,"line":1026},[918,4167,2955],{"class":924},[918,4169,2648],{"class":928},[918,4171,4172,4175,4178],{"class":920,"line":1049},[918,4173,4174],{"class":924},"    except",[918,4176,4177],{"class":1129}," FileNotFoundError",[918,4179,2453],{"class":928},[918,4181,4182,4184,4186,4188,4191,4193,4196,4198,4201],{"class":920,"line":1055},[918,4183,1480],{"class":1129},[918,4185,1133],{"class":928},[918,4187,1485],{"class":924},[918,4189,4190],{"class":1002},"\"错误：找不到命令 '",[918,4192,1034],{"class":1129},[918,4194,4195],{"class":928},"server_params.command",[918,4197,1496],{"class":1129},[918,4199,4200],{"class":1002},"'\"",[918,4202,1139],{"class":928},[918,4204,4205,4207,4209,4212],{"class":920,"line":1060},[918,4206,1480],{"class":1129},[918,4208,1133],{"class":928},[918,4210,4211],{"class":1002},"\"请确认 Server 程序已安装且路径正确\"",[918,4213,1139],{"class":928},[918,4215,4216,4218,4221,4224],{"class":920,"line":1066},[918,4217,4174],{"class":924},[918,4219,4220],{"class":1129}," ConnectionError",[918,4222,4223],{"class":924}," as",[918,4225,4226],{"class":928}," e:\n",[918,4228,4229,4231,4233,4235,4238,4240,4243,4245,4247],{"class":920,"line":1084},[918,4230,1480],{"class":1129},[918,4232,1133],{"class":928},[918,4234,1485],{"class":924},[918,4236,4237],{"class":1002},"\"连接失败: ",[918,4239,1034],{"class":1129},[918,4241,4242],{"class":928},"e",[918,4244,1496],{"class":1129},[918,4246,1499],{"class":1002},[918,4248,1139],{"class":928},[918,4250,4251,4253,4256],{"class":920,"line":1100},[918,4252,4174],{"class":924},[918,4254,4255],{"class":1129}," TimeoutError",[918,4257,2453],{"class":928},[918,4259,4260,4262,4264,4267],{"class":920,"line":1106},[918,4261,1480],{"class":1129},[918,4263,1133],{"class":928},[918,4265,4266],{"class":1002},"\"连接超时，请检查 Server 是否正常运行\"",[918,4268,1139],{"class":928},[904,4270,4271],{"id":4271},"工具调用错误",[909,4273,4275],{"className":911,"code":4274,"language":913,"meta":11,"style":11},"async def safe_call_tool(session, tool_name, arguments):\n    try:\n        result = await session.call_tool(name=tool_name, arguments=arguments)\n\n        # 检查是否返回了错误\n        if result.isError:\n            print(f\"工具执行失败: {result.content[0].text}\")\n            return None\n\n        return result\n    except Exception as e:\n        print(f\"调用工具 '{tool_name}' 时发生异常: {e}\")\n        return None\n",[915,4276,4277,4289,4295,4322,4326,4331,4338,4365,4373,4377,4384,4395,4425],{"__ignoreMap":11},[918,4278,4279,4281,4283,4286],{"class":920,"line":921},[918,4280,961],{"class":924},[918,4282,964],{"class":924},[918,4284,4285],{"class":967}," safe_call_tool",[918,4287,4288],{"class":928},"(session, tool_name, arguments):\n",[918,4290,4291,4293],{"class":920,"line":938},[918,4292,4129],{"class":924},[918,4294,2453],{"class":928},[918,4296,4297,4300,4302,4304,4307,4309,4311,4314,4317,4319],{"class":920,"line":951},[918,4298,4299],{"class":928},"        result ",[918,4301,987],{"class":924},[918,4303,1454],{"class":924},[918,4305,4306],{"class":928}," session.call_tool(",[918,4308,2759],{"class":996},[918,4310,987],{"class":924},[918,4312,4313],{"class":928},"tool_name, ",[918,4315,4316],{"class":996},"arguments",[918,4318,987],{"class":924},[918,4320,4321],{"class":928},"arguments)\n",[918,4323,4324],{"class":920,"line":958},[918,4325,955],{"emptyLinePlaceholder":954},[918,4327,4328],{"class":920,"line":974},[918,4329,4330],{"class":977},"        # 检查是否返回了错误\n",[918,4332,4333,4335],{"class":920,"line":981},[918,4334,1921],{"class":924},[918,4336,4337],{"class":928}," result.isError:\n",[918,4339,4340,4342,4344,4346,4349,4351,4354,4356,4359,4361,4363],{"class":920,"line":993},[918,4341,1130],{"class":1129},[918,4343,1133],{"class":928},[918,4345,1485],{"class":924},[918,4347,4348],{"class":1002},"\"工具执行失败: ",[918,4350,1034],{"class":1129},[918,4352,4353],{"class":928},"result.content[",[918,4355,3371],{"class":1129},[918,4357,4358],{"class":928},"].text",[918,4360,1496],{"class":1129},[918,4362,1499],{"class":1002},[918,4364,1139],{"class":928},[918,4366,4367,4370],{"class":920,"line":1009},[918,4368,4369],{"class":924},"            return",[918,4371,4372],{"class":1129}," None\n",[918,4374,4375],{"class":920,"line":1026},[918,4376,955],{"emptyLinePlaceholder":954},[918,4378,4379,4381],{"class":920,"line":1049},[918,4380,2811],{"class":924},[918,4382,4383],{"class":928}," result\n",[918,4385,4386,4388,4391,4393],{"class":920,"line":1055},[918,4387,4174],{"class":924},[918,4389,4390],{"class":1129}," Exception",[918,4392,4223],{"class":924},[918,4394,4226],{"class":928},[918,4396,4397,4399,4401,4403,4406,4408,4410,4412,4415,4417,4419,4421,4423],{"class":920,"line":1060},[918,4398,1480],{"class":1129},[918,4400,1133],{"class":928},[918,4402,1485],{"class":924},[918,4404,4405],{"class":1002},"\"调用工具 '",[918,4407,1034],{"class":1129},[918,4409,2984],{"class":928},[918,4411,1496],{"class":1129},[918,4413,4414],{"class":1002},"' 时发生异常: ",[918,4416,1034],{"class":1129},[918,4418,4242],{"class":928},[918,4420,1496],{"class":1129},[918,4422,1499],{"class":1002},[918,4424,1139],{"class":928},[918,4426,4427,4429],{"class":920,"line":1066},[918,4428,2811],{"class":924},[918,4430,4372],{"class":1129},[904,4432,4433],{"id":4433},"重连机制",[909,4435,4437],{"className":911,"code":4436,"language":913,"meta":11,"style":11},"import asyncio\n\nclass ResilientMCPClient:\n    \"\"\"支持自动重连的 MCP Client\"\"\"\n\n    def __init__(self, server_params, max_retries=3):\n        self.server_params = server_params\n        self.max_retries = max_retries\n        self.session = None\n\n    async def ensure_connected(self):\n        \"\"\"确保连接可用，如果断开则自动重连\"\"\"\n        if self.session is not None:\n            return\n\n        for attempt in range(self.max_retries):\n            try:\n                # 建立新连接\n                self._stdio = await stdio_client(\n                    self.server_params\n                ).__aenter__()\n                read, write = self._stdio\n                self.session = await ClientSession(\n                    read, write\n                ).__aenter__()\n                await self.session.initialize()\n                print(f\"连接成功（第 {attempt + 1} 次尝试）\")\n                return\n            except Exception as e:\n                print(f\"连接失败（第 {attempt + 1} 次）: {e}\")\n                if attempt \u003C self.max_retries - 1:\n                    await asyncio.sleep(2 ** attempt)  # 指数退避\n\n        raise ConnectionError(f\"经过 {self.max_retries} 次尝试后仍无法连接\")\n",[915,4438,4439,4445,4449,4458,4463,4467,4483,4495,4507,4518,4522,4533,4538,4557,4562,4566,4585,4592,4597,4612,4620,4629,4641,4654,4659,4667,4676,4704,4709,4720,4752,4774,4794,4798],{"__ignoreMap":11},[918,4440,4441,4443],{"class":920,"line":921},[918,4442,932],{"class":924},[918,4444,2399],{"class":928},[918,4446,4447],{"class":920,"line":938},[918,4448,955],{"emptyLinePlaceholder":954},[918,4450,4451,4453,4456],{"class":920,"line":951},[918,4452,2447],{"class":924},[918,4454,4455],{"class":967}," ResilientMCPClient",[918,4457,2453],{"class":928},[918,4459,4460],{"class":920,"line":958},[918,4461,4462],{"class":1002},"    \"\"\"支持自动重连的 MCP Client\"\"\"\n",[918,4464,4465],{"class":920,"line":974},[918,4466,955],{"emptyLinePlaceholder":954},[918,4468,4469,4471,4473,4476,4478,4481],{"class":920,"line":981},[918,4470,2467],{"class":924},[918,4472,2470],{"class":1129},[918,4474,4475],{"class":928},"(self, server_params, max_retries",[918,4477,987],{"class":924},[918,4479,4480],{"class":1129},"3",[918,4482,3474],{"class":928},[918,4484,4485,4487,4490,4492],{"class":920,"line":993},[918,4486,2478],{"class":1129},[918,4488,4489],{"class":928},".server_params ",[918,4491,987],{"class":924},[918,4493,4494],{"class":928}," server_params\n",[918,4496,4497,4499,4502,4504],{"class":920,"line":1009},[918,4498,2478],{"class":1129},[918,4500,4501],{"class":928},".max_retries ",[918,4503,987],{"class":924},[918,4505,4506],{"class":928}," max_retries\n",[918,4508,4509,4511,4514,4516],{"class":920,"line":1026},[918,4510,2478],{"class":1129},[918,4512,4513],{"class":928},".session ",[918,4515,987],{"class":924},[918,4517,4372],{"class":1129},[918,4519,4520],{"class":920,"line":1049},[918,4521,955],{"emptyLinePlaceholder":954},[918,4523,4524,4526,4528,4531],{"class":920,"line":1055},[918,4525,1069],{"class":924},[918,4527,964],{"class":924},[918,4529,4530],{"class":967}," ensure_connected",[918,4532,2473],{"class":928},[918,4534,4535],{"class":920,"line":1060},[918,4536,4537],{"class":1002},"        \"\"\"确保连接可用，如果断开则自动重连\"\"\"\n",[918,4539,4540,4542,4544,4546,4549,4552,4555],{"class":920,"line":1066},[918,4541,1921],{"class":924},[918,4543,2876],{"class":1129},[918,4545,4513],{"class":928},[918,4547,4548],{"class":924},"is",[918,4550,4551],{"class":924}," not",[918,4553,4554],{"class":1129}," None",[918,4556,2453],{"class":928},[918,4558,4559],{"class":920,"line":1084},[918,4560,4561],{"class":924},"            return\n",[918,4563,4564],{"class":920,"line":1100},[918,4565,955],{"emptyLinePlaceholder":954},[918,4567,4568,4570,4573,4575,4578,4580,4582],{"class":920,"line":1106},[918,4569,2677],{"class":924},[918,4571,4572],{"class":928}," attempt ",[918,4574,1472],{"class":924},[918,4576,4577],{"class":1129}," range",[918,4579,1133],{"class":928},[918,4581,3122],{"class":1129},[918,4583,4584],{"class":928},".max_retries):\n",[918,4586,4587,4590],{"class":920,"line":1115},[918,4588,4589],{"class":924},"            try",[918,4591,2453],{"class":928},[918,4593,4594],{"class":920,"line":1120},[918,4595,4596],{"class":977},"                # 建立新连接\n",[918,4598,4599,4602,4605,4607,4609],{"class":920,"line":1126},[918,4600,4601],{"class":1129},"                self",[918,4603,4604],{"class":928},"._stdio ",[918,4606,987],{"class":924},[918,4608,1454],{"class":924},[918,4610,4611],{"class":928}," stdio_client(\n",[918,4613,4614,4617],{"class":920,"line":2590},[918,4615,4616],{"class":1129},"                    self",[918,4618,4619],{"class":928},".server_params\n",[918,4621,4622,4625,4627],{"class":920,"line":2608},[918,4623,4624],{"class":928},"                ).",[918,4626,2603],{"class":1129},[918,4628,1552],{"class":928},[918,4630,4631,4634,4636,4638],{"class":920,"line":2625},[918,4632,4633],{"class":928},"                read, write ",[918,4635,987],{"class":924},[918,4637,2876],{"class":1129},[918,4639,4640],{"class":928},"._stdio\n",[918,4642,4643,4645,4647,4649,4651],{"class":920,"line":2633},[918,4644,4601],{"class":1129},[918,4646,4513],{"class":928},[918,4648,987],{"class":924},[918,4650,1454],{"class":924},[918,4652,4653],{"class":928}," ClientSession(\n",[918,4655,4656],{"class":920,"line":2638},[918,4657,4658],{"class":928},"                    read, write\n",[918,4660,4661,4663,4665],{"class":920,"line":2651},[918,4662,4624],{"class":928},[918,4664,2603],{"class":1129},[918,4666,1552],{"class":928},[918,4668,4669,4671,4673],{"class":920,"line":2656},[918,4670,4161],{"class":924},[918,4672,2876],{"class":1129},[918,4674,4675],{"class":928},".session.initialize()\n",[918,4677,4678,4681,4683,4685,4688,4690,4693,4696,4699,4702],{"class":920,"line":2662},[918,4679,4680],{"class":1129},"                print",[918,4682,1133],{"class":928},[918,4684,1485],{"class":924},[918,4686,4687],{"class":1002},"\"连接成功（第 ",[918,4689,1034],{"class":1129},[918,4691,4692],{"class":928},"attempt ",[918,4694,4695],{"class":924},"+",[918,4697,4698],{"class":1129}," 1}",[918,4700,4701],{"class":1002}," 次尝试）\"",[918,4703,1139],{"class":928},[918,4705,4706],{"class":920,"line":2674},[918,4707,4708],{"class":924},"                return\n",[918,4710,4711,4714,4716,4718],{"class":920,"line":2686},[918,4712,4713],{"class":924},"            except",[918,4715,4390],{"class":1129},[918,4717,4223],{"class":924},[918,4719,4226],{"class":928},[918,4721,4722,4724,4726,4728,4731,4733,4735,4737,4739,4742,4744,4746,4748,4750],{"class":920,"line":2695},[918,4723,4680],{"class":1129},[918,4725,1133],{"class":928},[918,4727,1485],{"class":924},[918,4729,4730],{"class":1002},"\"连接失败（第 ",[918,4732,1034],{"class":1129},[918,4734,4692],{"class":928},[918,4736,4695],{"class":924},[918,4738,4698],{"class":1129},[918,4740,4741],{"class":1002}," 次）: ",[918,4743,1034],{"class":1129},[918,4745,4242],{"class":928},[918,4747,1496],{"class":1129},[918,4749,1499],{"class":1002},[918,4751,1139],{"class":928},[918,4753,4754,4757,4759,4762,4764,4766,4769,4772],{"class":920,"line":2704},[918,4755,4756],{"class":924},"                if",[918,4758,4572],{"class":928},[918,4760,4761],{"class":924},"\u003C",[918,4763,2876],{"class":1129},[918,4765,4501],{"class":928},[918,4767,4768],{"class":924},"-",[918,4770,4771],{"class":1129}," 1",[918,4773,2453],{"class":928},[918,4775,4776,4779,4782,4785,4788,4791],{"class":920,"line":2713},[918,4777,4778],{"class":924},"                    await",[918,4780,4781],{"class":928}," asyncio.sleep(",[918,4783,4784],{"class":1129},"2",[918,4786,4787],{"class":924}," **",[918,4789,4790],{"class":928}," attempt)  ",[918,4792,4793],{"class":977},"# 指数退避\n",[918,4795,4796],{"class":920,"line":2722},[918,4797,955],{"emptyLinePlaceholder":954},[918,4799,4800,4802,4804,4806,4808,4811,4814,4817,4819,4822],{"class":920,"line":2734},[918,4801,2969],{"class":924},[918,4803,4220],{"class":1129},[918,4805,1133],{"class":928},[918,4807,1485],{"class":924},[918,4809,4810],{"class":1002},"\"经过 ",[918,4812,4813],{"class":1129},"{self",[918,4815,4816],{"class":928},".max_retries",[918,4818,1496],{"class":1129},[918,4820,4821],{"class":1002}," 次尝试后仍无法连接\"",[918,4823,1139],{"class":928},[892,4825,4827],{"id":4826},"多-server-管理","多 Server 管理",[896,4829,4830],{},"在实际应用中，你通常需要同时连接多个 MCP Server：",[909,4832,4834],{"className":911,"code":4833,"language":913,"meta":11,"style":11},"class MultiServerManager:\n    \"\"\"管理多个 MCP Server 连接\"\"\"\n\n    def __init__(self):\n        self.servers: dict[str, ClientSession] = {}\n        self.tool_registry: dict[str, str] = {}  # tool_name -> server_name\n\n    async def add_server(self, name: str, server_params):\n        \"\"\"添加并连接一个 Server\"\"\"\n        async with stdio_client(server_params) as (read, write):\n            async with ClientSession(read, write) as session:\n                await session.initialize()\n                self.servers[name] = session\n\n                # 注册该 Server 的所有工具\n                tools = await session.list_tools()\n                for tool in tools.tools:\n                    if tool.name in self.tool_registry:\n                        print(f\"警告：工具 '{tool.name}' 存在名称冲突\")\n                    self.tool_registry[tool.name] = name\n\n    async def call_tool(self, tool_name: str, arguments: dict):\n        \"\"\"自动路由工具调用到对应的 Server\"\"\"\n        server_name = self.tool_registry.get(tool_name)\n        if not server_name:\n            raise ValueError(f\"未找到工具: {tool_name}\")\n\n        session = self.servers[server_name]\n        return await session.call_tool(name=tool_name, arguments=arguments)\n\n    def get_all_tools(self) -> list[dict]:\n        \"\"\"获取所有 Server 的工具列表\"\"\"\n        # 用于构建发送给 AI 模型的 tools 参数\n        all_tools = []\n        for server_name, session in self.servers.items():\n            # 从缓存中获取工具信息\n            pass\n        return all_tools\n",[915,4835,4836,4845,4850,4854,4862,4877,4900,4904,4920,4925,4937,4949,4955,4966,4970,4975,4986,4997,5011,5034,5046,5050,5070,5075,5087,5096,5119,5123,5134,5154,5158,5171,5176,5181,5190,5204,5209,5214],{"__ignoreMap":11},[918,4837,4838,4840,4843],{"class":920,"line":921},[918,4839,2447],{"class":924},[918,4841,4842],{"class":967}," MultiServerManager",[918,4844,2453],{"class":928},[918,4846,4847],{"class":920,"line":938},[918,4848,4849],{"class":1002},"    \"\"\"管理多个 MCP Server 连接\"\"\"\n",[918,4851,4852],{"class":920,"line":951},[918,4853,955],{"emptyLinePlaceholder":954},[918,4855,4856,4858,4860],{"class":920,"line":958},[918,4857,2467],{"class":924},[918,4859,2470],{"class":1129},[918,4861,2473],{"class":928},[918,4863,4864,4866,4869,4871,4873,4875],{"class":920,"line":974},[918,4865,2478],{"class":1129},[918,4867,4868],{"class":928},".servers: dict[",[918,4870,2496],{"class":1129},[918,4872,2499],{"class":928},[918,4874,987],{"class":924},[918,4876,2504],{"class":928},[918,4878,4879,4881,4884,4886,4888,4890,4892,4894,4897],{"class":920,"line":981},[918,4880,2478],{"class":1129},[918,4882,4883],{"class":928},".tool_registry: dict[",[918,4885,2496],{"class":1129},[918,4887,3044],{"class":928},[918,4889,2496],{"class":1129},[918,4891,2369],{"class":928},[918,4893,987],{"class":924},[918,4895,4896],{"class":928}," {}  ",[918,4898,4899],{"class":977},"# tool_name -> server_name\n",[918,4901,4902],{"class":920,"line":993},[918,4903,955],{"emptyLinePlaceholder":954},[918,4905,4906,4908,4910,4913,4915,4917],{"class":920,"line":1009},[918,4907,1069],{"class":924},[918,4909,964],{"class":924},[918,4911,4912],{"class":967}," add_server",[918,4914,2532],{"class":928},[918,4916,2496],{"class":1129},[918,4918,4919],{"class":928},", server_params):\n",[918,4921,4922],{"class":920,"line":1026},[918,4923,4924],{"class":1002},"        \"\"\"添加并连接一个 Server\"\"\"\n",[918,4926,4927,4929,4931,4933,4935],{"class":920,"line":1049},[918,4928,1087],{"class":924},[918,4930,1072],{"class":924},[918,4932,1075],{"class":928},[918,4934,1078],{"class":924},[918,4936,1081],{"class":928},[918,4938,4939,4941,4943,4945,4947],{"class":920,"line":1055},[918,4940,4148],{"class":924},[918,4942,1072],{"class":924},[918,4944,1092],{"class":928},[918,4946,1078],{"class":924},[918,4948,1097],{"class":928},[918,4950,4951,4953],{"class":920,"line":1060},[918,4952,4161],{"class":924},[918,4954,1112],{"class":928},[918,4956,4957,4959,4962,4964],{"class":920,"line":1066},[918,4958,4601],{"class":1129},[918,4960,4961],{"class":928},".servers[name] ",[918,4963,987],{"class":924},[918,4965,2648],{"class":928},[918,4967,4968],{"class":920,"line":1084},[918,4969,955],{"emptyLinePlaceholder":954},[918,4971,4972],{"class":920,"line":1100},[918,4973,4974],{"class":977},"                # 注册该 Server 的所有工具\n",[918,4976,4977,4980,4982,4984],{"class":920,"line":1106},[918,4978,4979],{"class":928},"                tools ",[918,4981,987],{"class":924},[918,4983,1454],{"class":924},[918,4985,1457],{"class":928},[918,4987,4988,4990,4992,4994],{"class":920,"line":1115},[918,4989,3226],{"class":924},[918,4991,1469],{"class":928},[918,4993,1472],{"class":924},[918,4995,4996],{"class":928}," tools.tools:\n",[918,4998,4999,5001,5004,5006,5008],{"class":920,"line":1120},[918,5000,3240],{"class":924},[918,5002,5003],{"class":928}," tool.name ",[918,5005,1472],{"class":924},[918,5007,2876],{"class":1129},[918,5009,5010],{"class":928},".tool_registry:\n",[918,5012,5013,5016,5018,5020,5023,5025,5027,5029,5032],{"class":920,"line":1126},[918,5014,5015],{"class":1129},"                        print",[918,5017,1133],{"class":928},[918,5019,1485],{"class":924},[918,5021,5022],{"class":1002},"\"警告：工具 '",[918,5024,1034],{"class":1129},[918,5026,1493],{"class":928},[918,5028,1496],{"class":1129},[918,5030,5031],{"class":1002},"' 存在名称冲突\"",[918,5033,1139],{"class":928},[918,5035,5036,5038,5041,5043],{"class":920,"line":2590},[918,5037,4616],{"class":1129},[918,5039,5040],{"class":928},".tool_registry[tool.name] ",[918,5042,987],{"class":924},[918,5044,5045],{"class":928}," name\n",[918,5047,5048],{"class":920,"line":2608},[918,5049,955],{"emptyLinePlaceholder":954},[918,5051,5052,5054,5056,5059,5061,5063,5066,5068],{"class":920,"line":2625},[918,5053,1069],{"class":924},[918,5055,964],{"class":924},[918,5057,5058],{"class":967}," call_tool",[918,5060,2901],{"class":928},[918,5062,2496],{"class":1129},[918,5064,5065],{"class":928},", arguments: ",[918,5067,2796],{"class":1129},[918,5069,3474],{"class":928},[918,5071,5072],{"class":920,"line":2633},[918,5073,5074],{"class":1002},"        \"\"\"自动路由工具调用到对应的 Server\"\"\"\n",[918,5076,5077,5080,5082,5084],{"class":920,"line":2638},[918,5078,5079],{"class":928},"        server_name ",[918,5081,987],{"class":924},[918,5083,2876],{"class":1129},[918,5085,5086],{"class":928},".tool_registry.get(tool_name)\n",[918,5088,5089,5091,5093],{"class":920,"line":2651},[918,5090,1921],{"class":924},[918,5092,4551],{"class":924},[918,5094,5095],{"class":928}," server_name:\n",[918,5097,5098,5101,5103,5105,5107,5109,5111,5113,5115,5117],{"class":920,"line":2656},[918,5099,5100],{"class":924},"            raise",[918,5102,2972],{"class":1129},[918,5104,1133],{"class":928},[918,5106,1485],{"class":924},[918,5108,2979],{"class":1002},[918,5110,1034],{"class":1129},[918,5112,2984],{"class":928},[918,5114,1496],{"class":1129},[918,5116,1499],{"class":1002},[918,5118,1139],{"class":928},[918,5120,5121],{"class":920,"line":2662},[918,5122,955],{"emptyLinePlaceholder":954},[918,5124,5125,5127,5129,5131],{"class":920,"line":2674},[918,5126,2611],{"class":928},[918,5128,987],{"class":924},[918,5130,2876],{"class":1129},[918,5132,5133],{"class":928},".servers[server_name]\n",[918,5135,5136,5138,5140,5142,5144,5146,5148,5150,5152],{"class":920,"line":2686},[918,5137,2811],{"class":924},[918,5139,1454],{"class":924},[918,5141,4306],{"class":928},[918,5143,2759],{"class":996},[918,5145,987],{"class":924},[918,5147,4313],{"class":928},[918,5149,4316],{"class":996},[918,5151,987],{"class":924},[918,5153,4321],{"class":928},[918,5155,5156],{"class":920,"line":2695},[918,5157,955],{"emptyLinePlaceholder":954},[918,5159,5160,5162,5165,5167,5169],{"class":920,"line":2704},[918,5161,2467],{"class":924},[918,5163,5164],{"class":967}," get_all_tools",[918,5166,2793],{"class":928},[918,5168,2796],{"class":1129},[918,5170,2799],{"class":928},[918,5172,5173],{"class":920,"line":2713},[918,5174,5175],{"class":1002},"        \"\"\"获取所有 Server 的工具列表\"\"\"\n",[918,5177,5178],{"class":920,"line":2722},[918,5179,5180],{"class":977},"        # 用于构建发送给 AI 模型的 tools 参数\n",[918,5182,5183,5186,5188],{"class":920,"line":2734},[918,5184,5185],{"class":928},"        all_tools ",[918,5187,987],{"class":924},[918,5189,2516],{"class":928},[918,5191,5192,5194,5197,5199,5201],{"class":920,"line":2740},[918,5193,2677],{"class":924},[918,5195,5196],{"class":928}," server_name, session ",[918,5198,1472],{"class":924},[918,5200,2876],{"class":1129},[918,5202,5203],{"class":928},".servers.items():\n",[918,5205,5206],{"class":920,"line":2745},[918,5207,5208],{"class":977},"            # 从缓存中获取工具信息\n",[918,5210,5211],{"class":920,"line":2780},[918,5212,5213],{"class":924},"            pass\n",[918,5215,5216,5218],{"class":920,"line":2785},[918,5217,2811],{"class":924},[918,5219,5220],{"class":928}," all_tools\n",[892,5222,5224],{"id":5223},"typescript-完整示例","TypeScript 完整示例",[896,5226,5227],{},"以下是使用 TypeScript SDK 开发 MCP Client 的完整示例：",[909,5229,5231],{"className":1245,"code":5230,"language":1247,"meta":11,"style":11},"import { Client } from \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Findex.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Fstdio.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Fsse.js\";\n\nclass MCPClientApp {\n  private client: Client;\n\n  constructor() {\n    this.client = new Client({\n      name: \"my-ai-app\",\n      version: \"1.0.0\",\n    });\n  }\n\n  async connectStdio(command: string, args: string[]) {\n    const transport = new StdioClientTransport({ command, args });\n    await this.client.connect(transport);\n    console.log(\"已通过 stdio 连接\");\n  }\n\n  async connectSSE(url: string) {\n    const transport = new SSEClientTransport(new URL(url));\n    await this.client.connect(transport);\n    console.log(\"已通过 SSE 连接\");\n  }\n\n  async discoverCapabilities() {\n    const tools = await this.client.listTools();\n    console.log(\"可用工具:\", tools.tools.map((t) => t.name));\n\n    const resources = await this.client.listResources();\n    console.log(\"可用资源:\", resources.resources.map((r) => r.uri));\n\n    const prompts = await this.client.listPrompts();\n    console.log(\"可用提示词:\", prompts.prompts.map((p) => p.name));\n  }\n\n  async callTool(name: string, args: Record\u003Cstring, unknown>) {\n    const result = await this.client.callTool({ name, arguments: args });\n    return result;\n  }\n\n  async readResource(uri: string) {\n    const result = await this.client.readResource({ uri });\n    return result;\n  }\n\n  async close() {\n    await this.client.close();\n  }\n}\n\n\u002F\u002F 使用示例\nasync function main() {\n  const app = new MCPClientApp();\n\n  await app.connectStdio(\"python\", [\"path\u002Fto\u002Fserver.py\"]);\n  await app.discoverCapabilities();\n\n  const result = await app.callTool(\"list_directory\", { path: \".\" });\n  console.log(\"目录内容:\", result);\n\n  await app.close();\n}\n\nmain().catch(console.error);\n",[915,5232,5233,5245,5257,5271,5275,5285,5299,5303,5311,5327,5337,5346,5351,5355,5359,5387,5403,5417,5430,5434,5438,5455,5479,5491,5504,5508,5512,5521,5542,5573,5577,5597,5625,5629,5649,5676,5680,5684,5720,5739,5747,5751,5755,5773,5793,5799,5803,5807,5816,5829,5833,5837,5841,5846,5857,5873,5877,5900,5911,5915,5943,5958,5962,5972,5976,5980],{"__ignoreMap":11},[918,5234,5235,5237,5239,5241,5243],{"class":920,"line":921},[918,5236,932],{"class":924},[918,5238,1256],{"class":928},[918,5240,925],{"class":924},[918,5242,1261],{"class":1002},[918,5244,1264],{"class":928},[918,5246,5247,5249,5251,5253,5255],{"class":920,"line":938},[918,5248,932],{"class":924},[918,5250,1271],{"class":928},[918,5252,925],{"class":924},[918,5254,1276],{"class":1002},[918,5256,1264],{"class":928},[918,5258,5259,5261,5264,5266,5269],{"class":920,"line":951},[918,5260,932],{"class":924},[918,5262,5263],{"class":928}," { SSEClientTransport } ",[918,5265,925],{"class":924},[918,5267,5268],{"class":1002}," \"@modelcontextprotocol\u002Fsdk\u002Fclient\u002Fsse.js\"",[918,5270,1264],{"class":928},[918,5272,5273],{"class":920,"line":958},[918,5274,955],{"emptyLinePlaceholder":954},[918,5276,5277,5279,5282],{"class":920,"line":974},[918,5278,2447],{"class":924},[918,5280,5281],{"class":967}," MCPClientApp",[918,5283,5284],{"class":928}," {\n",[918,5286,5287,5290,5292,5295,5297],{"class":920,"line":981},[918,5288,5289],{"class":924},"  private",[918,5291,1336],{"class":996},[918,5293,5294],{"class":924},":",[918,5296,1343],{"class":967},[918,5298,1264],{"class":928},[918,5300,5301],{"class":920,"line":993},[918,5302,955],{"emptyLinePlaceholder":954},[918,5304,5305,5308],{"class":920,"line":1009},[918,5306,5307],{"class":924},"  constructor",[918,5309,5310],{"class":928},"() {\n",[918,5312,5313,5316,5319,5321,5323,5325],{"class":920,"line":1026},[918,5314,5315],{"class":1129},"    this",[918,5317,5318],{"class":928},".client ",[918,5320,987],{"class":924},[918,5322,1296],{"class":924},[918,5324,1343],{"class":967},[918,5326,1302],{"class":928},[918,5328,5329,5332,5335],{"class":920,"line":1049},[918,5330,5331],{"class":928},"      name: ",[918,5333,5334],{"class":1002},"\"my-ai-app\"",[918,5336,1006],{"class":928},[918,5338,5339,5342,5344],{"class":920,"line":1055},[918,5340,5341],{"class":928},"      version: ",[918,5343,1363],{"class":1002},[918,5345,1006],{"class":928},[918,5347,5348],{"class":920,"line":1060},[918,5349,5350],{"class":928},"    });\n",[918,5352,5353],{"class":920,"line":1066},[918,5354,2086],{"class":928},[918,5356,5357],{"class":920,"line":1084},[918,5358,955],{"emptyLinePlaceholder":954},[918,5360,5361,5364,5367,5369,5371,5373,5376,5378,5380,5382,5384],{"class":920,"line":1100},[918,5362,5363],{"class":924},"  async",[918,5365,5366],{"class":967}," connectStdio",[918,5368,1133],{"class":928},[918,5370,2565],{"class":996},[918,5372,5294],{"class":924},[918,5374,5375],{"class":1129}," string",[918,5377,3044],{"class":928},[918,5379,2573],{"class":996},[918,5381,5294],{"class":924},[918,5383,5375],{"class":1129},[918,5385,5386],{"class":928},"[]) {\n",[918,5388,5389,5392,5394,5396,5398,5400],{"class":920,"line":1106},[918,5390,5391],{"class":924},"    const",[918,5393,1290],{"class":1129},[918,5395,1293],{"class":924},[918,5397,1296],{"class":924},[918,5399,1299],{"class":967},[918,5401,5402],{"class":928},"({ command, args });\n",[918,5404,5405,5407,5410,5413,5415],{"class":920,"line":1115},[918,5406,1433],{"class":924},[918,5408,5409],{"class":1129}," this",[918,5411,5412],{"class":928},".client.",[918,5414,1384],{"class":967},[918,5416,1387],{"class":928},[918,5418,5419,5421,5423,5425,5428],{"class":920,"line":1120},[918,5420,2060],{"class":928},[918,5422,260],{"class":967},[918,5424,1133],{"class":928},[918,5426,5427],{"class":1002},"\"已通过 stdio 连接\"",[918,5429,1401],{"class":928},[918,5431,5432],{"class":920,"line":1126},[918,5433,2086],{"class":928},[918,5435,5436],{"class":920,"line":2590},[918,5437,955],{"emptyLinePlaceholder":954},[918,5439,5440,5442,5445,5447,5449,5451,5453],{"class":920,"line":2608},[918,5441,5363],{"class":924},[918,5443,5444],{"class":967}," connectSSE",[918,5446,1133],{"class":928},[918,5448,3835],{"class":996},[918,5450,5294],{"class":924},[918,5452,5375],{"class":1129},[918,5454,2055],{"class":928},[918,5456,5457,5459,5461,5463,5465,5468,5470,5473,5476],{"class":920,"line":2625},[918,5458,5391],{"class":924},[918,5460,1290],{"class":1129},[918,5462,1293],{"class":924},[918,5464,1296],{"class":924},[918,5466,5467],{"class":967}," SSEClientTransport",[918,5469,1133],{"class":928},[918,5471,5472],{"class":924},"new",[918,5474,5475],{"class":967}," URL",[918,5477,5478],{"class":928},"(url));\n",[918,5480,5481,5483,5485,5487,5489],{"class":920,"line":2633},[918,5482,1433],{"class":924},[918,5484,5409],{"class":1129},[918,5486,5412],{"class":928},[918,5488,1384],{"class":967},[918,5490,1387],{"class":928},[918,5492,5493,5495,5497,5499,5502],{"class":920,"line":2638},[918,5494,2060],{"class":928},[918,5496,260],{"class":967},[918,5498,1133],{"class":928},[918,5500,5501],{"class":1002},"\"已通过 SSE 连接\"",[918,5503,1401],{"class":928},[918,5505,5506],{"class":920,"line":2651},[918,5507,2086],{"class":928},[918,5509,5510],{"class":920,"line":2656},[918,5511,955],{"emptyLinePlaceholder":954},[918,5513,5514,5516,5519],{"class":920,"line":2662},[918,5515,5363],{"class":924},[918,5517,5518],{"class":967}," discoverCapabilities",[918,5520,5310],{"class":928},[918,5522,5523,5525,5528,5530,5532,5534,5536,5539],{"class":920,"line":2674},[918,5524,5391],{"class":924},[918,5526,5527],{"class":1129}," tools",[918,5529,1293],{"class":924},[918,5531,1454],{"class":924},[918,5533,5409],{"class":1129},[918,5535,5412],{"class":928},[918,5537,5538],{"class":967},"listTools",[918,5540,5541],{"class":928},"();\n",[918,5543,5544,5546,5548,5550,5553,5556,5559,5562,5565,5567,5570],{"class":920,"line":2686},[918,5545,2060],{"class":928},[918,5547,260],{"class":967},[918,5549,1133],{"class":928},[918,5551,5552],{"class":1002},"\"可用工具:\"",[918,5554,5555],{"class":928},", tools.tools.",[918,5557,5558],{"class":967},"map",[918,5560,5561],{"class":928},"((",[918,5563,5564],{"class":996},"t",[918,5566,1205],{"class":928},[918,5568,5569],{"class":924},"=>",[918,5571,5572],{"class":928}," t.name));\n",[918,5574,5575],{"class":920,"line":2695},[918,5576,955],{"emptyLinePlaceholder":954},[918,5578,5579,5581,5584,5586,5588,5590,5592,5595],{"class":920,"line":2704},[918,5580,5391],{"class":924},[918,5582,5583],{"class":1129}," resources",[918,5585,1293],{"class":924},[918,5587,1454],{"class":924},[918,5589,5409],{"class":1129},[918,5591,5412],{"class":928},[918,5593,5594],{"class":967},"listResources",[918,5596,5541],{"class":928},[918,5598,5599,5601,5603,5605,5608,5611,5613,5615,5618,5620,5622],{"class":920,"line":2713},[918,5600,2060],{"class":928},[918,5602,260],{"class":967},[918,5604,1133],{"class":928},[918,5606,5607],{"class":1002},"\"可用资源:\"",[918,5609,5610],{"class":928},", resources.resources.",[918,5612,5558],{"class":967},[918,5614,5561],{"class":928},[918,5616,5617],{"class":996},"r",[918,5619,1205],{"class":928},[918,5621,5569],{"class":924},[918,5623,5624],{"class":928}," r.uri));\n",[918,5626,5627],{"class":920,"line":2722},[918,5628,955],{"emptyLinePlaceholder":954},[918,5630,5631,5633,5636,5638,5640,5642,5644,5647],{"class":920,"line":2734},[918,5632,5391],{"class":924},[918,5634,5635],{"class":1129}," prompts",[918,5637,1293],{"class":924},[918,5639,1454],{"class":924},[918,5641,5409],{"class":1129},[918,5643,5412],{"class":928},[918,5645,5646],{"class":967},"listPrompts",[918,5648,5541],{"class":928},[918,5650,5651,5653,5655,5657,5660,5663,5665,5667,5669,5671,5673],{"class":920,"line":2740},[918,5652,2060],{"class":928},[918,5654,260],{"class":967},[918,5656,1133],{"class":928},[918,5658,5659],{"class":1002},"\"可用提示词:\"",[918,5661,5662],{"class":928},", prompts.prompts.",[918,5664,5558],{"class":967},[918,5666,5561],{"class":928},[918,5668,896],{"class":996},[918,5670,1205],{"class":928},[918,5672,5569],{"class":924},[918,5674,5675],{"class":928}," p.name));\n",[918,5677,5678],{"class":920,"line":2745},[918,5679,2086],{"class":928},[918,5681,5682],{"class":920,"line":2780},[918,5683,955],{"emptyLinePlaceholder":954},[918,5685,5686,5688,5691,5693,5695,5697,5699,5701,5703,5705,5708,5710,5712,5714,5717],{"class":920,"line":2785},[918,5687,5363],{"class":924},[918,5689,5690],{"class":967}," callTool",[918,5692,1133],{"class":928},[918,5694,2759],{"class":996},[918,5696,5294],{"class":924},[918,5698,5375],{"class":1129},[918,5700,3044],{"class":928},[918,5702,2573],{"class":996},[918,5704,5294],{"class":924},[918,5706,5707],{"class":967}," Record",[918,5709,4761],{"class":928},[918,5711,3791],{"class":1129},[918,5713,3044],{"class":928},[918,5715,5716],{"class":1129},"unknown",[918,5718,5719],{"class":928},">) {\n",[918,5721,5722,5724,5726,5728,5730,5732,5734,5736],{"class":920,"line":2802},[918,5723,5391],{"class":924},[918,5725,1965],{"class":1129},[918,5727,1293],{"class":924},[918,5729,1454],{"class":924},[918,5731,5409],{"class":1129},[918,5733,5412],{"class":928},[918,5735,1974],{"class":967},[918,5737,5738],{"class":928},"({ name, arguments: args });\n",[918,5740,5741,5744],{"class":920,"line":2808},[918,5742,5743],{"class":924},"    return",[918,5745,5746],{"class":928}," result;\n",[918,5748,5749],{"class":920,"line":2817},[918,5750,2086],{"class":928},[918,5752,5753],{"class":920,"line":2823},[918,5754,955],{"emptyLinePlaceholder":954},[918,5756,5757,5759,5762,5764,5767,5769,5771],{"class":920,"line":2836},[918,5758,5363],{"class":924},[918,5760,5761],{"class":967}," readResource",[918,5763,1133],{"class":928},[918,5765,5766],{"class":996},"uri",[918,5768,5294],{"class":924},[918,5770,5375],{"class":1129},[918,5772,2055],{"class":928},[918,5774,5775,5777,5779,5781,5783,5785,5787,5790],{"class":920,"line":2848},[918,5776,5391],{"class":924},[918,5778,1965],{"class":1129},[918,5780,1293],{"class":924},[918,5782,1454],{"class":924},[918,5784,5409],{"class":1129},[918,5786,5412],{"class":928},[918,5788,5789],{"class":967},"readResource",[918,5791,5792],{"class":928},"({ uri });\n",[918,5794,5795,5797],{"class":920,"line":2860},[918,5796,5743],{"class":924},[918,5798,5746],{"class":928},[918,5800,5801],{"class":920,"line":2866},[918,5802,2086],{"class":928},[918,5804,5805],{"class":920,"line":2882},[918,5806,955],{"emptyLinePlaceholder":954},[918,5808,5809,5811,5814],{"class":920,"line":2888},[918,5810,5363],{"class":924},[918,5812,5813],{"class":967}," close",[918,5815,5310],{"class":928},[918,5817,5818,5820,5822,5824,5827],{"class":920,"line":2893},[918,5819,1433],{"class":924},[918,5821,5409],{"class":1129},[918,5823,5412],{"class":928},[918,5825,5826],{"class":967},"close",[918,5828,5541],{"class":928},[918,5830,5831],{"class":920,"line":2913},[918,5832,2086],{"class":928},[918,5834,5835],{"class":920,"line":2919},[918,5836,2091],{"class":928},[918,5838,5839],{"class":920,"line":2933},[918,5840,955],{"emptyLinePlaceholder":954},[918,5842,5843],{"class":920,"line":2952},[918,5844,5845],{"class":977},"\u002F\u002F 使用示例\n",[918,5847,5848,5850,5853,5855],{"class":920,"line":2966},[918,5849,961],{"class":924},[918,5851,5852],{"class":924}," function",[918,5854,968],{"class":967},[918,5856,5310],{"class":928},[918,5858,5859,5862,5865,5867,5869,5871],{"class":920,"line":2993},[918,5860,5861],{"class":924},"  const",[918,5863,5864],{"class":1129}," app",[918,5866,1293],{"class":924},[918,5868,1296],{"class":924},[918,5870,5281],{"class":967},[918,5872,5541],{"class":928},[918,5874,5875],{"class":920,"line":2998},[918,5876,955],{"emptyLinePlaceholder":954},[918,5878,5879,5882,5885,5888,5890,5892,5895,5897],{"class":920,"line":3019},[918,5880,5881],{"class":924},"  await",[918,5883,5884],{"class":928}," app.",[918,5886,5887],{"class":967},"connectStdio",[918,5889,1133],{"class":928},[918,5891,1003],{"class":1002},[918,5893,5894],{"class":928},", [",[918,5896,1020],{"class":1002},[918,5898,5899],{"class":928},"]);\n",[918,5901,5902,5904,5906,5909],{"class":920,"line":3025},[918,5903,5881],{"class":924},[918,5905,5884],{"class":928},[918,5907,5908],{"class":967},"discoverCapabilities",[918,5910,5541],{"class":928},[918,5912,5913],{"class":920,"line":3053},[918,5914,955],{"emptyLinePlaceholder":954},[918,5916,5917,5919,5921,5923,5925,5927,5929,5931,5934,5937,5940],{"class":920,"line":3058},[918,5918,5861],{"class":924},[918,5920,1965],{"class":1129},[918,5922,1293],{"class":924},[918,5924,1454],{"class":924},[918,5926,5884],{"class":928},[918,5928,1974],{"class":967},[918,5930,1133],{"class":928},[918,5932,5933],{"class":1002},"\"list_directory\"",[918,5935,5936],{"class":928},", { path: ",[918,5938,5939],{"class":1002},"\".\"",[918,5941,5942],{"class":928}," });\n",[918,5944,5945,5948,5950,5952,5955],{"class":920,"line":3069},[918,5946,5947],{"class":928},"  console.",[918,5949,260],{"class":967},[918,5951,1133],{"class":928},[918,5953,5954],{"class":1002},"\"目录内容:\"",[918,5956,5957],{"class":928},", result);\n",[918,5959,5960],{"class":920,"line":3075},[918,5961,955],{"emptyLinePlaceholder":954},[918,5963,5964,5966,5968,5970],{"class":920,"line":3088},[918,5965,5881],{"class":924},[918,5967,5884],{"class":928},[918,5969,5826],{"class":967},[918,5971,5541],{"class":928},[918,5973,5974],{"class":920,"line":3101},[918,5975,2091],{"class":928},[918,5977,5978],{"class":920,"line":3114},[918,5979,955],{"emptyLinePlaceholder":954},[918,5981,5982,5985,5988,5991],{"class":920,"line":3128},[918,5983,5984],{"class":967},"main",[918,5986,5987],{"class":928},"().",[918,5989,5990],{"class":967},"catch",[918,5992,5993],{"class":928},"(console.error);\n",[892,5995,5996],{"id":5996},"最佳实践",[904,5998,6000],{"id":5999},"_1-工具选择策略","1. 工具选择策略",[896,6002,6003],{},"当连接多个 Server 后，你的应用可能拥有大量可用工具。需要合理策略来管理：",[909,6005,6007],{"className":911,"code":6006,"language":913,"meta":11,"style":11},"def filter_relevant_tools(all_tools: list, user_message: str) -> list:\n    \"\"\"根据用户消息筛选相关工具，避免 token 浪费\"\"\"\n    # 简单的关键词匹配策略\n    keywords = {\n        \"文件\": [\"list_directory\", \"read_file\", \"write_file\"],\n        \"数据库\": [\"query\", \"describe_table\"],\n        \"搜索\": [\"search_files\", \"web_search\"],\n    }\n\n    relevant = set()\n    for keyword, tools in keywords.items():\n        if keyword in user_message:\n            relevant.update(tools)\n\n    # 如果没有匹配到关键词，返回所有工具\n    if not relevant:\n        return all_tools\n\n    return [t for t in all_tools if t[\"name\"] in relevant]\n",[915,6008,6009,6034,6039,6044,6053,6074,6091,6108,6112,6116,6128,6140,6152,6157,6161,6166,6176,6182,6186],{"__ignoreMap":11},[918,6010,6011,6014,6017,6020,6023,6026,6028,6030,6032],{"class":920,"line":921},[918,6012,6013],{"class":924},"def",[918,6015,6016],{"class":967}," filter_relevant_tools",[918,6018,6019],{"class":928},"(all_tools: ",[918,6021,6022],{"class":1129},"list",[918,6024,6025],{"class":928},", user_message: ",[918,6027,2496],{"class":1129},[918,6029,2906],{"class":928},[918,6031,6022],{"class":1129},[918,6033,2453],{"class":928},[918,6035,6036],{"class":920,"line":938},[918,6037,6038],{"class":1002},"    \"\"\"根据用户消息筛选相关工具，避免 token 浪费\"\"\"\n",[918,6040,6041],{"class":920,"line":951},[918,6042,6043],{"class":977},"    # 简单的关键词匹配策略\n",[918,6045,6046,6049,6051],{"class":920,"line":958},[918,6047,6048],{"class":928},"    keywords ",[918,6050,987],{"class":924},[918,6052,5284],{"class":928},[918,6054,6055,6058,6060,6062,6064,6067,6069,6072],{"class":920,"line":974},[918,6056,6057],{"class":1002},"        \"文件\"",[918,6059,3708],{"class":928},[918,6061,5933],{"class":1002},[918,6063,3044],{"class":928},[918,6065,6066],{"class":1002},"\"read_file\"",[918,6068,3044],{"class":928},[918,6070,6071],{"class":1002},"\"write_file\"",[918,6073,1023],{"class":928},[918,6075,6076,6079,6081,6084,6086,6089],{"class":920,"line":981},[918,6077,6078],{"class":1002},"        \"数据库\"",[918,6080,3708],{"class":928},[918,6082,6083],{"class":1002},"\"query\"",[918,6085,3044],{"class":928},[918,6087,6088],{"class":1002},"\"describe_table\"",[918,6090,1023],{"class":928},[918,6092,6093,6096,6098,6101,6103,6106],{"class":920,"line":993},[918,6094,6095],{"class":1002},"        \"搜索\"",[918,6097,3708],{"class":928},[918,6099,6100],{"class":1002},"\"search_files\"",[918,6102,3044],{"class":928},[918,6104,6105],{"class":1002},"\"web_search\"",[918,6107,1023],{"class":928},[918,6109,6110],{"class":920,"line":1009},[918,6111,3745],{"class":928},[918,6113,6114],{"class":920,"line":1026},[918,6115,955],{"emptyLinePlaceholder":954},[918,6117,6118,6121,6123,6126],{"class":920,"line":1049},[918,6119,6120],{"class":928},"    relevant ",[918,6122,987],{"class":924},[918,6124,6125],{"class":1129}," set",[918,6127,1552],{"class":928},[918,6129,6130,6132,6135,6137],{"class":920,"line":1055},[918,6131,1466],{"class":924},[918,6133,6134],{"class":928}," keyword, tools ",[918,6136,1472],{"class":924},[918,6138,6139],{"class":928}," keywords.items():\n",[918,6141,6142,6144,6147,6149],{"class":920,"line":1060},[918,6143,1921],{"class":924},[918,6145,6146],{"class":928}," keyword ",[918,6148,1472],{"class":924},[918,6150,6151],{"class":928}," user_message:\n",[918,6153,6154],{"class":920,"line":1066},[918,6155,6156],{"class":928},"            relevant.update(tools)\n",[918,6158,6159],{"class":920,"line":1084},[918,6160,955],{"emptyLinePlaceholder":954},[918,6162,6163],{"class":920,"line":1100},[918,6164,6165],{"class":977},"    # 如果没有匹配到关键词，返回所有工具\n",[918,6167,6168,6171,6173],{"class":920,"line":1106},[918,6169,6170],{"class":924},"    if",[918,6172,4551],{"class":924},[918,6174,6175],{"class":928}," relevant:\n",[918,6177,6178,6180],{"class":920,"line":1115},[918,6179,2811],{"class":924},[918,6181,5220],{"class":928},[918,6183,6184],{"class":920,"line":1120},[918,6185,955],{"emptyLinePlaceholder":954},[918,6187,6188,6190,6193,6195,6198,6200,6203,6205,6208,6210,6212,6214],{"class":920,"line":1126},[918,6189,5743],{"class":924},[918,6191,6192],{"class":928}," [t ",[918,6194,2025],{"class":924},[918,6196,6197],{"class":928}," t ",[918,6199,1472],{"class":924},[918,6201,6202],{"class":928}," all_tools ",[918,6204,3631],{"class":924},[918,6206,6207],{"class":928}," t[",[918,6209,2831],{"class":1002},[918,6211,2369],{"class":928},[918,6213,1472],{"class":924},[918,6215,6216],{"class":928}," relevant]\n",[904,6218,6220],{"id":6219},"_2-连接池管理","2. 连接池管理",[896,6222,6223],{},"对于高并发场景，建议实现连接池：",[6225,6226,6227,6231,6234],"ul",{},[6228,6229,6230],"li",{},"预创建多个 Client 连接",[6228,6232,6233],{},"使用信号量控制并发调用数",[6228,6235,6236],{},"实现健康检查和自动重连",[904,6238,6240],{"id":6239},"_3-安全建议","3. 安全建议",[6225,6242,6243,6250,6256,6262],{},[6228,6244,6245,6249],{},[6246,6247,6248],"strong",{},"最小权限原则"," - 只连接必要的 MCP Server",[6228,6251,6252,6255],{},[6246,6253,6254],{},"输入验证"," - 在将 AI 模型的工具调用请求转发给 Server 之前，进行参数验证",[6228,6257,6258,6261],{},[6246,6259,6260],{},"Human-in-the-loop"," - 对于危险操作（如文件写入、数据修改），在执行前要求用户确认",[6228,6263,6264,6267],{},[6246,6265,6266],{},"日志审计"," - 记录所有工具调用日志，便于问题排查和安全审计",[904,6269,6271],{"id":6270},"_4-性能优化","4. 性能优化",[6225,6273,6274,6284,6290],{},[6228,6275,6276,6279,6280,6283],{},[6246,6277,6278],{},"缓存工具列表"," - ",[915,6281,6282],{},"list_tools()"," 的结果在 Server 不变的情况下可以缓存",[6228,6285,6286,6289],{},[6246,6287,6288],{},"超时设置"," - 为每个工具调用设置合理的超时时间",[6228,6291,6292,6295,6296,6299],{},[6246,6293,6294],{},"并行调用"," - 当 AI 模型需要同时调用多个工具时，使用 ",[915,6297,6298],{},"asyncio.gather"," 并行执行",[909,6301,6303],{"className":911,"code":6302,"language":913,"meta":11,"style":11},"import asyncio\n\nasync def parallel_tool_calls(session, calls: list[tuple[str, dict]]):\n    \"\"\"并行执行多个工具调用\"\"\"\n    tasks = [\n        session.call_tool(name=name, arguments=args)\n        for name, args in calls\n    ]\n    results = await asyncio.gather(*tasks, return_exceptions=True)\n    return results\n",[915,6304,6305,6311,6315,6336,6341,6350,6368,6380,6385,6413],{"__ignoreMap":11},[918,6306,6307,6309],{"class":920,"line":921},[918,6308,932],{"class":924},[918,6310,2399],{"class":928},[918,6312,6313],{"class":920,"line":938},[918,6314,955],{"emptyLinePlaceholder":954},[918,6316,6317,6319,6321,6324,6327,6329,6331,6333],{"class":920,"line":951},[918,6318,961],{"class":924},[918,6320,964],{"class":924},[918,6322,6323],{"class":967}," parallel_tool_calls",[918,6325,6326],{"class":928},"(session, calls: list[tuple[",[918,6328,2496],{"class":1129},[918,6330,3044],{"class":928},[918,6332,2796],{"class":1129},[918,6334,6335],{"class":928},"]]):\n",[918,6337,6338],{"class":920,"line":958},[918,6339,6340],{"class":1002},"    \"\"\"并行执行多个工具调用\"\"\"\n",[918,6342,6343,6346,6348],{"class":920,"line":974},[918,6344,6345],{"class":928},"    tasks ",[918,6347,987],{"class":924},[918,6349,2814],{"class":928},[918,6351,6352,6355,6357,6359,6362,6364,6366],{"class":920,"line":981},[918,6353,6354],{"class":928},"        session.call_tool(",[918,6356,2759],{"class":996},[918,6358,987],{"class":924},[918,6360,6361],{"class":928},"name, ",[918,6363,4316],{"class":996},[918,6365,987],{"class":924},[918,6367,2578],{"class":928},[918,6369,6370,6372,6375,6377],{"class":920,"line":993},[918,6371,2677],{"class":924},[918,6373,6374],{"class":928}," name, args ",[918,6376,1472],{"class":924},[918,6378,6379],{"class":928}," calls\n",[918,6381,6382],{"class":920,"line":1009},[918,6383,6384],{"class":928},"    ]\n",[918,6386,6387,6390,6392,6394,6397,6400,6403,6406,6408,6411],{"class":920,"line":1026},[918,6388,6389],{"class":928},"    results ",[918,6391,987],{"class":924},[918,6393,1454],{"class":924},[918,6395,6396],{"class":928}," asyncio.gather(",[918,6398,6399],{"class":924},"*",[918,6401,6402],{"class":928},"tasks, ",[918,6404,6405],{"class":996},"return_exceptions",[918,6407,987],{"class":924},[918,6409,6410],{"class":1129},"True",[918,6412,1139],{"class":928},[918,6414,6415,6417],{"class":920,"line":1049},[918,6416,5743],{"class":924},[918,6418,6419],{"class":928}," results\n",[1141,6421,6422],{},"\n并行调用多个工具时要注意资源竞争问题。如果多个工具操作同一个资源（如同一个文件或数据库表），可能需要串行执行以避免冲突。\n",[892,6424,6425],{"id":6425},"下一步",[896,6427,6428],{},"掌握了 MCP Client 开发后，你可以：",[6225,6430,6431,6442,6451],{},[6228,6432,6433,6434,6441],{},"参考 ",[6435,6436,6440],"a",{"href":6437,"rel":6438},"https:\u002F\u002Fmodelcontextprotocol.io",[6439],"nofollow","MCP 官方文档"," 了解协议的完整规范",[6228,6443,6444,6445,6450],{},"浏览 ",[6435,6446,6449],{"href":6447,"rel":6448},"https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers",[6439],"MCP Server 仓库"," 发现社区贡献的 Server",[6228,6452,6453],{},"结合 MCP Server 开发指南，构建自己的端到端 AI 应用",[6455,6456,6457],"style",{},"html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sP4rz, html code.shiki .sP4rz{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":11,"searchDepth":938,"depth":938,"links":6459},[6460,6461,6466,6471,6474,6475,6476,6477,6481,6486,6487,6488,6494],{"id":894,"depth":938,"text":894},{"id":901,"depth":938,"text":902,"children":6462},[6463,6464,6465],{"id":906,"depth":951,"text":907},{"id":1146,"depth":951,"text":1147},{"id":1241,"depth":951,"text":1242},{"id":1404,"depth":938,"text":1405,"children":6467},[6468,6469,6470],{"id":1411,"depth":951,"text":1411},{"id":1555,"depth":951,"text":1555},{"id":1672,"depth":951,"text":1672},{"id":1777,"depth":938,"text":1777,"children":6472},[6473],{"id":1952,"depth":951,"text":1953},{"id":2094,"depth":938,"text":2094},{"id":2233,"depth":938,"text":2233},{"id":2383,"depth":938,"text":2384},{"id":3655,"depth":938,"text":3655,"children":6478},[6479,6480],{"id":3661,"depth":951,"text":3662},{"id":3846,"depth":951,"text":3846},{"id":4081,"depth":938,"text":4081,"children":6482},[6483,6484,6485],{"id":4087,"depth":951,"text":4087},{"id":4271,"depth":951,"text":4271},{"id":4433,"depth":951,"text":4433},{"id":4826,"depth":938,"text":4827},{"id":5223,"depth":938,"text":5224},{"id":5996,"depth":938,"text":5996,"children":6489},[6490,6491,6492,6493],{"id":5999,"depth":951,"text":6000},{"id":6219,"depth":951,"text":6220},{"id":6239,"depth":951,"text":6240},{"id":6270,"depth":951,"text":6271},{"id":6425,"depth":938,"text":6425},"md",{},{"title":74,"description":75},"ai\u002Fmcp\u002Fclient","i3hgyoNaIsSk-DpsS8FW4CUrB5x-16FSzcoe3RY8K_4",1775474636282]