Skip to content

feat: warn users before making an mcp server public with system-provided env vars#2289

Merged
simplesagar merged 13 commits intomainfrom
worktree-swift-ray-srn6
Apr 19, 2026
Merged

feat: warn users before making an mcp server public with system-provided env vars#2289
simplesagar merged 13 commits intomainfrom
worktree-swift-ray-srn6

Conversation

@simplesagar
Copy link
Copy Markdown
Member

@simplesagar simplesagar commented Apr 19, 2026

Summary

  • Adds a confirmation dialog that fires before flipping an MCP server to Public when the attached environment has any variables currently injected server-side (state: "system"). Public MCP + system var = shared secret across every caller, which is easy to miss in the existing UI.
  • Lists the affected variable names in the dialog and links directly to the attached environment's detail page so the user can review before confirming.
  • Disables the "Public" option in the status dropdown while the MCP metadata or environments query is still loading, so the warning can't be silently bypassed on a cold page-load.
  • Adds system_vars_warned: boolean | undefined to the mcp_made_public telemetry event so we can track how often users see the warning vs. go straight through.

Scope

  • New: getSystemProvidedVariables(envVars, slug) pure helper + unit tests in client/dashboard/src/pages/mcp/environmentVariableUtils.{ts,test.ts}.
  • New: PublicMcpWarningDialog component + tests at client/dashboard/src/components/public-mcp-warning-dialog.{tsx,test.tsx}. Uses Diatype Mono for the variable-name list and a Swift-red accent border/icon; otherwise defers to the moonshine Dialog + Button primitives for default typography and layout. A11y: Dialog.Description wraps the body, decorative icons are aria-hidden.
  • Modified: client/dashboard/src/pages/mcp/MCPDetails.tsx (MCPStatusDropdown) — fetches the attached environment + metadata, routes public transitions through the new dialog, chains into the existing ServerEnableDialog on disabled → public, and snapshots the source status at dialog-open time to avoid a stale-closure race with toolset query revalidation.

Behavior matrix

From To System vars present? UX
private public yes Warning dialog → confirm → mutate
private public no No dialog, immediate mutate (unchanged)
disabled public yes Warning dialog → confirm → ServerEnableDialog → confirm → mutate
disabled public no ServerEnableDialog only (unchanged)
public private No dialog (unchanged)
* * metadata or environments query loading + target=public Public option disabled in dropdown until both queries land

Test plan

  • cd client/dashboard && pnpm test src/pages/mcp/environmentVariableUtils.test.ts — 4 helper tests pass
  • cd client/dashboard && pnpm test src/components/public-mcp-warning-dialog.test.tsx — 3 dialog tests pass
  • cd client/dashboard && pnpm tsc -p tsconfig.app.json --noEmit — no new type errors in MCPDetails.tsx
  • Manual: attach an env with a required system variable, flip private → public → warning dialog lists the var name and links to the env detail page
  • Manual: private → public without system vars → no dialog (preserves current behavior)
  • Manual: disabled → public with system vars → warning first, then ServerEnableDialog, then mutation
  • Manual: toolset with no metadata row (fresh/seed toolset) → Public option is selectable (404 from metadata endpoint is treated as "no attached env", not as an error)
  • Telemetry: verify mcp_made_public payload contains system_vars_warned: true/false matching the scenario

Trade-offs

  • The Public guard only activates during isLoading, not on query errors. The metadata endpoint returns a 404 when no metadata row exists for a toolset (the common case for fresh or seeded toolsets); treating that as fail-closed would lock the Public option permanently with retry: false. Genuine transient network errors on metadata will now fall through without a warning — consistent with how MCPAuthenticationTab and MCPEnvironmentSettings already handle the same query.
  • needsEnableDialog fires on disabled → private transitions too — that's pre-existing behavior, not changed here.

🤖 Generated with Claude Code

simplesagar and others added 7 commits April 19, 2026 09:21
- Wrap body paragraph in Dialog.Description to satisfy Radix's aria-describedby requirement
- Add aria-hidden="true" to decorative ShieldAlert and ExternalLink icons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Store {target, sourceStatus} in publicWarningPending so handlePublicWarningConfirm
uses the status captured at dialog-open time rather than live currentStatus, closing
a stale-closure race that could bypass the ServerEnableDialog billing gate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Design doc and implementation plan for the feature added in this branch.
Kept in-tree for reviewer context and future backfill of similar warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gram-docs-redirect Ready Ready Preview, Comment Apr 19, 2026 7:35pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 19, 2026

🦋 Changeset detected

Latest commit: d1bdf35

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
dashboard Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added the preview Spawn a preview environment label Apr 19, 2026
@simplesagar simplesagar changed the title Warn users before making an MCP server public with system-provided env vars feat: warn users before making an MCP server public with system-provided env vars Apr 19, 2026
The metadata endpoint returns 404 when no mcp_metadata row exists for a
toolset, which is the common state for fresh or seeded toolsets. With
retry: false that 404 became a permanent isError: true, which the earlier
guard treated as "unknown state" and locked the Public dropdown option
forever with "Loading environment data…".

A missing metadata row actually means "no attached env", so there can be
no system-provided vars to leak. Restrict the guard to isLoading only —
matching how MCPAuthenticationTab and MCPEnvironmentSettings already
handle the same query. Genuine network errors will fall through without
a warning, but that's consistent with the rest of the dashboard and
preferable to locking the UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@speakeasybot
Copy link
Copy Markdown
Collaborator

speakeasybot commented Apr 19, 2026

🚀 Preview Environment (PR #2289)

Preview URL: https://pr-2289.dev.getgram.ai

Component Status Details Updated (UTC)
✅ Database Ready Created and validated 2026-04-19 19:41:05.
✅ Images Available Container images ready 2026-04-19 19:40:25.

Gram Preview Bot

The spec and plan were committed in the previous docs commit for
reviewer context. Removing them here so the PR diff only contains the
dashboard feature. The files stay accessible via `git show da3cafb`
for anyone who wants the design context.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simplesagar simplesagar marked this pull request as ready for review April 19, 2026 18:25
@simplesagar simplesagar requested review from a team as code owners April 19, 2026 18:25
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

- Use the default Dialog.Title style (drop the Tobias inline styling).
- Reword the body to reference "the Default Environment" generically and
  clarify that shared system values are team/public credentials.
- Link text becomes `Review in "Default Environment"`.
- Drop the now-unused environmentName prop from the component and call site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Addresses Devin review: if useGetMcpMetadata resolved before
useListEnvironments, `environments` was still [] and attachedEnvironment
computed as null, which made systemVarNames empty and allowed the user
to flip to Public without the warning dialog appearing. Block the Public
option until both queries have landed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simplesagar
Copy link
Copy Markdown
Member Author

CleanShot 2026-04-19 at 11 32 15

- Add .changeset/mcp-public-system-vars-warning.md to satisfy the
  Lint PR Title and Changesets check.
- Run mise run gen:sdk to bring jsr.json, .speakeasy/gen.yaml, and
  src/lib/config.ts up to 0.32.65 (they were still at 0.32.64 after
  main's `chore: version packages` commit only updated
  client/sdk/package.json). This unblocks the Check-SDK-is-up-to-date CI
  job.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simplesagar simplesagar changed the title feat: warn users before making an MCP server public with system-provided env vars feat: warn users before making an mcp server public with system-provided env vars Apr 19, 2026
@simplesagar simplesagar merged commit 442223d into main Apr 19, 2026
26 of 27 checks passed
@simplesagar simplesagar deleted the worktree-swift-ray-srn6 branch April 19, 2026 19:55
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

preview Spawn a preview environment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants