{
  "canonical_name": "elastic/mcp-server-elasticsearch",
  "compilation_id": "pack_7e0fd5a3eb6a47238d1404bc43ec9f59",
  "created_at": "2026-05-31T01:22:41.187898+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=mcp_config, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=mcp_config, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio",
      "sandbox_container_image": "docker.elastic.co/mcp/elasticsearch",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "deterministic_isolated_install",
      "sandbox_validation_id": "sbx_b96078911c064ea59db267764802848e"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_cc0542a2a96f2781ca87b8b23eb8e57b",
    "canonical_name": "elastic/mcp-server-elasticsearch",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/elastic/mcp-server-elasticsearch",
    "slug": "mcp-server-elasticsearch",
    "source_packet_id": "phit_81cbb06e36d247419b264ab65a087e74",
    "source_validation_id": "dval_a637409e3fd74426bc5c840f395c1308"
  },
  "merchandising": {
    "best_for": "需要工具连接与集成能力，并使用 mcp_host的用户",
    "github_forks": 141,
    "github_stars": 666,
    "one_liner_en": "Elasticsearch MCP Server",
    "one_liner_zh": "Elasticsearch MCP Server",
    "primary_category": {
      "category_id": "tool-integrations",
      "confidence": "high",
      "name_en": "Tool Integrations",
      "name_zh": "工具连接与集成",
      "reason": "matched_keywords:mcp, api, server"
    },
    "target_user": "使用 mcp_host, claude, cursor 等宿主 AI 的用户",
    "title_en": "mcp-server-elasticsearch",
    "title_zh": "mcp-server-elasticsearch 能力包",
    "visible_tags": [
      {
        "label_en": "MCP Tools",
        "label_zh": "MCP 工具",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-mcp-tools",
        "type": "product_domain"
      },
      {
        "label_en": "Visual Workflow Orchestration",
        "label_zh": "视觉工作流编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-visual-workflow-orchestration",
        "type": "user_job"
      },
      {
        "label_en": "Retrieval Augmentation",
        "label_zh": "检索增强",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-retrieval-augmentation",
        "type": "core_capability"
      },
      {
        "label_en": "Node-based Workflow",
        "label_zh": "节点式流程编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-node-based-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Evaluation Suite",
        "label_zh": "评测体系",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-evaluation-suite",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_81cbb06e36d247419b264ab65a087e74",
  "page_model": {
    "artifacts": {
      "artifact_slug": "mcp-server-elasticsearch",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio",
          "label": "Docker · 官方安装入口",
          "source": "https://github.com/elastic/mcp-server-elasticsearch#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "MCP 工具",
        "视觉工作流编排",
        "检索增强",
        "节点式流程编排",
        "评测体系"
      ],
      "eyebrow": "工具连接与集成",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要工具连接与集成能力，并使用 mcp_host的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "Elasticsearch MCP Server"
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "mcp_host, claude, cursor",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "mcp_config, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "安装/运行入口包含 Docker 命令：docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio",
            "category": "安装坑",
            "evidence": [
              "identity.distribution | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio"
            ],
            "severity": "medium",
            "suggested_check": "标注 Docker 前置条件，并提供非 Docker 路径或失败提示。",
            "title": "依赖 Docker 环境",
            "user_impact": "非工程用户可能没有 Docker，启动成本明显增加。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Dependency Dashboard",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_5573c160ecdd4e34be6dbf6549fe2529 | https://github.com/elastic/mcp-server-elasticsearch/issues/6 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：Dependency Dashboard",
            "user_impact": "可能阻塞安装或首次运行。"
          },
          {
            "body": "项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。",
            "category": "配置坑",
            "evidence": [
              "capability.host_targets | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | host_targets=mcp_host, claude, cursor"
            ],
            "severity": "medium",
            "suggested_check": "列出会写入的配置文件、目录和卸载/回滚步骤。",
            "title": "可能修改宿主 AI 配置",
            "user_impact": "安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。"
          },
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_f8732a2deab341d6b739b122459d1243 | https://github.com/elastic/mcp-server-elasticsearch/issues/185 | 来源讨论提到 api key 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 10 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 依赖 Docker 环境。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 22,
        "forks": 141,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": 666
      },
      "source_url": "https://github.com/elastic/mcp-server-elasticsearch",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "Elasticsearch MCP Server",
      "title": "mcp-server-elasticsearch 能力包",
      "trial_prompt": "# mcp-server-elasticsearch - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 mcp-server-elasticsearch 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client / claude / Cursor\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 HTTP 200 with status text。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- health_endpoints: Provides HTTP health check endpoints at /ready, /live, and /ping for container orchestration. 输入：HTTP GET requests；输出：HTTP 200 with status text。\n\n【必须安装后才可验证的能力】\n- list_indices: Lists Elasticsearch indices matching a pattern, returning index name, status, and document count. 输入：index_pattern (string, optional)；输出：Array of {index, status, docs.count} objects。\n- get_mappings: Retrieves field mappings for a specified index, exposing the schema definition. 输入：index (string)；输出：Mapping definition with field types and properties。\n- search: Executes search queries against Elasticsearch indices with support for _source filtering and aggregations. 输入：index (string), query_body (JSON object), fields (optional array for _source)；输出：Search hits with _source fields, aggregations if present。\n- esql_query: Executes ES|QL (Elasticsearch Query Language) queries and returns results as JSON objects. 输入：query (ES|QL string), params (optional)；输出：Array of JSON objects keyed by column names。\n- get_shards: Returns shard allocation information for indices including replica state and node assignment. 输入：index_pattern (string, optional)；输出：Array of shard info objects。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-intro：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-architecture：系统架构。围绕“系统架构”模拟一次用户任务，不展示安装或运行结果。\n3. page-protocols：通信协议配置。围绕“通信协议配置”模拟一次用户任务，不展示安装或运行结果。\n4. page-tools：MCP 工具详解。围绕“MCP 工具详解”模拟一次用户任务，不展示安装或运行结果。\n5. page-deployment：Docker 部署指南。围绕“Docker 部署指南”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-intro\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-architecture\n输入：用户提供的“系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-protocols\n输入：用户提供的“通信协议配置”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-tools\n输入：用户提供的“MCP 工具详解”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-deployment\n输入：用户提供的“Docker 部署指南”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-intro：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-architecture：Step 2 必须围绕“系统架构”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-protocols：Step 3 必须围绕“通信协议配置”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-tools：Step 4 必须围绕“MCP 工具详解”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-deployment：Step 5 必须围绕“Docker 部署指南”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/elastic/mcp-server-elasticsearch\n- https://github.com/elastic/mcp-server-elasticsearch#readme\n- src/protocol/http.rs\n- README.md\n- catalog-info.yaml\n- src/lib.rs\n- src/cli.rs\n- src/servers/mod.rs\n- src/protocol/mod.rs\n- src/protocol/stdio.rs\n- src/servers/elasticsearch/base_tools.rs\n- src/servers/elasticsearch/mod.rs\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 mcp-server-elasticsearch 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: Dependency Dashboard（https://github.com/elastic/mcp-server-elasticsearch/issues/6）；github/github_issue: Dependency Dashboard（https://github.com/elastic/mcp-server-elasticsearch/issues/6）；github/github_issue: Dependency Dashboard（https://github.com/elastic/mcp-server-elasticsearch/issues/6）；github/github_issue: get_mappings tool fails with \"error decoding response body\" when nested （https://github.com/elastic/mcp-server-elasticsearch/issues/185）；github/github_issue: get_mappings tool fails with \"error decoding response body\" when nested （https://github.com/elastic/mcp-server-elasticsearch/issues/185）；github/github_release: v0.4.6（https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.6）；github/github_release: v0.4.6（https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.6）；github/github_release: v0.4.5（https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.5）；github/github_release: v0.4.5（https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.5）；github/github_release: v0.4.4（https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.4）；github/github_release: v0.4.4（https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.4）；github/github_release: v0.4.3（https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.3）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Dependency Dashboard",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/issues/6"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Dependency Dashboard",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/issues/6"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Dependency Dashboard",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/issues/6"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "get_mappings tool fails with \"error decoding response body\" when nested ",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/issues/185"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "get_mappings tool fails with \"error decoding response body\" when nested ",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/issues/185"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.4.6",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.6"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.4.6",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.6"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.4.5",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.5"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.4.5",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.5"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.4.4",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.4"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.4.4",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.4"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.4.3",
              "url": "https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.3"
            }
          ],
          "status": "已收录 12 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "工具连接与集成",
      "desc": "Elasticsearch MCP Server",
      "effort": "安装已验证",
      "forks": 141,
      "icon": "link",
      "name": "mcp-server-elasticsearch 能力包",
      "risk": "可发布",
      "slug": "mcp-server-elasticsearch",
      "stars": 666,
      "tags": [
        "MCP 工具",
        "视觉工作流编排",
        "检索增强",
        "节点式流程编排",
        "评测体系"
      ],
      "thumb": "gray",
      "type": "MCP 配置"
    },
    "manual": {
      "markdown": "# https://github.com/elastic/mcp-server-elasticsearch 项目说明书\n\n生成时间：2026-05-31 01:03:00 UTC\n\n## 目录\n\n- [项目介绍](#page-intro)\n- [版本历史与更新](#page-changelog)\n- [系统架构](#page-architecture)\n- [通信协议配置](#page-protocols)\n- [MCP 工具详解](#page-tools)\n- [配置与工具过滤](#page-config)\n- [Docker 部署指南](#page-deployment)\n- [认证配置](#page-auth)\n- [故障排除指南](#page-troubleshooting)\n- [安全最佳实践](#page-security)\n\n<a id='page-intro'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [catalog-info.yaml](https://github.com/elastic/mcp-server-elasticsearch/blob/main/catalog-info.yaml)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json)\n</details>\n\n# 项目介绍\n\n## 概述\n\nElasticsearch MCP Server 是由 Elastic 公司开发的 Model Context Protocol (MCP) 服务器实现，专门用于将 Elasticsearch 集群与 AI 助手（如 Claude、Cursor 等）进行集成。该项目允许 AI 代理通过标准化接口执行 Elasticsearch 操作，包括索引查询、映射获取、分片状态检查等高级功能。\n\n资料来源：[catalog-info.yaml:4]()\n\n### 项目定位\n\n| 属性 | 值 |\n|------|-----|\n| 类型 | 库 (library) |\n| 所属团队 | devtools-team |\n| 生命周期 | beta (测试阶段) |\n| 版权 | Elasticsearch B.V. 2025 |\n\n资料来源：[catalog-info.yaml:6-10]()\n\n## 核心架构\n\n### 整体架构图\n\n```mermaid\ngraph TD\n    A[\"MCP Client<br/>(Claude/Cursor)\"] --> B[\"Elasticsearch MCP Server\"]\n    B --> C[\"Elasticsearch Cluster\"]\n    \n    B --> D[\"base_tools<br/>基础工具集\"]\n    B --> E[\"custom_tools<br/>自定义工具\"]\n    \n    D --> D1[\"list_indices\"]\n    D --> D2[\"get_mappings\"]\n    D --> D3[\"search\"]\n    D --> D4[\"get_shards\"]\n    D --> D5[\"esql\"]\n    \n    E --> E1[\"ESQL 查询\"]\n    E --> E2[\"搜索模板\"]\n    \n    C --> F[\"REST API\"]\n```\n\n### 组件层次结构\n\n```mermaid\ngraph TD\n    A[\"ElasticsearchMcp\"] --> B[\"EsBaseTools\"]\n    B --> C[\"EsClientProvider\"]\n    C --> D[\"Elasticsearch<br/>HTTP Client\"]\n    \n    B --> E[\"ToolRouter<br/>工具路由器\"]\n    E --> F[\"工具处理器\"]\n    \n    A --> G[\"Configuration<br/>配置管理\"]\n    G --> H[\"环境变量解析\"]\n    G --> I[\"配置文件加载\"]\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:77-93]()\n\n## 工具集详解\n\n### 基础工具 (Base Tools)\n\n项目提供五个核心工具用于日常 Elasticsearch 操作：\n\n| 工具名称 | 功能描述 | 只读 |\n|----------|----------|------|\n| `list_indices` | 列出所有符合条件的 Elasticsearch 索引 | 是 |\n| `get_mappings` | 获取指定索引的字段映射信息 | 是 |\n| `search` | 使用 Query DSL 执行搜索查询 | 是 |\n| `get_shards` | 获取索引分片分配状态信息 | 是 |\n| `esql` | 执行 ES|QL 查询语句 | 是 |\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:1-100]()\n\n### 搜索功能增强\n\n`search` 工具支持以下高级特性：\n\n- **字段选择**：通过 `fields` 参数指定返回字段，减少上下文大小\n- **聚合支持**：自动返回聚合结果，支持复杂分析查询\n- **Query DSL 完整支持**：支持 query、size、from、sort 等完整查询语法\n\n```rust\n// 搜索结果数据结构\npub struct SearchResult {\n    pub hits: Hits,\n    #[serde(default)]\n    pub aggregations: IndexMap<String, Value>,  // 聚合结果\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Hits {\n    pub total: Option<TotalHits>,\n    pub hits: Vec<Hit>,\n}\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:100-130]()\n\n### 自定义工具 (Custom Tools)\n\n支持扩展的工具类型：\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(tag = \"type\", rename_all = \"snake_case\")]\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n\npub enum EsqlResultFormat {\n    Json,   // 默认，输出 JSON 数组或对象\n    Value,  // 单属性时仅输出值\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:20-35]()\n\n## 配置系统\n\n### 配置结构\n\n```yaml\n{\n  \"elasticsearch\": {\n    \"url\": \"https://localhost:9200\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n### 环境变量配置\n\n| 变量名 | 必填 | 说明 |\n|--------|------|------|\n| `ES_URL` | 是 | Elasticsearch 集群 URL |\n| `ES_API_KEY` | 否 | API Key 认证 |\n| `ES_USERNAME` | 否 | 用户名（需配合密码使用） |\n| `ES_PASSWORD` | 否 | 密码 |\n| `ES_SSL_SKIP_VERIFY` | 否 | 跳过 SSL 证书验证 |\n\n资料来源：[src/lib.rs:1-30]()\n\n### 配置加载流程\n\n```mermaid\nsequenceDiagram\n    participant CLI as 命令行\n    participant Config as 配置解析器\n    participant Interpolator as 变量插值器\n    participant ES as ElasticsearchMcp\n\n    CLI->>Config: 加载配置文件\n    Config->>Interpolator: 解析 ${VAR:default} 语法\n    Interpolator-->>Config: 返回展开后的配置\n    Config->>ES: new_with_config(config)\n    ES->>ES: 创建连接池和认证\n    ES-->>CLI: 返回处理器实例\n```\n\n## 通信协议\n\n### 支持的传输模式\n\n| 模式 | 说明 | 使用场景 |\n|------|------|----------|\n| `stdio` | 标准输入/输出 | 本地 Claude Desktop 集成 |\n| `http` | Streamable HTTP | Web 集成、远程访问 |\n\n资料来源：[src/cli.rs:30-50]()\n\n### HTTP 服务配置\n\n```rust\npub struct HttpCommand {\n    /// 配置文件路径\n    pub config: Option<PathBuf>,\n    \n    /// 监听地址 [default: 127.0.0.1:8080]\n    pub address: Option<std::net::SocketAddr>,\n    \n    /// 启用 SSE 服务于 '/sse'\n    pub sse: bool,\n}\n```\n\n| 参数 | 默认值 | 环境变量 |\n|------|--------|----------|\n| `--address` | 127.0.0.1:8080 | `HTTP_ADDRESS` |\n| `--config` | 无 | 无 |\n| `--sse` | false | 无 |\n\n资料来源：[src/cli.rs:35-48]()\n\n## 认证机制\n\n### 认证流程\n\n```mermaid\ngraph LR\n    A[\"请求上下文\"] --> B{\"授权头存在?\"}\n    B -->|是| C[\"使用请求头认证\"]\n    B -->|否| D{\"配置中有凭证?\"}\n    D -->|API Key| E[\"EncodedApiKey\"]\n    D -->|用户名密码| F[\"Basic Auth\"]\n    D -->|无| G[\"匿名访问\"]\n```\n\n### 凭证优先级\n\n1. HTTP 请求头中的 `Authorization`\n2. 配置中的 `api_key`\n3. 配置中的 `username` + `password`\n\n资料来源：[src/servers/elasticsearch/mod.rs:80-95]()\n\n## 部署方式\n\n### Docker 部署\n\n```bash\n# Stdio 模式\ndocker run --rm \\\n  -e ES_URL \\\n  -e ES_API_KEY \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n\n# HTTP 模式\ndocker run --rm \\\n  -e ES_URL \\\n  -e ES_API_KEY \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n### Claude Desktop 配置 (Stdio)\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"--rm\",\n        \"-e\", \"ES_URL\",\n        \"-e\", \"ES_API_KEY\",\n        \"docker.elastic.co/mcp/elasticsearch\",\n        \"stdio\"\n      ]\n    }\n  }\n}\n```\n\n### HTTP 模式配置\n\n通过 `mcp-proxy` 桥接到 Claude Desktop：\n\n```bash\nuv tool install mcp-proxy\n```\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"/path/to/mcp-proxy\",\n      \"args\": [\n        \"--transport=streamablehttp\",\n        \"--header\", \"Authorization\", \"ApiKey <key>\",\n        \"http://host:8080/mcp\"\n      ]\n    }\n  }\n}\n```\n\n## 已知问题与限制\n\n### 社区反馈的问题\n\n| 问题编号 | 描述 | 状态 |\n|----------|------|------|\n| #185 | `get_mappings` 工具在嵌套类型未显式声明时解码失败 | 待修复 |\n| #170 | Basic 认证失败 (401 Unauthorized) | 社区讨论中 |\n| #191 | 缺少 Linux ARM64 二进制发布 | 功能请求 |\n\n### 健康检查\n\nHTTP 模式提供健康检查端点：\n\n```bash\ncurl http://<host>:8080/ping\n# 返回: pong\n```\n\n## 版本历史\n\n| 版本 | 主要变更 |\n|------|----------|\n| v0.4.6 | 添加弃用通知 |\n| v0.4.5 | 修复用户名环境变量名称 |\n| v0.4.4 | 添加 CA 证书支持 |\n| v0.4.3 | 默认端口改回 8080 |\n| v0.4.2 | 默认端口改为 8000 |\n| v0.4.1 | 添加 `CLI_ARGS` 环境变量支持 |\n| v0.3.1 | 修复 `npx` 执行缺少 hashbang |\n| v0.3.0 | 添加 OpenTelemetry 支持、Smithery 配置 |\n\n## 技术栈\n\n| 组件 | 技术 |\n|------|------|\n| 语言 | Rust |\n| HTTP 客户端 | elasticsearch-rs |\n| MCP 框架 | rmcp |\n| 序列化 | serde_json, serde_json5 |\n| 宏处理 | rmcp_macros |\n| CLI | clap |\n\n## 依赖管理\n\n项目使用 Renovate 进行自动化依赖更新：\n\n- 计划：每周一 1:00 后执行\n- 配置：继承自 `elastic/renovate-config`\n\n```json\n{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\"local>elastic/renovate-config\"],\n  \"schedule\": [\"after 1am on monday\"]\n}\n```\n\n资料来源：[renovate.json:1-8]()\n\n## 持续集成\n\n项目使用 Buildkite 进行 CI/CD：\n\n| 流水线 | 触发条件 | 说明 |\n|--------|----------|------|\n| mcp-server-elasticsearch | PR、推送 | 执行检查 |\n| mcp-server-elasticsearch-docker | Tags | 构建并发布 Docker 镜像 |\n\n资料来源：[catalog-info.yaml:20-80]()\n\n---\n\n<a id='page-changelog'></a>\n\n## 版本历史与更新\n\n### 相关页面\n\n相关主题：[项目介绍](#page-intro), [故障排除指南](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [NOTICE.txt](https://github.com/elastic/mcp-server-elasticsearch/blob/main/NOTICE.txt)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n- [renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json)\n</details>\n\n# 版本历史与更新\n\nElasticsearch MCP Server 是由 Elasticsearch B.V. 开发维护的 Model Context Protocol (MCP) 服务器实现，旨在为 AI 代理提供与 Elasticsearch 集群交互的能力。本页面记录该项目的完整版本历史、功能演进以及重要更新信息。\n\n## 版本发布时间线\n\n```mermaid\ntimeline\n    title Elasticsearch MCP Server 版本发布历史\n    v0.2.0 : 新增 get_shards 工具\n             灵活认证验证\n             索引模式参数\n    v0.3.0 : Smithery 配置支持\n             OpenTelemetry 支持\n             聚合结果返回\n             profile 和 explain\n    v0.3.1 : 修复 npx hashbang 问题\n    v0.4.1 : Dockerfile EXPOSE\n             CLI_ARGS 环境变量\n    v0.4.2 : 默认端口 8000\n    v0.4.3 : 默认端口恢复 8080\n    v0.4.4 : 添加 CA 证书\n    v0.4.5 : 用户名 ENV 名称更新\n    v0.4.6 : 添加弃用通知\n```\n\n## 各版本详细说明\n\n### v0.4.6（最新版本）\n\n**发布状态**：当前稳定版本\n\n**主要变更**：添加了项目弃用通知（Deprecation Notice），提示用户项目已进入维护模式。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.6)\n\n---\n\n### v0.4.5\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #158 | @mol91 | 更新用户名环境变量名称 |\n\n该版本修复了环境变量命名问题，使认证配置更加直观。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.5)\n\n---\n\n### v0.4.4\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #145 | @swallez | 添加 CA 证书支持 |\n\n此版本添加了对 CA 证书的支持，增强了 SSL/TLS 连接的安全性验证。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.4)\n\n---\n\n### v0.4.3\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #144 | @swallez | 将默认端口改回 8080 |\n\n此版本将 HTTP 服务器的默认端口从 v0.4.2 的 8000 改回 8080，保持与之前版本的一致性。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.3)\n\n---\n\n### v0.4.2\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #142 | @JoshMock | 将默认端口改为 8000 |\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.2)\n\n---\n\n### v0.4.1\n\n**主要变更**：\n\n| 变更类型 | 提交 | 说明 |\n|---------|------|------|\n| 修复 | 0cc4d1fe | 添加 Dockerfile `EXPOSE 8080` 指令 |\n| 修复 | 336f4635 | 添加 `CLI_ARGS` 环境变量作为传参替代方案 |\n\n此版本改进了 Docker 部署体验，提供了更灵活的配置方式。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.1)\n\n---\n\n### v0.3.1\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #122 | @JoshMock | 修复 `npx -y @elastic/mcp-server-elasticsearch` 缺少 hashbang 的问题 |\n\n此版本修复了通过 npx 方式运行时的可执行性问题。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.3.1)\n\n---\n\n### v0.3.0\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 功能说明 |\n|---------|---------|--------|----------|\n| 功能 | #31 | @calclavia | Smithery 配置支持 |\n| 功能 | #64 | @anuraaga | OpenTelemetry 支持 |\n| 功能 | #46 | @sternbergm | 搜索工具添加聚合结果返回 |\n\n此版本是一个重要的功能版本，引入了多项关键功能：\n\n1. **Smithery 配置**：支持通过 Smithery 平台进行安装配置\n2. **OpenTelemetry 支持**：集成了分布式追踪能力，便于监控和调试\n3. **聚合结果**：search 工具现在可以返回聚合查询结果\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.3.0)\n\n---\n\n### v0.2.0\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 功能说明 |\n|---------|---------|--------|----------|\n| 功能 | #25 | @getsolaris | 新增 `get_shards` 工具 |\n| 功能 | #27 | @getsolaris | 更灵活的认证验证 |\n| 功能 | #100 | @susan-shu-c | list_indices 工具添加索引模式参数 |\n\n此版本奠定了 MCP Server 的核心工具集基础。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.2.0)\n\n---\n\n## 工具演进历史\n\n### 核心工具列表\n\n| 工具名称 | 首次引入版本 | 功能描述 |\n|----------|-------------|----------|\n| `list_indices` | v0.2.0 | 列出所有可用的 Elasticsearch 索引 |\n| `get_shards` | v0.2.0 | 获取索引分片信息 |\n| `search` | 初始版本 | 使用 Query DSL 执行搜索查询 |\n| `get_mappings` | 初始版本 | 获取索引映射定义 |\n| ES\\|QL | v0.3.0 | 执行 ES|QL 查询 |\n| Search Template | 后续版本 | 使用搜索模板执行查询 |\n\n### 工具实现架构\n\n```mermaid\ngraph TD\n    A[MCP Client] -->|Request| B[ServerHandler]\n    B --> C[EsBaseTools]\n    C --> D{工具类型}\n    D -->|list_indices| E[cat.indices API]\n    D -->|get_shards| F[cat.shards API]\n    D -->|search| G[search API]\n    D -->|get_mappings| H[mappings API]\n    D -->|esql| I[esql API]\n    \n    E --> J[Elasticsearch Cluster]\n    F --> J\n    G --> J\n    H --> J\n    I --> J\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n\n---\n\n## 协议与传输模式演进\n\n### 支持的传输模式\n\n| 模式 | 支持版本 | 说明 |\n|------|---------|------|\n| stdio | v0.2.0 起 | 标准输入输出模式，适用于本地 CLI |\n| HTTP | v0.4.x | Streamable HTTP 模式 |\n| SSE | v0.4.x | Server-Sent Events（已弃用） |\n\n### HTTP 端点配置\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n资料来源：[src/cli.rs:32-47](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### HTTP 路由结构\n\n| 端点 | 方法 | 功能 |\n|------|------|------|\n| `/` | GET | 服务信息 |\n| `/ping` | GET | 健康检查 |\n| `/mcp` | POST | MCP 请求端点 |\n| `/mcp/sse` | GET | SSE 连接端点 |\n| `/_health/ready` | GET | 就绪探针 |\n| `/_health/live` | GET | 存活探针 |\n\n资料来源：[src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n\n---\n\n## 认证机制演进\n\n### 支持的认证方式\n\n| 认证方式 | 配置参数 | 说明 |\n|----------|---------|------|\n| API Key | `ES_API_KEY` | Base64 编码的 API 密钥 |\n| Basic Auth | `ES_USERNAME` + `ES_PASSWORD` | 用户名密码认证 |\n\n### 认证配置代码\n\n```rust\nimpl ElasticsearchMcp {\n    pub fn new_with_config(config: ElasticsearchMcpConfig, container_mode: bool) -> anyhow::Result<base_tools::EsBaseTools> {\n        let creds = if let Some(api_key) = config.api_key.clone() {\n            Some(Credentials::EncodedApiKey(api_key))\n        } else if let Some(username) = config.username.clone() {\n            let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n            Some(Credentials::Basic(username, pwd))\n        } else {\n            None\n        };\n        // ...\n    }\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:94-107](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 已知认证问题\n\n**Issue #170**：部分用户反馈在使用 Docker 部署时，即使环境变量配置正确，仍然出现 401 Unauthorized 错误。建议检查：\n\n1. 环境变量名称是否正确（`ES_USERNAME` 而非 `ES_lOGIN`）\n2. Elasticsearch 集群的认证配置\n3. 网络连通性\n\n---\n\n## 依赖更新管理\n\n### Renovate 配置\n\n项目使用 Renovate 进行自动化依赖更新管理：\n\n```json\n{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"local>elastic/renovate-config\"\n  ],\n  \"schedule\": [\n    \"after 1am on monday\"\n  ]\n}\n```\n\n资料来源：[renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json)\n\n### 更新策略\n\n- **更新频率**：每周一凌晨 1 点后自动检查更新\n- **仪表板**：通过 [Issue #6](https://github.com/elastic/mcp-server-elasticsearch/issues/6) 查看所有待处理和已完成的依赖更新\n\n---\n\n## 已知问题与限制\n\n### get_mappings 工具问题\n\n**Issue #185**：当 mapping 中 nested 属性未显式指定 `\"type\": \"nested\"` 时，`get_mappings` 工具会返回 `\"error decoding response body\"` 错误，尽管该 mapping 在 Elasticsearch 规范中是有效的。\n\n**状态**：社区已报告，等待修复。\n\n### 其他社区关注的问题\n\n| Issue | 标题 | 关注度 |\n|-------|------|--------|\n| #17 | Support streamable HTTP | 4 评论 |\n| #170 | Basic auth failed - 401 Unauthorized | 22 评论 |\n| #45 | Add Aggregation results to return fields | 1 评论 |\n| #191 | Publish a linux arm64 binary | 3 评论 |\n| #173 | Error messages for some functions | 4 评论 |\n\n---\n\n## 版权与许可\n\n```\nElasticsearch MCP Server\nCopyright 2025 Elasticsearch B.V.\n```\n\n资料来源：[NOTICE.txt](https://github.com/elastic/mcp-server-elasticsearch/blob/main/NOTICE.txt)\n\n---\n\n## 相关资源\n\n| 资源类型 | 链接 |\n|---------|------|\n| GitHub 仓库 | https://github.com/elastic/mcp-server-elasticsearch |\n| 问题反馈 | https://github.com/elastic/mcp-server-elasticsearch/issues |\n| 版本发布页 | https://github.com/elastic/mcp-server-elasticsearch/releases |\n| MCP 协议文档 | https://modelcontextprotocol.io |\n| Renovate 配置 | [renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json) |\n\n---\n\n<a id='page-architecture'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[项目介绍](#page-intro), [通信协议配置](#page-protocols), [MCP 工具详解](#page-tools)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n</details>\n\n# 系统架构\n\n## 概述\n\nElasticsearch MCP Server 是一个基于 Model Context Protocol (MCP) 的中间件服务，用于将 Elasticsearch 集群与 AI 代理进行连接。它充当协议转换层，将 MCP 协议请求转换为 Elasticsearch HTTP API 调用，并返回结构化结果。\n\n**核心职责**：\n- 接收来自 MCP 客户端（如 Claude Desktop、Cursor 等）的标准化工具调用请求\n- 验证认证信息并建立与 Elasticsearch 集群的连接\n- 将请求路由至相应的工具处理器并执行查询\n- 将 Elasticsearch 响应转换回 MCP 协议格式返回\n\n**技术栈**：\n- 语言：Rust\n- MCP 协议：rmcp (Rust MCP 实现)\n- Elasticsearch 客户端：elasticsearch crate\n\n资料来源：[src/lib.rs:1-50](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n\n---\n\n## 架构分层\n\n```mermaid\ngraph TD\n    subgraph \"接入层\"\n        A[MCP 客户端]\n        B[Stdio Transport]\n        C[Streamable HTTP Transport]\n    end\n    \n    subgraph \"协议层\"\n        D[MCP 协议解析器]\n        E[工具调用分发]\n    end\n    \n    subgraph \"业务层\"\n        F[EsBaseTools 工具集]\n        G[CustomTool 自定义工具]\n        H[EsClientProvider 客户端管理]\n    end\n    \n    subgraph \"通信层\"\n        I[Elasticsearch HTTP API]\n    end\n    \n    subgraph \"外部服务\"\n        J[Elasticsearch 集群]\n    end\n    \n    A --> B\n    A --> C\n    B --> D\n    C --> D\n    D --> E\n    E --> F\n    E --> G\n    F --> H\n    G --> H\n    H --> I\n    I --> J\n```\n\n---\n\n## 服务器模式\n\nMCP Server 支持两种运行模式，通过命令行子命令选择：\n\n### Stdio 模式\n\n标准输入输出模式，适用于本地进程通信场景。这是 MCP 的传统传输方式。\n\n```rust\n#[derive(Debug, Subcommand)]\npub enum Command {\n    Stdio(StdioCommand),\n    Http(HttpCommand),\n}\n```\n\n配置示例：\n```json\n{\n  \"command\": \"docker\",\n  \"args\": [\"run\", \"--rm\", \"-e\", \"ES_URL=https://localhost:9200\", \n           \"-e\", \"ES_API_KEY=<key>\", \"mcp-server-elasticsearch\", \"stdio\"],\n  \"env\": {}\n}\n```\n\n资料来源：[src/cli.rs:30-45](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### HTTP 模式\n\n支持远程访问的 HTTP 服务器模式，默认监听 `127.0.0.1:8080`。\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n**启动命令示例**：\n```bash\n./mcp-server-elasticsearch http --address 0.0.0.0:8080\n```\n\n> [!NOTE]\n> 社区反馈显示，HTTP/SSE 模式在某些 AI 代理（如 n8n）中存在兼容性问题。参见 [Issue #173](https://github.com/elastic/mcp-server-elasticsearch/issues/173)。\n\n---\n\n## 配置系统\n\n### 配置层次结构\n\n```mermaid\ngraph LR\n    A[环境变量] --> B[interpolator]\n    C[config.json5] --> B\n    B --> D[Configuration]\n    D --> E[ElasticsearchMcpConfig]\n    D --> F[McpServer]\n```\n\n### 主配置结构\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Configuration {\n    pub elasticsearch: elasticsearch::ElasticsearchMcpConfig,\n    #[serde(default)]\n    pub mcp_servers: HashMap<String, McpServer>,\n}\n```\n\n资料来源：[src/cli.rs:95-105](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### Elasticsearch 配置项\n\n| 参数 | 环境变量 | 类型 | 默认值 | 说明 |\n|------|----------|------|--------|------|\n| url | `ES_URL` | String | - | Elasticsearch 集群地址 |\n| api_key | `ES_API_KEY` | Option<String> | None | API Key 认证 |\n| username | `ES_USERNAME` | Option<String> | None | 用户名（需配合 password） |\n| password | `ES_PASSWORD` | Option<String> | None | 密码（需配合 username） |\n| ssl_skip_verify | `ES_SSL_SKIP_VERIFY` | bool | false | 跳过 SSL 证书验证 |\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\npub struct ElasticsearchMcpConfig {\n    /// Cluster URL\n    pub url: String,\n\n    /// API key\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub api_key: Option<String>,\n\n    /// Username\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub username: Option<String>,\n\n    /// Password\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub password: Option<String>,\n\n    /// Should we skip SSL certificate verification?\n    #[serde(default, deserialize_with = \"deserialize_bool_from_anything\")]\n    pub ssl_skip_verify: bool,\n\n    /// Search templates to expose as tools or resources\n    #[serde(default)]\n    pub tools: Tools,\n\n    /// Prompts\n    #[serde(default)]\n    pub prompts: Vec<String>,\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:60-90](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 环境变量插值\n\n配置文件中支持 `${VAR_NAME}` 和 `${VAR_NAME:default_value}` 语法：\n\n```rust\nlet value = if let Some((name, default)) = expr.split_once(':') {\n    lookup(name).unwrap_or(default.to_string())\n} else {\n    lookup(expr).ok_or_else(|| err(char_no, format!(\"env variable '{expr}' not defined\")))?\n};\n```\n\n**示例配置**：\n\n```json\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n资料来源：[src/utils/interpolator.rs:40-50](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n\n---\n\n## 认证机制\n\n### 认证流程\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP 客户端\n    participant Server as MCP Server\n    participant ES as Elasticsearch\n    \n    MCP->>Server: 请求 (含 Authorization Header)\n    Server->>Server: 检查 Authorization Header\n    \n    alt 使用请求头中的认证\n        Server->>ES: 转发 Authorization Header\n    else 使用配置中的认证\n        Server->>ES: 使用配置的 API Key 或 Basic Auth\n    end\n    \n    ES-->>Server: 响应\n    Server-->>MCP: 处理结果\n```\n\n### 认证凭证类型\n\n```rust\nimpl ElasticsearchMcp {\n    pub fn new_with_config(config: ElasticsearchMcpConfig, container_mode: bool) \n        -> anyhow::Result<base_tools::EsBaseTools> {\n        \n        let creds = if let Some(api_key) = config.api_key.clone() {\n            Some(Credentials::EncodedApiKey(api_key))\n        } else if let Some(username) = config.username.clone() {\n            let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n            Some(Credentials::Basic(username, pwd))\n        } else {\n            None\n        };\n        \n        // ... 构建 Transport\n        if let Some(creds) = creds {\n            transport = transport.auth(creds);\n        }\n    }\n}\n```\n\n### 优先级规则\n\n1. **请求级别**：如果传入的 HTTP 请求包含 `Authorization` Header，则优先使用\n2. **配置级别**：否则使用配置文件中的认证信息\n\n```rust\n/// If the incoming request is a http request and has an `Authorization` header, use it\n/// to authenticate to the remote ES instance.\npub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:105-130](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n---\n\n## 工具系统\n\n### 内置工具\n\n| 工具名称 | 功能 | 只读 | 参数 |\n|----------|------|------|------|\n| `list_indices` | 列出匹配的索引 | 是 | `index_pattern: String` |\n| `get_mappings` | 获取索引映射 | 是 | `index: String` |\n| `get_shards` | 获取分片信息 | 是 | `index: Option<String>` |\n| `search` | 执行搜索查询 | 是 | `index, fields?, query_body` |\n| `esql` | 执行 ES\\|QL 查询 | 是 | `query: String` |\n\n### 工具定义示例\n\n```rust\n#[tool(\n    description = \"List all available Elasticsearch indices\",\n    annotations(title = \"List ES indices\", read_only_hint = true)\n)]\nasync fn list_indices(\n    &self,\n    req_ctx: RequestContext<RoleServer>,\n    Parameters(ListIndicesParams { index_pattern }): Parameters<ListIndicesParams>,\n) -> Result<CallToolResult, rmcp::Error> {\n    let es_client = self.es_client.get(req_ctx);\n    \n    let response = es_client\n        .cat()\n        .indices(CatIndicesParts::Index(&[&index_pattern]))\n        .h(&[\"index\", \"status\", \"docs.count\"])\n        .format(\"json\")\n        .send()\n        .await;\n\n    let response: Vec<CatIndexResponse> = read_json(response).await?;\n\n    Ok(CallToolResult::success(vec![\n        Content::text(format!(\"Found {} indices:\", response.len())),\n        Content::json(response)?,\n    ]))\n}\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:80-105](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n\n### 自定义工具\n\n除内置工具外，系统还支持通过配置文件定义自定义工具：\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(tag = \"type\", rename_all = \"snake_case\")]\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n```\n\n**自定义工具配置示例**：\n\n```json\n{\n  \"tools\": {\n    \"custom\": {\n      \"my_esql_tool\": {\n        \"type\": \"esql\",\n        \"description\": \"Run specific ES|QL query\",\n        \"parameters\": {},\n        \"query\": \"FROM my-index | LIMIT 10\"\n      }\n    }\n  }\n}\n```\n\n### SearchTemplate 工具\n\n支持将预定义的搜索模板暴露为 MCP 工具：\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum SearchTemplate {\n    TemplateId(String),\n    Template(serde_json::Value),\n}\n```\n\n---\n\n## 数据模型\n\n### 搜索响应\n\n```rust\n#[derive(Serialize, Deserialize)]\npub struct SearchResult {\n    pub hits: Hits,\n    #[serde(default)]\n    pub aggregations: IndexMap<String, Value>,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Hits {\n    pub total: Option<TotalHits>,\n    pub hits: Vec<Hit>,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Hit {\n    #[serde(rename = \"_source\")]\n    pub source: Value,\n}\n```\n\n### 映射响应\n\n```rust\n#[derive(Serialize, Deserialize)]\npub struct MappingResponse {\n    // HashMap<String, Mappings>\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Mappings {\n    pub mappings: Mapping,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Mapping {\n    #[serde(rename = \"_meta\", skip_serializing_if = \"Option::is_none\")]\n    pub meta: Option<JsonObject>,\n    properties: HashMap<String, MappingProperty>,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct MappingProperty {\n    #[serde(rename = \"type\")]\n    pub type_: String,\n    #[serde(flatten)]\n    pub settings: HashMap<String, serde_json::Value>,\n}\n```\n\n> [!WARNING]\n> 社区反馈显示，`get_mappings` 工具在处理嵌套类型属性时存在问题。当嵌套属性未显式声明 `\"type\": \"nested\"` 时，服务器会抛出 \"error decoding response body\" 错误。参见 [Issue #185](https://github.com/elastic/mcp-server-elasticsearch/issues/185)。\n\n---\n\n## 请求处理流程\n\n```mermaid\ngraph TD\n    A[接收 MCP 请求] --> B{解析请求类型}\n    \n    B -->|工具调用| C[分发至工具处理器]\n    B -->|资源请求| D[返回资源数据]\n    B -->|提示请求| E[返回预定义提示]\n    \n    C --> F{选择认证方式}\n    \n    F -->|使用配置的认证| G[从配置构建凭证]\n    F -->|使用请求头认证| H[从 Authorization Header 提取]\n    \n    G --> I[构建 Elasticsearch 客户端]\n    H --> I\n    \n    I --> J[发送 HTTP 请求到 ES]\n    J --> K{ES 响应状态}\n    \n    K -->|成功 2xx| L[读取响应体]\n    K -->|错误 4xx/5xx| M[构建错误响应]\n    \n    L --> N{解析响应格式}\n    N -->|JSON| O[反序列化为结构体]\n    N -->|纯文本| P[直接返回]\n    \n    O --> Q[构建 MCP CallToolResult]\n    P --> Q\n    \n    M --> R[返回 rmcp::Error]\n    Q --> S[返回给 MCP 客户端]\n```\n\n### 错误处理\n\n```rust\npub fn handle_error(result: Result<Response, elasticsearch::Error>) \n    -> Result<Response, rmcp::Error> {\n    match result {\n        Ok(resp) => resp.error_for_status_code(),\n        Err(e) => {\n            tracing::error!(\"Error: {:?}\", &e);\n            Err(e)\n        }\n    }\n    .map_err(internal_error)\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:140-155](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n---\n\n## 核心组件关系\n\n```mermaid\nclassDiagram\n    class ElasticsearchMcp {\n        +new_with_config(config, container_mode) EsBaseTools\n    }\n    \n    class EsBaseTools {\n        +es_client: EsClientProvider\n        +tool_router: ToolRouter~EsBaseTools~\n    }\n    \n    class EsClientProvider {\n        -client: Elasticsearch\n        +get(context) Elasticsearch\n    }\n    \n    class ElasticsearchMcpConfig {\n        +url: String\n        +api_key: Option~String~\n        +username: Option~String~\n        +password: Option~String~\n        +ssl_skip_verify: bool\n    }\n    \n    ElasticsearchMcp --> ElasticsearchMcpConfig : 配置\n    ElasticsearchMcp --> EsBaseTools : 创建\n    EsBaseTools --> EsClientProvider : 持有\n    EsClientProvider --> Elasticsearch : HTTP 客户端\n```\n\n---\n\n## MCP 服务器配置\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\n#[serde(tag = \"type\")]\npub enum McpServer {\n    Sse(Http),\n    StreamableHttp(Http),\n    Stdio(Stdio),\n}\n```\n\n| 类型 | 用途 | 配置项 |\n|------|------|--------|\n| `Sse` | Server-Sent Events 模式 | url, headers |\n| `StreamableHttp` | 可流式传输的 HTTP | url, headers |\n| `Stdio` | 标准输入输出模式 | command, args, env |\n\n---\n\n## 启动流程\n\n```mermaid\nsequenceDiagram\n    participant Main as main.rs\n    participant Lib as lib.rs\n    participant CLI as cli.rs\n    participant Server as MCP Server\n    \n    Main->>CLI: 解析命令行参数\n    Main->>Lib: 调用创建处理器\n    Lib->>Lib: 加载配置文件\n    Lib->>Lib: 环境变量插值\n    Lib->>Lib: 构建 ElasticsearchMcpConfig\n    Lib->>Server: new_with_config()\n    Server->>Server: 构建 EsClientProvider\n    Server->>Server: 注册工具处理器\n    Main->>Server: 启动服务器循环\n```\n\n初始化流程（简化版）：\n\n```rust\n// 1. 加载默认配置模板\nlet config = r#\"{\n    \"elasticsearch\": {\n        \"url\": \"${ES_URL}\",\n        \"api_key\": \"${ES_API_KEY:}\",\n        \"username\": \"${ES_USERNAME:}\",\n        \"password\": \"${ES_PASSWORD:}\",\n        \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n    }\n}\"#.to_string();\n\n// 2. 环境变量插值\nlet config = interpolator::interpolate_from_env(config)?;\n\n// 3. JSON5 解析（支持注释）\nlet config: Configuration = serde_json5::from_str(&config)?;\n\n// 4. 构建处理器\nlet handler = elasticsearch::ElasticsearchMcp::new_with_config(\n    config.elasticsearch, \n    container_mode\n)?;\n```\n\n资料来源：[src/lib.rs:20-45](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n\n---\n\n## 安全考虑\n\n### 凭证管理\n\n| 凭证类型 | 存储位置 | 说明 |\n|----------|----------|------|\n| API Key | 环境变量 | 推荐生产环境使用 |\n| 用户名/密码 | 环境变量 | 需配合使用 |\n| Authorization Header | HTTP 请求头 | 支持 per-request 认证 |\n\n### 网络安全\n\n- **HTTPS**：当 `ES_URL` 使用 `https://` 时自动启用 TLS 加密\n- **容器模式**：自动重写 `localhost` 为 `host.docker.internal` 以支持 Docker 网络\n\n```rust\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n### 证书验证\n\n- **验证启用**：`ES_SSL_SKIP_VERIFY=false`（默认）\n- **验证跳过**：`ES_SSL_SKIP_VERIFY=true`（仅用于测试环境）\n\n---\n\n<a id='page-protocols'></a>\n\n## 通信协议配置\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n- [src/protocol/stdio.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/stdio.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n</details>\n\n# 通信协议配置\n\n## 概述\n\nElasticsearch MCP Server 支持两种通信协议模式，用于与 MCP 客户端建立连接并传输数据。协议配置是整个服务架构的核心组成部分，决定了客户端如何与服务器通信、认证方式如何处理，以及请求如何在 MCP 协议层进行路由。\n\n本项目实现了 **Stdio（标准输入/输出）** 和 **HTTP/SSE（服务器发送事件）** 两种传输模式，分别适用于不同的部署场景和客户端类型。\n\n## 协议架构\n\n```mermaid\ngraph TD\n    A[MCP 客户端] --> B{传输模式选择}\n    B -->|Stdio| C[Stdio 协议层]\n    B -->|HTTP/SSE| D[HTTP 协议层]\n    C --> E[rmcp 框架]\n    D --> E\n    E --> F[工具路由器 ToolRouter]\n    F --> G[Elasticsearch 工具集]\n    G --> H[Elasticsearch 集群]\n    \n    style C fill:#e1f5fe\n    style D fill:#fff3e0\n```\n\n## 传输模式\n\n### Stdio 模式\n\nStdio 模式是最基础的通信方式，通过标准输入（stdin）和标准输出（stdout）进行 JSON-RPC 消息的传输。这种模式适用于本地进程调用和命令行工具集成。\n\n**配置参数：**\n\n| 参数 | 标志 | 说明 |\n|------|------|------|\n| 配置文件 | `-c, --config` | 可选配置文件路径 |\n| 传输类型 | `stdio` | 通过 stdin/stdout 通信 |\n\nStdio 模式的启动命令：\n\n```bash\nmcp-server-elasticsearch stdio --config /path/to/config.json\n```\n\n### HTTP/SSE 模式\n\nHTTP 模式提供了远程访问能力，支持通过 HTTP 请求与 MCP 服务器交互。该模式使用 Axum 框架构建异步 HTTP 服务器，并可选地启用 SSE（Server-Sent Events）端点实现服务端推送。\n\n**核心配置参数：**\n\n| 参数 | 环境变量 | 默认值 | 说明 |\n|------|----------|--------|------|\n| 监听地址 | `HTTP_ADDRESS` | `127.0.0.1:8080` | 服务器监听的网络地址 |\n| SSE 启用 | `--sse` | 关闭 | 是否启用 SSE 端点 |\n| 配置文件 | `-c, --config` | 无 | 配置文件路径 |\n\nHTTP 模式的启动命令：\n\n```bash\nmcp-server-elasticsearch http --address 0.0.0.0:8080 --config /path/to/config.json\n```\n\n启用 SSE 模式：\n\n```bash\nmcp-server-elasticsearch http --address 0.0.0.0:8080 --sse\n```\n\n**服务端点：**\n\n| 端点 | 方法 | 功能 |\n|------|------|------|\n| `/` | GET | 服务器信息 |\n| `/ping` | GET | 健康检查 |\n| `/mcp/sse` | SSE | SSE 传输端点 |\n| `/mcp` | MCP | MCP 协议处理 |\n| `/_health/ready` | GET | 就绪探针 |\n| `/_health/live` | GET | 存活探针 |\n\n```mermaid\nsequenceDiagram\n    participant C as MCP 客户端\n    participant H as HTTP 服务器\n    participant M as MCP 处理层\n    participant ES as Elasticsearch\n    \n    C->>H: HTTP POST /mcp (JSON-RPC)\n    H->>M: 转发请求\n    M->>ES: 执行查询\n    ES-->>M: 返回结果\n    M-->>H: JSON-RPC 响应\n    H-->>C: HTTP Response\n    \n    Note over C,H: SSE 模式可选用于服务端推送\n    C->>H: GET /mcp/sse\n    H-->>C: SSE Stream\n```\n\n## 命令行接口结构\n\n源码位置：[src/cli.rs:1-100](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### Command 枚举\n\n```rust\n#[derive(Debug, Subcommand)]\npub enum Command {\n    Stdio(StdioCommand),\n    Http(HttpCommand),\n}\n```\n\n服务器支持两个顶层命令，分别对应不同的协议模式：\n\n- `Stdio` - 启动标准输入/输出服务器\n- `Http` - 启动 HTTP 服务器（可选 SSE）\n\n### HttpCommand 配置\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n## HTTP 协议实现\n\n源码位置：[src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n\n### 健康检查路由\n\n服务器实现了标准的 Kubernetes 就绪/存活探针接口：\n\n```rust\nlet health_router = {\n    Router::new()\n        .route(\"/ready\", get(async || (StatusCode::OK, \"Ready\\n\")))\n        .route(\"/live\", get(async || \"Alive\\n\"))\n};\n```\n\n### 路由聚合\n\n```rust\nlet main_router = Router::new()\n    .route(\"/\", get(hello))\n    .route(\"/ping\", get(async || (StatusCode::OK, \"Ready\\n\")))\n    .nest(\"/mcp/sse\", sse_router)\n    .nest(\"/mcp\", sh_router)\n    .nest(\"/_health\", health_router)\n    .with_state(());\n```\n\n### 服务器启动\n\n```rust\nlet listener = tokio::net::TcpListener::bind(config.bind).await?;\nlet server = axum::serve(listener, main_router).with_graceful_shutdown({\n    let ct = ct.clone();\n    async move {\n        ct.cancelled().await;\n        tracing::info!(\"http server cancelled\");\n    }\n});\n```\n\n## 认证与客户端上下文\n\n源码位置：[src/servers/elasticsearch/mod.rs:100-150](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### Credentials 配置\n\n```rust\npub struct ElasticsearchMcpConfig {\n    /// Cluster URL\n    pub url: String,\n\n    /// API key\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub api_key: Option<String>,\n\n    /// Username\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub username: Option<String>,\n\n    /// Password\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub password: Option<String>,\n\n    /// Should we skip SSL certificate verification?\n    #[serde(default, deserialize_with = \"deserialize_bool_from_anything\")]\n    pub ssl_skip_verify: bool,\n}\n```\n\n### 认证凭证构建\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n### EsClientProvider 客户端提供者\n\n```rust\npub struct EsClientProvider(Elasticsearch);\n\nimpl EsClientProvider {\n    pub fn new(client: Elasticsearch) -> Self {\n        EsClientProvider(client)\n    }\n\n    /// If the incoming request is a http request and has an `Authorization` header, use it\n    /// to authenticate to the remote ES instance.\n    pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n        // 根据请求上下文获取客户端实例\n    }\n}\n```\n\n## 配置加载流程\n\n源码位置：[src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n\n```mermaid\nflowchart LR\n    A[启动应用] --> B[解析命令行参数]\n    B --> C{协议模式}\n    C -->|stdio| D[启动 Stdio 服务器]\n    C -->|http| E[启动 HTTP 服务器]\n    E --> F[加载配置文件]\n    F --> G[环境变量插值]\n    G --> H[解析 JSON5 配置]\n    H --> I[构建 Elasticsearch 客户端]\n    I --> J[初始化工具路由]\n    J --> K[等待客户端连接]\n```\n\n### 环境变量插值\n\n配置支持 `${VAR_NAME}` 和 `${VAR_NAME:default_value}` 语法：\n\n```rust\nlet config = interpolator::interpolate_from_env(config)?;\n```\n\n### 默认配置模板\n\n```json\n{\n    \"elasticsearch\": {\n        \"url\": \"${ES_URL}\",\n        \"api_key\": \"${ES_API_KEY:}\",\n        \"username\": \"${ES_USERNAME:}\",\n        \"password\": \"${ES_PASSWORD:}\",\n        \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n    }\n}\n```\n\n## 协议选择指南\n\n| 场景 | 推荐模式 | 原因 |\n|------|----------|------|\n| 本地开发调试 | Stdio | 简单直接，无需网络配置 |\n| Claude Desktop / Cursor | Stdio | 原生支持 MCP stdio 协议 |\n| 远程服务部署 | HTTP | 支持网络访问和负载均衡 |\n| n8n 集成 | HTTP/SSE | 适合工作流自动化 |\n| 容器化部署 | 两者皆可 | 根据客户端类型选择 |\n\n## 常见问题\n\n### HTTP 401 认证失败\n\n社区 Issue #170 报告了在使用 Docker 部署时配置了正确的环境变量但仍出现认证失败的问题。解决方案：\n\n1. 确认环境变量 `ES_USERNAME`、`ES_PASSWORD` 或 `ES_API_KEY` 正确设置\n2. 使用 `docker exec` 进入容器验证凭证配置\n3. 测试与 Elasticsearch 集群的连接：\n\n```bash\n# 使用用户名密码\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n\n# 使用 API Key\ndocker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n```\n\n### SSE 与 Streamable HTTP\n\n由于 SSE 已被废弃，项目正在迁移到新的 Streamable HTTP 传输模式。详见社区 Issue #17。\n\n## 最佳实践\n\n1. **安全建议**\n   - 生产环境优先使用 API Key 认证\n   - 通过 HTTPS 连接到 Elasticsearch\n   - 使用 AWS Secrets Manager 管理敏感凭证\n\n2. **性能优化**\n   - HTTP 模式默认监听本地地址，如需远程访问改为 `0.0.0.0`\n   - 使用健康检查端点进行负载均衡器配置\n\n3. **配置管理**\n   - 使用配置文件集中管理复杂配置\n   - 利用环境变量插值实现环境差异化配置\n\n---\n\n<a id='page-tools'></a>\n\n## MCP 工具详解\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [故障排除指南](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n</details>\n\n# MCP 工具详解\n\n## 概述\n\nMCP Server Elasticsearch 提供了多个 MCP 工具，使 AI Agent 能够与 Elasticsearch 集群进行交互。这些工具通过 Model Context Protocol (MCP) 暴露，允许 LLM 通过自然语言执行索引管理、搜索查询、数据分析等操作。\n\n核心工具定义位于 `EsBaseTools` 结构体中，通过 `#[tool_router]` 宏注册每个工具的处理程序。工具支持通过请求上下文动态获取 Elasticsearch 客户端实例，实现基于请求的认证凭证传递。\n\n## 工具架构\n\n### 工具注册机制\n\n工具通过 Rust 宏 `#[tool]` 和 `#[tool_handler]` 进行声明和实现：\n\n```rust\n#[tool_router]\nimpl EsBaseTools {\n    #[tool(\n        description = \"工具描述\",\n        annotations(title = \"显示标题\", read_only_hint = true)\n    )]\n    async fn tool_name(\n        &self,\n        req_ctx: RequestContext<RoleServer>,\n        Parameters(Params): Parameters<Params>,\n    ) -> Result<CallToolResult, rmcp::Error> {\n        // 工具实现\n    }\n}\n```\n\n### 客户端提供机制\n\n工具通过 `EsClientProvider` 获取 Elasticsearch 客户端，该提供者支持基于 HTTP 请求 Authorization 头的动态认证：\n\n```rust\n#[derive(Clone)]\npub struct EsClientProvider(Elasticsearch);\n\nimpl EsClientProvider {\n    pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n        // 从请求上下文中提取认证信息\n    }\n}\n```\n\n## 核心工具列表\n\n### 1. list_indices - 列出索引\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index_pattern | String | 是 | 索引名称或通配符模式 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:73-95`\n\n该工具调用 Elasticsearch Cat API，返回匹配的索引列表：\n\n```rust\nasync fn list_indices(\n    &self,\n    req_ctx: RequestContext<RoleServer>,\n    Parameters(ListIndicesParams { index_pattern }): Parameters<ListIndicesParams>,\n) -> Result<CallToolResult, rmcp::Error> {\n    let es_client = self.es_client.get(req_ctx);\n    let response = es_client\n        .cat()\n        .indices(CatIndicesParts::Index(&[&index_pattern]))\n        .h(&[\"index\", \"status\", \"docs.count\"])\n        .format(\"json\")\n        .send()\n        .await;\n\n    let response: Vec<CatIndexResponse> = read_json(response).await?;\n    Ok(CallToolResult::success(vec![\n        Content::text(format!(\"Found {} indices:\", response.len())),\n        Content::json(response)?,\n    ]))\n}\n```\n\n### 2. get_mappings - 获取索引映射\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index | String | 是 | 索引名称 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:97-120`\n\n> [!NOTE]\n> **已知问题**: 当嵌套属性未显式指定 `\"type\": \"nested\"` 时，`get_mappings` 工具会返回 `\"error decoding response body\"` 错误。这是 Issue #185 报告的问题，尽管 Elasticsearch 规范允许省略显式类型声明。\n\n### 3. search - 执行搜索\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index | String | 是 | 索引名称 |\n| query_body | Map<String, Value> | 是 | 完整的 Elasticsearch Query DSL 对象 |\n| fields | Option<Vec<String>> | 否 | 指定返回的字段列表 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:130-180`\n\nsearch 工具支持完整的 Elasticsearch Query DSL，包括 query、size、from、sort、aggregations 等参数。\n\n```rust\nstruct SearchParams {\n    index: String,\n    fields: Option<Vec<String>>,\n    query_body: Map<String, Value>,\n}\n```\n\n返回结果包含：\n- `hits.total` - 匹配文档总数\n- `hits.hits` - 文档数组\n- `aggregations` - 聚合结果（如果有）\n\n### 4. esql - ES|QL 查询\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| query | String | 是 | 完整的 ES|QL 查询语句 |\n\n**实现位置**: `src/servers/elasticsearch/mod.rs:46-50`\n\n```rust\npub enum EsqlResultFormat {\n    #[default]\n    Json,   // 输出为 JSON 对象数组或单个对象\n    Value,  // 如果是单个属性，输出其值\n}\n```\n\n### 5. get_shards - 获取分片信息\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index | Option<String> | 否 | 可选的索引名称 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:41-69`\n\n该工具返回分片的详细信息：\n\n```rust\npub struct CatShardsResponse {\n    pub index: String,\n    pub shard: usize,\n    pub prirep: String,    // primary 或 replica\n    pub state: String,    // STARTED, INITIALIZING, etc.\n    pub docs: Option<u64>,\n    pub store: Option<u64>,\n    pub node: String,\n}\n```\n\n## 自定义工具扩展\n\n### Tools 配置结构\n\n用户可以通过配置文件定义自定义工具：\n\n```rust\npub struct Tools {\n    #[serde(flatten)]\n    pub incl_excl: Option<IncludeExclude>,\n    pub custom: HashMap<String, CustomTool>,\n}\n\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n```\n\n### SearchTemplateTool\n\n支持两种搜索模板定义方式：\n\n```rust\npub enum SearchTemplate {\n    TemplateId(String),           // 通过模板 ID 引用\n    Template(serde_json::Value),   // 内联模板定义\n}\n```\n\n## 工具响应格式\n\n所有工具通过 `CallToolResult` 返回结果：\n\n```rust\npub struct SearchResult {\n    pub hits: Hits,\n    #[serde(default)]\n    pub aggregations: IndexMap<String, Value>,\n}\n\npub struct Hits {\n    pub total: Option<TotalHits>,\n    pub hits: Vec<Hit>,\n}\n\npub struct Hit {\n    #[serde(rename = \"_source\")]\n    pub source: Value,\n}\n```\n\n## 配置选项\n\n### ElasticsearchMcpConfig\n\n| 配置项 | 环境变量 | 类型 | 默认值 | 说明 |\n|--------|----------|------|--------|------|\n| url | ES_URL | String | - | Elasticsearch 集群地址 |\n| api_key | ES_API_KEY | Option<String> | None | API Key 认证 |\n| username | ES_USERNAME | Option<String> | None | 用户名 |\n| password | ES_PASSWORD | Option<String> | None | 密码 |\n| ssl_skip_verify | ES_SSL_SKIP_VERIFY | bool | false | 跳过 SSL 验证 |\n| tools | - | Tools | empty | 自定义工具配置 |\n\n**实现位置**: `src/servers/elasticsearch/mod.rs:24-52`\n\n## 数据流图\n\n```mermaid\ngraph TD\n    A[MCP Client 请求] --> B[RequestContext 解析]\n    B --> C{认证方式}\n    C -->|API Key| D[Credentials::EncodedApiKey]\n    C -->|用户名密码| E[Credentials::Basic]\n    C -->|无认证| F[None]\n    D --> G[TransportBuilder 配置]\n    E --> G\n    F --> G\n    G --> H[Elasticsearch 客户端]\n    H --> I{请求类型}\n    I -->|list_indices| J[Cat Indices API]\n    I -->|get_mappings| K[Get Mapping API]\n    I -->|search| L[Search API]\n    I -->|esql| M[ES|QL API]\n    I -->|get_shards| N[Cat Shards API]\n    J --> O[CatIndexResponse]\n    K --> P[Mapping JSON]\n    L --> Q[SearchResult]\n    M --> R[ES|QL Result]\n    N --> S[CatShardsResponse]\n    O --> T[CallToolResult]\n    P --> T\n    Q --> T\n    R --> T\n    S --> T\n```\n\n## HTTP 协议支持\n\nMCP Server 支持通过 HTTP 进行远程访问：\n\n### HttpServerConfig\n\n| 配置项 | 类型 | 说明 |\n|--------|------|------|\n| bind | SocketAddr | TCP 监听地址 |\n| ct | CancellationToken | 取消令牌 |\n| keep_alive | Option<Duration> | SSE 保活时间 |\n| stateful_mode | bool | 启用状态会话 |\n| session_manager | Arc<M> | 会话管理器 |\n\n**实现位置**: `src/protocol/http.rs:13-30`\n\n### 命令行配置\n\n```rust\npub struct HttpCommand {\n    pub config: Option<PathBuf>,        // 配置文件路径\n    pub address: Option<SocketAddr>,   // 监听地址 [default: 127.0.0.1:8080]\n    pub sse: bool,                      // 启用 SSE 端点\n}\n```\n\n## 已知问题\n\n| Issue | 描述 | 影响 |\n|-------|------|------|\n| #185 | `get_mappings` 工具在嵌套属性未显式指定 `type: nested` 时失败 | get_mappings 功能受限 |\n| #170 | Basic 认证失败 401 Unauthorized | 认证配置问题 |\n| #173 | 通过 HTTP/SSE 访问时部分功能返回错误 | HTTP 模式稳定性 |\n\n## 相关文档\n\n- [官方 MCP 协议文档](https://modelcontextprotocol.io/docs/concepts/transports#built-in-transport-types)\n- [Elasticsearch MCP Server 发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases)\n- [Dependency Dashboard](https://github.com/elastic/mcp-server-elasticsearch/issues/6)\n\n---\n\n<a id='page-config'></a>\n\n## 配置与工具过滤\n\n### 相关页面\n\n相关主题：[MCP 工具详解](#page-tools), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n</details>\n\n# 配置与工具过滤\n\n## 概述\n\nElasticsearch MCP Server 的配置与工具过滤系统提供了灵活的运行时自定义能力，允许管理员通过配置文件和环境变量来控制服务器行为、认证方式以及可用工具集。该系统支持两种传输模式（stdio 和 streamable-HTTP），配置通过 JSON5 格式加载，并支持 `${ENV_VAR}` 或 `${ENV_VAR:default}` 语法的环境变量插值。\n\n## 配置架构\n\n### 配置加载流程\n\n```mermaid\ngraph TD\n    A[CLI 启动命令] --> B[加载配置文件]\n    B --> C[读取 JSON5 内容]\n    C --> D[环境变量插值]\n    D --> E[解析为 Configuration]\n    E --> F[创建 ElasticsearchMcp]\n    \n    G[环境变量] -.->|${VAR}| D\n```\n\n配置加载逻辑位于 `src/lib.rs` 中，服务器启动时首先读取配置文件，然后通过插值器处理环境变量引用，最后解析为强类型配置结构体。\n\n### 核心配置结构体\n\n#### ElasticsearchMcpConfig\n\n`ElasticsearchMcpConfig` 是服务器的核心配置单元，定义了所有可配置的运行时参数：\n\n| 字段 | 类型 | 说明 | 环境变量 |\n|------|------|------|----------|\n| `url` | `String` | Elasticsearch 集群 URL | `ES_URL` |\n| `api_key` | `Option<String>` | API Key 认证 | `ES_API_KEY` |\n| `username` | `Option<String>` | 用户名 | `ES_USERNAME` |\n| `password` | `Option<String>` | 密码 | `ES_PASSWORD` |\n| `ssl_skip_verify` | `bool` | 跳过 SSL 证书验证 | `ES_SSL_SKIP_VERIFY` |\n| `tools` | `Tools` | 工具配置 | - |\n| `prompts` | `Vec<String>` | Prompt 模板列表 | - |\n\n资料来源：[src/servers/elasticsearch/mod.rs:55-78]()\n\n### 配置示例\n\n服务器提供了默认配置模板，位于 `src/lib.rs`：\n\n```json5\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n该模板展示了配置文件的推荐格式，支持：\n- JSON5 语法（注释和多行字符串）\n- 环境变量插值\n- 默认值指定\n\n## 认证配置\n\n### 认证凭证优先级\n\n系统支持三种认证方式，但同一时间只能使用一种：\n\n1. **API Key 认证**（优先）\n2. **用户名/密码认证**\n3. **无认证**（适用于信任网络）\n\n认证逻辑在 `ElasticsearchMcp::new_with_config` 方法中实现：\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:88-96]()\n\n### HTTP 请求转发认证\n\n`EsClientProvider` 提供了一个重要的功能：支持将 HTTP 请求中的 `Authorization` 头转发到远程 Elasticsearch 实例。这在 MCP 服务器代理认证时尤为重要。\n\n## 环境变量插值系统\n\n### 插值语法\n\n插值器支持两种语法格式：\n\n| 语法 | 说明 | 示例 |\n|------|------|------|\n| `${VAR}` | 必填变量，不存在则报错 | `${ES_URL}` |\n| `${VAR:default}` | 可选变量，默认值为 `default` | `${ES_SSL_SKIP_VERIFY:false}` |\n\n### 插值实现\n\n插值逻辑位于 `src/utils/interpolator.rs`，核心函数签名：\n\n```rust\npub fn interpolate(\n    input: String,\n    lookup: impl Fn(&str) -> Option<String>,\n) -> Result<String, InterpolationError>\n```\n\n工作原理：\n1. 扫描输入字符串中的 `${...}` 模式\n2. 对每个模式调用 `lookup` 函数获取值\n3. 支持默认值语法 `name:default`\n4. 返回插值后的字符串\n\n资料来源：[src/utils/interpolator.rs]()\n\n### 单元测试示例\n\n```rust\n#[test]\nfn good_extrapolation() -> anyhow::Result<()> {\n    assert_eq!(\"foo_value01234\", expand(\"${foo}01234\")?);\n    assert_eq!(\"foo_value01234\\n1234bar_value\", expand(\"${foo}01234\\n1234${bar}\")?);\n    Ok(())\n}\n```\n\n资料来源：[src/utils/interpolator.rs:47-51]()\n\n## 工具配置与过滤\n\n### 工具注册架构\n\n```mermaid\ngraph TD\n    A[Tools 配置] --> B[IncludeExclude 包含/排除规则]\n    A --> C[CustomTool 自定义工具]\n    \n    C --> D[EsqlTool ES|QL 查询工具]\n    C --> E[SearchTemplateTool 搜索模板工具]\n    \n    F[基础工具集] --> G[EsBaseTools]\n    F -->|list_indices| G\n    F -->|get_mappings| G\n    F -->|search| G\n    F -->|get_shards| G\n    F -->|esql| G\n```\n\n### 工具结构定义\n\n#### Tools 结构体\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\npub struct Tools {\n    #[serde(flatten)]\n    pub incl_excl: Option<IncludeExclude>,\n    pub custom: HashMap<String, CustomTool>,\n}\n```\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `incl_excl` | `Option<IncludeExclude>` | 包含/排除过滤规则 |\n| `custom` | `HashMap<String, CustomTool>` | 自定义工具集合 |\n\n资料来源：[src/servers/elasticsearch/mod.rs:27-32]()\n\n#### 自定义工具类型\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(tag = \"type\", rename_all = \"snake_case\")]\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n```\n\n| 工具类型 | 说明 | 配置字段 |\n|----------|------|----------|\n| `Esql` | ES|QL 查询工具 | `query`, `format` |\n| `SearchTemplate` | 搜索模板工具 | `template_id` 或 `template` |\n\n资料来源：[src/servers/elasticsearch/mod.rs:34-48]()\n\n### 基础工具集 (EsBaseTools)\n\n`EsBaseTools` 是 MCP 服务器的核心工具提供者，定义了所有内置工具：\n\n| 工具名称 | 功能 | 参数 |\n|----------|------|------|\n| `list_indices` | 列出 Elasticsearch 索引 | `index_pattern` |\n| `get_mappings` | 获取索引映射 | `index` |\n| `search` | 执行搜索查询 | `index`, `fields`, `query_body` |\n| `get_shards` | 获取分片信息 | `index`（可选） |\n| `esql` | 执行 ES|QL 查询 | `query` |\n\n#### 工具参数定义示例\n\n```rust\n#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]\nstruct ListIndicesParams {\n    /// Index pattern of Elasticsearch indices to list\n    pub index_pattern: String,\n}\n\n#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]\nstruct SearchParams {\n    /// Name of the Elasticsearch index to search\n    index: String,\n    /// Name of the fields that need to be returned (optional)\n    fields: Option<Vec<String>>,\n    /// Complete Elasticsearch query DSL object\n    query_body: Map<String, Value>,\n}\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:112-137]()\n\n### 工具注解系统\n\n每个工具都可以通过 `annotations` 属性添加元数据：\n\n```rust\n#[tool(\n    description = \"List all available Elasticsearch indices\",\n    annotations(title = \"List ES indices\", read_only_hint = true)\n)]\n```\n\n| 注解字段 | 说明 |\n|----------|------|\n| `title` | 工具显示标题 |\n| `read_only_hint` | 仅读提示（优化 LLM 决策） |\n\n## CLI 启动配置\n\n### 命令行结构\n\n```rust\n#[derive(Debug, Subcommand)]\npub enum Command {\n    Stdio(StdioCommand),\n    Http(HttpCommand),\n}\n```\n\n| 命令 | 说明 | 默认端口 |\n|------|------|----------|\n| `stdio` | 标准输入/输出模式 | - |\n| `http` | Streamable-HTTP 模式 | 8080 |\n\n### HTTP 模式配置\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n资料来源：[src/cli.rs]()\n\n### Stdio 模式配置\n\n```rust\n#[derive(Debug, Args)]\npub struct StdioCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n}\n```\n\n## 客户端提供器\n\n### EsClientProvider 实现\n\n`EsClientProvider` 是对 Elasticsearch 客户端的包装，提供基于请求上下文的客户端实例：\n\n```rust\n#[derive(Clone)]\npub struct EsClientProvider(Elasticsearch);\n\nimpl EsClientProvider {\n    pub fn new(client: Elasticsearch) -> Self {\n        EsClientProvider(client)\n    }\n\n    /// If the incoming request is a http request and has an `Authorization` header, use it\n    /// to authenticate to the remote ES instance.\n    pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n        // 返回配置好的客户端实例\n    }\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:106-119]()\n\n### 错误处理\n\n```rust\npub fn handle_error(result: Result<Response, elasticsearch::Error>) -> Result<Response, rmcp::Error> {\n    match result {\n        Ok(resp) => resp.error_for_status_code(),\n        Err(e) => {\n            tracing::error!(\"Error: {:?}\", &e);\n            Err(e)\n        }\n    }\n    .map_err(internal_error)\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:121-130]()\n\n## 配置最佳实践\n\n### 生产环境配置\n\n1. **使用环境变量存储敏感信息**\n   - API Key 或用户名/密码不应硬编码在配置文件中\n   - 推荐使用 `${ES_API_KEY}` 或 `${ES_PASSWORD}` 语法\n\n2. **SSL 证书验证**\n   - 生产环境应保持 `ssl_skip_verify: false`\n   - 如需跳过验证，明确设置 `${ES_SSL_SKIP_VERIFY:true}`\n\n3. **工具限制**\n   - 通过配置文件的 `incl_excl` 规则限制可用工具\n   - 使用 `custom` 字段添加预定义的 ES|QL 查询或搜索模板\n\n### 容器化部署\n\n```bash\ndocker run --rm \\\n  -e ES_URL=https://elasticsearch:9200 \\\n  -e ES_API_KEY=your-api-key \\\n  -e ES_SSL_SKIP_VERIFY=false \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n## 已知问题\n\n社区反馈的认证相关问题（#170）表明，在 Docker 容器部署时需要确保：\n- 环境变量名称正确（区分大小写）\n- `ES_USERNAME` 和 `ES_PASSWORD` 同时设置或使用 API Key\n- 检查容器日志中的认证错误信息\n\n---\n\n<a id='page-deployment'></a>\n\n## Docker 部署指南\n\n### 相关页面\n\n相关主题：[认证配置](#page-auth), [通信协议配置](#page-protocols), [安全最佳实践](#page-security)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [Dockerfile](https://github.com/elastic/mcp-server-elasticsearch/blob/main/Dockerfile)\n- [Dockerfile-8000](https://github.com/elastic/mcp-server-elasticsearch/blob/main/Dockerfile-8000)\n- [.env-example](https://github.com/elastic/mcp-server-elasticsearch/blob/main/.env-example)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n</details>\n\n# Docker 部署指南\n\n本文档介绍如何通过 Docker 容器方式部署 Elasticsearch MCP Server。Elasticsearch MCP Server 是基于 Model Context Protocol (MCP) 的 Elasticsearch 集成服务，允许 AI 代理通过标准化接口与 Elasticsearch 集群进行交互。\n\n## 核心概念\n\n### 架构概览\n\nMCP Server 以 Docker 容器的形式运行，提供两种协议支持：\n\n```mermaid\ngraph TD\n    A[AI Agent / MCP Client] -->|Stdio| B[MCP Server 容器<br/>stdio 模式]\n    A -->|Streamable HTTP| C[MCP Server 容器<br/>HTTP 模式]\n    B -->|HTTPS| D[Elasticsearch 集群]\n    C -->|HTTPS| D\n```\n\n### 容器模式识别\n\nMCP Server 支持自动检测运行环境的容器模式。当检测到容器运行时，服务器会自动将 `localhost` 替换为容器网络别名，以确保容器内的网络请求能正确路由到宿主机服务（如本地 Elasticsearch 集群）。\n\n资料来源：[src/lib.rs:89-101]()\n\n容器模式通过以下逻辑实现：\n\n```mermaid\ngraph LR\n    A[检测运行环境] --> B{是否容器模式?}\n    B -->|是| C[替换 localhost]\n    B -->|否| D[保持 localhost]\n    C --> E[host.containers.internal<br/>Podman<br/>其他别名]\n```\n\n支持的宿主机别名包括：\n- `host.containers.internal`（Podman 及部分 Docker 环境）\n- 其他平台特定别名\n\n资料来源：[src/servers/elasticsearch/mod.rs:89-95]()\n\n## 环境变量配置\n\n### 必需变量\n\n| 变量名 | 说明 | 示例值 |\n|--------|------|--------|\n| `ES_URL` | Elasticsearch 集群地址 | `https://localhost:9200` |\n| `ES_API_KEY` | API Key 认证密钥 | `base64EncodedApiKey...` |\n| `ES_USERNAME` | 基本认证用户名 | `elastic` |\n| `ES_PASSWORD` | 基本认证密码 | `password123` |\n| `ES_SSL_SKIP_VERIFY` | 跳过 SSL 证书验证 | `true` / `false` |\n\n### 配置优先级\n\n环境变量支持默认值语法，格式为 `${VAR_NAME:default_value}`。当变量未定义时使用默认值。\n\n资料来源：[src/lib.rs:67-77]()\n\n```bash\n# .env 文件示例\nES_URL=https://elasticsearch:9200\nES_API_KEY=your_api_key_here\nES_SSL_SKIP_VERIFY=false\n```\n\n### 认证方式\n\nMCP Server 支持三种认证方式：\n\n1. **API Key 认证**（推荐）：通过 `ES_API_KEY` 环境变量设置\n2. **用户名密码认证**：通过 `ES_USERNAME` 和 `ES_PASSWORD` 环境变量设置\n3. **SSL 跳过验证**：仅在开发环境中使用 `ES_SSL_SKIP_VERIFY=true`\n\n> [!IMPORTANT]\n> 认证凭证仅存储在环境变量中，不会持久化到磁盘或写入日志。\n\n资料来源：[.env-example]()\n\n## Docker 镜像\n\n### 镜像信息\n\n官方镜像托管在 Elastic 的 Docker Registry：\n\n```\ndocker.elastic.co/mcp/elasticsearch\n```\n\n### 镜像版本\n\n| 标签 | 说明 |\n|------|------|\n| `latest` | 最新稳定版本 |\n| `v0.4.6` | 特定版本号（当前最新） |\n\n### 端口配置\n\n| Dockerfile | 默认端口 | 用途 |\n|------------|----------|------|\n| `Dockerfile` | 8080 | HTTP 模式监听端口 |\n| `Dockerfile-8000` | 8000 | 备用端口配置 |\n\nv0.4.3 之前的版本默认端口为 8000，之后统一改为 8080。\n\n资料来源：[README.md]()\n\n## Stdio 模式部署\n\nStdio 模式适用于直接与 MCP Client 进程通信的场景。\n\n### 启动命令\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-cluster.es.region.amazonaws.com:9200\" \\\n  -e ES_API_KEY=\"your_api_key\" \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n### Claude Desktop 配置\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\",\n        \"--rm\",\n        \"-e\", \"ES_URL\",\n        \"-e\", \"ES_API_KEY\",\n        \"docker.elastic.co/mcp/elasticsearch\",\n        \"stdio\"\n      ],\n      \"env\": {\n        \"ES_URL\": \"<elasticsearch-cluster-url>\",\n        \"ES_API_KEY\": \"<elasticsearch-API-key>\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md]()\n\n## HTTP 模式部署\n\nHTTP 模式适用于需要远程访问、多客户端并发连接或通过代理桥接的场景。\n\n### 启动命令\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-cluster.es.region.amazonaws.com:9200\" \\\n  -e ES_API_KEY=\"your_api_key\" \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n### 端点说明\n\n| 端点 | 方法 | 说明 |\n|------|------|------|\n| `/mcp` | POST | Streamable HTTP MCP 端点 |\n| `/ping` | GET | 健康检查端点 |\n\n### 健康检查\n\n```bash\ncurl http://<host>:8080/ping\n```\n\n成功响应返回 `pong`。\n\n资料来源：[README.md]()\n\n### Claude Desktop 代理配置\n\n由于 Claude Desktop 免费版仅支持 stdio 协议，需要使用 `mcp-proxy` 进行协议桥接：\n\n1. 安装 mcp-proxy：\n```bash\nuv tool install mcp-proxy\n```\n\n2. 配置 Claude Desktop：\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"/<home-directory>/.local/bin/mcp-proxy\",\n      \"args\": [\n        \"--transport=streamablehttp\",\n        \"--header\", \"Authorization\", \"ApiKey <elasticsearch-API-key>\",\n        \"http://<mcp-server-host>:<mcp-server-port>/mcp\"\n      ]\n    }\n  }\n}\n```\n\n资料来源：[README.md]()\n\n## 故障排查\n\n### 常见问题\n\n#### 认证失败 (401 Unauthorized)\n\nIssue #170 中用户反馈使用 Docker 部署时环境变量配置正确但仍出现认证失败：\n\n- 确认 `ES_USERNAME`、`ES_PASSWORD` 环境变量名称拼写正确（区分大小写）\n- v0.4.5 版本修复了用户名环境变量名称问题，确保使用正确的变量名\n- 验证 Elasticsearch 集群的认证配置\n\n#### 连接超时\n\n如果容器无法连接到 Elasticsearch 集群：\n\n```bash\n# 从容器内部测试连接\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n```\n\n#### 容器模式 localhost 问题\n\n如果容器内访问宿主机 Elasticsearch 失败，检查容器是否正确识别容器模式。MCP Server 会自动将 `localhost` 替换为网络别名。\n\n资料来源：[src/servers/elasticsearch/mod.rs:89-95]()\n\n### 日志查看\n\n```bash\n# 查看容器日志\ndocker logs <container-id>\n\n# 实时跟踪日志\ndocker logs -f <container-id>\n```\n\n日志中可能出现的错误类型：\n- Elasticsearch 连接失败\n- 认证错误\n- 网络连接问题\n\n### 验证连接\n\n1. 检查容器状态：\n```bash\ndocker ps | grep elasticsearch-mcp-server\n```\n\n2. 测试健康端点：\n```bash\ncurl http://<host>:8080/ping\n```\n\n3. 通过 MCP Client 测试功能（如 `list_indices`、`get_shards`）\n\n## 安全最佳实践\n\n### 凭证管理\n\n| 安全措施 | 说明 |\n|----------|------|\n| 环境变量存储 | 凭证仅存储在环境变量中 |\n| 定期轮换 | 生产环境建议 30-90 天轮换 API Key |\n| 最小权限 | 使用仅读权限的 API Key |\n| 不提交凭证 | 禁止将凭证提交到版本控制 |\n\n### 网络安全\n\n- 使用 HTTPS 协议 (`ES_URL` 以 `https://` 开头)\n- 配置正确的安全组和网络 ACL\n- 生产环境避免使用 `ES_SSL_SKIP_VERIFY=true`\n\n### AWS 部署建议\n\n在 AWS 环境中部署时：\n- 使用 AWS Secrets Manager 管理凭证\n- 通过 IAM 角色控制 EKS/EC2 访问权限\n- 配置 VPC 安全组规则\n\n资料来源：[README.md]()\n\n## CLI_ARGS 环境变量\n\nv0.4.1 版本新增 `CLI_ARGS` 环境变量支持，可作为传递命令行参数的替代方式：\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://elasticsearch:9200\" \\\n  -e ES_API_KEY=\"your_key\" \\\n  -e CLI_ARGS=\"--config /path/to/config.json\" \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n资料来源：[README.md]()\n</details>\n\n---\n\n<a id='page-auth'></a>\n\n## 认证配置\n\n### 相关页面\n\n相关主题：[Docker 部署指南](#page-deployment), [故障排除指南](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [.env-example](https://github.com/elastic/mcp-server-elasticsearch/blob/main/.env-example)\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n</details>\n\n# 认证配置\n\n## 概述\n\nElasticsearch MCP Server 支持两种主要的认证方式与 Elasticsearch 集群建立安全连接。本页详细说明认证配置的工作原理、配置参数以及常见问题的排查方法。\n\n认证配置在 MCP Server 启动时通过环境变量或配置文件加载，用于建立与 Elasticsearch 集群的信任连接。所有认证凭证仅在运行时内存中处理，不会持久化到磁盘或日志中。\n\n## 认证方式\n\nMCP Server 支持两种认证方式：\n\n| 认证方式 | 配置参数 | 说明 |\n|---------|---------|------|\n| API Key 认证 | `ES_API_KEY` | 使用 Elasticsearch API 密钥进行认证 |\n| 用户名密码认证 | `ES_USERNAME` + `ES_PASSWORD` | 使用用户名和密码进行 Basic 认证 |\n\n> [!NOTE]\n> API Key 认证优先于用户名密码认证。如果同时配置了 API Key 和用户名密码，系统将使用 API Key。\n\n### 认证凭证优先级\n\n```mermaid\ngraph TD\n    A[启动 MCP Server] --> B{是否配置 ES_API_KEY?}\n    B -->|是| C[使用 API Key 认证]\n    B -->|否| D{是否配置 ES_USERNAME?}\n    D -->|是| E{是否配置 ES_PASSWORD?}\n    E -->|是| F[使用 Basic 认证]\n    E -->|否| G[无认证]\n    D -->|否| G\n    C --> H[连接 Elasticsearch]\n    F --> H\n    G --> H\n```\n\n## 配置参数详解\n\n### 环境变量配置\n\n| 环境变量 | 类型 | 必填 | 默认值 | 说明 |\n|---------|------|------|--------|------|\n| `ES_URL` | String | 是 | - | Elasticsearch 集群地址，如 `https://localhost:9200` |\n| `ES_API_KEY` | String | 否 | 空 | API Key 认证凭证 |\n| `ES_USERNAME` | String | 否 | 空 | Basic 认证用户名 |\n| `ES_PASSWORD` | String | 否 | 空 | Basic 认证密码 |\n| `ES_SSL_SKIP_VERIFY` | Boolean | 否 | `false` | 是否跳过 SSL 证书验证 |\n\n> [!CAUTION]\n> `ES_SSL_SKIP_VERIFY=true` 会绕过 SSL 证书验证，仅在测试环境中使用。生产环境应配置正确的 CA 证书。\n\n### 配置文件格式\n\n除了环境变量，还可以通过配置文件指定认证信息。配置文件支持 JSON5 格式（允许注释和多行字符串）：\n\n```json5\n{\n    \"elasticsearch\": {\n        \"url\": \"${ES_URL}\",\n        \"api_key\": \"${ES_API_KEY:}\",\n        \"username\": \"${ES_USERNAME:}\",\n        \"password\": \"${ES_PASSWORD:}\",\n        \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n    }\n}\n```\n\n配置文件中的 `${VAR:default}` 语法表示环境变量插值，如果环境变量未设置则使用默认值。\n\n## 认证实现架构\n\n### 核心组件\n\n```mermaid\nclassDiagram\n    class ElasticsearchMcpConfig {\n        +String url\n        +Option~String~ api_key\n        +Option~String~ username\n        +Option~String~ password\n        +bool ssl_skip_verify\n    }\n    \n    class ElasticsearchMcp {\n        +new_with_config(config, container_mode) EsBaseTools\n    }\n    \n    class EsClientProvider {\n        +Elasticsearch client\n        +get(context) Elasticsearch\n    }\n    \n    class Credentials {\n        <<enumeration>>\n        EncodedApiKey(String)\n        Basic(String, String)\n    }\n    \n    ElasticsearchMcpConfig --> ElasticsearchMcp : 配置输入\n    ElasticsearchMcp --> EsClientProvider : 创建客户端\n    ElasticsearchMcpConfig --> Credentials : 生成凭证\n    Credentials --> EsClientProvider : 注入传输层\n```\n\n### 凭证生成逻辑\n\n凭证生成在 `ElasticsearchMcp::new_with_config` 方法中完成：\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:57-64](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 传输层配置\n\n凭证创建后，通过 Elasticsearch Rust 客户端的 `TransportBuilder` 注入到传输层：\n\n```rust\nlet mut transport = elasticsearch::http::transport::TransportBuilder::new(pool);\nif let Some(creds) = creds {\n    transport = transport.auth(creds);\n}\n// ... 继续配置 SSL 等选项\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:66-70](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n## 运行时认证\n\n### HTTP 请求上下文认证\n\n`EsClientProvider` 支持从传入的 HTTP 请求中提取 `Authorization` 头，用于对远程 ES 实例进行认证：\n\n```rust\npub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n    // 从请求上下文中获取 Authorization 头\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:97-101](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 容器模式下的 localhost 重写\n\n当 MCP Server 在 Docker 容器中运行时，`rewrite_localhost` 函数会将 `localhost` URL 重写为 `host.docker.internal`，以便容器可以正确访问宿主机上的 Elasticsearch 服务：\n\n```rust\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:51-53](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n## 配置示例\n\n### 使用 API Key 认证\n\n```bash\n# 环境变量方式\nexport ES_URL=https://elasticsearch.example.com:9200\nexport ES_API_KEY=your_api_key_here\n\n# 运行 MCP Server\ndocker run -e ES_URL -e ES_API_KEY elastic/mcp-server-elasticsearch\n```\n\n### 使用用户名密码认证\n\n```bash\n# 环境变量方式\nexport ES_URL=https://elasticsearch.example.com:9200\nexport ES_USERNAME=elastic\nexport ES_PASSWORD=your_password\n\n# 运行 MCP Server\ndocker run -e ES_URL -e ES_USERNAME -e ES_PASSWORD elastic/mcp-server-elasticsearch\n```\n\n### 使用 .env 文件\n\n```bash\n# 创建 .env 文件\ncat > .env << 'EOF'\nES_URL=https://elasticsearch.example.com:9200\nES_USERNAME=elastic\nES_PASSWORD=your_password\nES_SSL_SKIP_VERIFY=false\nEOF\n\n# 运行 MCP Server\ndocker run --env-file .env elastic/mcp-server-elasticsearch\n```\n\n## 常见问题排查\n\n### 401 Unauthorized 错误\n\n**问题描述**：认证失败，返回 401 Unauthorized 错误。\n\n**可能原因**：\n- 凭证配置错误（用户名/密码不匹配）\n- API Key 格式不正确或已过期\n- Elasticsearch 安全策略阻止了该凭证\n\n**排查步骤**：\n\n1. 验证环境变量是否正确设置：\n```bash\ndocker exec <container-id> env | grep ES_\n```\n\n2. 直接测试 Elasticsearch 连接：\n```bash\n# 使用 Basic 认证\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n\n# 使用 API Key\ndocker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n```\n\n3. 检查凭证是否有正确的索引访问权限\n\n### 认证凭证优先级问题\n\n**问题描述**：同时配置了 API Key 和用户名密码，但使用了错误的认证方式。\n\n根据代码逻辑，API Key 具有最高优先级。如果希望使用 Basic 认证，请确保不设置 `ES_API_KEY` 环境变量。\n\n### 容器内连接问题\n\n**问题描述**：在 Docker 容器中运行时报连接错误。\n\n当 ES_URL 使用 `localhost` 时，容器内的进程无法访问宿主机的 Elasticsearch。需要使用 `rewrite_localhost` 功能或修改 ES_URL 为宿主机的实际 IP 地址。\n\n## 安全最佳实践\n\n| 安全措施 | 说明 |\n|---------|------|\n| 使用 AWS Secrets Manager | 生产环境应使用 AWS Secrets Manager 或类似服务管理凭证 |\n| 定期轮换 API Key | 建议每 30-90 天轮换一次生产环境的 API Key |\n| 最小权限原则 | 为 MCP Server 创建只读用户，仅授予必要的索引访问权限 |\n| 启用 SSL/TLS | 生产环境必须使用 HTTPS 协议 |\n| 避免 SSL 跳过验证 | 生产环境不应设置 `ES_SSL_SKIP_VERIFY=true` |\n\n> [!WARNING]\n> 切勿将凭证直接写入配置文件并提交到版本控制系统。所有凭证都应通过环境变量或密钥管理服务注入。\n\n## 相关文档\n\n- [官方部署文档](https://github.com/elastic/mcp-server-elasticsearch#deploy-the-mcp-server-container)\n- [Elasticsearch API Keys 文档](https://www.elastic.co/docs/deploy-manage/api-keys)\n- [Elasticsearch 用户和角色文档](https://www.elastic.co/docs/deploy-manage/users-roles)\n\n---\n\n<a id='page-troubleshooting'></a>\n\n## 故障排除指南\n\n### 相关页面\n\n相关主题：[认证配置](#page-auth), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n</details>\n\n# 故障排除指南\n\n本页面提供 Elasticsearch MCP Server 部署和运行过程中常见问题的诊断和解决方案。\n\n---\n\n## 1. 认证失败 (401 Unauthorized)\n\n### 问题描述\n\n用户反馈在使用 Docker 部署 MCP Server 时，已正确配置了 `ES_USERNAME`、`ES_PASSWORD` 环境变量，但仍然收到 \"401 Unauthorized\" 认证失败错误。\n\n资料来源：[issues/170](https://github.com/elastic/mcp-server-elasticsearch/issues/170)\n\n### 可能原因\n\nMCP Server 支持两种认证方式：**API Key** 和 **用户名/密码**。认证优先级如下：\n\n1. 如果设置了 `api_key`，优先使用 API Key 认证\n2. 如果设置了 `username`，使用 Basic Auth（必须同时设置 `password`）\n3. 如果两者都未设置，使用匿名访问\n\n资料来源：[src/servers/elasticsearch/mod.rs:58-65](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs#L58-L65)\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n### 解决方案\n\n#### 方案一：使用 API Key 认证\n\n```bash\ndocker run -e ES_URL=https://your-cluster.es.region.amazonaws.com \\\n           -e ES_API_KEY=your_api_key_here \\\n           -p 8080:8080 \\\n           elastic/mcp-server-elasticsearch\n```\n\n#### 方案二：使用用户名密码认证\n\n```bash\ndocker run -e ES_URL=https://your-cluster.es.region.amazonaws.com \\\n           -e ES_USERNAME=your_username \\\n           -e ES_PASSWORD=your_password \\\n           -p 8080:8080 \\\n           elastic/mcp-server-elasticsearch\n```\n\n> [!IMPORTANT]\n> 确保 `ES_USERNAME` 和 `ES_PASSWORD` **同时设置**。只设置其中一个将导致认证失败。\n\n### 验证认证配置\n\n在容器内测试认证连接：\n\n```bash\n# 使用 Basic Auth 测试\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n\n# 使用 API Key 测试\ndocker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n```\n\n---\n\n## 2. 网络连接问题\n\n### 容器内无法连接 Elasticsearch\n\n#### 问题表现\n\n容器日志显示连接超时或拒绝连接：\n\n```\nError: Connection refused\n```\n\n#### 诊断步骤\n\n1. **验证 Elasticsearch URL**\n\n确保 `ES_URL` 格式正确且可访问：\n\n```bash\ndocker exec <container-id> curl -k https://your-es-cluster:9200\n```\n\n2. **检查网络连通性**\n\n```bash\ndocker exec <container-id> ping <es-host>\ndocker exec <container-id> telnet <es-host> 9200\n```\n\n3. **验证 SSL 配置**\n\n如果使用自签名证书，需要设置 `ES_SSL_SKIP_VERIFY=true`：\n\n资料来源：[src/servers/elasticsearch/mod.rs:71-72](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs#L71-L72)\n\n```bash\ndocker run -e ES_URL=https://your-cluster.es.region.amazonaws.com \\\n           -e ES_API_KEY=your_api_key \\\n           -e ES_SSL_SKIP_VERIFY=true \\\n           -p 8080:8080 \\\n           elastic/mcp-server-elasticsearch\n```\n\n### localhost 重写问题 (容器模式)\n\n当 MCP Server 以容器模式运行时，URL 中的 `localhost` 会自动重写为 `host.docker.internal`，以便容器能够访问宿主机上的服务。\n\n资料来源：[src/servers/elasticsearch/mod.rs:42-44](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs#L42-L44)\n\n```rust\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n---\n\n## 3. get_mappings 工具响应解码错误\n\n### 问题描述\n\n使用 `get_mappings` 工具时，服务器返回错误：\n\n```\n\"Request failed (remote): error decoding response body\"\n```\n\n资料来源：[issues/185](https://github.com/elastic/mcp-server-elasticsearch/issues/185)\n\n### 根本原因\n\n当索引 mapping 中嵌套属性没有显式指定 `\"type\": \"nested\"` 时，ES 返回的响应可能包含非标准字段格式，导致 JSON 解码失败。\n\n### 临时解决方案\n\n在定义 mapping 时，确保嵌套类型显式声明：\n\n```json\n{\n  \"properties\": {\n    \"nested_field\": {\n      \"type\": \"nested\",\n      \"properties\": {\n        \"name\": { \"type\": \"keyword\" }\n      }\n    }\n  }\n}\n```\n\n---\n\n## 4. HTTP/Streamable HTTP 模式问题\n\n### 问题描述\n\n无法通过 HTTP 协议远程访问 MCP Server。\n\n### 配置说明\n\nMCP Server 支持两种传输模式：\n\n| 模式 | 命令 | 默认地址 | 用途 |\n|------|------|----------|------|\n| Stdio | `stdio` | - | 本地进程通信 |\n| Streamable HTTP | `http` | `127.0.0.1:8080` | 远程访问 |\n\n资料来源：[src/cli.rs:30-47](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs#L30-L47)\n\n### 启动 HTTP 服务器\n\n```bash\n# 基本 HTTP 模式\nmcp-server-elasticsearch http --address 0.0.0.0:8080\n\n# 启用 SSE 回退（已废弃）\nmcp-server-elasticsearch http --sse\n```\n\n### 验证 HTTP 服务\n\n```bash\ncurl http://<host>:8080/ping\n```\n\n预期响应：`pong`\n\n### 健康检查\n\nStreamable HTTP 模式提供 `/ping` 端点用于健康检查：\n\n```bash\ncurl http://localhost:8080/ping\n```\n\n---\n\n## 5. 环境变量插值问题\n\n### 问题描述\n\n配置文件中使用 `${VAR_NAME}` 语法引用环境变量时，变量未被正确展开。\n\n### 机制说明\n\nMCP Server 使用 `interpolator` 模块处理环境变量插值：\n\n资料来源：[src/utils/interpolator.rs:1-50](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs#L1-L50)\n\n**支持的语法：**\n\n| 语法 | 说明 |\n|------|------|\n| `${VAR}` | 展开环境变量，变量不存在则报错 |\n| `${VAR:default}` | 展开环境变量，变量不存在则使用默认值 |\n\n### 示例配置\n\n```json\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n资料来源：[src/lib.rs:20-33](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs#L20-L33)\n\n### 常见错误\n\n```\nmissing closing braces    # 缺少闭合大括号\nenv variable 'XXX' not defined  # 环境变量未定义\n```\n\n---\n\n## 6. 工具执行错误\n\n### 问题：esql 工具查询失败\n\n#### 错误表现\n\nES|QL 查询返回错误响应。\n\n#### 诊断步骤\n\n1. 检查 ES|QL 语法是否正确\n2. 验证用户是否有执行 ES|QL 的权限\n3. 检查 Elasticsearch 版本是否支持 ES|QL（8.x+）\n\n### 问题：search 工具返回空结果\n\n#### 错误表现\n\nsearch 工具成功执行但返回空 `hits` 数组。\n\n#### 可能原因\n\n- 查询条件与现有文档不匹配\n- 索引名称拼写错误\n- 时间范围过滤条件问题\n\n### 问题：list_indices 工具无响应\n\n#### 诊断\n\n```bash\n# 验证索引列表可访问\ndocker exec <container-id> curl -k -u user:pass <ES_URL>/_cat/indices?v\n```\n\n---\n\n## 7. 日志分析\n\n### 容器日志查看\n\n```bash\ndocker logs <container-id>\n```\n\n### 日志级别配置\n\n通过环境变量 `RUST_LOG` 设置日志级别：\n\n```bash\ndocker run -e RUST_LOG=debug \\\n           -e ES_URL=https://your-cluster:9200 \\\n           -e ES_API_KEY=your_key \\\n           elastic/mcp-server-elasticsearch\n```\n\n### 常见日志关键词\n\n| 关键词 | 含义 |\n|--------|------|\n| `Error: Connection refused` | 无法连接到 Elasticsearch |\n| `401 Unauthorized` | 认证失败 |\n| `error decoding response body` | 响应解析错误（通常与 mapping 格式相关）|\n| `missing password` | 使用用户名认证但未提供密码 |\n\n---\n\n## 8. 配置验证清单\n\n在报告问题前，请确认以下配置项：\n\n| 检查项 | 说明 | 验证命令 |\n|--------|------|----------|\n| ES_URL 格式 | 必须以 `http://` 或 `https://` 开头 | `echo $ES_URL` |\n| 认证凭证 | API Key 或 用户名+密码 | 检查环境变量 |\n| 网络连通性 | 容器可访问 ES 集群 | `docker exec <id> curl <ES_URL>` |\n| SSL 配置 | 自签名证书需设置 `ES_SSL_SKIP_VERIFY=true` | 检查日志 |\n| 权限 | 用户对索引有读取权限 | ES 角色检查 |\n\n---\n\n## 9. 获取帮助\n\n如果以上指南未能解决您的问题：\n\n1. 收集以下信息：\n   - MCP Server 版本：`docker logs <container-id> | grep version`\n   - 完整错误日志\n   - 配置文件（脱敏后）\n   - Elasticsearch 集群版本\n\n2. 在 [GitHub Issues](https://github.com/elastic/mcp-server-elasticsearch/issues) 创建问题时：\n   - 描述复现步骤\n   - 附上相关日志\n   - 说明环境和版本信息\n\n---\n\n<a id='page-security'></a>\n\n## 安全最佳实践\n\n### 相关页面\n\n相关主题：[认证配置](#page-auth), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n\n</details>\n\n# 安全最佳实践\n\n本文档介绍 Elasticsearch MCP Server 的安全最佳实践，涵盖身份认证、凭证管理、传输加密、网络配置等关键安全领域。\n\n## 身份认证配置\n\nElasticsearch MCP Server 支持两种身份认证方式：**API Key 认证** 和 **基本认证（用户名/密码）**。\n\n### 认证方式对比\n\n| 认证方式 | 环境变量 | 说明 |\n|---------|---------|------|\n| API Key | `ES_API_KEY` | 推荐用于生产环境，安全性更高 |\n| 基本认证 | `ES_USERNAME` + `ES_PASSWORD` | 适用于传统用户名密码场景 |\n| SSL 跳过验证 | `ES_SSL_SKIP_VERIFY` | 仅在开发/测试环境使用 |\n\n### 配置认证参数\n\n认证配置通过 `ElasticsearchMcpConfig` 结构体管理：\n\n```rust\n// 资料来源：src/servers/elasticsearch/mod.rs:88-102\npub struct ElasticsearchMcpConfig {\n    /// 集群 URL\n    pub url: String,\n\n    /// API 密钥\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub api_key: Option<String>,\n\n    /// 用户名\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub username: Option<String>,\n\n    /// 密码\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub password: Option<String>,\n\n    /// 是否跳过 SSL 证书验证\n    #[serde(default, deserialize_with = \"deserialize_bool_from_anything\")]\n    pub ssl_skip_verify: bool,\n}\n```\n\n### API Key 认证配置\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-elasticsearch:9200\" \\\n  -e ES_API_KEY=\"your-api-key-here\" \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n### 基本认证配置\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-elasticsearch:9200\" \\\n  -e ES_USERNAME=\"elastic\" \\\n  -e ES_PASSWORD=\"your-password\" \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n## 凭证安全管理\n\n### 凭证存储原则\n\nElasticsearch MCP Server 遵循严格的凭证安全管理原则：\n\n- **API 密钥和密码**：仅存储在传递给容器的环境变量中\n- **不持久化到磁盘**：凭证不会写入文件系统\n- **不记录到日志**：敏感信息不会出现在日志输出中\n\n```rust\n// 资料来源：src/servers/elasticsearch/mod.rs:72-79\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n### 环境变量插值\n\n配置文件支持环境变量插值，使用 `${VAR_NAME}` 或 `${VAR_NAME:default}` 语法：\n\n```json\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n```rust\n// 资料来源：src/lib.rs:48-52\nlet config = interpolator::interpolate_from_env(config)?;\n```\n\n### 生产环境凭证管理建议\n\n| 推荐做法 | 说明 |\n|---------|------|\n| AWS Secrets Manager | 使用 AWS Secrets Manager 存储和轮换凭证 |\n| AWS Systems Manager Parameter Store | 使用 Parameter Store 管理敏感参数 |\n| 定期轮换 | API 密钥建议每 30-90 天轮换一次 |\n| 最小权限 | 使用只读访问特定索引的 API 密钥 |\n\n## 传输加密\n\n### HTTPS 通信\n\nMCP Server 与 Elasticsearch 集群之间的通信采用 HTTPS 加密：\n\n```mermaid\ngraph LR\n    A[MCP Server] -->|HTTPS/TLS| B[Elasticsearch Cluster]\n    B -->|加密响应| A\n```\n\n当 `ES_URL` 使用 `https://` 协议时，通信自动加密：\n\n```bash\n# 正确的 HTTPS 配置\nES_URL=\"https://your-elasticsearch:9200\"\n```\n\n### SSL 证书验证\n\n#### 生产环境配置\n\n生产环境应保持 SSL 证书验证启用：\n\n```bash\n# 默认情况下 ssl_skip_verify 为 false，保持验证\ndocker run --rm \\\n  -e ES_URL=\"https://your-elasticsearch:9200\" \\\n  -e ES_API_KEY=\"your-api-key\" \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n#### 开发/测试环境配置\n\n仅在本地开发或使用自签名证书时禁用验证：\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://localhost:9200\" \\\n  -e ES_API_KEY=\"your-api-key\" \\\n  -e ES_SSL_SKIP_VERIFY=true \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n> ⚠️ **警告**：禁用 SSL 验证会使通信暴露于中间人攻击风险，仅限于受信任的内部网络。\n\n## 网络安全配置\n\n### HTTP 服务监听地址\n\nHTTP 模式下，默认监听地址为 `127.0.0.1:8080`：\n\n```rust\n// 资料来源：src/cli.rs:28-32\npub struct HttpCommand {\n    /// 监听地址 [默认: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// 同时启动 SSE 服务器在 '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n### 安全监听建议\n\n| 场景 | 推荐配置 | 说明 |\n|-----|---------|------|\n| 本地开发 | `127.0.0.1:8080` | 仅本地访问 |\n| Docker 网络 | `0.0.0.0:8080` | 容器间通信 |\n| 公网部署 | 使用反向代理 + TLS | 添加额外安全层 |\n\n### Docker 网络安全\n\n容器模式下，自动重写 localhost 引用：\n\n```rust\n// 资料来源：src/servers/elasticsearch/mod.rs:67-68\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n## 常见安全问题排查\n\n### 401 Unauthorized 错误\n\n社区反馈：Issue #170 中许多用户遇到基本认证失败的问题。\n\n#### 排查步骤\n\n1. **验证环境变量配置**：\n   ```bash\n   docker exec <container-id> env | grep ES_\n   ```\n\n2. **测试 Elasticsearch 连接**：\n   ```bash\n   # 使用 API Key\n   docker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n   \n   # 使用用户名密码\n   docker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n   ```\n\n3. **检查凭证是否正确传递**：\n   - 确认 `ES_USERNAME` 和 `ES_PASSWORD` 同时设置\n   - 确认 API Key 格式正确（不带 \"ApiKey\" 前缀）\n\n### SSL 证书错误\n\n```bash\n# 检查 Elasticsearch SSL 配置\ndocker exec <container-id> curl -v <ES_URL>\n```\n\n### 容器日志分析\n\n```bash\ndocker logs <container-id>\n```\n\n查看日志中的错误信息：\n\n- Elasticsearch 连接失败\n- 身份认证错误\n- 网络连接问题\n\n## 数据安全\n\n### 数据存储\n\n| 层面 | 说明 |\n|-----|------|\n| 传输中数据 | MCP Server 与 Elasticsearch 之间的通信加密 |\n| 静态数据 | 容器不本地存储数据，所有数据保留在 Elasticsearch 集群 |\n| 临时数据 | 容器重启后清除所有临时数据 |\n\n### 数据访问控制\n\n建议在 Elasticsearch 层面配置：\n\n- 基于角色的访问控制 (RBAC)\n- 字段级安全\n- 索引级权限\n\n```json\n{\n  \"roles\": [\n    {\n      \"name\": \"mcp_readonly\",\n      \"indices\": [\n        {\n          \"names\": [\"allowed-index-*\"],\n          \"privileges\": [\"read\", \"view_index_metadata\"]\n        }\n      ]\n    }\n  ]\n}\n```\n\n## 审计与监控\n\n### 健康检查端点\n\nHTTP 模式提供健康检查端点：\n\n```bash\ncurl http://<host>:8080/ping\n```\n\n成功响应返回 `pong`。\n\n### MCP 端点\n\n```bash\n# MCP 协议端点\nhttp://<host>:8080/mcp\n```\n\n## 最佳实践清单\n\n### 部署前检查\n\n- [ ] 使用 HTTPS 连接到 Elasticsearch\n- [ ] 配置有效的 API Key 或用户名密码\n- [ ] 不在生产环境设置 `ES_SSL_SKIP_VERIFY=true`\n- [ ] 使用只读权限的 API 密钥\n\n### 容器配置检查\n\n- [ ] 凭证通过环境变量传递，不写入配置文件\n- [ ] 容器日志不包含敏感信息\n- [ ] 网络访问限制在必要范围\n\n### 运维检查\n\n- [ ] 定期轮换 API 密钥（30-90 天）\n- [ ] 监控认证失败日志\n- [ ] 审计 Elasticsearch 访问日志\n\n## 相关资源\n\n- [Elasticsearch API Keys 文档](https://www.elastic.co/docs/deploy-manage/api-keys)\n- [Elasticsearch 用户角色文档](https://www.elastic.co/docs/deploy-manage/users-roles)\n- [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/)\n- [Model Context Protocol 文档](https://modelcontextprotocol.io/)\n\n---\n\n<!-- evidence_pipeline_checked: true -->\n<!-- evidence_injected: true -->\n\n---\n\n## Doramagic 踩坑日志\n\n项目：elastic/mcp-server-elasticsearch\n\n摘要：发现 10 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 依赖 Docker 环境。\n\n## 1. 安装坑 · 依赖 Docker 环境\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：安装/运行入口包含 Docker 命令：docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n- 对用户的影响：非工程用户可能没有 Docker，启动成本明显增加。\n- 建议检查：标注 Docker 前置条件，并提供非 Docker 路径或失败提示。\n- 复现命令：`docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio`\n- 防护动作：Docker 前置条件未说明时，不把项目标成普通用户低门槛。\n- 证据：identity.distribution | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n\n## 2. 安装坑 · 来源证据：Dependency Dashboard\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Dependency Dashboard\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_5573c160ecdd4e34be6dbf6549fe2529 | https://github.com/elastic/mcp-server-elasticsearch/issues/6 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。\n\n## 3. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | host_targets=mcp_host, claude, cursor\n\n## 4. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | README/documentation is current enough for a first validation pass.\n\n## 5. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | last_activity_observed missing\n\n## 6. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n\n## 7. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n\n## 8. 安全/权限坑 · 来源证据：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_f8732a2deab341d6b739b122459d1243 | https://github.com/elastic/mcp-server-elasticsearch/issues/185 | 来源讨论提到 api key 相关条件，需在安装/试用前复核。\n\n## 9. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | issue_or_pr_quality=unknown\n\n## 10. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | release_recency=unknown\n\n<!-- canonical_name: elastic/mcp-server-elasticsearch; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "mcp-server-elasticsearch",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:953992846",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/elastic/mcp-server-elasticsearch"
        },
        {
          "evidence_id": "art_cfb65a7eda0a49dfac62bff85cbd5963",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/elastic/mcp-server-elasticsearch#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "mcp-server-elasticsearch 说明书",
      "toc": [
        "https://github.com/elastic/mcp-server-elasticsearch 项目说明书",
        "目录",
        "项目介绍",
        "概述",
        "核心架构",
        "工具集详解",
        "配置系统",
        "通信协议",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "a2b050d07c1e0af19974f63efa20f4553cb43b2b",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "Dockerfile",
      "README.md",
      "docs/CONTRIBUTING.md"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# mcp-server-elasticsearch - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 mcp-server-elasticsearch 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0016` supported 0.86\n\n## 它能做什么\n\n- **list_indices**（需要安装后验证）：Lists Elasticsearch indices matching a pattern, returning index name, status, and document count. 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **get_mappings**（需要安装后验证）：Retrieves field mappings for a specified index, exposing the schema definition. 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **search**（需要安装后验证）：Executes search queries against Elasticsearch indices with support for _source filtering and aggregations. 证据：`src/servers/elasticsearch/base_tools.rs`, `src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **esql_query**（需要安装后验证）：Executes ES|QL (Elasticsearch Query Language) queries and returns results as JSON objects. 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **get_shards**（需要安装后验证）：Returns shard allocation information for indices including replica state and node assignment. 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **stdio_transport**（可做安装前预览）：Supports stdio protocol for direct MCP client connections in the same environment. 证据：`src/lib.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **streamable_http_transport**（可做安装前预览）：Supports streamable HTTP protocol for web-based integrations, stateful sessions, and concurrent clients. 证据：`src/protocol/http.rs`, `src/lib.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **api_key_authentication**（需要安装后验证）：Authenticates to Elasticsearch using API key credentials via ES_API_KEY environment variable. 证据：`src/servers/elasticsearch/mod.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **basic_authentication**（需要安装后验证）：Authenticates to Elasticsearch using username/password via ES_USERNAME and ES_PASSWORD environment variables. 证据：`src/servers/elasticsearch/mod.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **context_auth_forwarding**（可做安装前预览）：Forwards authentication from incoming MCP requests to Elasticsearch, supporting Bearer token formats. 证据：`src/servers/elasticsearch/mod.rs` Claim：`clm_0008` supported 0.86, `clm_0009` supported 0.86, `clm_0010` supported 0.86, `clm_0012` supported 0.86 等\n- **config_env_interpolation**（可做安装前预览）：Supports environment variable interpolation in JSON5 config files using ${VAR} and ${VAR:default} syntax. 证据：`src/utils/interpolator.rs`, `elastic-mcp.json5` Claim：`clm_0011` supported 0.86\n- **container_localhost_rewrite**（可做安装前预览）：Rewrites localhost URLs in container mode to host.docker.internal or host.containers.internal for Docker/Podman compatibility. 证据：`src/servers/elasticsearch/mod.rs`, `Dockerfile` Claim：`clm_0008` supported 0.86, `clm_0009` supported 0.86, `clm_0010` supported 0.86, `clm_0012` supported 0.86 等\n- **ssl_verification_toggle**（可做安装前预览）：Allows disabling SSL/TLS certificate verification via ES_SSL_SKIP_VERIFY for development environments. 证据：`src/servers/elasticsearch/mod.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **health_endpoints**（可做安装前预览）：Provides HTTP health check endpoints at /ready, /live, and /ping for container orchestration. 证据：`src/protocol/http.rs` Claim：`clm_0007` supported 0.86, `clm_0014` supported 0.86\n- **multiarch_docker_build**（可做安装前预览）：Supports building multi-architecture Docker images for linux/amd64 and linux/arm64 platforms. 证据：`Makefile`, `Dockerfile` Claim：`clm_0012` supported 0.86, `clm_0015` supported 0.86\n\n## 怎么开始\n\n- `uv tool install mcp-proxy` 证据：`README.md` Claim：`clm_0017` supported 0.86\n- `curl http://<host>:8080/ping` 证据：`README.md` Claim：`clm_0018` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：需要管理员/安全审批\n- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。\n\n### 30 秒判断\n\n- **现在怎么做**：需要管理员/安全审批\n- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装\n- **先别相信**：工具权限边界不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、环境变量 / API Key\n\n### 现在可以相信\n\n- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0016` supported 0.86\n- **能力存在：list_indices**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86\n- **能力存在：get_mappings**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86\n- **能力存在：search**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`src/servers/elasticsearch/base_tools.rs`, `src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86\n- **能力存在：esql_query**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86\n- **能力存在：get_shards**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86\n\n### 现在还不能相信\n\n- **工具权限边界不能在安装前相信。**（unverified）：MCP/tool 类项目通常会触碰文件、网络、浏览器或外部 API，必须真实检查权限和日志。\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`, `src/servers/elasticsearch/base_tools.rs`, `src/servers/elasticsearch/mod.rs`\n- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`README.md`\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0019` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0020` supported 0.86\n- **风险**： 处理方式：\n- **风险**： 处理方式：\n- **风险**： 处理方式：\n- **风险**： 处理方式：\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **list_indices**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **get_mappings**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **search**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`src/servers/elasticsearch/base_tools.rs`, `src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **esql_query**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **get_shards**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`src/servers/elasticsearch/base_tools.rs` Claim：`clm_0001` supported 0.86, `clm_0002` supported 0.86, `clm_0003` supported 0.86, `clm_0004` supported 0.86 等\n- **stdio_transport**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`src/lib.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **streamable_http_transport**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`src/protocol/http.rs`, `src/lib.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **api_key_authentication**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`src/servers/elasticsearch/mod.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **basic_authentication**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`src/servers/elasticsearch/mod.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **context_auth_forwarding**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`src/servers/elasticsearch/mod.rs` Claim：`clm_0008` supported 0.86, `clm_0009` supported 0.86, `clm_0010` supported 0.86, `clm_0012` supported 0.86 等\n- **config_env_interpolation**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`src/utils/interpolator.rs`, `elastic-mcp.json5` Claim：`clm_0011` supported 0.86\n- **container_localhost_rewrite**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`src/servers/elasticsearch/mod.rs`, `Dockerfile` Claim：`clm_0008` supported 0.86, `clm_0009` supported 0.86, `clm_0010` supported 0.86, `clm_0012` supported 0.86 等\n- **ssl_verification_toggle**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`src/servers/elasticsearch/mod.rs`, `README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86, `clm_0008` supported 0.86, `clm_0009` supported 0.86 等\n- **health_endpoints**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`src/protocol/http.rs` Claim：`clm_0007` supported 0.86, `clm_0014` supported 0.86\n- **multiarch_docker_build**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`Makefile`, `Dockerfile` Claim：`clm_0012` supported 0.86, `clm_0015` supported 0.86\n\n### 上下文规模\n\n- 文件总数：33\n- 重要文件覆盖：31/33\n- 证据索引条目：30\n- 角色 / Skill 条目：2\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 mcp-server-elasticsearch 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 mcp-server-elasticsearch 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 mcp-server-elasticsearch 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 2 个角色 / Skill / 项目文档条目。\n\n- **Elasticsearch MCP Server**（project_doc）：!CAUTION This MCP server is deprecated and will only receive critical security updates going forward. It has been superseded by the Elastic Agent Builder https://ela.st/agent-builder-docs MCP endpoint https://ela.st/agent-builder-mcp , which is available in Elastic 9.2.0+ and Elasticsearch Serverless projects. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n- **Contributing**（project_doc）：fork : https://github.com/elastic/mcp-server-elasticsearch/fork pr : https://github.com/elastic/mcp-server-elasticsearch/compare code-of-conduct : https://www.elastic.co/community/codeofconduct 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CONTRIBUTING.md`\n\n## 证据索引\n\n- 共索引 30 条证据。\n\n- **Elasticsearch MCP Server**（documentation）：!CAUTION This MCP server is deprecated and will only receive critical security updates going forward. It has been superseded by the Elastic Agent Builder https://ela.st/agent-builder-docs MCP endpoint https://ela.st/agent-builder-mcp , which is available in Elastic 9.2.0+ and Elasticsearch Serverless projects. 证据：`README.md`\n- **Contributing**（documentation）：fork : https://github.com/elastic/mcp-server-elasticsearch/fork pr : https://github.com/elastic/mcp-server-elasticsearch/compare code-of-conduct : https://www.elastic.co/community/codeofconduct 证据：`docs/CONTRIBUTING.md`\n- **License**（source_file）：Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ 证据：`LICENSE`\n- **Renovate**（structured_config）：{ \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\", \"extends\": \"local elastic/renovate-config\" , \"schedule\": \"after 1am on monday\" } 证据：`renovate.json`\n- **The MCP server looks for .env files to populate environment variables that aren't already set**（source_file）：The MCP server looks for .env files to populate environment variables that aren't already set Copy and edit this file it's listed in .gitignore 证据：`.env-example`\n- **Notice**（source_file）：Elasticsearch MCP Server Copyright 2025 Elasticsearch B.V. 证据：`NOTICE.txt`\n- **Catalog Info**（source_file）：apiVersion: backstage.io/v1alpha1 kind: Resource metadata: name: buildkite-pipeline-mcp-server-elasticsearch description: Buildkite Pipeline for mcp-server-elasticsearch links: - title: Pipeline url: https://buildkite.com/elastic/mcp-server-elasticsearch spec: type: buildkite-pipeline owner: group:devtools-team system: buildkite implementation: apiVersion: buildkite.elastic.dev/v1 kind: Pipeline metadata: name: mcp-server-elasticsearch description: Run checks for the mcp-server-elasticsearch package spec: repository: elastic/mcp-server-elasticsearch pipeline file: \".buildkite/pipeline.yml\" teams: devtools-team: access level: MANAGE BUILD AND READ everyone: access level: READ ONLY --- apiVer… 证据：`catalog-info.yaml`\n- **Cli**（source_file）：use crate::servers::elasticsearch; use clap::Parser; ⋮---- use std::collections::HashMap; use std::path::PathBuf; ⋮---- pub struct Cli { ⋮---- pub enum Command { ⋮---- pub struct HttpCommand { ⋮---- pub struct StdioCommand { ⋮---- pub struct Stdio { ⋮---- pub struct Http { ⋮---- pub enum McpServer { ⋮---- pub struct Configuration { 证据：`src/cli.rs`\n- **Lib**（source_file）：pub mod cli; mod protocol; mod servers; mod utils; ⋮---- use crate::servers::elasticsearch; use crate::utils::interpolator; use rmcp::transport::stdio; use rmcp::transport::streamable http server::session::never::NeverSessionManager; ⋮---- use std::path::PathBuf; use std::sync::Arc; use tokio::select; use tokio util::sync::CancellationToken; ⋮---- impl Cli { pub async fn run self - anyhow::Result { ⋮---- Command::Stdio cmd = run stdio cmd, self.container mode .await, Command::Http cmd = run http cmd, self.container mode .await, ⋮---- pub async fn run stdio cmd: StdioCommand, container mode: bool - anyhow::Result { ⋮---- let handler = setup services &cmd.config, container mode .await?; let s… 证据：`src/lib.rs`\n- **Start Http**（source_file）：use elasticsearch core mcp server::cli::HttpCommand; use elasticsearch core mcp server::run http; ⋮---- pub async fn main - anyhow::Result { println! \"Current directory: {:?}\", std::env::current dir ? ; ⋮---- run http HttpCommand { config: Some \"elastic-mcp.json5\".parse ? , ⋮---- Ok 证据：`src/bin/start_http.rs`\n- **Http**（source_file）：use crate::utils::rmcp ext::ServerProvider; use axum::Router; use axum::http::StatusCode; use axum::routing::get; use rmcp::transport::sse server::SseServerConfig; use rmcp::transport::streamable http server::session::local::LocalSessionManager; ⋮---- use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; use tokio util::sync::CancellationToken; use tracing::Instrument; ⋮---- pub struct HttpServerConfig { ⋮---- pub struct HttpProtocol {} ⋮---- impl HttpProtocol { pub async fn serve with config , M: SessionManager ⋮---- let server provider = server provider.into .0; ⋮---- let ct = config.ct.child token ; ⋮---- let server provider = server provider.clone ; ⋮---- StreamableHttp… 证据：`src/protocol/http.rs`\n- **Mod**（source_file）：pub mod http; pub mod stdio; 证据：`src/protocol/mod.rs`\n- **Base Tools**（source_file）：use elasticsearch::indices::IndicesGetMappingParts; ⋮---- use indexmap::IndexMap; ⋮---- use rmcp::service::RequestContext; ⋮---- use std::collections::HashMap; ⋮---- pub struct EsBaseTools { ⋮---- impl EsBaseTools { pub fn new es client: Elasticsearch - Self { ⋮---- struct ListIndicesParams { ⋮---- struct GetMappingsParams { ⋮---- struct SearchParams { ⋮---- struct EsqlQueryParams { ⋮---- struct GetShardsParams { ⋮---- async fn list indices ⋮---- let es client = self.es client.get req ctx ; ⋮---- .cat .indices CatIndicesParts::Index & &index pattern .h & \"index\", \"status\", \"docs.count\" .format \"json\" .send ⋮---- let response: Vec = read json response .await?; ⋮---- Ok CallToolResult::succes… 证据：`src/servers/elasticsearch/base_tools.rs`\n- **Mod**（source_file）：mod base tools; ⋮---- use crate::servers::IncludeExclude; use crate::utils::none if empty string; use elasticsearch::Elasticsearch; use elasticsearch::auth::Credentials; use elasticsearch::cert::CertificateValidation; use elasticsearch::http::Url; use elasticsearch::http::response::Response; use http::header::USER AGENT; use http::request::Parts; ⋮---- use indexmap::IndexMap; use rmcp::RoleServer; use rmcp::model::ToolAnnotations; use rmcp::service::RequestContext; use serde::de::DeserializeOwned; ⋮---- use serde aux::field attributes::deserialize bool from anything; use std::borrow::Cow; use std::collections::HashMap; ⋮---- pub struct ElasticsearchMcpConfig { ⋮---- pub struct EsClientProvi… 证据：`src/servers/elasticsearch/mod.rs`\n- **Mod**（source_file）：pub mod elasticsearch; ⋮---- pub enum IncludeExclude { ⋮---- impl IncludeExclude { pub fn is included &self, name: &str - bool { ⋮---- Include includes = includes.iter .map s s.as str .any s s == name , Exclude excludes = excludes.iter .map s s.as str .all s s != name , ⋮---- pub fn filter &self, tools: &mut Vec { tools.retain t self.is included &t.name 证据：`src/servers/mod.rs`\n- **Interpolator**（source_file）：use thiserror::Error; ⋮---- pub struct InterpolationError { ⋮---- pub fn interpolate from env s: String - Result { interpolate s, name std::env::var name .ok ⋮---- const OPEN LEN: usize = OPEN.len ; ⋮---- const CLOSE LEN: usize = CLOSE.len ; ⋮---- pub fn interpolate s: String, lookup: impl Fn &str - Option - Result { if !s.contains OPEN { return Ok s ; ⋮---- for line no, mut line in s.lines .enumerate { ⋮---- result.push '\\n' ; ⋮---- while let Some pos = line.find OPEN { ⋮---- result.push str &line ..pos ; ⋮---- if let Some pos = line.find CLOSE { ⋮---- let value = if let Some name, default = expr.split once ':' { lookup name .unwrap or default.to string ⋮---- lookup expr .ok or else err ch… 证据：`src/utils/interpolator.rs`\n- **Mod**（source_file）：pub mod interpolator; pub mod rmcp ext; ⋮---- pub fn none if empty string deserializer: D - Result , D::Error { ⋮---- Some s if s.is empty = Ok None , = Ok s , 证据：`src/utils/mod.rs`\n- **Pull Requests**（structured_config）：{ \"jobs\": { \"enabled\": true, \"pipelineSlug\": \"mcp-server-elasticsearch\", \"allow org users\": true, \"allowed repo permissions\": \"admin\", \"write\" , \"allowed list\": , \"set commit status\": true, \"commit status context\": \"buildkite/mcp-server-elasticsearch\", \"build on commit\": false, \"build on comment\": true, \"trigger comment regex\": \"^ ?: ?:buildkite\\\\W+ ? ?:build test \\\\W+ ?:this it \", \"always trigger comment regex\": \"^ ?: ?:buildkite\\\\W+ ? ?:build test \\\\W+ ?:this it \", \"skip ci labels\": \"skip-ci\" , \"skip target branches\": , \"always require ci on changed\": } } 证据：`.buildkite/pull-requests.json`\n- **!/bin/bash**（source_file）：!/bin/bash Produces a list of changed files between two commits works for merges and regular commits . Used in conjunction with the monorepo-diff-buildkite-plugin to determine which pipelines to upload/trigger based on the files changed. 证据：`.buildkite/diff`\n- **Docker**（source_file）：--- steps: - label: \"Build and publish Docker image\" command: \"make docker-push-elastic\" agents: provider: \"gcp\" 证据：`.buildkite/docker.yml`\n- **Pipeline**（source_file）：--- steps: - label: \"Triggering pipelines\" plugins: monorepo-diff diff: \".buildkite/diff ${BUILDKITE COMMIT}\" wait: true watch: - path: \"renovate.json\" config: label: \"Verify Renovate configuration\" command: \"renovate-config-validator\" agents: image: \"docker.elastic.co/ci-agent-images/pipelib:0.22.0@sha256:25503116fb91c18383b17aee528b9ca6e520ef58622c7f961c7d255bb8ba51f6\" - path: \"catalog-info.yaml\" config: command: \"/agent/check-catalog-info.sh\" agents: image: \"docker.elastic.co/ci-agent-images/pipelib:0.22.0@sha256:25503116fb91c18383b17aee528b9ca6e520ef58622c7f961c7d255bb8ba51f6\" 证据：`.buildkite/pipeline.yml`\n- **.dockerignore**（source_file）：docs target .idea .vscode 证据：`.dockerignore`\n- **Generated by Cargo**（source_file）：Generated by Cargo will have compiled files and executables debug/ target/ 证据：`.gitignore`\n- **Base stuff**（source_file）：package name = \"elasticsearch-core-mcp-server\" version = \"0.4.6\" edition = \"2024\" authors = \"Elastic.co\" license-file = \"LICENSE\" description = \"MCP server for core Elastisearch features\" homepage = \"https://github.com/elastic/mcp-server-elasticsearch\" repository = \"https://github.com/elastic/mcp-server-elasticsearch\" 证据：`Cargo.toml`\n- **Copyright Elasticsearch B.V. and contributors**（source_file）：Copyright Elasticsearch B.V. and contributors SPDX-License-Identifier: Apache-2.0 证据：`Dockerfile`\n- **Copyright Elasticsearch B.V. and contributors**（source_file）：Copyright Elasticsearch B.V. and contributors SPDX-License-Identifier: Apache-2.0 证据：`Dockerfile-8000`\n- **set version variable**（source_file）：set version variable VERSION = $ shell grep '^version' Cargo.toml head -n1 cut -d ' ' -f3 sed 's/\"//g' ES IMAGE = \"docker.elastic.co/mcp/elasticsearch:$ VERSION \" ES IMAGE LATEST = \"docker.elastic.co/mcp/elasticsearch:latest\" AWS IMAGE = \"709825985650.dkr.ecr.us-east-1.amazonaws.com/elastic/mcp/elasticsearch:$ VERSION \" 证据：`Makefile`\n- **Elastic Mcp**（source_file）：{ // Configure the target Elasticsearch server \"elasticsearch\": { \"url\": \"${ES URL}\", \"api key\": \"${ES API KEY:}\", \"username\": \"${ES USERNAME:}\", \"password\": \"${ES PASSWORD:}\", \"ssl skip verify\": \"${ES SSL SKIP VERIFY:false}\", 证据：`elastic-mcp.json5`\n- **Rustfmt**（source_file）：max width = 120 证据：`rustfmt.toml`\n- **Cargo Run**（source_file）：cd \"$ dirname $0 \"/.. exec cargo run \"$@\" 证据：`scripts/cargo-run.sh`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `docs/CONTRIBUTING.md`, `LICENSE`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `docs/CONTRIBUTING.md`, `LICENSE`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **项目介绍**：importance `high`\n  - source_paths: README.md, catalog-info.yaml\n- **版本历史与更新**：importance `medium`\n  - source_paths: NOTICE.txt\n- **系统架构**：importance `high`\n  - source_paths: src/lib.rs, src/cli.rs, src/servers/mod.rs, src/protocol/mod.rs\n- **通信协议配置**：importance `high`\n  - source_paths: src/protocol/http.rs, src/protocol/stdio.rs\n- **MCP 工具详解**：importance `high`\n  - source_paths: src/servers/elasticsearch/base_tools.rs, src/servers/elasticsearch/mod.rs\n- **配置与工具过滤**：importance `medium`\n  - source_paths: src/servers/mod.rs, src/utils/interpolator.rs, src/utils/mod.rs\n- **Docker 部署指南**：importance `high`\n  - source_paths: Dockerfile, Dockerfile-8000, .env-example\n- **认证配置**：importance `high`\n  - source_paths: src/servers/elasticsearch/mod.rs, .env-example\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `a2b050d07c1e0af19974f63efa20f4553cb43b2b`\n- inspected_files: `Dockerfile`, `README.md`, `docs/CONTRIBUTING.md`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 依赖 Docker 环境\n\n- Trigger: 安装/运行入口包含 Docker 命令：docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n- Host AI rule: 标注 Docker 前置条件，并提供非 Docker 路径或失败提示。\n- Why it matters: 非工程用户可能没有 Docker，启动成本明显增加。\n- Evidence: identity.distribution | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 来源证据：Dependency Dashboard\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Dependency Dashboard\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能阻塞安装或首次运行。\n- Evidence: community_evidence:github | cevd_5573c160ecdd4e34be6dbf6549fe2529 | https://github.com/elastic/mcp-server-elasticsearch/issues/6 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 可能修改宿主 AI 配置\n\n- Trigger: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- Host AI rule: 列出会写入的配置文件、目录和卸载/回滚步骤。\n- Why it matters: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- Evidence: capability.host_targets | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | host_targets=mcp_host, claude, cursor\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 8: 来源证据：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n\n- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能影响授权、密钥配置或安全边界。\n- Evidence: community_evidence:github | cevd_f8732a2deab341d6b739b122459d1243 | https://github.com/elastic/mcp-server-elasticsearch/issues/185 | 来源讨论提到 api key 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 9: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 10: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：elastic/mcp-server-elasticsearch\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：mcp_host, claude, cursor\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- 无阻塞项。\n\n## 项目专属踩坑\n\n- 依赖 Docker 环境（medium）：非工程用户可能没有 Docker，启动成本明显增加。 建议检查：标注 Docker 前置条件，并提供非 Docker 路径或失败提示。\n- 来源证据：Dependency Dashboard（medium）：可能阻塞安装或首次运行。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 可能修改宿主 AI 配置（medium）：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/elastic/mcp-server-elasticsearch 项目说明书\n\n生成时间：2026-05-31 01:03:00 UTC\n\n## 目录\n\n- [项目介绍](#page-intro)\n- [版本历史与更新](#page-changelog)\n- [系统架构](#page-architecture)\n- [通信协议配置](#page-protocols)\n- [MCP 工具详解](#page-tools)\n- [配置与工具过滤](#page-config)\n- [Docker 部署指南](#page-deployment)\n- [认证配置](#page-auth)\n- [故障排除指南](#page-troubleshooting)\n- [安全最佳实践](#page-security)\n\n<a id='page-intro'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [catalog-info.yaml](https://github.com/elastic/mcp-server-elasticsearch/blob/main/catalog-info.yaml)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json)\n</details>\n\n# 项目介绍\n\n## 概述\n\nElasticsearch MCP Server 是由 Elastic 公司开发的 Model Context Protocol (MCP) 服务器实现，专门用于将 Elasticsearch 集群与 AI 助手（如 Claude、Cursor 等）进行集成。该项目允许 AI 代理通过标准化接口执行 Elasticsearch 操作，包括索引查询、映射获取、分片状态检查等高级功能。\n\n资料来源：[catalog-info.yaml:4]()\n\n### 项目定位\n\n| 属性 | 值 |\n|------|-----|\n| 类型 | 库 (library) |\n| 所属团队 | devtools-team |\n| 生命周期 | beta (测试阶段) |\n| 版权 | Elasticsearch B.V. 2025 |\n\n资料来源：[catalog-info.yaml:6-10]()\n\n## 核心架构\n\n### 整体架构图\n\n```mermaid\ngraph TD\n    A[\"MCP Client<br/>(Claude/Cursor)\"] --> B[\"Elasticsearch MCP Server\"]\n    B --> C[\"Elasticsearch Cluster\"]\n    \n    B --> D[\"base_tools<br/>基础工具集\"]\n    B --> E[\"custom_tools<br/>自定义工具\"]\n    \n    D --> D1[\"list_indices\"]\n    D --> D2[\"get_mappings\"]\n    D --> D3[\"search\"]\n    D --> D4[\"get_shards\"]\n    D --> D5[\"esql\"]\n    \n    E --> E1[\"ESQL 查询\"]\n    E --> E2[\"搜索模板\"]\n    \n    C --> F[\"REST API\"]\n```\n\n### 组件层次结构\n\n```mermaid\ngraph TD\n    A[\"ElasticsearchMcp\"] --> B[\"EsBaseTools\"]\n    B --> C[\"EsClientProvider\"]\n    C --> D[\"Elasticsearch<br/>HTTP Client\"]\n    \n    B --> E[\"ToolRouter<br/>工具路由器\"]\n    E --> F[\"工具处理器\"]\n    \n    A --> G[\"Configuration<br/>配置管理\"]\n    G --> H[\"环境变量解析\"]\n    G --> I[\"配置文件加载\"]\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:77-93]()\n\n## 工具集详解\n\n### 基础工具 (Base Tools)\n\n项目提供五个核心工具用于日常 Elasticsearch 操作：\n\n| 工具名称 | 功能描述 | 只读 |\n|----------|----------|------|\n| `list_indices` | 列出所有符合条件的 Elasticsearch 索引 | 是 |\n| `get_mappings` | 获取指定索引的字段映射信息 | 是 |\n| `search` | 使用 Query DSL 执行搜索查询 | 是 |\n| `get_shards` | 获取索引分片分配状态信息 | 是 |\n| `esql` | 执行 ES|QL 查询语句 | 是 |\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:1-100]()\n\n### 搜索功能增强\n\n`search` 工具支持以下高级特性：\n\n- **字段选择**：通过 `fields` 参数指定返回字段，减少上下文大小\n- **聚合支持**：自动返回聚合结果，支持复杂分析查询\n- **Query DSL 完整支持**：支持 query、size、from、sort 等完整查询语法\n\n```rust\n// 搜索结果数据结构\npub struct SearchResult {\n    pub hits: Hits,\n    #[serde(default)]\n    pub aggregations: IndexMap<String, Value>,  // 聚合结果\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Hits {\n    pub total: Option<TotalHits>,\n    pub hits: Vec<Hit>,\n}\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:100-130]()\n\n### 自定义工具 (Custom Tools)\n\n支持扩展的工具类型：\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(tag = \"type\", rename_all = \"snake_case\")]\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n\npub enum EsqlResultFormat {\n    Json,   // 默认，输出 JSON 数组或对象\n    Value,  // 单属性时仅输出值\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:20-35]()\n\n## 配置系统\n\n### 配置结构\n\n```yaml\n{\n  \"elasticsearch\": {\n    \"url\": \"https://localhost:9200\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n### 环境变量配置\n\n| 变量名 | 必填 | 说明 |\n|--------|------|------|\n| `ES_URL` | 是 | Elasticsearch 集群 URL |\n| `ES_API_KEY` | 否 | API Key 认证 |\n| `ES_USERNAME` | 否 | 用户名（需配合密码使用） |\n| `ES_PASSWORD` | 否 | 密码 |\n| `ES_SSL_SKIP_VERIFY` | 否 | 跳过 SSL 证书验证 |\n\n资料来源：[src/lib.rs:1-30]()\n\n### 配置加载流程\n\n```mermaid\nsequenceDiagram\n    participant CLI as 命令行\n    participant Config as 配置解析器\n    participant Interpolator as 变量插值器\n    participant ES as ElasticsearchMcp\n\n    CLI->>Config: 加载配置文件\n    Config->>Interpolator: 解析 ${VAR:default} 语法\n    Interpolator-->>Config: 返回展开后的配置\n    Config->>ES: new_with_config(config)\n    ES->>ES: 创建连接池和认证\n    ES-->>CLI: 返回处理器实例\n```\n\n## 通信协议\n\n### 支持的传输模式\n\n| 模式 | 说明 | 使用场景 |\n|------|------|----------|\n| `stdio` | 标准输入/输出 | 本地 Claude Desktop 集成 |\n| `http` | Streamable HTTP | Web 集成、远程访问 |\n\n资料来源：[src/cli.rs:30-50]()\n\n### HTTP 服务配置\n\n```rust\npub struct HttpCommand {\n    /// 配置文件路径\n    pub config: Option<PathBuf>,\n    \n    /// 监听地址 [default: 127.0.0.1:8080]\n    pub address: Option<std::net::SocketAddr>,\n    \n    /// 启用 SSE 服务于 '/sse'\n    pub sse: bool,\n}\n```\n\n| 参数 | 默认值 | 环境变量 |\n|------|--------|----------|\n| `--address` | 127.0.0.1:8080 | `HTTP_ADDRESS` |\n| `--config` | 无 | 无 |\n| `--sse` | false | 无 |\n\n资料来源：[src/cli.rs:35-48]()\n\n## 认证机制\n\n### 认证流程\n\n```mermaid\ngraph LR\n    A[\"请求上下文\"] --> B{\"授权头存在?\"}\n    B -->|是| C[\"使用请求头认证\"]\n    B -->|否| D{\"配置中有凭证?\"}\n    D -->|API Key| E[\"EncodedApiKey\"]\n    D -->|用户名密码| F[\"Basic Auth\"]\n    D -->|无| G[\"匿名访问\"]\n```\n\n### 凭证优先级\n\n1. HTTP 请求头中的 `Authorization`\n2. 配置中的 `api_key`\n3. 配置中的 `username` + `password`\n\n资料来源：[src/servers/elasticsearch/mod.rs:80-95]()\n\n## 部署方式\n\n### Docker 部署\n\n```bash\n# Stdio 模式\ndocker run --rm \\\n  -e ES_URL \\\n  -e ES_API_KEY \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n\n# HTTP 模式\ndocker run --rm \\\n  -e ES_URL \\\n  -e ES_API_KEY \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n### Claude Desktop 配置 (Stdio)\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"--rm\",\n        \"-e\", \"ES_URL\",\n        \"-e\", \"ES_API_KEY\",\n        \"docker.elastic.co/mcp/elasticsearch\",\n        \"stdio\"\n      ]\n    }\n  }\n}\n```\n\n### HTTP 模式配置\n\n通过 `mcp-proxy` 桥接到 Claude Desktop：\n\n```bash\nuv tool install mcp-proxy\n```\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"/path/to/mcp-proxy\",\n      \"args\": [\n        \"--transport=streamablehttp\",\n        \"--header\", \"Authorization\", \"ApiKey <key>\",\n        \"http://host:8080/mcp\"\n      ]\n    }\n  }\n}\n```\n\n## 已知问题与限制\n\n### 社区反馈的问题\n\n| 问题编号 | 描述 | 状态 |\n|----------|------|------|\n| #185 | `get_mappings` 工具在嵌套类型未显式声明时解码失败 | 待修复 |\n| #170 | Basic 认证失败 (401 Unauthorized) | 社区讨论中 |\n| #191 | 缺少 Linux ARM64 二进制发布 | 功能请求 |\n\n### 健康检查\n\nHTTP 模式提供健康检查端点：\n\n```bash\ncurl http://<host>:8080/ping\n# 返回: pong\n```\n\n## 版本历史\n\n| 版本 | 主要变更 |\n|------|----------|\n| v0.4.6 | 添加弃用通知 |\n| v0.4.5 | 修复用户名环境变量名称 |\n| v0.4.4 | 添加 CA 证书支持 |\n| v0.4.3 | 默认端口改回 8080 |\n| v0.4.2 | 默认端口改为 8000 |\n| v0.4.1 | 添加 `CLI_ARGS` 环境变量支持 |\n| v0.3.1 | 修复 `npx` 执行缺少 hashbang |\n| v0.3.0 | 添加 OpenTelemetry 支持、Smithery 配置 |\n\n## 技术栈\n\n| 组件 | 技术 |\n|------|------|\n| 语言 | Rust |\n| HTTP 客户端 | elasticsearch-rs |\n| MCP 框架 | rmcp |\n| 序列化 | serde_json, serde_json5 |\n| 宏处理 | rmcp_macros |\n| CLI | clap |\n\n## 依赖管理\n\n项目使用 Renovate 进行自动化依赖更新：\n\n- 计划：每周一 1:00 后执行\n- 配置：继承自 `elastic/renovate-config`\n\n```json\n{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\"local>elastic/renovate-config\"],\n  \"schedule\": [\"after 1am on monday\"]\n}\n```\n\n资料来源：[renovate.json:1-8]()\n\n## 持续集成\n\n项目使用 Buildkite 进行 CI/CD：\n\n| 流水线 | 触发条件 | 说明 |\n|--------|----------|------|\n| mcp-server-elasticsearch | PR、推送 | 执行检查 |\n| mcp-server-elasticsearch-docker | Tags | 构建并发布 Docker 镜像 |\n\n资料来源：[catalog-info.yaml:20-80]()\n\n---\n\n<a id='page-changelog'></a>\n\n## 版本历史与更新\n\n### 相关页面\n\n相关主题：[项目介绍](#page-intro), [故障排除指南](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [NOTICE.txt](https://github.com/elastic/mcp-server-elasticsearch/blob/main/NOTICE.txt)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n- [renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json)\n</details>\n\n# 版本历史与更新\n\nElasticsearch MCP Server 是由 Elasticsearch B.V. 开发维护的 Model Context Protocol (MCP) 服务器实现，旨在为 AI 代理提供与 Elasticsearch 集群交互的能力。本页面记录该项目的完整版本历史、功能演进以及重要更新信息。\n\n## 版本发布时间线\n\n```mermaid\ntimeline\n    title Elasticsearch MCP Server 版本发布历史\n    v0.2.0 : 新增 get_shards 工具\n             灵活认证验证\n             索引模式参数\n    v0.3.0 : Smithery 配置支持\n             OpenTelemetry 支持\n             聚合结果返回\n             profile 和 explain\n    v0.3.1 : 修复 npx hashbang 问题\n    v0.4.1 : Dockerfile EXPOSE\n             CLI_ARGS 环境变量\n    v0.4.2 : 默认端口 8000\n    v0.4.3 : 默认端口恢复 8080\n    v0.4.4 : 添加 CA 证书\n    v0.4.5 : 用户名 ENV 名称更新\n    v0.4.6 : 添加弃用通知\n```\n\n## 各版本详细说明\n\n### v0.4.6（最新版本）\n\n**发布状态**：当前稳定版本\n\n**主要变更**：添加了项目弃用通知（Deprecation Notice），提示用户项目已进入维护模式。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.6)\n\n---\n\n### v0.4.5\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #158 | @mol91 | 更新用户名环境变量名称 |\n\n该版本修复了环境变量命名问题，使认证配置更加直观。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.5)\n\n---\n\n### v0.4.4\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #145 | @swallez | 添加 CA 证书支持 |\n\n此版本添加了对 CA 证书的支持，增强了 SSL/TLS 连接的安全性验证。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.4)\n\n---\n\n### v0.4.3\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #144 | @swallez | 将默认端口改回 8080 |\n\n此版本将 HTTP 服务器的默认端口从 v0.4.2 的 8000 改回 8080，保持与之前版本的一致性。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.3)\n\n---\n\n### v0.4.2\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #142 | @JoshMock | 将默认端口改为 8000 |\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.2)\n\n---\n\n### v0.4.1\n\n**主要变更**：\n\n| 变更类型 | 提交 | 说明 |\n|---------|------|------|\n| 修复 | 0cc4d1fe | 添加 Dockerfile `EXPOSE 8080` 指令 |\n| 修复 | 336f4635 | 添加 `CLI_ARGS` 环境变量作为传参替代方案 |\n\n此版本改进了 Docker 部署体验，提供了更灵活的配置方式。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.4.1)\n\n---\n\n### v0.3.1\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 说明 |\n|---------|---------|--------|------|\n| 修复 | #122 | @JoshMock | 修复 `npx -y @elastic/mcp-server-elasticsearch` 缺少 hashbang 的问题 |\n\n此版本修复了通过 npx 方式运行时的可执行性问题。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.3.1)\n\n---\n\n### v0.3.0\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 功能说明 |\n|---------|---------|--------|----------|\n| 功能 | #31 | @calclavia | Smithery 配置支持 |\n| 功能 | #64 | @anuraaga | OpenTelemetry 支持 |\n| 功能 | #46 | @sternbergm | 搜索工具添加聚合结果返回 |\n\n此版本是一个重要的功能版本，引入了多项关键功能：\n\n1. **Smithery 配置**：支持通过 Smithery 平台进行安装配置\n2. **OpenTelemetry 支持**：集成了分布式追踪能力，便于监控和调试\n3. **聚合结果**：search 工具现在可以返回聚合查询结果\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.3.0)\n\n---\n\n### v0.2.0\n\n**主要变更**：\n\n| 变更类型 | PR 编号 | 贡献者 | 功能说明 |\n|---------|---------|--------|----------|\n| 功能 | #25 | @getsolaris | 新增 `get_shards` 工具 |\n| 功能 | #27 | @getsolaris | 更灵活的认证验证 |\n| 功能 | #100 | @susan-shu-c | list_indices 工具添加索引模式参数 |\n\n此版本奠定了 MCP Server 的核心工具集基础。\n\n资料来源：[社区发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases/tag/v0.2.0)\n\n---\n\n## 工具演进历史\n\n### 核心工具列表\n\n| 工具名称 | 首次引入版本 | 功能描述 |\n|----------|-------------|----------|\n| `list_indices` | v0.2.0 | 列出所有可用的 Elasticsearch 索引 |\n| `get_shards` | v0.2.0 | 获取索引分片信息 |\n| `search` | 初始版本 | 使用 Query DSL 执行搜索查询 |\n| `get_mappings` | 初始版本 | 获取索引映射定义 |\n| ES\\|QL | v0.3.0 | 执行 ES|QL 查询 |\n| Search Template | 后续版本 | 使用搜索模板执行查询 |\n\n### 工具实现架构\n\n```mermaid\ngraph TD\n    A[MCP Client] -->|Request| B[ServerHandler]\n    B --> C[EsBaseTools]\n    C --> D{工具类型}\n    D -->|list_indices| E[cat.indices API]\n    D -->|get_shards| F[cat.shards API]\n    D -->|search| G[search API]\n    D -->|get_mappings| H[mappings API]\n    D -->|esql| I[esql API]\n    \n    E --> J[Elasticsearch Cluster]\n    F --> J\n    G --> J\n    H --> J\n    I --> J\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n\n---\n\n## 协议与传输模式演进\n\n### 支持的传输模式\n\n| 模式 | 支持版本 | 说明 |\n|------|---------|------|\n| stdio | v0.2.0 起 | 标准输入输出模式，适用于本地 CLI |\n| HTTP | v0.4.x | Streamable HTTP 模式 |\n| SSE | v0.4.x | Server-Sent Events（已弃用） |\n\n### HTTP 端点配置\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n资料来源：[src/cli.rs:32-47](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### HTTP 路由结构\n\n| 端点 | 方法 | 功能 |\n|------|------|------|\n| `/` | GET | 服务信息 |\n| `/ping` | GET | 健康检查 |\n| `/mcp` | POST | MCP 请求端点 |\n| `/mcp/sse` | GET | SSE 连接端点 |\n| `/_health/ready` | GET | 就绪探针 |\n| `/_health/live` | GET | 存活探针 |\n\n资料来源：[src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n\n---\n\n## 认证机制演进\n\n### 支持的认证方式\n\n| 认证方式 | 配置参数 | 说明 |\n|----------|---------|------|\n| API Key | `ES_API_KEY` | Base64 编码的 API 密钥 |\n| Basic Auth | `ES_USERNAME` + `ES_PASSWORD` | 用户名密码认证 |\n\n### 认证配置代码\n\n```rust\nimpl ElasticsearchMcp {\n    pub fn new_with_config(config: ElasticsearchMcpConfig, container_mode: bool) -> anyhow::Result<base_tools::EsBaseTools> {\n        let creds = if let Some(api_key) = config.api_key.clone() {\n            Some(Credentials::EncodedApiKey(api_key))\n        } else if let Some(username) = config.username.clone() {\n            let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n            Some(Credentials::Basic(username, pwd))\n        } else {\n            None\n        };\n        // ...\n    }\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:94-107](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 已知认证问题\n\n**Issue #170**：部分用户反馈在使用 Docker 部署时，即使环境变量配置正确，仍然出现 401 Unauthorized 错误。建议检查：\n\n1. 环境变量名称是否正确（`ES_USERNAME` 而非 `ES_lOGIN`）\n2. Elasticsearch 集群的认证配置\n3. 网络连通性\n\n---\n\n## 依赖更新管理\n\n### Renovate 配置\n\n项目使用 Renovate 进行自动化依赖更新管理：\n\n```json\n{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"local>elastic/renovate-config\"\n  ],\n  \"schedule\": [\n    \"after 1am on monday\"\n  ]\n}\n```\n\n资料来源：[renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json)\n\n### 更新策略\n\n- **更新频率**：每周一凌晨 1 点后自动检查更新\n- **仪表板**：通过 [Issue #6](https://github.com/elastic/mcp-server-elasticsearch/issues/6) 查看所有待处理和已完成的依赖更新\n\n---\n\n## 已知问题与限制\n\n### get_mappings 工具问题\n\n**Issue #185**：当 mapping 中 nested 属性未显式指定 `\"type\": \"nested\"` 时，`get_mappings` 工具会返回 `\"error decoding response body\"` 错误，尽管该 mapping 在 Elasticsearch 规范中是有效的。\n\n**状态**：社区已报告，等待修复。\n\n### 其他社区关注的问题\n\n| Issue | 标题 | 关注度 |\n|-------|------|--------|\n| #17 | Support streamable HTTP | 4 评论 |\n| #170 | Basic auth failed - 401 Unauthorized | 22 评论 |\n| #45 | Add Aggregation results to return fields | 1 评论 |\n| #191 | Publish a linux arm64 binary | 3 评论 |\n| #173 | Error messages for some functions | 4 评论 |\n\n---\n\n## 版权与许可\n\n```\nElasticsearch MCP Server\nCopyright 2025 Elasticsearch B.V.\n```\n\n资料来源：[NOTICE.txt](https://github.com/elastic/mcp-server-elasticsearch/blob/main/NOTICE.txt)\n\n---\n\n## 相关资源\n\n| 资源类型 | 链接 |\n|---------|------|\n| GitHub 仓库 | https://github.com/elastic/mcp-server-elasticsearch |\n| 问题反馈 | https://github.com/elastic/mcp-server-elasticsearch/issues |\n| 版本发布页 | https://github.com/elastic/mcp-server-elasticsearch/releases |\n| MCP 协议文档 | https://modelcontextprotocol.io |\n| Renovate 配置 | [renovate.json](https://github.com/elastic/mcp-server-elasticsearch/blob/main/renovate.json) |\n\n---\n\n<a id='page-architecture'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[项目介绍](#page-intro), [通信协议配置](#page-protocols), [MCP 工具详解](#page-tools)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n</details>\n\n# 系统架构\n\n## 概述\n\nElasticsearch MCP Server 是一个基于 Model Context Protocol (MCP) 的中间件服务，用于将 Elasticsearch 集群与 AI 代理进行连接。它充当协议转换层，将 MCP 协议请求转换为 Elasticsearch HTTP API 调用，并返回结构化结果。\n\n**核心职责**：\n- 接收来自 MCP 客户端（如 Claude Desktop、Cursor 等）的标准化工具调用请求\n- 验证认证信息并建立与 Elasticsearch 集群的连接\n- 将请求路由至相应的工具处理器并执行查询\n- 将 Elasticsearch 响应转换回 MCP 协议格式返回\n\n**技术栈**：\n- 语言：Rust\n- MCP 协议：rmcp (Rust MCP 实现)\n- Elasticsearch 客户端：elasticsearch crate\n\n资料来源：[src/lib.rs:1-50](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n\n---\n\n## 架构分层\n\n```mermaid\ngraph TD\n    subgraph \"接入层\"\n        A[MCP 客户端]\n        B[Stdio Transport]\n        C[Streamable HTTP Transport]\n    end\n    \n    subgraph \"协议层\"\n        D[MCP 协议解析器]\n        E[工具调用分发]\n    end\n    \n    subgraph \"业务层\"\n        F[EsBaseTools 工具集]\n        G[CustomTool 自定义工具]\n        H[EsClientProvider 客户端管理]\n    end\n    \n    subgraph \"通信层\"\n        I[Elasticsearch HTTP API]\n    end\n    \n    subgraph \"外部服务\"\n        J[Elasticsearch 集群]\n    end\n    \n    A --> B\n    A --> C\n    B --> D\n    C --> D\n    D --> E\n    E --> F\n    E --> G\n    F --> H\n    G --> H\n    H --> I\n    I --> J\n```\n\n---\n\n## 服务器模式\n\nMCP Server 支持两种运行模式，通过命令行子命令选择：\n\n### Stdio 模式\n\n标准输入输出模式，适用于本地进程通信场景。这是 MCP 的传统传输方式。\n\n```rust\n#[derive(Debug, Subcommand)]\npub enum Command {\n    Stdio(StdioCommand),\n    Http(HttpCommand),\n}\n```\n\n配置示例：\n```json\n{\n  \"command\": \"docker\",\n  \"args\": [\"run\", \"--rm\", \"-e\", \"ES_URL=https://localhost:9200\", \n           \"-e\", \"ES_API_KEY=<key>\", \"mcp-server-elasticsearch\", \"stdio\"],\n  \"env\": {}\n}\n```\n\n资料来源：[src/cli.rs:30-45](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### HTTP 模式\n\n支持远程访问的 HTTP 服务器模式，默认监听 `127.0.0.1:8080`。\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n**启动命令示例**：\n```bash\n./mcp-server-elasticsearch http --address 0.0.0.0:8080\n```\n\n> [!NOTE]\n> 社区反馈显示，HTTP/SSE 模式在某些 AI 代理（如 n8n）中存在兼容性问题。参见 [Issue #173](https://github.com/elastic/mcp-server-elasticsearch/issues/173)。\n\n---\n\n## 配置系统\n\n### 配置层次结构\n\n```mermaid\ngraph LR\n    A[环境变量] --> B[interpolator]\n    C[config.json5] --> B\n    B --> D[Configuration]\n    D --> E[ElasticsearchMcpConfig]\n    D --> F[McpServer]\n```\n\n### 主配置结构\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Configuration {\n    pub elasticsearch: elasticsearch::ElasticsearchMcpConfig,\n    #[serde(default)]\n    pub mcp_servers: HashMap<String, McpServer>,\n}\n```\n\n资料来源：[src/cli.rs:95-105](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### Elasticsearch 配置项\n\n| 参数 | 环境变量 | 类型 | 默认值 | 说明 |\n|------|----------|------|--------|------|\n| url | `ES_URL` | String | - | Elasticsearch 集群地址 |\n| api_key | `ES_API_KEY` | Option<String> | None | API Key 认证 |\n| username | `ES_USERNAME` | Option<String> | None | 用户名（需配合 password） |\n| password | `ES_PASSWORD` | Option<String> | None | 密码（需配合 username） |\n| ssl_skip_verify | `ES_SSL_SKIP_VERIFY` | bool | false | 跳过 SSL 证书验证 |\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\npub struct ElasticsearchMcpConfig {\n    /// Cluster URL\n    pub url: String,\n\n    /// API key\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub api_key: Option<String>,\n\n    /// Username\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub username: Option<String>,\n\n    /// Password\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub password: Option<String>,\n\n    /// Should we skip SSL certificate verification?\n    #[serde(default, deserialize_with = \"deserialize_bool_from_anything\")]\n    pub ssl_skip_verify: bool,\n\n    /// Search templates to expose as tools or resources\n    #[serde(default)]\n    pub tools: Tools,\n\n    /// Prompts\n    #[serde(default)]\n    pub prompts: Vec<String>,\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:60-90](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 环境变量插值\n\n配置文件中支持 `${VAR_NAME}` 和 `${VAR_NAME:default_value}` 语法：\n\n```rust\nlet value = if let Some((name, default)) = expr.split_once(':') {\n    lookup(name).unwrap_or(default.to_string())\n} else {\n    lookup(expr).ok_or_else(|| err(char_no, format!(\"env variable '{expr}' not defined\")))?\n};\n```\n\n**示例配置**：\n\n```json\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n资料来源：[src/utils/interpolator.rs:40-50](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n\n---\n\n## 认证机制\n\n### 认证流程\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP 客户端\n    participant Server as MCP Server\n    participant ES as Elasticsearch\n    \n    MCP->>Server: 请求 (含 Authorization Header)\n    Server->>Server: 检查 Authorization Header\n    \n    alt 使用请求头中的认证\n        Server->>ES: 转发 Authorization Header\n    else 使用配置中的认证\n        Server->>ES: 使用配置的 API Key 或 Basic Auth\n    end\n    \n    ES-->>Server: 响应\n    Server-->>MCP: 处理结果\n```\n\n### 认证凭证类型\n\n```rust\nimpl ElasticsearchMcp {\n    pub fn new_with_config(config: ElasticsearchMcpConfig, container_mode: bool) \n        -> anyhow::Result<base_tools::EsBaseTools> {\n        \n        let creds = if let Some(api_key) = config.api_key.clone() {\n            Some(Credentials::EncodedApiKey(api_key))\n        } else if let Some(username) = config.username.clone() {\n            let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n            Some(Credentials::Basic(username, pwd))\n        } else {\n            None\n        };\n        \n        // ... 构建 Transport\n        if let Some(creds) = creds {\n            transport = transport.auth(creds);\n        }\n    }\n}\n```\n\n### 优先级规则\n\n1. **请求级别**：如果传入的 HTTP 请求包含 `Authorization` Header，则优先使用\n2. **配置级别**：否则使用配置文件中的认证信息\n\n```rust\n/// If the incoming request is a http request and has an `Authorization` header, use it\n/// to authenticate to the remote ES instance.\npub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:105-130](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n---\n\n## 工具系统\n\n### 内置工具\n\n| 工具名称 | 功能 | 只读 | 参数 |\n|----------|------|------|------|\n| `list_indices` | 列出匹配的索引 | 是 | `index_pattern: String` |\n| `get_mappings` | 获取索引映射 | 是 | `index: String` |\n| `get_shards` | 获取分片信息 | 是 | `index: Option<String>` |\n| `search` | 执行搜索查询 | 是 | `index, fields?, query_body` |\n| `esql` | 执行 ES\\|QL 查询 | 是 | `query: String` |\n\n### 工具定义示例\n\n```rust\n#[tool(\n    description = \"List all available Elasticsearch indices\",\n    annotations(title = \"List ES indices\", read_only_hint = true)\n)]\nasync fn list_indices(\n    &self,\n    req_ctx: RequestContext<RoleServer>,\n    Parameters(ListIndicesParams { index_pattern }): Parameters<ListIndicesParams>,\n) -> Result<CallToolResult, rmcp::Error> {\n    let es_client = self.es_client.get(req_ctx);\n    \n    let response = es_client\n        .cat()\n        .indices(CatIndicesParts::Index(&[&index_pattern]))\n        .h(&[\"index\", \"status\", \"docs.count\"])\n        .format(\"json\")\n        .send()\n        .await;\n\n    let response: Vec<CatIndexResponse> = read_json(response).await?;\n\n    Ok(CallToolResult::success(vec![\n        Content::text(format!(\"Found {} indices:\", response.len())),\n        Content::json(response)?,\n    ]))\n}\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:80-105](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n\n### 自定义工具\n\n除内置工具外，系统还支持通过配置文件定义自定义工具：\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(tag = \"type\", rename_all = \"snake_case\")]\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n```\n\n**自定义工具配置示例**：\n\n```json\n{\n  \"tools\": {\n    \"custom\": {\n      \"my_esql_tool\": {\n        \"type\": \"esql\",\n        \"description\": \"Run specific ES|QL query\",\n        \"parameters\": {},\n        \"query\": \"FROM my-index | LIMIT 10\"\n      }\n    }\n  }\n}\n```\n\n### SearchTemplate 工具\n\n支持将预定义的搜索模板暴露为 MCP 工具：\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum SearchTemplate {\n    TemplateId(String),\n    Template(serde_json::Value),\n}\n```\n\n---\n\n## 数据模型\n\n### 搜索响应\n\n```rust\n#[derive(Serialize, Deserialize)]\npub struct SearchResult {\n    pub hits: Hits,\n    #[serde(default)]\n    pub aggregations: IndexMap<String, Value>,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Hits {\n    pub total: Option<TotalHits>,\n    pub hits: Vec<Hit>,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Hit {\n    #[serde(rename = \"_source\")]\n    pub source: Value,\n}\n```\n\n### 映射响应\n\n```rust\n#[derive(Serialize, Deserialize)]\npub struct MappingResponse {\n    // HashMap<String, Mappings>\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Mappings {\n    pub mappings: Mapping,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct Mapping {\n    #[serde(rename = \"_meta\", skip_serializing_if = \"Option::is_none\")]\n    pub meta: Option<JsonObject>,\n    properties: HashMap<String, MappingProperty>,\n}\n\n#[derive(Serialize, Deserialize)]\npub struct MappingProperty {\n    #[serde(rename = \"type\")]\n    pub type_: String,\n    #[serde(flatten)]\n    pub settings: HashMap<String, serde_json::Value>,\n}\n```\n\n> [!WARNING]\n> 社区反馈显示，`get_mappings` 工具在处理嵌套类型属性时存在问题。当嵌套属性未显式声明 `\"type\": \"nested\"` 时，服务器会抛出 \"error decoding response body\" 错误。参见 [Issue #185](https://github.com/elastic/mcp-server-elasticsearch/issues/185)。\n\n---\n\n## 请求处理流程\n\n```mermaid\ngraph TD\n    A[接收 MCP 请求] --> B{解析请求类型}\n    \n    B -->|工具调用| C[分发至工具处理器]\n    B -->|资源请求| D[返回资源数据]\n    B -->|提示请求| E[返回预定义提示]\n    \n    C --> F{选择认证方式}\n    \n    F -->|使用配置的认证| G[从配置构建凭证]\n    F -->|使用请求头认证| H[从 Authorization Header 提取]\n    \n    G --> I[构建 Elasticsearch 客户端]\n    H --> I\n    \n    I --> J[发送 HTTP 请求到 ES]\n    J --> K{ES 响应状态}\n    \n    K -->|成功 2xx| L[读取响应体]\n    K -->|错误 4xx/5xx| M[构建错误响应]\n    \n    L --> N{解析响应格式}\n    N -->|JSON| O[反序列化为结构体]\n    N -->|纯文本| P[直接返回]\n    \n    O --> Q[构建 MCP CallToolResult]\n    P --> Q\n    \n    M --> R[返回 rmcp::Error]\n    Q --> S[返回给 MCP 客户端]\n```\n\n### 错误处理\n\n```rust\npub fn handle_error(result: Result<Response, elasticsearch::Error>) \n    -> Result<Response, rmcp::Error> {\n    match result {\n        Ok(resp) => resp.error_for_status_code(),\n        Err(e) => {\n            tracing::error!(\"Error: {:?}\", &e);\n            Err(e)\n        }\n    }\n    .map_err(internal_error)\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:140-155](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n---\n\n## 核心组件关系\n\n```mermaid\nclassDiagram\n    class ElasticsearchMcp {\n        +new_with_config(config, container_mode) EsBaseTools\n    }\n    \n    class EsBaseTools {\n        +es_client: EsClientProvider\n        +tool_router: ToolRouter~EsBaseTools~\n    }\n    \n    class EsClientProvider {\n        -client: Elasticsearch\n        +get(context) Elasticsearch\n    }\n    \n    class ElasticsearchMcpConfig {\n        +url: String\n        +api_key: Option~String~\n        +username: Option~String~\n        +password: Option~String~\n        +ssl_skip_verify: bool\n    }\n    \n    ElasticsearchMcp --> ElasticsearchMcpConfig : 配置\n    ElasticsearchMcp --> EsBaseTools : 创建\n    EsBaseTools --> EsClientProvider : 持有\n    EsClientProvider --> Elasticsearch : HTTP 客户端\n```\n\n---\n\n## MCP 服务器配置\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\n#[serde(tag = \"type\")]\npub enum McpServer {\n    Sse(Http),\n    StreamableHttp(Http),\n    Stdio(Stdio),\n}\n```\n\n| 类型 | 用途 | 配置项 |\n|------|------|--------|\n| `Sse` | Server-Sent Events 模式 | url, headers |\n| `StreamableHttp` | 可流式传输的 HTTP | url, headers |\n| `Stdio` | 标准输入输出模式 | command, args, env |\n\n---\n\n## 启动流程\n\n```mermaid\nsequenceDiagram\n    participant Main as main.rs\n    participant Lib as lib.rs\n    participant CLI as cli.rs\n    participant Server as MCP Server\n    \n    Main->>CLI: 解析命令行参数\n    Main->>Lib: 调用创建处理器\n    Lib->>Lib: 加载配置文件\n    Lib->>Lib: 环境变量插值\n    Lib->>Lib: 构建 ElasticsearchMcpConfig\n    Lib->>Server: new_with_config()\n    Server->>Server: 构建 EsClientProvider\n    Server->>Server: 注册工具处理器\n    Main->>Server: 启动服务器循环\n```\n\n初始化流程（简化版）：\n\n```rust\n// 1. 加载默认配置模板\nlet config = r#\"{\n    \"elasticsearch\": {\n        \"url\": \"${ES_URL}\",\n        \"api_key\": \"${ES_API_KEY:}\",\n        \"username\": \"${ES_USERNAME:}\",\n        \"password\": \"${ES_PASSWORD:}\",\n        \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n    }\n}\"#.to_string();\n\n// 2. 环境变量插值\nlet config = interpolator::interpolate_from_env(config)?;\n\n// 3. JSON5 解析（支持注释）\nlet config: Configuration = serde_json5::from_str(&config)?;\n\n// 4. 构建处理器\nlet handler = elasticsearch::ElasticsearchMcp::new_with_config(\n    config.elasticsearch, \n    container_mode\n)?;\n```\n\n资料来源：[src/lib.rs:20-45](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n\n---\n\n## 安全考虑\n\n### 凭证管理\n\n| 凭证类型 | 存储位置 | 说明 |\n|----------|----------|------|\n| API Key | 环境变量 | 推荐生产环境使用 |\n| 用户名/密码 | 环境变量 | 需配合使用 |\n| Authorization Header | HTTP 请求头 | 支持 per-request 认证 |\n\n### 网络安全\n\n- **HTTPS**：当 `ES_URL` 使用 `https://` 时自动启用 TLS 加密\n- **容器模式**：自动重写 `localhost` 为 `host.docker.internal` 以支持 Docker 网络\n\n```rust\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n### 证书验证\n\n- **验证启用**：`ES_SSL_SKIP_VERIFY=false`（默认）\n- **验证跳过**：`ES_SSL_SKIP_VERIFY=true`（仅用于测试环境）\n\n---\n\n<a id='page-protocols'></a>\n\n## 通信协议配置\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n- [src/protocol/stdio.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/stdio.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n</details>\n\n# 通信协议配置\n\n## 概述\n\nElasticsearch MCP Server 支持两种通信协议模式，用于与 MCP 客户端建立连接并传输数据。协议配置是整个服务架构的核心组成部分，决定了客户端如何与服务器通信、认证方式如何处理，以及请求如何在 MCP 协议层进行路由。\n\n本项目实现了 **Stdio（标准输入/输出）** 和 **HTTP/SSE（服务器发送事件）** 两种传输模式，分别适用于不同的部署场景和客户端类型。\n\n## 协议架构\n\n```mermaid\ngraph TD\n    A[MCP 客户端] --> B{传输模式选择}\n    B -->|Stdio| C[Stdio 协议层]\n    B -->|HTTP/SSE| D[HTTP 协议层]\n    C --> E[rmcp 框架]\n    D --> E\n    E --> F[工具路由器 ToolRouter]\n    F --> G[Elasticsearch 工具集]\n    G --> H[Elasticsearch 集群]\n    \n    style C fill:#e1f5fe\n    style D fill:#fff3e0\n```\n\n## 传输模式\n\n### Stdio 模式\n\nStdio 模式是最基础的通信方式，通过标准输入（stdin）和标准输出（stdout）进行 JSON-RPC 消息的传输。这种模式适用于本地进程调用和命令行工具集成。\n\n**配置参数：**\n\n| 参数 | 标志 | 说明 |\n|------|------|------|\n| 配置文件 | `-c, --config` | 可选配置文件路径 |\n| 传输类型 | `stdio` | 通过 stdin/stdout 通信 |\n\nStdio 模式的启动命令：\n\n```bash\nmcp-server-elasticsearch stdio --config /path/to/config.json\n```\n\n### HTTP/SSE 模式\n\nHTTP 模式提供了远程访问能力，支持通过 HTTP 请求与 MCP 服务器交互。该模式使用 Axum 框架构建异步 HTTP 服务器，并可选地启用 SSE（Server-Sent Events）端点实现服务端推送。\n\n**核心配置参数：**\n\n| 参数 | 环境变量 | 默认值 | 说明 |\n|------|----------|--------|------|\n| 监听地址 | `HTTP_ADDRESS` | `127.0.0.1:8080` | 服务器监听的网络地址 |\n| SSE 启用 | `--sse` | 关闭 | 是否启用 SSE 端点 |\n| 配置文件 | `-c, --config` | 无 | 配置文件路径 |\n\nHTTP 模式的启动命令：\n\n```bash\nmcp-server-elasticsearch http --address 0.0.0.0:8080 --config /path/to/config.json\n```\n\n启用 SSE 模式：\n\n```bash\nmcp-server-elasticsearch http --address 0.0.0.0:8080 --sse\n```\n\n**服务端点：**\n\n| 端点 | 方法 | 功能 |\n|------|------|------|\n| `/` | GET | 服务器信息 |\n| `/ping` | GET | 健康检查 |\n| `/mcp/sse` | SSE | SSE 传输端点 |\n| `/mcp` | MCP | MCP 协议处理 |\n| `/_health/ready` | GET | 就绪探针 |\n| `/_health/live` | GET | 存活探针 |\n\n```mermaid\nsequenceDiagram\n    participant C as MCP 客户端\n    participant H as HTTP 服务器\n    participant M as MCP 处理层\n    participant ES as Elasticsearch\n    \n    C->>H: HTTP POST /mcp (JSON-RPC)\n    H->>M: 转发请求\n    M->>ES: 执行查询\n    ES-->>M: 返回结果\n    M-->>H: JSON-RPC 响应\n    H-->>C: HTTP Response\n    \n    Note over C,H: SSE 模式可选用于服务端推送\n    C->>H: GET /mcp/sse\n    H-->>C: SSE Stream\n```\n\n## 命令行接口结构\n\n源码位置：[src/cli.rs:1-100](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n\n### Command 枚举\n\n```rust\n#[derive(Debug, Subcommand)]\npub enum Command {\n    Stdio(StdioCommand),\n    Http(HttpCommand),\n}\n```\n\n服务器支持两个顶层命令，分别对应不同的协议模式：\n\n- `Stdio` - 启动标准输入/输出服务器\n- `Http` - 启动 HTTP 服务器（可选 SSE）\n\n### HttpCommand 配置\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n## HTTP 协议实现\n\n源码位置：[src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n\n### 健康检查路由\n\n服务器实现了标准的 Kubernetes 就绪/存活探针接口：\n\n```rust\nlet health_router = {\n    Router::new()\n        .route(\"/ready\", get(async || (StatusCode::OK, \"Ready\\n\")))\n        .route(\"/live\", get(async || \"Alive\\n\"))\n};\n```\n\n### 路由聚合\n\n```rust\nlet main_router = Router::new()\n    .route(\"/\", get(hello))\n    .route(\"/ping\", get(async || (StatusCode::OK, \"Ready\\n\")))\n    .nest(\"/mcp/sse\", sse_router)\n    .nest(\"/mcp\", sh_router)\n    .nest(\"/_health\", health_router)\n    .with_state(());\n```\n\n### 服务器启动\n\n```rust\nlet listener = tokio::net::TcpListener::bind(config.bind).await?;\nlet server = axum::serve(listener, main_router).with_graceful_shutdown({\n    let ct = ct.clone();\n    async move {\n        ct.cancelled().await;\n        tracing::info!(\"http server cancelled\");\n    }\n});\n```\n\n## 认证与客户端上下文\n\n源码位置：[src/servers/elasticsearch/mod.rs:100-150](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### Credentials 配置\n\n```rust\npub struct ElasticsearchMcpConfig {\n    /// Cluster URL\n    pub url: String,\n\n    /// API key\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub api_key: Option<String>,\n\n    /// Username\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub username: Option<String>,\n\n    /// Password\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub password: Option<String>,\n\n    /// Should we skip SSL certificate verification?\n    #[serde(default, deserialize_with = \"deserialize_bool_from_anything\")]\n    pub ssl_skip_verify: bool,\n}\n```\n\n### 认证凭证构建\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n### EsClientProvider 客户端提供者\n\n```rust\npub struct EsClientProvider(Elasticsearch);\n\nimpl EsClientProvider {\n    pub fn new(client: Elasticsearch) -> Self {\n        EsClientProvider(client)\n    }\n\n    /// If the incoming request is a http request and has an `Authorization` header, use it\n    /// to authenticate to the remote ES instance.\n    pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n        // 根据请求上下文获取客户端实例\n    }\n}\n```\n\n## 配置加载流程\n\n源码位置：[src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n\n```mermaid\nflowchart LR\n    A[启动应用] --> B[解析命令行参数]\n    B --> C{协议模式}\n    C -->|stdio| D[启动 Stdio 服务器]\n    C -->|http| E[启动 HTTP 服务器]\n    E --> F[加载配置文件]\n    F --> G[环境变量插值]\n    G --> H[解析 JSON5 配置]\n    H --> I[构建 Elasticsearch 客户端]\n    I --> J[初始化工具路由]\n    J --> K[等待客户端连接]\n```\n\n### 环境变量插值\n\n配置支持 `${VAR_NAME}` 和 `${VAR_NAME:default_value}` 语法：\n\n```rust\nlet config = interpolator::interpolate_from_env(config)?;\n```\n\n### 默认配置模板\n\n```json\n{\n    \"elasticsearch\": {\n        \"url\": \"${ES_URL}\",\n        \"api_key\": \"${ES_API_KEY:}\",\n        \"username\": \"${ES_USERNAME:}\",\n        \"password\": \"${ES_PASSWORD:}\",\n        \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n    }\n}\n```\n\n## 协议选择指南\n\n| 场景 | 推荐模式 | 原因 |\n|------|----------|------|\n| 本地开发调试 | Stdio | 简单直接，无需网络配置 |\n| Claude Desktop / Cursor | Stdio | 原生支持 MCP stdio 协议 |\n| 远程服务部署 | HTTP | 支持网络访问和负载均衡 |\n| n8n 集成 | HTTP/SSE | 适合工作流自动化 |\n| 容器化部署 | 两者皆可 | 根据客户端类型选择 |\n\n## 常见问题\n\n### HTTP 401 认证失败\n\n社区 Issue #170 报告了在使用 Docker 部署时配置了正确的环境变量但仍出现认证失败的问题。解决方案：\n\n1. 确认环境变量 `ES_USERNAME`、`ES_PASSWORD` 或 `ES_API_KEY` 正确设置\n2. 使用 `docker exec` 进入容器验证凭证配置\n3. 测试与 Elasticsearch 集群的连接：\n\n```bash\n# 使用用户名密码\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n\n# 使用 API Key\ndocker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n```\n\n### SSE 与 Streamable HTTP\n\n由于 SSE 已被废弃，项目正在迁移到新的 Streamable HTTP 传输模式。详见社区 Issue #17。\n\n## 最佳实践\n\n1. **安全建议**\n   - 生产环境优先使用 API Key 认证\n   - 通过 HTTPS 连接到 Elasticsearch\n   - 使用 AWS Secrets Manager 管理敏感凭证\n\n2. **性能优化**\n   - HTTP 模式默认监听本地地址，如需远程访问改为 `0.0.0.0`\n   - 使用健康检查端点进行负载均衡器配置\n\n3. **配置管理**\n   - 使用配置文件集中管理复杂配置\n   - 利用环境变量插值实现环境差异化配置\n\n---\n\n<a id='page-tools'></a>\n\n## MCP 工具详解\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [故障排除指南](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/protocol/http.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/protocol/http.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n</details>\n\n# MCP 工具详解\n\n## 概述\n\nMCP Server Elasticsearch 提供了多个 MCP 工具，使 AI Agent 能够与 Elasticsearch 集群进行交互。这些工具通过 Model Context Protocol (MCP) 暴露，允许 LLM 通过自然语言执行索引管理、搜索查询、数据分析等操作。\n\n核心工具定义位于 `EsBaseTools` 结构体中，通过 `#[tool_router]` 宏注册每个工具的处理程序。工具支持通过请求上下文动态获取 Elasticsearch 客户端实例，实现基于请求的认证凭证传递。\n\n## 工具架构\n\n### 工具注册机制\n\n工具通过 Rust 宏 `#[tool]` 和 `#[tool_handler]` 进行声明和实现：\n\n```rust\n#[tool_router]\nimpl EsBaseTools {\n    #[tool(\n        description = \"工具描述\",\n        annotations(title = \"显示标题\", read_only_hint = true)\n    )]\n    async fn tool_name(\n        &self,\n        req_ctx: RequestContext<RoleServer>,\n        Parameters(Params): Parameters<Params>,\n    ) -> Result<CallToolResult, rmcp::Error> {\n        // 工具实现\n    }\n}\n```\n\n### 客户端提供机制\n\n工具通过 `EsClientProvider` 获取 Elasticsearch 客户端，该提供者支持基于 HTTP 请求 Authorization 头的动态认证：\n\n```rust\n#[derive(Clone)]\npub struct EsClientProvider(Elasticsearch);\n\nimpl EsClientProvider {\n    pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n        // 从请求上下文中提取认证信息\n    }\n}\n```\n\n## 核心工具列表\n\n### 1. list_indices - 列出索引\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index_pattern | String | 是 | 索引名称或通配符模式 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:73-95`\n\n该工具调用 Elasticsearch Cat API，返回匹配的索引列表：\n\n```rust\nasync fn list_indices(\n    &self,\n    req_ctx: RequestContext<RoleServer>,\n    Parameters(ListIndicesParams { index_pattern }): Parameters<ListIndicesParams>,\n) -> Result<CallToolResult, rmcp::Error> {\n    let es_client = self.es_client.get(req_ctx);\n    let response = es_client\n        .cat()\n        .indices(CatIndicesParts::Index(&[&index_pattern]))\n        .h(&[\"index\", \"status\", \"docs.count\"])\n        .format(\"json\")\n        .send()\n        .await;\n\n    let response: Vec<CatIndexResponse> = read_json(response).await?;\n    Ok(CallToolResult::success(vec![\n        Content::text(format!(\"Found {} indices:\", response.len())),\n        Content::json(response)?,\n    ]))\n}\n```\n\n### 2. get_mappings - 获取索引映射\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index | String | 是 | 索引名称 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:97-120`\n\n> [!NOTE]\n> **已知问题**: 当嵌套属性未显式指定 `\"type\": \"nested\"` 时，`get_mappings` 工具会返回 `\"error decoding response body\"` 错误。这是 Issue #185 报告的问题，尽管 Elasticsearch 规范允许省略显式类型声明。\n\n### 3. search - 执行搜索\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index | String | 是 | 索引名称 |\n| query_body | Map<String, Value> | 是 | 完整的 Elasticsearch Query DSL 对象 |\n| fields | Option<Vec<String>> | 否 | 指定返回的字段列表 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:130-180`\n\nsearch 工具支持完整的 Elasticsearch Query DSL，包括 query、size、from、sort、aggregations 等参数。\n\n```rust\nstruct SearchParams {\n    index: String,\n    fields: Option<Vec<String>>,\n    query_body: Map<String, Value>,\n}\n```\n\n返回结果包含：\n- `hits.total` - 匹配文档总数\n- `hits.hits` - 文档数组\n- `aggregations` - 聚合结果（如果有）\n\n### 4. esql - ES|QL 查询\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| query | String | 是 | 完整的 ES|QL 查询语句 |\n\n**实现位置**: `src/servers/elasticsearch/mod.rs:46-50`\n\n```rust\npub enum EsqlResultFormat {\n    #[default]\n    Json,   // 输出为 JSON 对象数组或单个对象\n    Value,  // 如果是单个属性，输出其值\n}\n```\n\n### 5. get_shards - 获取分片信息\n\n| 参数 | 类型 | 必需 | 说明 |\n|------|------|------|------|\n| index | Option<String> | 否 | 可选的索引名称 |\n\n**实现位置**: `src/servers/elasticsearch/base_tools.rs:41-69`\n\n该工具返回分片的详细信息：\n\n```rust\npub struct CatShardsResponse {\n    pub index: String,\n    pub shard: usize,\n    pub prirep: String,    // primary 或 replica\n    pub state: String,    // STARTED, INITIALIZING, etc.\n    pub docs: Option<u64>,\n    pub store: Option<u64>,\n    pub node: String,\n}\n```\n\n## 自定义工具扩展\n\n### Tools 配置结构\n\n用户可以通过配置文件定义自定义工具：\n\n```rust\npub struct Tools {\n    #[serde(flatten)]\n    pub incl_excl: Option<IncludeExclude>,\n    pub custom: HashMap<String, CustomTool>,\n}\n\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n```\n\n### SearchTemplateTool\n\n支持两种搜索模板定义方式：\n\n```rust\npub enum SearchTemplate {\n    TemplateId(String),           // 通过模板 ID 引用\n    Template(serde_json::Value),   // 内联模板定义\n}\n```\n\n## 工具响应格式\n\n所有工具通过 `CallToolResult` 返回结果：\n\n```rust\npub struct SearchResult {\n    pub hits: Hits,\n    #[serde(default)]\n    pub aggregations: IndexMap<String, Value>,\n}\n\npub struct Hits {\n    pub total: Option<TotalHits>,\n    pub hits: Vec<Hit>,\n}\n\npub struct Hit {\n    #[serde(rename = \"_source\")]\n    pub source: Value,\n}\n```\n\n## 配置选项\n\n### ElasticsearchMcpConfig\n\n| 配置项 | 环境变量 | 类型 | 默认值 | 说明 |\n|--------|----------|------|--------|------|\n| url | ES_URL | String | - | Elasticsearch 集群地址 |\n| api_key | ES_API_KEY | Option<String> | None | API Key 认证 |\n| username | ES_USERNAME | Option<String> | None | 用户名 |\n| password | ES_PASSWORD | Option<String> | None | 密码 |\n| ssl_skip_verify | ES_SSL_SKIP_VERIFY | bool | false | 跳过 SSL 验证 |\n| tools | - | Tools | empty | 自定义工具配置 |\n\n**实现位置**: `src/servers/elasticsearch/mod.rs:24-52`\n\n## 数据流图\n\n```mermaid\ngraph TD\n    A[MCP Client 请求] --> B[RequestContext 解析]\n    B --> C{认证方式}\n    C -->|API Key| D[Credentials::EncodedApiKey]\n    C -->|用户名密码| E[Credentials::Basic]\n    C -->|无认证| F[None]\n    D --> G[TransportBuilder 配置]\n    E --> G\n    F --> G\n    G --> H[Elasticsearch 客户端]\n    H --> I{请求类型}\n    I -->|list_indices| J[Cat Indices API]\n    I -->|get_mappings| K[Get Mapping API]\n    I -->|search| L[Search API]\n    I -->|esql| M[ES|QL API]\n    I -->|get_shards| N[Cat Shards API]\n    J --> O[CatIndexResponse]\n    K --> P[Mapping JSON]\n    L --> Q[SearchResult]\n    M --> R[ES|QL Result]\n    N --> S[CatShardsResponse]\n    O --> T[CallToolResult]\n    P --> T\n    Q --> T\n    R --> T\n    S --> T\n```\n\n## HTTP 协议支持\n\nMCP Server 支持通过 HTTP 进行远程访问：\n\n### HttpServerConfig\n\n| 配置项 | 类型 | 说明 |\n|--------|------|------|\n| bind | SocketAddr | TCP 监听地址 |\n| ct | CancellationToken | 取消令牌 |\n| keep_alive | Option<Duration> | SSE 保活时间 |\n| stateful_mode | bool | 启用状态会话 |\n| session_manager | Arc<M> | 会话管理器 |\n\n**实现位置**: `src/protocol/http.rs:13-30`\n\n### 命令行配置\n\n```rust\npub struct HttpCommand {\n    pub config: Option<PathBuf>,        // 配置文件路径\n    pub address: Option<SocketAddr>,   // 监听地址 [default: 127.0.0.1:8080]\n    pub sse: bool,                      // 启用 SSE 端点\n}\n```\n\n## 已知问题\n\n| Issue | 描述 | 影响 |\n|-------|------|------|\n| #185 | `get_mappings` 工具在嵌套属性未显式指定 `type: nested` 时失败 | get_mappings 功能受限 |\n| #170 | Basic 认证失败 401 Unauthorized | 认证配置问题 |\n| #173 | 通过 HTTP/SSE 访问时部分功能返回错误 | HTTP 模式稳定性 |\n\n## 相关文档\n\n- [官方 MCP 协议文档](https://modelcontextprotocol.io/docs/concepts/transports#built-in-transport-types)\n- [Elasticsearch MCP Server 发布说明](https://github.com/elastic/mcp-server-elasticsearch/releases)\n- [Dependency Dashboard](https://github.com/elastic/mcp-server-elasticsearch/issues/6)\n\n---\n\n<a id='page-config'></a>\n\n## 配置与工具过滤\n\n### 相关页面\n\n相关主题：[MCP 工具详解](#page-tools), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n</details>\n\n# 配置与工具过滤\n\n## 概述\n\nElasticsearch MCP Server 的配置与工具过滤系统提供了灵活的运行时自定义能力，允许管理员通过配置文件和环境变量来控制服务器行为、认证方式以及可用工具集。该系统支持两种传输模式（stdio 和 streamable-HTTP），配置通过 JSON5 格式加载，并支持 `${ENV_VAR}` 或 `${ENV_VAR:default}` 语法的环境变量插值。\n\n## 配置架构\n\n### 配置加载流程\n\n```mermaid\ngraph TD\n    A[CLI 启动命令] --> B[加载配置文件]\n    B --> C[读取 JSON5 内容]\n    C --> D[环境变量插值]\n    D --> E[解析为 Configuration]\n    E --> F[创建 ElasticsearchMcp]\n    \n    G[环境变量] -.->|${VAR}| D\n```\n\n配置加载逻辑位于 `src/lib.rs` 中，服务器启动时首先读取配置文件，然后通过插值器处理环境变量引用，最后解析为强类型配置结构体。\n\n### 核心配置结构体\n\n#### ElasticsearchMcpConfig\n\n`ElasticsearchMcpConfig` 是服务器的核心配置单元，定义了所有可配置的运行时参数：\n\n| 字段 | 类型 | 说明 | 环境变量 |\n|------|------|------|----------|\n| `url` | `String` | Elasticsearch 集群 URL | `ES_URL` |\n| `api_key` | `Option<String>` | API Key 认证 | `ES_API_KEY` |\n| `username` | `Option<String>` | 用户名 | `ES_USERNAME` |\n| `password` | `Option<String>` | 密码 | `ES_PASSWORD` |\n| `ssl_skip_verify` | `bool` | 跳过 SSL 证书验证 | `ES_SSL_SKIP_VERIFY` |\n| `tools` | `Tools` | 工具配置 | - |\n| `prompts` | `Vec<String>` | Prompt 模板列表 | - |\n\n资料来源：[src/servers/elasticsearch/mod.rs:55-78]()\n\n### 配置示例\n\n服务器提供了默认配置模板，位于 `src/lib.rs`：\n\n```json5\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n该模板展示了配置文件的推荐格式，支持：\n- JSON5 语法（注释和多行字符串）\n- 环境变量插值\n- 默认值指定\n\n## 认证配置\n\n### 认证凭证优先级\n\n系统支持三种认证方式，但同一时间只能使用一种：\n\n1. **API Key 认证**（优先）\n2. **用户名/密码认证**\n3. **无认证**（适用于信任网络）\n\n认证逻辑在 `ElasticsearchMcp::new_with_config` 方法中实现：\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:88-96]()\n\n### HTTP 请求转发认证\n\n`EsClientProvider` 提供了一个重要的功能：支持将 HTTP 请求中的 `Authorization` 头转发到远程 Elasticsearch 实例。这在 MCP 服务器代理认证时尤为重要。\n\n## 环境变量插值系统\n\n### 插值语法\n\n插值器支持两种语法格式：\n\n| 语法 | 说明 | 示例 |\n|------|------|------|\n| `${VAR}` | 必填变量，不存在则报错 | `${ES_URL}` |\n| `${VAR:default}` | 可选变量，默认值为 `default` | `${ES_SSL_SKIP_VERIFY:false}` |\n\n### 插值实现\n\n插值逻辑位于 `src/utils/interpolator.rs`，核心函数签名：\n\n```rust\npub fn interpolate(\n    input: String,\n    lookup: impl Fn(&str) -> Option<String>,\n) -> Result<String, InterpolationError>\n```\n\n工作原理：\n1. 扫描输入字符串中的 `${...}` 模式\n2. 对每个模式调用 `lookup` 函数获取值\n3. 支持默认值语法 `name:default`\n4. 返回插值后的字符串\n\n资料来源：[src/utils/interpolator.rs]()\n\n### 单元测试示例\n\n```rust\n#[test]\nfn good_extrapolation() -> anyhow::Result<()> {\n    assert_eq!(\"foo_value01234\", expand(\"${foo}01234\")?);\n    assert_eq!(\"foo_value01234\\n1234bar_value\", expand(\"${foo}01234\\n1234${bar}\")?);\n    Ok(())\n}\n```\n\n资料来源：[src/utils/interpolator.rs:47-51]()\n\n## 工具配置与过滤\n\n### 工具注册架构\n\n```mermaid\ngraph TD\n    A[Tools 配置] --> B[IncludeExclude 包含/排除规则]\n    A --> C[CustomTool 自定义工具]\n    \n    C --> D[EsqlTool ES|QL 查询工具]\n    C --> E[SearchTemplateTool 搜索模板工具]\n    \n    F[基础工具集] --> G[EsBaseTools]\n    F -->|list_indices| G\n    F -->|get_mappings| G\n    F -->|search| G\n    F -->|get_shards| G\n    F -->|esql| G\n```\n\n### 工具结构定义\n\n#### Tools 结构体\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\npub struct Tools {\n    #[serde(flatten)]\n    pub incl_excl: Option<IncludeExclude>,\n    pub custom: HashMap<String, CustomTool>,\n}\n```\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `incl_excl` | `Option<IncludeExclude>` | 包含/排除过滤规则 |\n| `custom` | `HashMap<String, CustomTool>` | 自定义工具集合 |\n\n资料来源：[src/servers/elasticsearch/mod.rs:27-32]()\n\n#### 自定义工具类型\n\n```rust\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(tag = \"type\", rename_all = \"snake_case\")]\npub enum CustomTool {\n    Esql(EsqlTool),\n    SearchTemplate(SearchTemplateTool),\n}\n```\n\n| 工具类型 | 说明 | 配置字段 |\n|----------|------|----------|\n| `Esql` | ES|QL 查询工具 | `query`, `format` |\n| `SearchTemplate` | 搜索模板工具 | `template_id` 或 `template` |\n\n资料来源：[src/servers/elasticsearch/mod.rs:34-48]()\n\n### 基础工具集 (EsBaseTools)\n\n`EsBaseTools` 是 MCP 服务器的核心工具提供者，定义了所有内置工具：\n\n| 工具名称 | 功能 | 参数 |\n|----------|------|------|\n| `list_indices` | 列出 Elasticsearch 索引 | `index_pattern` |\n| `get_mappings` | 获取索引映射 | `index` |\n| `search` | 执行搜索查询 | `index`, `fields`, `query_body` |\n| `get_shards` | 获取分片信息 | `index`（可选） |\n| `esql` | 执行 ES|QL 查询 | `query` |\n\n#### 工具参数定义示例\n\n```rust\n#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]\nstruct ListIndicesParams {\n    /// Index pattern of Elasticsearch indices to list\n    pub index_pattern: String,\n}\n\n#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]\nstruct SearchParams {\n    /// Name of the Elasticsearch index to search\n    index: String,\n    /// Name of the fields that need to be returned (optional)\n    fields: Option<Vec<String>>,\n    /// Complete Elasticsearch query DSL object\n    query_body: Map<String, Value>,\n}\n```\n\n资料来源：[src/servers/elasticsearch/base_tools.rs:112-137]()\n\n### 工具注解系统\n\n每个工具都可以通过 `annotations` 属性添加元数据：\n\n```rust\n#[tool(\n    description = \"List all available Elasticsearch indices\",\n    annotations(title = \"List ES indices\", read_only_hint = true)\n)]\n```\n\n| 注解字段 | 说明 |\n|----------|------|\n| `title` | 工具显示标题 |\n| `read_only_hint` | 仅读提示（优化 LLM 决策） |\n\n## CLI 启动配置\n\n### 命令行结构\n\n```rust\n#[derive(Debug, Subcommand)]\npub enum Command {\n    Stdio(StdioCommand),\n    Http(HttpCommand),\n}\n```\n\n| 命令 | 说明 | 默认端口 |\n|------|------|----------|\n| `stdio` | 标准输入/输出模式 | - |\n| `http` | Streamable-HTTP 模式 | 8080 |\n\n### HTTP 模式配置\n\n```rust\n#[derive(Debug, Args)]\npub struct HttpCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n\n    /// Address to listen to [default: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// Also start an SSE server on '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n资料来源：[src/cli.rs]()\n\n### Stdio 模式配置\n\n```rust\n#[derive(Debug, Args)]\npub struct StdioCommand {\n    /// Config file\n    #[clap(short, long)]\n    pub config: Option<PathBuf>,\n}\n```\n\n## 客户端提供器\n\n### EsClientProvider 实现\n\n`EsClientProvider` 是对 Elasticsearch 客户端的包装，提供基于请求上下文的客户端实例：\n\n```rust\n#[derive(Clone)]\npub struct EsClientProvider(Elasticsearch);\n\nimpl EsClientProvider {\n    pub fn new(client: Elasticsearch) -> Self {\n        EsClientProvider(client)\n    }\n\n    /// If the incoming request is a http request and has an `Authorization` header, use it\n    /// to authenticate to the remote ES instance.\n    pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n        // 返回配置好的客户端实例\n    }\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:106-119]()\n\n### 错误处理\n\n```rust\npub fn handle_error(result: Result<Response, elasticsearch::Error>) -> Result<Response, rmcp::Error> {\n    match result {\n        Ok(resp) => resp.error_for_status_code(),\n        Err(e) => {\n            tracing::error!(\"Error: {:?}\", &e);\n            Err(e)\n        }\n    }\n    .map_err(internal_error)\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:121-130]()\n\n## 配置最佳实践\n\n### 生产环境配置\n\n1. **使用环境变量存储敏感信息**\n   - API Key 或用户名/密码不应硬编码在配置文件中\n   - 推荐使用 `${ES_API_KEY}` 或 `${ES_PASSWORD}` 语法\n\n2. **SSL 证书验证**\n   - 生产环境应保持 `ssl_skip_verify: false`\n   - 如需跳过验证，明确设置 `${ES_SSL_SKIP_VERIFY:true}`\n\n3. **工具限制**\n   - 通过配置文件的 `incl_excl` 规则限制可用工具\n   - 使用 `custom` 字段添加预定义的 ES|QL 查询或搜索模板\n\n### 容器化部署\n\n```bash\ndocker run --rm \\\n  -e ES_URL=https://elasticsearch:9200 \\\n  -e ES_API_KEY=your-api-key \\\n  -e ES_SSL_SKIP_VERIFY=false \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n## 已知问题\n\n社区反馈的认证相关问题（#170）表明，在 Docker 容器部署时需要确保：\n- 环境变量名称正确（区分大小写）\n- `ES_USERNAME` 和 `ES_PASSWORD` 同时设置或使用 API Key\n- 检查容器日志中的认证错误信息\n\n---\n\n<a id='page-deployment'></a>\n\n## Docker 部署指南\n\n### 相关页面\n\n相关主题：[认证配置](#page-auth), [通信协议配置](#page-protocols), [安全最佳实践](#page-security)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [Dockerfile](https://github.com/elastic/mcp-server-elasticsearch/blob/main/Dockerfile)\n- [Dockerfile-8000](https://github.com/elastic/mcp-server-elasticsearch/blob/main/Dockerfile-8000)\n- [.env-example](https://github.com/elastic/mcp-server-elasticsearch/blob/main/.env-example)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n</details>\n\n# Docker 部署指南\n\n本文档介绍如何通过 Docker 容器方式部署 Elasticsearch MCP Server。Elasticsearch MCP Server 是基于 Model Context Protocol (MCP) 的 Elasticsearch 集成服务，允许 AI 代理通过标准化接口与 Elasticsearch 集群进行交互。\n\n## 核心概念\n\n### 架构概览\n\nMCP Server 以 Docker 容器的形式运行，提供两种协议支持：\n\n```mermaid\ngraph TD\n    A[AI Agent / MCP Client] -->|Stdio| B[MCP Server 容器<br/>stdio 模式]\n    A -->|Streamable HTTP| C[MCP Server 容器<br/>HTTP 模式]\n    B -->|HTTPS| D[Elasticsearch 集群]\n    C -->|HTTPS| D\n```\n\n### 容器模式识别\n\nMCP Server 支持自动检测运行环境的容器模式。当检测到容器运行时，服务器会自动将 `localhost` 替换为容器网络别名，以确保容器内的网络请求能正确路由到宿主机服务（如本地 Elasticsearch 集群）。\n\n资料来源：[src/lib.rs:89-101]()\n\n容器模式通过以下逻辑实现：\n\n```mermaid\ngraph LR\n    A[检测运行环境] --> B{是否容器模式?}\n    B -->|是| C[替换 localhost]\n    B -->|否| D[保持 localhost]\n    C --> E[host.containers.internal<br/>Podman<br/>其他别名]\n```\n\n支持的宿主机别名包括：\n- `host.containers.internal`（Podman 及部分 Docker 环境）\n- 其他平台特定别名\n\n资料来源：[src/servers/elasticsearch/mod.rs:89-95]()\n\n## 环境变量配置\n\n### 必需变量\n\n| 变量名 | 说明 | 示例值 |\n|--------|------|--------|\n| `ES_URL` | Elasticsearch 集群地址 | `https://localhost:9200` |\n| `ES_API_KEY` | API Key 认证密钥 | `base64EncodedApiKey...` |\n| `ES_USERNAME` | 基本认证用户名 | `elastic` |\n| `ES_PASSWORD` | 基本认证密码 | `password123` |\n| `ES_SSL_SKIP_VERIFY` | 跳过 SSL 证书验证 | `true` / `false` |\n\n### 配置优先级\n\n环境变量支持默认值语法，格式为 `${VAR_NAME:default_value}`。当变量未定义时使用默认值。\n\n资料来源：[src/lib.rs:67-77]()\n\n```bash\n# .env 文件示例\nES_URL=https://elasticsearch:9200\nES_API_KEY=your_api_key_here\nES_SSL_SKIP_VERIFY=false\n```\n\n### 认证方式\n\nMCP Server 支持三种认证方式：\n\n1. **API Key 认证**（推荐）：通过 `ES_API_KEY` 环境变量设置\n2. **用户名密码认证**：通过 `ES_USERNAME` 和 `ES_PASSWORD` 环境变量设置\n3. **SSL 跳过验证**：仅在开发环境中使用 `ES_SSL_SKIP_VERIFY=true`\n\n> [!IMPORTANT]\n> 认证凭证仅存储在环境变量中，不会持久化到磁盘或写入日志。\n\n资料来源：[.env-example]()\n\n## Docker 镜像\n\n### 镜像信息\n\n官方镜像托管在 Elastic 的 Docker Registry：\n\n```\ndocker.elastic.co/mcp/elasticsearch\n```\n\n### 镜像版本\n\n| 标签 | 说明 |\n|------|------|\n| `latest` | 最新稳定版本 |\n| `v0.4.6` | 特定版本号（当前最新） |\n\n### 端口配置\n\n| Dockerfile | 默认端口 | 用途 |\n|------------|----------|------|\n| `Dockerfile` | 8080 | HTTP 模式监听端口 |\n| `Dockerfile-8000` | 8000 | 备用端口配置 |\n\nv0.4.3 之前的版本默认端口为 8000，之后统一改为 8080。\n\n资料来源：[README.md]()\n\n## Stdio 模式部署\n\nStdio 模式适用于直接与 MCP Client 进程通信的场景。\n\n### 启动命令\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-cluster.es.region.amazonaws.com:9200\" \\\n  -e ES_API_KEY=\"your_api_key\" \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n### Claude Desktop 配置\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\",\n        \"--rm\",\n        \"-e\", \"ES_URL\",\n        \"-e\", \"ES_API_KEY\",\n        \"docker.elastic.co/mcp/elasticsearch\",\n        \"stdio\"\n      ],\n      \"env\": {\n        \"ES_URL\": \"<elasticsearch-cluster-url>\",\n        \"ES_API_KEY\": \"<elasticsearch-API-key>\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md]()\n\n## HTTP 模式部署\n\nHTTP 模式适用于需要远程访问、多客户端并发连接或通过代理桥接的场景。\n\n### 启动命令\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-cluster.es.region.amazonaws.com:9200\" \\\n  -e ES_API_KEY=\"your_api_key\" \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n### 端点说明\n\n| 端点 | 方法 | 说明 |\n|------|------|------|\n| `/mcp` | POST | Streamable HTTP MCP 端点 |\n| `/ping` | GET | 健康检查端点 |\n\n### 健康检查\n\n```bash\ncurl http://<host>:8080/ping\n```\n\n成功响应返回 `pong`。\n\n资料来源：[README.md]()\n\n### Claude Desktop 代理配置\n\n由于 Claude Desktop 免费版仅支持 stdio 协议，需要使用 `mcp-proxy` 进行协议桥接：\n\n1. 安装 mcp-proxy：\n```bash\nuv tool install mcp-proxy\n```\n\n2. 配置 Claude Desktop：\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"/<home-directory>/.local/bin/mcp-proxy\",\n      \"args\": [\n        \"--transport=streamablehttp\",\n        \"--header\", \"Authorization\", \"ApiKey <elasticsearch-API-key>\",\n        \"http://<mcp-server-host>:<mcp-server-port>/mcp\"\n      ]\n    }\n  }\n}\n```\n\n资料来源：[README.md]()\n\n## 故障排查\n\n### 常见问题\n\n#### 认证失败 (401 Unauthorized)\n\nIssue #170 中用户反馈使用 Docker 部署时环境变量配置正确但仍出现认证失败：\n\n- 确认 `ES_USERNAME`、`ES_PASSWORD` 环境变量名称拼写正确（区分大小写）\n- v0.4.5 版本修复了用户名环境变量名称问题，确保使用正确的变量名\n- 验证 Elasticsearch 集群的认证配置\n\n#### 连接超时\n\n如果容器无法连接到 Elasticsearch 集群：\n\n```bash\n# 从容器内部测试连接\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n```\n\n#### 容器模式 localhost 问题\n\n如果容器内访问宿主机 Elasticsearch 失败，检查容器是否正确识别容器模式。MCP Server 会自动将 `localhost` 替换为网络别名。\n\n资料来源：[src/servers/elasticsearch/mod.rs:89-95]()\n\n### 日志查看\n\n```bash\n# 查看容器日志\ndocker logs <container-id>\n\n# 实时跟踪日志\ndocker logs -f <container-id>\n```\n\n日志中可能出现的错误类型：\n- Elasticsearch 连接失败\n- 认证错误\n- 网络连接问题\n\n### 验证连接\n\n1. 检查容器状态：\n```bash\ndocker ps | grep elasticsearch-mcp-server\n```\n\n2. 测试健康端点：\n```bash\ncurl http://<host>:8080/ping\n```\n\n3. 通过 MCP Client 测试功能（如 `list_indices`、`get_shards`）\n\n## 安全最佳实践\n\n### 凭证管理\n\n| 安全措施 | 说明 |\n|----------|------|\n| 环境变量存储 | 凭证仅存储在环境变量中 |\n| 定期轮换 | 生产环境建议 30-90 天轮换 API Key |\n| 最小权限 | 使用仅读权限的 API Key |\n| 不提交凭证 | 禁止将凭证提交到版本控制 |\n\n### 网络安全\n\n- 使用 HTTPS 协议 (`ES_URL` 以 `https://` 开头)\n- 配置正确的安全组和网络 ACL\n- 生产环境避免使用 `ES_SSL_SKIP_VERIFY=true`\n\n### AWS 部署建议\n\n在 AWS 环境中部署时：\n- 使用 AWS Secrets Manager 管理凭证\n- 通过 IAM 角色控制 EKS/EC2 访问权限\n- 配置 VPC 安全组规则\n\n资料来源：[README.md]()\n\n## CLI_ARGS 环境变量\n\nv0.4.1 版本新增 `CLI_ARGS` 环境变量支持，可作为传递命令行参数的替代方式：\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://elasticsearch:9200\" \\\n  -e ES_API_KEY=\"your_key\" \\\n  -e CLI_ARGS=\"--config /path/to/config.json\" \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n资料来源：[README.md]()\n</details>\n\n---\n\n<a id='page-auth'></a>\n\n## 认证配置\n\n### 相关页面\n\n相关主题：[Docker 部署指南](#page-deployment), [故障排除指南](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [.env-example](https://github.com/elastic/mcp-server-elasticsearch/blob/main/.env-example)\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n</details>\n\n# 认证配置\n\n## 概述\n\nElasticsearch MCP Server 支持两种主要的认证方式与 Elasticsearch 集群建立安全连接。本页详细说明认证配置的工作原理、配置参数以及常见问题的排查方法。\n\n认证配置在 MCP Server 启动时通过环境变量或配置文件加载，用于建立与 Elasticsearch 集群的信任连接。所有认证凭证仅在运行时内存中处理，不会持久化到磁盘或日志中。\n\n## 认证方式\n\nMCP Server 支持两种认证方式：\n\n| 认证方式 | 配置参数 | 说明 |\n|---------|---------|------|\n| API Key 认证 | `ES_API_KEY` | 使用 Elasticsearch API 密钥进行认证 |\n| 用户名密码认证 | `ES_USERNAME` + `ES_PASSWORD` | 使用用户名和密码进行 Basic 认证 |\n\n> [!NOTE]\n> API Key 认证优先于用户名密码认证。如果同时配置了 API Key 和用户名密码，系统将使用 API Key。\n\n### 认证凭证优先级\n\n```mermaid\ngraph TD\n    A[启动 MCP Server] --> B{是否配置 ES_API_KEY?}\n    B -->|是| C[使用 API Key 认证]\n    B -->|否| D{是否配置 ES_USERNAME?}\n    D -->|是| E{是否配置 ES_PASSWORD?}\n    E -->|是| F[使用 Basic 认证]\n    E -->|否| G[无认证]\n    D -->|否| G\n    C --> H[连接 Elasticsearch]\n    F --> H\n    G --> H\n```\n\n## 配置参数详解\n\n### 环境变量配置\n\n| 环境变量 | 类型 | 必填 | 默认值 | 说明 |\n|---------|------|------|--------|------|\n| `ES_URL` | String | 是 | - | Elasticsearch 集群地址，如 `https://localhost:9200` |\n| `ES_API_KEY` | String | 否 | 空 | API Key 认证凭证 |\n| `ES_USERNAME` | String | 否 | 空 | Basic 认证用户名 |\n| `ES_PASSWORD` | String | 否 | 空 | Basic 认证密码 |\n| `ES_SSL_SKIP_VERIFY` | Boolean | 否 | `false` | 是否跳过 SSL 证书验证 |\n\n> [!CAUTION]\n> `ES_SSL_SKIP_VERIFY=true` 会绕过 SSL 证书验证，仅在测试环境中使用。生产环境应配置正确的 CA 证书。\n\n### 配置文件格式\n\n除了环境变量，还可以通过配置文件指定认证信息。配置文件支持 JSON5 格式（允许注释和多行字符串）：\n\n```json5\n{\n    \"elasticsearch\": {\n        \"url\": \"${ES_URL}\",\n        \"api_key\": \"${ES_API_KEY:}\",\n        \"username\": \"${ES_USERNAME:}\",\n        \"password\": \"${ES_PASSWORD:}\",\n        \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n    }\n}\n```\n\n配置文件中的 `${VAR:default}` 语法表示环境变量插值，如果环境变量未设置则使用默认值。\n\n## 认证实现架构\n\n### 核心组件\n\n```mermaid\nclassDiagram\n    class ElasticsearchMcpConfig {\n        +String url\n        +Option~String~ api_key\n        +Option~String~ username\n        +Option~String~ password\n        +bool ssl_skip_verify\n    }\n    \n    class ElasticsearchMcp {\n        +new_with_config(config, container_mode) EsBaseTools\n    }\n    \n    class EsClientProvider {\n        +Elasticsearch client\n        +get(context) Elasticsearch\n    }\n    \n    class Credentials {\n        <<enumeration>>\n        EncodedApiKey(String)\n        Basic(String, String)\n    }\n    \n    ElasticsearchMcpConfig --> ElasticsearchMcp : 配置输入\n    ElasticsearchMcp --> EsClientProvider : 创建客户端\n    ElasticsearchMcpConfig --> Credentials : 生成凭证\n    Credentials --> EsClientProvider : 注入传输层\n```\n\n### 凭证生成逻辑\n\n凭证生成在 `ElasticsearchMcp::new_with_config` 方法中完成：\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:57-64](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 传输层配置\n\n凭证创建后，通过 Elasticsearch Rust 客户端的 `TransportBuilder` 注入到传输层：\n\n```rust\nlet mut transport = elasticsearch::http::transport::TransportBuilder::new(pool);\nif let Some(creds) = creds {\n    transport = transport.auth(creds);\n}\n// ... 继续配置 SSL 等选项\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:66-70](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n## 运行时认证\n\n### HTTP 请求上下文认证\n\n`EsClientProvider` 支持从传入的 HTTP 请求中提取 `Authorization` 头，用于对远程 ES 实例进行认证：\n\n```rust\npub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {\n    // 从请求上下文中获取 Authorization 头\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:97-101](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n### 容器模式下的 localhost 重写\n\n当 MCP Server 在 Docker 容器中运行时，`rewrite_localhost` 函数会将 `localhost` URL 重写为 `host.docker.internal`，以便容器可以正确访问宿主机上的 Elasticsearch 服务：\n\n```rust\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n资料来源：[src/servers/elasticsearch/mod.rs:51-53](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n\n## 配置示例\n\n### 使用 API Key 认证\n\n```bash\n# 环境变量方式\nexport ES_URL=https://elasticsearch.example.com:9200\nexport ES_API_KEY=your_api_key_here\n\n# 运行 MCP Server\ndocker run -e ES_URL -e ES_API_KEY elastic/mcp-server-elasticsearch\n```\n\n### 使用用户名密码认证\n\n```bash\n# 环境变量方式\nexport ES_URL=https://elasticsearch.example.com:9200\nexport ES_USERNAME=elastic\nexport ES_PASSWORD=your_password\n\n# 运行 MCP Server\ndocker run -e ES_URL -e ES_USERNAME -e ES_PASSWORD elastic/mcp-server-elasticsearch\n```\n\n### 使用 .env 文件\n\n```bash\n# 创建 .env 文件\ncat > .env << 'EOF'\nES_URL=https://elasticsearch.example.com:9200\nES_USERNAME=elastic\nES_PASSWORD=your_password\nES_SSL_SKIP_VERIFY=false\nEOF\n\n# 运行 MCP Server\ndocker run --env-file .env elastic/mcp-server-elasticsearch\n```\n\n## 常见问题排查\n\n### 401 Unauthorized 错误\n\n**问题描述**：认证失败，返回 401 Unauthorized 错误。\n\n**可能原因**：\n- 凭证配置错误（用户名/密码不匹配）\n- API Key 格式不正确或已过期\n- Elasticsearch 安全策略阻止了该凭证\n\n**排查步骤**：\n\n1. 验证环境变量是否正确设置：\n```bash\ndocker exec <container-id> env | grep ES_\n```\n\n2. 直接测试 Elasticsearch 连接：\n```bash\n# 使用 Basic 认证\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n\n# 使用 API Key\ndocker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n```\n\n3. 检查凭证是否有正确的索引访问权限\n\n### 认证凭证优先级问题\n\n**问题描述**：同时配置了 API Key 和用户名密码，但使用了错误的认证方式。\n\n根据代码逻辑，API Key 具有最高优先级。如果希望使用 Basic 认证，请确保不设置 `ES_API_KEY` 环境变量。\n\n### 容器内连接问题\n\n**问题描述**：在 Docker 容器中运行时报连接错误。\n\n当 ES_URL 使用 `localhost` 时，容器内的进程无法访问宿主机的 Elasticsearch。需要使用 `rewrite_localhost` 功能或修改 ES_URL 为宿主机的实际 IP 地址。\n\n## 安全最佳实践\n\n| 安全措施 | 说明 |\n|---------|------|\n| 使用 AWS Secrets Manager | 生产环境应使用 AWS Secrets Manager 或类似服务管理凭证 |\n| 定期轮换 API Key | 建议每 30-90 天轮换一次生产环境的 API Key |\n| 最小权限原则 | 为 MCP Server 创建只读用户，仅授予必要的索引访问权限 |\n| 启用 SSL/TLS | 生产环境必须使用 HTTPS 协议 |\n| 避免 SSL 跳过验证 | 生产环境不应设置 `ES_SSL_SKIP_VERIFY=true` |\n\n> [!WARNING]\n> 切勿将凭证直接写入配置文件并提交到版本控制系统。所有凭证都应通过环境变量或密钥管理服务注入。\n\n## 相关文档\n\n- [官方部署文档](https://github.com/elastic/mcp-server-elasticsearch#deploy-the-mcp-server-container)\n- [Elasticsearch API Keys 文档](https://www.elastic.co/docs/deploy-manage/api-keys)\n- [Elasticsearch 用户和角色文档](https://www.elastic.co/docs/deploy-manage/users-roles)\n\n---\n\n<a id='page-troubleshooting'></a>\n\n## 故障排除指南\n\n### 相关页面\n\n相关主题：[认证配置](#page-auth), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n</details>\n\n# 故障排除指南\n\n本页面提供 Elasticsearch MCP Server 部署和运行过程中常见问题的诊断和解决方案。\n\n---\n\n## 1. 认证失败 (401 Unauthorized)\n\n### 问题描述\n\n用户反馈在使用 Docker 部署 MCP Server 时，已正确配置了 `ES_USERNAME`、`ES_PASSWORD` 环境变量，但仍然收到 \"401 Unauthorized\" 认证失败错误。\n\n资料来源：[issues/170](https://github.com/elastic/mcp-server-elasticsearch/issues/170)\n\n### 可能原因\n\nMCP Server 支持两种认证方式：**API Key** 和 **用户名/密码**。认证优先级如下：\n\n1. 如果设置了 `api_key`，优先使用 API Key 认证\n2. 如果设置了 `username`，使用 Basic Auth（必须同时设置 `password`）\n3. 如果两者都未设置，使用匿名访问\n\n资料来源：[src/servers/elasticsearch/mod.rs:58-65](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs#L58-L65)\n\n```rust\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n### 解决方案\n\n#### 方案一：使用 API Key 认证\n\n```bash\ndocker run -e ES_URL=https://your-cluster.es.region.amazonaws.com \\\n           -e ES_API_KEY=your_api_key_here \\\n           -p 8080:8080 \\\n           elastic/mcp-server-elasticsearch\n```\n\n#### 方案二：使用用户名密码认证\n\n```bash\ndocker run -e ES_URL=https://your-cluster.es.region.amazonaws.com \\\n           -e ES_USERNAME=your_username \\\n           -e ES_PASSWORD=your_password \\\n           -p 8080:8080 \\\n           elastic/mcp-server-elasticsearch\n```\n\n> [!IMPORTANT]\n> 确保 `ES_USERNAME` 和 `ES_PASSWORD` **同时设置**。只设置其中一个将导致认证失败。\n\n### 验证认证配置\n\n在容器内测试认证连接：\n\n```bash\n# 使用 Basic Auth 测试\ndocker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n\n# 使用 API Key 测试\ndocker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n```\n\n---\n\n## 2. 网络连接问题\n\n### 容器内无法连接 Elasticsearch\n\n#### 问题表现\n\n容器日志显示连接超时或拒绝连接：\n\n```\nError: Connection refused\n```\n\n#### 诊断步骤\n\n1. **验证 Elasticsearch URL**\n\n确保 `ES_URL` 格式正确且可访问：\n\n```bash\ndocker exec <container-id> curl -k https://your-es-cluster:9200\n```\n\n2. **检查网络连通性**\n\n```bash\ndocker exec <container-id> ping <es-host>\ndocker exec <container-id> telnet <es-host> 9200\n```\n\n3. **验证 SSL 配置**\n\n如果使用自签名证书，需要设置 `ES_SSL_SKIP_VERIFY=true`：\n\n资料来源：[src/servers/elasticsearch/mod.rs:71-72](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs#L71-L72)\n\n```bash\ndocker run -e ES_URL=https://your-cluster.es.region.amazonaws.com \\\n           -e ES_API_KEY=your_api_key \\\n           -e ES_SSL_SKIP_VERIFY=true \\\n           -p 8080:8080 \\\n           elastic/mcp-server-elasticsearch\n```\n\n### localhost 重写问题 (容器模式)\n\n当 MCP Server 以容器模式运行时，URL 中的 `localhost` 会自动重写为 `host.docker.internal`，以便容器能够访问宿主机上的服务。\n\n资料来源：[src/servers/elasticsearch/mod.rs:42-44](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs#L42-L44)\n\n```rust\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n---\n\n## 3. get_mappings 工具响应解码错误\n\n### 问题描述\n\n使用 `get_mappings` 工具时，服务器返回错误：\n\n```\n\"Request failed (remote): error decoding response body\"\n```\n\n资料来源：[issues/185](https://github.com/elastic/mcp-server-elasticsearch/issues/185)\n\n### 根本原因\n\n当索引 mapping 中嵌套属性没有显式指定 `\"type\": \"nested\"` 时，ES 返回的响应可能包含非标准字段格式，导致 JSON 解码失败。\n\n### 临时解决方案\n\n在定义 mapping 时，确保嵌套类型显式声明：\n\n```json\n{\n  \"properties\": {\n    \"nested_field\": {\n      \"type\": \"nested\",\n      \"properties\": {\n        \"name\": { \"type\": \"keyword\" }\n      }\n    }\n  }\n}\n```\n\n---\n\n## 4. HTTP/Streamable HTTP 模式问题\n\n### 问题描述\n\n无法通过 HTTP 协议远程访问 MCP Server。\n\n### 配置说明\n\nMCP Server 支持两种传输模式：\n\n| 模式 | 命令 | 默认地址 | 用途 |\n|------|------|----------|------|\n| Stdio | `stdio` | - | 本地进程通信 |\n| Streamable HTTP | `http` | `127.0.0.1:8080` | 远程访问 |\n\n资料来源：[src/cli.rs:30-47](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs#L30-L47)\n\n### 启动 HTTP 服务器\n\n```bash\n# 基本 HTTP 模式\nmcp-server-elasticsearch http --address 0.0.0.0:8080\n\n# 启用 SSE 回退（已废弃）\nmcp-server-elasticsearch http --sse\n```\n\n### 验证 HTTP 服务\n\n```bash\ncurl http://<host>:8080/ping\n```\n\n预期响应：`pong`\n\n### 健康检查\n\nStreamable HTTP 模式提供 `/ping` 端点用于健康检查：\n\n```bash\ncurl http://localhost:8080/ping\n```\n\n---\n\n## 5. 环境变量插值问题\n\n### 问题描述\n\n配置文件中使用 `${VAR_NAME}` 语法引用环境变量时，变量未被正确展开。\n\n### 机制说明\n\nMCP Server 使用 `interpolator` 模块处理环境变量插值：\n\n资料来源：[src/utils/interpolator.rs:1-50](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs#L1-L50)\n\n**支持的语法：**\n\n| 语法 | 说明 |\n|------|------|\n| `${VAR}` | 展开环境变量，变量不存在则报错 |\n| `${VAR:default}` | 展开环境变量，变量不存在则使用默认值 |\n\n### 示例配置\n\n```json\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n资料来源：[src/lib.rs:20-33](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs#L20-L33)\n\n### 常见错误\n\n```\nmissing closing braces    # 缺少闭合大括号\nenv variable 'XXX' not defined  # 环境变量未定义\n```\n\n---\n\n## 6. 工具执行错误\n\n### 问题：esql 工具查询失败\n\n#### 错误表现\n\nES|QL 查询返回错误响应。\n\n#### 诊断步骤\n\n1. 检查 ES|QL 语法是否正确\n2. 验证用户是否有执行 ES|QL 的权限\n3. 检查 Elasticsearch 版本是否支持 ES|QL（8.x+）\n\n### 问题：search 工具返回空结果\n\n#### 错误表现\n\nsearch 工具成功执行但返回空 `hits` 数组。\n\n#### 可能原因\n\n- 查询条件与现有文档不匹配\n- 索引名称拼写错误\n- 时间范围过滤条件问题\n\n### 问题：list_indices 工具无响应\n\n#### 诊断\n\n```bash\n# 验证索引列表可访问\ndocker exec <container-id> curl -k -u user:pass <ES_URL>/_cat/indices?v\n```\n\n---\n\n## 7. 日志分析\n\n### 容器日志查看\n\n```bash\ndocker logs <container-id>\n```\n\n### 日志级别配置\n\n通过环境变量 `RUST_LOG` 设置日志级别：\n\n```bash\ndocker run -e RUST_LOG=debug \\\n           -e ES_URL=https://your-cluster:9200 \\\n           -e ES_API_KEY=your_key \\\n           elastic/mcp-server-elasticsearch\n```\n\n### 常见日志关键词\n\n| 关键词 | 含义 |\n|--------|------|\n| `Error: Connection refused` | 无法连接到 Elasticsearch |\n| `401 Unauthorized` | 认证失败 |\n| `error decoding response body` | 响应解析错误（通常与 mapping 格式相关）|\n| `missing password` | 使用用户名认证但未提供密码 |\n\n---\n\n## 8. 配置验证清单\n\n在报告问题前，请确认以下配置项：\n\n| 检查项 | 说明 | 验证命令 |\n|--------|------|----------|\n| ES_URL 格式 | 必须以 `http://` 或 `https://` 开头 | `echo $ES_URL` |\n| 认证凭证 | API Key 或 用户名+密码 | 检查环境变量 |\n| 网络连通性 | 容器可访问 ES 集群 | `docker exec <id> curl <ES_URL>` |\n| SSL 配置 | 自签名证书需设置 `ES_SSL_SKIP_VERIFY=true` | 检查日志 |\n| 权限 | 用户对索引有读取权限 | ES 角色检查 |\n\n---\n\n## 9. 获取帮助\n\n如果以上指南未能解决您的问题：\n\n1. 收集以下信息：\n   - MCP Server 版本：`docker logs <container-id> | grep version`\n   - 完整错误日志\n   - 配置文件（脱敏后）\n   - Elasticsearch 集群版本\n\n2. 在 [GitHub Issues](https://github.com/elastic/mcp-server-elasticsearch/issues) 创建问题时：\n   - 描述复现步骤\n   - 附上相关日志\n   - 说明环境和版本信息\n\n---\n\n<a id='page-security'></a>\n\n## 安全最佳实践\n\n### 相关页面\n\n相关主题：[认证配置](#page-auth), [Docker 部署指南](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/elastic/mcp-server-elasticsearch/blob/main/README.md)\n- [src/servers/elasticsearch/mod.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/mod.rs)\n- [src/servers/elasticsearch/base_tools.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/servers/elasticsearch/base_tools.rs)\n- [src/lib.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/lib.rs)\n- [src/cli.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/cli.rs)\n- [src/utils/interpolator.rs](https://github.com/elastic/mcp-server-elasticsearch/blob/main/src/utils/interpolator.rs)\n\n</details>\n\n# 安全最佳实践\n\n本文档介绍 Elasticsearch MCP Server 的安全最佳实践，涵盖身份认证、凭证管理、传输加密、网络配置等关键安全领域。\n\n## 身份认证配置\n\nElasticsearch MCP Server 支持两种身份认证方式：**API Key 认证** 和 **基本认证（用户名/密码）**。\n\n### 认证方式对比\n\n| 认证方式 | 环境变量 | 说明 |\n|---------|---------|------|\n| API Key | `ES_API_KEY` | 推荐用于生产环境，安全性更高 |\n| 基本认证 | `ES_USERNAME` + `ES_PASSWORD` | 适用于传统用户名密码场景 |\n| SSL 跳过验证 | `ES_SSL_SKIP_VERIFY` | 仅在开发/测试环境使用 |\n\n### 配置认证参数\n\n认证配置通过 `ElasticsearchMcpConfig` 结构体管理：\n\n```rust\n// 资料来源：src/servers/elasticsearch/mod.rs:88-102\npub struct ElasticsearchMcpConfig {\n    /// 集群 URL\n    pub url: String,\n\n    /// API 密钥\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub api_key: Option<String>,\n\n    /// 用户名\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub username: Option<String>,\n\n    /// 密码\n    #[serde(default, deserialize_with = \"none_if_empty_string\")]\n    pub password: Option<String>,\n\n    /// 是否跳过 SSL 证书验证\n    #[serde(default, deserialize_with = \"deserialize_bool_from_anything\")]\n    pub ssl_skip_verify: bool,\n}\n```\n\n### API Key 认证配置\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-elasticsearch:9200\" \\\n  -e ES_API_KEY=\"your-api-key-here\" \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n### 基本认证配置\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://your-elasticsearch:9200\" \\\n  -e ES_USERNAME=\"elastic\" \\\n  -e ES_PASSWORD=\"your-password\" \\\n  -p 8080:8080 \\\n  docker.elastic.co/mcp/elasticsearch \\\n  http\n```\n\n## 凭证安全管理\n\n### 凭证存储原则\n\nElasticsearch MCP Server 遵循严格的凭证安全管理原则：\n\n- **API 密钥和密码**：仅存储在传递给容器的环境变量中\n- **不持久化到磁盘**：凭证不会写入文件系统\n- **不记录到日志**：敏感信息不会出现在日志输出中\n\n```rust\n// 资料来源：src/servers/elasticsearch/mod.rs:72-79\nlet creds = if let Some(api_key) = config.api_key.clone() {\n    Some(Credentials::EncodedApiKey(api_key))\n} else if let Some(username) = config.username.clone() {\n    let pwd = config.password.clone().ok_or(anyhow::Error::msg(\"missing password\"))?;\n    Some(Credentials::Basic(username, pwd))\n} else {\n    None\n};\n```\n\n### 环境变量插值\n\n配置文件支持环境变量插值，使用 `${VAR_NAME}` 或 `${VAR_NAME:default}` 语法：\n\n```json\n{\n  \"elasticsearch\": {\n    \"url\": \"${ES_URL}\",\n    \"api_key\": \"${ES_API_KEY:}\",\n    \"username\": \"${ES_USERNAME:}\",\n    \"password\": \"${ES_PASSWORD:}\",\n    \"ssl_skip_verify\": \"${ES_SSL_SKIP_VERIFY:false}\"\n  }\n}\n```\n\n```rust\n// 资料来源：src/lib.rs:48-52\nlet config = interpolator::interpolate_from_env(config)?;\n```\n\n### 生产环境凭证管理建议\n\n| 推荐做法 | 说明 |\n|---------|------|\n| AWS Secrets Manager | 使用 AWS Secrets Manager 存储和轮换凭证 |\n| AWS Systems Manager Parameter Store | 使用 Parameter Store 管理敏感参数 |\n| 定期轮换 | API 密钥建议每 30-90 天轮换一次 |\n| 最小权限 | 使用只读访问特定索引的 API 密钥 |\n\n## 传输加密\n\n### HTTPS 通信\n\nMCP Server 与 Elasticsearch 集群之间的通信采用 HTTPS 加密：\n\n```mermaid\ngraph LR\n    A[MCP Server] -->|HTTPS/TLS| B[Elasticsearch Cluster]\n    B -->|加密响应| A\n```\n\n当 `ES_URL` 使用 `https://` 协议时，通信自动加密：\n\n```bash\n# 正确的 HTTPS 配置\nES_URL=\"https://your-elasticsearch:9200\"\n```\n\n### SSL 证书验证\n\n#### 生产环境配置\n\n生产环境应保持 SSL 证书验证启用：\n\n```bash\n# 默认情况下 ssl_skip_verify 为 false，保持验证\ndocker run --rm \\\n  -e ES_URL=\"https://your-elasticsearch:9200\" \\\n  -e ES_API_KEY=\"your-api-key\" \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n#### 开发/测试环境配置\n\n仅在本地开发或使用自签名证书时禁用验证：\n\n```bash\ndocker run --rm \\\n  -e ES_URL=\"https://localhost:9200\" \\\n  -e ES_API_KEY=\"your-api-key\" \\\n  -e ES_SSL_SKIP_VERIFY=true \\\n  docker.elastic.co/mcp/elasticsearch \\\n  stdio\n```\n\n> ⚠️ **警告**：禁用 SSL 验证会使通信暴露于中间人攻击风险，仅限于受信任的内部网络。\n\n## 网络安全配置\n\n### HTTP 服务监听地址\n\nHTTP 模式下，默认监听地址为 `127.0.0.1:8080`：\n\n```rust\n// 资料来源：src/cli.rs:28-32\npub struct HttpCommand {\n    /// 监听地址 [默认: 127.0.0.1:8080]\n    #[clap(long, value_name = \"IP_ADDRESS:PORT\", env = \"HTTP_ADDRESS\")]\n    pub address: Option<std::net::SocketAddr>,\n\n    /// 同时启动 SSE 服务器在 '/sse'\n    #[clap(long)]\n    pub sse: bool,\n}\n```\n\n### 安全监听建议\n\n| 场景 | 推荐配置 | 说明 |\n|-----|---------|------|\n| 本地开发 | `127.0.0.1:8080` | 仅本地访问 |\n| Docker 网络 | `0.0.0.0:8080` | 容器间通信 |\n| 公网部署 | 使用反向代理 + TLS | 添加额外安全层 |\n\n### Docker 网络安全\n\n容器模式下，自动重写 localhost 引用：\n\n```rust\n// 资料来源：src/servers/elasticsearch/mod.rs:67-68\nif container_mode {\n    rewrite_localhost(&mut url)?;\n}\n```\n\n## 常见安全问题排查\n\n### 401 Unauthorized 错误\n\n社区反馈：Issue #170 中许多用户遇到基本认证失败的问题。\n\n#### 排查步骤\n\n1. **验证环境变量配置**：\n   ```bash\n   docker exec <container-id> env | grep ES_\n   ```\n\n2. **测试 Elasticsearch 连接**：\n   ```bash\n   # 使用 API Key\n   docker exec <container-id> curl -k -H \"Authorization: ApiKey <api-key>\" <ES_URL>\n   \n   # 使用用户名密码\n   docker exec <container-id> curl -k -u <username>:<password> <ES_URL>\n   ```\n\n3. **检查凭证是否正确传递**：\n   - 确认 `ES_USERNAME` 和 `ES_PASSWORD` 同时设置\n   - 确认 API Key 格式正确（不带 \"ApiKey\" 前缀）\n\n### SSL 证书错误\n\n```bash\n# 检查 Elasticsearch SSL 配置\ndocker exec <container-id> curl -v <ES_URL>\n```\n\n### 容器日志分析\n\n```bash\ndocker logs <container-id>\n```\n\n查看日志中的错误信息：\n\n- Elasticsearch 连接失败\n- 身份认证错误\n- 网络连接问题\n\n## 数据安全\n\n### 数据存储\n\n| 层面 | 说明 |\n|-----|------|\n| 传输中数据 | MCP Server 与 Elasticsearch 之间的通信加密 |\n| 静态数据 | 容器不本地存储数据，所有数据保留在 Elasticsearch 集群 |\n| 临时数据 | 容器重启后清除所有临时数据 |\n\n### 数据访问控制\n\n建议在 Elasticsearch 层面配置：\n\n- 基于角色的访问控制 (RBAC)\n- 字段级安全\n- 索引级权限\n\n```json\n{\n  \"roles\": [\n    {\n      \"name\": \"mcp_readonly\",\n      \"indices\": [\n        {\n          \"names\": [\"allowed-index-*\"],\n          \"privileges\": [\"read\", \"view_index_metadata\"]\n        }\n      ]\n    }\n  ]\n}\n```\n\n## 审计与监控\n\n### 健康检查端点\n\nHTTP 模式提供健康检查端点：\n\n```bash\ncurl http://<host>:8080/ping\n```\n\n成功响应返回 `pong`。\n\n### MCP 端点\n\n```bash\n# MCP 协议端点\nhttp://<host>:8080/mcp\n```\n\n## 最佳实践清单\n\n### 部署前检查\n\n- [ ] 使用 HTTPS 连接到 Elasticsearch\n- [ ] 配置有效的 API Key 或用户名密码\n- [ ] 不在生产环境设置 `ES_SSL_SKIP_VERIFY=true`\n- [ ] 使用只读权限的 API 密钥\n\n### 容器配置检查\n\n- [ ] 凭证通过环境变量传递，不写入配置文件\n- [ ] 容器日志不包含敏感信息\n- [ ] 网络访问限制在必要范围\n\n### 运维检查\n\n- [ ] 定期轮换 API 密钥（30-90 天）\n- [ ] 监控认证失败日志\n- [ ] 审计 Elasticsearch 访问日志\n\n## 相关资源\n\n- [Elasticsearch API Keys 文档](https://www.elastic.co/docs/deploy-manage/api-keys)\n- [Elasticsearch 用户角色文档](https://www.elastic.co/docs/deploy-manage/users-roles)\n- [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/)\n- [Model Context Protocol 文档](https://modelcontextprotocol.io/)\n\n---\n\n<!-- evidence_pipeline_checked: true -->\n<!-- evidence_injected: true -->\n\n---\n\n## Doramagic 踩坑日志\n\n项目：elastic/mcp-server-elasticsearch\n\n摘要：发现 10 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 依赖 Docker 环境。\n\n## 1. 安装坑 · 依赖 Docker 环境\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：安装/运行入口包含 Docker 命令：docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n- 对用户的影响：非工程用户可能没有 Docker，启动成本明显增加。\n- 建议检查：标注 Docker 前置条件，并提供非 Docker 路径或失败提示。\n- 复现命令：`docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio`\n- 防护动作：Docker 前置条件未说明时，不把项目标成普通用户低门槛。\n- 证据：identity.distribution | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n\n## 2. 安装坑 · 来源证据：Dependency Dashboard\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Dependency Dashboard\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_5573c160ecdd4e34be6dbf6549fe2529 | https://github.com/elastic/mcp-server-elasticsearch/issues/6 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。\n\n## 3. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | host_targets=mcp_host, claude, cursor\n\n## 4. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | README/documentation is current enough for a first validation pass.\n\n## 5. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | last_activity_observed missing\n\n## 6. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n\n## 7. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n\n## 8. 安全/权限坑 · 来源证据：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_f8732a2deab341d6b739b122459d1243 | https://github.com/elastic/mcp-server-elasticsearch/issues/185 | 来源讨论提到 api key 相关条件，需在安装/试用前复核。\n\n## 9. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | issue_or_pr_quality=unknown\n\n## 10. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | release_recency=unknown\n\n<!-- canonical_name: elastic/mcp-server-elasticsearch; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：elastic/mcp-server-elasticsearch\n\n摘要：发现 10 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 依赖 Docker 环境。\n\n## 1. 安装坑 · 依赖 Docker 环境\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：安装/运行入口包含 Docker 命令：docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n- 对用户的影响：非工程用户可能没有 Docker，启动成本明显增加。\n- 建议检查：标注 Docker 前置条件，并提供非 Docker 路径或失败提示。\n- 复现命令：`docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio`\n- 防护动作：Docker 前置条件未说明时，不把项目标成普通用户低门槛。\n- 证据：identity.distribution | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n\n## 2. 安装坑 · 来源证据：Dependency Dashboard\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Dependency Dashboard\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_5573c160ecdd4e34be6dbf6549fe2529 | https://github.com/elastic/mcp-server-elasticsearch/issues/6 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。\n\n## 3. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | host_targets=mcp_host, claude, cursor\n\n## 4. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | README/documentation is current enough for a first validation pass.\n\n## 5. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | last_activity_observed missing\n\n## 6. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n\n## 7. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium\n\n## 8. 安全/权限坑 · 来源证据：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：get_mappings tool fails with \"error decoding response body\" when nested type is omitted in properties\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_f8732a2deab341d6b739b122459d1243 | https://github.com/elastic/mcp-server-elasticsearch/issues/185 | 来源讨论提到 api key 相关条件，需在安装/试用前复核。\n\n## 9. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | issue_or_pr_quality=unknown\n\n## 10. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# mcp-server-elasticsearch - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 mcp-server-elasticsearch 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client / claude / Cursor\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 HTTP 200 with status text。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- health_endpoints: Provides HTTP health check endpoints at /ready, /live, and /ping for container orchestration. 输入：HTTP GET requests；输出：HTTP 200 with status text。\n\n【必须安装后才可验证的能力】\n- list_indices: Lists Elasticsearch indices matching a pattern, returning index name, status, and document count. 输入：index_pattern (string, optional)；输出：Array of {index, status, docs.count} objects。\n- get_mappings: Retrieves field mappings for a specified index, exposing the schema definition. 输入：index (string)；输出：Mapping definition with field types and properties。\n- search: Executes search queries against Elasticsearch indices with support for _source filtering and aggregations. 输入：index (string), query_body (JSON object), fields (optional array for _source)；输出：Search hits with _source fields, aggregations if present。\n- esql_query: Executes ES|QL (Elasticsearch Query Language) queries and returns results as JSON objects. 输入：query (ES|QL string), params (optional)；输出：Array of JSON objects keyed by column names。\n- get_shards: Returns shard allocation information for indices including replica state and node assignment. 输入：index_pattern (string, optional)；输出：Array of shard info objects。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-intro：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-architecture：系统架构。围绕“系统架构”模拟一次用户任务，不展示安装或运行结果。\n3. page-protocols：通信协议配置。围绕“通信协议配置”模拟一次用户任务，不展示安装或运行结果。\n4. page-tools：MCP 工具详解。围绕“MCP 工具详解”模拟一次用户任务，不展示安装或运行结果。\n5. page-deployment：Docker 部署指南。围绕“Docker 部署指南”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-intro\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-architecture\n输入：用户提供的“系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-protocols\n输入：用户提供的“通信协议配置”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-tools\n输入：用户提供的“MCP 工具详解”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-deployment\n输入：用户提供的“Docker 部署指南”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-intro：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-architecture：Step 2 必须围绕“系统架构”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-protocols：Step 3 必须围绕“通信协议配置”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-tools：Step 4 必须围绕“MCP 工具详解”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-deployment：Step 5 必须围绕“Docker 部署指南”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/elastic/mcp-server-elasticsearch\n- https://github.com/elastic/mcp-server-elasticsearch#readme\n- src/protocol/http.rs\n- README.md\n- catalog-info.yaml\n- src/lib.rs\n- src/cli.rs\n- src/servers/mod.rs\n- src/protocol/mod.rs\n- src/protocol/stdio.rs\n- src/servers/elasticsearch/base_tools.rs\n- src/servers/elasticsearch/mod.rs\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 mcp-server-elasticsearch 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：elastic/mcp-server-elasticsearch\n\n## 官方安装入口\n\n### Docker · 官方安装入口\n\n```bash\ndocker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio\n```\n\n来源：https://github.com/elastic/mcp-server-elasticsearch#readme\n\n## 来源\n\n- repo: https://github.com/elastic/mcp-server-elasticsearch\n- docs: https://github.com/elastic/mcp-server-elasticsearch#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_a637409e3fd74426bc5c840f395c1308"
}
