Skip to content

feat: add Test connection tab to virtual server details drawer - #76

Open
marekdano wants to merge 5 commits into
mainfrom
5650-virtual-server-test-connection
Open

feat: add Test connection tab to virtual server details drawer#76
marekdano wants to merge 5 commits into
mainfrom
5650-virtual-server-test-connection

Conversation

@marekdano

@marekdano marekdano commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a "Test connection" tab to the virtual server details drawer, running an MCP handshake against the virtual server's own endpoint and surfacing the result - negotiation path, server identity, advertised capabilities, credential source used, and component counts cross-checked against the virtual server's own aggregate (flagged on mismatch).

Closes IBM/mcp-context-forge#5650.

Depends on IBM/mcp-context-forge#6405 (fixes IBM/mcp-context-forge#6370) — the original gateway-scoped POST /v1/mcp-servers/test-handshake endpoint could never succeed for a virtual server, since its SSRF allowlist only ever matches registered-gateway URLs. #6405 adds a virtual-server-scoped POST /v1/virtual-servers/{id}/test-handshake instead: it derives the test target from the server's own ID and dispatches in-process (no SSRF allowlist involved), reusing the caller's own forwarded session/bearer credentials by default. This PR has been updated to call that endpoint. Still opening as draft — #6405 is open but not yet merged, so full manual end-to-end verification against a running backend is still pending.

What's included

  • src/api/virtualServers.tstestVirtualServerHandshake() wrapper for POST /v1/virtual-servers/{id}/test-handshake.
  • src/components/servers/HandshakeTestPanel.tsx — the handshake test panel: read-only endpoint display (the target is now derived server-side from the ID, not caller-supplied, so the URL field is no longer editable), optional header-override form, result rendering (latency, negotiation path, server identity, capabilities, component-count badges with mismatch flagging against the virtual server's aggregate, credential source including the new session source, per-failure-class actionable copy, size-capped raw preview).
  • src/components/gateways/VirtualServerDetailsPanel.tsx — adds the Components / Test connection tab shell (following the #5648 drawer-tab pattern), passes the server's own ID through for the handshake call, and computes+forwards the virtual server's own aggregated tool/resource/prompt counts for mismatch comparison.
  • openapi.json — adds the new POST /v1/virtual-servers/{server_id}/test-handshake path and ServerHandshakeRequest schema, and extends GatewayHandshakeResponse.credentialSource with the new session value, matching #6405's backend schema changes.
  • Tests: HandshakeTestPanel.test.tsx (idle/success/failure/validation/cancel/unmount/capabilities/credential-source/failure-copy/count-mismatch, including a regression case built from a real backend response) and updated cases in VirtualServerDetailsPanel.test.tsx covering the tab wiring against the new endpoint.

Test plan

  • npx tsc -b — clean
  • npm run lint / npm run format:check — clean
  • npx vitest run — 184 files / 3107 tests passing

Screenshots

Screenshot 2026-08-28 at 14 22 50
Screenshot 2026-08-28 at 14 13 11

@marekdano

Copy link
Copy Markdown
Contributor Author

This PR can be merged after the PR IBM/mcp-context-forge#6405 is in main

@a-effort a-effort 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.

Nice work on this! I'll follow up tomorrow with visual suggestions, but here are some things to consider addressing in the meantime:

Count cross-check compares two different populations. aggregatedComponentCounts (VirtualServerDetailsPanel.tsx:286) comes from the three drawer queries, which pass include_inactive=true (:211,217,223). The handshake counts come from tools/list over /servers/{id}/mcp, which reaches list_server_tools with the default include_inactive=False and so counts enabled components only. Any virtual server with one disabled tool permanently shows "Component counts don't match the virtual server's aggregate ... a federated source is unreachable or filtering has diverged." Counting only enabled components for the comparison fixes it. The same comparison runs against fallbackComponents while the queries are in flight, which is a third population again.

Partial counts always mismatch. _probe_mcp_session sets counts_partial when a list returns a nextCursor, making component_counts a first-page lower bound. getCountMismatchKeys (HandshakeTestPanel.tsx:129) still compares with !==, so the banner shows with a parenthetical admitting it may not be a real mismatch (:282). Suppress the flag when countsPartial, or compare as a lower bound. main's TestConnectionPanel has the display convention for this ("{count}+ tools", en-US/mcpServer.json:214).

Failure copy describes the wrong mechanism. FAILURE_CLASS_COPY.transport (:50) says "Check the URL and that the endpoint is publicly reachable", but the probe in IBM/mcp-context-forge#6405 runs in-process with no outbound call, and the URL is not editable here. The likeliest transport failure is the backend's "Virtual server 'X' is disabled. Enable it before testing the connection", which arrives as failure_class="transport" and gets that line appended under it. protocol has the same issue.

Panel is English-only. All strings are hardcoded while the surrounding drawer uses intl.formatMessage. main's TestConnectionPanel already has 28 mcpServer.testConnection.* keys across en-US, es-ES and pt-BR covering the headline, failure classes, credential sources, negotiation path and counts. No locale keys are added, so es-ES and pt-BR render an English tab. The new session credential source needs a key in all three files.

Related to the last one: validateHeaders here is TestConnectionPanel's minus its "Header values must be strings" check, so {"X": 1} passes client validation and returns a 422.

@marekdano
marekdano force-pushed the 5650-virtual-server-test-connection branch from e908afd to f827970 Compare August 26, 2026 10:33
@marekdano
marekdano requested a review from a-effort August 26, 2026 10:36

@vishu-bh vishu-bh 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.

Solid implementation, positive direction. Needs one minor check

useEffect(() => () => abortRef.current?.abort(), []);

const handleTest = useCallback(async () => {
setResult(null);

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.

setResult(null) runs before validation, but invalid headers return without resetting status. After a successful test, enter invalid JSON and click “Re-test”: panel still renders “Handshake succeeded” even though no request ran. Reset status before returning (or preserve prior result), and add regression test for success → invalid re-test.

Signed-off-by: Marek Dano <mk.dano@gmail.com>
… endpoint

IBM/mcp-context-forge#6405 replaces the gateway-scoped test-handshake call
this panel relied on (which could never succeed for a virtual server, per
IBM/mcp-context-forge#6370) with POST /v1/virtual-servers/{id}/test-handshake,
which derives its target from the server's own ID instead of a caller-supplied
URL. Update HandshakeTestPanel to call the new endpoint by server ID, drop the
now-meaningless URL input in favor of a read-only endpoint display, and add
the "session" credential source the new endpoint can report.

Signed-off-by: Marek Dano <mk.dano@gmail.com>
Signed-off-by: Marek Dano <mk.dano@gmail.com>
Signed-off-by: Marek Dano <mk.dano@gmail.com>
@marekdano
marekdano force-pushed the 5650-virtual-server-test-connection branch from f827970 to b4fbd75 Compare August 26, 2026 14:11

@vishu-bh vishu-bh 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.

LGTM 🚀

@marekdano
marekdano requested a review from vishu-bh August 28, 2026 14:24
@marekdano

marekdano commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

@a-effort, @gcgoncalves , @vishu-bh
I updated this PR to match Anna's design
The blocked issue IBM/mcp-context-forge#6370 is fixed and merged in the PR IBM/mcp-context-forge#6405
So the feature to test the connection of virtual servers can now be tested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants