Skip to content
Agentmart
Submit a tool

TopicForge

Read-only MCP server for ROS2 and DDS: topics, participants, QoS mismatches, bags.

Connector by yaniswav · GitHub account verified by the MCP Registry

IndexedMITLocal (stdio)★ 3
Write a review

Chalk Labs

Need help deploying TopicForge?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.

npx agentmarket install connector/yaniswav-topicforge

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Read-only MCP server for ROS2 and DDS: topics, participants, QoS mismatches, bags.

Use cases: monitoring-observability, debugging

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this server can do and what it asks for, from its tool list, install config and code. Checked Oct 25, 2026.

Tools
16 read · 0 write · 0 deleteRead-only
Secrets
None asked for
Install scripts
None found
Runs as
Python package

Tools by what they do 16

Read from the source code; the running server may list different tools.

Read 16 · Look things up without changing anything.

  • analyze_bag
  • detect_qos_mismatches
  • get_node_info
  • get_topic_info
  • graph_diff
  • health_check
  • inspect_tf
  • list_endpoints
  • list_nodes
  • list_participants
  • list_topics
  • participant_events
Show 4 more tools
  • peek_bag_samples
  • peek_dds_samples
  • sample_messages
  • topic_metrics

Secrets and settings it asks for

Other settings (environment variables or headers).

  • TOPICFORGE_DDS_BACKEND
  • TOPICFORGE_DDS_DOMAIN_ID
  • TOPICFORGE_MODE
  • TOPICFORGE_TELEMETRY

Network hosts it talks to 9

  • agent-plugins.org · found in code
  • cyclonedds.io · found in code
  • design.ros2.org · found in code
  • eprosima.com · found in code
  • fast-dds.docs.eprosima.com · found in code
  • github.com · found in code
  • glama.ai · found in code
  • rustup.rs · found in code
  • topicforge.horizonvista.xyz · found in code

Files it touches

  • /opt/topicforge/tests/integration/ros2/bench_params.yaml
  • Your home directory (~)
  • Any path the agent passes to its tools

Tools (16)

Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].

  • analyze_bag

    Summarize a ROS 2 bag at `path` as a `BagAnalysis`: storage format, duration, message count, per-topic stats and `mode_effective`. Per topic `frequency_hz` is `(n - 1) / (last - first message time)` (`frequency_basis` `topic_span`), with `first_timestamp_ns`, `last_timestamp_ns` and `latched`; a latched topic whose messages all fall within 1 s (e.g. `/tf_static`) has a null `frequency_hz`. When the bag cannot be read locally or is a `.mcap` over 200 MiB, the rate falls back to count / bag duration (`bag_duration`) and `note` says why. **Live mode** runs `ros2 bag info` on `.mcap`, `.db3` or `r…

  • detect_qos_mismatches

    Explain why DDS readers and writers on a topic do not talk, and who will. Pairs every reader with every writer per topic and returns a `MismatchScan`: `summary` (one line, read it first), `matched` (pairs DDS will connect given the announced QoS; data flow is not observed), `reports` (incompatible or risky QoS pairs, with participant names, requested vs offered values and the failed rule in `details`), `not_matched` (pairs DDS never matches: different partitions or type names; the QoS rules are NOT evaluated for them, and `latent_incompatible_policies` lists what would also break once fixed), …

  • get_node_info

    ROS 2 graph only; on a DDS-only setup use `list_participants`. Describe one ROS 2 node as a `NodeInfo`: the topics it publishes and subscribes to, the services and actions it serves or calls (each `{name, type}`), its parameters and `use_sim_time`. Interfaces come from the graph (`ros2 node info`), which never waits for the node. Parameters come from a read (`ros2 param dump`) bounded by `timeout_s`: **a node that does not answer in time is a finding, not an error**: `parameters` is `null`, `parameters_note` says its executor is probably blocked, and the interfaces are still returned. A value …

  • get_topic_info

    ROS 2 graph only; on a DDS-only setup use `list_endpoints`. Describe one ROS 2 `topic` (fully qualified, e.g. `/cmd_vel`) as a `TopicInfo`: counts and, in live mode, `publisher_qos` / `subscription_qos` (`reliability`, `durability` where `transient_local` marks a latched topic such as `/tf_static`, `endpoint_count`; a `null` side says why in its `_note`) and `publisher_nodes` / `subscriber_nodes`. **Raises an MCP error** for a malformed or unknown topic, or without a `ros2` CLI. Read-only; no side effects. **Duration**: `ros2` CLI behind the ROS lock, one call at a time; ends within 45 s; `bus…

  • graph_diff

    ROS 2 graph only. Answer "what changed since it last worked": snapshot the graph (or `bag_path`) and compare it with `baseline`, as a `GraphDiff`. `changes` are node, topic, type, qos, rate and count differences; `added` = present now, absent from the baseline. `not_compared` names what a pair cannot support: nodes and counts need live against live, rates bag against bag, writer QoS a DDS backend. `/rosout` and `/parameter_events` count noise is only tallied in `builtin_changes_count`. The first call stores a snapshot and says so in `note`. Snapshots stay in memory (16, lost on restart). **Rai…

  • health_check

    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. `paylo…

  • inspect_tf

    ROS 2 graph only. Rebuild the TF tree from the transforms on `/tf_static` (latched) and `/tf` (listened to for `window_s`) and flag what breaks lookups. Returns a `TfReport`: `frames` (parent, `kind` static/dynamic/both, `age_s`, `stale`, `observed_frequency_hz` on wall time, `sim_frequency_hz` on stamps), `roots`, counts and `findings` `{kind, frames, text}`: `stale` (a frame trails the newest `/tf` stamp by more than `stale_after_s`), `two_parents`, `disconnected` (several roots), `static_and_dynamic`, `cycle`, `no_path`. Ages and rates use header stamps, so they hold on sim time (`real_time…

  • list_endpoints

    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 wi…

  • list_nodes

    ROS 2 graph only; on a DDS-only setup use `list_participants`. List the nodes on the ROS 2 graph (or the mock graph) from one `ros2 node list` call as a `NodeListing`: `name`, `namespace`, `full_name`, `duplicate_count`, `lifecycle` (managed node; state not read, `lifecycle_note` if unknown), `by_namespace` counts. `duplicates` lists full names used by several nodes (a per-node tool then answers for one of them, unidentified). Nodes starting with an underscore are hidden and a node on another `ROS_DOMAIN_ID` is invisible. **Empty `nodes`** when the graph has none. Use `get_node_info` for one n…

  • list_participants

    List DDS participants observed on the bus as a `ParticipantListing`: `guid`, `vendor` (read from the GUID prefix, `unknown` for vendors that do not put theirs there, e.g. Dust DDS and RTI Connext; see `vendor_source`), optional `name` (the announced EntityName, e.g. `lidar_driver`; a participant with none is normal, not a fault: identify it by its topics), `hostname`, `domain_id` and `is_observer` (TopicForge's own read-only participant, listed like any other). Lifecycle: `status` (`active` / `left`), `first_seen_ns` / `last_seen_ns` (TopicForge's clock), `announced_ns` (DDS source timestamp) …

  • list_topics

    ROS 2 graph only; on a DDS-only setup use `list_endpoints`. List the topics on the ROS 2 graph (or the mock graph) as a `TopicListing`: each has `name`, `message_type`, `publisher_count` and `subscriber_count`; `mode_effective` tells a real graph from fixtures. QoS is not listed: use `get_topic_info`. **Empty `topics`** when the graph has none or live discovery times out. **Raises an MCP error** without a `ros2` CLI. Read-only; no side effects. **Duration**: `ros2` CLI behind the ROS lock, one call at a time; ends within 45 s; `busy` error if the lock is held (retry).

  • participant_events

    Return DDS participant lifecycle events (`discovered` / `lost`) from a recent window, e.g. 'who left in the last 5 minutes?', as a `ParticipantEventListing`, newest first: `guid`, `event_type`, `vendor`, `timestamp_ns`, `time_source`, `observed_ns`, `age_s` (seconds before the response; live only), optional `name` (announced name), `hostname` and `domain_id`. `time_source` is `dds_source_timestamp` (timestamp of the announcement or dispose) or `observed_local` (when TopicForge noticed, weakest). **Crash caveat**: a `lost` timestamp is an upper bound of the death: exact after a clean shutdown, …

  • peek_bag_samples

    Description is built at runtime.

  • peek_dds_samples

    Peek recent samples on a raw DDS topic as a `SampleResult`, like `sample_messages` but read from the DDS layer (works without ROS 2). `count` defaults to 5, clamped to 50. (a) The builtin discovery topics (`DCPSParticipant`, `DCPSSubscription`, `DCPSPublication`) return structured discovery records: on Cyclone the CURRENT state (one per live participant or endpoint), not recent events (use `participant_events`); `DCPSPublication` / `DCPSSubscription` are the raw data behind `list_endpoints`. The topic may be `/scan`, `scan` or `rt/scan`. (b) User topics: payload decoding is DISABLED on every b…

  • sample_messages

    Description is built at runtime.

Show 1 more tools
  • topic_metrics

    Return temporal metrics (frequency, sequence gaps, latency percentiles) for a DDS topic over a recent window as a `TopicMetrics`. **Read `status` first**: `unsupported_user_topic` means the payload is not decoded, so no metric exists: every null or 0 is not a measurement; `no_samples_yet` is a builtin topic with nothing buffered; `ok` means computed. **Limits**: the buffer is filled only when `peek_dds_samples` runs on the topic, so `observed_frequency_hz` reflects how often it was called, not the publish rate: a coarse presence signal. `declared_frequency_hz` is `1 / deadline` of the shortest…

Signals

Stars
3
Forks
0
Open issues
0
Weekly downloads
351
Last commit
Oct 21, 2026 (9 days ago)
Last release
Oct 26, 2026 (5 days ago)
Last package publish
Oct 21, 2026 (9 days ago)

From GitHub (fetched Oct 24, 2026) and the package registry.

Details

Registry name
io.github.yaniswav/topicforge
Version
0.8.1
Auth
No auth
Packages
pypi topicforge
License
MIT
First seen
Oct 24, 2026
Last checked
Oct 26, 2026

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get TopicForge running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying TopicForge?

CallGet help
Cite this page

TopicForge MCP server. Agent Mart. https://agentmart.dev/connectors/yaniswav-topicforge (last updated 2026-10-26)