☰
基于 Chainlit 与 Microsoft Learn Docs MCP 构建个性化学习计划生成器:从 CLI 客户端到 VS Code 内联文档的完整实战
2026/10/5 2:19:52 网站建设 项目流程
  • 教程
  • 文档
  • 人工智能

【免费下载链接】mcp-for-beginners

This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.

项目地址:https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看免费下载

导读

本文以 mcp-for-beginners 开源课程中「连接 Microsoft Learn Docs MCP 服务器」这一案例为骨架,完整讲解如何通过 Python 客户端接入https://learn.microsoft.com/api/mcp端点,调用microsoft_docs_search工具实时检索微软官方文档。你将掌握三种落地形态:可交互的命令行文档检索客户端、基于 Chainlit + Azure OpenAI 的对话式学习计划生成器(输入「AI-900 认证,8 周」即可输出逐周学习路线),以及把文档检索能力直接嵌入 VS Code(配合 GitHub Copilot)的编辑器内工作流。文中所有代码均可在仓库的 09-CaseStudy/docs-mcp/solution/python 目录中找到可运行版本。

案例背景:把文档带进你的工作流

现代开发早已不只是写代码,更是在正确的时间找到正确的信息。文档无处不在,却很少出现在你最需要它的地方——你的工具和工作流内部。Microsoft Learn Docs MCP 服务器把「实时、上下文感知的文档检索」封装成了标准的 MCP 工具,任何遵循 Model Context Protocol 的客户端都可以通过统一方式调用它。这意味着,无论是命令行工具、Web 应用还是 IDE 扩展,都能在几行代码内获得官方文档的检索能力,从而减少浏览器与编辑器之间的上下文切换,显著提升开发与学习的效率。

本案例的完整讲解位于 09-CaseStudy/docs-mcp/README.md,其中 Python 解决方案的安装与使用说明对应 09-CaseStudy/docs-mcp/solution/python/README.md,本文即围绕该说明文档展开,并结合源码 scenario1.py 与 scenario2.py 进行深入解析。

前置条件与环境准备

运行本案例需要满足以下条件:

  • Python 3.8 或更高版本
  • pip(Python 包管理器)
  • 可访问互联网,用于连接 Microsoft Learn Docs MCP 服务器(端点地址为https://learn.microsoft.com/api/mcp)
  • Azure OpenAI 资源(仅 Scenario 2 需要,用于驱动对话代理生成学习计划)

安装依赖只需一条命令(依赖清单见 requirements.txt):

pip install -r requirements.txt

从依赖清单可以确认本项目的技术栈构成:

依赖包在项目中的用途
chainlit构建对话式 Web 应用界面(Scenario 2)
mcp官方 MCP Python SDK,提供streamablehttp_client与ClientSession
semantic-kernel将 MCP 工具封装为语义内核插件,供 Azure OpenAI 代理调用
werkzeug>=3.1.6安全锁定版本,修复safe_join在 Windows 设备名上的 DoS 漏洞(CVE-2025-66221 / CVE-2026-21860 / CVE-2026-27199)

值得说明的是,werkzeug是 Chainlit 的传递依赖,requirements.txt 中通过版本下限强制其解析到 3.1.6 及以上,体现了生产级项目对供应链安全的最小锁定实践。

Scenario 1:命令行文档检索客户端

核心目标

Scenario 1 的目标是写一个连接到 Microsoft Learn Docs MCP 服务器的控制台程序:调用microsoft_docs_search工具,把流式返回的文档结果解析并打印到终端。它是构建更复杂集成(聊天机器人、IDE 扩展、Web 仪表盘)的基础。

完整实现与逐段解析

完整源码位于 scenario1.py,其关键结构如下:

① 导入与端点定义

import asyncio import logging import sys import json from mcp.client.streamable_http import streamablehttp_client from mcp import ClientSession MCP_SERVER_URL = "https://learn.microsoft.com/api/mcp"

这里用到的是官方 MCP SDK 的两个核心对象:streamablehttp_client(可流式 HTTP 客户端,负责建立传输通道)和ClientSession(会话层,负责初始化握手与工具调用)。

② 日志配置与交互提示

logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) logger = logging.getLogger('mcp_client') def prompt_user(): print("Type your Microsoft Docs search query (or 'exit' to quit):") try: return input("> ").strip() except (KeyboardInterrupt, EOFError): print("\nDetected exit signal.") return "exit"

prompt_user兼顾了两种退出信号(Ctrl+C 与 Ctrl+D),保证交互循环可被干净地中断。

③ 连接、初始化与循环查询

async def main(): logger.info("Connecting to Microsoft Docs MCP Server at: %s", MCP_SERVER_URL) try: async with streamablehttp_client(MCP_SERVER_URL) as (read_stream, write_stream, _): async with ClientSession(read_stream, write_stream) as session: await session.initialize() # ... 打印客户端提示信息 ... while True: user_query = prompt_user() if not user_query: print("Query cannot be empty. Please try again.") continue if user_query.lower() in ("exit", "quit"): break try: result = await session.call_tool("microsoft_docs_search", {"question": user_query}) if hasattr(result, 'content'): for item in result.content: my_list = json.loads(item.text) for doc in my_list: print(f"[Title]: {doc.get('title', 'No title')}") print(f"[Content]: {doc.get('content', 'No content')}") print("---") except Exception as e: logger.error("Query failed: %s", e) print(f"Error: {e}. Please try a different query or check your connection.\n") except Exception as e: logger.error("Connection error: %s", e) sys.exit(1)

这段代码揭示了几个关键实现细节:

  • 工具参数名是question:调用call_tool("microsoft_docs_search", {"question": user_query})时,查询参数键为question(而非query),这是服务端工具的约定,写错键名将导致检索失败;
  • 返回结构是嵌套 JSON 文本:result.content中每个 item 的text字段是一个 JSON 数组字符串,需要json.loads解析后才能拿到title与content字段;
  • 会话复用:while True循环在同一个ClientSession内多次调用工具,避免了每次查询都重新建立连接的开销;
  • 双层异常处理:内层捕获单次查询失败(如网络抖动),外层捕获连接建立失败并直接退出,程序对两种故障场景给出了不同的恢复策略。

运行与预期输出

python scenario1.py

启动后按提示输入查询,例如:

Prompt> What is Azure Key Vault? Answer> Azure Key Vault is a cloud service for securely storing and accessing secrets. ...

每条结果会以[Title]/[Content]形式分段打印,多个文档之间以---分隔。输入exit或quit即可结束会话。

Scenario 2:Chainlit 对话式学习计划生成器

核心目标

Scenario 2 把 Docs MCP 集成进 Web 开发项目:用户只需在聊天窗口输入学习主题与学习周数(例如「AI-900 认证,8 周」),应用就会分析输入、通过 MCP 服务器检索 Microsoft Learn 上的相关官方内容,并组织成逐周的个性化学习计划,推荐内容直接显示在对话流中,方便用户跟进与追踪进度。

架构剖析:MCP + Semantic Kernel + Azure OpenAI

scenario2.py 展示了比 Scenario 1 更完整的工程化设计,其架构分三层:

第一层:把 MCP 工具封装为 Semantic Kernel 插件

class MCPDocsPlugin: def __init__(self, mcp_server_url): self.mcp_server_url = mcp_server_url @kernel_function(name="search_docs", description="Search Microsoft Docs using MCP") async def search_docs(self, question: str) -> str: async with streamablehttp_client(self.mcp_server_url) as (read_stream, write_stream, _): async with ClientSession(read_stream, write_stream) as session: await session.initialize() result = await session.call_tool("microsoft_docs_search", {"question": question}) output = [] if hasattr(result, 'content'): for item in result.content: try: my_list = json.loads(item.text) for doc in my_list: title = doc.get('title', 'No title') content = doc.get('content', 'No content') output.append(f"**{title}**\n{content}") except Exception: output.append(item.text) return "\n".join(output) else: return "No content returned from the search."

该插件通过@kernel_function注解把 MCP 工具注册成 Semantic Kernel 可感知的函数,返回内容用 Markdown 加粗标题组织,便于在聊天界面直接渲染。同时源码中还保留了一个独立的mcp_docs_search辅助函数,展示了「不依赖插件体系、直接调用 MCP」的备选路径。

第二层:构建 ChatCompletionAgent 代理

kernel = Kernel() service_id = "agent" kernel.add_service(AzureChatCompletion(service_id=service_id)) settings = kernel.get_prompt_execution_settings_from_service_id(service_id=service_id) settings.function_choice_behavior = FunctionChoiceBehavior.Auto() mcp_plugin = MCPDocsPlugin(MCP_SERVER_URL) kernel.add_plugin(mcp_plugin, plugin_name="MCPDocs") agent = ChatCompletionAgent( service=AzureChatCompletion(), name="DocsAgent", instructions="You are a helpful assistant that uses the MCPDocs plugin to answer Microsoft Docs questions. Format your answers clearly.", plugins=[mcp_plugin] )

关键点在于FunctionChoiceBehavior.Auto():它允许 Azure OpenAI 模型在对话过程中自主决定何时调用MCPDocs.search_docs工具,这正是「代理(Agent)自主使用 MCP 工具」的标准模式。系统提示词(instructions)约束代理只通过插件回答 Microsoft Docs 相关问题。

第三层:Chainlit 事件驱动的聊天循环

@cl.on_chat_start async def start(): await cl.Message(content="Welcome! Enter your Microsoft Docs search query below.").send() # ... 构建 kernel 与 agent,并通过 cl.user_session 缓存 ... @cl.on_message async def handle_message(message: cl.Message): agent = cl.user_session.get("agent") user_query = message.content.strip() if not user_query: await cl.Message(content="Query cannot be empty. Please try again.").send() return answer = cl.Message(content="Processing your request...") await answer.send() try: response_printed = False async for content in agent.invoke(user_query): msg = content.content if hasattr(msg, "content"): msg = msg.content if msg: await answer.stream_token(str(msg)) response_printed = True if not response_printed: await answer.stream_token("No response generated by the agent.\n") await answer.update() except Exception as e: await answer.stream_token(f"\n\n❌ Error: {str(e)}\n\n") await answer.update()

@cl.on_chat_start在会话建立时初始化代理并通过cl.user_session缓存;@cl.on_message处理每次用户消息,使用agent.invoke()流式获取响应,通过answer.stream_token()实现打字机式的逐字输出,并提供「无响应」兜底与异常信息内联展示。

必需的 Azure OpenAI 环境变量

运行 Scenario 2 前,必须在python文件夹内的.env文件中设置以下变量:

AZURE_OPENAI_CHAT_DEPLOYMENT_NAME= AZURE_OPENAI_API_KEY= AZURE_OPENAI_ENDPOINT= AZURE_OPENAI_API_VERSION=

请用你自己的 Azure OpenAI 资源信息填充这些值,否则AzureChatCompletion无法完成认证与推理调用。需要部署自有模型时,可借助 Microsoft Foundry 平台(Azure AI 门户)便捷发布。

启动应用

chainlit run scenario2.py

终端会输出本地访问地址(如http://localhost:8000),在浏览器打开后在聊天窗口输入学习主题与周数即可。

为什么选择 Chainlit

Chainlit 是一个现代、开源的对话式 Web 应用构建框架,非常适合快速构建与后端服务(如 Microsoft Learn Docs MCP 服务器)对接的聊天界面。本项目使用它提供一种简单、交互式的实时个性化学习计划生成体验;借助 Chainlit,开发者可以快速构建并部署提升生产力与学习效率的对话工具。

推荐查询示例

以下查询展示了应用对不同学习目标与时间框架的适配能力:

  • AI-900 认证,8 周
  • 学习 Azure Functions,4 周
  • Azure DevOps,6 周
  • Azure 上的数据工程,10 周
  • Microsoft 安全基础,5 周
  • Power Platform,7 周
  • Azure AI 服务,12 周
  • 云架构,9 周

实际运行效果可参考案例文档中展示的交互截图:

Scenario 3:在 VS Code 中直接检索与引用文档

核心目标

除了编写独立客户端,你还可以把 Microsoft Learn 文档检索能力直接嵌入 VS Code:不用再切换浏览器标签页,即可在编辑器内搜索和阅读文档、在 README 或课程文件中直接插入参考链接,并与 GitHub Copilot 协同实现「AI 驱动的文档工作流」。这一形态对课程作者、文档编写者和频繁查阅资料的开发者尤为适用。

配置步骤

第 1 步:在工作区添加 MCP 配置文件

在工作区根目录创建.vscode/mcp.json,内容如下(仓库中的完整示例见 09-CaseStudy/docs-mcp/solution/scenario3/mcp.json):

{ "servers": { "LearnDocsMCP": { "url": "https://learn.microsoft.com/api/mcp" } } }

这段配置告诉 VS Code 如何连接 Microsoft Learn Docs MCP 服务器。注意:没有这个有效的mcp.json,Scenario 3 将无法工作,文件位置必须是.vscode/mcp.json。

第 2 步:打开 GitHub Copilot Chat 面板

若尚未安装 GitHub Copilot 扩展,请先在 VS Code 的扩展视图中安装 Copilot Chat,然后从侧边栏打开聊天面板。

第 3 步:启用代理模式并验证工具

在 Copilot Chat 面板中启用 agent mode(代理模式),随后确认 MCP 服务器已出现在可用工具列表中——这保证 Copilot 代理可以访问文档服务器抓取相关信息。

第 4 步:新建会话并向代理提问

在聊天面板中新建会话,直接以自然语言提出文档查询。例如:

"I'm trying to write a study plan for topic X. I'm going to study it for 8 weeks, for each week, suggest content I should take."

代理将借助 MCP 服务器拉取并在编辑器内直接展示相关 Microsoft Learn 文档,聊天交互效果可参考案例中的截图:

第 5 步:实时查询与结果引用

代理返回的文档链接与摘要可以直接插入 Markdown 文件,或作为代码中的参考资料。完整的带截图分步指南见 09-CaseStudy/docs-mcp/solution/scenario3/README.md。

适用场景与示例查询

在编辑器内结合 Copilot 与 MCP,你可以:

  • 在编写课程或项目文档时,快速向 README 添加参考链接;
  • 用 Copilot 生成代码,同时用 MCP 即时查找并引用相关官方文档;
  • 全程保持注意力在编辑器内,提升产出效率。

可尝试的典型查询包括:「Show me how to use Azure Functions triggers.」「Insert a link to the official documentation for Azure Key Vault.」「What are the best practices for securing Azure resources?」「Find a quickstart for Azure AI services.」

三个场景的横向对比与选型建议

场景运行形态关键技术适用对象
Scenario 1命令行交互程序官方 MCP SDK、流式 HTTP 客户端、ClientSession需要脚本化批量检索、学习 MCP 客户端原理的开发者
Scenario 2Chainlit Web 应用MCP + Semantic Kernel 插件 + Azure OpenAI 代理需要面向最终用户提供对话式学习/检索工具的产品
Scenario 3VS Code 编辑器集成.vscode/mcp.json+ GitHub Copilot 代理模式课程作者、文档编写者、频繁查阅资料的开发者

三者的技术底座完全相同——都通过https://learn.microsoft.com/api/mcp端点与microsoft_docs_search工具交互;差异只在于调用方与呈现层。理解了 Scenario 1 的连接与会话机制,就能顺理成章地把它迁移到 Web 界面(Scenario 2)或 IDE 插件(Scenario 3)中。

关键技术要点回顾

  • 统一的 MCP 接入模式:streamablehttp_client(url)建立传输通道 →ClientSession初始化会话 →session.call_tool("microsoft_docs_search", {"question": ...})调用工具,这一三段式流程贯穿全部三个场景;
  • 参数键与返回结构:工具参数键是question;返回的content[].text是 JSON 数组字符串,需解析后读取title/content字段;
  • 代理化调用:Scenario 2 通过FunctionChoiceBehavior.Auto()让 LLM 自主决定调用 MCP 工具,是「让模型使用外部工具」的标准范式;
  • 配置驱动的编辑器集成:Scenario 3 仅需一份.vscode/mcp.json,即可让 VS Code 与 Copilot 获得完整的文档检索能力;
  • 安全基线:依赖清单对传递依赖werkzeug做了版本下限锁定,规避已知安全公告,生产项目应同样关注传递依赖的漏洞面。

将文档检索直接集成进工具链,不只是便利性的提升,更是生产力的质变:它消除了代码与文档之间的上下文切换,让开发者能够实时获取最新、最相关的官方资料,并构建出更智能、更具交互性的开发工具。

  • 教程
  • 文档
  • 人工智能

【免费下载链接】mcp-for-beginners

This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.

项目地址:https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看免费下载

相关推荐

上一篇:三步免费解锁 Wand 专业版:Wand-Enhancer 完整上手与进阶玩法指南
下一篇:SMUDebugTool完整入门指南:AMD处理器调试工具的免费全能工具箱

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询