mcpField
S
secobserve-mcp

secobserve-mcp

本地服务
github.com/nh4ttruong安全15 周前更新

关于 secobserve-mcp

secobserve-mcp 将 SecObserve 的 REST API 提供给 MCP 客户端,供安全团队处理发现项和管理产品数据。它以资源为中心组织工具,并支持审批流程和 VEX 生成。

主要功能

  1. 01浏览并分诊观察项
  2. 02管理产品、分支和规则
  3. 03导入扫描报告与 SBOM
  4. 04触发扫描和后台任务
  5. 05生成 CSAF、OpenVEX 和 CycloneDX VEX
  6. 06审批流程与审计日志

适用场景

  1. 01审查并评估未处理的漏洞发现项
  2. 02导入扫描器报告和 SBOM 文件
  3. 03运行内置 OSV 或 VulnerableCode 扫描
  4. 04生成或修订 VEX 文档

MCP 相关

它将 SecObserve REST API 操作作为 MCP 工具和提示词提供,包括读取、增删改、评估、导入、扫描和 VEX 生成。默认使用 stdio,也支持 HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"nh4ttruong-secobserve": {
"command": "uvx",
"args": [
"secobserve-mcp"
],
"env": {
"SECOBSERVE_BASE_URL": "<SECOBSERVE_BASE_URL>",
"SECOBSERVE_API_TOKEN": "<SECOBSERVE_API_TOKEN>",
"SECOBSERVE_READ_ONLY": "<SECOBSERVE_READ_ONLY>",
"SECOBSERVE_ALLOW_DELETE": "<SECOBSERVE_ALLOW_DELETE>"
}
}
}
}
启动命令uvx secobserve-mcp
需要配置的环境变量
SECOBSERVE_BASE_URLSecObserve base URL without /api, e.g. https://secobserve.example.com
SECOBSERVE_API_TOKEN密钥SecObserve user or product API token
SECOBSERVE_READ_ONLYSet to true to refuse every write operation
SECOBSERVE_ALLOW_DELETESet to true to enable the delete tool; deletion cascades and is irreversible

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypisecobserve-mcp1.0.0
ocighcr.io/nh4ttruong/secobserve-mcp:1.0.0

工具

18

收录的工具列表 · 更新于 2 周前

参数类型必填说明
containsany否仅列出名称或摘要中包含此文本的资源(例如 'license'、'vex')。

详细介绍

README 配图

secobserve-mcp

面向 SecObserve 的 MCP 服务 — 由 Agent 进行分类、导入和管理

PyPI Python SecObserve License Glama

工具 • 安装 • 配置 • 与客户端注册 • 设计

secobserve-mcp 通过模型上下文协议向大模型 Agent 提供 SecObserve REST API:浏览并分类观察结果,管理产品、分支和规则,导入扫描报告与 SBOM,运行扫描和后台任务,以及生成 VEX 文档。默认使用 stdio 传输。该项目已列入官方 MCP 注册表,名称为 io.github.nh4ttruong/secobserve-mcp。

工具

共有 18 个工具,而不是每个端点一个。SecObserve 有约 50 个 REST 资源和约 40 个命名操作;如果每个都注册为一个工具,所耗费的上下文会超过其返回的数据量,因此 API 被建模为数据,工具则是访问这些数据的接口。

工具用途
secobserve_list_resources资源目录:列出所有资源、支持的动词和操作。不调用 API,因此可免费优先调用。
secobserve_describe_resource从运行实例的 OpenAPI 架构中读取精确的筛选条件、字段和枚举值。
secobserve_list / _get读取数据,支持筛选、排序、分页和字段投影。
secobserve_create / _update / _delete对目录中的任意资源执行 CRUD 操作。
secobserve_call_action涵盖大量不常用操作:apply_rules、copy、simulate、license_overview、导出。
secobserve_assess_observation对一条发现进行分类。写入观察日志,并遵循审批工作流。
secobserve_bulk_assess_observations对多达 250 条发现执行相同的评估。
secobserve_approve_observation_log批准或驳回待处理的评估(四眼原则)。
secobserve_product_metrics预聚合计数:当前数据、时间线、两个日期之间的变化,以及数据的过时程度。
secobserve_upload_file从磁盘导入扫描报告、SBOM 或 VEX 文档。
secobserve_api_import通过已保存的 API 配置拉取发现。该操作会阻塞;如果超时,会报告任务仍在运行以及查看其结果的位置。
secobserve_trigger_scan运行 SecObserve 内置的 OSV 或 VulnerableCode 扫描。超时行为相同。
secobserve_run_periodic_task触发后台任务,或列出已注册的任务。
secobserve_status版本、运行状况、公开设置、队列统计信息和 PURL 类型。
secobserve_vex_document生成或修订 CSAF / OpenVEX / CycloneDX 文档。

提示词

六个提示词,用于需要按顺序调用而非一次完成的工作。有人选择提示词时,才会按名称获取,因此不会产生每个会话的开销;而工具架构会在每次连接时发送。

提示词用途
triage-product处理某个产品的未解决发现,优先处理严重性最高且 fix_available 为真的发现,并逐一根据证据进行评估。
daily-changes查看本地午夜以来的变化:新增、解析器变更、已解决和人工评估的项目。
weekly-changes查看过去 7 天的相同动态,并按天细分。
daily-report查看今天各产品的计数、今天的变化以及仍未解决的项目。
weekly-report查看过去 7 天的相同三部分内容,供发送报告的人使用。
monthly-report查看月末统计数据和环比变化。

每个提示词都包含决定报告是否准确的注意事项:指标仅涵盖默认分支;如果作业尚未运行,则会返回 200,且所有计数均为零;没有任何筛选条件表示一个日历月;SecObserve 中没有到期日或 SLA。

安装

uvx secobserve-mcp --help

uvx 会下载并运行它,无需永久安装。在 VS Code 中:一键安装。

若要改为将其放到你的 PATH 中:

uv tool install secobserve-mcp

完成后,名称将由 uv tool 管理:直接运行 uvx secobserve-mcp 会始终运行固定版本的副本,不会发现更新的版本,因此请使用 uv tool upgrade secobserve-mcp 保持更新。 因此,下面的客户端配置使用 uvx secobserve-mcp@latest,它会在每次启动时向 PyPI 重新验证——每个客户端会话一次,而非每条命令一次。 --check 会有意使用不带版本限定的名称,因为它的作用是报告客户端实际运行的副本情况。

从代码检出目录进行开发:

uv venv && uv pip install -e ".[dev]"

配置

变量默认值说明
SECOBSERVE_BASE_URLhttp://localhost:8000基础 URL,不含 /api。
SECOBSERVE_API_TOKEN—用户或产品 API 令牌。建议设置。
SECOBSERVE_JWT—API 令牌的替代方案。
SECOBSERVE_TIMEOUT60秒。SecObserve 会在请求中导入和扫描,而超时不会取消这些操作;调高此值可直接从调用中获取计数。
SECOBSERVE_VERIFY_SSLtrue仅在使用自签名开发证书时设为 false。
SECOBSERVE_READ_ONLYfalse设为 true 时会拒绝所有非 GET 调用。
SECOBSERVE_ALLOW_DELETEfalse只有启用此项后,才可使用 secobserve_delete。
SECOBSERVE_IMPORT_DIR工作目录上传内容只能从此目录树中读取。
SECOBSERVE_EXPORT_DIR./secobserve-exports导出文件和 VEX 文档会写入此处。
SECOBSERVE_AUDIT_LOGtrue每次工具调用都会在 stderr 输出一行 JSON。设为 false 可关闭此功能。

创建用户 API 令牌:

curl -X POST "$SECOBSERVE_BASE_URL/api/authentication/create_user_api_token/" \
  -H "Content-Type: application/json" \
  -d '{"username": "you", "password": "...", "name": "mcp"}'

交给客户端之前,先检查连接配置:

uvx secobserve-mcp --check

它会打印实例版本、已认证用户、只读和删除功能是否启用,以及当前安装版本与 PyPI 最新版本的比较结果。 这是此服务唯一调用 pypi.org 的地方;只需发送一个短暂请求。如果索引无法访问,则会降级为仅输出一行信息。

作为容器运行

docker run --rm -p 8931:8931 \
  -e SECOBSERVE_BASE_URL=https://secobserve.example.com \
  -e SECOBSERVE_API_TOKEN=... \
  ghcr.io/nh4ttruong/secobserve-mcp \
  --transport http --host 0.0.0.0 --shared-identity

该镜像为 linux/amd64 和 linux/arm64 构建,以非 root 用户运行,并通过 GET /healthz 返回自身版本。 /healthz 仅用于存活检查,绝不会调用 SecObserve,因此后端故障不会导致该服务被重启。

必须指定 --shared-identity,且它不在镜像的默认命令中:令牌已写入环境,因此每个调用该端口的调用方都会以同一个 SecObserve 身份操作,而在有人确认这是预期行为之前,服务会拒绝通过 HTTP 启动。 随后,服务会拒绝所有写入,因为使用共享令牌进行的评估会在观察记录和四眼审批中记录错误的操作者。 docker run 的参数会替换 CMD,而不是扩展它,因此上面会重复指定传输标志。

请将其置于一个负责验证调用方身份的网关之后,并避免使用任何公共端口。 对于单个用户,通过 stdio 使用 uvx 更合适:一个进程、一个令牌,并且包含写入操作。

注册客户端

服务会打印自己的注册配置片段,因此下面的代码块都不需要手动复制:

uvx secobserve-mcp --print-config claude   # or: codex, vscode, json

它会从环境变量读取 SECOBSERVE_BASE_URL,并始终将令牌保留为占位符——该配置片段是供粘贴使用的,不应随附令牌。提示会输出到 stderr,因此运行 --print-config json > mcp.json 会写入干净的文件。

Claude Code
claude mcp add secobserve --env SECOBSERVE_BASE_URL=http://localhost:8000 --env SECOBSERVE_API_TOKEN=... -- uvx secobserve-mcp@latest
Codex CLI

在 ~/.codex/config.toml 中:

[mcp_servers.secobserve]
command = "uvx"
args = ["secobserve-mcp@latest"]
env = { SECOBSERVE_BASE_URL = "http://localhost:8000", SECOBSERVE_API_TOKEN = "..." }
其他 MCP 客户端

大多数客户端都使用相同的 JSON 结构:

{
  "mcpServers": {
    "secobserve": {
      "command": "uvx",
      "args": ["secobserve-mcp@latest"],
      "env": {
        "SECOBSERVE_BASE_URL": "http://localhost:8000",
        "SECOBSERVE_API_TOKEN": "..."
      }
    }
  }
}

对于共享部署,请在负责验证调用方身份的网关后,通过无状态 JSON 运行可流式传输的 HTTP:

uvx secobserve-mcp --transport http --host 127.0.0.1 --port 8931 --shared-identity

--shared-identity 是服务能够启动的关键:传输本身不进行身份验证,因此每个调用方都会使用 SECOBSERVE_API_TOKEN 中的同一个身份进行操作;该标志接受这一设置,并强制进程以只读模式运行。

设计

阅读代码前,值得了解以下三项设计决策:

响应经过投影。 SecObserve 的序列化器会返回模型的所有列;一个 Observation 大约有 100 列。每种资源都有默认字段集,每个列表结果都会说明省略了哪些字段。传入 fields=["*"] 可选择不使用默认字段集。

资源说明来自实例,而非此仓库。 secobserve_describe_resource 会从正在运行的后端读取 /api/oa3/schema/,因此筛选器名称和枚举值不会与已部署版本不一致。系统也会使用同一架构,在发送请求前拒绝未知筛选器名称:django-filter 会静默忽略它不认识的参数,因此 filters={"vulnerability_id": "CVE-2021-44228"} 原本会返回未经筛选的完整列表,导致 Agent 给出看似确信、实则错误的答案。现在遇到这种情况时,系统会报错并列出实际存在的筛选器。

只要架构中定义了规则,就由架构负责验证。 缺少评论的评估、缺少备注的拒绝操作、包含超过 250 个 ID 的批量调用,或既没有 product_id 也没有 product_name 的创建请求,都会在发送任何 HTTP 请求前被输入模型拒绝。其他情况都会直接传递,API 的 400 响应正文(其中会指出出错字段)也会原样返回。

预期内的失败会以工具文本的形式返回,而不是抛出异常:MCP 抛出的异常会以 Error executing tool <name> 的形式直接报告给客户端,这会丢掉 Agent 正确重试所需的关键信息。

审计日志

每次工具调用都会向 stderr 写入一行 JSON。SecObserve 自身的观测日志只记录写入操作,因此若没有这项功能,读取操作——也就是数据离开的方式——将不会留下任何记录。

{"ts":"2026-09-20T19:01:06.474+00:00","tool":"secobserve_list","caller":"apitoken:82fd9d5b1ae9","claimed_username":null,"resource":"observations","outcome":"returned","ms":37.0}
{"ts":"2026-09-20T19:01:06.518+00:00","tool":"secobserve_list","caller":"jwt:09f002a0620f","claimed_username":"[email protected]","resource":"observations","outcome":"returned","ms":0.9}
键含义
caller<source>:<digest>。对于请求在 X-SecObserve-Token 中携带的凭据,source 为 apitoken 或 jwt;对于进程自身的凭据(stdio,或未带请求头的 HTTP),source 为 server。如果完全无法读取凭据,则为 unknown。
claimed_usernameJWT 的 username 声明,用于标明调用者身份。未经验证:令牌是调用者自己的数据,且只有 SecObserve 持有密钥。
resourceresource 参数,且仅当目录中包含该名称时记录。对于不接受此参数的工具,以及此服务无法识别的值,均为 null。
outcome工具返回结果时为 returned;工具抛出异常且 MCP 报告错误结果时为 error;调用未到达工具时为 rejected。
ms整个调用的耗时,无论工具返回还是抛出异常,均以相同方式测量。

摘要是凭据经域分隔 SHA-256 计算所得的前 12 个十六进制字符。它只会将同一调用者的日志行相互关联,不会关联任何其他信息:持有日志的人可以区分不同调用、归纳某位调用者的读取操作,并确认自己已经持有的令牌曾在此处使用过——但无法恢复凭据,也无法在没有凭据的情况下将摘要对应到 SecObserve 用户。这依赖于凭据具有高熵:已签发的 API 令牌具备这一特性,而手写的令牌则不具备。

日志绝不记录参数、凭据、Authorization 请求头或请求正文。resource 是唯一的例外,而目录检查正是其例外的依据:调用者自行编造的值会被丢弃,不会写入日志。

设置 SECOBSERVE_AUDIT_LOG=false 可关闭全部审计日志。默认启用是因为需要人们记得开启的日志,恰恰会在需要时缺失;而 stderr 不是协议通道,因此不会影响任何 stdio 客户端。如果工具以文本形式返回预期的失败结果,该结果会记为 returned:要区分这类情况就必须读取字符串,这会让审计层依赖仓库中每条错误消息的措辞。

安全性

  • 凭据来自环境变量,工具绝不会返回凭据。
  • 默认禁用 secobserve_delete;删除产品或产品组还必须要求 confirm_name 与记录中的确切名称匹配,此项由 API 本身验证。删除操作会级联执行且不可恢复。
  • 上传仅限于 SECOBSERVE_IMPORT_DIR;导出文件会写入 SECOBSERVE_EXPORT_DIR,并使用经过净化的单段文件名。
  • HTTP 传输默认绑定到 127.0.0.1;如果使用来自环境变量的凭据,除非 --shared-identity 接受所有调用者共享该凭据,否则服务会拒绝启动;启用该选项后,服务将为只读模式。
  • 观测标题、描述、组件名称和扫描器输出均为第三方数据,由扫描器以及编写被扫描代码的人提供。服务会在其 MCP 说明和相关工具描述中说明这一点。应将这些内容视为数据,而非指令。

警告

此服务对 SecObserve 拥有完整写入权限。如果 Agent 只需要处理一个产品,请优先使用产品 API 令牌,而非超级用户令牌;对于只读会话,请设置 SECOBSERVE_READ_ONLY=true。

测试

uv run pytest

测试套件使用 respx 模拟 SecObserve API,覆盖投影、分页元数据、错误转换、只读和删除限制、上传路径限制、未知筛选条件拒绝、架构切片,以及评估/批准负载规则。

ruff check、ruff format --check 和 mypy --strict 均通过。


如何设置并提出更改:CONTRIBUTING.md。AI Agent 更改此代码时需遵守的不变量和工作流程:AGENTS.md。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。