ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用 Docker 把 agents 接入 Elasticsearch:基于模型上下文协议的配置与验证

用 Docker 把 agents 接入 Elasticsearch:基于模型上下文协议的配置与验证 1. 为什么要在 Docker 里跑 agents 接 Elasticsearch如果你正在做本地开发或者自托管的检索场景大概率会遇到这样一个需求让 agents 能直接查 Elasticsearch 里的索引而不是每次手写 DSL。Elasticsearch 官方已经把 MCP server 重写成了 Docker 镜像形态支持 stdio、SSE 和 streamable-HTTP 三种协议这意味着你可以把「agents 通过模型上下文协议连接 Elasticsearch」这件事收敛成一条可复现的容器链路。我这次要落地的目标很明确在 Docker 环境里用 docker-compose 起一个 Elasticsearch再让 agents 通过 MCP server 连上去最后用一次真实检索请求确认读写都正常。适合谁适合正在做 RAG 检索层、日志分析助手、或者自托管知识库的开发者。你不需要把 Elasticsearch 暴露到公网也不需要改 agents 的底层代码只要把 MCP server 的容器配置对凭据走统一通道管理就行。整条链路里最容易出问题的不是 Elasticsearch 本身而是三件事容器之间怎么互相找到、API key 怎么安全传进去、SSL 自签证书怎么处理。下面我按「先起服务、再配 MCP、再验证」的顺序拆开讲每一步都给可复制的命令和配置。2. 前置准备TaoToken 统一 Key 与 API 通道在动手写 compose 之前先把凭据管理这件事定下来。很多人的做法是把 Elasticsearch 的 API key 直接写进 compose 文件或者环境变量里本地玩玩没问题但一旦要接多个 agents、多个模型通道凭据就会散得到处都是。我的做法是用 TaoToken 作为统一的 Key/API 通道把模型侧和检索侧的凭据入口收敛到一处。TaoToken 在这里的角色是「统一凭据与 API 通道」你可以在它的控制台里生成和管理 API Keyagents 调用模型时走这个通道检索侧的服务配置也从同一个地方取凭据避免每个容器里塞一份明文。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 这个不加 UTM。具体操作上你先到控制台创建一个 API Key后面 agents 的模型调用会用到它。如果你打算长期跑编码类或 Agent 类任务可以顺带看一下 Coding Plan它更适合持续性的开发场景如果只是临时验证模型连通性用模型对话页面就够了。这一步不用纠结太久先把 Key 拿到手后面配置里会引用。注意Elasticsearch 自己的 API key 和 TaoToken 的 API Key 是两套东西。前者用于 MCP server 连 ES后者用于 agents 调模型。不要混用也不要把任意一个提交到公开仓库。3. 可复制配置docker-compose 骨架与 MCP 服务端3.1 docker-compose 起 Elasticsearch 单节点先写一个最小可用的 compose 文件把 Elasticsearch 跑起来。单节点、关闭安全认证的版本适合本地开发如果你要开 xpack.security后面我再补 API key 的配法。version: 3.8 services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:9.1.2 container_name: es-local environment: - discovery.typesingle-node - xpack.security.enabledfalse - ES_JAVA_OPTS-Xms1g -Xmx1g ports: - 9200:9200 volumes: - es-data:/usr/share/elasticsearch/data networks: - mcp-net volumes: es-data: networks: mcp-net: driver: bridge启动命令docker compose up -d elasticsearch docker compose logs -f elasticsearch等日志里出现started之后验证一下curl -s http://localhost:9200 | head -20你会看到集群名、版本号、Lucene 版本这些信息。到这一步Elasticsearch 本身是通的。3.2 MCP server 的 stdio 模式配置Elasticsearch MCP server 的镜像地址是docker.elastic.co/mcp/elasticsearch。不带参数运行会打印用法docker run --rm docker.elastic.co/mcp/elasticsearch输出里能看到三个子命令stdio、http、help。stdio 模式适合 Claude Desktop 这类只支持标准输入输出的客户端http 模式适合远程或容器间调用。先讲 stdio因为它最直接。stdio 模式需要两个核心环境变量ES_URL和ES_API_KEY或者ES_USERNAMEES_PASSWORD。如果 ES 用的是自签证书再加ES_SSL_SKIP_VERIFYtrue。关键点在于容器里的localhost指的是容器自己不是宿主机。所以 ES 跑在宿主机上时MCP server 容器里要用host.docker.internal来指向宿主机。Linux 下如果这个域名不生效需要在 compose 里加extra_hosts。mcp-es: image: docker.elastic.co/mcp/elasticsearch container_name: mcp-es command: [stdio] environment: - ES_URLhttps://host.docker.internal:9200 - ES_API_KEY${ES_API_KEY} - ES_SSL_SKIP_VERIFYtrue extra_hosts: - host.docker.internal:host-gateway networks: - mcp-net stdin_open: true tty: true这里ES_API_KEY从宿主机环境变量注入不写死在文件里。你可以在.env文件里放ES_API_KEY你的ElasticsearchAPIKey3.3 用 http 模式让 agents 远程接入如果你的 agents 不是 Claude Desktop而是自己写的服务http 模式更合适。它启动一个 streamable-HTTP 服务agents 通过 HTTP 请求调用。mcp-es-http: image: docker.elastic.co/mcp/elasticsearch container_name: mcp-es-http command: [http] ports: - 8080:8080 environment: - ES_URLhttp://elasticsearch:9200 - ES_API_KEY${ES_API_KEY} networks: - mcp-net注意这里ES_URL用的是http://elasticsearch:9200因为两个容器在同一个mcp-net网络里可以直接用服务名互相访问。这是 Docker 网络最实用的地方比host.docker.internal更干净。启动后验证端口docker compose up -d mcp-es-http curl -s http://localhost:8080/health如果返回健康状态说明 MCP server 的 HTTP 层已经起来了。4. 验证请求从索引创建到一次真实检索4.1 写入测试索引先造点数据不然检索没东西可查。用 Kibana 自带的航班样例数据最省事但这里我直接用一个 curl 写入方便你在纯命令行环境复现。curl -X PUT http://localhost:9200/flights -H Content-Type: application/json -d { mappings: { properties: { OriginCityName: { type: keyword }, DestCityName: { type: keyword }, OriginCountry: { type: keyword }, DestCountry: { type: keyword }, AvgTicketPrice: { type: float } } } }写入两条文档curl -X POST http://localhost:9200/flights/_doc -H Content-Type: application/json -d {OriginCityName:Beijing,DestCityName:New York,OriginCountry:CN,DestCountry:US,AvgTicketPrice:820.5} curl -X POST http://localhost:9200/flights/_doc -H Content-Type: application/json -d {OriginCityName:Shanghai,DestCityName:Los Angeles,OriginCountry:CN,DestCountry:US,AvgTicketPrice:640.0}刷新索引让数据可搜curl -X POST http://localhost:9200/flights/_refresh4.2 通过 MCP server 发起检索现在让 agents 通过 MCP server 来查。MCP server 暴露的工具里有一个search它接收查询 DSL。你可以先用 curl 直接打 http 模式的 MCP 端点模拟 agents 的调用。curl -X POST http://localhost:8080/mcp \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 1, method: tools/call, params: { name: search, arguments: { index: flights, query_body: { size: 1, sort: [{AvgTicketPrice: {order: asc}}], query: { bool: { must: [ {term: {OriginCountry: CN}}, {term: {DestCountry: US}} ] } }, _source: [AvgTicketPrice, OriginCityName, DestCityName] } } } }如果返回里包含Shanghai和640.0说明整条链路通了agents 通过 MCP 协议把查询 DSL 传给 MCP serverMCP server 再打到 Elasticsearch结果原路返回。4.3 用自然语言触发Claude Desktop 场景如果你用的是 Claude Desktop配置好 MCP server 后直接在对话框里输入What is the cheapest price from CN to US? and tell me the OriginCityName and DestCityNameClaude 会自己决定调用search工具并生成对应的 DSL。你不需要手写查询体。中文也可以从中国到美国的最低价格是多少请告诉我出发城市名称和目的地城市名称。实测下来中文查询同样能命中因为 MCP server 只负责执行 DSL语义理解在模型侧完成。5. 本篇常见错排查5.1 容器里连不上 Elasticsearch最常见的报错是Connection refused或No route to host。原因几乎都是ES_URL写成了localhost。记住MCP server 容器里的localhost是它自己。宿主机上的 ES 要用host.docker.internal同网络里的 ES 容器要用服务名。Linux 下host.docker.internal默认不解析必须在 compose 里加extra_hosts: - host.docker.internal:host-gateway5.2 SSL 证书验证失败自签证书场景下会报certificate verify failed。临时方案是设ES_SSL_SKIP_VERIFYtrue。生产环境建议把 CA 证书挂进容器而不是跳过验证。目前 MCP server 对自定义证书的支持还在完善跳过验证只适合本地开发。5.3 API key 无效或权限不足如果返回security_exception先确认 API key 有没有对应索引的读权限。Elasticsearch 的 API key 是绑定权限的不是拿到就能查所有索引。你可以在 Kibana 的 Stack Management 里检查 key 的 role descriptor。5.4 MCP server 启动即退出stdio 模式下如果没加-iinteractive容器会因为没有标准输入而立刻退出。compose 里要写stdin_open: true和tty: true。http 模式则不需要。5.5 端口冲突8080经常被占用。改 compose 里的端口映射比如18080:8080然后 curl 打18080。6. 把凭据和接入收敛到统一通道整条链路跑通之后你会发现真正需要长期维护的不是 Docker 命令而是凭据。Elasticsearch 的 API key、agents 调模型用的 Key如果每个环境都手动配一遍很容易出错。我的做法是把模型侧的 Key 统一走 TaoToken 管理控制台里生成、轮换、吊销都在一处完成。接入文档在 https://taotoken.net/doc 里面有各语言 SDK 的接入示例。如果你要生成新的 Key直接去 https://taotoken.net/api-keys 。验证模型连通性用模型对话页面最直观长期跑编码或 Agent 任务则建议看 Coding Plan它的额度模型更适合持续性调用。回到 Elasticsearch 这条链路MCP server 的配置本身不复杂复杂的是「让 agents 稳定地拿到凭据并连上检索层」。把 ES 的 key 放在.env里、把模型 key 放在 TaoToken 控制台里两边各司其职compose 文件里只留引用这样换环境时只需要改.env不用动配置结构。最后留一个实用技巧每次改完 compose 后先docker compose config检查一遍变量有没有正确展开再up -d。很多「配置看起来对但连不上」的问题都是环境变量没传进去导致的。
返回列表