端点数据查询服务器

为Fleet端点安全平台提供模型上下文协议(MCP)接口,使AI系统能够原生查询主机数据、运行实时查询并检查策略合规性。

  • by karmine05
  • Go
  • 本地部署
  • 4 星标
  • 更新于
在 GitHub 查看 karmine05/fleet-mcp

使用说明

舰队MCP服务器🚀

A. 模型上下文协议(MCP) 服务器 舰队 端点安全平台。

转变您与端点数据的交互方式。查询osquery,检查合规性,深入了解每台主机的策略结果,并从Claude、Cursor和任何兼容MCP的AI代理本地调查CVE。

🔗 GitHub回购: https://github.com/fleetdm/fleet/tree/main/cmd/fleet-mcp 🔗 了解MCP: https://modelcontextprotocol.io/ 🔗 了解舰队: https://fleetdm.com/


📺 在行动中看到它

观看1小时的演练,演示如何使用Claude Desktop在整个机群中即时编写和运行实时操作系统查询。

概述

此服务器为Fleet提供MCP接口,使AI系统(Claude Desktop、Claude Code、Cursor和任何兼容MCP的客户端)能够与您的Fleet部署进行本地交互。它公开的不是原始的API端点,而是类型化的 工具 AI代理可以直接调用——列出具有丰富服务器端过滤器的主机,深入了解每台主机的策略合规性,查找受CVE影响的主机,运行实时osquery等等。

两者 上海证券交易所 (服务器发送的事件)和 标准 支持运输。同一刀具表面在两者上的暴露方式相同。

工具

服务器跨四个域公开工具: 主机文件, 查询, 政策/漏洞,以及 库存其中之一(run_live_query)在设备上运行任意osquery,因此相应地确定Fleet API令牌的范围(请参阅 安全模型).

主机

工具 说明
get_endpoints 使用丰富的服务器端筛选器列出Fleet中注册的主机/端点(fleet, platform, status, query, label, policy_id, policy_response, per_page).所有过滤器都组合在一起——精确地缩小范围,而不是在客户端分页,并返回 total 反映了筛选的范围,而不是全局库存。这 query 仅参数就涵盖了主机名/序列号/主IP/硬件型号/用户清单(用户名、电子邮件、IdP组)。
get_host 获取单个主机的完整详细信息,包括标签、机群、硬件序列号、主IP和平台信息。接受数字 host_id (最精确地说,绕过任何主机名冲突)或 identifier (确切的主机名/UID/序列号/computer_name,或模糊的子字符串)。当标识符与多个主机(例如共享主机名)匹配时,返回一个候选列表,其中包含每个主机的id/hostname/display_name/serial/primary_ip/fleet,以消除歧义。
get_host_policies 获取应用于单个主机的每个策略的合规性状态(全局+继承的机队)。返回每个策略及其 response 现场(pass / fail / "" 尚未运行)加上摘要块(failing_count, passing_count, not_run_count, total).镜像Fleet UI的每台主机策略选项卡。接受 host_id (首选)或 identifier,具有与相同的消歧行为 get_host.支持可选 response 过滤到只通过或失败。
get_total_system_count 活动注册系统总数
get_aggregate_platforms 按操作系统平台(macOS/Windows/Linux等)细分的系统计数
get_fleets 列出所有车队及其ID和名称
get_labels 列出所有端点标签

查询

工具 说明
get_queries 列出所有已保存的车队查询(全局+每个车队)
prepare_live_query 第1步(共2步):验证目标并返回编写有效SQL语句所需的osquery模式
run_live_query 第2步(共2步):对实时Fleet设备执行osquery SQL语句。 模式优先合同:呼叫者必须呼叫 get_osquery_schema (或 prepare_live_query)第一;SQL已针对规范列类型进行了预验证——TEXT与纯整数比较被拒绝。目标通过直接选择器解析服务器端,如 hostnames / host_ids 交叉滤波器包括 fleet, platform, label, status, query, policy_id, policy_response,以及 cve_id. 舰队范围:当 fleet 设置后,只有该舰队中的主机是目标。
get_osquery_schema 返回Fleet/osquery表的规范真值源模式。来源于Fleet monorepo schema/osquery_fleet_schema.json (也呈现于 https://fleetdm.com/tables)并在后台刷新——列TYPES总是准确的。默认为经过筛选的精选短名单 platform;通行证 tables (逗号分隔)以获取360多个表中任何一个的完整规范覆盖率。
refresh_osquery_schema 从强制刷新内存中的架构 https://raw.githubusercontent.com/fleetdm/fleet/main/schema/osquery_fleet_schema.json.使用时 get_osquery_schema 返回与实时Fleet文档冲突的数据。背景刷新处理常规漂移;此工具用于罕见的手动超控。
get_vetted_queries 获取适用于macOS、Windows和Linux的100%经过审查的生产安全CIS-8.1策略查询库

政策和漏洞

工具 说明
get_policies 列出所有策略(全局+每个机队)及其通过/失败主机计数
get_policy_compliance 获取特定策略的通过/失败计数。默认为全局聚合;过 fleet 将范围扩展到单个车队(与车队UI中的每个车队计数相匹配)。
get_policy_hosts 列出通过或未通过给定策略的主机,可选择按以下方式缩小范围 fleet, platform, label, status, query。使用此选项回答“哪些Linux主机未通过策略42?”——所有过滤器维度都组成服务器端。
get_vulnerability_impact 受CVE影响的系统总数
get_vulnerability_hosts 列出受CVE影响的特定主机,可选择按以下方式缩小范围 fleet, platform, label, status, query.编写一个3步查找(/software/titles?vulnerable=true&query=CVE → 易受攻击的版本ID→ /hosts?software_version_id=N)并与客户端相交。之所以需要,是因为舰队 /hosts?cve= 和 /hosts?platform= 过滤器被默默地忽略了——请参阅操作学习部分。

库存

这些从Fleet存储的主机清单中读取(在每次主机登记时刷新),因此它们回答“安装了什么/谁有帐户” 没有 实时osquery查询——它们甚至适用于当前离线的主机。

工具 说明
get_software 列出Fleet存储库存中的软件/软件包。两种模式,自动选择: 每台主机 (通过 host_id 或 host_identifier)通过以下方式返回该主机上的每个包及其版本/源代码/安装路径/匹配的CVE /hosts/:id/software; 跨主机 (无主机arg)通过以下方式返回跨主机看到的软件TITLES /software/titles --默认情况下为完整库存,可选范围如下 fleet / vulnerable (以及 platform,这需要 fleet:Fleet的头衔端点仅按平台和团队过滤)。这 source arg(例如。 npm_packages, python_packages, apps, deb_packages, chrome_extensions)是针对osquery源表名的客户端不区分大小写的过滤器。使用 query 对于软件名称或CVE id的子字符串匹配。更喜欢这样 run_live_query 用于库存查找——缓存,始终可用,没有主机CPU。
get_host_users 按osquery(uid、用户名、类型、组名、shell)列出单个主机上的操作系统本地用户帐户。接受 host_id (首选)或 host_identifier (相同的消歧 get_host).可选的 query substring在username/uid/groupname/shell之间过滤客户端返回的用户。

过滤器尺寸一览

维度 如何过滤 备注
用户/IP/主机名 query= substring 一个字段——Fleet的子字符串匹配器涵盖了所有这些以及serial/model。
显示名称 无法通过搜索 query 使用 host_id 直接(从候选人名单或之前的电话中)。这 /hosts/identifier/:id 端点也匹配 computer_name 确切地说,它通常等于显示名称。
舰队 fleet=<name> 服务器端已解决为 fleet_id.
标签 label=<name> 服务器端已解决为 label_id仅限单标签-Fleet的API不接受多标签交叉。
政策结果 policy_id=<id> + policy_response=passing|failing policy_response 需要 policy_id否则在MCP层被拒绝。
平台/状态 platform= / status= 标准车队主机过滤器。

主机名冲突和host_id

Fleet允许多个主机共享一个 hostname (例如,几台Mac都在报告 hostname=mac).舰队的 /hosts/identifier/:id 端点默默地返回其中一个,这曾经意味着策略查找可能会悄悄地针对错误的主机。当前的工具通过 先查询 解析器:

  1. 如果你通过 host_id (数字),它直接指向 /hosts/:host_id --确切地说,不可能发生碰撞。
  2. 否则,该工具将首先进行子字符串搜索。一场比赛→ 按ID获取。多个匹配项→ 返回每个主持人的候选人列表 id, hostname, display_name, hardware_serial, primary_ip,以及 fleet_name.零匹配→ 退回到 /hosts/identifier/:id (捕获UUID和 computer_name-只有比赛)。

如果你的人工智能代理收到候选人名单,它应该选择正确的 id 并再次致电 host_id仅显示名称的主机(用户友好的显示名称与任何索引字符串字段都不匹配)最好使用以下方式获取 host_id 从一开始。

配置

使用环境变量或 .env 文件(与二进制文件位于同一目录中)。

变量 默认值 描述
FLEET_BASE_URL (必填) Fleet实例的基本URL,例如。 https://your-fleet.example.com
FLEET_API_KEY (必填) 舰队API令牌-请参阅 舰队文件. 使用涵盖您的工具的特权最低的Fleet角色: 一 观察者 / 观察员+ 令牌足以用于所有工具- 管理员不是必需的
MCP_AUTH_TOKEN (必填) 用于验证MCP客户端的承载令牌。生成方式 openssl rand -hex 32 (最少32个字符--服务器拒绝较弱的字符). 每次运输(包括stdio)都需要;服务器拒绝在没有它的情况下启动。 在SSE模式下,服务器在每次请求时都会对其进行验证;在stdio模式下,必须对其进行设置,但在运行时不进行检查(客户端将二进制文件作为本地子进程启动)。
PORT 8080 用于SSE传输的HTTP端口。在stdio模式下忽略。Render会自动注入此内容。
LOG_LEVEL info 日志冗长: debug / info / warn / error.注: debug 记录每个Fleet API调用的路由形状(仅查询字符串之前的路径-没有PII标识符)。避免 debug 在生产部署中,日志被运送到集中式聚合器。
FLEET_TLS_SKIP_VERIFY false 跳过TLS证书验证。 硬门控到本地主机——服务器拒绝使用此设置和非环回启动 FLEET_BASE_URL. 与冲突 FLEET_CA_FILE.
FLEET_CA_FILE (可选) 自签名Fleet实例的PEM CA证书路径
FLEET_LIVE_QUERY_REST_PERIOD 25s 多长时间 run_live_query 等待主机报告后返回。接受任何Go持续时间字符串(例如。 25s, 1m).一旦每个在线主机都做出响应,多主机运行就会提前停止;这是等待的上限。在Fleet服务器上镜像相同的变量——保持该变量≥服务器的值,这样MCP在服务器完成活动之前就不会放弃。

复制提供的模板:

cp .env.example .env
# Edit .env with your Fleet URL, Fleet API key, and a freshly generated MCP_AUTH_TOKEN

克劳德桌面(stdio)注意事项: Claude Desktop从中读取环境变量 env 块 claude_desktop_config.json, 不 从一 .env 文件。看 标准运输 部分。

安装

先决条件

  • 转到1.25.7+
  • 跑步 舰队 例子
  • 具有适当读取权限的Fleet API令牌

构建

git clone https://github.com/fleetdm/fleet
cd fleet/cmd/fleet-mcp
go mod tidy
go build -o fleet-mcp .

生成MCP身份验证令牌

openssl rand -hex 32

将输出用作 MCP_AUTH_TOKEN 在你的 .env (SSE)或您的Claude桌面配置(stdio)。

用法

SSE传输(克劳德代码、游标、web客户端)

启动服务器——它将监听SSE连接:

./fleet-mcp
# transport: SSE — listening on :8080

配置您的MCP客户端以连接到 http://localhost:8080/sse 并且包括承载令牌。对于 Claude 代码,添加到您的项目 .mcp.json 或您的全局MCP配置:

{
  "mcpServers": {
    "fleet": {
      "type": "sse",
      "url": "http://localhost:8080/sse",
      "headers": {
        "Authorization": "Bearer <your-MCP_AUTH_TOKEN>"
      }
    }
  }
}

对于远程部署(例如Render):

{
  "mcpServers": {
    "fleet": {
      "type": "sse",
      "url": "https://your-fleet-mcp.onrender.com/sse",
      "headers": {
        "Authorization": "Bearer <your-MCP_AUTH_TOKEN>"
      }
    }
  }
}

标准传输(克劳德桌面)

Stdio模式直接将二进制文件作为子进程运行——没有网络端口,不用担心TLS,所有通信都通过stdin/stdout JSON-RPC进行。

  1. 构建二进制文件:

    go build -o fleet-mcp .
    
  2. (仅限macOS)对二进制文件进行临时签名 所以看门人在更换后不会杀死它。 Apple Silicon每次重建后都需要 --如果没有这个,将新构建的二进制文件复制到同一路径上的现有二进制文件上可能会导致静默崩溃或 exit 137:

    codesign --force --sign - ./fleet-mcp
    
  3. 编辑 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

    {
      "mcpServers": {
        "fleet-mcp": {
          "command": "/absolute/path/to/fleet-mcp",
          "args": ["-transport", "stdio"],
          "env": {
            "FLEET_BASE_URL": "https://your-fleet.example.com",
            "FLEET_API_KEY": "YOUR_FLEET_API_KEY",
            "MCP_AUTH_TOKEN": "YOUR_MCP_AUTH_TOKEN",
            "LOG_LEVEL": "info"
          }
        }
      }
    }
    

    使用A 绝对路径 为了 command.相对路径和 ~ 没有扩展。

  4. 完全退出并重新启动Claude Desktop (Cmd+Q,而不仅仅是关闭窗口)。所有工具都将出现在您的上下文中。

不带克劳德桌面的烟雾测试标准模式

您可以直接通过stdio JSON-RPC驱动二进制文件进行调试:

export FLEET_BASE_URL="https://your-fleet.example.com"
export FLEET_API_KEY="..."
export MCP_AUTH_TOKEN="..."

cat <<'EOF' | ./fleet-mcp -transport stdio
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_total_system_count","arguments":{}}}
EOF

替换 tools/call 使用任何工具的线,例如。 get_host_policies 与 host_id.

-seed 旗帜

该二进制文件还支持单次种子模式,该模式使用此仓库附带的标准保存查询集加载Fleet,然后退出:

./fleet-mcp -seed

这为开发人员提供了便利——跳过它即可正常使用MCP服务器。

工具注释和Claude桌面

这里的每个工具都附带了明确的MCP注释:

  • readOnlyHint --这个工具是只读还是会写?
  • destructiveHint --它能变异或删除数据吗?
  • idempotentHint --重复呼叫是否具有相同的效果?
  • openWorldHint --它是与远程系统通信,还是仅以二进制数据进行咨询?

如果没有这些,Claude Desktop会保守地将破坏性行动审查背后的每个工具都关起来,并可能将表面折叠成一个工具。只读工具带有注释 readOnly=true, destructive=false, idempotent=true 因此AI代理可以自由使用它们。 注: 这些注释是行为良好的客户端所遵循的建议性提示(例如,在破坏性工具之前的Claude Desktop提示)——它们不是服务器端控件。真正的控制权是 FLEET_API_KEY 角色(使用最小特权/观察者令牌;请参阅 安全模型).

一种工具具有明显的破坏性,需要MCP客户端的用户批准:

工具 注释 为什么具有破坏性
run_live_query readOnly=false, destructive=true, idempotent=false 通过临时活动对每个目标设备发起osquery,消耗设备CPU,并显示在EDR遥测中。即使是仅使用SELECT的SQL在舰队规模上也具有操作破坏性。

这意味着Claude Desktop将在启动之前显示一个确认提示,这是运营商的Fleet API令牌可以运行实时查询(observer-plus或更高版本)的任何生产部署所必需的。

安全模型

MCP持有操作员的 FLEET_API_KEY 并且与该令牌的Fleet角色完全一致——具有可以运行实时查询的角色(观察者加或更高),MCP的妥协为攻击者提供了完整的主机清单访问权限,以及对每个注册设备的任意osquery。防御:

  • 在前面终止TLS(SSE侦听器是纯HTTP)。 服务器在上讲HTTP PORT,所以 MCP_AUTH_TOKEN 承载者和所有流量 电报上的明文。对于任何非环回部署,请在TLS终止层后面运行它: 渲染器的边缘已经做到了这一点;对于自托管/专用网络部署,请在前面放置一个反向代理(nginx/Caddy/CCloudflare),并且只公开HTTPS端点。这 stdio 传输不受影响(无网络跳转)。
  • TLS跳过验证硬门控到本地主机。 FLEET_TLS_SKIP_VERIFY=true 与非环回配对 FLEET_BASE_URL 使二进制文件拒绝启动(logrus.Fatalf)--复制dev .env 远程部署不能再将Fleet令牌暴露给在线攻击者。
  • 强壮的 MCP_AUTH_TOKEN 强制执行。 如果发生以下情况,服务器将拒绝启动 MCP_AUTH_TOKEN 短于32个字符——高熵令牌是对承载暴力的真正防御(openssl rand -hex 32 满足它)。
  • 速率限制/DoS保护属于上游。 MCP不运行自己的限制器——Fleet通常运行在终止TLS(如上所述)并限制请求的反向代理/边缘后面,这是每个客户端速率限制的所在(Render的边缘;或反向代理/WAF,如nginx/Caddy/CCloudflare)。强者 MCP_AUTH_TOKEN 是暴力防御,失败的身份验证请求在到达舰队之前会被MCP拒绝。
  • 仅需要API令牌。 启动时,MCP调用 GET /api/v1/fleet/me 和 拒绝开始,除非 FLEET_API_KEY 属于仅限API的震源组用户.仅限API的用户没有UI会话,没有自己的审核身份,并且通过Fleet的每个用户角色/团队范围界定,可以锁定到MCP所需的端点(和团队/车队),在MCP的承载身份验证之上添加Fleet侧授权边界。失败关闭:如果 /me 无法确认MCP不会启动的主体(舰队无法访问或令牌无效)。要创建一个具有正确访问权限的,请参阅Fleet的文档: 仅创建API用户, 只有API的用户可以访问的端点,以及 使用 fleetctl 具有仅使用API的用户.
  • 读取vs运行=令牌的舰队角色。 MCP的作用正是 FLEET_API_KEY (它没有自己的模式),Fleet强制执行。只读工具与 观察者 代币;一个变异工具, run_live_query,需要 observer_plus (或管理员/维护人员/技术人员)根据Fleet的RBAC——观察者令牌将获得 403. 不需要维护者或管理员角色。 建议:具有的仅限API的用户 最低角色 你的工具需要-- 观察者 对于只读部署, observer_plus 如果你使用 run_live_query.MCP不推断或记录这些权限-它只强制执行上面的仅限API的要求。
  • 实时查询运行任意osquery(范围令牌)。 run_live_query 将任意osquery分派给设备——就像Fleet自己的UI一样/ fleetctl /由MCP代理的实时查询REST API。表格,如 curl / curl_certificate / carves 可以发出出站请求或从受管设备泄露文件内容(例如云元数据凭据)。 这是一种舰队/作战系统查询功能,并非特定于MCP --MCP没有(也不应该)特殊情况。MCP层控制是 最低特权 FLEET_API_KEY (观察员令牌→ Fleet完全拒绝实时查询)。为了移除所有地方的功能(UI, fleetctl、scheduled、MCP),禁用osquery代理上的表: --disable_tables=curl,curl_certificate,carves,yara,yara_events 通过fleetd/orbit代理选项。
  • SSE运输工具上的车身尺寸盖。 http.MaxBytesReader 将每个传入请求体的大小限制为1 MiB。敌对客户端无法通过超大JSON-RPC有效载荷对MCP进行OOM。
  • HTTP服务器超时。 ReadHeaderTimeout=10s, ReadTimeout=30s, IdleTimeout=120s 击败斯洛洛里斯式头球/身体饥饿。
  • 启动时已保存查询清除程序。 任何 fleet-mcp-temp-* 上次运行遗留的已保存查询(其延迟删除在崩溃或5xx期间失败)将在下次MCP启动时删除。临时查询名称使用 crypto/rand 后缀,这样并发调用就不会发生冲突。
  • PII安全调试日志。 机队API调用日志已更改为仅记录路线形状(任何 ? 查询字符串)--主机序列号、通过传递的用户电子邮件 ?query=,CVE ID不再泄漏到调试日志中。
  • MCP层的CVE/policy/par_page输入验证。 cve_id 必须匹配 ^CVE-\d{4}-\d{4,}$, policy_id 必须是正整数, per_page 被夹紧到200。不正确的输入在任何Fleet API调用之前都会得到一条可用的错误消息。
  • 端到端的上下文传播。 每个FleetClient方法都需要 ctx context.Context;MCP处理程序取消传播到飞行机队API调用,包括扇出路径的迭代之间(CVE组成,标签交叉)。取消的MCP请求会停止整个扇出,而不是将剩余的每个HTTP调用都运行到完成。

部署以渲染

cmd/fleet-mcp/render.yaml 是独立于根的渲染蓝图 render.yaml 由主要舰队服务使用。

  1. 推 cmd/fleet-mcp/render.yaml 到你的仓库。
  2. 在“渲染”仪表板中,转到 New → 蓝图.
  3. 连接您的仓库并设置 蓝图文件路径 到 cmd/fleet-mcp/render.yaml.
  4. 在设置过程中,填写以下环境变量:
    • FLEET_BASE_URL --Fleet实例的URL
    • FLEET_API_KEY -舰队API代币
    • MCP_AUTH_TOKEN --生成与 openssl rand -hex 32
  5. PORT 由Render自动注入,无需任何操作。
  6. 健康检查:将Render(或任何编排器)的探测器指向 GET /healthz --它回来了 200 ok 未经身份验证,因此在负载下保持绿色。

发展

项目布局

cmd/fleet-mcp/
  main.go                  # entrypoint, flag parsing, transport selection, http.Server timeouts, body-size cap
  config.go                # env-var loading
  auth.go                  # bearer-auth middleware (SSE)
  route_guard.go           # SSE route allow-list
  fleet_integration.go     # FleetClient — wraps Fleet REST API. Every method takes ctx context.Context as first param.
  mcp_server.go            # SetupMCPServer orchestrator
  mcp_helpers.go           # getOptionalString, parseCSVArg, parsePerPageArg, validateCVEID, parsePositiveUintString, jsonResult
  mcp_tools_hosts.go       # host-domain MCP tools
  mcp_tools_queries.go     # query-domain MCP tools
  mcp_tools_policies.go    # policy/vuln MCP tools
  mcp_tools_inventory.go   # inventory MCP tools
  schema.go                # canonical osquery schema (embedded fallback + live HTTP refresh from raw.githubusercontent.com/fleetdm/fleet/main/schema/osquery_fleet_schema.json) and ValidateSQLForPlatforms (table-vs-platform + TEXT-column type sniff)
  osquery_fleet_schema.json # vendored canonical snapshot (//go:embed source-of-truth fallback). Refresh via `go generate ./cmd/fleet-mcp/...`.
  vetted_queries.go        # vetted CIS-8.1 query library
  seed_fleet.go            # -seed mode

架构层的可调参数(环境变量):

  • FLEET_MCP_SCHEMA_REFRESH_INTERVAL --刷新后台goroutine的节奏,接受任何 time.Duration 字符串(例如。 6h, 30m).默认 24h.
  • FLEET_MCP_SCHEMA_REFRESH_DISABLE --设置后,实时刷新goroutine不会启动,二进制文件仅使用嵌入式快照。适用于气隙环境。

添加新工具

  1. 添加一个方法 FleetClient 在 fleet_integration.go 封装Fleet API调用。
  2. 选择正确的域文件(mcp_tools_hosts.go, mcp_tools_queries.go, mcp_tools_policies.go,或 mcp_tools_inventory.go)并添加a register<ToolName> 功能。
  3. 将新的寄存器功能连接到匹配中 register<Domain>Tools 编排器位于同一文件的顶部。
  4. 始终设置 readOnly / destructive / idempotent 注释,以便克劳德桌面可以为其做广告。
  5. 构建并运行烟雾测试 烟雾测试标准模式 部分。

操作学习

在构建过程中发现了一些不明显的行为:

  • ?query= 子字符串匹配包括主机名、序列号、主IP、硬件型号和主机用户(用户名/电子邮件/IdP组) --但是 不 显示名称。使用 host_id 用于仅显示名称的查找。
  • /hosts/identifier/:id 匹配的内容比文档所声称的要多: 除了主机名/UID/serial之外,它还匹配 computer_name 确切地。这就是为什么用户设置的计算机名会在标识符端点上解析,即使 ?query= (它没有索引 computer_name)与之不匹配。
  • 主机名冲突是真实存在的 在任何规模庞大的舰队中。总是喜欢 host_id 当你有它的时候。子字符串解析器最多返回50个候选者 display_name / serial / primary_ip 为了消除歧义。
  • policy_response 需要 policy_id API水平。MCP层以一个干净的错误预先拒绝了孤儿组合,而不是让Fleet返回一个模糊的400。
  • 舰队的 /hosts 端点默默地忽略了我们测试的几个过滤器参数。 截至舰队4.85,通过 cve=CVE-X, platform=linux,或 label_id=N 到 GET /hosts 没有错误地被接受,但返回未过滤的主机列表——MCP不能依赖这些。此仓库中提供的解决方案:
    • 平台/标签范围 路线通过 GET /labels/:id/hosts (这确实是一种荣誉 fleet_id 和 query,但也忽略了 software_version_id 和 policy_id,因此策略+标签交集是通过主机ID在客户端计算的)。
    • get_endpoints total 作用域为相同的筛选器 作为上市,而不是全球库存:它来自 GET /hosts/count 具有相同的参数(label_id 标签/平台),标签除外+ policy_id 组合在哪里 /hosts/count 忽略 policy_id --这里的计数是相同客户端标签∩策略交集的大小。
    • CVE → hosts 是一个三步组合 GetHostsForCVE: GET /software/titles?vulnerable=true&query=CVE-X → 按标题 GET /software/titles/:id 获取易受攻击的版本ID→ GET /hosts?software_version_id=N 按ID→ 与客户端的舰队/状态/查询/标签id相交。
    • 一个电话 GET /hosts?cve= 故意不使用路径,因为它返回错误的结果(例如CVE-2025-12345通过以下方式生成50个主机 ?cve=,但正确答案是1)。
    • 未来的舰队版本可能会修复这些问题——重访 GetEndpointsWithFilters 和 GetHostsForCVE 如果/当这种情况发生时。
  • 车队范围的政策合规性 用途 /fleets/:fleet_id/policies/:policy_id而不是全球道路。 get_policy_compliance 根据是否确定路线 fleet 已设置。
  • /api/v1/fleet/host_summary 是聚合平台计数的正确端点 — GET /hosts 默认为100个主机页面,因此任何客户端聚合 GetEndpoints(0) 在超过100个主机的Fleets上,这是一个无声的错误。 get_aggregate_platforms 用途 host_summary 直接使总计与任何库存规模的Fleet UI匹配。
  • fetchHostsFromPath 内部分页 带着一顶硬帽子(fetchHostsHardCap = 10000).如果没有这个,一次调用就可以缓冲内存中的全部主机库存(每个端点约2KB×50k主机≈100MB),并对MCP进行OOM。当cap触发时,会记录一个警告,以便操作员看到截断,而不是默默地获取部分主机集。
  • 按车队扇出(get_queries, get_policies)是有界并发的。 8架机上飞机,按机队指数稳定合并。在拥有50多个车队的企业车队实例上,顺序路径是主要的延迟源;有界并发在不让Fleet被数千个并发请求淹没的情况下,摊销了往返次数。
  • CSV参数删除空段。 parseCSVArg("foo,,bar") 回报 ["foo", "bar"] --传统的拆分和修剪行为将零值字符串泄漏到过滤器逻辑中,前导空段可能会默默地禁用读取的过滤器 parts[0].
  • macOS网守缓存临时签名 已键入文件标识。替换同一路径上的二进制文件会自动使缓存的批准无效--重新运行 codesign --force --sign - 每次重建后,Claude Desktop都会启动它。
  • 克劳德桌面阅读 env 从JSON配置,不是从a .env 文件。这 .env 此仓库中的模板仅用于SSE/本地开发。

许可证

麻省理工学院