akashcli 4.7.0__tar.gz → 4.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {akashcli-4.7.0 → akashcli-4.7.1}/PKG-INFO +1 -1
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/__init__.py +1 -1
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/cli.py +41 -227
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli.egg-info/PKG-INFO +1 -1
- {akashcli-4.7.0 → akashcli-4.7.1}/pyproject.toml +1 -1
- {akashcli-4.7.0 → akashcli-4.7.1}/README.md +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/_net.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/auth.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/client.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/config.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/crypto.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/env_manager.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/exceptions.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/exec.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/integrity.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/logger.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/models.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/p2p.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/packages.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/relay.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/restore.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/snapshot_crypto.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/storage.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/terminal.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/uploader.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli/utils.py +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli.egg-info/SOURCES.txt +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli.egg-info/dependency_links.txt +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli.egg-info/entry_points.txt +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli.egg-info/requires.txt +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/akashcli.egg-info/top_level.txt +0 -0
- {akashcli-4.7.0 → akashcli-4.7.1}/setup.cfg +0 -0
|
@@ -204,40 +204,45 @@ def _print_help():
|
|
|
204
204
|
C, G, Y, DM, RS = _C, _G, _Y, _DM, _RS
|
|
205
205
|
lines = [
|
|
206
206
|
"",
|
|
207
|
-
f" {C}akash{RS} {DM}
|
|
207
|
+
f" {C}akash{RS} {DM}— encrypted cloud backup · remote shell · AI agent vault{RS}",
|
|
208
208
|
"",
|
|
209
|
-
f" {DM}
|
|
210
|
-
f" {C}
|
|
211
|
-
f" {C}
|
|
209
|
+
f" {DM}ACCOUNT & SERVER{RS}",
|
|
210
|
+
f" {C}login{RS} {DM}[--label NAME] [--url URL]{RS} save your API key + name this device",
|
|
211
|
+
f" {C}whoami{RS} account quota, storage URL & device info",
|
|
212
|
+
f" {C}url{RS} {DM}[NEW_URL|--reset]{RS} view or switch configured storage server URL",
|
|
213
|
+
f" {C}logout{RS} clear saved credentials from this device",
|
|
212
214
|
"",
|
|
213
215
|
f" {DM}ENVIRONMENT BACKUP{RS}",
|
|
214
|
-
f" {C}backup{RS} {DM}[--password
|
|
215
|
-
f" {C}restore{RS} {DM}<CODE|PATH>{RS}
|
|
216
|
-
f" {C}
|
|
217
|
-
f" {C}
|
|
216
|
+
f" {C}backup{RS} {DM}[--label NAME] [--password PASS]{RS} save environment & packages to cloud or disk",
|
|
217
|
+
f" {C}restore{RS} {DM}<CODE|PATH> [--dry-run]{RS} restore terminal environment from cloud or archive",
|
|
218
|
+
f" {C}saves{RS} {DM}[--json]{RS} list cloud-saved and local environments",
|
|
219
|
+
f" {C}pull{RS} {DM}<CODE> [--target DIR]{RS} one-shot restore on fresh machine (no login needed)",
|
|
218
220
|
"",
|
|
219
|
-
f" {DM}REMOTE TERMINAL{RS}",
|
|
220
|
-
f" {C}shell{RS} {DM}[
|
|
221
|
-
f" {C}run{RS} {DM}<CMD> [--device NAME]{RS}
|
|
222
|
-
f" {C}serve{RS} {DM}[--share]{RS}
|
|
223
|
-
f" {C}devices{RS} {DM}[--revoke NAME]{RS}
|
|
221
|
+
f" {DM}REMOTE TERMINAL & SHELL{RS}",
|
|
222
|
+
f" {C}shell{RS} {DM}[DEVICE|--code CODE]{RS} open interactive shell (local, device, or code)",
|
|
223
|
+
f" {C}run{RS} {DM}<CMD> [--device NAME]{RS} run command on server or enrolled device",
|
|
224
|
+
f" {C}serve{RS} {DM}[--share] [--label NAME]{RS} make this device reachable (or get one-time code)",
|
|
225
|
+
f" {C}devices{RS} {DM}[--revoke NAME]{RS} list or manage enrolled devices",
|
|
224
226
|
"",
|
|
225
|
-
f" {DM}
|
|
226
|
-
f" {C}
|
|
227
|
-
f" {C}send{RS} {DM}<USER> <FILE>{RS} end-to-end encrypted P2P file transfer",
|
|
228
|
-
f" {C}inbox{RS} {DM}[CODE]{RS} receive & decrypt files sent to your identity",
|
|
229
|
-
f" {C}id{RS} {DM}[--renew]{RS} view or renew your P2P identity fingerprint",
|
|
227
|
+
f" {DM}AI AGENTS & MCP{RS}",
|
|
228
|
+
f" {C}mcp{RS} {DM}<serve|share|create|list…>{RS} AI agent & MCP tool bridge (Codex, Claude, Cursor)",
|
|
230
229
|
"",
|
|
231
|
-
f" {DM}
|
|
232
|
-
f" {C}
|
|
233
|
-
f" {C}
|
|
234
|
-
f" {C}whoami{RS} account quota, storage URL & device info",
|
|
235
|
-
f" {C}url{RS} {DM}[NEW_URL|--reset]{RS} view or switch configured storage server URL",
|
|
236
|
-
f" {C}version{RS} check CLI and server status & versions",
|
|
237
|
-
f" {C}env{RS} {DM}<set|get|list…>{RS} encrypted local .env store",
|
|
238
|
-
f" {C}check{RS} {DM}[--seal]{RS} verify source integrity & tamper detection",
|
|
230
|
+
f" {DM}FILES & CLOUD VAULT{RS}",
|
|
231
|
+
f" {C}cloud{RS} {DM}<upload|files|stream|delete…>{RS} cloud file vault & media streaming engine",
|
|
232
|
+
f" {C}pipe{RS} {DM}[--name NAME] [--burn]{RS} pipe stdin or command output directly to cloud vault",
|
|
239
233
|
"",
|
|
240
|
-
f" {DM}
|
|
234
|
+
f" {DM}SECURE P2P TRANSFERS{RS}",
|
|
235
|
+
f" {C}send{RS} {DM}<USER> <FILE>{RS} end-to-end encrypted P2P file transfer",
|
|
236
|
+
f" {C}inbox{RS} {DM}[CODE]{RS} receive & decrypt files sent to your identity",
|
|
237
|
+
f" {C}id{RS} {DM}[--export|--add]{RS} show P2P fingerprint, export key, or add contacts",
|
|
238
|
+
"",
|
|
239
|
+
f" {DM}SECRETS & SYSTEM{RS}",
|
|
240
|
+
f" {C}env{RS} {DM}<set|get|list|export|push…>{RS} encrypted local .env store & cloud sync",
|
|
241
|
+
f" {C}log{RS} {DM}[--stats]{RS} view operation history & bandwidth summary",
|
|
242
|
+
f" {C}check{RS} {DM}[--seal]{RS} verify source integrity & tamper detection",
|
|
243
|
+
f" {C}version{RS} check CLI and server status & versions",
|
|
244
|
+
"",
|
|
245
|
+
f" {DM}Run {RS}{C}akash <command> --help{RS}{DM} for full options on any command.{RS}",
|
|
241
246
|
"",
|
|
242
247
|
]
|
|
243
248
|
nl = chr(10)
|
|
@@ -2670,8 +2675,10 @@ def env_pull(
|
|
|
2670
2675
|
# AKASH AGENT & DEVICE BINDING COMMANDS
|
|
2671
2676
|
# =============================================================================
|
|
2672
2677
|
|
|
2673
|
-
|
|
2674
|
-
|
|
2678
|
+
mcp_app = typer.Typer(help="Model Context Protocol (MCP) server & AI agent tool bridge.")
|
|
2679
|
+
agent_app = mcp_app
|
|
2680
|
+
app.add_typer(mcp_app, name="mcp", help="MCP server · AI agent tools · Claude/Cursor/Codex bridge")
|
|
2681
|
+
app.add_typer(mcp_app, name="agent", hidden=True, help="Alias for akash mcp")
|
|
2675
2682
|
|
|
2676
2683
|
def _render_inspection_card(r: dict) -> None:
|
|
2677
2684
|
print(f"\n {_C}╭─ ⚡ INCOMING AGENT DEVICE REGISTRATION ────────────────────────────{_RS}")
|
|
@@ -2983,30 +2990,6 @@ def agent_create(
|
|
|
2983
2990
|
print(f" {_G}akash mcp serve --id {profile_id}{_RS}")
|
|
2984
2991
|
_p()
|
|
2985
2992
|
|
|
2986
|
-
@agent_app.command("update")
|
|
2987
|
-
def agent_update(
|
|
2988
|
-
client_id: str = typer.Argument(..., help="Client ID of the agent to update"),
|
|
2989
|
-
scopes: str = typer.Option(..., "--scopes", "-s", help="New scopes or role preset (e.g., @coder, +exec:package_install)"),
|
|
2990
|
-
url: Optional[str] = typer.Option(None, "--url", help="Override server URL"),
|
|
2991
|
-
):
|
|
2992
|
-
"""Update permissions/scopes for an existing AI Agent application."""
|
|
2993
|
-
api_key, base = _resolve_client(url, require_key=False)
|
|
2994
|
-
hdrs = {"Origin": "https://akash.cli", "x-device-id": _device_fingerprint()}
|
|
2995
|
-
if api_key: hdrs["x-api-key"] = api_key
|
|
2996
|
-
|
|
2997
|
-
with _Spin(f"updating permissions for {client_id}…"):
|
|
2998
|
-
res = httpx.patch(
|
|
2999
|
-
f"{base}/api/agent/app/{client_id}",
|
|
3000
|
-
headers=hdrs,
|
|
3001
|
-
json={"scopes": scopes},
|
|
3002
|
-
timeout=10.0
|
|
3003
|
-
)
|
|
3004
|
-
if res.status_code == 200:
|
|
3005
|
-
d = res.json()
|
|
3006
|
-
_ok(f"Agent {_ye(client_id)} permissions updated to: {_cy(d.get('scopes', ''))}")
|
|
3007
|
-
else:
|
|
3008
|
-
_err(f"Failed to update scopes: {res.text}")
|
|
3009
|
-
|
|
3010
2993
|
@agent_app.command("requests")
|
|
3011
2994
|
def agent_requests(url: Optional[str] = typer.Option(None, "--url", help="Override server URL")):
|
|
3012
2995
|
"""List pending device registration requests."""
|
|
@@ -3094,64 +3077,11 @@ def agent_reject(request_id: str, url: Optional[str] = typer.Option(None, "--url
|
|
|
3094
3077
|
else:
|
|
3095
3078
|
_err(f"Rejection failed: {res.text}")
|
|
3096
3079
|
|
|
3097
|
-
@app.command("guard")
|
|
3098
|
-
def guard_console(url: Optional[str] = typer.Option(None, "--url", help="Override server URL")):
|
|
3099
|
-
import time
|
|
3100
|
-
"""Interactive real-time terminal console that listens for agent access requests."""
|
|
3101
|
-
api_key, base = _resolve_client(url, require_key=False)
|
|
3102
|
-
hdrs = {"Origin": "https://akash.cli", "x-device-id": _device_fingerprint()}
|
|
3103
|
-
if api_key: hdrs["x-api-key"] = api_key
|
|
3104
|
-
print(f"\n {_G}◉{_RS} {_W}Akash Guard Console Online{_RS}")
|
|
3105
|
-
print(f" {_DM}Listening for incoming agent device registrations (Ctrl-C to stop)…{_RS}\n")
|
|
3106
|
-
|
|
3107
|
-
handled_requests = set()
|
|
3108
|
-
while True:
|
|
3109
|
-
try:
|
|
3110
|
-
res = httpx.get(
|
|
3111
|
-
f"{base}/api/agent/requests",
|
|
3112
|
-
headers=hdrs,
|
|
3113
|
-
timeout=5.0
|
|
3114
|
-
)
|
|
3115
|
-
if res.status_code == 200:
|
|
3116
|
-
for r in res.json().get("requests", []):
|
|
3117
|
-
rid = r["request_id"]
|
|
3118
|
-
if r["status"] == "pending" and rid not in handled_requests:
|
|
3119
|
-
_render_inspection_card(r)
|
|
3120
|
-
try:
|
|
3121
|
-
sys.stdout.write(f" Approve access for this device? [y/N]: ")
|
|
3122
|
-
sys.stdout.flush()
|
|
3123
|
-
choice = sys.stdin.readline().strip().lower()
|
|
3124
|
-
except (KeyboardInterrupt, EOFError):
|
|
3125
|
-
choice = "n"
|
|
3126
|
-
|
|
3127
|
-
if choice == "y":
|
|
3128
|
-
httpx.post(f"{base}/api/agent/requests/{rid}/approve", headers=hdrs, timeout=5)
|
|
3129
|
-
_ok(f"Approved {rid} - Access token released to agent!\n")
|
|
3130
|
-
else:
|
|
3131
|
-
httpx.post(f"{base}/api/agent/requests/{rid}/reject", headers=hdrs, timeout=5)
|
|
3132
|
-
_warn(f"Rejected {rid}.\n")
|
|
3133
|
-
handled_requests.add(rid)
|
|
3134
|
-
time.sleep(2.0)
|
|
3135
|
-
except KeyboardInterrupt:
|
|
3136
|
-
print(f"\n {_DM}Guard console stopped.{_RS}\n")
|
|
3137
|
-
break
|
|
3138
|
-
except Exception:
|
|
3139
|
-
time.sleep(3.0)
|
|
3140
|
-
|
|
3141
3080
|
|
|
3142
3081
|
# =============================================================================
|
|
3143
|
-
# MODEL CONTEXT PROTOCOL (MCP)
|
|
3082
|
+
# MODEL CONTEXT PROTOCOL (MCP) & AI AGENT ENGINE (MERGED)
|
|
3144
3083
|
# =============================================================================
|
|
3145
3084
|
|
|
3146
|
-
mcp_app = typer.Typer(help="Model Context Protocol (MCP) server for AI agents.")
|
|
3147
|
-
app.add_typer(mcp_app, name="mcp", help="Model Context Protocol (MCP) bridge for AI agents")
|
|
3148
|
-
mcp_app.command("guard", help="Terminal approval console for incoming agent requests")(guard_console)
|
|
3149
|
-
|
|
3150
|
-
@mcp_app.command("list")
|
|
3151
|
-
def mcp_list(raw: bool = typer.Option(False, "--json", help="Raw JSON output")):
|
|
3152
|
-
"""List all available Agent Profile IDs for MCP."""
|
|
3153
|
-
agent_list(raw=raw)
|
|
3154
|
-
|
|
3155
3085
|
_ASYNC_JOBS = {}
|
|
3156
3086
|
_LAST_UNDO_DIR = Path.home() / ".akash" / "undo_vault"
|
|
3157
3087
|
|
|
@@ -3268,7 +3198,7 @@ def _parse_temp_duration(val: str) -> int:
|
|
|
3268
3198
|
elif unit in ('d', 'day', 'days'): return num * 1440
|
|
3269
3199
|
return num
|
|
3270
3200
|
|
|
3271
|
-
@
|
|
3201
|
+
@agent_app.command("serve")
|
|
3272
3202
|
def mcp_serve(
|
|
3273
3203
|
url: Optional[str] = typer.Option(None, "--url", help="Override server URL"),
|
|
3274
3204
|
client_id: Optional[str] = typer.Option(None, "--client-id", help="Agent Client ID"),
|
|
@@ -3449,8 +3379,8 @@ def mcp_serve(
|
|
|
3449
3379
|
print(f" {_GR}{now_t}{_RS} {_Y}⚠{_RS} {_dim(f'Worker disconnected ({e}). Reconnecting in {backoff:.1f}s (attempt {reconnect_attempts})…')}")
|
|
3450
3380
|
time.sleep(backoff)
|
|
3451
3381
|
|
|
3452
|
-
@
|
|
3453
|
-
@
|
|
3382
|
+
@agent_app.command("share")
|
|
3383
|
+
@agent_app.command("url", hidden=True)
|
|
3454
3384
|
def mcp_share(
|
|
3455
3385
|
target: Optional[str] = typer.Argument(None, help="Profile ID (optional if only 1 profile exists)"),
|
|
3456
3386
|
id: Optional[str] = typer.Option(None, "--id", "-i", help="Profile ID"),
|
|
@@ -3642,123 +3572,7 @@ def mcp_share(
|
|
|
3642
3572
|
_p()
|
|
3643
3573
|
|
|
3644
3574
|
|
|
3645
|
-
@
|
|
3646
|
-
def mcp_share(
|
|
3647
|
-
target: Optional[str] = typer.Argument(None, help="Profile ID (optional if only 1 profile exists)"),
|
|
3648
|
-
id: Optional[str] = typer.Option(None, "--id", "-i", help="Profile ID"),
|
|
3649
|
-
temp: Optional[str] = typer.Option(None, "--temp", "-t", help="Temporary short URL duration (e.g. '30m', '30 min', '1h')"),
|
|
3650
|
-
codex: bool = typer.Option(False, "--codex", "-c", help="Show snippet only for Codex CLI/Desktop"),
|
|
3651
|
-
claude: bool = typer.Option(False, "--claude", help="Show snippet only for Claude Desktop / Cursor"),
|
|
3652
|
-
keys: bool = typer.Option(False, "--keys", "-k", help="Show raw Client ID and Secret"),
|
|
3653
|
-
url: Optional[str] = typer.Option(None, "--url", help="Override server URL"),
|
|
3654
|
-
):
|
|
3655
|
-
"""Generate ready-to-copy MCP configuration for Codex, Claude, or Cursor on ANY device."""
|
|
3656
|
-
import json, urllib.parse
|
|
3657
|
-
from pathlib import Path
|
|
3658
|
-
|
|
3659
|
-
agents_file = Path.home() / ".akash" / "agents.json"
|
|
3660
|
-
if not agents_file.exists():
|
|
3661
|
-
_err("No saved agent profiles found. Create one with: akash agent create")
|
|
3662
|
-
raise typer.Exit(1)
|
|
3663
|
-
|
|
3664
|
-
try:
|
|
3665
|
-
agents = json.loads(agents_file.read_text(encoding="utf-8"))
|
|
3666
|
-
except Exception: agents = {}
|
|
3667
|
-
|
|
3668
|
-
target_id = id or target
|
|
3669
|
-
if not target_id:
|
|
3670
|
-
if len(agents) == 1:
|
|
3671
|
-
target_id = next(iter(agents.keys()))
|
|
3672
|
-
elif "af4f" in agents:
|
|
3673
|
-
target_id = "af4f"
|
|
3674
|
-
else:
|
|
3675
|
-
_err("Multiple profiles found. Specify which one: akash mcp share <ID>")
|
|
3676
|
-
raise typer.Exit(1)
|
|
3677
|
-
|
|
3678
|
-
pid, cid, name = _resolve_agent_id(target_id)
|
|
3679
|
-
profile = agents.get(pid, {})
|
|
3680
|
-
csec = profile.get("client_secret", "")
|
|
3681
|
-
|
|
3682
|
-
if not csec:
|
|
3683
|
-
_err(f"No client_secret found for profile {pid}.")
|
|
3684
|
-
raise typer.Exit(1)
|
|
3685
|
-
|
|
3686
|
-
_, base = _resolve_client(url or profile.get("url"), require_key=False, silent=True)
|
|
3687
|
-
dev_fp = _device_fingerprint()
|
|
3688
|
-
|
|
3689
|
-
lan_ip = _get_lan_ip()
|
|
3690
|
-
port = base.split(":")[-1] if ":" in base.replace("http://", "").replace("https://", "") else "8000"
|
|
3691
|
-
wifi_base = f"http://{lan_ip}:{port}"
|
|
3692
|
-
|
|
3693
|
-
if temp:
|
|
3694
|
-
try:
|
|
3695
|
-
ttl_min = _parse_temp_duration(temp)
|
|
3696
|
-
except ValueError as ve:
|
|
3697
|
-
_err(str(ve))
|
|
3698
|
-
raise typer.Exit(1)
|
|
3699
|
-
|
|
3700
|
-
with _Spin(f"generating {ttl_min}m short link…"):
|
|
3701
|
-
try:
|
|
3702
|
-
res = httpx.post(
|
|
3703
|
-
f"{base}/api/agent/mcp/ticket",
|
|
3704
|
-
json={"client_id": cid, "client_secret": csec, "device_fp": dev_fp, "ttl_minutes": ttl_min},
|
|
3705
|
-
timeout=10.0
|
|
3706
|
-
)
|
|
3707
|
-
res.raise_for_status()
|
|
3708
|
-
d = res.json()
|
|
3709
|
-
tcode = d["ticket_code"]
|
|
3710
|
-
local_url = f"{base}/mcp/t/{tcode}"
|
|
3711
|
-
wifi_url = f"{wifi_base}/mcp/t/{tcode}"
|
|
3712
|
-
mode_label = f"Temporary ({ttl_min} mins · Ephemeral)"
|
|
3713
|
-
except Exception as e:
|
|
3714
|
-
_err(f"Failed to issue temporary ticket: {e}")
|
|
3715
|
-
raise typer.Exit(1)
|
|
3716
|
-
else:
|
|
3717
|
-
params = urllib.parse.urlencode({"cid": cid, "csec": csec, "dfp": dev_fp})
|
|
3718
|
-
local_url = f"{base}/mcp?{params}"
|
|
3719
|
-
wifi_url = f"{wifi_base}/mcp?{params}"
|
|
3720
|
-
mode_label = "Permanent Small & Secure"
|
|
3721
|
-
|
|
3722
|
-
_p()
|
|
3723
|
-
print(" " + _C + "◈" + _RS + " " + _W + "Akash MCP · Quick Connect" + _RS)
|
|
3724
|
-
print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
|
|
3725
|
-
print(" " + _DM + "Agent : " + _RS + _ye(name) + " " + _dim("(" + pid + ")"))
|
|
3726
|
-
print(" " + _DM + "Mode : " + _RS + _C + mode_label + _RS)
|
|
3727
|
-
if keys:
|
|
3728
|
-
print(" " + _DM + "Client ID: " + _RS + _dim(cid))
|
|
3729
|
-
print(" " + _DM + "Secret : " + _RS + _dim(csec))
|
|
3730
|
-
print(" " + _DM + "Device FP: " + _RS + _dim(dev_fp))
|
|
3731
|
-
print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
|
|
3732
|
-
_p()
|
|
3733
|
-
|
|
3734
|
-
show_all = not codex and not claude
|
|
3735
|
-
|
|
3736
|
-
if show_all or codex:
|
|
3737
|
-
print(" " + _C + "For Codex CLI / Desktop" + _RS + " " + _dim("(~/.codex/config.toml)") + ":")
|
|
3738
|
-
print(" " + _DM + "Option A: Same Device (Termux / Localhost)" + _RS)
|
|
3739
|
-
print(" [mcp_servers.akash]")
|
|
3740
|
-
print(' url = "' + local_url + '"')
|
|
3741
|
-
if lan_ip != "127.0.0.1":
|
|
3742
|
-
print()
|
|
3743
|
-
print(" " + _DM + "Option B: Other Device (Over Wi-Fi)" + _RS)
|
|
3744
|
-
print(" [mcp_servers.akash]")
|
|
3745
|
-
print(' url = "' + wifi_url + '"')
|
|
3746
|
-
print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
|
|
3747
|
-
_p()
|
|
3748
|
-
|
|
3749
|
-
if show_all or claude:
|
|
3750
|
-
print(" " + _C + "For Claude Desktop / Cursor" + _RS + " " + _dim("(config.json)") + ":")
|
|
3751
|
-
claude_cfg = json.dumps({"mcpServers": {"akash": {"url": local_url}}}, indent=2)
|
|
3752
|
-
for c_line in claude_cfg.splitlines():
|
|
3753
|
-
print(" " + c_line)
|
|
3754
|
-
print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
|
|
3755
|
-
_p()
|
|
3756
|
-
|
|
3757
|
-
_info("Paste snippet into AI client, then keep running:")
|
|
3758
|
-
_info(f" {_cy('akash mcp serve')}")
|
|
3759
|
-
_p()
|
|
3760
|
-
|
|
3761
|
-
@mcp_app.command("status")
|
|
3575
|
+
@agent_app.command("status")
|
|
3762
3576
|
def mcp_status(
|
|
3763
3577
|
url: Optional[str] = typer.Option(None, "--url", help="Override server URL")
|
|
3764
3578
|
):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|