@mexl/backstage-plugin-mcp-frontend
Version:
Enhanced Backstage frontend plugin for MCP (Model Context Protocol) entity visualization with JSON/Text toggle, syntax highlighting, and VSCode integration
215 lines (212 loc) • 8.04 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { makeStyles, Card, CardHeader, CardContent, Box, Typography, Chip, Table, TableBody, TableRow, TableCell, Link } from '@material-ui/core';
import { useEntity } from '@backstage/plugin-catalog-react';
const useStyles = makeStyles((theme) => ({
card: {
height: "100%"
},
section: {
marginBottom: theme.spacing(2)
},
table: {
marginBottom: theme.spacing(2)
},
linkChip: {
margin: theme.spacing(0.25),
fontSize: "0.75rem"
},
tagChip: {
margin: theme.spacing(0.25),
fontSize: "0.75rem"
}
}));
const MCPMetadataCard = () => {
const { entity } = useEntity();
const classes = useStyles();
if (!entity || entity.kind !== "MCP") {
return null;
}
const spec = entity.spec;
const metadata = spec.metadata;
if (!metadata) {
return null;
}
const renderPricing = (pricing) => {
if (!pricing) return null;
const getPricingColor = (model) => {
switch (model) {
case "free":
return "primary";
case "freemium":
return "default";
case "paid":
return "secondary";
case "enterprise":
return "default";
default:
return "default";
}
};
return /* @__PURE__ */ jsxs(Box, { className: classes.section, children: [
/* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "Pricing" }),
/* @__PURE__ */ jsx(Box, { display: "flex", alignItems: "center", style: { gap: 8 }, mb: 1, children: /* @__PURE__ */ jsx(
Chip,
{
label: pricing.model,
size: "small",
color: getPricingColor(pricing.model)
}
) }),
pricing.details && /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: pricing.details })
] });
};
const renderLimits = (limits) => {
if (!limits) return null;
return /* @__PURE__ */ jsxs(Box, { className: classes.section, children: [
/* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "Rate Limits" }),
/* @__PURE__ */ jsx(Table, { size: "small", className: classes.table, children: /* @__PURE__ */ jsxs(TableBody, { children: [
limits.requestsPerMinute && /* @__PURE__ */ jsxs(TableRow, { children: [
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx("strong", { children: "Per Minute" }) }),
/* @__PURE__ */ jsx(TableCell, { children: limits.requestsPerMinute.toLocaleString() })
] }),
limits.requestsPerHour && /* @__PURE__ */ jsxs(TableRow, { children: [
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx("strong", { children: "Per Hour" }) }),
/* @__PURE__ */ jsx(TableCell, { children: limits.requestsPerHour.toLocaleString() })
] }),
limits.requestsPerDay && /* @__PURE__ */ jsxs(TableRow, { children: [
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx("strong", { children: "Per Day" }) }),
/* @__PURE__ */ jsx(TableCell, { children: limits.requestsPerDay.toLocaleString() })
] }),
limits.maxConcurrentConnections && /* @__PURE__ */ jsxs(TableRow, { children: [
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx("strong", { children: "Max Connections" }) }),
/* @__PURE__ */ jsx(TableCell, { children: limits.maxConcurrentConnections })
] })
] }) })
] });
};
const renderSupport = (support) => {
if (!support) return null;
const supportLinks = [
{ key: "documentation", label: "Documentation", url: support.documentation },
{ key: "community", label: "Community", url: support.community },
{ key: "issues", label: "Issues", url: support.issues },
{ key: "examples", label: "Examples", url: support.examples }
].filter((link) => link.url);
if (supportLinks.length === 0) return null;
return /* @__PURE__ */ jsxs(Box, { className: classes.section, children: [
/* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "Support Resources" }),
/* @__PURE__ */ jsx(Box, { children: supportLinks.map((link) => /* @__PURE__ */ jsx(
Link,
{
href: link.url,
target: "_blank",
rel: "noopener noreferrer",
style: { textDecoration: "none" },
children: /* @__PURE__ */ jsx(
Chip,
{
label: link.label,
clickable: true,
variant: "outlined",
size: "small",
className: classes.linkChip
}
)
},
link.key
)) })
] });
};
const renderMaturity = (maturity) => {
if (!maturity) return null;
const getStabilityColor = (stability) => {
switch (stability) {
case "alpha":
return "default";
case "beta":
return "primary";
case "stable":
return "primary";
case "mature":
return "secondary";
default:
return "default";
}
};
const getMaintenanceColor = (status) => {
switch (status) {
case "active":
return "primary";
case "maintenance":
return "default";
case "deprecated":
return "secondary";
default:
return "default";
}
};
return /* @__PURE__ */ jsxs(Box, { className: classes.section, children: [
/* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "Maturity Status" }),
/* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", style: { gap: 8 }, children: [
/* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", style: { gap: 8 }, children: [
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: "Stability:" }),
/* @__PURE__ */ jsx(
Chip,
{
label: maturity.stability,
size: "small",
color: getStabilityColor(maturity.stability)
}
)
] }),
/* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", style: { gap: 8 }, children: [
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: "Maintenance:" }),
/* @__PURE__ */ jsx(
Chip,
{
label: maturity.maintenanceStatus,
size: "small",
color: getMaintenanceColor(maturity.maintenanceStatus)
}
)
] }),
maturity.lastUpdated && /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
"Last updated: ",
new Date(maturity.lastUpdated).toLocaleDateString()
] })
] })
] });
};
const renderTags = (tags) => {
if (!tags || tags.length === 0) return null;
return /* @__PURE__ */ jsxs(Box, { className: classes.section, children: [
/* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "Tags" }),
/* @__PURE__ */ jsx(Box, { children: tags.map((tag, index) => /* @__PURE__ */ jsx(
Chip,
{
label: tag,
size: "small",
variant: "outlined",
className: classes.tagChip
},
index
)) })
] });
};
const hasMetadata = metadata.pricing || metadata.limits || metadata.support || metadata.maturity || metadata.tags && metadata.tags.length > 0;
if (!hasMetadata) {
return null;
}
return /* @__PURE__ */ jsxs(Card, { className: classes.card, children: [
/* @__PURE__ */ jsx(CardHeader, { title: "Metadata" }),
/* @__PURE__ */ jsxs(CardContent, { children: [
renderPricing(metadata.pricing),
renderLimits(metadata.limits),
renderSupport(metadata.support),
renderMaturity(metadata.maturity),
renderTags(metadata.tags)
] })
] });
};
export { MCPMetadataCard };
//# sourceMappingURL=MCPMetadataCard.esm.js.map