Skip to main content
Glama

list_endpoints

Read-onlyIdempotent

Lists every DDS writer and reader on the ROS 2 bus with topic, type, participant, and QoS details. Use it to inspect discovery state and orphaned topics without parsing sample data.

Instructions

List every DDS endpoint (writer and reader) announced on the bus as an EndpointListing; one EndpointInfo each with role, dds_topic (raw, e.g. rt/scan), ros_topic (/scan; null with ros_topic_note for a non-ROS topic), type_name, type_id, the owning participant_guid with participant_name, and a structured qos. Use it instead of parsing peek_dds_samples and joining GUID prefixes. Large buses: pass fields compact to replace each qos by a one-line qos_summary and drop type_id, announced_ns and ros_topic_note; the default full is verbose, so scope with topic or participant_guid to read one topic's full QoS. Orphans: by_topic rolls endpoints up per topic with writer_count, reader_count, orphan (no_reader = a writer nobody subscribes to, no_writer = a reader nobody publishes to) and the union of partitions. In qos, a duration or policy of None is infinite/unset or not announced. Among EXCLUSIVE writers the live one with the highest ownership_strength delivers; which one owns an instance is runtime state TopicForge cannot observe. Departed endpoints: a leaving participant's endpoints are remembered (last 200, 1 h) and shown in by_topic as departed_writers / departed_readers (listed in endpoints only with include_departed), so a topic that lost its only writer is explained in one call. Topic filter: rt/scan and scan match each other; a filter matching nothing returns a note with the closest topics. This lists discovery facts, not data flow: it cannot tell a silent or hung writer from a healthy one; pair it with detect_qos_mismatches. The observer's own endpoints are excluded unless include_observer; ROS 2 service and action endpoints (rq/, rr/, rs/, rp/, ra/, ros_discovery_info) unless include_internal. Capped at 500 endpoints (truncated, total); by_topic covers all matches. Raises an MCP error when no DDS module is active; mock returns a fixture. Duration: DDS lock, one call at a time, ends within 45 s; busy if held.

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": "list_endpoints"
  }
}

Input Schema

NameRequiredDescriptionDefault
topicNoOnly endpoints on this DDS topic: `scan` or `rt/scan` (exact name first, then the alternate form). Omit for every topic.
fieldsNo`full` (default) or `compact`: one-line `qos_summary` instead of the full `qos`, no `type_id`, `announced_ns` or `ros_topic_note`. Use `compact` on large buses.full
domain_idNoIgnored: it does not switch domains and is only range-checked (0..232). The domain observed is the one joined at startup (`TOPICFORGE_DDS_DOMAIN_ID`), reported in the response `domain_id`; `note` flags a different non-zero value.
include_departedNoAlso list endpoints whose participant left (flagged with `gone_ns`); `by_topic` reports them either way. Default false.
include_internalNoAlso list ROS 2 service and action endpoints (`rq/`, `rr/`, `rs/`, `rp/`, `ra/`, `ros_discovery_info`), most of a small robot's endpoints. Default false.
include_observerNoInclude TopicForge's own observer endpoints. Default false.
participant_guidNoOnly endpoints of this participant (a guid from `list_participants`). Omit for all.

Output Schema

NameRequiredDescriptionDefault
noteNoSet when a `topic` filter matched nothing: the closest known topics.
hintsNoFacts true of every endpoint, stated once (e.g. liveness is not observed).
totalYesEndpoints in the discovery cache before any filter.
fieldsNoDetail level served: `compact` drops per-endpoint QoS detail, type id and notes.
by_topicYesRoll-up over every matching endpoint.
returnedYes
domain_idYes
endpointsYesMatching endpoints, capped (see `truncated`).
truncatedYesTrue when matching endpoints exceeded the cap.
snapshot_nsYesWall-clock time of the snapshot, ns since epoch.
observer_guidNoGUID of TopicForge's own participant, `None` in mock.
mode_effectiveYes`live` or `mock` (fixtures).
departed_endpoint_countNoDeparted endpoints matching the filters; listed in `endpoints` only with `include_departed`.
hidden_internal_endpoint_countNoService/action endpoints (`rq/`, `rr/`, `rs/`, `rp/`, `ra/`, `ros_discovery_info`) hidden unless `include_internal`.
excluded_observer_endpoint_countNoTopicForge's own endpoints left out of `endpoints` (counted in `total`).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.9.0
    • changedOutput schema / $defs / QosProfile / properties / durability / description
      Previous value: -"`VOLATILE` keeps nothing for late joiners, `TRANSIENT_LOCAL` does; a TRANSIENT_LOCAL reader cannot match a VOLATILE writer."New value: +"`VOLATILE` keeps nothing for late joiners, `TRANSIENT_LOCAL` does; TRANSIENT_LOCAL readers skip VOLATILE writers."
    • changedOutput schema / $defs / QosProfile / properties / partitions / description
      Previous value: -"Partition names; the default partition is `[\"\"]`, never `[]`. Endpoints match only if partitions intersect; `None` when unreadable."New value: +"Partition names; default `[\"\"]`, never `[]`. Endpoints match only if partitions intersect; `None` if unreadable."
    • changedOutput schema / $defs / QosProfile / properties / unknown_policies / description
      Previous value: -"Policies announced but unreadable (e.g. `Deadline`): their fields are `None`, which does NOT mean infinite; the scan does not compare them."New value: +"Announced but unreadable (e.g. `Deadline`): fields are `None`, which does NOT mean infinite; the scan skips them."
    • changedOutput schema / properties / hidden_internal_endpoint_count / description
      Previous value: -"Service/action endpoints (`rq/`, `rr/`, `rs/`, `rp/`, `ra/`, `ros_discovery_info`) left out while `include_internal` is false."New value: +"Service/action endpoints (`rq/`, `rr/`, `rs/`, `rp/`, `ra/`, `ros_discovery_info`) hidden unless `include_internal`."
  2. Changed103 schema fields changedv0.8.0
    • removedOutput schema / $defs / DepartedEndpoint / properties / gone_ns / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / DepartedEndpoint / properties / gone_ns / default
      Removed value: -null
    • addedOutput schema / $defs / DepartedEndpoint / properties / gone_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / $defs / DepartedEndpoint / properties / participant_name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / DepartedEndpoint / properties / participant_name / default
      Removed value: -null
    • addedOutput schema / $defs / DepartedEndpoint / properties / participant_name / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / EndpointInfo / properties / announced_ns / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / announced_ns / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / announced_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / $defs / EndpointInfo / properties / gone_ns / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / gone_ns / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / gone_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • addedOutput schema / $defs / EndpointInfo / properties / node_name
      Added value: +{
      +  "description": "ROS 2 node owning the endpoint (`ros_discovery_info`); `None` if not announced.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • removedOutput schema / $defs / EndpointInfo / properties / participant_name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / participant_name / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / participant_name / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / EndpointInfo / properties / participant_vendor / default
      Removed value: -"unknown"
    • removedOutput schema / $defs / EndpointInfo / properties / qos / default
      Removed value: -null
    • removedOutput schema / $defs / EndpointInfo / properties / qos_summary / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / qos_summary / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / qos_summary / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / EndpointInfo / properties / ros_topic / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / ros_topic / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / ros_topic / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / EndpointInfo / properties / ros_topic_note / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / ros_topic_note / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / ros_topic_note / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / EndpointInfo / properties / type_id / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / type_id / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / type_id / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / EndpointInfo / properties / type_name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / EndpointInfo / properties / type_name / default
      Removed value: -null
    • addedOutput schema / $defs / EndpointInfo / properties / type_name / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / data_representation / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / data_representation / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / data_representation / items
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / $defs / QosProfile / properties / data_representation / type
      Added value: +[
      +  "array",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / deadline_ns / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / deadline_ns / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / deadline_ns / minimum
      Added value: +0
    • addedOutput schema / $defs / QosProfile / properties / deadline_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / destination_order / anyOf
      Removed value: -[
      -  {
      -    "enum": [
      -      "BY_RECEPTION_TIMESTAMP",
      -      "BY_SOURCE_TIMESTAMP"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / destination_order / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / destination_order / enum
      Added value: +[
      +  "BY_RECEPTION_TIMESTAMP",
      +  "BY_SOURCE_TIMESTAMP",
      +  null
      +]
    • addedOutput schema / $defs / QosProfile / properties / destination_order / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / history / anyOf
      Removed value: -[
      -  {
      -    "enum": [
      -      "KEEP_LAST",
      -      "KEEP_ALL"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / history / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / history / enum
      Added value: +[
      +  "KEEP_LAST",
      +  "KEEP_ALL",
      +  null
      +]
    • addedOutput schema / $defs / QosProfile / properties / history / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / history_depth / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / history_depth / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / history_depth / minimum
      Added value: +0
    • addedOutput schema / $defs / QosProfile / properties / history_depth / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / history_note / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / history_note / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / history_note / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / latency_budget_ns / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / latency_budget_ns / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / latency_budget_ns / minimum
      Added value: +0
    • addedOutput schema / $defs / QosProfile / properties / latency_budget_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / liveliness_kind / anyOf
      Removed value: -[
      -  {
      -    "enum": [
      -      "AUTOMATIC",
      -      "MANUAL_BY_PARTICIPANT",
      -      "MANUAL_BY_TOPIC"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / liveliness_kind / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / liveliness_kind / enum
      Added value: +[
      +  "AUTOMATIC",
      +  "MANUAL_BY_PARTICIPANT",
      +  "MANUAL_BY_TOPIC",
      +  null
      +]
    • addedOutput schema / $defs / QosProfile / properties / liveliness_kind / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / liveliness_lease_ns / anyOf
      Removed value: -[
      -  {
      -    "minimum": 0,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / liveliness_lease_ns / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / liveliness_lease_ns / minimum
      Added value: +0
    • addedOutput schema / $defs / QosProfile / properties / liveliness_lease_ns / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / ownership_kind / anyOf
      Removed value: -[
      -  {
      -    "enum": [
      -      "SHARED",
      -      "EXCLUSIVE"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / ownership_kind / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / ownership_kind / enum
      Added value: +[
      +  "SHARED",
      +  "EXCLUSIVE",
      +  null
      +]
    • addedOutput schema / $defs / QosProfile / properties / ownership_kind / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / ownership_strength / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / ownership_strength / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / ownership_strength / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / partitions / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / partitions / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / partitions / items
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / $defs / QosProfile / properties / partitions / type
      Added value: +[
      +  "array",
      +  "null"
      +]
    • removedOutput schema / $defs / QosProfile / properties / unknown_policies / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / QosProfile / properties / unknown_policies / default
      Removed value: -null
    • addedOutput schema / $defs / QosProfile / properties / unknown_policies / items
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / $defs / QosProfile / properties / unknown_policies / type
      Added value: +[
      +  "array",
      +  "null"
      +]
    • removedOutput schema / $defs / TopicSummary / properties / orphan / anyOf
      Removed value: -[
      -  {
      -    "enum": [
      -      "no_reader",
      -      "no_writer"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / TopicSummary / properties / orphan / default
      Removed value: -null
    • addedOutput schema / $defs / TopicSummary / properties / orphan / enum
      Added value: +[
      +  "no_reader",
      +  "no_writer",
      +  null
      +]
    • addedOutput schema / $defs / TopicSummary / properties / orphan / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • addedOutput schema / $defs / TopicSummary / properties / reader_nodes
      Added value: +{
      +  "description": "Sorted ROS 2 nodes of the readers (`node_name`).",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • removedOutput schema / $defs / TopicSummary / properties / ros_topic / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / $defs / TopicSummary / properties / ros_topic / default
      Removed value: -null
    • addedOutput schema / $defs / TopicSummary / properties / ros_topic / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • addedOutput schema / $defs / TopicSummary / properties / writer_nodes
      Added value: +{
      +  "description": "Sorted ROS 2 nodes of the writers (`node_name`).",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • removedOutput schema / description
      Removed value: -"Envelope returned by `list_endpoints`."
    • removedOutput schema / properties / departed_endpoint_count / default
      Removed value: -0
    • removedOutput schema / properties / excluded_observer_endpoint_count / default
      Removed value: -0
    • removedOutput schema / properties / fields / default
      Removed value: -"full"
    • removedOutput schema / properties / hidden_internal_endpoint_count / default
      Removed value: -0
    • 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 / observer_guid / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / observer_guid / default
      Removed value: -null
    • addedOutput schema / properties / observer_guid / type
      Added value: +[
      +  "string",
      +  "null"
      +]
  3. Changed125 schema fields changedv0.7.1
    • changedInput schema / properties / domain_id / description
      Previous value: -"Accepted for compatibility (0..232). TopicForge observes the domain it joined at startup (TOPICFORGE_DDS_DOMAIN_ID); this argument does not switch domains, and the response `domain_id` says which one was observed."New value: +"Ignored: it does not switch domains and is only range-checked (0..232). The domain observed is the one joined at startup (`TOPICFORGE_DDS_DOMAIN_ID`), reported in the response `domain_id`; `note` flags a different non-zero value."
    • removedInput schema / properties / domain_id / title
      Removed value: -"Domain Id"
    • addedInput schema / properties / fields
      Added value: +{
      +  "default": "full",
      +  "description": "`full` (default) or `compact`: one-line `qos_summary` instead of the full `qos`, no `type_id`, `announced_ns` or `ros_topic_note`. Use `compact` on large buses.",
      +  "enum": [
      +    "full",
      +    "compact"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / include_departed / description
      Previous value: -"Also list endpoints whose participant left the bus (flagged with `gone_ns`). Defaults to false; `by_topic` reports them as `departed_writers` / `departed_readers` either way."New value: +"Also list endpoints whose participant left (flagged with `gone_ns`); `by_topic` reports them either way. Default false."
    • removedInput schema / properties / include_departed / title
      Removed value: -"Include Departed"
    • addedInput schema / properties / include_internal
      Added value: +{
      +  "default": false,
      +  "description": "Also list ROS 2 service and action endpoints (`rq/`, `rr/`, `rs/`, `rp/`, `ra/`, `ros_discovery_info`), most of a small robot's endpoints. Default false.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / include_observer / description
      Previous value: -"Include TopicForge's own observer participant's endpoints. Defaults to false."New value: +"Include TopicForge's own observer endpoints. Default false."
    • removedInput schema / properties / include_observer / title
      Removed value: -"Include Observer"
    • changedInput schema / properties / participant_guid / description
      Previous value: -"Only endpoints owned by this participant, as the guid reported by `list_participants` or by an earlier `list_endpoints`. Omit for all participants."New value: +"Only endpoints of this participant (a guid from `list_participants`). Omit for all."
    • removedInput schema / properties / participant_guid / title
      Removed value: -"Participant Guid"
    • changedInput schema / properties / topic / description
      Previous value: -"Only endpoints on this DDS topic name: a bare name such as `scan` or a ROS 2 mangled name such as `rt/scan` (exact name first, then the alternate form). Omit to list every topic."New value: +"Only endpoints on this DDS topic: `scan` or `rt/scan` (exact name first, then the alternate form). Omit for every topic."
    • removedInput schema / properties / topic / title
      Removed value: -"Topic"
    • removedInput schema / title
      Removed value: -"list_endpointsArguments"
    • removedOutput schema / $defs / DepartedEndpoint / description
      Removed value: -"An endpoint whose participant left the bus (crash, clean exit or lease expiry)."
    • removedOutput schema / $defs / DepartedEndpoint / properties / gone_ns / title
      Removed value: -"Gone Ns"
    • removedOutput schema / $defs / DepartedEndpoint / properties / guid / description
      Removed value: -"GUID of the departed endpoint."
    • removedOutput schema / $defs / DepartedEndpoint / properties / guid / title
      Removed value: -"Guid"
    • removedOutput schema / $defs / DepartedEndpoint / properties / participant_guid / description
      Removed value: -"GUID of the participant that owned it."
    • removedOutput schema / $defs / DepartedEndpoint / properties / participant_guid / title
      Removed value: -"Participant Guid"
    • removedOutput schema / $defs / DepartedEndpoint / properties / participant_name / description
      Removed value: -"Announced name of that participant, `None` when it set none."
    • removedOutput schema / $defs / DepartedEndpoint / properties / participant_name / title
      Removed value: -"Participant Name"
    • removedOutput schema / $defs / DepartedEndpoint / title
      Removed value: -"DepartedEndpoint"
    • removedOutput schema / $defs / EndpointInfo / description
      Removed value: -"One DDS endpoint (writer or reader) announced through discovery."
    • removedOutput schema / $defs / EndpointInfo / properties / activity
      Removed value: -{
      -  "default": null,
      -  "description": "Reserved for a future liveness signal. Always `None` today.",
      -  "title": "Activity",
      -  "type": "null"
      -}
    • removedOutput schema / $defs / EndpointInfo / properties / activity_note
      Removed value: -{
      -  "default": "not observed: TopicForge holds no reader on user topics, so it cannot tell a silent or hung writer from a healthy one",
      -  "description": "Why `activity` is not populated.",
      -  "title": "Activity Note",
      -  "type": "string"
      -}
    • changedOutput schema / $defs / EndpointInfo / properties / announced_ns / description
      Previous value: -"Source timestamp of the discovery announcement, ns since epoch, read on the announcing side's clock (it can differ from this host's clock). `None` when not available."New value: +"Source timestamp of the announcement, on the announcer's clock; `None` if unavailable."
    • removedOutput schema / $defs / EndpointInfo / properties / announced_ns / title
      Removed value: -"Announced Ns"
    • addedOutput schema / $defs / EndpointInfo / properties / dds_topic
      Added value: +{
      +  "type": "string"
      +}
    • removedOutput schema / $defs / EndpointInfo / properties / domain_id
      Removed value: -{
      -  "description": "DDS domain the endpoint was observed on.",
      -  "maximum": 232,
      -  "minimum": 0,
      -  "title": "Domain Id",
      -  "type": "integer"
      -}
    • changedOutput schema / $defs / EndpointInfo / properties / gone_ns / description
      Previous value: -"`None` for a live endpoint. For a departed endpoint (only listed with `include_departed`): when its participant was lost (the participant's `lost_ns`, an upper bound of the death)."New value: +"`None` for a live endpoint; for a departed one (`include_departed`) when its participant was lost (upper bound)."
    • removedOutput schema / $defs / EndpointInfo / properties / gone_ns / title
      Removed value: -"Gone Ns"
    • removedOutput schema / $defs / EndpointInfo / properties / guid / description
      Removed value: -"GUID of the endpoint, `xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx`."
    • removedOutput schema / $defs / EndpointInfo / properties / guid / title
      Removed value: -"Guid"
    • removedOutput schema / $defs / EndpointInfo / properties / is_observer / title
      Removed value: -"Is Observer"
    • removedOutput schema / $defs / EndpointInfo / properties / mode_effective
      Removed value: -{
      -  "description": "Runtime mode the adapter served this response in: `live` (real ROS2 introspection) or `mock` (deterministic fixtures). Lets a caller tell a real graph from a demo one without calling `health_check`.",
      -  "enum": [
      -    "mock",
      -    "live"
      -  ],
      -  "title": "Mode Effective",
      -  "type": "string"
      -}
    • removedOutput schema / $defs / EndpointInfo / properties / participant_guid / description
      Removed value: -"GUID of the owning participant, same format as `list_participants`."
    • removedOutput schema / $defs / EndpointInfo / properties / participant_guid / title
      Removed value: -"Participant Guid"
    • removedOutput schema / $defs / EndpointInfo / properties / participant_name / description
      Removed value: -"Announced name of the owning participant, `None` when it set none."
    • removedOutput schema / $defs / EndpointInfo / properties / participant_name / title
      Removed value: -"Participant Name"
    • removedOutput schema / $defs / EndpointInfo / properties / participant_vendor / description
      Removed value: -"Vendor of the owning participant, same value as `list_participants` (`unknown` when it cannot be determined)."
    • removedOutput schema / $defs / EndpointInfo / properties / participant_vendor / title
      Removed value: -"Participant Vendor"
    • changedOutput schema / $defs / EndpointInfo / properties / qos / description
      Previous value: -"QoS the endpoint announced. Durations (`deadline_ns`, `liveliness_lease_ns`, `latency_budget_ns`) of `None` mean infinite or not set. `None` when reliability or durability could not be resolved."New value: +"Announced QoS; `None` when reliability or durability could not be resolved. A duration of `None` is infinite or unset."
    • addedOutput schema / $defs / EndpointInfo / properties / qos_summary
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "One-line QoS, set only with `fields` `compact` (where `qos` is `None`)."
      +}
    • removedOutput schema / $defs / EndpointInfo / properties / role / title
      Removed value: -"Role"
    • addedOutput schema / $defs / EndpointInfo / properties / ros_topic
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "ROS 2 name of the topic, for example `/scan`. `None` when the endpoint is not a ROS 2 topic: see `ros_topic_note`."
      +}
    • addedOutput schema / $defs / EndpointInfo / properties / ros_topic_note
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Why `ros_topic` is `None`. `None` when it is set."
      +}
    • removedOutput schema / $defs / EndpointInfo / properties / topic
      Removed value: -{
      -  "description": "DDS topic name.",
      -  "title": "Topic",
      -  "type": "string"
      -}
    • removedOutput schema / $defs / EndpointInfo / properties / type_id / title
      Removed value: -"Type Id"
    • removedOutput schema / $defs / EndpointInfo / properties / type_name / description
      Removed value: -"Announced data type name."
    • removedOutput schema / $defs / EndpointInfo / properties / type_name / title
      Removed value: -"Type Name"
    • changedOutput schema / $defs / EndpointInfo / required
      Previous value: -[
      -  "guid",
      -  "role",
      -  "participant_guid",
      -  "topic",
      -  "is_observer",
      -  "domain_id",
      -  "mode_effective"
      -]New value: +[
      +  "guid",
      +  "role",
      +  "participant_guid",
      +  "dds_topic",
      +  "is_observer"
      +]
    • removedOutput schema / $defs / EndpointInfo / title
      Removed value: -"EndpointInfo"
    • removedOutput schema / $defs / QosProfile / description
      Removed value: -"QoS profile of one DDS endpoint (reader or writer).\n\nCovers the policies behind most \"subscriber receives nothing\" cases.\nVendor-specific extensions are ignored."
    • changedOutput schema / $defs / QosProfile / properties / data_representation / description
      Previous value: -"Data representations the endpoint accepts or offers, from `XCDR1` and `XCDR2`. `None` when not announced."New value: +"`XCDR1` / `XCDR2` accepted or offered; `None` when not announced."
    • removedOutput schema / $defs / QosProfile / properties / data_representation / title
      Removed value: -"Data Representation"
    • changedOutput schema / $defs / QosProfile / properties / deadline_ns / description
      Previous value: -"Deadline QoS in nanoseconds. `None` means no deadline (infinite, the DDS default). A reader deadline tighter (smaller) than a writer deadline is incompatible: the writer cannot guarantee the reader's promise."New value: +"Deadline in ns; `None` is infinite. A reader deadline shorter than the writer's is incompatible."
    • removedOutput schema / $defs / QosProfile / properties / deadline_ns / title
      Removed value: -"Deadline Ns"
    • removedOutput schema / $defs / QosProfile / properties / destination_order / title
      Removed value: -"Destination Order"
    • changedOutput schema / $defs / QosProfile / properties / durability / description
      Previous value: -"DDS Durability QoS. `VOLATILE` writers do not retain samples for late joiners; `TRANSIENT_LOCAL` writers do. A `TRANSIENT_LOCAL` reader cannot match a `VOLATILE` writer."New value: +"`VOLATILE` keeps nothing for late joiners, `TRANSIENT_LOCAL` does; a TRANSIENT_LOCAL reader cannot match a VOLATILE writer."
    • removedOutput schema / $defs / QosProfile / properties / durability / title
      Removed value: -"Durability"
    • changedOutput schema / $defs / QosProfile / properties / history / description
      Previous value: -"DDS History QoS. `KEEP_LAST` keeps a bounded ring buffer of size `history_depth`; `KEEP_ALL` keeps every sample (memory permitting). Mixed `KEEP_ALL` reader with `KEEP_LAST` writer is risky but not strictly incompatible. `None` when it is not known: DDS discovery does not carry History, so it is reported only for TopicForge's own endpoints and for Cyclone DDS peers that set something other than the default (see `history_note`)."New value: +"`KEEP_LAST` (ring of `history_depth`) or `KEEP_ALL`; `None` when discovery did not announce it (see `history_note`)."
    • removedOutput schema / $defs / QosProfile / properties / history / title
      Removed value: -"History"
    • changedOutput schema / $defs / QosProfile / properties / history_depth / description
      Previous value: -"Depth for `KEEP_LAST`. `None` for `KEEP_ALL` or when `history` is `None`."New value: +"Depth for `KEEP_LAST`; else `None`."
    • removedOutput schema / $defs / QosProfile / properties / history_depth / title
      Removed value: -"History Depth"
    • changedOutput schema / $defs / QosProfile / properties / history_note / description
      Previous value: -"Set when `history` was left out because discovery did not announce it."New value: +"Why `history` is `None`."
    • removedOutput schema / $defs / QosProfile / properties / history_note / title
      Removed value: -"History Note"
    • changedOutput schema / $defs / QosProfile / properties / latency_budget_ns / description
      Previous value: -"LatencyBudget QoS in nanoseconds (a delivery-delay hint). `0` is the DDS default. `None` means infinite or not announced."New value: +"LatencyBudget in ns (a hint); `0` is the default, `None` is infinite or not announced."
    • removedOutput schema / $defs / QosProfile / properties / latency_budget_ns / title
      Removed value: -"Latency Budget Ns"
    • changedOutput schema / $defs / QosProfile / properties / liveliness_kind / description
      Previous value: -"Liveliness QoS kind. `AUTOMATIC` is asserted by the middleware; the two `MANUAL_*` kinds need the application to write or assert liveliness, and the endpoint is declared not alive when it does not within `liveliness_lease_ns`. `None` when not announced."New value: +"`AUTOMATIC`, or `MANUAL_*` (the app must assert liveliness within `liveliness_lease_ns`); `None` when not announced."
    • removedOutput schema / $defs / QosProfile / properties / liveliness_kind / title
      Removed value: -"Liveliness Kind"
    • changedOutput schema / $defs / QosProfile / properties / liveliness_lease_ns / description
      Previous value: -"Liveliness lease duration in nanoseconds. `None` means infinite (the DDS default) or not announced."New value: +"Liveliness lease in ns; `None` is infinite or not announced."
    • removedOutput schema / $defs / QosProfile / properties / liveliness_lease_ns / title
      Removed value: -"Liveliness Lease Ns"
    • changedOutput schema / $defs / QosProfile / properties / ownership_kind / description
      Previous value: -"Ownership QoS kind. With `EXCLUSIVE`, only the writer with the highest `ownership_strength` delivers samples to a reader. `None` when not announced."New value: +"With `EXCLUSIVE` only the writer with the highest `ownership_strength` delivers; `None` when not announced."
    • removedOutput schema / $defs / QosProfile / properties / ownership_kind / title
      Removed value: -"Ownership Kind"
    • changedOutput schema / $defs / QosProfile / properties / ownership_strength / description
      Previous value: -"Ownership strength of a writer (`EXCLUSIVE` ownership). `None` when not announced."New value: +"Writer strength under `EXCLUSIVE` ownership; `None` when not announced."
    • removedOutput schema / $defs / QosProfile / properties / ownership_strength / title
      Removed value: -"Ownership Strength"
    • changedOutput schema / $defs / QosProfile / properties / partitions / description
      Previous value: -"Partition names the endpoint's Publisher or Subscriber belongs to. No Partition policy is the default partition, reported as `[\"\"]` (never an empty list). Endpoints only match when their partitions intersect. `None` only when the backend cannot read partitions at all (unknown, not the default)."New value: +"Partition names; the default partition is `[\"\"]`, never `[]`. Endpoints match only if partitions intersect; `None` when unreadable."
    • removedOutput schema / $defs / QosProfile / properties / partitions / title
      Removed value: -"Partitions"
    • changedOutput schema / $defs / QosProfile / properties / reliability / description
      Previous value: -"DDS Reliability QoS. `RELIABLE` retries lost samples; `BEST_EFFORT` does not. A `RELIABLE` reader cannot match a `BEST_EFFORT` writer."New value: +"`RELIABLE` retries lost samples, `BEST_EFFORT` does not; a RELIABLE reader cannot match a BEST_EFFORT writer."
    • removedOutput schema / $defs / QosProfile / properties / reliability / title
      Removed value: -"Reliability"
    • changedOutput schema / $defs / QosProfile / properties / unknown_policies / description
      Previous value: -"Policies the endpoint announced but whose value could not be read (for example `Deadline`). Their duration fields are `None` here, which does NOT mean infinite for these: the scan does not compare them."New value: +"Policies announced but unreadable (e.g. `Deadline`): their fields are `None`, which does NOT mean infinite; the scan does not compare them."
    • removedOutput schema / $defs / QosProfile / properties / unknown_policies / title
      Removed value: -"Unknown Policies"
    • removedOutput schema / $defs / QosProfile / title
      Removed value: -"QosProfile"
    • removedOutput schema / $defs / TopicSummary / description
      Removed value: -"Per-topic roll-up of the listed endpoints, for spotting orphans."
    • addedOutput schema / $defs / TopicSummary / properties / dds_topic
      Added value: +{
      +  "type": "string"
      +}
    • changedOutput schema / $defs / TopicSummary / properties / departed_readers / description
      Previous value: -"Readers on this topic whose participant left, newest first."New value: +"Readers whose participant left, newest first."
    • removedOutput schema / $defs / TopicSummary / properties / departed_readers / title
      Removed value: -"Departed Readers"
    • changedOutput schema / $defs / TopicSummary / properties / departed_writers / description
      Previous value: -"Writers on this topic whose participant left, newest first (bounded memory: last 200 departed endpoints, 1 h). Explains a topic that lost its only writer."New value: +"Writers whose participant left, newest first (last 200, 1 h)."
    • removedOutput schema / $defs / TopicSummary / properties / departed_writers / title
      Removed value: -"Departed Writers"
    • changedOutput schema / $defs / TopicSummary / properties / orphan / description
      Previous value: -"`no_reader`: writers but no reader. `no_writer`: readers but no writer. `None` when both sides exist."New value: +"`no_reader` (writers only), `no_writer` (readers only), else `None`."
    • removedOutput schema / $defs / TopicSummary / properties / orphan / title
      Removed value: -"Orphan"
    • removedOutput schema / $defs / TopicSummary / properties / partitions / title
      Removed value: -"Partitions"
    • removedOutput schema / $defs / TopicSummary / properties / reader_count / description
      Removed value: -"Number of listed readers."
    • removedOutput schema / $defs / TopicSummary / properties / reader_count / title
      Removed value: -"Reader Count"
    • addedOutput schema / $defs / TopicSummary / properties / ros_topic
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "ROS 2 name of the topic, for example `/scan`. `None` for a DDS topic that is not a ROS 2 topic."
      +}
    • removedOutput schema / $defs / TopicSummary / properties / topic
      Removed value: -{
      -  "description": "DDS topic name.",
      -  "title": "Topic",
      -  "type": "string"
      -}
    • removedOutput schema / $defs / TopicSummary / properties / type_names / description
      Removed value: -"Distinct type names announced on this topic."
    • removedOutput schema / $defs / TopicSummary / properties / type_names / title
      Removed value: -"Type Names"
    • removedOutput schema / $defs / TopicSummary / properties / writer_count / description
      Removed value: -"Number of listed writers."
    • removedOutput schema / $defs / TopicSummary / properties / writer_count / title
      Removed value: -"Writer Count"
    • changedOutput schema / $defs / TopicSummary / required
      Previous value: -[
      -  "topic",
      -  "type_names",
      -  "writer_count",
      -  "reader_count",
      -  "partitions"
      -]New value: +[
      +  "dds_topic",
      +  "type_names",
      +  "writer_count",
      +  "reader_count",
      +  "partitions"
      +]
    • removedOutput schema / $defs / TopicSummary / title
      Removed value: -"TopicSummary"
    • removedOutput schema / properties / by_topic / title
      Removed value: -"By Topic"
    • addedOutput schema / properties / departed_endpoint_count
      Added value: +{
      +  "default": 0,
      +  "description": "Departed endpoints matching the filters; listed in `endpoints` only with `include_departed`.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • removedOutput schema / properties / departed_endpoints
      Removed value: -{
      -  "default": 0,
      -  "description": "Departed endpoints (their participant left) matching the filters. They are in `endpoints` only with `include_departed`; `by_topic` always carries them as `departed_writers` / `departed_readers`.",
      -  "minimum": 0,
      -  "title": "Departed Endpoints",
      -  "type": "integer"
      -}
    • removedOutput schema / properties / domain_id / description
      Removed value: -"DDS domain observed."
    • removedOutput schema / properties / domain_id / title
      Removed value: -"Domain Id"
    • removedOutput schema / properties / endpoints / title
      Removed value: -"Endpoints"
    • addedOutput schema / properties / excluded_observer_endpoint_count
      Added value: +{
      +  "default": 0,
      +  "description": "TopicForge's own endpoints left out of `endpoints` (counted in `total`).",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • removedOutput schema / properties / excluded_observer_endpoints
      Removed value: -{
      -  "default": 0,
      -  "description": "Endpoints of TopicForge's own observer participant left out of `endpoints` (they are counted in `total_discovered`). Explains `total_discovered` vs `returned` together with the filters.",
      -  "minimum": 0,
      -  "title": "Excluded Observer Endpoints",
      -  "type": "integer"
      -}
    • addedOutput schema / properties / fields
      Added value: +{
      +  "default": "full",
      +  "description": "Detail level served: `compact` drops per-endpoint QoS detail, type id and notes.",
      +  "enum": [
      +    "full",
      +    "compact"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / hidden_internal_endpoint_count
      Added value: +{
      +  "default": 0,
      +  "description": "Service/action endpoints (`rq/`, `rr/`, `rs/`, `rp/`, `ra/`, `ros_discovery_info`) left out while `include_internal` is false.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / hints
      Added value: +{
      +  "description": "Facts true of every endpoint, stated once (e.g. liveness is not observed).",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / properties / mode_effective / description
      Previous value: -"Runtime mode the adapter served this response in: `live` (real ROS2 introspection) or `mock` (deterministic fixtures). Lets a caller tell a real graph from a demo one without calling `health_check`."New value: +"`live` or `mock` (fixtures)."
    • removedOutput schema / properties / mode_effective / title
      Removed value: -"Mode Effective"
    • changedOutput schema / properties / note / description
      Previous value: -"Hint when a `topic` filter matched nothing: names the closest known topics."New value: +"Set when a `topic` filter matched nothing: the closest known topics."
    • removedOutput schema / properties / note / title
      Removed value: -"Note"
    • removedOutput schema / properties / observer_guid / title
      Removed value: -"Observer Guid"
    • removedOutput schema / properties / returned / description
      Removed value: -"Length of `endpoints`."
    • removedOutput schema / properties / returned / title
      Removed value: -"Returned"
    • removedOutput schema / properties / snapshot_ns / title
      Removed value: -"Snapshot Ns"
    • addedOutput schema / properties / total
      Added value: +{
      +  "description": "Endpoints in the discovery cache before any filter.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • removedOutput schema / properties / total_discovered
      Removed value: -{
      -  "description": "Endpoints in the discovery cache before any filter.",
      -  "minimum": 0,
      -  "title": "Total Discovered",
      -  "type": "integer"
      -}
    • removedOutput schema / properties / truncated / title
      Removed value: -"Truncated"
    • changedOutput schema / required
      Previous value: -[
      -  "domain_id",
      -  "snapshot_ns",
      -  "endpoints",
      -  "by_topic",
      -  "total_discovered",
      -  "returned",
      -  "truncated",
      -  "mode_effective"
      -]New value: +[
      +  "domain_id",
      +  "snapshot_ns",
      +  "endpoints",
      +  "by_topic",
      +  "total",
      +  "returned",
      +  "truncated",
      +  "mode_effective"
      +]
  4. First observedv0.5.6

TDQS

A4.4/5.0
Behavior4/5

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

Beyond the readOnly/idempotent annotations the description discloses real operational traits: a 500-endpoint cap with `truncated`/`total`, a DDS lock with 45 s timeout returning `busy`, an MCP error when no DDS module is active, and a 200-entry/1-hour departed-endpoint cache. That is substantial context an agent cannot get from the annotations, though it stops short of describing ordering of results.

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?

Despite its length, it is front-loaded with the core purpose and uses bold section markers ('Large buses', 'Orphans', 'Departed endpoints', 'Duration') that make scanning easy. A few points, such as `domain_id` being ignored and the `rt/scan` equivalence, duplicate the schema text and could be trimmed.

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

Completeness5/5

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

For a read-only discovery tool with an output schema, the description covers the non-obvious gaps an agent would otherwise stumble on: default exclusions, truncation behavior, error and busy conditions, and the semantics of `None` in QoS. Nothing needed to call it correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all seven parameters, including the `domain_id` no-op and the `compact` field dropping behavior, which the description largely restates. The description adds marginal value, mostly tying parameter choices to bus size rather than defining new parameter semantics.

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?

The opening clause names a specific verb and resource ('List every DDS endpoint (writer and reader) announced on the bus') and immediately enumerates the returned fields, so the agent knows exactly what comes back. It also differentiates from the sibling 'peek_dds_samples' by stating it replaces manual GUID-prefix joining.

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?

Explicit routing guidance is given: use this instead of parsing peek_dds_samples, use `by_topic` for orphan detection, use `compact` on large buses, and pair with `detect_qos_mismatches`. It also states a clear limitation ('cannot tell a silent or hung writer from a healthy one'), which is genuine when-not guidance.

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