Files
fusion/packages/dashboard/app/components/settings/sections/McpServersCard.css
gsxdsm f685518a93 FN-7064: discover MCP servers in settings
Add read-only MCP discovery with settings UI controls that keep discovered secrets bound to Fusion secret references.

- Add core MCP discovery source resolution and parsing for supported global and project tool configs.
- Expose discovered MCP server candidates through the dashboard API and engine discovery service.
- Surface discovered servers in global and project MCP settings with explicit add flows and configured-state handling.
- Require discovered sensitive env/header/token descriptors to stay locked until bound or created as Fusion secret references.
- Document discovery behavior and add a published package changeset.

Files changed:
 .changeset/fn-7064-mcp-auto-discovery.md           |   7 ++
 docs/dashboard-guide.md                            |   3 +-
 docs/mcp.md                                        |  53 ++++++++-
 docs/settings-reference.md                         |   4 +-
 packages/core/src/__tests__/mcp-discovery.test.ts  |  74 ++++++++++++
 packages/core/src/index.ts                         |   7 ++
 packages/core/src/mcp-discovery.ts                 | 125 ++++++++++++++++++++
 .../__tests__/SettingsModal.mcp.test.tsx           |  76 +++++++++++-
 .../settings/sections/McpServersCard.css           |  34 +++++-
 .../settings/sections/McpServersCard.tsx           | 130 ++++++++++++++++++++-
 .../src/__tests__/mcp-discovered-route.test.ts     | 109 +++++++++++++++++
 packages/dashboard/src/routes.ts                   |  46 ++++++++
 .../src/__tests__/mcp-discovery-service.test.ts    |  60 ++++++++++
 packages/engine/src/index.ts                       |   1 +
 packages/engine/src/mcp-discovery-service.ts       |  65 +++++++++++
 15 files changed, 782 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7064
Fusion-Task-Lineage: ef5dc53f-f8d1-4cc8-bdaf-e98d63ee8406
2026-06-26 11:56:12 -07:00

210 lines
4.1 KiB
CSS

.mcp-servers-card {
display: flex;
flex-direction: column;
gap: var(--space-md);
}
.mcp-servers-card__header,
.mcp-server-row,
.mcp-discovery__header,
.mcp-discovery-row,
.mcp-import-export,
.mcp-sensitive-row,
.mcp-inline-actions {
display: flex;
gap: var(--space-md);
}
.mcp-servers-card__header,
.mcp-server-row,
.mcp-discovery__header,
.mcp-discovery-row {
align-items: flex-start;
justify-content: space-between;
}
.mcp-servers-card__title,
.mcp-server-row p,
.mcp-discovery p,
.mcp-discovery h6,
.mcp-import-export h6 {
margin: 0;
}
.mcp-servers-card__description,
.mcp-server-row p,
.mcp-discovery p,
.mcp-empty,
.mcp-empty-inline,
.mcp-effective-count {
color: var(--text-muted);
}
.mcp-server-list,
.mcp-discovery,
.mcp-discovery__group,
.mcp-editor,
.mcp-sensitive-list,
.mcp-import-export__pane,
.mcp-server-row__main {
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
.mcp-server-row,
.mcp-discovery,
.mcp-discovery-row,
.mcp-editor,
.mcp-import-export__pane {
padding: var(--space-md);
border: var(--border-width) solid var(--border);
border-radius: var(--radius-md);
background: var(--surface);
}
.mcp-discovery-row {
background: var(--surface-hover);
}
.mcp-discovery__notes,
.mcp-discovery-row__note {
color: var(--color-warning);
}
.mcp-server-row__titleline,
.mcp-validation-status,
.mcp-server-row__actions {
display: flex;
align-items: center;
gap: var(--space-sm);
flex-wrap: wrap;
}
.mcp-state-badge,
.mcp-transport-badge {
display: inline-flex;
align-items: center;
border-radius: var(--radius-full);
padding: var(--space-2xs) var(--space-xs);
font-size: var(--font-size-xs);
line-height: var(--line-height-tight);
border: var(--border-width) solid var(--border);
color: var(--text-muted);
}
.mcp-state-badge--disabled,
.mcp-state-badge--disabled-global {
color: var(--color-error);
background: color-mix(in srgb, var(--color-error) 12%, transparent);
}
.mcp-state-badge--overridden,
.mcp-state-badge--project-local {
color: var(--color-info);
background: color-mix(in srgb, var(--color-info) 12%, transparent);
}
.mcp-state-badge--inherited {
color: var(--color-warning);
background: color-mix(in srgb, var(--color-warning) 12%, transparent);
}
.mcp-state-badge--configured {
color: var(--color-success);
background: color-mix(in srgb, var(--color-success) 12%, transparent);
}
.mcp-state-badge--required {
color: var(--color-warning);
background: color-mix(in srgb, var(--color-warning) 12%, transparent);
}
.mcp-validation-status {
color: var(--text-muted);
}
.mcp-validation-status__badge {
display: inline-flex;
align-items: center;
border-radius: var(--radius-full);
padding: var(--space-2xs) var(--space-xs);
border: var(--border-width) solid var(--border);
color: inherit;
}
.mcp-validation-status--pending {
color: var(--color-warning);
}
.mcp-validation-status--valid {
color: var(--color-success);
}
.mcp-validation-status--unreachable,
.mcp-validation-status--error {
color: var(--color-error);
}
.mcp-editor-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-md);
}
.mcp-editor-grid__wide,
.mcp-import-export__pane,
.mcp-server-row__main {
flex: 1 1 auto;
min-width: 0;
}
.mcp-sensitive-row {
align-items: center;
flex-wrap: wrap;
}
.mcp-sensitive-row .input,
.mcp-sensitive-row .select {
flex: 1 1 var(--settings-field-min-width, 12rem);
min-width: 0;
}
.mcp-subheading {
font-weight: var(--font-weight-semibold);
}
.mcp-json-textarea {
min-height: calc(var(--space-xl) * 4);
resize: vertical;
font-family: var(--font-mono);
}
.mcp-enabled-toggle {
align-self: flex-start;
}
@media (max-width: 768px) {
.mcp-servers-card__header,
.mcp-server-row,
.mcp-discovery__header,
.mcp-discovery-row,
.mcp-import-export,
.mcp-server-row__actions,
.mcp-sensitive-row,
.mcp-inline-actions {
flex-direction: column;
align-items: stretch;
}
.mcp-editor-grid {
grid-template-columns: 1fr;
}
.mcp-server-row__actions .btn,
.mcp-inline-actions .btn,
.mcp-sensitive-row .btn {
justify-content: center;
}
}