为什么创建 MCP?—— 标准化集成层的需求
Model Context Protocol ( MCP )的创建是为了解决构建智能代理型 AI(agentic AI)应用中的一个核心问题:将孤立的大型语言模型( large language models - LLMs )连接到外部世界。默认情况下, LLM 是强大的推理引擎,但它们的知识是静态的,受限于训练截止时间,并且没有原生能力访问实时数据或在外部系统中执行操作。
过去,连接 LLM 到外部系统通常通过直接、自定义的 API 集成实现。这种方式虽然有效,但要求每个应用开发者都要学习每个工具的特定 API,编写代码处理查询和解析结果,并长期维护这些连接。随着 AI 应用和可用工具数量的增加,这种方式面临效率和可扩展性的挑战,急需更标准化的方法。
MCP 提供了这个标准协议,它借鉴了诸如 Web 服务中的 REST 和开发者工具中的 Language Server Protocol( LSP )等成熟标准。 MCP 不是让每个开发者都去掌握每个工具的 API,而是为连接层建立了统一语言。
这实现了清晰的职责分离,使平台和工具提供者可以通过单一、可复用的 MCP 服务器暴露他们的服务,这些服务器天然适配 LLM。这样,集成的维护责任就从 AI 应用开发者转移到外部系统的拥有者。这推动了一个健壮、可互操作的生态系统,任何符合规范的应用都能连接到任何符合规范的工具,大大简化了开发与维护工作。
ES/Kibana 双 MCP 架构下的新一代 Aiops 智能分析排障与管理实践 - 完整视频
双 MCP 赋能 ES liuke 南京 20250628
使用 MCP 将代理连接到 Elasticsearch 并对索引进行查询
MCP 如何工作:核心架构
MCP 架构
MCP 基于客户端-服务器模型运行,旨在将一个推理引擎(即 LLM )连接到一组外部能力。该架构从 LLM 开始,逐步揭示使其能够与外部世界交互的各个组件。
该架构由三个关键组件组成:
- Hosts 是希望通过 MCP 访问数据的 LLM 应用(例如 Claude Desktop、IDE、AI 代理)。
- Servers 是通过 MCP 暴露特定能力的轻量级程序。
- Clients 在 host 应用内部与 servers 保持一对一连接。
MCP 客户端或主机
MCP 客户端或主机是协调 LLM 与一个或多个 MCP 服务器交互的应用。客户端很关键,它包含应用特定的逻辑。服务器提供原始能力,客户端负责使用这些能力。客户端通过以下功能来实现:
- 提示词组装:从多个服务器收集上下文,构建最终有效的 LLM 提示词
- 状态管理:维护多次交互中的对话历史和用户上下文
- 协调控制:决定向哪些服务器请求哪些信息,并在 LLM 决定使用工具时执行逻辑
MCP 客户端通过标准网络请求(通常是 HTTPS)连接到已知的服务器端点。该协议的强大之处在于,它标准化了双方的通信契约。协议本身与语言无关,采用基于 JSON 的格式。因此任何客户端,无论使用什么语言开发,都能正确与任意服务器通信。
MCP 服务器
MCP 服务器是一个后端程序,作为特定数据源或工具的标准化包装器。它实现 MCP 规范,通过网络暴露功能,比如可执行的工具或数据资源。本质上,它把特定服务的独特协议(如数据库查询或第三方 REST API)翻译成 MCP 的通用语言,使任何 MCP 客户端都能理解。
实践:如何创建你的第一个 MCP 服务器?
以暴露工具的服务器为例(关于工具的定义见下文)。该服务器需要处理来自客户端的两个主要请求:
1)安装 SDK
# Python
pip install mcp
# Node.js
npm install @modelcontextprotocol/sdk
# Or explore the specification
git clone https://github.com/modelcontextprotocol/specification
2)创建你的第一个服务器
# Save as weather_server.py
from mcp.server import Server
import asyncio
app = Server("weather-server")
@app.tool()
async def get_weather(city: str) -> str:
return f"Weather in {city}: Sunny, 72°F"
if __name__ == "__main__":
asyncio.run(app.run())
3)连接到 Claude Desktop
// Add to Claude Desktop config
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["weather_server.py"],
"env": {}
}
}
}
官方 SDK 和资源
你可以使用官方开源 SDK 开始构建自己的 MCP 客户端和服务器:
MCP 工具 - tools
工具是 MCP 服务器向客户端暴露的具体可执行能力。与被动的数据资源(如文件或文档)不同,工具代表 LLM 可以决定调用的动作,比如发送邮件、创建项目工单或查询实时数据库。
工具与服务器的交互方式如下:MCP 服务器声明它提供的工具。例如,Elastic 服务器会暴露一个 list_indices
工具,定义其名称、用途和所需参数(如 list_indices
、get_mappings
、get_shards
和 search
)。
客户端连接到服务器并发现这些可用工具。客户端将可用工具作为系统提示或上下文的一部分呈现给 LLM。当 LLM 的输出表示有使用工具的意图时,客户端解析该意图并正式请求相应服务器使用指定参数执行该工具。
动手实践:低级 MCP 服务器实现
虽然低级示例有助于理解协议的机制,但大多数开发者会使用官方 SDK 来构建服务器。SDK 处理协议的样板代码 —— 比如消息解析和请求路由 ——让 你可以专注于工具的核心逻辑。
以下示例使用官方 MCP Python SDK 创建一个简单服务器,暴露一个 get_current_time 工具。相比低级实现,这种方式更加简洁且声明式。
import asyncio
import datetime
from typing import AsyncIterator
from mcp.server import (
MCPServer,
Tool,
tool,
)
# --- Tool Implementation ---
# The @tool decorator from the SDK handles the registration and schema generation.
# We define a simple asynchronous function that will be exposed as an MCP tool.
@tool
async def get_current_time() -> AsyncIterator[str]:
"""
Returns the current UTC time and date as an ISO 8601 string.
This docstring is automatically used as the tool's description for the LLM.
"""
# The SDK expects an async iterator, so we yield the result.
yield datetime.datetime.now(datetime.timezone.utc).isoformat()
# --- Server Definition ---
# We create an instance of the MCPServer, passing it the tools we want to expose.
# The SDK automatically discovers any functions decorated with @tool.
SERVER = MCPServer(
tools=[
# The SDK automatically picks up our decorated function.
Tool.from_callable(get_current_time),
],
)
# --- Main execution block ---
# The SDK provides a main entry point to run the server.
# This handles all the underlying communication logic (stdio, HTTP, etc.).
async def main() -> None:
"""Runs the simple tool server."""
await SERVER.run()
if __name__ == "__main__":
asyncio.run(main())
这个动手示例展示了使用 SDK 构建 MCP 服务器的强大功能:
- @tool decorator:该装饰器会自动将 get_current_time 函数注册为 MCP 工具。它会检查函数的签名和文档字符串,生成协议所需的模式和描述,免去了你手动编写的麻烦。
- MCPServer 实例:MCPServer 类是 SDK 的核心。你只需提供想要暴露的工具列表,剩下的交给它处理。
- SERVER.run():这条命令启动服务器并管理所有底层通信,包括处理 stdio 或 HTTP 等不同的传输方式。
如你所见,SDK 抽象了协议的几乎所有复杂性,使你只需几行 Python 代码就能定义强大的工具。
三个核心 primitives
MCP 通过定义服务器可以暴露的三个核心原语,标准化了 LLM 与外部世界的交互方式。这些原语提供了一个完整的系统,用于连接 LLM 和外部功能。
1)资源(Resources):提供上下文
- 功能:数据访问
- 类比:GET 端点
- 资源是为 LLM 提供上下文的主要机制。它们代表模型可以检索并用于生成响应的数据源,如文档、数据库记录或搜索查询结果。它们通常是只读操作。
2)工具(Tools):执行操作
- 功能:动作和计算
- 类比:POST 或 PUT 端点
- 工具是可执行的函数,允许 LLM 执行动作,直接影响外部系统。这使得代理不仅仅是简单的数据检索,还能做诸如发送邮件、创建项目工单或调用第三方 API 等操作。
3)提示(Prompts):引导交互
- 功能:交互模板
- 类比:工作流程配方
- 提示是可复用的模板,引导 LLM 与用户或系统的交互。它们允许开发者标准化常见或复杂的对话流程,确保模型行为更一致和可靠。
模型上下文协议(MCP)本身
核心概念
MCP 为 LLM 应用(主机)与外部数据和能力(服务器)集成提供了标准化方式。该规范基于 JSON-RPC 2.0 消息格式,定义了一套必需和可选组件,以支持丰富的、有状态的交互。
核心协议与功能
MCP 核心标准化了通信层。所有实现必须支持基础协议和生命周期管理。
- 基础协议:所有通信使用标准的 JSON-RPC 消息(请求、响应和通知)。
- 服务器功能:服务器可以向客户端提供以下任意组合的能力:
-
资源(Resources):供用户或模型使用的上下文数据
-
提示(Prompts):模板化消息和工作流
-
工具(Tools):LLM 可调用的可执行功能
-
- 客户端功能:客户端可以向服务器提供以下功能,实现更高级的双向工作流:
-
采样(Sampling):允许服务器发起智能(agentic)行为或递归 LLM 交互
-
引导(Elicitation):使服务器能够向用户请求额外信息
-
MCP 基础协议
MCP 建立在基础协议和生命周期管理的必要基础上。客户端和服务器之间的所有通信必须遵守 JSON-RPC 2.0 规范,定义了三种消息类型:
-
请求(Requests):用于发起操作。要求包含唯一的字符串或整数
id
以便跟踪,且同一会话中不可重复使用该 id。 -
响应(Responses):对请求的回复。必须包含原请求的 id,成功时包含
result
对象,失败时包含error
对象。 -
通知(Notifications):单向消息,无需包含 id,也不要求接收方回复。
客户端功能:支持高级工作流
对于更复杂的双向通信,客户端还可以向服务器提供以下功能:
-
采样(Sampling):允许服务器通过客户端请求 LLM 推断。这是实现多步骤智能工作流的强大功能,工具可能需要 “反问” LLM 获取更多信息后再完成任务。
-
引导(Elicitation):提供服务器向最终用户请求更多信息的正式机制。这对需要澄清或确认后再执行操作的交互式工具至关重要。
服务器功能:暴露能力
服务器通过一组标准功能向客户端暴露能力。服务器可以实现以下任意组合:
-
工具(Tools):工具是使 LLM 执行动作的主要机制。它们是服务器暴露的可执行函数,允许 LLM 与外部系统交互,例如调用第三方 API、查询数据库或修改文件。
-
资源(Resources):资源代表 LLM 可检索的上下文数据源。与执行动作的工具不同,资源主要用于只读数据检索。它们是将 LLM 与实时外部信息结合的机制,是高级 RAG 流水线的关键部分。
-
提示(Prompts):服务器可以暴露预定义的提示模板供客户端使用,允许标准化和共享常用、复杂或高度优化的提示,确保交互的一致性。
安全与信任
规范强调安全,列出了实施者应遵循的关键原则。协议本身无法强制执行这些规则,责任在于应用开发者。
-
用户同意与控制:用户必须明确同意并保留对所有数据访问和工具调用的控制。授权应有清晰的用户界面。
-
数据隐私:主机不得在未经明确同意情况下向服务器传输用户数据,且必须实施适当的访问控制。
-
工具安全:工具调用相当于执行任意代码,必须谨慎对待。主机在调用任何工具前必须获得用户明确同意。
为什么 MCP 如此重要?
MCP 的核心优势在于它标准化了模型与工具之间的通信和交互层。这为开发者创造了一个可预测且可靠的生态系统。标准化的关键领域包括:
-
统一的连接器 API:连接任何外部服务的单一、一致接口
-
标准化上下文:传递重要信息(如会话历史、嵌入、工具输出和长期记忆)的通用消息格式
-
工具调用协议:约定的请求和响应模式,确保调用外部工具时的可预测性
-
数据流控制:内置规则用于过滤、优先级排序、流式传输和批处理上下文,优化提示构建
-
安全与认证模式:统一的 API 密钥或 OAuth 认证、限流和加密钩子,保障数据交换安全
-
生命周期和路由规则:定义何时获取上下文、缓存多长时间、以及如何在系统间路由数据的约定
-
元数据和可观测性:统一元数据字段,实现所有连接模型和工具的一致日志、指标和分布式追踪
-
扩展点:定义添加自定义逻辑的钩子,如前后处理步骤、自定义验证规则和插件注册
大规模场景下:解决“ M×N ”或乘法扩展的集成难题
在快速扩展的 AI 领域,开发者面临重大集成挑战。AI 应用( M )需要访问大量外部数据源和工具( N ),包括数据库、搜索引擎、API 和代码库等。如果没有标准协议,开发者必须为每对应用与数据源构建和维护独特的自定义集成,即 “ M×N 问题”。
这种做法带来了几个关键问题:
-
重复的开发工作:团队为每个新的 AI 应用反复解决相同的集成问题,浪费宝贵时间和资源。
-
过于复杂:不同数据源以不同方式处理类似功能,导致集成层复杂且不一致。
-
维护过度:缺乏标准化造成自定义集成生态脆弱。单个工具 API 的小变更即可导致连接断裂,需要持续的被动维护。
MCP 将这个 M×N 问题转化为更简单的 M+N 方程。通过创建通用标准,开发者只需构建 M 个客户端(对应应用)和 N 个服务器(对应工具),大幅降低复杂性和维护负担。
比较 agentic 方法
MCP 不是像检索增强生成(retrieval augmented generation - RAG)或 LangChain 这样的流行模式或框架的替代品;它是一个基础的连接协议,使它们更强大、模块化且更易维护。它通过标准化集成的 “最后一公里” 解决了应用连接外部工具的普遍问题。
以下是 MCP 在现代 AI 技术栈中的作用:
驱动高级 RAG
标准 RAG 功能强大,但通常连接的是静态向量数据库。对于更高级的用例,需要从实时复杂系统中检索动态信息。
- 无 MCP:开发者必须编写自定义代码,将其 RAG 应用直接连接到如 Elasticsearch 之类搜索 API 的特定查询语言。
- 有 MCP:搜索系统通过标准 MCP 服务器暴露其功能。RAG 应用现在可以使用简单、可重用的 MCP 客户端查询这个实时数据源,无需了解底层系统的具体 API。这使得 RAG 实现更简洁,未来更容易替换其他数据源。
与 agentic 框架集成(如 LangChain、LangGraph)
Agentic 框架提供构建应用逻辑的优秀工具,但仍需要连接外部工具的方式。
- 替代方案:
-
自定义代码:从头编写直接集成,需大量工程投入和持续维护
-
框架专用工具包:使用预构建连接器或为特定框架编写自定义包装器(这会产生对该框架架构的依赖,锁定生态系统)
-
- MCP 优势:
- MCP 提供一个开放、通用的标准。工具提供者可以为其产品创建单一的 MCP 服务器。现在,任何框架 —— LangChain、LangGraph 或自定义解决方案 —— 都可以使用通用 MCP 客户端与该服务器交互。这种方式更高效,避免了供应商锁定。
为什么协议简化一切
最终,MCP 的价值在于提供了集成两种极端方式的开放标准替代方案:
-
编写自定义代码易碎且维护成本高
-
使用框架特定包装器导致半封闭生态和供应商依赖
MCP 将集成的所有权转移给外部系统的拥有者,使其提供单一、稳定的 MCP 端点。应用开发者只需使用这些端点,极大简化了构建、扩展和维护强大且具有上下文感知能力的 AI 应用的工作。
开始使用 Elasticsearch MCP 服务器
如何操作:实现 Elasticsearch MCP 服务器
Elastic 开发了一个用于 Elasticsearch 的 MCP 服务器,允许你轻松地将数据连接到任何兼容 MCP 的 host。通过该服务器,你可以让模型访问查询索引、检查映射以及执行搜索。
设置服务器非常简单。下面的代码片段展示了如何定义一个 Elasticsearch 客户端并实例化 MCP 服务器:
{
"mcpServers": {
"elasticsearch-mcp-server": {
"command": "npx",
"args": [
"-y",
"@elastic/mcp-server-elasticsearch"
],
"env": {
"ES_URL": "your-elasticsearch-url",
"ES_API_KEY": "your-api-key"
}
}
}
}
请按照我们 GitHub 仓库中的剩余步骤操作。
与我们一起参与 MCP 和 AI
深入了解使用 Elastic 构建
保持对 AI 和智能搜索应用相关内容的关注。探索我们的资源,了解更多关于使用 Elastic 构建的内容。
- 与 Elasticsearch 结合的 LLM 功能,实现智能查询转换
- AI 代理和 Elastic AI SDK for Python
- Elasticsearch 的 Model Context Protocol
原文:Connect Agents to Elasticsearch with Model Context Protocol - Elasticsearch Labs