Skip to content

Commit a0840f7

Browse files
gate behind registry-enabled flag
1 parent c9dfb33 commit a0840f7

File tree

5 files changed

+74
-14
lines changed

5 files changed

+74
-14
lines changed

mcpjam-inspector/client/src/App.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ export default function App() {
145145
);
146146
const learningEnabled = useFeatureFlagEnabled("mcpjam-learning");
147147
const clientConfigEnabled = useFeatureFlagEnabled("client-config-enabled");
148+
const registryEnabled = useFeatureFlagEnabled("registry-enabled");
148149
const {
149150
getAccessToken,
150151
signIn,
@@ -657,6 +658,11 @@ export default function App() {
657658
)} plan. Upgrade the organization to continue.`,
658659
);
659660
applyNavigation("servers", { updateHash: true });
661+
} else if (
662+
activeTab === "registry" &&
663+
registryEnabled !== true
664+
) {
665+
applyNavigation("servers", { updateHash: true });
660666
} else if (
661667
activeTab === "learning" &&
662668
(learningEnabled !== true || !isAuthenticated)
@@ -671,6 +677,7 @@ export default function App() {
671677
}, [
672678
ciEvalsEnabled,
673679
clientConfigEnabled,
680+
registryEnabled,
674681
activeTabBillingFeature,
675682
activeTabBillingLocked,
676683
learningEnabled,
@@ -892,10 +899,15 @@ export default function App() {
892899
isLoadingWorkspaces={isLoadingRemoteWorkspaces}
893900
onWorkspaceShared={handleWorkspaceShared}
894901
onLeaveWorkspace={() => handleLeaveWorkspace(activeWorkspaceId)}
895-
onNavigateToRegistry={() => handleNavigate("registry")}
902+
isRegistryEnabled={registryEnabled === true}
903+
onNavigateToRegistry={
904+
registryEnabled === true
905+
? () => handleNavigate("registry")
906+
: undefined
907+
}
896908
/>
897909
)}
898-
{activeTab === "registry" && (
910+
{activeTab === "registry" && registryEnabled === true && (
899911
<RegistryTab
900912
workspaceId={convexWorkspaceId}
901913
isAuthenticated={isAuthenticated}

mcpjam-inspector/client/src/components/ServersTab.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ interface ServersTabProps {
375375
isLoadingWorkspaces?: boolean;
376376
onWorkspaceShared?: (sharedWorkspaceId: string) => void;
377377
onLeaveWorkspace?: () => void;
378+
isRegistryEnabled?: boolean;
378379
onNavigateToRegistry?: () => void;
379380
}
380381

@@ -389,6 +390,7 @@ export function ServersTab({
389390
activeWorkspaceId,
390391
isLoadingWorkspaces,
391392
onWorkspaceShared,
393+
isRegistryEnabled = false,
392394
onNavigateToRegistry,
393395
}: ServersTabProps) {
394396
const posthog = usePostHog();
@@ -403,6 +405,7 @@ export function ServersTab({
403405
isLoading: isRegistryCatalogLoading,
404406
connect: connectRegistryServer,
405407
} = useRegistryServers({
408+
enabled: isRegistryEnabled,
406409
workspaceId: registryWorkspaceId,
407410
isAuthenticated,
408411
liveServers: workspaceServers,
@@ -632,12 +635,15 @@ export function ServersTab({
632635
}, [totalServerCards]);
633636

634637
const shouldShowQuickConnect =
635-
isRegistryCatalogLoading ||
636-
quickConnectCatalogAvailableCount > 0 ||
637-
isPendingQuickConnectVisible;
638+
isRegistryEnabled &&
639+
(isRegistryCatalogLoading ||
640+
quickConnectCatalogAvailableCount > 0 ||
641+
isPendingQuickConnectVisible);
638642

639643
const shouldShowBrowseRegistryOnly =
640-
!shouldShowQuickConnect && quickConnectCatalogAvailableCount > 0;
644+
isRegistryEnabled &&
645+
!shouldShowQuickConnect &&
646+
quickConnectCatalogAvailableCount > 0;
641647

642648
const activeWorkspace = workspaces[activeWorkspaceId];
643649
const sharedWorkspaceId = activeWorkspace?.sharedWorkspaceId;

mcpjam-inspector/client/src/components/__tests__/ServersTab.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ describe("ServersTab shared detail modal", () => {
384384
isLoadingWorkspaces: false,
385385
onWorkspaceShared: vi.fn(),
386386
onLeaveWorkspace: vi.fn(),
387+
isRegistryEnabled: true,
387388
onNavigateToRegistry: vi.fn(),
388389
};
389390

@@ -982,6 +983,32 @@ describe("ServersTab shared detail modal", () => {
982983
).not.toBeInTheDocument();
983984
});
984985

986+
it("hides quick connect and browse registry when the registry flag is disabled", () => {
987+
mockIsAuthenticated = true;
988+
mockCatalogCards = [createLinearCatalogCard()];
989+
990+
render(
991+
<ServersTab
992+
{...defaultProps}
993+
isRegistryEnabled={false}
994+
onNavigateToRegistry={undefined}
995+
workspaceServers={{}}
996+
/>,
997+
);
998+
999+
expect(
1000+
screen.queryByTestId("servers-quick-connect-section"),
1001+
).not.toBeInTheDocument();
1002+
expect(
1003+
screen.queryByTestId("servers-tab-browse-registry-header-fallback"),
1004+
).not.toBeInTheDocument();
1005+
expect(mockUseRegistryServers).toHaveBeenCalledWith(
1006+
expect.objectContaining({
1007+
enabled: false,
1008+
}),
1009+
);
1010+
});
1011+
9851012
it("passes the shared workspace id to registry queries instead of the local workspace key", () => {
9861013
mockIsAuthenticated = true;
9871014
mockCatalogCards = [createLinearCatalogCard()];
@@ -1000,6 +1027,7 @@ describe("ServersTab shared detail modal", () => {
10001027

10011028
expect(mockUseRegistryServers).toHaveBeenCalledWith(
10021029
expect.objectContaining({
1030+
enabled: true,
10031031
workspaceId: "ws_shared_123",
10041032
}),
10051033
);
@@ -1020,6 +1048,7 @@ describe("ServersTab shared detail modal", () => {
10201048

10211049
expect(mockUseRegistryServers).toHaveBeenCalledWith(
10221050
expect.objectContaining({
1051+
enabled: true,
10231052
workspaceId: null,
10241053
}),
10251054
);

mcpjam-inspector/client/src/components/mcp-sidebar.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ const navigationSections: NavSection[] = [
138138
title: "Registry",
139139
url: "#registry",
140140
icon: LayoutGrid,
141+
featureFlag: "registry-enabled",
141142
},
142143
{
143144
title: "Chat",
@@ -330,6 +331,7 @@ export function MCPSidebar({
330331
const learningFlagEnabled = useFeatureFlagEnabled("mcpjam-learning");
331332
const sandboxesEnabled = useFeatureFlagEnabled("sandboxes-enabled");
332333
const clientConfigEnabled = useFeatureFlagEnabled("client-config-enabled");
334+
const registryEnabled = useFeatureFlagEnabled("registry-enabled");
333335
const { isAuthenticated } = useConvexAuth();
334336
const learningEnabled = !!learningFlagEnabled && isAuthenticated;
335337
const themeMode = usePreferencesStore((s) => s.themeMode);
@@ -433,12 +435,14 @@ export function MCPSidebar({
433435
"mcpjam-learning": !!learningEnabled,
434436
"sandboxes-enabled": !!sandboxesEnabled && isAuthenticated,
435437
"client-config-enabled": !!clientConfigEnabled && isAuthenticated,
438+
"registry-enabled": registryEnabled === true,
436439
}),
437440
[
438441
ciEvalsEnabled,
439442
learningEnabled,
440443
sandboxesEnabled,
441444
clientConfigEnabled,
445+
registryEnabled,
442446
isAuthenticated,
443447
],
444448
);

mcpjam-inspector/client/src/hooks/useRegistryServers.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,14 @@ function isMissingWorkspaceConnectionError(error: unknown): boolean {
360360
* Pattern follows useWorkspaceMutations / useServerMutations in useWorkspaces.ts.
361361
*/
362362
export function useRegistryServers({
363+
enabled = true,
363364
workspaceId,
364365
isAuthenticated,
365366
liveServers,
366367
onConnect,
367368
onDisconnect,
368369
}: {
370+
enabled?: boolean;
369371
workspaceId: string | null;
370372
isAuthenticated: boolean;
371373
liveServers?: Record<string, { connectionStatus: string }>;
@@ -401,11 +403,13 @@ export function useRegistryServers({
401403
}, []);
402404

403405
useEffect(() => {
406+
if (!enabled) return;
404407
if (DEV_MOCK_REGISTRY) return;
405408
void loadCatalog();
406-
}, [loadCatalog]);
409+
}, [enabled, loadCatalog]);
407410

408411
useEffect(() => {
412+
if (!enabled) return;
409413
if (!HOSTED_MODE || !isAuthenticated || DEV_MOCK_REGISTRY) return;
410414
const guestToken = peekStoredGuestToken();
411415
if (!guestToken || mergeRanRef.current) return;
@@ -425,11 +429,11 @@ export function useRegistryServers({
425429
toast.error(message);
426430
}
427431
})();
428-
}, [isAuthenticated, loadCatalog]);
432+
}, [enabled, isAuthenticated, loadCatalog]);
429433

430434
const connections = useQuery(
431435
"registryServers:getWorkspaceRegistryConnections" as any,
432-
!DEV_MOCK_REGISTRY && isAuthenticated && workspaceId
436+
enabled && !DEV_MOCK_REGISTRY && isAuthenticated && workspaceId
433437
? ({ workspaceId } as any)
434438
: "skip",
435439
) as RegistryServerConnection[] | undefined;
@@ -447,30 +451,33 @@ export function useRegistryServers({
447451
}, [connections]);
448452

449453
const catalogCards = useMemo(() => {
454+
if (!enabled) return [];
450455
if (rawCatalog === null) return [];
451456
const enriched = enrichCatalogCards(
452457
rawCatalog,
453458
connectedRegistryIds,
454459
liveServers,
455460
);
456461
return sortCatalogCards(enriched);
457-
}, [rawCatalog, connectedRegistryIds, liveServers]);
462+
}, [enabled, rawCatalog, connectedRegistryIds, liveServers]);
458463

459464
const categories = useMemo(() => {
465+
if (!enabled) return [];
460466
const cats = new Set<string>();
461467
for (const card of catalogCards) {
462468
for (const v of card.variants) {
463469
if (v.category) cats.add(v.category);
464470
}
465471
}
466472
return Array.from(cats).sort();
467-
}, [catalogCards]);
473+
}, [enabled, catalogCards]);
468474

469475
const [pendingServerIds, setPendingServerIds] = useState<Map<string, string>>(
470476
new Map(),
471477
);
472478

473479
useEffect(() => {
480+
if (!enabled) return;
474481
if (!isAuthenticated || !workspaceId || DEV_MOCK_REGISTRY) return;
475482
for (const [registryServerId, serverName] of pendingServerIds) {
476483
if (connectedRegistryIds.has(registryServerId)) {
@@ -500,18 +507,20 @@ export function useRegistryServers({
500507
pendingServerIds,
501508
isAuthenticated,
502509
workspaceId,
510+
enabled,
503511
connectMutation,
504512
connectedRegistryIds,
505513
]);
506514

507515
const connectionsAreLoading =
516+
enabled &&
508517
!DEV_MOCK_REGISTRY &&
509518
isAuthenticated &&
510519
!!workspaceId &&
511520
connections === undefined;
512521

513522
const isLoading =
514-
!DEV_MOCK_REGISTRY && (rawCatalog === null || connectionsAreLoading);
523+
enabled && !DEV_MOCK_REGISTRY && (rawCatalog === null || connectionsAreLoading);
515524

516525
const toggleStar = useCallback(
517526
async (registryCardKey: string) => {
@@ -635,8 +644,8 @@ export function useRegistryServers({
635644

636645
/** Flat list of enriched servers for legacy callers / tests */
637646
const registryServers = useMemo(
638-
() => catalogCards.flatMap((c) => c.variants),
639-
[catalogCards],
647+
() => (enabled ? catalogCards.flatMap((c) => c.variants) : []),
648+
[enabled, catalogCards],
640649
);
641650

642651
return {

0 commit comments

Comments
 (0)