feat(mcp): mesh_publish tool — surface publish_to / publish_to_direct (#56) - #57
Merged
Conversation
…r direct dial (#56) Surfaces the bus's `publish_to` / `publish_to_direct` primitives through `amesh mcp` (they were reachable only from the Python bindings). Follow-up to #52's out-of-scope note. - New `mesh_publish` tool: publish a body to a peer on a topic, fire-and-forget (no reply awaited). The peer's bus fans it out to its topic subscribers. Same dual-mode peer naming as `mesh_request` — `peer` (resolve over mDNS → `publish_to`) or `addr`+`pubkey` (direct dial → `publish_to_direct`, no discovery). - Factors the peer-naming resolution (`peer` xor `addr`+`pubkey`, plus its validation) and the topic/body extraction out of `tool_request` into shared `peer_route` / `topic_and_body` helpers, so `mesh_request` and `mesh_publish` name peers identically and their rules can't drift. A small `McpPeerRoute` enum carries the resolved route. Tests (all deterministic, no multicast): - New `mcp_server_direct_addr_publishes_to_subscriber` (`agent-mesh-cli/tests/mcp_stdio.rs`) — real `amesh mcp` subprocess publishes to an in-process quiet-bound subscriber `Bus` by explicit `addr`+`pubkey` over loopback QUIC; the subscriber's topic `broadcast::Receiver` receives the body. Ran 5× back to back, ~0.3s each. - New `mcp.rs` unit tests: `mesh_publish` rejects neither-peer-nor-addr and half-specified direct args (confirming it routes through the shared helper). - Updated the `tools/list` assertions (now 4 tools) in `mcp.rs` and `mcp_stdio.rs`. Closes #56. Co-authored-by: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Surfaces the bus's fire-and-forget pub/sub primitives (
Bus::publish_to/Bus::publish_to_direct) throughamesh mcp— previously reachable onlyfrom the Python bindings. Follow-up to #52's out-of-scope note; closes #56.
mesh_publishtool — publish a body to a peer on a topic,fire-and-forget (no reply). The peer's bus fans it out to its topic
subscribers. Same dual-mode peer naming as
mesh_request:peer(resolveover mDNS →
publish_to) ORaddr+pubkey(direct dial →publish_to_direct, no discovery).peerxoraddr+pubkey+ itsvalidation) and topic/body extraction are factored out of
tool_requestinto shared
peer_route/topic_and_bodyhelpers (with a smallMcpPeerRouteenum), somesh_requestandmesh_publishname peersidentically and can't drift.
amesh listenis not a bus subscriber (rawEndpoint::accept, bypassing theinbox), so there is no CLI publish verb — the coherent surface is the tool.
Test plan
Local:
just check+just cov-ci(75% floor) green on Windows.mcp_server_direct_addr_publishes_to_subscriber(
agent-mesh-cli/tests/mcp_stdio.rs) — realamesh mcpsubprocesspublishes to an in-process quiet-bound subscriber
Busby explicitaddr+pubkeyover loopback QUIC (no multicast); the subscriber'stopic
broadcast::Receiverreceives the body. Subscribe-before-publishmakes it deterministic; ran 5× back to back, ~0.3s each.
mcp.rsunit tests:mesh_publishrejects neither-peer-nor-addrand half-specified direct args (confirms it routes through the shared
helper). Existing
mesh_requestvalidation tests still pass unchanged.tools/listassertions (4 tools now) inmcp.rs+mcp_stdio.rs.cargo test --workspace,cargo clippy --workspace --all-targets -- -D warnings,cargo fmt --all -- --check— all clean.Out of scope
mesh_subscribe(streaming server→client notifications) — alarger, separate feature.
amesh publishverb (no CLI subscriber exists to receive it).Refs #56, #52.