diff --git a/clients/web/src/App.tsx b/clients/web/src/App.tsx
index a1a313e7..7d64073c 100644
--- a/clients/web/src/App.tsx
+++ b/clients/web/src/App.tsx
@@ -1,41 +1,59 @@
import {
- Title,
- Text,
- Container,
- Stack,
- useMantineColorScheme,
- useComputedColorScheme,
ActionIcon,
+ Container,
Group,
+ Stack,
+ Text,
+ Title,
+ useComputedColorScheme,
+ useMantineColorScheme,
} from "@mantine/core";
+import { MdDarkMode, MdLightMode } from "react-icons/md";
+
+const PageContainer = Container.withProps({
+ size: "sm",
+ py: "xl",
+});
+
+const PageStack = Stack.withProps({
+ align: "center",
+ gap: "md",
+});
+
+const ThemeToggle = ActionIcon.withProps({
+ variant: "default",
+ size: "lg",
+ "aria-label": "Toggle color scheme",
+});
+
+const SubtitleText = Text.withProps({
+ c: "var(--inspector-text-secondary)",
+});
function App() {
const { setColorScheme } = useMantineColorScheme();
const computedColorScheme = useComputedColorScheme("light");
+ const isDark = computedColorScheme === "dark";
+ const ThemeIcon = isDark ? MdLightMode : MdDarkMode;
- const toggleColorScheme = () => {
- setColorScheme(computedColorScheme === "dark" ? "light" : "dark");
- };
+ function toggleColorScheme() {
+ setColorScheme(isDark ? "light" : "dark");
+ }
return (
-
-
+
+
MCP Inspector
-
- {computedColorScheme === "dark" ? "\u2600" : "\u263E"}
-
+
+
+
-
+
Web client for the Model Context Protocol Inspector
-
-
-
+
+
+
);
}
diff --git a/clients/web/src/components/views/InspectorView/InspectorView.tsx b/clients/web/src/components/views/InspectorView/InspectorView.tsx
index 0371d6e9..c2ec403e 100644
--- a/clients/web/src/components/views/InspectorView/InspectorView.tsx
+++ b/clients/web/src/components/views/InspectorView/InspectorView.tsx
@@ -1,5 +1,5 @@
-import { useMemo, useState } from "react";
-import { AppShell } from "@mantine/core";
+import { useMemo, useState, type ReactNode } from "react";
+import { AppShell, Box, Stack, Transition } from "@mantine/core";
import type {
InitializeResult,
LoggingLevel,
@@ -35,11 +35,45 @@ const ALL_TABS: string[] = [
"Tools",
"Prompts",
"Resources",
- "Logs",
"Tasks",
+ "Logs",
"History",
];
+const SCREEN_TRANSITION_MS = 350;
+
+const ScreenStageContainer = Stack.withProps({
+ pos: "relative",
+ gap: 0,
+ flex: 1,
+ mih: "100%",
+});
+
+function ScreenStage({
+ active,
+ children,
+}: {
+ active: boolean;
+ children: ReactNode;
+}) {
+ return (
+
+ {(styles) => (
+ // `style={styles}` is the runtime transition state from Mantine's
+ // Transition API — these are interpolated values, not static styling.
+
+ {children}
+
+ )}
+
+ );
+}
+
// Demo stub: every screen-action callback below resolves to noop. Phase 3
// wiring will replace each with its real `useManaged*` / `useConnection`
// hook call. Anything still pointing here in Phase 3 is unfinished.
@@ -204,84 +238,86 @@ export function InspectorView({
)}
- {activeTab === SERVERS_TAB && (
-
- )}
- {activeTab === "Tools" && (
-
- )}
- {activeTab === "Prompts" && (
-
- )}
- {activeTab === "Resources" && (
-
- )}
- {activeTab === "Logs" && (
- setAutoScroll((prev) => !prev)}
- onCopyAll={noop}
- />
- )}
- {activeTab === "Tasks" && (
-
- )}
- {activeTab === "History" && (
-
- )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setAutoScroll((prev) => !prev)}
+ onCopyAll={noop}
+ />
+
+
+
+
+
);