Skip to content

Preserve MCP client config and secure install writes - #267

Merged
Sayan- merged 5 commits into
mainfrom
hypeship/secure-mcp-installs
Sep 24, 2026
Merged

Sayan- merged 5 commits into
mainfrom
hypeship/secure-mcp-installs

Conversation

@Sayan-

@Sayan- Sayan- commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Update only the Kernel MCP entry while preserving other servers, custom Kernel fields, recognized mcp-remote options, and fx environment-variable authentication. Cursor installs also remove stale transport types.
  • Preserve JSON comments and formatting outside edited fields. Reject empty, malformed, ambiguous, and non-object config without changing it.
  • Write through private temporary files and replace config atomically on POSIX. Use mode 0600 for credential-capable files, preserving stricter POSIX mode bits. VS Code now uses its user-profile mcp.json and carries forward missing Kernel fields from legacy settings.json.

Validation

  • Reproduced the prior behavior and exercised the built CLI against isolated config directories for all eight file-writing targets.
  • Added regression tests for all eight targets, unrelated entries, repeated installs, stale Cursor transport types, comments, malformed and missing files, permissions, legacy VS Code settings, and replacement failures.

Remaining limits

  • Replacing an existing file preserves POSIX mode bits but may not preserve a custom file ACL. ACL behavior on macOS and Windows has not been verified.
  • An editor saving the same config concurrently can race with install. Atomic replacement prevents partial files on POSIX, but does not coordinate separate writers.

Note

Medium Risk
The CLI now edits real user config files on disk with new validation and VS Code path/migration behavior; mistakes could break MCP setup or permissions, though atomic writes and tests reduce exposure.

Overview
Replaces per-editor install helpers with a spec-driven kernel mcp install flow in new config.go, using hujson to patch only the Kernel MCP entry while keeping other servers, custom Kernel fields (headers, fx bearer_token_env), and mcp-remote CLI flags.

Install now rejects empty/malformed JSON, duplicate keys, and symlink config paths without mutating the file; VS Code targets user mcp.json (servers.kernel) and copies missing Kernel fields from legacy settings.json (mcp.servers). Writes go through private temp files + atomic rename, tighten modes to 0600 when needed, and skip rewrites when content already matches.

install help text is generated from targetSpecs. Adds broad regression tests in config_test.go and the tailscale/hujson dependency.

Reviewed by Cursor Bugbot for commit 4d111d3. Bugbot is set up for automated code reviews on this repo. Configure here.

@socket-security

socket-security Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedgolang/​github.com/​tailscale/​hujson@​v0.0.0-20250605163823-992244df8c5a100100100100100

View full report

@Sayan-
Sayan- marked this pull request as ready for review September 23, 2026 19:18

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4e7ebef. Configure here.

Comment thread cmd/mcp/config.go
@Sayan-
Sayan- marked this pull request as draft September 23, 2026 19:45
@Sayan-
Sayan- marked this pull request as ready for review September 23, 2026 19:52

@tnsardesai tnsardesai 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.

Correctness

  • Non-blocking bug — Nested duplicate keys are accepted — cmd/mcp/config.go:L411-L419
    • Problem: objectAt checks only the objects it visits. Install succeeds with two different Authorization keys inside kernel.headers; I reproduced this against the reviewed head.
    • Impact: the client may interpret an ambiguous authentication value differently.
    • Fix: check object keys recursively before patching, including imported legacy fields.
    • Evidence: the PR body says ambiguous config is rejected.

Standards

  • Non-blocking CI coverage gap — Go tests do not run on this stacked PR — PR-level
    • Problem: this PR targets hypeship/add-antigravity-mcp-target, but .github/workflows/test.yaml runs on pull requests targeting main only.
    • Impact: reviewers have no Go test check on this PR head. make test passed locally.
    • Fix: run the workflow against this head SHA or cover stacked PRs in its trigger.

@masnwilliams masnwilliams 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.

This is a meaningful improvement over the per-client installers: hand-edited Kernel fields and other servers survive reinstalls, the config keeps its surrounding formatting, and credential-capable files get private permissions. I ran go test ./... locally; it passes.

A few follow-ups worth addressing, though I would not block this PR on them:

  • objectAt checks duplicate keys only along the paths being edited. A config with two Authorization keys in kernel.headers still installs successfully and retains both. This was also identified in the existing review. Validating object keys recursively once when reading the destination and legacy documents would make the stated rejection of ambiguous config reliable and remove repeated validation during patching.
  • For VS Code, installConfig chmods legacy settings.json before writing mcp.json. With an unwritable destination directory, install fails, but the old settings file has already changed from 0644 to 0600. Please move that side effect after a successful destination write or report it as a separate operation, and cover the failure path.
  • mergeConfig now owns section creation, legacy import, transport migration, stdio argument parsing, fx auth policy, and syntax-tree edits. As more targets evolve, I would split document mutation from transport-specific entry policy rather than extend the configField options (ifMissing/skipWhen) for additional special cases.

None of these changes the overall direction or the existing approval.

Base automatically changed from hypeship/add-antigravity-mcp-target to main September 24, 2026 20:04
@Sayan-
Sayan- force-pushed the hypeship/secure-mcp-installs branch from 896e43c to 4d111d3 Compare September 24, 2026 20:04
@Sayan-
Sayan- merged commit 02ff53f into main Sep 24, 2026
8 checks passed
@Sayan-
Sayan- deleted the hypeship/secure-mcp-installs branch September 24, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants