Skip to content

app: MCP: Add permissions center - #6618

Open
rootp1 wants to merge 1 commit into
kubernetes-sigs:mainfrom
rootp1:feature/mcp-permissions-center
Open

app: MCP: Add permissions center#6618
rootp1 wants to merge 1 commit into
kubernetes-sigs:mainfrom
rootp1:feature/mcp-permissions-center

Conversation

@rootp1

@rootp1 rootp1 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds an MCP permissions center by persisting approved effective permissions for desktop MCP servers and exposing those permissions through Electron IPC.

Related Issue

Fixes #6617

Changes

  • Added persisted MCP server permission snapshots for command, args, granted environment variable names, cluster dependency, and restart policy.
  • Added enforcement so enabled MCP servers with unapproved changed permissions are skipped before mcpServers are constructed.
  • Updated the MCP settings confirmation dialog to show effective permission details before saving.
  • Added an mcp-get-permissions IPC path exposed through preload so the desktop UI can inspect approved permissions and recent tool usage.
  • Added focused tests for permission persistence, unapproved permission blocking, and permission-center output.

Steps to Test

  1. Run cd app && npx vitest run electron/mcp/MCPSettings.test.ts.
  2. Run npm run app:test:unit.
  3. Run npm run app:tsc.
  4. Run npm run app:lint.
  5. Run npm run lint.
  6. Run npm test.
  7. Run npm run app:build.

Screenshots (if applicable)

There's no renderer-side UI, but the confirmation dialog itself is a real, user-facing surface (a native Electron dialog.showMessageBox), so here's a screen recording of it showing the effective permission summary before applying MCP settings changes:

Uploading demo.mp4…

Notes for the Reviewer

  • The issue and PR use the repository feature-request and pull-request templates.
  • The permissions approval snapshot is stamped when MCP settings are saved after the existing confirmation dialog. If settings are edited outside that flow to broaden command, args, env keys, cluster dependency, or restart policy, the server is skipped until re-approved.
  • npm run app:test:e2e was attempted but could not run because app/e2e-tests currently has no test script.
  • The first aggregate npm run lint attempt hit stale golangci-lint cache entries from another local checkout; rerunning with an isolated GOLANGCI_LINT_CACHE passed.

Summary by CodeRabbit

  • New Features

    • Added MCP permission management with approval tracking and restart policies.
    • Added visibility into effective access, approval status, restart behavior, and recent tool usage.
    • Added an API for retrieving MCP permission information.
  • Bug Fixes

    • MCP servers now start only when permissions are approved.
    • Restricted MCP environment variables to approved baseline and configured values.
    • Improved validation for broadened and narrowed permission changes.
    • Added support for cluster placeholder expansion in MCP permissions.

@kubernetes-prow kubernetes-prow Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Jul 23, 2026
@illume
illume requested a review from Copilot July 24, 2026 08:10

@illume illume left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for this PR.

A few of the commits don't quite follow the project guidelines. We use Linux kernel style for git commits — have a look at the contributing guide and previous commits with git log.

Commits that need attention
  • app: add MCP permissions center — Description must start with a capital letter — e.g. frontend: HomeButton: Fix the button not frontend: HomeButton: fix the button.
Commit guidelines
  • Use atomic commits focused on a single change.
  • Use the title format <area>: <Description of changes> — description must start with a capital letter.
  • Keep the title under 72 characters (soft requirement).
  • Explain the intention and why the change is needed.
  • Make commit titles meaningful and describe what changed.
  • Do not add code that a later commit rewrites; squash or reorder commits instead.
  • Do not include Fixes #NN in commit messages.

Good examples:

  • frontend: HomeButton: Fix so it navigates to home
  • backend: config: Add enable-dynamic-clusters flag

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a desktop-side MCP “permissions center” by persisting a per-server permission snapshot into MCP settings, enforcing that enabled servers with unapproved permission drift are skipped at runtime, and exposing permissions/tool-usage via a new Electron IPC endpoint.

Changes:

  • Persist “approved effective permissions” into MCP settings on save, and skip enabled servers whose effective permissions no longer match the approved snapshot.
  • Extend the MCP settings confirmation dialog to display effective permission details.
  • Expose a new mcp-get-permissions IPC route via Electron preload, and add unit tests covering persistence/enforcement/permissions-center output.

Note: CI/check status and PR commit history (merge commits / commit coherence) are not available in the provided context—please confirm CI is green and the PR history is linear.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
app/electron/preload.ts Exposes desktopApi.mcp.getPermissions() via ipcRenderer.invoke('mcp-get-permissions').
app/electron/mcp/MCPSettings.ts Adds permission snapshot types/helpers, approval enforcement when building mcpServers, and permissions summary output for the settings dialog/IPC.
app/electron/mcp/MCPSettings.test.ts Updates tests for persisted permissions, adds coverage for unapproved-permission blocking and permissions-center output.
app/electron/mcp/MCPClient.ts Adds mcp-get-permissions IPC handler that returns permissions-center data (plus tool usage).

Comment thread app/electron/mcp/MCPSettings.ts
Comment thread app/electron/mcp/MCPSettings.ts

@illume illume left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the contribution.

There are some open Copilot review comments — could you take a look at them? Please mark each one as resolved once you've addressed it.

@illume
illume requested a review from Copilot July 24, 2026 12:41

@illume illume left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for this PR.

A few of the commits don't quite follow the project guidelines. We use Linux kernel style for git commits — have a look at the contributing guide and previous commits with git log.

Commits that need attention
  • app: add MCP permissions center — Description must start with a capital letter — e.g. frontend: HomeButton: Fix the button not frontend: HomeButton: fix the button.
  • app: align MCP permission env reporting — Description must start with a capital letter — e.g. frontend: HomeButton: Fix the button not frontend: HomeButton: fix the button.
Commit guidelines
  • Use atomic commits focused on a single change.
  • Use the title format <area>: <Description of changes> — description must start with a capital letter.
  • Keep the title under 72 characters (soft requirement).
  • Explain the intention and why the change is needed.
  • Make commit titles meaningful and describe what changed.
  • Do not add code that a later commit rewrites; squash or reorder commits instead.
  • Do not include Fixes #NN in commit messages.

Good examples:

  • frontend: HomeButton: Fix so it navigates to home
  • backend: config: Add enable-dynamic-clusters flag

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

app/electron/mcp/MCPSettings.ts:133

  • buildMcpServerEnv currently returns only the explicitly configured server.env values (or {}), which drops critical base environment like PATH/HOME/SystemRoot. That can prevent typical commands (e.g. node, python, kubectl) from being found or can break runtimes that rely on HOME/TMP, even when permissions are otherwise approved. Consider inheriting a minimal, non-secret allowlist from process.env and including those keys in the permission snapshot/approval (since envKeys is derived from this function).
function buildMcpServerEnv(server: MCPServer): Record<string, string> {
  return { ...(server.env || {}) };
}

Comment thread app/electron/mcp/MCPSettings.ts
Comment thread app/electron/mcp/MCPSettings.ts
@rootp1

rootp1 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@illume CI checks and review comments are green now. Please have a look whenever you have a chance to.

@rootp1
rootp1 requested a review from illume July 24, 2026 19:55
@rootp1
rootp1 force-pushed the feature/mcp-permissions-center branch from b389ebc to 23738cb Compare July 24, 2026 20:19
@rootp1

rootp1 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@illume I reworded the commit messages to match the contribution guidelines. The force push retriggered CI, so I will wait for the new checks to finish.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

app/electron/mcp/MCPSettings.ts:133

  • buildMcpServerEnv returns only the explicit server.env entries. Because this object is also used as the process environment for the spawned MCP server, it will typically omit required baseline variables like PATH (and on Windows, SystemRoot/PATHEXT). That can break command resolution for documented configs where command is a PATH-resolved executable (e.g. k8sgpt, flux-operator-mcp). Consider inheriting a minimal safe baseline env needed for process launching, then overlaying the explicitly approved server.env values so permissions reporting stays accurate.
function buildMcpServerEnv(server: MCPServer): Record<string, string> {
  return { ...(server.env || {}) };
}

app/electron/mcp/MCPSettings.ts:424

  • normalizeLastUsed calls new Date(lastUsed).toISOString() without validating the input. If persisted tool state contains an invalid/unknown date string, this will throw a RangeError and break the mcp-get-permissions IPC handler. It’s safer to treat invalid dates as undefined.
  function normalizeLastUsed(lastUsed?: Date | string): string | undefined {
    if (!lastUsed) {
      return undefined;
    }

    return new Date(lastUsed).toISOString();
  }

@rootp1

rootp1 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

@illume I checked the current branch commits and the commit titles on this PR are in the project format now.

@illume illume added app kind/feature Categorizes issue or PR as related to a new feature. testing labels Jul 25, 2026
@github-actions
github-actions Bot force-pushed the feature/mcp-permissions-center branch from 23738cb to 2712da2 Compare July 26, 2026 15:33
@illume illume added this to the v0.44.0 milestone Jul 27, 2026
@github-actions
github-actions Bot force-pushed the feature/mcp-permissions-center branch from 2712da2 to ad11916 Compare July 27, 2026 08:18
@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: rootp1
Once this PR has been reviewed and has the lgtm label, please ask for approval from ashu8912. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions
github-actions Bot force-pushed the feature/mcp-permissions-center branch from ad11916 to d491d01 Compare July 27, 2026 11:45
@kubernetes-prow kubernetes-prow Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 6, 2026
@rootp1

rootp1 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

@illume Pushed a fix for the last open comment: withApprovedMCPPermissions now keeps a server's existing approvedAt when its effective permissions are unchanged, instead of restamping it on every save. Squashed back into the single commit and all app tests, tsc, and lint are green. Would appreciate another look when you have time.

@rootp1
rootp1 force-pushed the feature/mcp-permissions-center branch from 39be7d8 to dad5301 Compare August 6, 2026 20:46
@github-actions
github-actions Bot force-pushed the feature/mcp-permissions-center branch from dad5301 to c819baf Compare August 7, 2026 00:19
@illume
illume requested a lite review from Copilot August 7, 2026 08:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (1)

app/electron/mcp/MCPSettings.ts:497

  • The "request permission approval" change detection is currently too strict: it triggers whenever the saved permissions.envKeys differs from the next effective envKeys, even if the next permissions are already approved under the current snapshot (e.g. when the config narrows env access). This makes the dialog misleading and can also flag approval when the current server is unapproved but the next config returns to the approved baseline.

Instead of comparing snapshots with JSON.stringify and checking currentApproved, compute whether the next server would be approved under the current persisted snapshot using hasApprovedMCPServerPermissions({ ...nextServer, permissions: currentServer.permissions }). Only request approval when that returns false (or when no snapshot exists).

      if (
        !currentPermissions ||
        !currentApproved ||
        currentPermissions.command !== nextPermissions.command ||
        JSON.stringify(currentPermissions.args || []) !== JSON.stringify(nextPermissions.args) ||

@github-actions
github-actions Bot force-pushed the feature/mcp-permissions-center branch 6 times, most recently from ebc9ad6 to cb12963 Compare August 7, 2026 23:51
@illume
illume requested a balanced review from Copilot August 8, 2026 09:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

app/electron/mcp/MCPSettings.ts:497

  • This exact envKeys comparison still requests approval when access is narrowed. For example, removing one previously approved env key makes this dialog say “request permission approval,” while hasApprovedMCPServerPermissions(nextServer) correctly reports the same effective permissions as approved because they are a subset. Use the same approval predicate here so the dialog does not contradict itself or prompt for non-broadened access.
        currentPermissions.command !== nextPermissions.command ||
        JSON.stringify(currentPermissions.args || []) !== JSON.stringify(nextPermissions.args) ||
        JSON.stringify(currentPermissions.envKeys || []) !== JSON.stringify(nextPermissions.envKeys)

app/electron/preload.ts:106

  • The linked feature asks for a user-facing permissions center that includes recent tool usage, but this API has no renderer consumer anywhere in the repository. The only visible surface added here is the save-confirmation summary, which calls mcpPermissionsCenter without tool state and does not display recentToolUsage; therefore users still cannot inspect recent usage. Add a renderer UI that consumes this method, or narrow the PR/issue scope explicitly.
    getPermissions: () => ipcRenderer.invoke('mcp-get-permissions'),

Comment thread app/electron/mcp/MCPSettings.ts Outdated
@github-actions
github-actions Bot force-pushed the feature/mcp-permissions-center branch 5 times, most recently from 1767c21 to 783e0a4 Compare August 8, 2026 17:41

@illume illume left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the contribution.

There are some open Copilot review comments — could you take a look at them? Please mark each one as resolved once you've addressed it.

@github-actions
github-actions Bot force-pushed the feature/mcp-permissions-center branch 3 times, most recently from 8a0e268 to 5021613 Compare August 10, 2026 11:41
@rootp1

rootp1 commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the remaining open thread: settings.json now persists a one-time permissionsMigrated marker, so a server added later by hand-editing the file (without a permissions field) is no longer silently auto-approved the way pre-existing legacy servers are — it now goes through the normal unapproved-permission flow. Also squashed onto a single commit without a Signed-off-by trailer, and fixed the PR title casing. CI was green on this branch before the push (the only failure was the Windows electron download EOF, unrelated to this change).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (3)

app/electron/preload.ts:106

  • The new API is not consumed anywhere in the renderer (the only repository match is this declaration), so users still cannot open a permissions center or inspect approvedAt and recent tool usage. The native save-confirmation dialog is only shown during an update and does not expose those fields. Add a renderer surface that calls this API to satisfy issue #6617's user-inspection acceptance criterion.
    getPermissions: () => ipcRenderer.invoke('mcp-get-permissions'),

app/electron/preload.ts:106

  • The PR's sole commit has only the title app: MCP: Add permissions center; it has no description explaining why permission persistence and enforcement are needed. Add a commit body that records the intent and rationale so the commit satisfies the repository's commit-message guidance.
    getPermissions: () => ipcRenderer.invoke('mcp-get-permissions'),

app/electron/mcp/MCPSettings.ts:513

  • This exact envKeys comparison contradicts the subset-aware approval check above. Removing an approved environment key is permitted by hasApprovedMCPServerPermissions, but this branch still says “request permission approval,” so the same dialog can report that the narrowed permissions are both approved and requesting approval. Reuse hasApprovedMCPServerPermissions with the current snapshot applied to nextServer.
        !currentPermissions ||
        !currentApproved ||
        currentPermissions.command !== nextPermissions.command ||
        JSON.stringify(currentPermissions.args || []) !== JSON.stringify(nextPermissions.args) ||
        JSON.stringify(currentPermissions.envKeys || []) !== JSON.stringify(nextPermissions.envKeys)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

app: add MCP trust and permissions center

4 participants