Skip to content

Conversation

@jtcorbett
Copy link
Contributor

@jtcorbett jtcorbett commented Sep 11, 2025

TL;DR

Unified server resolution logic across CLI commands by implementing a centralized get_app_or_config method.

What changed?

  • Removed the redundant resolve_server and parse_app_identifier utility functions
  • Replaced all instances of these functions with direct calls to client.get_app_or_config
  • Updated the log tailing functionality to work with server URLs directly
  • Simplified server URL resolution in workflow commands
  • Enhanced the tail_logs command to accept server URLs as input
  • Updated help text and examples to reflect the new capabilities

How to test?

  1. Test the logger tail command with different identifier types:

    mcp-agent cloud logger tail app_abc123 --follow
    mcp-agent cloud logger tail apcnf_xyz789 --follow
    mcp-agent cloud logger tail https://abc123.mcpcloud.ai --follow
    
  2. Test server commands with different identifier types:

    mcp-agent cloud servers describe app_abc123
    mcp-agent cloud servers describe https://abc123.mcpcloud.ai
    
  3. Test workflow commands with server URLs:

    mcp-agent cloud workflows list https://abc123.mcpcloud.ai
    

Summary by CodeRabbit

  • New Features

    • Logger tail now supports using a direct server URL in addition to identifiers.
  • Refactor

    • Unified server resolution across logger, servers, and workflows commands for more consistent behavior.
    • Log fetching and streaming now operate directly on server objects, simplifying CLI flows.
  • Documentation

    • Added an example showing how to tail logs using a server URL.
  • Chores

    • Removed legacy helper utilities for server parsing/resolution to reduce complexity.

@coderabbitai
Copy link

coderabbitai bot commented Sep 11, 2025

Walkthrough

Refactors CLI server resolution to use client.get_app_or_config and server objects (MCPApp/MCPAppConfiguration). Logger tail now fetches/streams logs based on a server object and server.appServerInfo.serverUrl. Removes parse_app_identifier, resolve_server_url, and resolve_server helpers from utils; updates servers and workflows commands accordingly.

Changes

Cohort / File(s) Summary
Logger tail refactor to server-centric flow
src/mcp_agent/cli/cloud/commands/logger/tail/main.py
Tail command now accepts a server object (MCPApp or MCPAppConfiguration). _fetch_logs and _stream_logs signatures updated to take server. Derives app_id/config_id from server at runtime; maps order_by/asc/desc to API enums; streaming uses server.appServerInfo.serverUrl. Removes identifier parsing and URL resolution helpers.
Servers commands: resolve via client.get_app_or_config
src/mcp_agent/cli/cloud/commands/servers/delete/main.py, src/mcp_agent/cli/cloud/commands/servers/describe/main.py
Replaces resolve_server usage with run_async(client.get_app_or_config(id_or_url)). Logic for delete/describe otherwise unchanged.
Workflows commands: server resolution update
src/mcp_agent/cli/cloud/commands/workflows/.../main.py (cancel, describe, list, resume, runs)
Replaces resolve_server with run_async(client.get_app_or_config(server_id_or_url)). Retains server.appServerInfo.serverUrl extraction and existing error paths. Public signatures unchanged.
Cloud commands utils cleanup
src/mcp_agent/cli/cloud/commands/utils.py
Removes resolve_server helper and related imports. Leaves other utilities (e.g., error handling) intact.
Core utils: remove identifier parsing and API URL resolution
src/mcp_agent/cli/core/utils.py
Deletes parse_app_identifier and resolve_server_url. Removes HTTP/API-based resolution and related imports. Retains attach_url_servers/attach_stdio_servers and ensure_mcp_servers.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI: logger tail
  participant Client as MCPAppClient
  participant Server as Server (MCPApp/MCPAppConfiguration)
  participant LogsAPI as Logs API

  User->>CLI: tail --app <identifier> [--since/--limit/...]
  CLI->>Client: get_app_or_config(identifier)
  Client-->>CLI: Server
  alt Fetch once
    CLI->>Client: get_app_logs(app_id/app_configuration_id, order_by, dir, since, limit)
    Client-->>CLI: LogEntries
    CLI->>CLI: Optional grep + format
    CLI-->>User: Display logs (title=app_identifier)
  else Stream
    CLI->>CLI: server_url = Server.appServerInfo.serverUrl
    CLI->>LogsAPI: GET {server_url}/logs/stream<br/>Headers: X-Routing-Key (deployment_id)
    LogsAPI-->>CLI: SSE/stream events
    CLI-->>User: Live log lines
  end
Loading
sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI: workflows/*, servers/*
  participant Client as MCPAppClient
  participant Server as Server (MCPApp/MCPAppConfiguration)

  User->>CLI: cmd --server <id-or-url>
  alt Input is URL
    CLI->>CLI: Use provided URL directly
  else Identifier
    CLI->>Client: get_app_or_config(id)
    Client-->>CLI: Server
    CLI->>CLI: Extract serverUrl = Server.appServerInfo.serverUrl
  end
  CLI-->>User: Proceed with action using serverUrl
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • petersonbill64
  • saqadri

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title is concise, focused, and accurately reflects the primary change in the PR — enabling the logger command to accept direct URLs — so it clearly summarizes the main intent without extra noise.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Poem

A rabbit taps logs with a twitch of an ear,
IDs hop away; the servers draw near.
Streams start to babble, timestamps align,
Workflows and tails in a tidy new line.
I thump in approval—refactors done right,
Carrots for all, and clean code tonight! 🥕🐇

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ 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-11-allow_logger_to_also_take_urls

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

This stack of pull requests is managed by Graphite. Learn more about stacking.

@jtcorbett jtcorbett changed the title allow logger to also take URLs Allow logger to also take URLs Sep 11, 2025
@jtcorbett jtcorbett marked this pull request as ready for review September 11, 2025 18:09
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.

Love it!

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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
src/mcp_agent/cli/cloud/commands/workflows/list/main.py (1)

48-51: Fix potential double “//” in SSE URL

Use rstrip('/') before appending /sse.

-            sse_url = (
-                f"{server_url}/sse" if not server_url.endswith("/sse") else server_url
-            )
+            sse_url = (
+                f"{server_url.rstrip('/')}/sse"
+                if not server_url.endswith("/sse")
+                else server_url
+            )
src/mcp_agent/cli/cloud/commands/workflows/runs/main.py (1)

48-51: Fix potential double “//” in SSE URL

Use rstrip('/') when appending /sse.

-            sse_url = (
-                f"{server_url}/sse" if not server_url.endswith("/sse") else server_url
-            )
+            sse_url = (
+                f"{server_url.rstrip('/')}/sse"
+                if not server_url.endswith("/sse")
+                else server_url
+            )
src/mcp_agent/cli/cloud/commands/workflows/describe/main.py (1)

48-51: Fix potential double “//” in SSE URL

Use rstrip('/') when appending.

-            sse_url = (
-                f"{server_url}/sse" if not server_url.endswith("/sse") else server_url
-            )
+            sse_url = (
+                f"{server_url.rstrip('/')}/sse"
+                if not server_url.endswith("/sse")
+                else server_url
+            )
src/mcp_agent/cli/cloud/commands/logger/tail/main.py (2)

312-317: Fix SSE buffer growth and duplicate processing.
Currently, processed lines remain in buffer, causing unbounded growth and repeated parsing.

                 buffer += chunk
                 lines = buffer.split("\n")
 
                 for line in lines[:-1]:
                     if line.startswith("data:"):
                         data_content = line.removeprefix("data:")
+                # Keep only the trailing partial line for the next iteration
+                buffer = lines[-1]

439-444: Handle ms/ISO timestamps to prevent crashes and wrong times.
SSE often uses ms or ISO strings; large ms values can raise or format far-future times.

-def _convert_timestamp_to_local(timestamp: float) -> str:
-    """Convert UTC timestamp to local time ISO format."""
-    dt_utc = datetime.fromtimestamp(timestamp, timezone.utc)
-    dt_local = dt_utc.astimezone()
-    return dt_local.isoformat()
+def _convert_timestamp_to_local(timestamp: Any) -> str:
+    """Convert UTC/epoch(ms|s|ns) or ISO timestamp to local time ISO format."""
+    try:
+        if isinstance(timestamp, str):
+            dt_utc = datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
+        else:
+            t = float(timestamp)
+            if t > 1e12:  # ns -> s
+                t /= 1e9
+            elif t > 1e10:  # ms -> s
+                t /= 1e3
+            dt_utc = datetime.fromtimestamp(t, timezone.utc)
+        return dt_utc.astimezone().isoformat()
+    except Exception:
+        return datetime.now().astimezone().isoformat()
🧹 Nitpick comments (8)
src/mcp_agent/cli/core/utils.py (1)

12-27: run_async fallback is unsafe inside a running event loop

Calling run_until_complete on an already running loop will raise RuntimeError. Prefer failing fast with a clear message; callers in async contexts should await directly.

Apply:

 def run_async(coro):
@@
-    except RuntimeError as e:
-        # If we're already in an event loop (like in pytest-asyncio tests)
-        if "cannot be called from a running event loop" in str(e):
-            loop = asyncio.get_event_loop()
-            return loop.run_until_complete(coro)
-        raise
+    except RuntimeError as e:
+        if "cannot be called from a running event loop" in str(e):
+            raise RuntimeError(
+                "run_async cannot be used from within an async context; await the coroutine instead."
+            ) from e
+        raise
src/mcp_agent/cli/cloud/commands/servers/describe/main.py (1)

22-27: Update help text to reflect URL support

Include “or server URL”.

-    id_or_url: str = typer.Argument(
-        ..., help="Server ID or app configuration ID to describe"
-    ),
+    id_or_url: str = typer.Argument(
+        ..., help="Server ID, app configuration ID, or server URL to describe"
+    ),
src/mcp_agent/cli/cloud/commands/workflows/runs/main.py (1)

263-264: Non-standard color “orange”

Rich may not support [orange] everywhere; use [yellow] for portability.

-        return "[orange]⏰ Timed Out[/orange]"
+        return "[yellow]⏰ Timed Out[/yellow]"
src/mcp_agent/cli/cloud/commands/servers/delete/main.py (1)

18-23: Update help text to reflect URL support

Include URL in the prompt.

-    id_or_url: str = typer.Argument(
-        ..., help="Server ID or app configuration ID to delete"
-    ),
+    id_or_url: str = typer.Argument(
+        ..., help="Server ID, app configuration ID, or server URL to delete"
+    ),
src/mcp_agent/cli/cloud/commands/workflows/describe/main.py (1)

106-111: Use shared validator for format for consistency

Reuse validate_output_format to match other commands.

-    if format not in ["text", "json", "yaml"]:
-        console.print("[red]Error: --format must be 'text', 'json', or 'yaml'[/red]")
-        raise typer.Exit(6)
-
-    run_async(_describe_workflow_async(server_id_or_url, run_id, format))
+    validate_output_format(format)
+    run_async(_describe_workflow_async(server_id_or_url, run_id, format))
src/mcp_agent/cli/cloud/commands/logger/tail/main.py (3)

33-33: Docs/UX: help and examples now mention server URLs — nice.
Optional: explicitly show that the scheme is required (e.g., https://) in the help string.

-        help="App ID, app configuration ID, or server URL to retrieve logs for"
+        help="App ID, app configuration ID, or server URL (including scheme, e.g., https://...)"

Also applies to: 96-97


186-193: Prefer isinstance over hasattr; add an explicit else guard.
Reduces ambiguity and makes failures obvious if a different type slips through.

-    if hasattr(server, 'appId'):  # MCPApp
-        app_id = server.appId
-        config_id = None
-    else:  # MCPAppConfiguration
-        app_id = None
-        config_id = server.appConfigurationId
+    if isinstance(server, MCPApp):
+        app_id = server.appId
+        config_id = None
+    elif isinstance(server, MCPAppConfiguration):
+        app_id = None
+        config_id = server.appConfigurationId
+    else:
+        raise CLIError(f"Unsupported server object type: {type(server).__name__}")

253-254: Nit: title now uses the raw identifier.
Optional: include a friendly name when available, e.g., server.app.name or the server URL hostname, falling back to the identifier.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fb3daf and 4b9d901.

📒 Files selected for processing (10)
  • src/mcp_agent/cli/cloud/commands/logger/tail/main.py (8 hunks)
  • src/mcp_agent/cli/cloud/commands/servers/delete/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/servers/describe/main.py (2 hunks)
  • src/mcp_agent/cli/cloud/commands/utils.py (0 hunks)
  • src/mcp_agent/cli/cloud/commands/workflows/cancel/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/workflows/describe/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/workflows/list/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/workflows/resume/main.py (1 hunks)
  • src/mcp_agent/cli/cloud/commands/workflows/runs/main.py (1 hunks)
  • src/mcp_agent/cli/core/utils.py (1 hunks)
💤 Files with no reviewable changes (1)
  • src/mcp_agent/cli/cloud/commands/utils.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-22T18:59:49.368Z
Learnt from: CR
PR: lastmile-ai/mcp-agent#0
File: examples/usecases/reliable_conversation/CLAUDE.md:0-0
Timestamp: 2025-07-22T18:59:49.368Z
Learning: Applies to examples/usecases/reliable_conversation/examples/reliable_conversation/src/utils/config.py : Configuration values such as quality_threshold, max_refinement_attempts, consolidation_interval, and evaluator_model_provider must be loaded from mcp_agent.config.yaml.

Applied to files:

  • src/mcp_agent/cli/cloud/commands/logger/tail/main.py
🧬 Code graph analysis (8)
src/mcp_agent/cli/cloud/commands/workflows/resume/main.py (2)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/workflows/runs/main.py (2)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/workflows/list/main.py (2)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/workflows/describe/main.py (2)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/workflows/cancel/main.py (2)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/servers/describe/main.py (2)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/servers/delete/main.py (2)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (1)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/logger/tail/main.py (4)
src/mcp_agent/cli/core/utils.py (1)
  • run_async (12-27)
src/mcp_agent/cli/mcp_app/api_client.py (3)
  • MCPApp (22-29)
  • MCPAppConfiguration (33-38)
  • get_app_or_config (247-283)
src/mcp_agent/cli/cloud/commands/utils.py (1)
  • setup_authenticated_client (17-31)
src/mcp_agent/cli/exceptions.py (1)
  • CLIError (4-9)
🔇 Additional comments (7)
src/mcp_agent/cli/cloud/commands/servers/describe/main.py (1)

16-33: Good switch to client.get_app_or_config()

Synchronous usage of run_async here is appropriate.

src/mcp_agent/cli/cloud/commands/workflows/cancel/main.py (1)

61-75: Don't forward --reason — backend tool doesn't accept it

Server-side "workflows-cancel" (src/mcp_agent/server/app_server.py, ~lines 863–865) only accepts run_id/workflow_id; adding tool_params["reason"] would be unsupported. Either add a 'reason' parameter+handling in the server tool, or keep the CLI --reason without forwarding.

Likely an incorrect or invalid review comment.

src/mcp_agent/cli/cloud/commands/servers/delete/main.py (1)

27-28: Good: centralized resolution via get_app_or_config

Synchronous run_async use is correct here.

src/mcp_agent/cli/cloud/commands/logger/tail/main.py (4)

9-9: LGTM: imports and typing updates align with the refactor.

Also applies to: 22-22, 24-24


144-149: LGTM: call sites now pass a resolved server object.

Also applies to: 152-164


174-175: LGTM: server-typed signatures clarify intent.

Also applies to: 182-183


257-262: LGTM: streamed variant matches the fetch signature.

Comment on lines +137 to 140
client = setup_authenticated_client()
server = run_async(client.get_app_or_config(app_identifier))

try:
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Catch resolution errors: wrap get_app_or_config in the existing try.
Right now, failures raise before the try/except and bypass clean CLIError formatting.

-    client = setup_authenticated_client()
-    server = run_async(client.get_app_or_config(app_identifier))
-    
-    try:
+    try:
+        client = setup_authenticated_client()
+        server = run_async(client.get_app_or_config(app_identifier))

Optional (outside this hunk): add specific excepts for httpx.HTTPStatusError (401/404) around this try to mirror _fetch_logs.

📝 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
client = setup_authenticated_client()
server = run_async(client.get_app_or_config(app_identifier))
try:
try:
client = setup_authenticated_client()
server = run_async(client.get_app_or_config(app_identifier))
🤖 Prompt for AI Agents
In src/mcp_agent/cli/cloud/commands/logger/tail/main.py around lines 137 to 140,
the call to client.get_app_or_config(app_identifier) is executed before entering
the try/except so any resolution errors escape the CLIError handling; move or
wrap the run_async(client.get_app_or_config(app_identifier)) invocation inside
the existing try block so its exceptions are caught and formatted correctly, and
optionally add specific except clauses for httpx.HTTPStatusError (handling
401/404) alongside the existing excepts to mirror _fetch_logs.

Comment on lines +265 to 270
# Get server URL directly from the server object
if not server.appServerInfo or not server.appServerInfo.serverUrl:
raise CLIError("Server URL not available - server may not be deployed")

server_url = server.appServerInfo.serverUrl

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Harden server URL handling; add connect timeout for SSE.

  • Append /logs relative to any existing path (not just host root).
  • Derive routing key robustly; hostname may be None or lack dots.
  • Use a finite connect timeout for AsyncClient; keep read timeout None for streaming.
-    if not server.appServerInfo or not server.appServerInfo.serverUrl:
+    if not getattr(server, "appServerInfo", None) or not server.appServerInfo.serverUrl:
         raise CLIError("Server URL not available - server may not be deployed")
-    
-    server_url = server.appServerInfo.serverUrl
+    server_url = server.appServerInfo.serverUrl.rstrip("/")

Additional changes outside this hunk to complete the fix:

-    parsed = urlparse(server_url)
-    stream_url = f"{parsed.scheme}://{parsed.netloc}/logs"
+    parsed = urlparse(server_url)
+    base_path = (parsed.path or "").rstrip("/")
+    stream_url = f"{parsed.scheme}://{parsed.netloc}{base_path}/logs"
-    hostname = parsed.hostname or ""
-    deployment_id = hostname.split(".")[0] if "." in hostname else hostname
+    hostname = (parsed.hostname or "").strip()
+    deployment_id = hostname.split(".", 1)[0] if hostname else ""

And for the client (outside this hunk):

-        async with httpx.AsyncClient(timeout=None) as client:
+        async with httpx.AsyncClient(timeout=httpx.Timeout(connect=10.0, read=None)) as client:
📝 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
# Get server URL directly from the server object
if not server.appServerInfo or not server.appServerInfo.serverUrl:
raise CLIError("Server URL not available - server may not be deployed")
server_url = server.appServerInfo.serverUrl
# Get server URL directly from the server object
if not getattr(server, "appServerInfo", None) or not server.appServerInfo.serverUrl:
raise CLIError("Server URL not available - server may not be deployed")
server_url = server.appServerInfo.serverUrl.rstrip("/")

Comment on lines +27 to 28
server = run_async(client.get_app_or_config(server_id_or_url))

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: run_async used inside async function

Await instead.

-        server = run_async(client.get_app_or_config(server_id_or_url))
+        server = await client.get_app_or_config(server_id_or_url)
📝 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
server = run_async(client.get_app_or_config(server_id_or_url))
server = await client.get_app_or_config(server_id_or_url)
🤖 Prompt for AI Agents
In src/mcp_agent/cli/cloud/commands/workflows/cancel/main.py around lines 27-28,
the code calls run_async(client.get_app_or_config(server_id_or_url)) inside an
async function; replace this with an await expression (await
client.get_app_or_config(server_id_or_url)) and remove run_async. Ensure the
enclosing function is declared async and that any callers properly await it or
handle the coroutine.

Comment on lines +29 to 30
server = run_async(client.get_app_or_config(server_id_or_url))

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: run_async used inside async function

Await instead.

-        server = run_async(client.get_app_or_config(server_id_or_url))
+        server = await client.get_app_or_config(server_id_or_url)
📝 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
server = run_async(client.get_app_or_config(server_id_or_url))
server = await client.get_app_or_config(server_id_or_url)
🤖 Prompt for AI Agents
In src/mcp_agent/cli/cloud/commands/workflows/describe/main.py around lines
29-30, the code calls run_async(client.get_app_or_config(server_id_or_url))
inside an async function; replace that with using await directly (server = await
client.get_app_or_config(server_id_or_url)) so the coroutine is properly awaited
within the async context and remove the run_async wrapper.

Comment on lines +29 to 30
server = run_async(client.get_app_or_config(server_id_or_url))

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: run_async used inside async function

This will fail under a running event loop. Await the coroutine instead.

-        server = run_async(client.get_app_or_config(server_id_or_url))
+        server = await client.get_app_or_config(server_id_or_url)
📝 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
server = run_async(client.get_app_or_config(server_id_or_url))
server = await client.get_app_or_config(server_id_or_url)
🤖 Prompt for AI Agents
In src/mcp_agent/cli/cloud/commands/workflows/list/main.py around lines 29-30,
run_async is being used to execute a coroutine inside an already async function
which will fail when an event loop is running; replace the run_async call by
directly awaiting the coroutine (i.e., assign server = await
client.get_app_or_config(server_id_or_url)), ensure the containing function is
declared async, and remove any now-unused run_async import.

Comment on lines +31 to 32
server = run_async(client.get_app_or_config(server_id_or_url))

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: run_async used inside async function

Await instead.

-        server = run_async(client.get_app_or_config(server_id_or_url))
+        server = await client.get_app_or_config(server_id_or_url)
📝 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
server = run_async(client.get_app_or_config(server_id_or_url))
server = await client.get_app_or_config(server_id_or_url)
🤖 Prompt for AI Agents
In src/mcp_agent/cli/cloud/commands/workflows/resume/main.py around lines 31-32,
the code calls run_async(...) from inside an async function which is incorrect;
replace the run_async call with an await of the coroutine (server = await
client.get_app_or_config(server_id_or_url)), and remove or stop using the
run_async helper/import if it becomes unused.

Comment on lines +29 to 30
server = run_async(client.get_app_or_config(server_id_or_url))

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: run_async used inside async function

Await instead.

-        server = run_async(client.get_app_or_config(server_id_or_url))
+        server = await client.get_app_or_config(server_id_or_url)
📝 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
server = run_async(client.get_app_or_config(server_id_or_url))
server = await client.get_app_or_config(server_id_or_url)
🤖 Prompt for AI Agents
In src/mcp_agent/cli/cloud/commands/workflows/runs/main.py around lines 29-30,
the code calls run_async(client.get_app_or_config(server_id_or_url)) inside an
async function; replace this with awaiting the coroutine directly: change the
call to await client.get_app_or_config(server_id_or_url) and assign that result
to server, removing the run_async wrapper so the coroutine is awaited properly.

@jtcorbett jtcorbett merged commit b97af6d into main Sep 11, 2025
9 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