Skip to content

feat: add mcpd config volumes remove command#250

Merged
peteski22 merged 3 commits intomainfrom
feature/config-volumes-remove
Mar 5, 2026
Merged

feat: add mcpd config volumes remove command#250
peteski22 merged 3 commits intomainfrom
feature/config-volumes-remove

Conversation

@peteski22
Copy link
Contributor

@peteski22 peteski22 commented Mar 2, 2026

Summary

  • Add mcpd config volumes remove <server-name> -- --<volume-name> [--<volume-name>...] command to remove volume mappings from MCP server runtime configurations
  • Improve existing set command: noop-aware messaging, consistent validation naming (validateSetArgsCore), clearer withVolumes doc comment
  • Centralise dual-field volume assignment in withVolumes helper shared by both commands

Test plan

  • go test ./cmd/config/volumes/... -count=1 passes
  • go test ./... -count=1 passes (full suite)
  • Remove single volume, multiple volumes, all volumes (triggers deleted result)
  • Remove nonexistent volume returns noop message
  • Remove from nonexistent server returns error
  • Validation: missing server name, missing -- separator, invalid volume format, empty volume name
  • Loader and upsert error paths covered
  • Set command noop case tested (set same value)

Closes #200

Summary by CodeRabbit

  • New Features

    • Added a remove command to delete volume mappings from targeted MCP servers in the runtime configuration.
  • Improvements

    • Stronger argument validation and clearer error messages for volume commands (separator, name/path checks).
    • Better handling and reporting of no-op situations when no changes are required.
    • Improved parsing and trimming of quoted paths.
    • Reordered CLI commands for clearer flow.
  • Tests

    • Extensive unit tests covering remove/set behaviours, validation and edge cases.

@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0cb032b8-536c-42cc-9da5-fe8134d7fc01

📥 Commits

Reviewing files that changed from the base of the PR and between 40fd430 and 5678265.

📒 Files selected for processing (3)
  • cmd/config/volumes/cmd.go
  • cmd/config/volumes/remove.go
  • cmd/config/volumes/set.go

Walkthrough

Adds a new remove subcommand for volumes, reorders volumes subcommands to include remove, refactors set to use context.VolumeExecutionContext with a withVolumes helper, updates argument validation and parsing, and adds/updates unit tests for remove and set behaviours.

Changes

Cohort / File(s) Summary
New Remove Command
cmd/config/volumes/remove.go, cmd/config/volumes/remove_test.go
Adds NewRemoveCmd and its Cobra wiring, argument validation and parsing for --name style args, runtime removal logic that updates/persists server volume mappings, and comprehensive tests covering success, noop and error paths.
Command Registration & Helpers
cmd/config/volumes/cmd.go
Reorders subcommands to insert NewRemoveCmd between list and set; adds withVolumes(server context.VolumeExecutionContext, working context.VolumeExecutionContext) context.ServerExecutionContext and stripDashPrefix helpers; imports updated (fmt, maps, strings).
Set Command Refactor
cmd/config/volumes/set.go, cmd/config/volumes/set_test.go
Replaces validateArgs with validateSetArgsCore, changes parsing to return context.VolumeExecutionContext, introduces trimQuotes, updates run signature to accept cobraCmd, switches to withVolumes/Upsert workflow and refines Upsert/no-op semantics; tests adjusted for new behaviours and Upsert branches.
Tests & Mocks Adjustments
cmd/config/volumes/*_test.go
Mocks updated (modifier Upsert) to distinguish noop/create/update/delete outcomes; tests renamed/rewired to assert new outputs, validation functions and context.VolumeExecutionContext types.

Possibly related PRs

Suggested labels

cli

Suggested reviewers

  • dpoulopoulos
  • agpituk
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add mcpd config volumes remove command' accurately and specifically summarises the main addition in the PR, which is a new CLI remove command for volume configurations.
Linked Issues check ✅ Passed The PR implements the feature request in issue #200 by adding the 'mcpd config volumes remove' command that removes specified volume mappings from MCP servers, meeting all stated objectives.
Out of Scope Changes check ✅ Passed All changes directly support the remove command feature or improve related existing code; modifications to set.go and cmd.go are closely related supporting enhancements with no unrelated scope creep.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/config-volumes-remove

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/config/volumes/remove.go`:
- Around line 142-159: parseRemoveArgs duplicates the same "--" prefix
validation/stripping logic used by parseVolumeArgs; extract a small helper like
ensurePrefixed(arg string, prefix string) (or stripLeadingDashes(arg string))
that verifies strings.HasPrefix(arg, "--"), returns the remainder (trimmed) or
an error, and use it from both parseRemoveArgs and parseVolumeArgs to centralize
the validation and trimming logic; keep the existing empty-name checks (e.g.,
name == "") in each caller as-needed.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 557fc34 and 5b27405.

📒 Files selected for processing (5)
  • cmd/config/volumes/cmd.go
  • cmd/config/volumes/remove.go
  • cmd/config/volumes/remove_test.go
  • cmd/config/volumes/set.go
  • cmd/config/volumes/set_test.go

@peteski22 peteski22 requested a review from javiermtorres March 2, 2026 20:20
Copy link

@javiermtorres javiermtorres left a comment

Choose a reason for hiding this comment

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

Minor nitpick, otherwise lgtm

Implement `mcpd config volumes remove <server-name> -- --<volume-name>`
to remove volume mappings from MCP server runtime configurations.

Also improves the existing `set` command: noop-aware messaging,
consistent validation naming, and clearer withVolumes doc comment.

Closes #200
@peteski22 peteski22 force-pushed the feature/config-volumes-remove branch from b0e37d9 to 70da343 Compare March 3, 2026 15:40
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/config/volumes/remove.go`:
- Around line 108-111: Currently the code clones server.RawVolumes into working
and falls back to an empty context.VolumeExecutionContext{}, which ignores
server.Volumes when RawVolumes is nil; change the initialization so you first
attempt maps.Clone(server.RawVolumes), if that result is nil then attempt
maps.Clone(server.Volumes), and only if that is still nil set working =
context.VolumeExecutionContext{}; update the code around the working variable
assignment (the clone of server.RawVolumes) so it checks server.Volumes as the
secondary source.
- Around line 146-153: The arg-parsing loop in remove.go currently accepts flags
like "--workspace=/tmp" as a literal volume name; update the loop that iterates
over args (the for _, arg := range args block) to reject any arg that contains
an '=' after the "--" prefix (e.g., detect strings.Contains(arg[len("--"):],
"=") or check for '=' in the derived name variable) and return an error such as
"invalid volume name '%s': flag assignments are not allowed for remove" instead
of treating them as names; keep the existing empty-name check on name
(strings.TrimSpace(strings.TrimPrefix(arg, "--"))), but add the '=' check before
trimming/using name so remove will not accept "--name=path".

In `@cmd/config/volumes/set.go`:
- Around line 113-116: The current logic initializes working from
server.RawVolumes and falls back to an empty context if nil, which can drop
existing mappings in server.Volumes; change the initialization so working is
maps.Clone(server.RawVolumes) if non-nil, otherwise maps.Clone(server.Volumes)
(and if both are nil use an empty context like
context.VolumeExecutionContext{}), updating the working variable creation in
set.go to prefer server.Volumes as the fallback before applying updates.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b27405 and 70da343.

📒 Files selected for processing (5)
  • cmd/config/volumes/cmd.go
  • cmd/config/volumes/remove.go
  • cmd/config/volumes/remove_test.go
  • cmd/config/volumes/set.go
  • cmd/config/volumes/set_test.go

The remove command only accepts volume names (--workspace), not
key=value pairs (--workspace=/tmp). Without this check, a mistyped
--name=path arg would be parsed as a literal volume name that never
matches, resulting in a silent noop.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
cmd/config/volumes/remove.go (1)

108-111: ⚠️ Potential issue | 🟠 Major

Use server.Volumes as fallback before mutating volume state.

At Line 108, working is cloned from server.RawVolumes only. If RawVolumes is nil but Volumes is populated, this path can apply removals against an empty map and then persist that empty state via withVolumes, causing unintended volume loss.

#!/bin/bash
# Verify whether RawVolumes is always initialised during load, and where it is assigned.
# Expected result:
# - If loader guarantees RawVolumes <- Volumes (or raw source), current code may be safe.
# - If not, remove.go should fallback to server.Volumes before empty-map initialisation.

rg -n --type=go -C4 '\bRawVolumes\b'
rg -n --type=go -C6 'func .*Load\(' internal/context
rg -n --type=go -C4 '\bwithVolumes\s*\(' cmd/config/volumes
Suggested patch
-	working := maps.Clone(server.RawVolumes)
-	if working == nil {
-		working = context.VolumeExecutionContext{}
-	}
+	working := maps.Clone(server.RawVolumes)
+	if working == nil {
+		working = maps.Clone(server.Volumes)
+	}
+	if working == nil {
+		working = context.VolumeExecutionContext{}
+	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/config/volumes/remove.go` around lines 108 - 111, The code clones only
server.RawVolumes into working which can be nil and cause removals to be applied
to an empty map; change the logic in remove.go to choose a source map by
preferring server.RawVolumes but falling back to server.Volumes before calling
maps.Clone (then if both nil, initialize working =
context.VolumeExecutionContext{}), and continue to pass working into withVolumes
so you don't persist an unintended empty map; update references around
maps.Clone(server.RawVolumes), the working variable, and the call to withVolumes
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/config/volumes/remove_test.go`:
- Around line 41-118: Add a new test case in cmd/config/volumes/remove_test.go
within the existing tests slice that covers the regression where RawVolumes is
nil but Volumes is populated: create a case (e.g., name "rawVolumes nil but
volumes present") with serverName "filesystem", volumeArgs like
[]string{"--workspace"}, existingServers containing
context.ServerExecutionContext where Volumes has "workspace": "/Users/foo/repos"
and RawVolumes is nil (omit or set to nil), then assert expectedOutput and
expectedVolumes match the removal behavior (operation updated/deleted as
appropriate) to validate remove logic handles persisted runtime shapes;
reference the test harness that reads existingServers and uses
context.ServerExecutionContext, Volumes and RawVolumes fields to locate the
change.

---

Duplicate comments:
In `@cmd/config/volumes/remove.go`:
- Around line 108-111: The code clones only server.RawVolumes into working which
can be nil and cause removals to be applied to an empty map; change the logic in
remove.go to choose a source map by preferring server.RawVolumes but falling
back to server.Volumes before calling maps.Clone (then if both nil, initialize
working = context.VolumeExecutionContext{}), and continue to pass working into
withVolumes so you don't persist an unintended empty map; update references
around maps.Clone(server.RawVolumes), the working variable, and the call to
withVolumes accordingly.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70da343 and 40fd430.

📒 Files selected for processing (2)
  • cmd/config/volumes/remove.go
  • cmd/config/volumes/remove_test.go

Extract shared "--" prefix validation and stripping into stripDashPrefix
helper, used by both parseRemoveArgs and parseVolumeArgs. Consolidates
the flag-format constraint in one place.
@peteski22 peteski22 merged commit 3c3e4f6 into main Mar 5, 2026
2 of 3 checks passed
@peteski22 peteski22 deleted the feature/config-volumes-remove branch March 5, 2026 11:16
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.

mcpd config volumes remove

2 participants