Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 40 additions & 47 deletions src/mcp_agent/cli/cloud/commands/deploy/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Deploy command for MCP Agent Cloud CLI.
"""Deploy command for mcp-agent cloud CLI.

This module provides the deploy_config function which processes configuration files
with secret tags and transforms them into deployment-ready configurations with secret handles.
Expand Down Expand Up @@ -130,7 +130,7 @@ def deploy_config(
resolve_path=True,
),
) -> str:
"""Deploy an MCP agent using the specified configuration.
"""Deploy an mcp-agent using the specified configuration.

An MCP App is deployed from bundling the code at the specified config directory.
This directory must contain an 'mcp_agent.config.yaml' at its root. The process will look for an existing
Expand Down Expand Up @@ -176,19 +176,12 @@ def deploy_config(
if app_name is None:
if default_app_name:
print_info(
f"No app name provided. Using '{default_app_name}' from configuration."
f"Using app name from config.yaml: '{default_app_name}'"
)
app_name = default_app_name
else:
app_name = "default"
print_info("No app name provided. Using 'default' as app name.")

if app_description is None:
if default_app_description:
print_info(
"No app description provided. Using description from configuration."
)
app_description = default_app_description
print_info("Using app name: 'default'")

provided_key = api_key
effective_api_url = api_url or settings.API_BASE_URL
Expand All @@ -203,40 +196,50 @@ def deploy_config(
)
if not effective_api_key:
raise CLIError(
"Must be logged in to deploy. Run 'mcp-agent login', set MCP_API_KEY environment variable or specify --api-key option.",
"You need to be logged in to deploy.\n\n"
"To continue, do one of the following:\n"
" • Run: mcp-agent login\n"
" • Or set the MCP_API_KEY environment variable\n"
" • Or use the --api-key flag with your key",
retriable=False,
)
print_info(f"Using API at {effective_api_url}")

if settings.VERBOSE:
print_info(f"Using API at {effective_api_url}")

mcp_app_client = MCPAppClient(
api_url=effective_api_url, api_key=effective_api_key
)

print_info(f"Checking for existing app ID for '{app_name}'...")
if settings.VERBOSE:
print_info(f"Checking for existing app ID for '{app_name}'...")

try:
app_id = run_async(mcp_app_client.get_app_id_by_name(app_name))
if not app_id:
print_info(
f"No existing app found with name '{app_name}'. Creating a new app..."
)
print_info(f"App '{app_name}' not found — creating a new one...")
app = run_async(
mcp_app_client.create_app(
name=app_name, description=app_description
)
)
app_id = app.appId
print_success(f"Created new app with ID: {app_id}")
print_success(f"Created new app '{app_name}'")
if settings.VERBOSE:
print_info(f"New app id: `{app_id}`")
else:
short_id = f"{app_id[:8]}…"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
short_id = f"{app_id[:8]}…"
short_id = f"{app_id[:8]}{app_id[-4:]}"

recommend including some substring from the end since the first 8 digits can definitely match other ids

print_success(
f"Found existing app with ID: {app_id} for name '{app_name}'"
f"Found existing app '{app_name}' (ID: `{short_id}`)"
)
if not non_interactive:
use_existing = typer.confirm(
f"Do you want deploy an update to the existing app ID: {app_id}?",
f"Deploy an update to '{app_name}' (ID: `{short_id}`)?",
default=True,
)
if use_existing:
print_info(f"Will deploy an update to app ID: {app_id}")
if settings.VERBOSE:
print_info(f"Will deploy an update to app ID: `{app_id}`")
else:
print_error(
"Cancelling deployment. Please choose a different app name."
Expand All @@ -257,25 +260,21 @@ def deploy_config(
# If a deployed secrets file already exists, determine if it should be used or overwritten
if deployed_secrets_file:
if secrets_file:
print_info(
f"Both '{MCP_SECRETS_FILENAME}' and '{MCP_DEPLOYED_SECRETS_FILENAME}' found in {config_dir}."
)
if settings.VERBOSE:
print_info(
f"Both '{MCP_SECRETS_FILENAME}' and '{MCP_DEPLOYED_SECRETS_FILENAME}' found in {config_dir}."
)
if non_interactive:
print_info(
"--non-interactive specified, using existing deployed secrets file without changes."
"Running in non-interactive mode — reusing previously deployed secrets."
)
else:
reuse = typer.confirm(
f"Do you want to reuse the previously deployed secrets in '{MCP_DEPLOYED_SECRETS_FILENAME}'?",
f"Re-use the deployed secrets from '{MCP_DEPLOYED_SECRETS_FILENAME}'?",
default=True,
)
if not reuse:
print_info(
f"Will update existing '{MCP_DEPLOYED_SECRETS_FILENAME}' by re-processing '{MCP_SECRETS_FILENAME}'."
)
deployed_secrets_file = None # Will trigger re-processing
else:
print_info(f"Using existing '{MCP_DEPLOYED_SECRETS_FILENAME}'.")
deployed_secrets_file = None # Will trigger re-processing)
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a syntax error in this line - an extra closing parenthesis after the comment. Additionally, the original code included an else clause that informed users when they chose to reuse existing secrets, but this message has been removed in the new version.

Consider:

  1. Removing the trailing parenthesis: deployed_secrets_file = None # Will trigger re-processing
  2. Adding back the informational message in the else clause with a verbose check:
else:
    if settings.VERBOSE:
        print_info(f"Using existing '{MCP_DEPLOYED_SECRETS_FILENAME}'.")

This maintains the user feedback while following the PR's goal of moving non-critical messages to verbose mode.

Suggested change
deployed_secrets_file = None # Will trigger re-processing)
deployed_secrets_file = None # Will trigger re-processing
else:
if settings.VERBOSE:
print_info(f"Using existing '{MCP_DEPLOYED_SECRETS_FILENAME}'.")

Spotted by Graphite Agent

Fix in Graphite


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

else:
print_info(
f"Found '{MCP_DEPLOYED_SECRETS_FILENAME}' in {config_dir}, but no '{MCP_SECRETS_FILENAME}' to re-process. Using existing deployed secrets file."
Expand All @@ -287,7 +286,7 @@ def deploy_config(

secrets_transformed_path = None
if secrets_file and not deployed_secrets_file:
print_info("Processing secrets file...")
# print_info("Processing secrets file...")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# print_info("Processing secrets file...")
if settings.VERBOSE:
print_info("Processing secrets file...")

secrets_transformed_path = config_dir / MCP_DEPLOYED_SECRETS_FILENAME

run_async(
Expand All @@ -301,21 +300,14 @@ def deploy_config(
)

print_success("Secrets file processed successfully")
print_info(
f"Transformed secrets file written to {secrets_transformed_path}"
)
if settings.VERBOSE:
print_info(
f"Transformed secrets file written to {secrets_transformed_path}"
)

else:
print_info("Skipping secrets processing...")

console.print(
Panel(
"Ready to deploy MCP Agent with processed configuration",
title="Deployment Ready",
border_style="green",
)
)

# Optionally create a local git tag as a breadcrumb of this deployment
if git_tag:
git_meta = get_git_metadata(config_dir)
Expand All @@ -325,7 +317,7 @@ def deploy_config(
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
tag_name = f"mcp-deploy/{safe_name}/{ts}-{git_meta.short_sha}"
msg = (
f"MCP Agent deploy for app '{app_name}' (id {app_id})\n"
f"mcp-agent deploy for app '{app_name}' (ID: `{app_id}`)\n"
f"Commit: {git_meta.commit_sha}\n"
f"Branch: {git_meta.branch or ''}\n"
f"Dirty: {git_meta.dirty}"
Expand Down Expand Up @@ -358,7 +350,7 @@ def deploy_config(
)
)

print_info(f"App ID: {app_id}")
print_info(f"App Name '{app_name}'")
Copy link
Member

@rholinshead rholinshead Oct 8, 2025

Choose a reason for hiding this comment

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

Can we keep this as ID? Otherwise we lose that critical info for debugging

if app.appServerInfo:
status = (
"ONLINE"
Expand Down Expand Up @@ -463,7 +455,8 @@ async def _perform_api_deployment():
raise

if retry_count > 1:
print_info(f"Deployment API configured with up to {retry_count} attempts")
if settings.VERBOSE:
print_info(f"Deployment API configured with up to {retry_count} attempts")

try:
return await retry_async_with_exponential_backoff(
Expand Down
6 changes: 4 additions & 2 deletions src/mcp_agent/cli/cloud/commands/deploy/wrangler_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ def wrangler_deploy(
else:
print_info(f"Using ignore patterns from {ignore_file}")
else:
print_info("No ignore file provided; applying default excludes only")
if settings.VERBOSE:
print_info("No ignore file provided; applying default excludes only")

# Copy the entire project to temp directory, excluding unwanted directories and the live secrets file
def ignore_patterns(path_str, names):
Expand Down Expand Up @@ -294,7 +295,8 @@ def ignore_patterns(path_str, names):
},
)
meta_vars.update({"MCP_DEPLOY_WORKSPACE_HASH": bundle_hash})
print_info(f"Deploying from non-git workspace (hash {bundle_hash[:12]}…)")
if settings.VERBOSE:
print_info(f"Deploying from non-git workspace (hash {bundle_hash[:12]}…)")

# Write a breadcrumb file into the project so it ships with the bundle.
# Use a Python file for guaranteed inclusion without renaming.
Expand Down
2 changes: 1 addition & 1 deletion src/mcp_agent/cli/utils/ux.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def print_deployment_header(
f"Configuration: [cyan]{config_file}[/cyan]\n"
f"Secrets file: [cyan]{secrets_file or 'N/A'}[/cyan]\n"
f"Deployed secrets file: [cyan]{deployed_secrets_file or 'Pending creation'}[/cyan]\n",
title="MCP Agent Deployment",
title="mcp-agent deployment",
subtitle="LastMile AI",
border_style="blue",
expand=False,
Expand Down
Loading