Skip to main content
Glama

health_check

Read-onlyIdempotent

Reports TopicForge environment health and ROS/DDS backend state, including domain, tools, and discovery tracker status, to diagnose issues before further inspection.

Instructions

Report TopicForge environment state as a HealthReport: mode, ros_backend, dds_backend, ros_tools_available, ros2_distro, rmw_implementation, dds_domain_id and observed_domain_note (only the domain joined at startup is observed), server version and sample cap; for a live DDS backend also observer_started_ns / now_ns (nothing earlier was watched) and the discovery tracker status tracker_* (errors, evictions or a stale pass mean gaps). live with ros_backend none is a DDS-only setup: use list_endpoints. With dds_backend none, dds_inactive_note says why. payload_decoding is disabled (DDS user-topic payloads are not decoded); dds_security is not_supported. Always succeeds: call it first when something looks wrong. Duration: never waits for a lock and never runs the ros2 CLI; it answers at once.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "health_check"
  }
}

Input Schema

NameRequiredDescriptionDefault

No arguments

Output Schema

NameRequiredDescriptionDefault
modeYesMode serving: `mock` or `live` (`live` + `ros_backend` `none`: DDS tools only); may differ from `requested_mode`.
noteNoOne sentence of context, or `None`.
now_nsNoServer wall-clock time (ns since epoch) when this report was built.
dds_decodeNoUser payloads decoded.
rmw_sourceNo`env`, `ros2_cli`, `distro_default` (not verified on the graph) or `none`.
dds_backendNoDDS backend serving: `mock`, `cyclone` or `none` (DDS module inactive).
ros2_distroNo`ROS_DISTRO` if set (disclosed by design under the local-trust model).
ros_backendNoROS 2 backend: `ros2_cli`, `mock` or `none`.
dds_securityNoDDS Security is not handled: protected endpoints and data are invisible.
dds_domain_idNoDDS domain id observed when the DDS module is active.
requested_modeYesMode requested by configuration (may be `auto`).
ros2_availableYesWhether a `ros2` CLI is on PATH.
server_versionYesTopicForge version.
tracker_errorsNoTracker passes that raised; non-zero means gaps.
tracker_passesNoCompleted discovery tracker passes since start.
tracker_runningNoWhether the discovery tracker thread is alive (Cyclone); `None` without a tracker.
contract_versionNoOutput contract version; changes when a field is renamed, removed or retyped.
max_sample_countYesServer cap on samples per call; larger requests are clamped.
payload_decodingNo`disabled`: DDS user-topic payloads are not decoded.
sampling_backendNo`sample_messages` runs on: `cli`, `rclpy` helper, `unavailable`.
dds_inactive_noteNoWhy `dds_backend` is `none` while ROS 2 serves; else `null`.
ros_security_noteNoSet when `ros_security_enabled`: what stays invisible.
rmw_implementationNoROS 2 middleware, e.g. `rmw_fastrtps_cpp`; `None` when `rmw_source` is `none`.
observer_started_nsNons when the DDS observer joined; nothing earlier was watched. `None` without one.
ros_tools_availableNoTrue when the ROS 2 tools can run (`ros_backend` is not `none`); on a DDS-only setup use `list_endpoints`.
sim_clock_publishedNoWhether `/clock` had a publisher at the last graph read (stamps may be sim time); `None` in mock or unread.
middleware_availableNoTrue when a DDS backend serves; else whether the configured binding is importable.
observed_domain_noteNoWhich DDS domain is observed: only the one joined at startup; others are invisible.
ros_security_enabledNo`ROS_SECURITY_ENABLE` is `true`; `None` unless the ros2 CLI serves.
tracker_last_pass_nsNons of the last tracker pass; far older than `now_ns` means stale lifecycle.
payload_decoding_noteNoReason for `payload_decoding`.
ros_security_strategyNo`ROS_SECURITY_STRATEGY` when set to a valid value.
sampling_backend_noteNoWhy not `rclpy`.
tracker_cache_evictionsNoDiscovery entries dropped from a full tracker cache; non-zero means the bus is bigger than listed.
ros_security_keystore_setNoWhether a keystore variable is set (the path is never shown).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changedv0.10.0
    • changedOutput schema / properties / dds_backend / description
      Previous value: -"DDS backend serving: `mock`, `cyclone` or `none` (DDS module inactive); `fast` is retired."New value: +"DDS backend serving: `mock`, `cyclone` or `none` (DDS module inactive)."
    • changedOutput schema / properties / dds_backend / enum
      Previous value: -[
      -  "mock",
      -  "cyclone",
      -  "fast",
      -  "none"
      -]New value: +[
      +  "mock",
      +  "cyclone",
      +  "none"
      +]
    • addedOutput schema / properties / dds_decode
      Added value: +{
      +  "description": "User payloads decoded.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / sampling_backend
      Added value: +{
      +  "description": "`sample_messages` runs on: `cli`, `rclpy` helper, `unavailable`.",
      +  "enum": [
      +    "cli",
      +    "rclpy",
      +    "unavailable",
      +    null
      +  ],
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / sampling_backend_note
      Added value: +{
      +  "description": "Why not `rclpy`.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  2. Changed3 schema fields changedv0.9.0
    • changedOutput schema / properties / dds_backend / description
      Previous value: -"DDS backend serving: `mock`, `cyclone`, `fast`, or `none` (DDS module inactive)."New value: +"DDS backend serving: `mock`, `cyclone` or `none` (DDS module inactive); `fast` is retired."
    • changedOutput schema / properties / mode / description
      Previous value: -"Mode serving: `mock` or `live` (`live` with `ros_backend` `none`: DDS tools only); may differ from `requested_mode` after a fallback."New value: +"Mode serving: `mock` or `live` (`live` + `ros_backend` `none`: DDS tools only); may differ from `requested_mode`."
    • changedOutput schema / properties / sim_clock_published / description
      Previous value: -"Whether `/clock` had a publisher at the last graph read (stamps may be sim time); `None` in mock or without a recent read."New value: +"Whether `/clock` had a publisher at the last graph read (stamps may be sim time); `None` in mock or unread."
  3. Changed70 schema fields changedv0.8.0
    • removedOutput schema / properties / contract_version / default
      Removed value: -2
    • changedOutput schema / properties / contract_version / description
      Previous value: -"Output contract version; changes only when a field is renamed, removed or retyped."New value: +"Output contract version; changes when a field is renamed, removed or retyped."
    • removedOutput schema / properties / dds_backend / default
      Removed value: -"none"
    • removedOutput schema / properties / dds_domain_id / anyOf
      Removed value: -[
      -  {
      -    "maximum": 232,
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / dds_domain_id / default
      Removed value: -null
    • addedOutput schema / properties / dds_domain_id / maximum
      Added value: +232
    • addedOutput schema / properties / dds_domain_id / minimum
      Added value: +0
    • addedOutput schema / properties / dds_domain_id / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / properties / dds_inactive_note / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / dds_inactive_note / default
      Removed value: -null
    • changedOutput schema / properties / dds_inactive_note / description
      Previous value: -"Why `dds_backend` is `none` while ROS 2 serves (not selected, binding missing, or failed to start); else `null`."New value: +"Why `dds_backend` is `none` while ROS 2 serves; else `null`."
    • addedOutput schema / properties / dds_inactive_note / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / dds_security / default
      Removed value: -"not_supported"
    • removedOutput schema / properties / middleware_available / default
      Removed value: -false
    • changedOutput schema / properties / mode / description
      Previous value: -"Mode actually serving: `mock` or `live` (`live` with `ros_backend` `none`: DDS tools only). May differ from `requested_mode` after a fallback."New value: +"Mode serving: `mock` or `live` (`live` with `ros_backend` `none`: DDS tools only); may differ from `requested_mode` after a fallback."
    • removedOutput schema / properties / note / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / note / default
      Removed value: -null
    • addedOutput schema / properties / note / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / now_ns / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / now_ns / default
      Removed value: -null
    • addedOutput schema / properties / now_ns / minimum
      Added value: +0
    • addedOutput schema / properties / now_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / properties / observed_domain_note / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / observed_domain_note / default
      Removed value: -null
    • addedOutput schema / properties / observed_domain_note / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / observer_started_ns / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / observer_started_ns / default
      Removed value: -null
    • addedOutput schema / properties / observer_started_ns / minimum
      Added value: +0
    • addedOutput schema / properties / observer_started_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / properties / payload_decoding / default
      Removed value: -"disabled"
    • removedOutput schema / properties / payload_decoding_note / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / payload_decoding_note / default
      Removed value: -"user-topic payload decoding is switched off until it is validated on a real bus; builtin discovery topics are still readable"
    • addedOutput schema / properties / payload_decoding_note / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / rmw_implementation / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / rmw_implementation / default
      Removed value: -null
    • addedOutput schema / properties / rmw_implementation / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / rmw_source / default
      Removed value: -"none"
    • removedOutput schema / properties / ros2_distro / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / ros2_distro / default
      Removed value: -null
    • addedOutput schema / properties / ros2_distro / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / ros_backend / default
      Removed value: -"none"
    • addedOutput schema / properties / ros_security_enabled
      Added value: +{
      +  "description": "`ROS_SECURITY_ENABLE` is `true`; `None` unless the ros2 CLI serves.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / ros_security_keystore_set
      Added value: +{
      +  "description": "Whether a keystore variable is set (the path is never shown).",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / ros_security_note
      Added value: +{
      +  "description": "Set when `ros_security_enabled`: what stays invisible.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / ros_security_strategy
      Added value: +{
      +  "description": "`ROS_SECURITY_STRATEGY` when set to a valid value.",
      +  "enum": [
      +    "Enforce",
      +    "Permissive",
      +    null
      +  ],
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • removedOutput schema / properties / ros_tools_available / default
      Removed value: -false
    • removedOutput schema / properties / sim_clock_published / anyOf
      Removed value: -[
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / sim_clock_published / default
      Removed value: -null
    • changedOutput schema / properties / sim_clock_published / description
      Previous value: -"Whether `/clock` had a publisher in the last graph read (a hint that stamps may be sim time). `None` in mock or without a recent read; `health_check` never runs `ros2`."New value: +"Whether `/clock` had a publisher at the last graph read (stamps may be sim time); `None` in mock or without a recent read."
    • addedOutput schema / properties / sim_clock_published / type
      Added value: +[
      +  "boolean",
      +  "null"
      +]
    • removedOutput schema / properties / tracker_cache_evictions / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / tracker_cache_evictions / default
      Removed value: -null
    • changedOutput schema / properties / tracker_cache_evictions / description
      Previous value: -"Discovery entries dropped from a full tracker cache (4096 each); non-zero means the bus is bigger than listed."New value: +"Discovery entries dropped from a full tracker cache; non-zero means the bus is bigger than listed."
    • addedOutput schema / properties / tracker_cache_evictions / minimum
      Added value: +0
    • addedOutput schema / properties / tracker_cache_evictions / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / properties / tracker_errors / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / tracker_errors / default
      Removed value: -null
    • addedOutput schema / properties / tracker_errors / minimum
      Added value: +0
    • addedOutput schema / properties / tracker_errors / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / properties / tracker_last_pass_ns / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / tracker_last_pass_ns / default
      Removed value: -null
    • addedOutput schema / properties / tracker_last_pass_ns / minimum
      Added value: +0
    • addedOutput schema / properties / tracker_last_pass_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / properties / tracker_passes / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / tracker_passes / default
      Removed value: -null
    • addedOutput schema / properties / tracker_passes / minimum
      Added value: +0
    • addedOutput schema / properties / tracker_passes / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / properties / tracker_running / anyOf
      Removed value: -[
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / tracker_running / default
      Removed value: -null
    • addedOutput schema / properties / tracker_running / type
      Added value: +[
      +  "boolean",
      +  "null"
      +]
  4. Changed50 schema fields changedv0.7.1
    • removedInput schema / title
      Removed value: -"health_checkArguments"
    • addedOutput schema / properties / contract_version
      Added value: +{
      +  "default": 2,
      +  "description": "Output contract version; changes only when a field is renamed, removed or retyped.",
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / dds_backend / description
      Previous value: -"DDS backend of the adapter actually serving requests. `none` when the DDS module is not active (default for ROS2-only installs). `mock` for synthetic fixtures. `cyclone` requires `pip install \"topicforge[dds-cyclone]\"` (Eclipse CycloneDDS); `fast` requires a Fast DDS Python binding built from eProsima sources (not on PyPI); `opendds` and `dust` are permanent stub adapters that never serve."New value: +"DDS backend serving: `mock`, `cyclone`, `fast`, or `none` (DDS module inactive)."
    • changedOutput schema / properties / dds_backend / enum
      Previous value: -[
      -  "mock",
      -  "cyclone",
      -  "fast",
      -  "opendds",
      -  "dust",
      -  "none"
      -]New value: +[
      +  "mock",
      +  "cyclone",
      +  "fast",
      +  "none"
      +]
    • removedOutput schema / properties / dds_backend / title
      Removed value: -"Dds Backend"
    • removedOutput schema / properties / dds_domain_id / title
      Removed value: -"Dds Domain Id"
    • addedOutput schema / properties / dds_inactive_note
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Why `dds_backend` is `none` while ROS 2 serves (not selected, binding missing, or failed to start); else `null`."
      +}
    • removedOutput schema / properties / dds_inactive_reason
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Why `dds_backend` is `none` while the ROS 2 CLI serves: the backend was not selected (`TOPICFORGE_DDS_BACKEND` unset or `mock`), its Python binding is not installed, or the binding is installed but the adapter failed to start. `null` when a DDS backend is serving or the cause is not known.",
      -  "title": "Dds Inactive Reason"
      -}
    • changedOutput schema / properties / dds_security / description
      Previous value: -"DDS Security is not handled. On a secured domain TopicForge can show participants but not protected endpoints or data."New value: +"DDS Security is not handled: protected endpoints and data are invisible."
    • removedOutput schema / properties / dds_security / title
      Removed value: -"Dds Security"
    • changedOutput schema / properties / max_sample_count / description
      Previous value: -"Server-side cap on the number of samples returned per `sample_messages` call. Requests above this limit are silently clamped; the value is exposed here so a client can size its requests proactively. Constant within a given server version."New value: +"Server cap on samples per call; larger requests are clamped."
    • removedOutput schema / properties / max_sample_count / title
      Removed value: -"Max Sample Count"
    • changedOutput schema / properties / middleware_available / description
      Previous value: -"True when a DDS backend is serving (`dds_backend` is not `none`). When the DDS module is inactive (`dds_backend == 'none'`), whether the *configured* backend's Python bindings are importable, so a missing binding is visible."New value: +"True when a DDS backend serves; else whether the configured binding is importable."
    • removedOutput schema / properties / middleware_available / title
      Removed value: -"Middleware Available"
    • changedOutput schema / properties / mode / description
      Previous value: -"Runtime mode of the adapter actually serving requests: `mock` or `live`. `live` with `ros_backend` `none` means the DDS tools are live and the ROS 2 tools are not available. Can differ from `requested_mode` when a live backend could not start (e.g. `live` requested without `ros2` installed falls back to `mock`)."New value: +"Mode actually serving: `mock` or `live` (`live` with `ros_backend` `none`: DDS tools only). May differ from `requested_mode` after a fallback."
    • removedOutput schema / properties / mode / title
      Removed value: -"Mode"
    • addedOutput schema / properties / note
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "One sentence of context, or `None`."
      +}
    • removedOutput schema / properties / now_ns / title
      Removed value: -"Now Ns"
    • changedOutput schema / properties / observed_domain_note / description
      Previous value: -"Plain statement of which DDS domain is observed, set when a DDS module is active: only the domain joined at startup is visible, a program on another domain is invisible."New value: +"Which DDS domain is observed: only the one joined at startup; others are invisible."
    • removedOutput schema / properties / observed_domain_note / title
      Removed value: -"Observed Domain Note"
    • changedOutput schema / properties / observer_started_ns / description
      Previous value: -"Wall-clock time (ns since epoch) when the DDS observer joined the bus. Nothing earlier than this was watched: `now_ns` minus this is how long TopicForge has been observing. `None` without a live DDS observer."New value: +"ns when the DDS observer joined; nothing earlier was watched. `None` without one."
    • removedOutput schema / properties / observer_started_ns / title
      Removed value: -"Observer Started Ns"
    • changedOutput schema / properties / payload_decoding / description
      Previous value: -"Whether DDS user-topic payloads are decoded. `disabled` today: `peek_dds_samples` and `topic_metrics` do not return message content for user topics."New value: +"`disabled`: DDS user-topic payloads are not decoded."
    • removedOutput schema / properties / payload_decoding / title
      Removed value: -"Payload Decoding"
    • addedOutput schema / properties / payload_decoding_note
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": "user-topic payload decoding is switched off until it is validated on a real bus; builtin discovery topics are still readable",
      +  "description": "Reason for `payload_decoding`."
      +}
    • removedOutput schema / properties / payload_decoding_reason
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": "user-topic payload decoding is switched off until it is validated on a real bus; builtin discovery topics are still readable",
      -  "description": "One-line reason for `payload_decoding`.",
      -  "title": "Payload Decoding Reason"
      -}
    • changedOutput schema / properties / requested_mode / description
      Previous value: -"Mode requested via configuration (may be `auto`)."New value: +"Mode requested by configuration (may be `auto`)."
    • removedOutput schema / properties / requested_mode / title
      Removed value: -"Requested Mode"
    • addedOutput schema / properties / rmw_implementation
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "ROS 2 middleware, e.g. `rmw_fastrtps_cpp`; `None` when `rmw_source` is `none`."
      +}
    • addedOutput schema / properties / rmw_source
      Added value: +{
      +  "default": "none",
      +  "description": "`env`, `ros2_cli`, `distro_default` (not verified on the graph) or `none`.",
      +  "enum": [
      +    "env",
      +    "ros2_cli",
      +    "distro_default",
      +    "none"
      +  ],
      +  "type": "string"
      +}
    • removedOutput schema / properties / ros2_available / title
      Removed value: -"Ros2 Available"
    • changedOutput schema / properties / ros2_distro / description
      Previous value: -"Value of `ROS_DISTRO` if set in the environment. **Env disclosure, by design**: under the local-trust threat model (see README 'Security model'), the MCP client is a trusted agent on a machine the user controls, and exposing the ROS2 distro lets it adapt to e.g. `humble`/`jazzy` differences. For a hosted multi-tenant TopicForge endpoint this field would be scrubbed ."New value: +"`ROS_DISTRO` if set (disclosed by design under the local-trust model)."
    • removedOutput schema / properties / ros2_distro / title
      Removed value: -"Ros2 Distro"
    • changedOutput schema / properties / ros_backend / description
      Previous value: -"Active ROS2 backend. `ros2_cli` when the `ros2` CLI is on PATH and live mode resolves to a Ros2CliAdapter (alone or as the ROS half of a composite). `mock` when MockAdapter serves the ROS surface. `none` when no ROS2 backend is active (e.g. DDS-only live install with no `ros2` CLI). Together with `dds_backend` it tells the ROS2 and DDS halves of the runtime apart."New value: +"ROS 2 backend: `ros2_cli`, `mock` or `none`."
    • removedOutput schema / properties / ros_backend / title
      Removed value: -"Ros Backend"
    • changedOutput schema / properties / ros_tools_available / description
      Previous value: -"True when the ROS 2 tools (`list_topics`, `get_topic_info`, `sample_messages`, `analyze_bag`, `peek_bag_samples`) can run, i.e. `ros_backend` is not `none`. False on a DDS-only setup: use `list_endpoints` for topics and wiring there."New value: +"True when the ROS 2 tools can run (`ros_backend` is not `none`); on a DDS-only setup use `list_endpoints`."
    • removedOutput schema / properties / ros_tools_available / title
      Removed value: -"Ros Tools Available"
    • changedOutput schema / properties / server_version / description
      Previous value: -"TopicForge server version (matches the PyPI release of the `topicforge` package)."New value: +"TopicForge version."
    • removedOutput schema / properties / server_version / title
      Removed value: -"Server Version"
    • changedOutput schema / properties / sim_clock_published / description
      Previous value: -"Whether `/clock` has at least one publisher on the ROS 2 graph. True suggests nodes may run on simulated time (`use_sim_time`), so `header.stamp` values are sim time, not wall time (compare with `received_ns`). It is a hint: a publisher on `/clock` does not prove a given node follows it. `None` in mock mode or when the `ros2` CLI could not answer."New value: +"Whether `/clock` had a publisher in the last graph read (a hint that stamps may be sim time). `None` in mock or without a recent read; `health_check` never runs `ros2`."
    • removedOutput schema / properties / sim_clock_published / title
      Removed value: -"Sim Clock Published"
    • changedOutput schema / properties / tracker_cache_evictions / description
      Previous value: -"Discovery entries dropped because a tracker cache was full (4096 per cache). Non-zero means the bus is bigger than what is listed."New value: +"Discovery entries dropped from a full tracker cache (4096 each); non-zero means the bus is bigger than listed."
    • removedOutput schema / properties / tracker_cache_evictions / title
      Removed value: -"Tracker Cache Evictions"
    • changedOutput schema / properties / tracker_errors / description
      Previous value: -"Discovery tracker passes that raised (swallowed and logged). Non-zero means gaps."New value: +"Tracker passes that raised; non-zero means gaps."
    • removedOutput schema / properties / tracker_errors / title
      Removed value: -"Tracker Errors"
    • changedOutput schema / properties / tracker_last_pass_ns / description
      Previous value: -"Wall-clock time (ns since epoch) of the last completed tracker pass. A value far older than `now_ns` means lifecycle is stale."New value: +"ns of the last tracker pass; far older than `now_ns` means stale lifecycle."
    • removedOutput schema / properties / tracker_last_pass_ns / title
      Removed value: -"Tracker Last Pass Ns"
    • removedOutput schema / properties / tracker_passes / title
      Removed value: -"Tracker Passes"
    • changedOutput schema / properties / tracker_running / description
      Previous value: -"Whether the continuous discovery tracker thread is alive (Cyclone). `None` when the backend has no tracker."New value: +"Whether the discovery tracker thread is alive (Cyclone); `None` without a tracker."
    • removedOutput schema / properties / tracker_running / title
      Removed value: -"Tracker Running"
  5. Changed1 schema field changedv0.6.3
    • addedOutput schema / properties / sim_clock_published
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Whether `/clock` has at least one publisher on the ROS 2 graph. True suggests nodes may run on simulated time (`use_sim_time`), so `header.stamp` values are sim time, not wall time (compare with `received_ns`). It is a hint: a publisher on `/clock` does not prove a given node follows it. `None` in mock mode or when the `ros2` CLI could not answer.",
      +  "title": "Sim Clock Published"
      +}
  6. First observedv0.5.6

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond the readOnly/idempotent annotations: always succeeds, never waits for a lock, never runs the ros2 CLI, answers at once, only the startup domain is observed, and payload_decoding/dds_security are disabled/unsupported. The only gap is that the enumeration of report fields leans on the output schema rather than explaining each one.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the return shape and then the routing and operational guarantees, with no filler sentences. It is dense and long for a no-arg tool, partly because it restates field names the output schema already defines.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Annotations cover safety, an output schema covers the return shape, and the description fills in latency, failure, and scoping guarantees, leaving little an agent needs to know before calling it. Minor redundancy with the output schema keeps it just short of full marks.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so baseline 4 applies; the description instead spends its words on output field semantics (tracker_* errors/evictions indicating gaps, observed_domain_note scoping), which is useful but not parameter guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Report TopicForge environment state as a HealthReport') and enumerates exactly what the report contains, so an agent knows this is a static environment snapshot, not a live query of nodes or topics like its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit first-call rule ('call it first when something looks wrong') and routes on outcomes: 'live' with ros_backend 'none' means use list_endpoints, and dds_backend 'none' points to dds_inactive_note for the reason.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.