Skip to content

feat(expert): fetch flow-building tool catalog over MQTT - #8293

Merged
andypalmi merged 10 commits into
mainfrom
feat/expert-catalog-over-mqtt
Sep 23, 2026
Merged

andypalmi merged 10 commits into
mainfrom
feat/expert-catalog-over-mqtt

Conversation

@andypalmi

@andypalmi andypalmi commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Closes #8611

Description

The /api/v4/expert/mcp/tools route (tool-permissions catalog, added in #7639) builds the list of tools shown in the permissions UI. It previously fetched the flow-building tools with a direct axios.get to the Expert instance's /mcp/flow-tools endpoint, authenticated with the expert.service.token.

This replaces that HTTP fetch with a request over MQTT to the gateway's list_flow_catalog tool, reusing the existing third-party MCP request/response channel:

  • request: ff/v1/mcp/<platformId>/flow-building-tool-catalog/<uuid>/request
  • response: ff/v1/mcp/<platformId>/flow-building-tool-catalog/<uuid>/response

The flow-building-tool-catalog sentinel sits in the userId topic level to mark the fetch as the first-party, session-less catalog read.

Design points:

  • No service token is needed on this path.
  • No new topic. The catalog rides the channel the bridge and the central gateway already carry (ff/v1/mcp/+/+/+/request / .../response), so no new bridge source, rule, or gateway handler is required. list_flow_catalog is already a registered tool on the gateway's MCP server, so the request is served by the same dispatch as any other MCP call.
  • Not gated on mcpThirdParty. The ACL recognises the sentinel userId and treats it as a first-party read: exempt from the third-party feature gate and from the user lookup. Every other check (platform client, platformId shape, topic-safe session id) still applies, so the sentinel can only perform the designed request/response exchange. Deployments that have not enabled third-party MCP still get the permissions-UI catalog.
  • If the gateway is unreachable or errors, the route degrades to the platform tools alone and still returns 200, rather than forwarding an upstream failure to the browser.

Backward compatibility

Forge no longer sends the service token on this path. The Expert instance keeps its HTTP /mcp/flow-tools endpoint for older Forge deployments; new Forge uses MQTT only, with no HTTP fallback.

Testing

Unit tests cover the sentinel ACL path (including that the catalog channel works with mcpThirdParty disabled and without a real user, while the topic-shape checks still apply) and the route fetching the catalog over MQTT. Validated live on a self-hosted deployment with the central broker.

…MQTT

Replace the HTTP GET to the Expert service /mcp/flow-tools with an MQTT
request to the gateway's list_flow_catalog meta-tool via the existing MCP
gateway proxy. This removes the Expert service token from the tool-catalog
path; the catalog is session-less so no team or scope context is sent, and
a gateway failure degrades to the platform tools alone.
@andypalmi
andypalmi requested a review from cstns August 26, 2026 15:57
@andypalmi
andypalmi marked this pull request as draft August 26, 2026 16:37
@codecov

codecov Bot commented Aug 26, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.38462% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.35%. Comparing base (f8a701f) to head (00ffb35).

Files with missing lines Patch % Lines
forge/ee/routes/expert/index.js 90.62% 3 Missing ⚠️
forge/comms/mcpGateway.js 50.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8293      +/-   ##
==========================================
+ Coverage   77.34%   77.35%   +0.01%     
==========================================
  Files         466      467       +1     
  Lines       25245    25277      +32     
  Branches     6720     6730      +10     
==========================================
+ Hits        19525    19553      +28     
- Misses       5720     5724       +4     
Flag Coverage Δ
backend 77.35% <90.38%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…topic

Move the flow-building catalog fetch off the third-party MCP session channel
(ff/v1/mcp/<platformId>/<userId>/<mcpSessionId>) onto a dedicated first-party
topic (ff/v1/mcp/catalog/<platformId>). The catalog is global and session-less,
so the topic carries no user or session, and its ACL is not gated on the
mcpThirdParty feature - deployments without third-party MCP still get the
permissions-UI catalog.

- mcpGateway: proxyCatalogRequest publishes on the catalog topic
- commsClient: handle the catalog response and subscribe per-replica
- aclManager: checkMcpCatalogTopic verify + forge_platform pub/sub rules
- bridge: forward the catalog request and add a source for its response
@Steve-Mcl

Steve-Mcl commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

not a review - just a quick eye over this. This PR introduces yet another topic for the bridge. I suspect we could use an existing topic channel e.g. ff/v1/mcp/+/+/+/request already. Could just set the "userid" and "mcpSessionId" fields of that topic as something arbitrary/known/checked e.g. ff/v1/mcp/<platformId>/flow-building-tool-catalog/<random-uid-for-separation-of-concerns>/request (ensuring if element [5] is === "flow-building-tool-catalog" the only operation it can make is the designed request) (or some other topic that fits ff/v1/mcp/+/+/+/request)

andypalmi added 2 commits September 21, 2026 16:49
# Conflicts:
#	forge/comms/aclManager.js
…channel

Fetch the flow-building tool catalog over the existing third-party MCP
request/response channel instead of a dedicated ff/v1/mcp/catalog/... topic,
marked by a sentinel userId. The ACL treats that value as a first-party read:
exempt from the mcpThirdParty gate and the user lookup, with every other topic
check still applied. The EMQX bridge and the central gateway need no new topic,
source or handler.
andypalmi added 2 commits September 21, 2026 18:13
Move the CallToolResult unwrap out of the catalog route into a shared
parseMcpToolResult helper, so other MCP-over-MQTT tool-call results can reuse it.
@andypalmi
andypalmi marked this pull request as ready for review September 21, 2026 16:17

@Steve-Mcl Steve-Mcl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nits

Comment thread test/unit/forge/comms/authRoutesV2_spec.js Outdated
Comment thread forge/comms/utils/mcpToolResult.js
Comment thread forge/ee/routes/expert/index.js Outdated
…lures

Give the catalog request its own short budget instead of reusing the 60s
HTTP timeout, so an MQTT publish to an absent bridge no longer blocks
GET /mcp/tools for a full minute.

Warn when the gateway returns an error, an error tool result, or an
unparseable response, so a broken gateway is distinguishable from an
empty flow catalog. Fold two identical catalog ACL tests into one.

@Steve-Mcl Steve-Mcl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested locally!

@andypalmi
andypalmi merged commit a5a0282 into main Sep 23, 2026
29 checks passed
@andypalmi
andypalmi deleted the feat/expert-catalog-over-mqtt branch September 23, 2026 14:37

This branch was successfully deployed

1 active deployment
staging — 00ffb35e Deployed Sep 23, 2026 by andypalmi via Remove application #11885
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fetch the flow-building tools catalog over the message bus

2 participants