Skip to content

Commit d8a640d

Browse files
committed
Add structured server.json sections: tools, expandable remotes, schema toggles
1 parent 3ff224d commit d8a640d

12 files changed

Lines changed: 1091 additions & 216 deletions

.github/actions/check-component-ids/componentId-registry.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,34 @@ module.exports = {
19181918
"mlflow.mcp_registry.detail.update_status_error": "",
19191919
"mlflow.mcp_registry.detail.update_status_modal": "",
19201920
"mlflow.mcp_registry.detail.update_status_terminal": "",
1921+
"mlflow.mcp_registry.detail.copy_package_identifier": "",
1922+
"mlflow.mcp_registry.detail.copy_package_identifier_button": "",
1923+
"mlflow.mcp_registry.detail.copy_remote_url": "",
1924+
"mlflow.mcp_registry.detail.copy_remote_url_button": "",
1925+
"mlflow.mcp_registry.detail.env_var_required": "",
1926+
"mlflow.mcp_registry.detail.env_var_secret": "",
1927+
"mlflow.mcp_registry.detail.header_required": "",
1928+
"mlflow.mcp_registry.detail.header_secret": "",
1929+
"mlflow.mcp_registry.detail.package_registry_tag": "",
1930+
"mlflow.mcp_registry.detail.raw_json.copy": "",
1931+
"mlflow.mcp_registry.detail.raw_json.copy_button": "",
1932+
"mlflow.mcp_registry.detail.raw_json.toggle": "",
1933+
"mlflow.mcp_registry.detail.raw_tools_json.copy": "",
1934+
"mlflow.mcp_registry.detail.raw_tools_json.copy_button": "",
1935+
"mlflow.mcp_registry.detail.raw_tools_json.toggle": "",
1936+
"mlflow.mcp_registry.detail.remote_transport_tag": "",
1937+
"mlflow.mcp_registry.detail.toggle_env_vars": "",
1938+
"mlflow.mcp_registry.detail.toggle_packages": "",
1939+
"mlflow.mcp_registry.detail.toggle_tools": "",
1940+
"mlflow.mcp_registry.detail.tool_annotation_tag": "",
1941+
"mlflow.mcp_registry.detail.tool_input_schema.copy": "",
1942+
"mlflow.mcp_registry.detail.tool_input_schema.copy_button": "",
1943+
"mlflow.mcp_registry.detail.tool_input_schema.toggle": "",
1944+
"mlflow.mcp_registry.detail.tool_name_tag": "",
1945+
"mlflow.mcp_registry.detail.tool_output_schema.copy": "",
1946+
"mlflow.mcp_registry.detail.tool_output_schema.copy_button": "",
1947+
"mlflow.mcp_registry.detail.tool_output_schema.toggle": "",
1948+
"mlflow.mcp_registry.detail.version_tabs": "",
19211949
"mlflow.mcp_registry.detail.version.add_description": "",
19221950
"mlflow.mcp_registry.detail.version.add_metadata": "",
19231951
"mlflow.mcp_registry.detail.version.description.error": "",

mlflow/server/js/src/mcp-registry/components/MCPServerAccessBindings.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ export const MCPServerAccessBindings = ({
146146
onClick={onAddBinding}
147147
size="small"
148148
>
149-
<FormattedMessage defaultMessage="Add access binding" description="MCP server add access binding button" />
149+
<FormattedMessage
150+
defaultMessage="Add access binding"
151+
description="MCP server add access binding button"
152+
/>
150153
</Button>
151154
)}
152155
</div>

mlflow/server/js/src/mcp-registry/components/MCPServerVersionDetail.tsx

Lines changed: 43 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Modal,
88
PencilIcon,
99
Spacer,
10+
Tabs,
1011
Tag,
1112
SimpleSelect,
1213
SimpleSelectOption,
@@ -20,14 +21,11 @@ import { FormattedMessage, useIntl } from 'react-intl';
2021
import type { MCPAccessBinding, MCPServer, MCPServerVersion } from '../types';
2122
import { STATUS_TAG_COLOR, STATUS_TRANSITIONS, resolveDisplayName } from '../utils';
2223
import type { MCPStatus } from '../types';
23-
import { CollapsibleSection } from '../../common/components/CollapsibleSection';
2424
import { MCPServerAccessBindings } from './MCPServerAccessBindings';
25+
import { ServerJSONSection, ToolsSection } from './ServerJSONSection';
2526
import { ConfirmationModal } from '../../admin/ConfirmationModal';
2627
import { ModelVersionTableAliasesCell } from '../../model-registry/components/aliases/ModelVersionTableAliasesCell';
27-
import {
28-
useUpdateMCPServerVersion,
29-
useDeleteMCPServerVersion,
30-
} from '../hooks/useMCPServerVersionMutations';
28+
import { useUpdateMCPServerVersion, useDeleteMCPServerVersion } from '../hooks/useMCPServerVersionMutations';
3129
import { KeyValueTag } from '../../common/components/KeyValueTag';
3230
import { AliasSelect } from '../../common/components/AliasSelect';
3331
import { LATEST_ALIAS, RESERVED_ALIASES, validateToolsJson } from '../utils';
@@ -73,7 +71,6 @@ export const MCPServerVersionDetail = ({
7371
const [editVersionToolsText, setEditVersionToolsText] = useState('');
7472
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
7573
const [toolsValidationError, setToolsValidationError] = useState<string | null>(null);
76-
7774
const updateVersionMutation = useUpdateMCPServerVersion(server.name);
7875
const deleteVersionMutation = useDeleteMCPServerVersion(server.name);
7976

@@ -280,122 +277,47 @@ export const MCPServerVersionDetail = ({
280277
</div>
281278
</div>
282279

283-
<div css={{ '& svg': { width: 14, height: 14 } }}>
284-
{version.server_json && (
285-
<CollapsibleSection
286-
title={
287-
<span
288-
css={{ fontWeight: theme.typography.typographyBoldFontWeight, fontSize: theme.typography.fontSizeBase }}
289-
>
290-
<FormattedMessage
291-
defaultMessage="Configuration"
292-
description="MCP server version detail configuration section heading"
293-
/>
294-
</span>
295-
}
296-
defaultCollapsed
297-
componentId="mlflow.mcp_registry.detail.configuration_section"
298-
>
299-
<pre
300-
css={{
301-
margin: 0,
302-
padding: theme.spacing.md,
303-
backgroundColor: theme.colors.backgroundSecondary,
304-
borderRadius: theme.borders.borderRadiusSm,
305-
overflow: 'auto',
306-
fontSize: theme.typography.fontSizeSm,
307-
}}
308-
>
309-
<code>{JSON.stringify(version.server_json, null, 2)}</code>
310-
</pre>
311-
</CollapsibleSection>
312-
)}
313-
{version.tools && version.tools.length > 0 && (
314-
<CollapsibleSection
315-
title={
316-
<span
317-
css={{ fontWeight: theme.typography.typographyBoldFontWeight, fontSize: theme.typography.fontSizeBase }}
318-
>
319-
<FormattedMessage
320-
defaultMessage="Tools <light>({count})</light>"
321-
description="MCP server version detail tools section heading"
322-
values={{
323-
count: version.tools.length,
324-
light: (chunks: React.ReactNode) => <span css={{ fontWeight: 'normal' }}>{chunks}</span>,
325-
}}
326-
/>
327-
</span>
328-
}
329-
defaultCollapsed
330-
componentId="mlflow.mcp_registry.detail.tools_section"
331-
>
332-
<Typography.Hint css={{ marginBottom: theme.spacing.sm }}>
280+
<Tabs.Root
281+
componentId="mlflow.mcp_registry.detail.version_tabs"
282+
valueHasNoPii
283+
defaultValue="configuration"
284+
css={{ marginTop: theme.spacing.md, '& svg': { width: 14, height: 14 } }}
285+
>
286+
<Tabs.List>
287+
<Tabs.Trigger value="configuration">
288+
<FormattedMessage
289+
defaultMessage="Configuration"
290+
description="MCP server version detail configuration tab"
291+
/>
292+
</Tabs.Trigger>
293+
{version.tools && version.tools.length > 0 && (
294+
<Tabs.Trigger value="tools">
333295
<FormattedMessage
334-
defaultMessage="Tools are observed from the live endpoint and may change between snapshots."
335-
description="MCP server version detail tools disclaimer"
296+
defaultMessage="Tools ({count})"
297+
description="MCP server version detail tools tab"
298+
values={{ count: version.tools.length }}
336299
/>
337-
</Typography.Hint>
338-
<div
339-
css={{
340-
display: 'grid',
341-
gridTemplateColumns: '1fr 1fr',
342-
gap: theme.spacing.sm,
343-
}}
344-
>
345-
{version.tools.map((tool) => (
346-
<div
347-
key={tool.name}
348-
css={{
349-
display: 'flex',
350-
alignItems: 'baseline',
351-
gap: theme.spacing.sm,
352-
padding: `${theme.spacing.sm}px ${theme.spacing.md}px`,
353-
border: `1px solid ${theme.colors.borderDecorative}`,
354-
borderRadius: theme.borders.borderRadiusMd,
355-
}}
356-
>
357-
<Tag
358-
componentId="mlflow.mcp_registry.detail.tool_name_tag"
359-
color="turquoise"
360-
css={{
361-
minWidth: 120,
362-
textAlign: 'center',
363-
flexShrink: 0,
364-
display: 'inline-flex',
365-
justifyContent: 'center',
366-
}}
367-
>
368-
{tool.name}
369-
</Tag>
370-
{tool.description && (
371-
<Typography.Text
372-
color="secondary"
373-
size="sm"
374-
css={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}
375-
>
376-
{tool.description}
377-
</Typography.Text>
378-
)}
379-
</div>
380-
))}
381-
</div>
382-
</CollapsibleSection>
300+
</Tabs.Trigger>
301+
)}
302+
<Tabs.Trigger value="access-bindings">
303+
<FormattedMessage
304+
defaultMessage="Access Bindings"
305+
description="MCP server version detail access bindings tab"
306+
/>
307+
</Tabs.Trigger>
308+
</Tabs.List>
309+
310+
<Tabs.Content value="configuration" css={{ paddingTop: theme.spacing.md }}>
311+
{version.server_json && <ServerJSONSection serverJson={version.server_json} />}
312+
</Tabs.Content>
313+
314+
{version.tools && version.tools.length > 0 && (
315+
<Tabs.Content value="tools" css={{ paddingTop: theme.spacing.md }}>
316+
<ToolsSection tools={version.tools} />
317+
</Tabs.Content>
383318
)}
384319

385-
<CollapsibleSection
386-
title={
387-
<span
388-
css={{ fontWeight: theme.typography.typographyBoldFontWeight, fontSize: theme.typography.fontSizeBase }}
389-
>
390-
<FormattedMessage
391-
defaultMessage="Access Bindings"
392-
description="MCP server version detail access bindings section heading"
393-
/>
394-
</span>
395-
}
396-
defaultCollapsed
397-
componentId="mlflow.mcp_registry.detail.bindings_section"
398-
>
320+
<Tabs.Content value="access-bindings" css={{ paddingTop: theme.spacing.md }}>
399321
<MCPServerAccessBindings
400322
server={server}
401323
bindings={bindings}
@@ -406,8 +328,8 @@ export const MCPServerVersionDetail = ({
406328
onDeleteBinding={onDeleteBinding}
407329
hideTitle
408330
/>
409-
</CollapsibleSection>
410-
</div>
331+
</Tabs.Content>
332+
</Tabs.Root>
411333

412334
<Modal
413335
componentId="mlflow.mcp_registry.detail.version.edit_version_modal"
@@ -469,7 +391,7 @@ export const MCPServerVersionDetail = ({
469391
type="error"
470392
closable
471393
onClose={() => updateVersionMutation.reset()}
472-
message={(updateVersionMutation.error as Error).message}
394+
message={updateVersionMutation.error instanceof Error ? updateVersionMutation.error.message : String(updateVersionMutation.error)}
473395
css={{ marginBottom: theme.spacing.sm }}
474396
/>
475397
)}

0 commit comments

Comments
 (0)