Skip to content

Conversation

@jtcorbett
Copy link
Contributor

@jtcorbett jtcorbett commented Sep 5, 2025

TL;DR

Improved app identifier handling by removing URL support and enforcing proper ID formats.

What changed?

  • Modified parse_app_identifier() to only accept proper app IDs (app_...) or app configuration IDs (apcnf_...), removing URL support
  • Updated the function to return a tuple of just (app_id, config_id) instead of including server URL
  • Added proper error handling with descriptive error messages when invalid identifiers are provided
  • Updated help text in CLI commands to reflect the new identifier requirements
  • Removed server URL parameters from internal functions that no longer need them
  • Updated example commands to use proper app IDs instead of URLs

How to test?

  1. Try using the logger tail command with proper app IDs:

    mcp-agent cloud logger tail app_abc123
    mcp-agent cloud logger tail apcnf_xyz789
    
  2. Verify that using URLs now fails with a clear error message:

    mcp-agent cloud logger tail https://app.mcpac.dev/abc123
    
  3. Test server commands with proper IDs:

    mcp-agent cloud servers describe app_abc123
    mcp-agent cloud servers delete apcnf_xyz789
    

Why make this change?

This change standardizes how we identify apps and configurations throughout the CLI, making the interface more consistent and reducing confusion. By enforcing proper ID formats and providing clear error messages, users will better understand what identifiers are expected. Removing URL support simplifies the codebase and creates a more predictable user experience.

Summary by CodeRabbit

  • Refactor

    • Standardized CLI error output across status, workflows, logger configuration, and log tailing.
    • Log tailing now accepts App ID or app configuration ID only; URL-based identifiers are no longer supported. Streaming/fetching behavior unchanged.
    • Stricter identifier parsing with clear errors for invalid formats.
    • Improved failure handling during logger configuration with consistent error reporting.
  • Documentation

    • Updated help text to reflect ID-based inputs for log tailing and server delete/describe commands.
    • Refreshed examples to use App ID–style identifiers.
  • Style

    • Minor formatting adjustments to success panels and messages.

@coderabbitai
Copy link

coderabbitai bot commented Sep 5, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Caution

Review failed

The pull request is closed.

Walkthrough

Consolidates CLI error handling via print_error, shifts identifier parsing to ID-only (removes URL branch), updates logger tail to app ID/config ID addressing and internal URL resolution, tightens API client log response to logEntries only, and updates help texts. Some signatures changed accordingly.

Changes

Cohort / File(s) Summary
Standardize error handling (print_error)
src/mcp_agent/cli/cloud/commands/app/status/main.py, src/mcp_agent/cli/cloud/commands/app/workflows/main.py, src/mcp_agent/cli/cloud/commands/logger/configure/main.py
Replace colored console/Panel errors with centralized print_error; maintain existing control flow; in configure, raise CLIError on save failure and unify some prints.
Logger tail: ID-based addressing & internal URL resolution
src/mcp_agent/cli/cloud/commands/logger/tail/main.py
CLI/help now expects App ID or app config ID; parse_app_identifier returns only (app_id, config_id); remove server_url parameter from functions; resolve server_url internally; convert errors to print_error/CLIError; adjust non-stream fetch to use app_id/config_id.
Identifier parsing simplification
src/mcp_agent/cli/core/utils.py
parse_app_identifier now returns a 2-tuple (app_id, config_id); removes URL handling; raises ValueError on unrecognized formats; docstring updated.
Server resolution utilities
src/mcp_agent/cli/cloud/commands/servers/utils.py
Remove URL-based resolution branch; rely on (app_id, config_id); translate ValueError to CLIError; docstrings updated.
API log model tightening
src/mcp_agent/cli/mcp_app/api_client.py
Remove log_entries field; log_entries_list now returns only logEntries (or empty).
Help text updates (ID vs URL)
src/mcp_agent/cli/cloud/commands/servers/delete/main.py, src/mcp_agent/cli/cloud/commands/servers/describe/main.py
Update argument help from “URL” to “app configuration ID”; no functional changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI tail_logs
  participant Utils as parse_app_identifier / resolve_server_url
  participant API as MCP App API
  participant SSE as Log Stream (SSE)

  User->>CLI: tail-logs app_identifier [--stream/--since ...]
  CLI->>Utils: parse_app_identifier(identifier)
  Note right of Utils: Returns (app_id, config_id)<br/>Raises ValueError on invalid
  Utils-->>CLI: app_id, config_id

  alt streaming mode
    CLI->>Utils: resolve_server_url(app_id/config_id)
    Utils-->>CLI: server_url
    CLI->>SSE: Connect to server_url with credentials
    SSE-->>CLI: log events
    CLI->>CLI: filter/format (optional grep/format)
    CLI-->>User: stream output
  else fetch mode
    CLI->>API: GET /logs?app_id/config_id&since&limit&order
    API-->>CLI: GetAppLogsResponse (logEntries)
    CLI->>CLI: map to list (model_dump), filter/format
    CLI-->>User: printed logs
  end

  opt errors
    CLI->>CLI: print_error(...) and/or raise CLIError
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • rholinshead
  • saqadri
  • petersonbill64

Poem

A hop, a skip, IDs in tow,
No URLs—just where apps go.
Logs now stream in tidy rows,
Errors whisper, not in throes.
Bunny taps the keys with cheer—
“print_error here, and clarity near!”
(_/) ✨ tailing made clear.


📜 Recent 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 0827cb1 and 1dd21da.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • src/mcp_agent/cli/cloud/commands/app/status/main.py (5 hunks)
  • src/mcp_agent/cli/cloud/commands/app/workflows/main.py (3 hunks)
  • src/mcp_agent/cli/cloud/commands/logger/configure/main.py (4 hunks)
  • src/mcp_agent/cli/cloud/commands/logger/tail/main.py (6 hunks)
  • src/mcp_agent/cli/cloud/commands/servers/delete/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/servers/describe/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/servers/utils.py (2 hunks)
  • src/mcp_agent/cli/core/utils.py (1 hunks)
  • src/mcp_agent/cli/mcp_app/api_client.py (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 09-05-do_not_allow_unsupported_server_urls_as_arguments

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
Contributor Author

jtcorbett commented Sep 5, 2025

@jtcorbett jtcorbett marked this pull request as ready for review September 5, 2025 18:36

if not server_url:
server_url = await resolve_server_url(app_id, config_id, credentials)
server_url = await resolve_server_url(app_id, config_id, credentials)
Copy link
Contributor

Choose a reason for hiding this comment

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

The removal of the null check for server_url creates a potential issue. The resolve_server_url() function may return None in error cases, which would cause a runtime error when urlparse(server_url) is called on line 256.

Consider either:

  1. Restoring the null check with appropriate error handling:
server_url = await resolve_server_url(app_id, config_id, credentials)
if not server_url:
    console.print("[red]Error: Could not resolve server URL[/red]")
    raise typer.Exit(1)
  1. Ensuring resolve_server_url() never returns None by handling errors internally and raising appropriate exceptions that can be caught by the existing error handlers.

This will prevent unexpected crashes when streaming logs from servers that cannot be resolved.

Suggested change
server_url = await resolve_server_url(app_id, config_id, credentials)
server_url = await resolve_server_url(app_id, config_id, credentials)
if not server_url:
console.print("[red]Error: Could not resolve server URL[/red]")
raise typer.Exit(1)

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Member

@rholinshead rholinshead left a comment

Choose a reason for hiding this comment

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

Code LGTM, just small things -- I missed the resolve_server_url implementation earlier but seems like it could be cleaned up a bit later.

I have some reservations about removing the support in general but can appreciate that this is what the task asked for. We do want to use only the server url for configuration though

Copy link
Member

@rholinshead rholinshead left a comment

Choose a reason for hiding this comment

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

Just some comments but LGTM assuming it works (not confident about the snake case though)

@jtcorbett jtcorbett force-pushed the 09-05-do_not_allow_unsupported_server_urls_as_arguments branch from 9416bbb to 6456278 Compare September 5, 2025 20:54
@jtcorbett jtcorbett force-pushed the 09-05-do_not_allow_unsupported_server_urls_as_arguments branch from 6456278 to edc93a2 Compare September 5, 2025 21:15
@jtcorbett jtcorbett force-pushed the 09-05-refactor_logger_tail_http_requests_to_api_client branch from 8a35062 to 273b208 Compare September 5, 2025 21:15
Raises:
ValueError: If identifier format is not recognized
"""

Copy link
Contributor

Choose a reason for hiding this comment

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

The removal of the fallback case return identifier, None, None in favor of raising a ValueError represents a significant breaking change. This change will cause failures for any code that currently passes identifiers not prefixed with app_ or apcnf_.

Consider whether:

  1. This breaking change is intentional as part of the API redesign
  2. There are existing callers that rely on the previous behavior
  3. A more graceful transition might be appropriate, such as:
    • Adding a deprecation warning before raising an error
    • Providing a migration path for existing code
    • Including documentation about the change in release notes

If the strict validation is indeed the desired behavior, ensure that all calling code has been updated to use the new format requirements.

Suggested change
# Fallback with deprecation warning for backward compatibility
import warnings
warnings.warn(
f"Identifier '{identifier}' does not match expected format with 'app_' or 'apcnf_' prefix. "
"Returning (identifier, None, None) for backward compatibility. "
"This behavior is deprecated and will raise ValueError in a future release. "
"Please update your code to use properly formatted identifiers.",
DeprecationWarning,
stacklevel=2
)
return identifier, None, None

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Contributor Author

jtcorbett commented Sep 5, 2025

Merge activity

  • Sep 5, 9:23 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Sep 5, 9:25 PM UTC: Graphite couldn't merge this pull request because a downstack PR refactor logger tail http requests to api_client #422 failed to merge.
  • Sep 5, 9:29 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Sep 5, 9:38 PM UTC: Graphite couldn't merge this PR because it failed for an unknown reason (Your push would publish a private email address. You can make your email public or disable this protection on GitHub).

@jtcorbett jtcorbett changed the base branch from 09-05-refactor_logger_tail_http_requests_to_api_client to graphite-base/423 September 5, 2025 21:25
@jtcorbett jtcorbett force-pushed the 09-05-do_not_allow_unsupported_server_urls_as_arguments branch from 897130c to 0998161 Compare September 5, 2025 21:28
@jtcorbett jtcorbett changed the base branch from graphite-base/423 to 09-05-refactor_logger_tail_http_requests_to_api_client September 5, 2025 21:29
@jtcorbett jtcorbett changed the base branch from 09-05-refactor_logger_tail_http_requests_to_api_client to graphite-base/423 September 5, 2025 21:36
@jtcorbett jtcorbett changed the base branch from graphite-base/423 to main September 5, 2025 21:36
@jtcorbett jtcorbett force-pushed the 09-05-do_not_allow_unsupported_server_urls_as_arguments branch from 0998161 to 1dd21da Compare September 5, 2025 23:31
@jtcorbett jtcorbett merged commit c0fc9f6 into main Sep 5, 2025
6 of 7 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Sep 8, 2025
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.

4 participants