M9: MCP Hub locale/correlation propagation, real Hub health check, fix stale test image
Fixed two concrete gaps in the MCP knowledge-search endpoint: no locale field existed at all (now nl-BE/en-GB/fr-BE, wired to the knowledge provider's existing language param), and the correlation ID was always freshly minted, ignoring any inbound X-Correlation-Id header. Added a shared dependency and applied it to all four MCP endpoints so Fleet Ops's own audit log preserves the Hub's real correlation ID end to end. MCP_HUB_BASE_URL/MCP_PROVIDER_ID were declared in .env.example but never read anywhere. Since the Hub's own registration is catalog-driven (it never needs Fleet Ops to push a registration call), wired mcp_hub_base_url for a real Hub reachability health check instead of an unneeded self-registration call. Renamed Fleet Ops's own internal audit tool labels mobilityops_* -> fleet_ops_* (mirrored in contracts/mcp-tools.json with mobilityops_* kept as deprecated aliases); documented that the live Hub connector's own dotted tool namespace is a separate, Hub-owned naming layer, deliberately not touched. Automation page's MCP card now shows real evidence (last tool/client/count/ timestamp, honest no-evidence state) instead of just the registration flag. Also fixed a real methodology gap found mid-session: compose.yaml's api service has no bind mount, so `docker compose run --rm api` silently tests a stale image until rebuilt. Re-ran every local gate after rebuilding; fixed one genuinely stale test assertion and two lint line-length errors surfaced by that rebuild. 176 tests passing, ruff clean, mypy clean (50 files). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2ae2044e3a
commit
727c19a779
@@ -209,12 +209,32 @@ export function Automation() {
|
||||
<div>
|
||||
<span className="integration-kicker">{t("cards.gatewayKicker")}</span>
|
||||
<h2>{t("cards.mcpTitle")}</h2>
|
||||
<p>{integrationStatus?.mcp_hub.registration_enabled ? t("cards.mcpEnabled") : t("cards.mcpNotConnected")}</p>
|
||||
<p>
|
||||
{(() => {
|
||||
const hub = integrationStatus?.mcp_hub;
|
||||
if (!hub?.registration_enabled) return t("cards.mcpNotConnected");
|
||||
if (hub.total_calls > 0) {
|
||||
return t("cards.mcpEvidence", { tool: hub.last_tool, client: hub.last_client, count: hub.total_calls });
|
||||
}
|
||||
return t("cards.mcpNoEvidence");
|
||||
})()}
|
||||
</p>
|
||||
{integrationStatus?.mcp_hub.last_called_at && (
|
||||
<small>{formatDateTime(integrationStatus.mcp_hub.last_called_at)}</small>
|
||||
)}
|
||||
</div>
|
||||
<div className="integration-badge-stack">
|
||||
{(() => {
|
||||
const meta = integrationStatus ? MCP_STATE_META[integrationStatus.mcp_hub.state] : null;
|
||||
return <StatusBadge status={meta?.statusClass ?? "not_configured"} label={meta ? t(`statusLabels.${meta.labelKey}`) : undefined} />;
|
||||
})()}
|
||||
{integrationStatus?.mcp_hub.hub_reachable !== null && integrationStatus?.mcp_hub.hub_reachable !== undefined && (
|
||||
<StatusBadge
|
||||
status={integrationStatus.mcp_hub.hub_reachable ? "available" : "unavailable"}
|
||||
label={t(integrationStatus.mcp_hub.hub_reachable ? "cards.mcpHubReachable" : "cards.mcpHubUnreachable")}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{(() => {
|
||||
const meta = integrationStatus ? MCP_STATE_META[integrationStatus.mcp_hub.state] : null;
|
||||
return <StatusBadge status={meta?.statusClass ?? "not_configured"} label={meta ? t(`statusLabels.${meta.labelKey}`) : undefined} />;
|
||||
})()}
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user