Skip to content

Conversation

@rholinshead
Copy link
Member

@rholinshead rholinshead commented Sep 3, 2025

Description

The existing mcp-agent apps list command is pretty unusable, especially on smaller CLI windows:
Screenshot 2025-09-03 at 7 30 17 PM

Let's just list the apps and configured apps directly so that IDs and server URLs can be easily copied

Screenshot 2025-09-03 at 7 30 00 PM

Summary by CodeRabbit

  • New Features

    • More compact, copy-friendly CLI output for listing apps and configurations.
    • Colorized status indicators with emojis (Online, Offline, Unknown).
    • Clear “no results” headers and a separator line when no apps/configs are found.
  • Style

    • Switched from table-based display to a line-oriented layout, showing key details (names, IDs, URLs, descriptions, created timestamps) for improved readability.

@coderabbitai
Copy link

coderabbitai bot commented Sep 3, 2025

Walkthrough

Replaced Rich table-based rendering with plain, line-oriented text output for app listings and configurations. Added explicit empty-state headers and separators. Updated _server_status_text to return color-marked strings. Docstrings revised. No public API changes.

Changes

Cohort / File(s) Summary
CLI apps list rendering
src/mcp_agent/cli/cloud/commands/apps/list/main.py
Switched from Rich Table/Padding to copyable line-based output; added 0-result headers/separators; updated print_apps and print_app_configs to multiline records; _server_status_text now returns colorized status strings; is_last_row no longer affects formatting; updated docstrings.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I hop through logs with nimble cheer,
Tables gone, the lines are clear—
IDs, URLs, easy to copy, neat!
Status lights blink green and sweet.
With paws that type and ears that twirl,
I ship this CLI with a happy whirl. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/update-apps-list-UI

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@rholinshead rholinshead requested a review from saqadri September 3, 2025 23:33
Copy link
Collaborator

@saqadri saqadri left a comment

Choose a reason for hiding this comment

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

Beautiful

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

🧹 Nitpick comments (3)
src/mcp_agent/cli/cloud/commands/apps/list/main.py (3)

74-88: Use dynamic separator instead of fixed-width line

A fixed 80-char rule may wrap on narrow terminals. Prefer a console-native rule to adapt to terminal width.

-        console.print("\n" + "─" * 80 + "\n")
+        console.rule()

137-169: Prefer “Unknown” over “Offline” when appServerInfo is missing

Keeps semantics accurate and consistent with other commands.

-        status = _server_status_text(
-            config.appServerInfo.status
-            if config.appServerInfo
-            else "APP_SERVER_STATUS_OFFLINE"
-        )
+        status = _server_status_text(
+            config.appServerInfo.status if config.appServerInfo else None
+        )

171-178: Tighten _server_status_text signature; remove unused arg; clarify docstring

  • is_last_row is unused; drop it.
  • Accept Optional[str] to support “Unknown” fallback.
  • Docstring should mention color-marked output.
-def _server_status_text(status: str, is_last_row: bool = False):
-    """Convert server status code to emoji."""
+def _server_status_text(status: Optional[str]) -> str:
+    """Convert server status code to color-marked text with emoji for Rich console."""
     if status == "APP_SERVER_STATUS_ONLINE":
-        return "[green]🟢 Online[/green]"
+        return "[green]🟢 Online[/green]"
     elif status == "APP_SERVER_STATUS_OFFLINE":
-        return "[red]🔴 Offline[/red]"
+        return "[red]🔴 Offline[/red]"
     else:
         return "❓ Unknown"

Follow-up (optional): this helper exists in another command (app/status). Consider centralizing to a shared utility to avoid divergence.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1beacc0 and 91ceaa9.

📒 Files selected for processing (1)
  • src/mcp_agent/cli/cloud/commands/apps/list/main.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/mcp_agent/cli/cloud/commands/apps/list/main.py (3)
src/mcp_agent/cli/utils/ux.py (1)
  • print_info (32-49)
src/mcp_agent/cli/cloud/commands/app/status/main.py (1)
  • _server_status_text (114-120)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • MCPAppConfiguration (33-38)

Comment on lines +111 to +133
"""Print a list of deployed apps in a clean, copyable format."""
console.print(f"\n[bold blue]📦 Deployed MCP Apps ({len(apps)})[/bold blue]")

table.add_column("Name", style="cyan", overflow="fold")
table.add_column("ID", style="bright_blue", no_wrap=True)
table.add_column("Description", style="cyan", overflow="fold")
table.add_column("Server URL", style="bright_blue", no_wrap=True)
table.add_column("Status", style="bright_blue", no_wrap=True)
table.add_column("Created", style="cyan", overflow="fold")

for idx, app in enumerate(apps):
is_last_row = idx == len(apps) - 1
table.add_row(
app.name,
app.appId,
app.description,
app.appServerInfo.serverUrl if app.appServerInfo else "",
_server_status_text(
(
app.appServerInfo.status
if app.appServerInfo
else "APP_SERVER_STATUS_OFFLINE"
),
is_last_row,
),
app.createdAt.strftime("%Y-%m-%d %H:%M:%S"),
for i, app in enumerate(apps):
if i > 0:
console.print()

status = _server_status_text(
app.appServerInfo.status
if app.appServerInfo
else "APP_SERVER_STATUS_OFFLINE"
)

console.print(table)
console.print(f"[bold cyan]{app.name or 'Unnamed'}[/bold cyan] {status}")
console.print(f" App ID: {app.appId}")

if app.appServerInfo and app.appServerInfo.serverUrl:
console.print(f" Server: {app.appServerInfo.serverUrl}")

if app.description:
console.print(f" Description: {app.description}")

console.print(f" Created: {app.createdAt.strftime('%Y-%m-%d %H:%M:%S')}")
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Guard against None createdAt and don’t default missing server info to “Offline”

  • createdAt may be None (seen on configurations; apps can be similar) → AttributeError risk.
  • Treat missing appServerInfo as Unknown, not Offline.
-        status = _server_status_text(
-            app.appServerInfo.status
-            if app.appServerInfo
-            else "APP_SERVER_STATUS_OFFLINE"
-        )
+        status = _server_status_text(
+            app.appServerInfo.status if app.appServerInfo else None
+        )
@@
-        console.print(f"  Created: {app.createdAt.strftime('%Y-%m-%d %H:%M:%S')}")
+        if app.createdAt:
+            console.print(f"  Created: {app.createdAt.strftime('%Y-%m-%d %H:%M:%S')}")
+        else:
+            console.print("  Created: -")

Additionally update the helper to accept Optional status (see suggestion below).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"""Print a list of deployed apps in a clean, copyable format."""
console.print(f"\n[bold blue]📦 Deployed MCP Apps ({len(apps)})[/bold blue]")
table.add_column("Name", style="cyan", overflow="fold")
table.add_column("ID", style="bright_blue", no_wrap=True)
table.add_column("Description", style="cyan", overflow="fold")
table.add_column("Server URL", style="bright_blue", no_wrap=True)
table.add_column("Status", style="bright_blue", no_wrap=True)
table.add_column("Created", style="cyan", overflow="fold")
for idx, app in enumerate(apps):
is_last_row = idx == len(apps) - 1
table.add_row(
app.name,
app.appId,
app.description,
app.appServerInfo.serverUrl if app.appServerInfo else "",
_server_status_text(
(
app.appServerInfo.status
if app.appServerInfo
else "APP_SERVER_STATUS_OFFLINE"
),
is_last_row,
),
app.createdAt.strftime("%Y-%m-%d %H:%M:%S"),
for i, app in enumerate(apps):
if i > 0:
console.print()
status = _server_status_text(
app.appServerInfo.status
if app.appServerInfo
else "APP_SERVER_STATUS_OFFLINE"
)
console.print(table)
console.print(f"[bold cyan]{app.name or 'Unnamed'}[/bold cyan] {status}")
console.print(f" App ID: {app.appId}")
if app.appServerInfo and app.appServerInfo.serverUrl:
console.print(f" Server: {app.appServerInfo.serverUrl}")
if app.description:
console.print(f" Description: {app.description}")
console.print(f" Created: {app.createdAt.strftime('%Y-%m-%d %H:%M:%S')}")
"""Print a list of deployed apps in a clean, copyable format."""
console.print(f"\n[bold blue]📦 Deployed MCP Apps ({len(apps)})[/bold blue]")
for i, app in enumerate(apps):
if i > 0:
console.print()
status = _server_status_text(
app.appServerInfo.status if app.appServerInfo else None
)
console.print(f"[bold cyan]{app.name or 'Unnamed'}[/bold cyan] {status}")
console.print(f" App ID: {app.appId}")
if app.appServerInfo and app.appServerInfo.serverUrl:
console.print(f" Server: {app.appServerInfo.serverUrl}")
if app.description:
console.print(f" Description: {app.description}")
if app.createdAt:
console.print(f" Created: {app.createdAt.strftime('%Y-%m-%d %H:%M:%S')}")
else:
console.print(" Created: -")

@rholinshead rholinshead merged commit e763520 into main Sep 4, 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.

3 participants