Last9

官方

无缝地将实时生产环境上下文——日志、指标和追踪——引入本地环境,从而更快地自动修复代码。

你可以用 Last9 MCP 做什么?

  • 调查生产事故 — 让你的助手为某项服务提取日志、追踪、指标、异常和触发的告警,以便诊断故障原因。
  • 关联变更与影响 — 检查部署和配置变更,然后比较变更前后某项服务及其调用方的情况,判断变更是否导致了回归。
  • 查询 Prometheus 指标 — 运行 PromQL 范围查询或即时查询,并列出标签值,以探索数据源中的任意指标。
  • 检查数据库性能 — 发现数据库、查找执行缓慢的查询,并通过 OTel spans 查看查询模式和服务器端指标。
  • 分析追踪和性能剖析 — 按 ID 获取追踪瀑布图,比较不同群组间的属性偏差并排序,或提取某项服务的火焰图和热门函数。
  • 管理告警和仪表板 — 检查告警覆盖范围和规范性,创建或修改告警规则,并列出、验证或编辑自定义仪表板。

文档

Last9 MCP Server

last9 mcp demo

你的 AI 代理不知道生产环境出了什么问题。这个服务器可以解决这个问题。

Last9 MCP Server 可将 Claude、Cursor、Windsurf 以及任何其他支持 MCP 的 AI 助手直接连接到你的生产环境可观测性数据——日志、指标、追踪、异常、数据库查询、告警和部署。代理不再靠猜测,而是开始读取实际信号。


30 秒内启动(托管版)

无需安装二进制文件。无需管理令牌。只需一个 URL,在浏览器中完成 OAuth,即可使用。

在你的 Last9 URL 中找到组织标识:app.last9.io/<org_slug>/...

Claude Code

claude mcp add --transport http last9 https://app.last9.io/api/v4/organizations/<org_slug>/mcp

输入 /mcp,选择 last9,然后进行身份验证。就这么简单。

Cursor

Settings > MCP > Add New MCP Server:

{
  "mcpServers": {
    "last9": {
      "type": "http",
      "url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
    }
  }
}

点击 Connect,完成 OAuth。

VS Code

需要 v1.99+。打开命令面板 → MCP: Add Server,粘贴 URL 并进行身份验证。

或者直接在 settings.json 中配置:

{
  "mcp": {
    "servers": {
      "last9": {
        "type": "http",
        "url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
      }
    }
  }
}

Windsurf

Settings > Cascade > Open MCP Marketplace > 齿轮图标 (mcp_config.json):

{
  "mcpServers": {
    "last9": {
      "serverUrl": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
    }
  }
}

Claude Web/Desktop

**Settings > Connectors > Add custom connector。**将其命名为 last9,粘贴 URL 并进行身份验证。

需要拥有 Claude 组织的管理员权限。


自托管(STDIO)

当你的 MCP 客户端不支持 HTTP 传输,或需要在本地运行服务器时,请使用此方式。

安装

Homebrew:

brew install last9/tap/last9-mcp

NPM:

需要 Node.js 22.23.4+、24.22.1+ 或 26.12.1+:较早版本在安装程序下载二进制文件时,会接受来自已泄露的 eMudhra 中间证书的 TLS 证书。

npm install -g @last9/mcp-server@latest
# or directly:
npx -y @last9/mcp-server@latest

二进制版本(Windows / 手动安装):

从 GitHub Releases 下载:

平台压缩包
Windows (x64)last9-mcp-server_Windows_x86_64.zip
Windows (ARM64)last9-mcp-server_Windows_arm64.zip
Linux (x64)last9-mcp-server_Linux_x86_64.tar.gz
Linux (ARM64)last9-mcp-server_Linux_arm64.tar.gz
macOS (x64)last9-mcp-server_Darwin_x86_64.tar.gz
macOS (ARM64)last9-mcp-server_Darwin_arm64.tar.gz

获取刷新令牌

只有管理员可以创建令牌。

  1. 前往 API Access
  2. 点击 Generate Token 并授予写入权限
  3. 复制令牌

客户端配置

Homebrew:

{
  "mcpServers": {
    "last9": {
      "command": "/opt/homebrew/bin/last9-mcp",
      "env": {
        "LAST9_REFRESH_TOKEN": "<your_refresh_token>"
      }
    }
  }
}

NPM:

{
  "mcpServers": {
    "last9": {
      "command": "npx",
      "args": ["-y", "@last9/mcp-server@latest"],
      "env": {
        "LAST9_REFRESH_TOKEN": "<your_refresh_token>"
      }
    }
  }
}

粘贴位置:

客户端位置
Claude Web/DesktopSettings > Developer > Edit Config (claude_desktop_config.json)
CursorSettings > Cursor Settings > MCP > Add New Global MCP Server
WindsurfSettings > Cascade > MCP Marketplace > 齿轮图标 (mcp_config.json)
VS Code在 settings.json 中将其包装在 { "mcp": { "servers": { ... } } } 内 — 详情
VS Code STDIO 配置
{
  "mcp": {
    "servers": {
      "last9": {
        "type": "stdio",
        "command": "/opt/homebrew/bin/last9-mcp",
        "env": {
          "LAST9_REFRESH_TOKEN": "<your_refresh_token>"
        }
      }
    }
  }
}

对于 NPM:使用 "command": "npx" 并添加 "args": ["-y", "@last9/mcp-server@latest"]。

Windows

从 GitHub Releases 下载后,解压并指定完整路径:

{
  "mcpServers": {
    "last9": {
      "command": "C:\\Users\\<user>\\AppData\\Local\\Programs\\last9-mcp-server.exe",
      "env": {
        "LAST9_REFRESH_TOKEN": "<your_refresh_token>"
      }
    }
  }
}

在 Windows 上使用 NPM 更简单——无需管理路径。

环境变量

变量默认值说明
LAST9_REFRESH_TOKEN(必填)从 API Access 获取的刷新令牌
LAST9_DATASOURCE组织默认值数据源/集群名称——拥有多个 Levitate 集群时很有用
LAST9_FAKE_NOW_ISO(未设置)**仅用于评估/回放;切勿在生产环境中设置。**RFC3339 时间点(例如 2026-01-02T15:04:05Z),用于替代解析相对时间窗口(如 lookback_minutes)时的当前时间,以确保运行结果可复现。无效值会导致启动错误。超时、缓存和令牌过期仍使用实际时间
LAST9_API_HOSTapp.last9.io覆盖 API 主机
LAST9_TOOLSETS所有工具以逗号分隔要公开的工具集(logs、traces、metrics、alerts、dashboards、profiles、grafana、investigate、all)。别名:LAST9_MCP_TOOLSETS
LAST9_MCP_READ_ONLYfalse将 true 设为仅提供只读工具;参见只读模式。非布尔值会导致启动错误。别名:LAST9_READ_ONLY
LAST9_MCP_ALLOW_WRITE_TOOLS—只读模式下仍提供的、以逗号分隔的写入工具。别名:LAST9_ALLOW_WRITE_TOOLS
LAST9_MAX_GET_LOGS_ENTRIES5000分块 get_logs 请求的最大条目数
LAST9_USE_LOG_SEARCH_APIfalse将 true 设为通过一次服务器端搜索调用响应 get_logs 和 get_service_logs,而不是由客户端分块。每次调用最多等待 90 秒,之后会返回缩小时间窗口的建议;502 或 503 会在此时间内重试一次
LAST9_DEBUG_CHUNKINGfalse将 true 设为记录 get_logs、get_service_logs、get_traces 的分块规划详情
LAST9_DISABLE_TELEMETRYtrue将 false 设为启用内部 OTel 追踪
OTEL_SDK_DISABLED—标准 OTel 环境变量。覆盖 LAST9_DISABLE_TELEMETRY
OTEL_EXPORTER_OTLP_ENDPOINT—OTLP 收集器端点(仅在启用遥测时使用)
OTEL_EXPORTER_OTLP_HEADERS—OTLP 身份验证标头(仅在启用遥测时使用)

工具阶段耗时

启用内部遥测后,工具 span 会携带 last9.phase.<phase>.duration_ms (实际经过的毫秒数)和 last9.phase.<phase>.failed(该阶段是否 返回错误)。当配置的日志记录器接受调试级别记录时,同样的字段也会作为 tool phase completed 调试 日志输出,并包含 tool 和 phase。这些计时信息不会添加输入、查询文本、凭据或错误正文。

工具阶段
get_log_patternssample:获取并解码样本;mine:模式挖掘;deep_link:解析可选索引并构建链接
get_logsfetch:获取、解码并合并结果,包括重试和可选的计数合理性检查;count_sanity:嵌套的可选检查;post_process:生成指导信息、摘要并格式化 JSON;deep_link:解析索引并构建链接
get_service_profilerequest:通过共享 API 客户端准备并发送请求,然后读取完整响应,之后再进行简要格式化

只记录实际执行的阶段,包括失败的获取操作。会抑制错误的可选辅助程序仍保持原有行为;failed: false 并不能证明可选链接或计数检查可用。嵌套的 count_sanity 耗时已包含在 fetch 中;不要重复相加。获取耗时包含客户端工作,因此并非仅测量后端执行时间。在调整采样或缓存之前,请先比较等效时间窗口和搜索路径下的这些阶段。

调查延迟时,请在基线版本和候选版本上,使用相同的服务、数据源、索引、时间窗口和限制进行回放。记录构建 SHA、工具总耗时、阶段耗时、last9.logs.search_path、存在时的重试属性,以及覆盖标志。除了典型调用,也要比较慢调用。获取或性能分析请求耗时较长,说明应调查网络/API 阶段;在将长尾延迟归因于后端之前,需要有独立且相关的证据证明后端执行情况。仅凭这些诊断信息无法确认延迟有所改善。

只读模式

--read-only(或 LAST9_MCP_READ_ONLY=true)仅提供标注为 readOnlyHint: true 的工具,因此没有任何工具可以创建、更改或删除告警规则、通知渠道、仪表板或丢弃规则,也无法确认或重新分配告警,或静默告警组。没有注解的工具会被视为写入工具并隐藏。

若要保留少数写入工具,请通过 --allow-write-tools(或 LAST9_MCP_ALLOW_WRITE_TOOLS)列出它们:

last9-mcp --read-only --allow-write-tools=acknowledge_alert,mute_alert_group
  • 如果允许的名称不是写入工具(例如拼写错误,或填写了读取工具的名称),服务器会拒绝启动;错误信息会列出有效的写入工具。
  • 不带 --read-only 的 --allow-write-tools 会导致启动错误,因为此时所有写入工具都已提供。
  • 只读模式与 --toolsets 组合使用:工具必须同时满足两者的条件才会提供。--toolsets=alerts --read-only --allow-write-tools=mute_alert_group 会提供告警读取工具以及 mute_alert_group;不属于所选工具集的允许写入工具仍会被隐藏。
  • --http 模式和 dump-tools 使用相同的标志和环境变量:go run . dump-tools --read-only 会打印只读接口,以及服务器在 instructions 中提供的指令。
  • 读取工具的说明、架构和结果,以及服务器指令,都不会提及隐藏的写入工具。允许的写入工具仍可能提及其被隐藏的同类工具(create_alert 会创建一个由 patch_alert 启用的禁用规则),因此应将这类工具配对一并允许。

功能介绍

概览

  • get_workspace_overview — 当请求未指定服务或工具时,建议首先调用此工具(指定了服务或工具的请求会直接调用相应工具):通过一次低成本调用获取环境信息、过去一小时内检测到的信号(日志、追踪、指标)、服务和告警组数量、正在触发的告警以及当前时间。某个信号在这一小时内未出现,并不代表它没有更早的数据,因此仍可查询。如果某个子调用失败,其字段会标记为 null,并添加一条 errors[] 条目。所有工具集均提供此工具
  • get_current_time — 当前时间,以及 last 2h、yesterday 或 since yesterday 9am IST 的绝对边界;支持任意 IANA 时区或常见缩写。所有工具集均提供此工具

服务健康状况

  • get_service_summary — 按排名排列的全体服务 (service, env) 行:时间间隔内的 request_count、throughput_rpm、HTTP 4xx/5xx 计数和 gRPC 错误计数
  • get_service_environments — 服务可用的环境。请先运行此工具——其他 APM 工具需要此处提供的 env
  • get_service_performance_details — 完整细分数据:吞吐量、错误率、p50/p90/p95/平均值/最大值、apdex、可用性(默认提供摘要;使用 include_series 可获取完整序列)
  • get_service_operations_summary — 按 HTTP 端点、数据库调用、消息传递和 HTTP 客户端分组的操作
  • get_service_dependency_graph — 上游/下游/基础设施的依赖关系图,包含吞吐量、延迟和错误率
  • get_apm_service_deviations — 将当前时间窗口与等时长的基线进行比较:回归/改进、Apdex 对账以及最终结果(全体服务或单个服务)
  • get_exceptions — 可按服务和 span 筛选的服务器端异常

数据库可观测性

这四种工具可直接分析数据库性能,数据来源于 OpenTelemetry trace span;如果没有追踪数据,则使用 CloudWatch 等基础设施指标。如果你已经在使用 OTel,则无需额外埋点。

  • get_databases — 发现基础设施中的所有数据库:数据库类型、主机、吞吐量(查询/分钟)、p95 延迟、错误率、依赖服务数量。还会发现来自 CloudWatch 等基础设施指标的数据库,无需进行跟踪插桩——这些行会显示活动值,而不是跟踪指标
  • get_database_slow_queries — 按持续时间排序的实际最慢查询执行记录,并附带用于深入查看完整跟踪的跟踪 ID
  • get_database_queries — 查询模式和聚合数据:查询运行频率、平均/p95 持续时间、错误率
  • get_database_server_metrics — 来自数据库主机本身的服务器端指标(CPU、连接数、缓冲区命中率——取决于数据库系统)

支持 PostgreSQL、MySQL、MongoDB、Redis、Aerospike,以及任何带有 db_system 属性的 OTel 跟踪中的其他数据库;还支持从 CloudWatch 等基础设施指标中发现的数据库,这些数据库的行会显示活动值,而不是跟踪指标。

Prometheus / PromQL

  • prometheus_range_query — 对任意指标执行 PromQL 范围查询
  • prometheus_instant_query — 即时查询;使用 avg_over_time、sum_over_time 等汇总函数
  • prometheus_label_values — 获取给定序列的标签值
  • prometheus_labels — 获取序列的所有可用标签

设置 LAST9_DATASOURCE,或在单次调用中设置 datasource,即可将这些查询指向默认数据源/集群以外的目标。省略 datasource 时使用默认值;如果匹配器认为某个唯一的近似匹配是安全的(例如大小写变体),则使用最接近的匹配项。缺少、多出或调换字母时,不保证能自动解析:即使只有一个候选项,如果修改可能影响区域或环境代码,也可能需要确认。较宽松或有歧义的匹配会返回候选项且不会运行查询(不算错误);未知名称则会返回错误。只要数据源名称不是完全匹配,额外的内容块就会指出所用的数据源。get_metric_status、get_service_profile 和 get_apm_service_deviations 以相同方式解析 datasource。

日志

  • get_logs — 完整的 JSON 管道日志查询(聚合、筛选、字段提取)
  • get_service_logs — 服务的日志行,可按严重性和正文内容筛选;除非 response_mode 为 raw,否则会将结果汇总为 20 行
  • get_log_patterns — 将某个时间窗口内服务的日志行聚类为消息模板,并显示数量、首次/最后出现时间、严重性分布和示例
  • get_emerging_log_patterns — 与基线时间窗口相比新增、增加、减少或消失的日志模板,并显示两个窗口的数量
  • get_log_attributes — 指定时间窗口内日志架构中属性的全局目录
  • get_log_attributes_for_pipeline — 正在进行的管道中实际存在的日志字段(范围限定的发现),每个字段都附带其精确的 filter_field
  • get_drop_rules — 来自 Last9 Control Plane 的日志丢弃规则
  • add_drop_rule — 创建新的丢弃规则,从源头减少日志量
  • get_remapping_rules — 来自 Last9 Control Plane 的重映射规则(logs_extract、logs_map、traces_map)
  • add_remapping_rule — 创建重映射规则,在摄取时提取或映射日志和跟踪属性

跟踪

  • get_traces — 用于广泛搜索和聚合的 JSON 管道跟踪查询
  • get_service_traces — 按精确跟踪 ID 或服务名称查询跟踪。已有跟踪 ID 时使用此项,速度更快
  • get_trace_attributes — 跟踪架构中属性的全局目录
  • get_trace_attributes_for_pipeline — 正在进行的管道中实际存在的属性(范围限定的发现),每个属性都附带其精确的 filter_field
  • get_trace_attribute_values — 跟踪属性的不同值,可选择限定到某个管道
  • get_trace_attribute_deviations — 对两个有界 span 群组(慢与快、错误与非错误,或两个时间窗口)中不同的属性值进行排名。表示相关性,而非因果关系
  • get_trace_waterfall — 将一条精确跟踪显示为父子瀑布图,并提供区间并集自耗时、最慢 span 和图结构警告

变更事件与告警

  • get_change_events — 部署、配置变更、回滚。将事故与变更内容关联起来
  • analyze_change_impact — 变更是否造成了问题?比较变更前后某个服务及其直接调用方的黄金信号、APM 和跟踪属性偏差、新触发的告警,以及判定结果(regression likely / no significant change / insufficient data)
  • get_alert_groups — 已配置的 Compass 告警组,包含元数据标签、团队、层级和规则数量——包括规则数为零且未触发的组
  • get_alert_operations_summary — 指定时间窗口内的值班健康状况:触发与已确认的告警数、积压、投递情况;使用 include_rules 时,还会显示最嘈杂、反复触发和未路由的规则。每个计数都附带其 status(available / partial / unavailable)
  • get_alert_coverage — 尚未设置告警的内容:未覆盖的黄金信号、完全禁用或未路由的告警组,以及静默时间过长的规则;每项都附带建议的修复工具。只读。
  • get_alert_config — 告警规则配置——可按名称、严重性、类型和标签搜索
  • get_entity_kpis — 某个告警组中的所有 KPI(id、名称、PromQL、单位),包括尚未被任何规则使用的 KPI——create_alert 和 validate_alert_expression 需要这些信息
  • create_kpi — 当现有 KPI 都不适用时,在告警组中创建 KPI(PromQL + 单位)。只创建一次,并保留返回的 id
  • get_alerts — 指定时间窗口内当前正在触发的告警
  • get_alert_rule_state — 按 rule_id 分组,显示时间范围内每条告警规则的历史触发状态(1/0)。可按告警组、规则名称、标签筛选条件和状态筛选。
  • get_alert_hygiene — 过去 7 或 30 天内嘈杂、反复触发、过时和未路由的告警规则,按排名列出,并为每项提供判定依据和建议的修复方法。只读。
  • get_notification_channels — 已配置的通知渠道(Slack、PagerDuty、电子邮件等)。scope=channels 列出渠道本身(用于关联的 id);默认的 attached 则列出每个告警组的关联渠道
  • recommend_alert_config — 创建告警规则前提供只读设计指导(生命周期、验证关卡、响应人员上下文)
  • validate_alert_expression — 对告警组的 KPI 试运行告警表达式,不保存任何内容
  • describe_alert_chart — Discover 图表上可用于告警的信号(key、单位),只读(discover-service、discover-exceptions)
  • create_alert — 在现有告警组中创建告警规则(静态规则,或通过 adaptive_std_cmp 创建自适应规则);始终以禁用的草稿状态创建。只创建一次;使用 update_alert / patch_alert 进行调整
  • create_alert_from_chart — 一次调用即可从 Discover 图表创建静态阈值告警规则。与 create_alert 一样,规则会以禁用的草稿状态创建
  • update_alert — 完整替换规则的评估配置(可能会返回替换后的规则 ID)
  • patch_alert — 部分修改规则:启用/暂停、mute_until、响应人员 properties、每周 recurring_mute_schedule(或 clear_recurring_mute_schedule)
  • delete_alert — 永久删除告警规则
  • mute_alert_group — 将告警组中的所有规则静默(或取消静默)至指定截止时间
  • acknowledge_alert — 接管正在触发的告警,或释放该告警
  • reassign_alert — 将已确认的告警转交给其他用户
  • create_notification_channel — 创建 Slack、PagerDuty、Opsgenie、电子邮件或通用 webhook 渠道
  • attach_notification_channel — 将现有渠道路由到告警组,以用于 breach、threat 或两者
  • detach_notification_channel — 移除一个渠道与告警组之间的关联
  • delete_notification_channel — 永久删除没有任何关联的渠道

告警写入工具(create_kpi、create_alert、update_alert、patch_alert、delete_alert、create_alert_from_chart、mute_alert_group、acknowledge_alert、reassign_alert、create_notification_channel、attach_notification_channel、detach_notification_channel、delete_notification_channel)需要具有写入范围的令牌;delete_alert、detach_notification_channel 和 delete_notification_channel 则需要删除范围。它们仅在 alerts 工具集中提供。

这些工具创建的规则、渠道和关联会标记为 created_via: last9-mcp,并附带 MCP 客户端的名称和版本(对于规则,还会添加 _l9_created_via_ 和 _l9_created_via_client_ 注释;patch_alert 和 update_alert 会保留这些注释,调用方无法设置)。get_entity_alert_rules 和 get_notification_channels 会显示该标记;delete_alert、detach_notification_channel 和 delete_notification_channel 会指示代理仅清理带标记的资源,除非用户明确指定某个资源。

自定义仪表板

  • list_dashboards — 按名称筛选并分页列出自定义仪表板,结果不超过 32 KB:包括 ID、名称、最后更新时间、作者和锁定状态
  • get_dashboard — 按 ID 获取完整仪表板定义,包括面板和查询
  • preview_dashboard — 对未保存的仪表板或补丁进行只读预览:解析查询、限制每个面板的结果,并显示面板差异;绝不保存
  • validate_dashboard — 对已保存的仪表板 id 或内联 dashboard_definition 执行只读 lint、查询和分类,时间窗口不超过 24 小时。绝不创建或更新仪表板
  • create_dashboard — 一次性创建全新的自定义仪表板(面板、查询、元数据)。返回 id 后,使用 patch_dashboard 编辑面板。
  • update_dashboard — 按 ID 大幅重构现有仪表板(完整替换;只读系统仪表板会返回错误)。如需编辑单个面板,请使用 patch_dashboard
  • patch_dashboard — 按 ID 对现有仪表板进行定向编辑(添加/更新/移除/移动面板、设置标题、设置变量);返回精简差异,而非完整仪表板
  • delete_dashboard — 按 ID 删除自定义仪表板
  • set_dashboard_lock — 按 ID 锁定或解锁自定义仪表板(仅作者或组织管理员可操作);锁定的仪表板无法更新、打补丁或删除
  • list_dashboard_snapshots — 仪表板的冻结时间点快照(仅元数据)
  • get_dashboard_snapshot — 包含面板数据的完整冻结快照,用于 RCA / 可分享视图
  • delete_dashboard_snapshot — 按 ID 删除冻结快照

无需安装 skill,即可通过 MCP prompts/list 和 prompts/get 创建仪表板。以下三个提示均不接受参数:

  • create_dashboard_guide — 发现、布局和面板选择;在审批前验证完整候选方案并运行每个面板的查询,只创建一次,使用补丁进行定向编辑,然后读取结果。
  • dashboard_examples — 完整示例,涵盖服务 RED、端点延迟、状态类别、主机健康状况、日志计数和跟踪面板,并包含依赖变量。
  • query_guide — 计数器/仪表/直方图和派生跟踪指标语义、即时查询与范围查询、速率窗口、百分比边界,以及 logjson/tracejson 规则。

相同内容也可通过 last9://reference/create_dashboard_guide、last9://reference/dashboard_examples 和 last9://reference/query_guide 阅读。所有工具集下都可以发现提示和资源;执行工作流需要相关工具(对于混合信号创作,请使用 --toolsets=dashboards,investigate,它也适用于 list_datasources)。只读会话可以准备和验证,但无法保存。执行步骤前请检查工具是否可用。

面板检查目前会将 prometheus_range_query、prometheus_instant_query、get_logs 和 get_traces 与 validate_dashboard 配合使用。验证器不支持的查询类型和简化默认值并不能证明渲染结果一致。#475 合并后,独立的查询检查步骤将切换到 query_panel。

持续剖析

需要为组织启用持续剖析。先使用 get_profile_services 发现服务,然后获取火焰图或排名函数。

  • get_profile_services — 在时间窗口内有性能分析数据的服务(查询前索引)
  • get_flamegraph — 单个服务的嵌套火焰图树(默认 cpu;也支持 alloc、wall)
  • get_top_functions — 单个服务中最热门函数的自身采样排名
  • get_profile_summary — 对单个服务的性能分析进行简短的自然语言排查

Grafana 仪表板

针对组织 Grafana 实例的只读工具(通过 Last9 的 Grafana 代理)。凭据字段绝不会返回给模型。使用 LAST9_TOOLSETS=grafana 启用(或不设置工具集以启用所有工具)。

  • grafana_search_dashboards — 按标题子字符串搜索仪表板(分页;达到上限时为 truncated: true)
  • grafana_get_dashboard — 按 uid 获取仪表板摘要(面板、变量、PromQL 目标);原始 Grafana JSON 使用 full_json=true
  • grafana_list_folders — 文件夹树
  • grafana_list_folder_dashboards — 单个文件夹中的仪表板(分页)
  • grafana_list_datasources — 不含凭据的数据源清单

模糊名称解析

  • did_you_mean — 当代理不确定实体名称时,此工具会从目录中返回最接近的匹配项(服务、环境、主机、数据库、K8s 部署/命名空间、作业)。最多提供 3 个建议及相似度分数。大多数工具在名称查询无结果时,服务器会自动调用此工具。

服务概况

  • get_service_profile — 在查询服务之前,了解其遥测数据的实际情况:有哪些信号、语言和运行时、部署环境、日志的结构,以及适用时建议的采集修复方案。这样代理可以在服务没有跟踪数据时跳过跟踪工具;当 SeverityText 为空时,也可以从日志正文解析严重性,而不是按其筛选却一无所获。

工作原理

每个响应都包含深层链接。 每个工具都会返回一个 deep_link 字段,其中包含指向 Last9 仪表板的直接 URL,精确对应相应查询和时间范围。代理可以把链接发给你;点击即可打开对应页面。

工具集。 默认情况下,服务器会公开所有工具。只需要进行调查(日志/跟踪/指标/性能分析)的自动化主机可以设置 LAST9_TOOLSETS=investigate(或传入 --toolsets=investigate),这样无需在客户端批量禁用工具,也能让 tools/list 保持精简。命名工具包:logs、traces、metrics、alerts、dashboards、profiles、grafana、investigate、all。未知名称会立即报错。所有工具集都会提供 get_current_time 和 get_workspace_overview。在 HTTP 模式下,请求可以通过 X-Last9-Toolsets 标头进一步缩小范围(参见按请求设置工具集)。alerts 工具包还提供只读的 prometheus_range_query 和 get_dashboard,由 author-alert 提示调用。仅使用 metrics 工具包不包含 list_datasources 或 did_you_mean — 需要这些发现辅助工具时,请使用 investigate(或组合多个工具集)。

工具参考资源。 较长的 logjson/tracejson/service-logs/metrics 手册是 MCP 资源(last9://reference/logjson、last9://reference/tracejson、last9://reference/service_logs、last9://reference/metrics、last9://reference/investigation、last9://reference/alerting),而不是始终显示的工具描述文本。告警手册涵盖告警表达式语法、静态字段与自适应字段、单位、validate_alert_expression 的检查内容,以及延迟/错误率/饱和度规则模板。关键查询规则仍保留在工具描述中,因此即使代理从不调用 resources/read,也能正确构造查询。使用 get_log_attributes / get_log_attributes_for_pipeline(以及对应的跟踪工具)发现组织专属字段——这些字段不会注入描述中。

分块处理大型结果。 get_logs 和 get_traces 通过分块处理大型结果集,而不是截断结果。日志的默认上限为 5000 条;可通过 LAST9_MAX_GET_LOGS_ENTRIES 配置。


开发

HTTP 模式、curl 测试、从源代码构建

在 HTTP 模式下运行

export LAST9_REFRESH_TOKEN="your_refresh_token"
export LAST9_HTTP=true
export LAST9_PORT=8080
./last9-mcp-server

服务器启动于 http://localhost:8080/mcp。

使用 curl 测试

Streamable HTTP 处理程序以无状态模式运行,因此每个请求都会独立处理。initialize 握手和 Mcp-Session-Id 标头均为可选项——发送这些内容的客户端仍可正常工作(标头会被接受并忽略),客户端也可以直接跳过,转而发送 tools/list / tools/call。每个工具都是独立的请求/响应查询;服务器不会发送服务器→客户端通知,因此 GET /mcp(SSE 流)会返回 405。

# List tools — a session handshake is optional in stateless mode
curl -s -X POST http://localhost:8080/mcp \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}'

# Call a tool
curl -s -X POST http://localhost:8080/mcp \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{
      "jsonrpc": "2.0",
      "id": 2,
      "method": "tools/call",
      "params": {
        "name": "get_service_logs",
        "arguments": {
          "service_name": "your-service-name",
          "lookback_minutes": 30,
          "limit": 10
        }
      }
    }'

按请求设置工具集

在 HTTP 模式下,请求可以通过 X-Last9-Toolsets 标头缩小可用工具范围;无法设置标头的客户端可以使用 toolsets 查询参数(/mcp?toolsets=logs,traces)。如果两者都提供,则非空白标头优先。其值使用与 --toolsets 相同的逗号分隔名称。请求可见的工具集是其与启动时 --toolsets 的交集:只能缩小范围,不能扩大;all 或空值会保留启动时的工具集。未知名称会返回指出该名称的 400。tools/list、tools/call 和 initialize 指令都会遵循生效的工具集;get_current_time 和 get_workspace_overview 则始终包含在所有工具集中。

curl -s -X POST http://localhost:8080/mcp \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -H "X-Last9-Toolsets: logs,alerts" \
    -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}'

每个不同的生效工具集都由独立服务器提供服务,该服务器会在首次请求时构建(耗时数十毫秒),并一直保留到关闭;如果请求指定的工具集与启动时相同,则会复用启动服务器。不会进行淘汰:只接受命名工具集,因此缓存中每种组合最多保留一个服务器(目前共 135 种组合,实时堆内存合计约 75 MB;测试中完整缓存稳定后常驻内存接近 230 MB)。

从源代码构建

git clone https://github.com/last9/last9-mcp-server.git
cd last9-mcp-server
go build -o last9-mcp-server
LAST9_HTTP=true ./last9-mcp-server

LAST9_HTTP=true适用于本地开发。实际使用时,托管 HTTP 端点更方便。


工具参考

所有参数、时间输入规范和详细信息

时间输入

  • 绝对时间(start_time_iso/end_time_iso,或 time_iso)优先于 lookback_minutes。
  • 对于相对时间窗口:使用 lookback_minutes。
  • 对于绝对时间窗口:使用 RFC3339/ISO8601 — 2026-02-09T15:04:05Z。
  • 旧版 YYYY-MM-DD HH:MM:SS 仅为兼容性而接受。
  • 将 since yesterday 9am IST 等短语解析为 RFC3339 边界,并使用 get_current_time。

get_workspace_overview

无参数。并发探测最近 60 分钟的数据,每个子调用都设有较短超时,并返回 current_time、lookback_minutes、environments、telemetry(logs/traces/metrics 布尔值)、service_count(不同服务的 get_service_summary 排名,涵盖所有环境)、alert_group_count、firing_alert_count 和 errors([{field, error}])。子调用失败的字段为 null(未知),绝不会是 0 或 false。这些探测不会受 --toolsets 限制:工具集决定提供哪些工具,而 API 令牌决定服务器可以读取哪些内容。

get_current_time

  • range(字符串,可选):last 2h、past 30 minutes、last 7d(s、m、h、d = 24h、w = 7d;最多 366d);today;yesterday;since <point>;<point> to <point>。时间点可以是 RFC3339,也可以是 today / yesterday / 星期几(monday、mon:最近一次出现的日期,包括今天)/ YYYY-MM-DD,并可选带有 9am、9:30pm 或 14:30。末尾的时区会覆盖两个边界的 timezone;其他位置出现时区则会报错。若只需要 now,请省略。
  • timezone(字符串,可选):IANA 名称或缩写(IST = Asia/Kolkata、PST/PDT、EST/EDT、UTC、GMT)。默认值为 UTC。未知时区会报错;含义不明确的 CST 也会报错(请传入 America/Chicago 或 Asia/Shanghai)。

返回 now(以及在 range 下的 start/end),格式为 {iso, epoch_seconds, local};仅当时区非 UTC 时才会出现 local。

get_exceptions

  • limit(整数,可选):异常数量上限。默认值:20。
  • lookback_minutes(整数,可选):默认值:60。
  • start_time_iso / end_time_iso(字符串,可选):绝对时间范围。
  • service_name(字符串,可选):按服务筛选。
  • span_name(字符串,可选):按 span 名称筛选。
  • env(字符串,可选):按环境筛选。

get_service_summary

  • start_time_iso / end_time_iso(字符串,可选)
  • env(字符串,可选):PromQL 正则表达式。默认值为 .*。精确匹配需要锚点(例如 ^prod$)。
  • sort_by(字符串,可选):request_count(默认值)、throughput_rpm、http_4xx_count、http_5xx_count 或 grpc_error_count。
  • limit(整数,可选):排名行数上限。省略或设为 0 表示 10;大于 100 的值会限制为 100。

get_service_environments

  • start_time_iso / end_time_iso(字符串,可选)

所有其他 APM 工具都需要 env 值。如果此处返回空值,请使用 ""。

get_service_performance_details

默认返回每个序列的摘要:points、missing_points(无流量的可用性时间段,不计入统计)、min、p50、p90、p99(最近秩)、max、mean、last、baseline_mean(有效数据点前半部分的均值,而非整个时间窗口的均值)、delta_pct(有效数据点后半部分相对于基线的变化;基线为 0 时不显示),以及最多 3 个 change_points(timestamp、before_mean、after_mean);每项指标和每个响应时间分位数最多包含 4 个序列(按均值从高到低排列;series_omitted 统计其余序列)。带有 points: 0 的序列不包含统计数据;baseline_mean/delta_pct 至少需要 6 个数据点(每半部分 3 个)。full_series 表示可通过 include_series 获取原始数据点。

  • service_name(字符串,必填)
  • lookback_minutes(整数,可选):默认值:60。
  • start_time_iso / end_time_iso(字符串,可选)
  • env(字符串,可选):默认值为 prod。
  • top_n(整数,可选):top-operations/top-errors 列表的条目上限。默认值:5;使用 include_series=true 时为 10。最大值为 100。
  • include_series(布尔值,可选):返回每个序列的所有数据点,而非摘要。默认值:false。

get_service_operations_summary

  • service_name(字符串,必填)
  • lookback_minutes(整数,可选):默认值:60。
  • start_time_iso / end_time_iso(字符串,可选)
  • env(字符串,可选):默认值为 prod。

get_service_dependency_graph

  • service_name(字符串,可选)
  • lookback_minutes(整数,可选):默认值:60。
  • start_time_iso / end_time_iso(字符串,可选)
  • env(字符串,可选):默认值为 prod。

get_apm_service_deviations

  • service_name (字符串,可选):省略表示整个集群范围;提供此参数可指定单个服务及其操作关联。
  • lookback_minutes (整数,可选):当前时间窗口。默认值:60。
  • start_time_iso / end_time_iso (字符串,可选):显式指定当前时间窗口。
  • baseline_start_time_iso / baseline_end_time_iso (字符串,可选):显式指定基线。默认使用紧邻当前窗口之前、时长相同的窗口。
  • datasource (字符串,可选):省略则使用默认值;近似名称的解析方式与 Prometheus 工具相同。响应会指出使用的默认项或最接近的匹配项;名称有歧义时会返回候选项,不会执行查询。
  • env (字符串,可选):默认值为 prod。
  • max_services / max_operations (整数,可选):默认值为 10,每项最大值为 10。

get_databases

  • env (字符串,可选):按环境筛选。接受正则表达式。默认值:全部。
  • lookback_minutes (整数,可选):默认值:60。时间窗口不得超过 7 天。
  • start_time_iso / end_time_iso (字符串,可选)

get_database_slow_queries

  • db_system (字符串,可选):例如 postgresql、mysql、mongodb、redis。
  • host (字符串,可选):数据库主机(net_peer_name)。
  • service_name (字符串,可选):调用方服务名称。
  • env (字符串,可选)
  • min_duration_ms (浮点数,可选):查询时长下限,单位为 ms。
  • lookback_minutes (整数,可选):默认值:60。
  • start_time_iso / end_time_iso (字符串,可选)
  • limit (整数,可选):默认值:20。

get_database_queries

  • db_system (字符串,可选)
  • host (字符串,可选)
  • service_name (字符串,可选)
  • env (字符串,可选)
  • lookback_minutes (整数,可选):默认值:60。
  • start_time_iso / end_time_iso (字符串,可选)
  • limit (整数,可选):默认值:20。

get_database_server_metrics

  • db_system (字符串,必需):例如 postgresql、mysql、mongodb、redis、aerospike。
  • host (字符串,可选)
  • lookback_minutes (整数,可选):默认值:60。
  • start_time_iso / end_time_iso (字符串,可选)

prometheus_range_query

  • query (字符串,必需):PromQL 查询。
  • start_time_iso / end_time_iso (字符串,可选):默认查询最近 60 分钟。
  • lookback_minutes (浮点数,可选):默认值:60。

prometheus_instant_query

  • query (字符串,必需)
  • time_iso (字符串,可选):默认值为当前时间。
  • lookback_minutes (浮点数,可选)

prometheus_label_values

  • match_query (字符串,可选):PromQL 筛选条件。
  • label (字符串,必需):标签名称。
  • lookback_minutes (浮点数,可选):默认值:60。
  • start_time_iso / end_time_iso (字符串,可选)

未指定时间窗口且 match_query 指定了一个指标(metric{...} 或 {__name__="metric"})时,如果 60 分钟的结果为空,则会在 4 天的时间范围内重试一次;第二个文本块会说明结果涵盖的时间窗口。

prometheus_labels

  • match_query (字符串,可选):PromQL 筛选条件。
  • lookback_minutes (浮点数,可选):默认值:60。
  • start_time_iso / end_time_iso (字符串,可选)

与 prometheus_label_values 类似,单指标查询结果为空时会在 4 天的时间范围内重试。

get_logs

  • logjson_query (数组,必需):JSON 管道查询。
  • lookback_minutes (整数,可选):默认值:5。
  • start_time_iso / end_time_iso (字符串,可选)
  • limit (整数,可选):服务器默认值:5000。
  • index (字符串,可选):physical_index:<name> 或 rehydration_index:<block_name>。
  • response_mode (字符串,可选):summary(默认值;也适用于 null)或 raw。原始行结果超过 20 行时,会以 summary 返回:lines_summarized、severity_counts(前六个标签,其余放在 other_severities 中)、first_timestamp/last_timestamp、覆盖查询时间窗口的 10 桶 histogram(基于返回的行;如果结果被限制截断,则包含 truncated: true),以及排名靠前的 patterns(template、count,最多两个 samples),其余汇总到 other 中;总长度最多为 4000 个字符。仍然无法放入的顶层元数据会被丢弃,并在 dropped_fields 中列出。raw 会返回这些行。聚合结果不会被汇总。

对于基于日志的服务清单,先查询 physical_index_service_count:

sum by (name, service_name, env) (physical_index_service_count{destination="logs"})

将 service_name 用作 ServiceName,存在时将 env 用作环境,并将 name 用作物理索引名称。如果 name="default",则省略 index;如果用户选择了非默认物理索引,则传入 index: "physical_index:<name>"。如果后端拒绝显式物理索引筛选,则不带 index 重试,并说明该后端不支持显式物理索引筛选。

get_service_logs

  • service_name (字符串,必需)
  • lookback_minutes (整数,可选):默认值:60。
  • limit (整数,可选):默认值:100;使用 response_mode: "raw" 时为 20。
  • env (字符串,可选)
  • severity_filters (数组,可选):例如 ["error", "warn"]。使用 OR 逻辑。
  • body_filters (数组,可选):例如 ["timeout", "failed"]。使用 OR 逻辑。
  • start_time_iso / end_time_iso (字符串,可选)
  • index (字符串,可选)
  • response_mode (字符串,可选):summary(默认值;也适用于 null)或 raw。超过 20 行时,logs 会替换为与 get_logs 相同的 summary,其他字段保持不变;raw 会返回这些条目。

多种筛选类型之间使用 AND 逻辑。每个数组内部使用 OR 逻辑。 先使用 get_logs 获取宽泛的聚合计数;只有在将范围缩小到服务/环境/索引和少量样本集后,才使用 get_service_logs。

get_log_patterns

  • service_name (字符串,必需)
  • env (字符串,可选)
  • start_time_iso / end_time_iso (字符串,可选)
  • lookback_minutes (整数,可选):默认值:60。
  • severity_filters / body_filters (数组,可选):使用 OR 逻辑,与 get_service_logs 中相同。仅当 get_service_profile 报告 severity_set all 时才设置 severity_filters;使用 none 或 partial 时,它会丢弃正文中严重性符合条件的行。
  • index (字符串,可选)
  • sample_size (整数,可选):从时间窗口中采样的行数,按最新优先。默认值:1000,最大值:5000。
  • top_n (整数,可选):按计数返回的模板数。默认值:20,最大值:100。其余模板的计数汇总到 other 中。

聚类在 MCP 服务器中对采样行执行,因此计数、first_seen 和 last_seen 均基于样本;当样本可能遗漏匹配行时,window.sample_limit_reached 会说明这一点(样本包含 sample_size 行,且 API 未报告与此相等的精确 total_matching_lines,或者搜索已被 logs_truncated),此时样本仅包含该时间窗口中最新的行。每个 template 和 sample 最多截取 500 个字符,并以 … 结尾,因此无法聚类的正文(例如不含 message 字段的 JSON)不会占满响应。搜索中有分块失败时会返回工具错误;搜索被截断或达到上限时仍会返回模式,并通过 sample_limit_reached 标记。只有在 sample_limit_reached 为 false 时,空的 patterns 列表才表示没有匹配项;如果为 true,则表示搜索提前停止,可能遗漏匹配行。

get_emerging_log_patterns

接受所有 get_log_patterns 参数(时间范围为当前窗口),并额外接受:

  • baseline_start_time_iso / baseline_end_time_iso (字符串,可选):必须同时设置或都不设置。默认值:紧邻当前窗口之前、时长相同的窗口。
  • min_count (整数,可选):变化模式在其数量较多的窗口中所需的行数:对于 new/increased,使用当前窗口;对于 decreased/disappeared,使用基线窗口。默认值:3(如果 sample_size 更小,则使用该值),最大值:sample_size。
  • change_factor (数字,可选):频率比,必须大于 1;在两个窗口中都出现的模式必须达到该比值(increased),或降至其倒数(decreased)。默认值:2。

两个阈值都必须满足,因此频率未变化达到 change_factor 的高频模板绝不会被报告。仅返回发生变化的模板(new、increased、decreased、disappeared),并附带 current 和 baseline 计数;unchanged_patterns 统计两个窗口中都出现、但变化幅度小于 change_factor 的模板;below_min_count_patterns 统计因行数少于 min_count 而被丢弃的变化。当两个样本都包含所有匹配行时,按每分钟频率进行比较;对于达到上限的样本,则根据精确的 total_matching_lines 估算每分钟频率;其他情况下,按样本占比比较,此时 increased/decreased 描述的是组成而非速率(comparison_basis)。空的 patterns 列表表示没有变化超过两个阈值,并不表示日志没有变化:较少见的变化会计入 below_min_count_patterns;如果某个窗口包含 sample_limit_reached,则比较的是样本,而非整个窗口。

get_log_attributes

  • lookback_minutes (整数,可选):默认值:15。
  • start_time_iso / end_time_iso (字符串,可选)
  • region (字符串,可选)
  • index (字符串,可选)

get_log_attributes_for_pipeline

  • pipeline (数组,必需):用于限定属性发现范围的前置筛选阶段,例如 [{"type":"filter","query":{"$eq":["ServiceName","<service>"]}}]。
  • lookback_minutes (整数,可选):默认值:15。
  • start_time_iso / end_time_iso (字符串,可选)
  • region (字符串,可选)
  • index (字符串,可选)

get_drop_rules

无参数。通过 GET /otel_settings/drop?region=... 列出丢弃规则。

add_drop_rule

  • name (字符串,必需)
  • filters (数组,必需):每个筛选条件包含:key、value、operator(equals/not_equals)、conjunction(and)。
  • 筛选键必须使用 attributes["key_name"] 或 resource.attributes["key_name"](Last9 API 要求)。
  • 通过 POST /otel_settings/drop?region=...&cluster_id=... 创建规则。

get_remapping_rules

  • rule_type (字符串,必需):logs_extract、logs_map 或 traces_map。
  • region (字符串,可选):默认值:已配置的数据源区域。
  • 通过 GET /otel_settings/remapping/{rule_type}?region=... 列出规则。

add_remapping_rule

每次调用创建一条规则;映射规则需要针对每个 target_attribute 单独调用。

  • rule_type(字符串,必填):logs_extract、logs_map 或 traces_map。
  • name(字符串,必填)
  • remap_keys(数组,必填):源字段。logs_extract 配合 json 使用时:正文中的字段名;配合 pattern 使用时:恰好一个带命名捕获组的正则表达式。映射规则:属性路径,优先采用第一个非空值。
  • target_attribute(字符串,必填):logs_extract:log_attributes 或 resource_attributes。logs_map:service、severity 或 resource_deployment.environment。traces_map:service。
  • extract_type(字符串,仅限 logs_extract,且在该模式下必填):json 或 pattern。
  • action(字符串,仅限 logs_extract):upsert(默认值)或 insert。
  • prefix(字符串,仅限 logs_extract)
  • preconditions(数组,仅限 logs_extract):最多一个 {key, value, operator};operator 为 equals(默认值)、not_equals 或 like(正则表达式)。
  • region(字符串,可选):默认值:已配置的数据源区域。
  • 通过 POST /otel_settings/remapping/{rule_type}?region=... 创建规则。不会重试;超时后,请使用 get_remapping_rules 检查。

get_traces

用于广泛搜索和聚合。若要精确查找 trace ID,请使用 get_service_traces。

  • tracejson_query(数组,必填)
  • start_time_iso / end_time_iso(字符串,可选)
  • lookback_minutes(整数,可选):默认值:60。
  • limit(整数,可选):默认值:5000。

get_service_traces

必须且只能提供 trace_id 或 service_name 其中之一。

  • trace_id(字符串,可选):默认回溯时间:72 小时。
  • service_name(字符串,可选):默认回溯时间:60 分钟。
  • lookback_minutes(整数,可选)
  • start_time_iso / end_time_iso(字符串,可选)
  • limit(整数,可选):默认值:10。
  • env(字符串,可选)

get_trace_attributes

  • lookback_minutes(整数,可选):默认值:15。
  • start_time_iso / end_time_iso(字符串,可选)
  • region(字符串,可选)

get_trace_attributes_for_pipeline

  • pipeline(数组,必填):用于限定发现范围的前置筛选阶段,例如 [{"type":"filter","query":{"$eq":["ServiceName","<service>"]}}]。
  • lookback_minutes(整数,可选):默认值:15。
  • start_time_iso / end_time_iso(字符串,可选)
  • region(字符串,可选)

get_trace_attribute_values

  • tag_name(字符串,必填):来自 get_trace_attributes 的属性名称(例如 resource_department 或 attributes['http.method'])。
  • pipeline(数组,可选):用于限定值范围的前置筛选阶段;省略则返回全局值。
  • lookback_minutes(整数,可选):默认值:15。
  • start_time_iso / end_time_iso(字符串,可选):历史 RFC3339 时间边界;优先于 lookback_minutes。
  • region(字符串,可选)

get_trace_attribute_deviations

  • comparison_mode(字符串,必填):latency、errors 或 time。
  • service_name(字符串,必填)
  • environment(字符串,必填):精确的 deployment.environment 值。
  • operation(字符串,可选)
  • filters(数组,可选):Trace JSON 筛选条件。
  • candidate_attributes(数组,可选):最多 8 个;省略则执行有界发现。
  • latency_threshold_ms(数字,可选):latency 模式必填;其他模式不接受。
  • start_time_iso / end_time_iso(字符串,可选)
  • lookback_minutes(整数,可选):默认值:15。最大值:15。
  • baseline_start_time_iso / baseline_end_time_iso(字符串,可选):time 模式必填;时间范围不得重叠,且时长须与目标窗口相同。
  • minimum_cohort_size(整数,可选):默认值:100。最小值:20。
  • minimum_value_support(整数,可选):默认值:20。最小值:10。
  • limit(整数,可选):默认值:10。最大值:10。

需要启用配套的后端功能。

get_trace_waterfall

  • trace_id(字符串,必填)
  • environment(字符串,可选)
  • start_time_iso / end_time_iso(字符串,可选)
  • lookback_minutes(整数,可选):默认值:4320(72 小时)。
  • selected_span_id(字符串,可选):仅返回该 span 的属性、事件和链接。
  • max_spans(整数,可选):默认值:500。最大值:1000;组织的脱敏策略可能会将上限设得更低。

原样返回 trace 服务的 investigation-evidence/v1 信封;瀑布图位于 data 下。服务会生成瀑布图,并在数据离开后端前,按照每个组织各自的策略对值进行脱敏(凭据、查询字面值、URL、电子邮件、IP、用户标识符):sanitizer 指明所执行的策略,evidence.sanitization 统计被脱敏或截断的内容。如果所需内容被脱敏,请让组织管理员调整策略,而不要尝试绕过策略。如果响应没有 sanitizer 块、sanitizer.version 不是 trace-evidence-sanitizer/v1、正文中重复出现 JSON 键,或正文超过 512 KiB(降低 max_spans),该工具将拒绝响应。需要启用配套的后端功能。

get_change_events

  • start_time_iso / end_time_iso(字符串,可选)
  • lookback_minutes(整数,可选):默认值:60。
  • service_name(字符串,可选)
  • env(字符串,可选)
  • event_name(字符串,可选):首次调用时不传此参数,以获取 available_event_names。

analyze_change_impact

恰好传入 change_event 或 service + timestamp 其中一种。

  • change_event(对象,可选):get_change_events change_events[] 中的一个元素,保持原样。使用 metric.service、metric.deployment_environment 和最早的 values[].timestamp。
  • service(字符串,可选):省略 change_event 时,必须与 timestamp 一起提供。
  • timestamp(字符串,可选):RFC3339 或 Unix 秒数,向下取整到分钟。
  • env(字符串,可选):精确环境。默认值:事件所属环境;否则为全部环境。
  • baseline_minutes(整数,可选):默认值:60。限制在 30..120。
  • after_minutes(整数,可选):默认值:baseline_minutes。限制在 30..120,且不晚于当前时间。

满足以下任一条件时,regression likely:服务或其吞吐量排名前 10 的调用方之一,错误率至少上升 1 个百分点、p95 至少上升 40%,或吞吐量(rpm)至少下降 50%;排名依据两个窗口合计的吞吐量(变更前至少有 100 个请求;对于吞吐量,还要求变更后至少有 100 个请求;p95 仅统计 latency_env 的请求);某个告警在变更后开始触发,并在变更后窗口结束时仍处于触发状态(按告警组名称或 service、service_name 或 service.name 标签进行不区分大小写的匹配;若无匹配,则检查注释,绝不匹配摘要等自由文本);提供 env 时,带有其他环境标签的告警(忽略大小写)会被排除,未标注环境的告警则标记为 env_match: unlabelled;或者发现来自 get_apm_service_deviations 的回归。若变更后窗口不足 5 分钟(包括变更发生在未来)、服务请求数过少,或黄金信号、直接调用方查询、告警或 get_apm_service_deviations 失败(全部失败或 deviations.apm.unavailable 中列出的任一查询失败),则为 insufficient data:证据缺失绝不会得出 no significant change;即使仍发现回归,也会注明失败项。no significant change 是有效结论,并非失败。仅当设置了 env 时才会运行 Trace 属性偏差分析,每侧最多覆盖 15 分钟;该分析用于解释结论,但不会决定结论,因此跳过或获取失败都不会改变结论。每个列表最多保留 10 项,并报告丢弃的数量;上游调用失败时,只会在对应部分留下一个 error。黄金信号延迟在两个窗口中均取自同一环境,该环境会在 latency_env 中注明:未提供 env 时,使用流量最大的环境。黄金信号错误率统计 5xx 和 gRPC 错误;deviations.apm 还会统计错误状态的 span 和 429。调用方信号取自其自身的服务器 span,因此仅有客户端 span 的调用方会显示 0 rpm。

regressions 会按 reason 的顺序,为 regression likely 背后的每个触发条件列出一项;对于其他结论则为 []。每项包含 service、role(changed 或 dependent)、env、metric(恰好为 error_rate_pct、latency_p95_ms、throughput_rpm、alert、apm_deviation 之一),以及以指标单位(%、ms、rpm 或 APM 信号自身的值;对于 alert 则为 null)表示的 baseline/after。alert 项还会添加 rule_id 和 state,表示该实例在变更后窗口中最新的、列出该实例的告警监控切片中的状态,始终为 firing:变更后开始触发、但在变更后窗口结束前已恢复的告警不算回归,因此不会创建工单;它仍会保留在 alerts.started 中,并带有其 state,而 reason 会统计它。env 表示测量指标所用的环境:若指定了 env,则使用该环境;否则,错误率和吞吐量汇总所有环境(env: ""),而 p95 使用流量最大的环境(latency_env);告警使用其自身的环境标签,APM 偏差则使用其自身的环境。所有回归都针对整个服务,因此不会指向任何端点。

get_alert_groups

用于 changeboard / 标签覆盖率审计的已配置 Compass 告警组清单。包括规则数为零的组和当前未触发的组。不返回 PromQL。

  • alert_group_name / alert_group_type / data_source_name(字符串,可选):不区分大小写的子字符串匹配。
  • team / tier(字符串,可选):对已配置元数据进行不区分大小写的精确匹配。
  • label_key + label_value(字符串,可选):必须同时设置。对一个 metadata.labels 键值对进行不区分大小写的精确匹配,键和值均须匹配。

返回精简 JSON {"count":N,"groups":[...]},包含 id、name、type、entity_class、team、tier、metadata.labels 和规则计数。空的 team / labels 表示未设置。

get_alert_operations_summary

  • start_time_iso / end_time_iso(字符串,必填):RFC3339 时间窗口,最长 31 天。
  • timezone(字符串,可选):用于划分日期边界的 IANA 名称。默认值:UTC。
  • severities / services(数组,可选):缩小摘要范围。
  • include_rules(布尔值,可选):同时返回每条规则的健康状况(按 fire_count 排名前 20 的规则、频繁抖动和未路由规则;若 API 限制了规则列表,则包含 truncated)。默认值:false。

返回包含 alerts_raised、acknowledged、unacknowledged、current_backlog、delivered、notification_outcomes、top_rules、needs_attention 和 coverage 的 JSON。每项指标均为 {status, count?, reason?};partial 计数仅覆盖窗口的一部分,并非下限。

get_alert_coverage

针对某个服务、环境、告警组,或在未指定范围时针对整个组织,回答“我有哪些内容尚未配置告警?”。只读:不会创建、修改或取消静默任何内容。也可通过 investigate 工具集调用。

  • service(字符串,可选):服务名称。
  • environment(字符串,可选):部署环境(例如 prod)。
  • entity_id(字符串,可选):告警组(实体)UUID,由 get_alert_groups 返回。
  • muted_days(整数,可选):整天数,范围为 1 到 3650。默认值:7;0 表示使用默认值。规则静默时间超过此值时,会被视为 muted_too_long 缺口。 数值会被去除首尾空白;空字符串会被忽略。缺口类型:uncovered_signal(latency、error_rate、throughput 或 saturation 上没有启用的规则;会指出一个可覆盖该信号的已禁用规则)、all_rules_disabled(规则全部已禁用的告警组)、no_notification_channel(其严重级别没有任何告警组路由渠道的规则)、muted_too_long(无限期静音或静音时间超过 muted_days;muted_since 是规则的最后更新时间;无限期静音时省略 mute_until)。

返回精简 JSON {scope, generated_at, complete, summary, counts, groups}。groups 对每种存在的类型包含一个 {kind, count, gaps, omitted} 条目,每种类型最多列出 10 个缺口(其余数量由 omitted 统计;缩小范围以查看这些缺口);每个缺口包含 suggested_tool(create_alert、create_alert_from_chart、attach_notification_channel 或 patch_alert)和 suggested_args,其中仅包含该工具接受的输入(patch_alert:entity_id、id 和 is_disabled=false 或 mute_until=0;attach_notification_channel:alert_group_id 和一个 breach/threat severity;create_alert:entity_id;create_alert_from_chart:service_name);缺口自身的 entity_id、rule_id 和 signal 会列在旁边。仅当建议的工具在当前会话中可用且用户确认后,才调用该工具。只有当 API 未列出任何缺口、所有计数均为 0,且至少有一个告警组与范围匹配时,complete 才为 true(精确的 service_name / env 标签,根据 get_alert_groups 的列表进行检查);范围未匹配任何对象、查询失败或存在计数但未列出缺口,都不算完成;summary 会说明原因。

get_alert_config

  • search_term(string,可选):按名称、组、数据源和标签进行全文搜索。
  • rule_name(string,可选)
  • severity(string,可选)
  • rule_type(string,可选):static 或 anomaly。
  • alert_group_name / alert_group_type / data_source_name(string,可选)
  • tags(array,可选):必须全部匹配(AND 逻辑)。

每条规则都会列出 Recent Evaluations:5 个一分钟采样点,按时间从新到旧排列,每个采样点标注其结束时的 UTC 分钟;最新采样点的结束时间比调用时间早 1–2 分钟,因为监控器会延迟填充最新的一分钟。firing;ok = 监控器报告该规则未触发(正常、已解决、待处理或空状态,如 is_firing=0 在 get_alert_rule_state 中所示);unknown = 没有该规则的监控器行(尚未评估,或该分钟的查询失败,响应顶部会注明),或者该行的状态不属于 firing、normal、resolved、pending 或 empty(例如 no_data、silenced)。已禁用的规则显示 none。匹配的已启用规则超过 25 条时,所有这些规则的历史记录都会省略,并且响应会说明这一点。

get_entity_kpis

只读;仅适用于 alerts 和 investigate 工具集。列出一个告警组中的所有 KPI,包括尚未被任何告警规则使用的 KPI。在 expression_args / indicators_used 中使用返回的 ID;切勿自行编造。

  • entity_id(string,必填):告警组/实体 UUID,来自 get_alert_groups 或 get_alert_config。

返回按名称排序的 JSON {"entity_id","count","kpis":[{"id","name","description","query","unit"}]}。unit 是显示标签:阈值会与原始查询值进行比较。没有合适的 KPI 时,使用 create_kpi 创建一个。仅当会话提供该功能时,空组的结果才会列出 create_kpi;使用 --read-only(除非是 --allow-write-tools=create_kpi)或 investigate 工具集时,结果会说明 KPI 创建需要可写的 alerts 会话。

create_kpi

在现有告警组中创建 KPI;仅适用于 alerts 工具集。仅当 get_entity_kpis 中没有所需查询的 KPI 时才使用。先用 prometheus_range_query 检查查询是否返回数据:API 只会拒绝无法解析的查询,并会保存语法有效但对应指标不存在的查询。

  • entity_id(string,必填):告警组/实体 UUID。
  • name(string,必填):在告警组内唯一;使用相同名称再次创建会因冲突而被拒绝。
  • query(string,必填):PromQL。若要对仪表板面板设置告警,请从 get_dashboard 获取该面板的 PromQL。
  • unit(string,必填):查询原始值的单位,例如 seconds、ms、percent、ratio、count、req/s。它只是标签,不会进行任何转换,因此阈值会与原始值进行比较。
  • description(string,可选)
  • data_source_id(string,可选):默认为告警组的数据源。

没有 MCP 工具可以删除或编辑 KPI(请使用 Last9 UI),因此创建前请确认名称、查询和单位。只创建一次,并保留返回的 ID 以供 expression_args / indicators_used 使用;名称冲突时,请从 get_entity_kpis 复用现有 KPI 的 ID。发生超时或连接错误时,创建操作可能已生效,也可能未生效:重试前先用 get_entity_kpis 按名称检查。返回 {"id","name","query","unit"}。

get_alerts

  • time_iso(string,可选):RFC3339 格式的评估时间。
  • window(integer,可选):回溯秒数。默认值:900。范围:60–86400。
  • lookback_minutes(integer,可选):范围:1–1440。

get_alert_rule_state

  • start_time(integer 或 string,必填):范围起点(包含):Unix 纪元秒数(1718000000)或 RFC3339(2024-06-10T06:13:20Z)。Unix 纪元毫秒、微秒和纳秒会转换为秒;早于 2000-01-01 的值会被拒绝。
  • end_time(integer 或 string,必填):范围终点(包含),格式相同。
  • step(integer,必填):采样间隔秒数。采样数 ((end_time - start_time) / step + 1) 上限为 100。每个采样点都是一次上游调用,覆盖以其时间戳为终点的 min(step, 3600) 秒;每次获取 5 个采样点,如果耗时超过 60s,工具会返回错误并提供重试指引。
  • alert_group_id(string,可选):按告警组 ID 筛选。
  • rule_name(string,可选):按规则名称进行正则表达式筛选。
  • alert_group_name(string,可选):按告警组名称进行正则表达式筛选。
  • label_filters(string,可选):以逗号分隔的 key=value 标签筛选条件。
  • state(string,可选):按状态筛选(例如 firing)。

返回 rule_id -> [{timestamp, is_firing}] 的 JSON 映射。上游响应中缺少某条规则的时间戳会报告为 is_firing=0 ——这表示“未观察到正在触发”,而非已确认处于正常状态。

get_alert_hygiene

对已启用告警规则进行只读审计。不会更改任何内容:每项建议修复都只是提案,只有用户明确确认后,才会通过 update_alert(调整)、patch_alert(is_disabled)、delete_alert 或 attach_notification_channel 应用(前提是这些工具可用)。

  • window(string,可选):7d 或 30d。默认值:7d。
  • limit(integer,可选):返回的标记规则数量上限,按问题严重程度从高到低排列。默认值:20。范围:1–100。

时间窗口截至当前。类别(同一规则可能属于多个类别):noisy(每天触发 ≥ 5 次,且 < 20% acked; with an unavailable ack_rate it is judged on fire rate alone and the reason says so; mute time is not reported), flapping (> 每天抖动 4 次)、stale(上次触发时间早于窗口且窗口内没有触发时间;或者已启用的已配置规则在窗口内没有事件,且生命周期 coverage 已完成、API 返回的列表未被截断)、unrouted(窗口内没有任何触发到达渠道,且告警组当前未关联任何渠道;无法读取关联信息时,该规则会归入 unavailable.routed)。每项统计值为 {status, count|value, reason} 或 null:不可用的值绝不会被视为 0,且只会跳过依赖该值的检查;unavailable 会统计每种缺失值对应的已启用规则数量(fire_count、flap_count、ack_rate、routed、rule_config 表示规则未出现在告警规则列表中,因此其修复建议不包含当前值;activity 表示已配置但没有事件的规则,其静默状态无法通过历史记录证实,因此不会进行评估)。coverage 说明告警历史覆盖了多长的窗口;速率按已覆盖时长计算,且至少为一天。若 API 仅返回最响亮的 200 条规则,则 upstream_truncated 为 true,因此较安静的规则不会被评估。修复建议基于告警规则列表中的各规则配置生成:提高 bad_minutes(count_true(result) >= N 中的 N)或延长 eval_window(最长 60 分钟);对于嘈杂的静态阈值,将阈值调整到 condition(expr > 100),或将表达式切换为 adaptive_std_cmp(metric, sensitivity, window);关联通知渠道;禁用或删除过时规则。

返回精简 JSON {window, from, to, coverage, upstream_truncated, rules_evaluated, flagged_rules, truncated, omitted_for_size, unavailable, rules},目标大小为 32 KB:当标记规则数量超过 limit 或该大小目标时,truncated 为 true;omitted_for_size 统计因大小限制而从 limit 中删去的规则数量(始终保留问题最严重的规则,因此单条规则超过 32 KB 时会单独返回,并超出目标大小);每条规则包含 findings(category、reason、suggested_fix、可选的 alternative_fix)以及原始的 stats。

get_notification_channels

  • scope(string,可选):attached(默认)会为每个告警组关联项返回一行;id 是关联项 ID,由 detach_notification_channel 使用。channels 会返回组织的渠道(id、name、type、send_resolved、created_via);id 是渠道 ID,由 attach_notification_channel 使用。绝不会返回目标地址、标头或证书。

以 TSV 表格形式返回已配置的通知渠道(Slack、PagerDuty、电子邮件、webhook 等)。关联项行(已设置 service_fqid)会显示 global 为 false,且 services 为 -;services 仅列出旧版服务绑定。在关联项行中,send_resolved 是该行存储的默认值,而非实际投递所用的值;解决通知遵循渠道自身的 send_resolved(scope=channels)。两个范围都包含 created_via(由 MCP 代理创建的行显示 last9-mcp,否则显示 -)。

recommend_alert_config

只读。返回生命周期指导、验证门槛和响应人员上下文要求;这些内容本身并非证据,因此应使用遥测工具来确定阈值。

  • signal(string,必填):指标或用户影响信号,包括单位和维度。
  • objective(string,必填):要检测的症状或用户影响。
  • rule_type(string,可选):static(默认)或 anomaly。
  • severity(string,可选):breach(默认)或 threat。
  • environment(string,可选):环境和流量特征。

validate_alert_expression

对表达式进行试运行,不会保存。请在 create_alert / update_alert 之前使用。

  • entity_id(string,必填):告警组/实体 UUID。
  • expression(string,必填):对以 KPI 精确名称命名的指标进行算术运算,例如 errors / requests。最多 3 个指标。名称中包含空格、点或连字符时,按原样书写(Test Alert / errors),与 create_alert 保存的名称完全一致。
  • indicators_used(object,必填,非空):指标名称到 KPI UUID 的映射;这些 KPI 归属于 entity_id;使用 get_entity_kpis 列出该组的 KPI ID 和名称。使用每个 KPI 的精确名称:此试运行接受任意名称,但 create_alert 和 update_alert 会拒绝键名不是所绑定 KPI 名称的 expression_args。 仅检查算术表达式(传入内部指标表达式,而不是 adaptive_std_cmp(...) 包装器);不检查 condition / alert_condition。仅当使用多个指标时,才会执行至少一个时间序列检查。

返回 {"valid":true} 或 {"valid":false,"reason":"..."};无效表达式是正常结果,不是工具错误。

describe_alert_chart

只读。列出受支持的 Discover 图表上的可告警信号(key、unit、eval_query、query_kind)。拒绝查看者角色令牌。

  • surface(字符串,必填):discover-service 或 discover-exceptions;包括自定义仪表板在内的任何其他界面都会在调用 API 前被拒绝(改用 create_alert 并指定 KPI)。
  • chart_key(字符串,必填):例如 apdex、error_rate、response_time、exception_count。
  • service_name(字符串,必填)
  • env(字符串,可选)
  • attributes(对象,可选):额外的身份维度,使用此工具报告的键名。

create_alert

在现有告警组中创建规则,始终处于禁用状态(草稿,即使传入 is_disabled=false 也是如此)。先调用 recommend_alert_config,仅在用户确认后再通过 patch_alert is_disabled=false 启用。只创建一次并保留返回的规则 ID。如果告警组已使用 rule_name(不区分大小写),则拒绝创建任何内容,并指出现有规则的 id。

  • entity_id(字符串,必填):告警组/实体 UUID。
  • alert_rule(对象,必填):完整的类型化规则正文,包括绑定到实体真实 KPI 的 primary_indicator 和 expression_args。每个 expression_args 键都必须是其绑定 KPI 的确切名称(不能是 x 之类的占位符),并且 primary_indicator 和 expression 使用这些名称。静态规则需要 condition、alert_condition 和 eval_window(0–60 分钟)。自适应规则使用 expression = adaptive_std_cmp(<primary_indicator>, sensitivity, window);此时这三个字段均为可选项(默认值为 expr > 0、count_true(result) >= 1、1)。不能设置 algorithm。响应者上下文放在 properties 中(描述、运行手册、注释、query_mode)。

通知路由配置在告警组上,而不是规则上。

create_alert_from_chart

根据 describe_alert_chart 描述的图表创建静态阈值规则。与 create_alert 一样,规则创建后会处于禁用状态,作为草稿且不会触发;仅在用户确认后通过 patch_alert is_disabled=false 启用。图表 API 创建的规则默认启用,因此此工具会在创建后立即禁用规则;如果禁用失败,结果会报错并指出规则 id,该规则可能仍处于启用状态。

  • surface / chart_key / service_name / signal_key / name(字符串,必填)
  • env(字符串,可选)
  • attributes(对象,可选)
  • threshold(数字,可选):使用信号的单位;必须大于或等于 0。Apdex 等评分单位信号需要显式指定值。
  • threshold_operator(字符串,可选):>(默认值)、<、>=、<=、==、!=。
  • eval_window(整数,可选):分钟,1–60。默认值:5。
  • bad_minutes(整数,可选):1–eval_window。默认值:3。
  • severity(字符串,可选):breach 或 threat。
  • description(字符串,可选)
  • group_id(字符串,可选):通常省略。

update_alert

完整替换规则的评估配置。先通过 get_alert_config 或 get_entity_alert_rules 获取规则。如果规则不存在或属于其他告警组,则拒绝操作且不做任何更改。此操作可能会软删除并重新创建规则,因此之后请使用返回的替换规则 ID。

  • entity_id(字符串,必填)
  • id(字符串,必填):告警规则 UUID。
  • alert_rule(对象,必填):完整配置;结构与 create_alert 相同。

patch_alert

部分更改,保留规则 ID。至少需要进行一项更改。如果规则不存在或属于其他告警组,则拒绝操作且不做任何更改。

  • entity_id(字符串,必填)
  • id(字符串,必填):告警规则 UUID。
  • is_disabled(布尔值,可选):false 会启用规则,true 会暂停规则。
  • mute_until(整数,可选):Unix 纪元截止时间;0 会取消静音。
  • properties(对象,可选):description、runbook、annotations、query_mode。每个已发送字段都会替换已存储的对应字段;省略或留空的字段保留其已存储值。annotations 会替换整个映射,因此要保留现有内容,请发送所有键;{} 会清除该映射。
  • recurring_mute_schedule(对象,可选):替换每周计划:enabled(默认值为 false)、timezone(IANA 名称,必填)以及 windows(weekdays 中的 1–20 个时间段,格式为 sun..sat,start_time / end_time 使用 24 小时制的 HH:MM)。结束时间早于或等于开始时间时,结束时间视为次日。要保留所有时间段,请全部发送。
  • clear_recurring_mute_schedule(布尔值,可选):完全移除计划;不能与 recurring_mute_schedule 同时使用。与 enabled=false 不同,后者会保留已存储的时间段。

查看者角色用户只能更改 mute_until。当组或实体处于静音状态时,拒绝更改规则级静音设置。使用 get_entity_alert_rules 读取更改后的状态,其中会显示 mute_until、recurring_mute_schedule 和 properties。

delete_alert

永久删除规则。先通过 get_alert_config 验证,并取得用户的明确确认。如果规则不存在或属于其他告警组,则拒绝删除任何内容。

  • entity_id(字符串,必填)
  • id(字符串,必填):告警规则 UUID。

mute_alert_group

将组中所有当前规则和未来规则设为静音;若要将单条规则设为静音,请使用带有 mute_until 的 patch_alert。需要编辑者权限。

  • entity_id(字符串,必填):告警组/实体 UUID。
  • until(整数,必填):静音结束时的 Unix 纪元秒数。0 会取消静音;负值(例如 -1)表示无限期静音。

acknowledge_alert

接管正在触发的告警,或释放该告警。不会解决或静音告警。确认自己已拥有的告警是安全的空操作。除非 get_alerts 在过去一小时内列出了该确切告警(全部三个 ID),否则 ack 会拒绝操作且不记录任何内容。

  • alert_group_id / rule_id / rule_type(字符串,必填):从 get_alerts 中的告警复制。
  • action(字符串,可选):ack(默认值)或 unack。只有所有者或组织管理员可以取消确认。
  • mute_until(整数,可选):仅限 ack。记录你已通过 mute_alert_group 或 patch_alert 应用的静音;不会执行静音操作。

reassign_alert

将已有所有者的告警转交给另一位用户;如果告警没有所有者,请先确认该告警。如果告警没有所有者而未能转交,工具会说明 get_alerts 是否在过去一小时内列出过该告警。Last9 不会通知新所有者。

  • alert_group_id / rule_id / rule_type(字符串,必填):从 get_alerts 中的告警复制。
  • owner_email(字符串,可选):优先使用;与活跃组织用户进行不区分大小写的匹配。
  • owner_user_id(字符串,可选):必须且只能提供 owner_email 或 owner_user_id 之一。

create_notification_channel

创建通知渠道;在通过 attach_notification_channel 关联之前,该渠道不会路由任何通知。只创建一次并保留 ID;没有更新工具。仅返回 id、name、type 和 send_resolved。

  • name(字符串,必填):在同一类型中必须唯一;不能包含冒号。
  • type(字符串,必填):slack、pagerduty、opsgenie、email 或 generic_webhook。
  • destination(字符串,必填):Slack Incoming Webhook URL(或使用 slack_app_mode 时的频道 ID)、PagerDuty 路由密钥、Opsgenie API 密钥、以逗号分隔的工作邮箱地址(可使用任何域名,不限于组织的域名;API 会拒绝 Gmail 等个人邮箱服务提供商的地址,而使用个人账号登录的组织只接受其管理员的地址),或 HTTPS webhook URL。
  • slack_app_mode(布尔值,可选):仅限 Slack。默认值:false。
  • mention_handles(字符串,可选):以逗号分隔,例如 user|U123ABC|name、special|here、special|channel。
  • webhook_headers(对象,可选):仅限 generic_webhook。
  • webhook_ca_certificate(字符串,可选):仅限 generic_webhook;一个 PEM CA 证书,最大 64 KiB。
  • send_resolved(布尔值,可选):默认值:true。

attach_notification_channel

将现有渠道路由到一个告警组。此操作具有幂等性。关联项会在关联时复制渠道的投递设置(标头、证书、提及);如果之后更改了渠道设置,请重新关联。

  • channel_id(整数,必填):渠道 ID(使用 scope=channels 时的 get_notification_channels),而不是关联 ID。
  • alert_group_id(字符串,必填):来自 get_alert_groups。
  • severity(字符串,必填):breach、threat 或 both。both 会创建两个关联;如果第二个失败,第一个仍会保留,错误会指出需要重试的严重级别。

detach_notification_channel

移除一个关联。需要具有删除范围的令牌;写入范围的令牌无法解除关联。

  • attachment_id(整数,必填):使用 scope=attached 时,来自 get_notification_channels 的 id。拒绝渠道 ID。
  • alert_group_id(字符串,可选):如果该关联属于其他组,则拒绝操作。

delete_notification_channel

永久删除没有任何关联的渠道;请先解除其关联。需要具有删除范围的令牌。通过重新列出渠道来确认删除。

  • channel_id(整数,必填):使用 scope=channels 时,来自 get_notification_channels 的 id。拒绝关联 ID。

did_you_mean

  • query(字符串,必填):要搜索的名称——可以是不完整、拼写错误或缩写形式。
  • type(字符串,可选):按实体类型筛选:service、environment、host、database、k8s_deployment、k8s_namespace、job。

最多返回 3 个最接近的匹配项及其相似度分数。实体名称不确定时,在调用任何工具前使用此工具。如果之前的调用返回空结果,请在重试前使用此工具。

get_service_profile

  • service_name(字符串,必填):要为其推导遥测配置文件的服务。
  • datasource(字符串,可选):数据源名称。默认数据源可省略;近似名称的解析方式与 Prometheus 工具相同。 返回简短的调查摘要,后接原始 JSON 格式的完整配置文件:信号是否存在(logs/traces/metrics,分别表示 present、absent 或 unknown)、语言和运行时、部署环境、日志 signal_shape(log_format、severity_set、level_field、trace_context_in_logs),以及适用时建议的摄取修复方案。当后端报告 freshness 时,摘要会添加一行 last seen,其中包含 freshness.logs.last_seen 和 freshness.traces.last_seen(RFC3339;为 null 时使用 none);当 freshness.traces_stale 为 true 时,还会添加 traces stale 警告:跨度已停止而日志仍在继续,因此应调查 freshness.traces.last_seen 附近的回归问题,而不是缺少配置。数据源自上游并经过缓存,TTL 约为 15 分钟。

在进行任何特定服务的调查之前调用此工具,以便工具选择与服务的实际遥测数据相匹配——当 traces 为 absent 时跳过跟踪工具;当 severity_set 为 none 或 partial 时,从日志正文中的 level_field 解析严重性,而不要使用 severity_filters。metrics 始终为 unknown,且 v1 中不会填充 dependencies。当 logs 和 traces 均为 absent 时,请先通过 did_you_mean 确认名称,再断定该服务未受监控。

list_dashboards

  • name(字符串,可选):仪表板名称中不区分大小写的子字符串。用于缩小列表范围并 total。
  • limit(整数,可选):每页仪表板数,1–200。默认值:100。
  • cursor(字符串,可选):上一页的 next_cursor;传入时需同时传入相同的 name。

返回 {"dashboards": [{"id", "name", "updated_at", "created_by", "locked"}], "total", "next_cursor"},按最近更新时间从新到旧排列。为空时省略 created_by;API 未报告 readonly 时省略 locked。updated_at 是以字符串表示的 Unix 纪元秒数。为保持在 32 KB 以内,页面可能提前结束;最后一页不包含 next_cursor。

get_dashboard

  • id(字符串,必填):仪表板 UUID。
  • region(字符串,可选):用于填充面板查询的区域。默认为已配置的数据源区域。

结果会添加顶层字段 locked(API 未提供时为 false)和 created_by(作者的用户 ID)。

如需为面板设置告警,请参阅 last9://reference/alerting。

validate_dashboard

只读。绝不会创建或更新仪表板。必须且只能提供 dashboard_id 或 dashboard_definition 其中之一。

  • dashboard_id(字符串,可选):要验证的已保存仪表板 UUID。
  • dashboard_definition(对象,可选):内联的未保存仪表板正文(真正的试运行)。如果传入 {dashboard, metadata} 创建封装对象,则会解包其 dashboard 对象。
  • start_time_iso / end_time_iso(字符串,可选):验证时间范围(RFC3339)。必须 ≤ 24h。
  • region(字符串,可选):执行面板查询的区域。

返回 dashboard_validation/v1:逐面板的 lint + 执行分类(data / no_data / invalid / error)。首日的空结果会分类为 valid_no_data,不会执行诊断探测。没有面板的仪表板会返回 success: false 和 error: "no_panels"。其他格式中的面板字段(Grafana 的 gridPos、title、type,以及需要查询的面板上的 targets)和类型错误的字段会按面板列在 shape_problems 中,在 summary.panels_invalid_shape 中计数,并使 overall 变为 fail。

preview_dashboard

只读的客户端预览。传入 dashboard(创建请求中的未保存仪表板对象),或传入 id 和 ops(与 patch_dashboard 相同顺序的操作)。必填的 start_time_iso 和 end_time_iso 是 RFC3339 时间戳,跨度最多为 24 小时。可选的 variables 包含标量覆盖值;否则使用仪表板值和内置默认值。

{
  "id": "dashboard-id",
  "ops": [{"op": "update_panel", "panel_id": "panel-id", "fields": {"name": "Request latency"}}],
  "start_time_iso": "2026-10-01T08:00:00Z",
  "end_time_iso": "2026-10-01T09:00:00Z"
}

返回 saved: false、定义/查询 validation 摘要(包括创建架构不匹配时的 definition_error),以及包含 ok / empty / error 状态、已解析查询和目标诊断信息的 panels。PromQL 和 LogJSON 会执行;不支持的查询类型和无法解析的变量会使面板报错。有效的非查询面板为 ok;无效的面板定义为 error。补丁 diff 包含净 panels_added、panels_changed(包括移动)和 panels_removed,以及按顺序排列的操作变更。ID 和从零开始的索引用于标识面板;已移除面板的索引指向原始仪表板。已保存的面板必须具有互不相同且非空的 ID。

限制:50 个面板、100 个查询、100 个操作;输入和候选仪表板的 JSON 字节数各不超过 65536;执行时限为 60 秒。超过 65536 个 JSON 字节的已解析查询会在执行前被拒绝。每个目标最多保留三个样本和 1024 个 JSON 字节;省略样本时会包含 truncated: true。超过 262144 字节的 JSON 报告会失败,并提示缩减输入。

不会创建或更新任何仪表板。此操作会根据创建架构检查候选内容,并使用现有验证器执行查询;但不能保证后端接受或正确渲染。后端分配的 ID、默认值、被丢弃的字段或并发编辑都可能改变保存结果。预览使用与写入相同的本地补丁操作和面板版本默认值。

create_dashboard

仅用于新建。此调用返回 dashboard.id 后,请使用 patch_dashboard 编辑面板(或使用 update_dashboard 调整结构)——不要再次创建仪表板来添加、精简或修复面板。

  • dashboard(对象,必填):包含 name 和 panels[] 的仪表板定义。每个面板都必须包含 name、version、layout(x、y、w、h)、visualization.type 和 queries[]。
  • metadata(对象,可选):仪表板元数据字段——_category 和 _type(例如 {"_category":"custom","_type":"metrics"})。

update_dashboard

仅用于重构仪表板的大部分内容;如需添加、编辑、移除或移动单个面板,请使用 patch_dashboard。按 ID 完整替换(正文与创建时相同):必须重新发送每个面板。

  • id(字符串,必填):要更新的仪表板 UUID。
  • dashboard(对象,必填):完整替换用的仪表板正文(结构与创建时相同)。
  • metadata(对象,可选):替换用的元数据。只读系统仪表板会返回可恢复的工具错误。

patch_dashboard

小幅调整时优先使用此工具,而不是 update_dashboard:不会重新发送未更改的面板。读取仪表板,按顺序应用 ops,然后写回;因此,在读取和写入之间由其他位置进行的编辑会被覆盖。返回 {dashboard_id, changes[]};仪表板已满足的操作会被省略,如果没有任何变更,则不会写入。写入后会通过重新读取来检查差异:面板 fields 显示已存储的值,not_stored 列出 API 丢弃的键,not_removed 列出 API 在收到 null 后仍保留的键。超过 200 个字符的差异值会原地缩短,同时保留其 JSON 类型。

  • id(字符串,必填):要修补的仪表板 UUID。
  • ops(数组,必填):按顺序应用的操作;如果任何操作无效,则不会写入,并会在错误中将其标记为 ops[i]。
    • add_panel:panel(完整面板对象;version 默认为 1),可选的 index(从零开始的插入位置,默认追加)。
    • update_panel:panel_id、fields(要替换的顶层面板键;null 会移除键;id 不可更改)。
    • remove_panel:panel_id。
    • move_panel:panel_id、index(移动后的从零开始的位置)。
    • set_title:title(仪表板名称)。
    • set_variable:variable;替换具有相同 target 的变量,否则追加。

delete_dashboard

  • id(字符串,必填):要删除的仪表板 UUID。无法删除只读系统仪表板。

set_dashboard_lock

  • id(字符串,必填):仪表板 UUID。
  • locked(布尔值,必填):true 会锁定仪表板,false 会解锁仪表板。

写入工具;仅在用户明确提出要求时调用。只有仪表板作者或组织管理员可以锁定或解锁仪表板,内置仪表板始终为只读。返回包含最终状态的 {"id", "locked"}。锁定期间,update_dashboard、patch_dashboard 和 delete_dashboard 不会发送写入请求,并会返回可恢复的工具错误;错误以 dashboard is locked 开头,指出作者,并建议解锁或使用 create_dashboard 复制仪表板。

list_dashboard_snapshots

  • dashboard_id(字符串,必填):要列出快照的仪表板 UUID。

仅返回元数据(id、name、expires_at 等)。如需获取冻结的面板数据,请使用 get_dashboard_snapshot。

get_dashboard_snapshot

  • id(字符串,必填):快照 UUID。

返回完整的冻结快照,包括 dashboard_definition、panel_data、time_range 和 variables。

delete_dashboard_snapshot

  • id(字符串,必填):要删除的快照 UUID。

get_profile_services

  • lookback_minutes / start_time_iso / end_time_iso(可选):时间范围;优先使用回溯时长或明确的 ISO 边界(默认 60m)。
  • region(字符串,可选):区域覆盖值。

返回在该时间范围内有性能分析数据的服务。在调用 get_flamegraph / get_top_functions / get_profile_summary 之前先调用此工具。

get_flamegraph

  • service(字符串,必填):来自 get_profile_services 的服务名称。
  • profile_type(字符串,可选):cpu(默认值)、alloc 或 wall。比较不同时间范围时请固定类型。
  • env / cluster / namespace / runtime(字符串,可选):范围筛选条件。
  • limit(数字,可选):聚合堆栈行数上限(默认 1000,最大 10000)。
  • lookback_minutes / start_time_iso / end_time_iso / region(可选)。

返回嵌套的火焰图树(name / value / self / children)。truncated: true 表示已达到 API 行数上限。

get_top_functions

筛选条件与 get_flamegraph 相同。返回按自身采样数排序的热点函数。结果可能被截断;请检查 truncated。

get_profile_summary

筛选条件与 get_flamegraph 相同。返回针对该服务性能分析数据的简短自然语言分诊摘要。

grafana_search_dashboards

  • query(字符串,可选):标题子字符串。为空时会广泛列出(受 5,000 行上限约束)。

返回包含 uid、title、uri、url、type、tags 的 {"dashboards":[…], "truncated":bool}。请将 uid 与 grafana_get_dashboard 配合使用。

grafana_get_dashboard

  • uid(字符串,必填):Grafana 仪表板 uid。
  • full_json(布尔值,可选):为 true 时,返回原始 Grafana JSON,而不是经过筛选的摘要。

默认摘要:版本、标签、模板变量,以及每个面板的类型/数据源/gridPos/promQL 目标。未知的插件面板类型会显示在 unsupportedPanelTypes 中。

grafana_list_folders

无参数。返回文件夹树。

grafana_list_folder_dashboards

  • folder_uid (string, required): Grafana 文件夹 uid。

返回该文件夹中仪表板的 {"dashboards":[…], "truncated":bool}(分页,最多 5,000 个)。

grafana_list_datasources

无参数。返回数据源的安全投影(不包含凭据字段)。


测试

运行测试 goroutine 分析器,但不执行应用程序测试:

make lint-test

这会对所有软件包运行 Go 的 testinggoroutine 分析器,包括其 *_test.go 文件,并使用不安全和安全的测试样例进行检查。两个 CI 测试 工作流都会将 go vet -testinggoroutine ./... 作为单独步骤运行,因此缓存的 软件包测试结果无法绕过 lint 检查。

根软件包也会将该分析器作为测试运行。使用 go test -count=1 ./... 运行完整测试套件并禁用该检查的缓存:Go 的测试缓存不会跟踪分析器子进程读取的 内部软件包源文件。修改这些文件后,普通的 go test ./... 可能会复用根测试之前通过的结果。

Fatal、Fatalf 和 FailNow 在 testing.T 或 testing.B 上必须在 父测试 goroutine 中运行。工作线程应将错误发送回父线程,以便父线程进行断言:

errs := make(chan error, 1)
go func() { errs <- doWork() }()
if err := <-errs; err != nil {
    t.Fatal(err)
}

该分析器会捕获 go func 闭包中的直接调用;它不是通用的跨过程检查,无法检测隐藏在任意辅助函数调用后的断言。 除非设置了 TEST_REFRESH_TOKEN,否则集成测试会跳过。


MseeP.ai Security Assessment Badge