Skip to content

Commit 9416bbb

Browse files
committed
do not allow unsupported server URLs as arguments
1 parent 92622d0 commit 9416bbb

File tree

5 files changed

+31
-25
lines changed

5 files changed

+31
-25
lines changed

src/mcp_agent/cli/cloud/commands/logger/tail/main.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
def tail_logs(
3030
app_identifier: str = typer.Argument(
31-
help="Server ID, URL, or app configuration ID to retrieve logs for"
31+
help="App ID or app configuration ID to retrieve logs for"
3232
),
3333
since: Optional[str] = typer.Option(
3434
None,
@@ -83,7 +83,7 @@ def tail_logs(
8383
mcp-agent cloud logger tail app_abc123 --limit 50
8484
8585
# Stream logs continuously
86-
mcp-agent cloud logger tail https://app.mcpac.dev/abc123 --follow
86+
mcp-agent cloud logger tail app_abc123 --follow
8787
8888
# Show logs from the last hour with error filtering
8989
mcp-agent cloud logger tail app_abc123 --since 1h --grep "ERROR|WARN"
@@ -129,14 +129,17 @@ def tail_logs(
129129
console.print("[red]Error: --format must be 'text', 'json', or 'yaml'[/red]")
130130
raise typer.Exit(6)
131131

132-
app_id, config_id, server_url = parse_app_identifier(app_identifier)
132+
try:
133+
app_id, config_id = parse_app_identifier(app_identifier)
134+
except ValueError as e:
135+
console.print(f"[red]Error: {e}[/red]")
136+
raise typer.Exit(6)
133137

134138
try:
135139
if follow:
136140
asyncio.run(_stream_logs(
137141
app_id=app_id,
138142
config_id=config_id,
139-
server_url=server_url,
140143
credentials=credentials,
141144
grep_pattern=grep,
142145
app_identifier=app_identifier,
@@ -146,7 +149,6 @@ def tail_logs(
146149
asyncio.run(_fetch_logs(
147150
app_id=app_id,
148151
config_id=config_id,
149-
server_url=server_url,
150152
credentials=credentials,
151153
since=since,
152154
grep_pattern=grep,
@@ -168,7 +170,6 @@ def tail_logs(
168170
async def _fetch_logs(
169171
app_id: Optional[str],
170172
config_id: Optional[str],
171-
server_url: Optional[str],
172173
credentials: UserCredentials,
173174
since: Optional[str],
174175
grep_pattern: Optional[str],
@@ -241,17 +242,15 @@ async def _fetch_logs(
241242

242243
async def _stream_logs(
243244
app_id: Optional[str],
244-
config_id: Optional[str],
245-
server_url: Optional[str],
245+
config_id: Optional[str],
246246
credentials: UserCredentials,
247247
grep_pattern: Optional[str],
248248
app_identifier: str,
249249
format: str,
250250
) -> None:
251251
"""Stream logs continuously via SSE."""
252252

253-
if not server_url:
254-
server_url = await resolve_server_url(app_id, config_id, credentials)
253+
server_url = await resolve_server_url(app_id, config_id, credentials)
255254

256255
parsed = urlparse(server_url)
257256
stream_url = f"{parsed.scheme}://{parsed.netloc}/logs"

src/mcp_agent/cli/cloud/commands/servers/delete/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
@handle_server_api_errors
1919
def delete_server(
20-
id_or_url: str = typer.Argument(..., help="Server ID or URL to delete"),
20+
id_or_url: str = typer.Argument(..., help="Server ID or app configuration ID to delete"),
2121
force: bool = typer.Option(False, "--force", "-f", help="Force deletion without confirmation prompt"),
2222
) -> None:
2323
"""Delete a specific MCP Server."""

src/mcp_agent/cli/cloud/commands/servers/describe/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
@handle_server_api_errors
2121
def describe_server(
22-
id_or_url: str = typer.Argument(..., help="Server ID or URL to describe"),
22+
id_or_url: str = typer.Argument(..., help="Server ID or app configuration ID to describe"),
2323
format: Optional[str] = typer.Option("text", "--format", help="Output format (text|json|yaml)"),
2424
) -> None:
2525
"""Describe a specific MCP Server."""

src/mcp_agent/cli/cloud/commands/servers/utils.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ def validate_output_format(format: str) -> None:
5151

5252

5353
def resolve_server(client: MCPAppClient, id_or_url: str) -> Union[MCPApp, MCPAppConfiguration]:
54-
"""Resolve server from ID or URL.
54+
"""Resolve server from ID.
5555
5656
Args:
5757
client: Authenticated MCP App client
58-
id_or_url: Server identifier (ID, config ID, or URL)
58+
id_or_url: Server identifier (app ID or app config ID)
5959
6060
Returns:
6161
Server object (MCPApp or MCPAppConfiguration)
@@ -64,15 +64,15 @@ def resolve_server(client: MCPAppClient, id_or_url: str) -> Union[MCPApp, MCPApp
6464
CLIError: If server resolution fails
6565
"""
6666
try:
67-
app_id, config_id, server_url = parse_app_identifier(id_or_url)
67+
app_id, config_id = parse_app_identifier(id_or_url)
6868

69-
if server_url:
70-
return run_async(client.get_app(server_url=server_url))
71-
elif config_id:
69+
if config_id:
7270
return run_async(client.get_app_configuration(app_config_id=config_id))
7371
else:
7472
return run_async(client.get_app(app_id=app_id))
7573

74+
except ValueError as e:
75+
raise CLIError(str(e)) from e
7676
except Exception as e:
7777
raise CLIError(f"Failed to resolve server '{id_or_url}': {str(e)}") from e
7878

src/mcp_agent/cli/core/utils.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,26 @@ def run_async(coro):
2626
raise
2727

2828

29-
def parse_app_identifier(identifier: str) -> Tuple[Optional[str], Optional[str], Optional[str]]:
30-
"""Parse app identifier to extract app ID, config ID, and server URL."""
29+
def parse_app_identifier(identifier: str) -> Tuple[Optional[str], Optional[str]]:
30+
"""Parse app identifier to extract app ID and config ID.
3131
32-
if identifier.startswith(('http://', 'https://')):
33-
return None, None, identifier
32+
Args:
33+
identifier: App identifier (must be app_... or apcnf_...)
34+
35+
Returns:
36+
Tuple of (app_id, config_id)
37+
38+
Raises:
39+
ValueError: If identifier format is not recognized
40+
"""
3441

3542
if identifier.startswith('apcnf_'):
36-
return None, identifier, None
43+
return None, identifier
3744

3845
if identifier.startswith('app_'):
39-
return identifier, None, None
46+
return identifier, None
4047

41-
return identifier, None, None
48+
raise ValueError(f"Invalid identifier format: '{identifier}'. Must be an app ID (app_...) or app configuration ID (apcnf_...)")
4249

4350

4451
async def resolve_server_url(

0 commit comments

Comments
 (0)