Skip to content

Conversation

saqadri
Copy link
Collaborator

@saqadri saqadri commented Oct 12, 2025

  • Add a --no-auth flag to the deploy command to enable an unauthenticated app deployment
  • Add an update command (mcp-agent cloud apps update) to toggle auth, name, description, etc.

Summary by CodeRabbit

  • New Features

    • New “apps update” CLI command to modify app name, description, and authentication requirement.
    • Deploy command now supports --no-auth/--auth to control unauthenticated access and can update existing apps accordingly.
    • Post-deploy output now clearly shows the app’s authentication status.
  • Style

    • Minor formatting improvement to a verbose deploy log message.
  • Tests

    • Added coverage for the new apps update command and deploy authentication flags.

@saqadri saqadri requested a review from rholinshead October 12, 2025 01:52
Copy link

coderabbitai bot commented Oct 12, 2025

Walkthrough

Introduces an apps update CLI command, wires it into the cloud CLI, extends API and mock clients with unauthenticatedAccess support and update functionality, updates deploy command to pass/create/update this flag, and adds corresponding tests. Minor logging reformatting included.

Changes

Cohort / File(s) Summary of changes
Apps CLI exports
src/mcp_agent/cli/cloud/commands/apps/__init__.py
Import and export update_app; extend __all__ to include it.
Apps update package export
src/mcp_agent/cli/cloud/commands/apps/update/__init__.py
New module re-exporting update_app from .main.
Apps update command
src/mcp_agent/cli/cloud/commands/apps/update/main.py
New async CLI handler update_app with args for name, description, unauthenticated access, API URL/key; resolves target app/config; calls client update_app; handles errors; prints summary.
Cloud CLI wiring
src/mcp_agent/cli/cloud/main.py
Registers apps.update subcommand by importing and exposing update_app_command.
Deploy command flow
src/mcp_agent/cli/cloud/commands/deploy/main.py
Adds --no-auth/--auth flag; threads unauthenticated_access to create_app; conditionally calls update_app when updating existing apps; adjusts output to show auth requirement; minor message formatting.
Wrangler wrapper logging
src/mcp_agent/cli/cloud/commands/deploy/wrangler_wrapper.py
Reformats a verbose log statement without logic change.
MCP app API client
src/mcp_agent/cli/mcp_app/api_client.py
Adds unauthenticatedAccess to AppServerInfo and MCPApp; create_app accepts/forwards unauthenticated_access; new update_app method with validation and payload construction.
Mock MCP app client
src/mcp_agent/cli/mcp_app/mock_client.py
Changes _createdApps to Dict[str, MCPApp]; create_app accepts unauthenticated_access; adds update_app to mutate stored app and timestamps; caches results.
Tests: apps update
tests/cli/commands/test_apps_update.py
New test suite covering required fields, unauthenticated flag propagation, and config identifier handling.
Tests: deploy
tests/cli/commands/test_deploy_command.py
Adds tests for --no-auth propagation on create and --auth updating existing app; updates help assertions.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as apps update CLI
  participant Resolver as resolve_server
  participant Client as MCPAppClient
  participant API as Cloud API

  User->>CLI: mcp-agent apps update <id|name> [--name ... --desc ... --no-auth/--auth]
  CLI->>Resolver: resolve_server(app_id_or_name)
  Resolver-->>CLI: MCPApp or MCPAppConfiguration
  CLI->>Client: update_app(app_id, name?, description?, unauthenticated_access?)
  Client->>API: PATCH /apps/{app_id} { name?, description?, unauthenticatedAccess? }
  API-->>Client: Updated MCPApp
  Client-->>CLI: MCPApp
  CLI-->>User: Print updated summary (id, name, desc, server URL, auth status)
  note over CLI,Client: On UnauthenticatedError → raise CLIError
Loading
sequenceDiagram
  autonumber
  actor User
  participant Deploy as deploy CLI
  participant Client as MCPAppClient
  participant API as Cloud API

  User->>Deploy: mcp-agent deploy [--no-auth | --auth]
  alt App does not exist
    Deploy->>Client: create_app(name, desc?, unauthenticated_access?)
    Client->>API: POST /apps { name, description?, unauthenticatedAccess? }
    API-->>Client: MCPApp
  else App exists
    Deploy->>Client: update_app(app_id, description?, unauthenticated_access?)
    Client->>API: PATCH /apps/{app_id} { description?, unauthenticatedAccess? }
    API-->>Client: MCPApp
  end
  Deploy-->>User: Print post-deploy with auth requirement
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • rholinshead
  • petersonbill64
  • jtcorbett

Poem

A nibble of flags, a toggle so neat,
I hop through configs on soft little feet.
Update or deploy, I whisk with delight,
Auth on or off, the settings just right.
Carrot-shaped cursors blink—success in sight! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title accurately captures the two primary features introduced in this changeset—adding the update CLI command and the new no-auth flag—so it clearly reflects the main changes without extraneous detail.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/cli_no_auth

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a63f642 and 934e345.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • src/mcp_agent/cli/cloud/commands/apps/__init__.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/apps/update/__init__.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/apps/update/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/deploy/main.py (7 hunks)
  • src/mcp_agent/cli/cloud/commands/deploy/wrangler_wrapper.py (1 hunks)
  • src/mcp_agent/cli/cloud/main.py (2 hunks)
  • src/mcp_agent/cli/mcp_app/api_client.py (5 hunks)
  • src/mcp_agent/cli/mcp_app/mock_client.py (4 hunks)
  • tests/cli/commands/test_apps_update.py (1 hunks)
  • tests/cli/commands/test_deploy_command.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (10)
src/mcp_agent/cli/cloud/commands/apps/update/__init__.py (3)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • update_app (259-311)
src/mcp_agent/cli/mcp_app/mock_client.py (1)
  • update_app (140-169)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (5)
src/mcp_agent/cli/auth/main.py (1)
  • load_api_key_credentials (108-115)
src/mcp_agent/cli/core/api_client.py (1)
  • UnauthenticatedError (9-12)
src/mcp_agent/cli/exceptions.py (1)
  • CLIError (4-10)
src/mcp_agent/cli/mcp_app/api_client.py (4)
  • MCPApp (23-32)
  • MCPAppClient (133-750)
  • MCPAppConfiguration (36-41)
  • update_app (259-311)
src/mcp_agent/cli/cloud/commands/utils.py (1)
  • resolve_server (96-100)
src/mcp_agent/cli/cloud/commands/deploy/wrangler_wrapper.py (1)
src/mcp_agent/cli/utils/ux.py (1)
  • print_info (32-49)
tests/cli/commands/test_deploy_command.py (3)
src/mcp_agent/cli/mcp_app/api_client.py (2)
  • create_app (136-175)
  • update_app (259-311)
src/mcp_agent/cli/mcp_app/mock_client.py (2)
  • create_app (91-138)
  • update_app (140-169)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/cloud/commands/deploy/main.py (5)
src/mcp_agent/cli/utils/ux.py (2)
  • print_info (32-49)
  • print_success (52-63)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • update_app (259-311)
src/mcp_agent/cli/mcp_app/mock_client.py (1)
  • update_app (140-169)
src/mcp_agent/cli/mcp_app/api_client.py (3)
src/mcp_agent/cli/mcp_app/mock_client.py (2)
  • create_app (91-138)
  • update_app (140-169)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/core/api_client.py (1)
  • put (89-101)
src/mcp_agent/cli/mcp_app/mock_client.py (2)
src/mcp_agent/cli/mcp_app/api_client.py (4)
  • MCPApp (23-32)
  • create_app (136-175)
  • update_app (259-311)
  • get_app (177-214)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/cloud/main.py (2)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • update_app (259-311)
tests/cli/commands/test_apps_update.py (3)
src/mcp_agent/cli/mcp_app/api_client.py (4)
  • AppServerInfo (12-19)
  • MCPApp (23-32)
  • MCPAppConfiguration (36-41)
  • update_app (259-311)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/mcp_app/mock_client.py (1)
  • update_app (140-169)
src/mcp_agent/cli/cloud/commands/apps/__init__.py (3)
src/mcp_agent/cli/cloud/commands/apps/update/main.py (1)
  • update_app (20-126)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • update_app (259-311)
src/mcp_agent/cli/mcp_app/mock_client.py (1)
  • update_app (140-169)
🔇 Additional comments (28)
src/mcp_agent/cli/cloud/commands/deploy/wrangler_wrapper.py (1)

299-301: LGTM!

The reformatting improves readability without changing the logic or output.

src/mcp_agent/cli/cloud/main.py (2)

19-19: LGTM!

The import follows the existing pattern for other command imports in this file.


92-92: LGTM!

The command registration is consistent with other commands in the app_cmd_app group.

src/mcp_agent/cli/cloud/commands/apps/__init__.py (1)

4-6: LGTM!

The import and re-export pattern matches the existing approach for list_apps.

src/mcp_agent/cli/cloud/commands/apps/update/__init__.py (1)

1-5: LGTM!

Standard Python re-export pattern for the update command module.

src/mcp_agent/cli/cloud/commands/deploy/main.py (5)

86-90: LGTM!

The --no-auth/--auth flag follows Typer's boolean option pattern and provides clear help text.


181-191: LGTM!

The description_provided_by_cli flag correctly tracks whether the description was explicitly provided via CLI, which is necessary for the conditional update logic later.


228-241: LGTM!

The unauthenticated_access parameter is correctly passed to create_app, and the print messages are appropriately formatted.


259-273: LGTM!

The conditional update logic is well-structured: it only calls update_app when there are actual updates to apply (description from CLI or unauthenticated_access flag).


384-390: LGTM!

The authentication status is clearly displayed in the post-deployment output when the server info is available.

src/mcp_agent/cli/cloud/commands/apps/update/main.py (4)

20-64: LGTM!

The function signature is well-documented, and the validation correctly ensures at least one updatable field is provided.


66-88: LGTM!

API key resolution follows the standard pattern, and the app resolution logic correctly handles both MCPApp and MCPAppConfiguration identifiers.


90-117: LGTM!

The update operation and success messaging are clear and comprehensive, including appropriate fallbacks for app name and description display.


119-126: LGTM!

Error handling is thorough and provides helpful guidance for each error type.

tests/cli/commands/test_deploy_command.py (3)

77-77: LGTM!

The help text assertion correctly verifies that the new --no-auth option is documented.


148-202: LGTM!

The test correctly verifies that the --no-auth flag is passed to create_app with unauthenticated_access=True.


204-258: LGTM!

The test correctly verifies that the --auth flag triggers update_app for existing apps with unauthenticated_access=False.

src/mcp_agent/cli/mcp_app/api_client.py (4)

19-19: LGTM!

Adding unauthenticatedAccess to AppServerInfo is appropriate for tracking authentication requirements at the server level.


30-30: LGTM!

Adding unauthenticatedAccess to MCPApp is appropriate for tracking authentication requirements at the app level.


136-175: LGTM!

The create_app method correctly includes the new unauthenticated_access parameter and conditionally adds it to the payload when provided.


259-311: LGTM!

The update_app method is well-implemented with:

  • Proper validation of app_id format
  • Requirement for at least one field to update
  • Appropriate type validation for name (non-empty string) and description (any string, including empty)
  • Correct handling of the boolean unauthenticated_access parameter
  • Standard error handling and response validation
tests/cli/commands/test_apps_update.py (3)

35-48: LGTM!

The test correctly validates that the update command requires at least one field to be specified.


51-85: LGTM!

The test properly validates the --no-auth flag functionality by mocking dependencies and verifying both the API call arguments and user-facing output.


88-128: LGTM!

The test correctly validates that the update command can accept configuration identifiers and properly extracts the underlying app before updating.

src/mcp_agent/cli/mcp_app/mock_client.py (4)

34-34: LGTM!

Simplifying the storage from a nested dictionary to a flat dictionary improves code clarity without losing functionality.


73-89: LGTM!

The caching logic is appropriate for a mock client, though it differs from the real API behavior (which would return a 404 for non-existent apps). This permissive behavior is acceptable for testing convenience.


91-138: LGTM!

The method signature and implementation correctly mirror the API client's create_app, including the new unauthenticated_access parameter. Caching the created app enables consistent behavior across multiple test calls.


140-169: LGTM!

The implementation correctly handles field updates and maintains consistency with the API client signature. Note that this mock allows updating apps that don't exist (line 153 creates them via get_app), which differs from the real API behavior but is acceptable for test convenience.


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.

@saqadri saqadri merged commit 8bbc1ca into main Oct 12, 2025
8 checks passed
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.

1 participant