Created
February 7, 2026 18:47
-
-
Save R44VC0RP/fa297e8db729ddf0699aec43c40d6e68 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # solo-mcp: Stateless CLI for Solo process manager via MCP protocol | |
| # Usage: | |
| # solo-mcp list-projects | |
| # solo-mcp list [project_id] | |
| # solo-mcp status <project_id> <process_name> | |
| # solo-mcp restart <project_id> <process_name> | |
| # solo-mcp start <project_id> <process_name> | |
| # solo-mcp stop <project_id> <process_name> | |
| # solo-mcp restart-all <project_id> | |
| # solo-mcp start-all <project_id> | |
| # solo-mcp stop-all <project_id> | |
| # solo-mcp output <project_id> <process_name> [lines] | |
| # solo-mcp ports <project_id> <process_name> | |
| # solo-mcp stats <project_id> | |
| set -euo pipefail | |
| SOLO_MCP_PORT="${SOLO_MCP_PORT:-45678}" | |
| SOLO_MCP_URL="http://localhost:${SOLO_MCP_PORT}/" | |
| # --- helpers --- | |
| mcp_call() { | |
| local id="$1" method="$2" params="$3" | |
| curl -sf -X POST "$SOLO_MCP_URL" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"jsonrpc\":\"2.0\",\"id\":${id},\"method\":\"${method}\",\"params\":${params}}" \ | |
| 2>/dev/null | sed 's/^data: //' | |
| } | |
| mcp_tool() { | |
| local tool_name="$1" args="$2" | |
| mcp_call 1 "tools/call" "{\"name\":\"${tool_name}:${SUFFIX}\",\"arguments\":${args}}" | |
| } | |
| get_suffix() { | |
| local tools_resp | |
| tools_resp=$(mcp_call 1 "tools/list" "{}") | |
| SUFFIX=$(echo "$tools_resp" | python3 -c " | |
| import sys, json | |
| data = json.loads(sys.stdin.read()) | |
| tools = data.get('result', {}).get('tools', []) | |
| for t in tools: | |
| if ':' in t['name']: | |
| print(t['name'].split(':')[-1]) | |
| break | |
| " 2>/dev/null) | |
| if [ -z "$SUFFIX" ]; then | |
| echo "Error: Could not connect to Solo MCP server on port ${SOLO_MCP_PORT}" >&2 | |
| exit 1 | |
| fi | |
| } | |
| select_project() { | |
| local project_id="$1" | |
| local resp | |
| resp=$(mcp_tool "select_project" "{\"project_id\":${project_id}}") | |
| local is_error | |
| is_error=$(echo "$resp" | python3 -c "import sys,json; print(json.loads(sys.stdin.read()).get('result',{}).get('isError',False))" 2>/dev/null) | |
| if [ "$is_error" = "True" ]; then | |
| echo "$resp" | python3 -c "import sys,json; r=json.loads(sys.stdin.read()); [print(c['text']) for c in r['result']['content']]" 2>/dev/null | |
| exit 1 | |
| fi | |
| } | |
| extract_text() { | |
| python3 -c " | |
| import sys, json | |
| data = json.loads(sys.stdin.read()) | |
| result = data.get('result', {}) | |
| if result.get('isError'): | |
| for c in result.get('content', []): | |
| print('Error:', c.get('text', '')) | |
| sys.exit(1) | |
| for c in result.get('content', []): | |
| print(c.get('text', '')) | |
| " 2>/dev/null | |
| } | |
| # --- commands --- | |
| cmd_list_projects() { | |
| get_suffix | |
| mcp_tool "list_projects" "{}" | extract_text | |
| } | |
| cmd_list() { | |
| local project_id="${1:-}" | |
| get_suffix | |
| if [ -n "$project_id" ]; then | |
| select_project "$project_id" | |
| mcp_tool "list_processes" "{}" | extract_text | |
| else | |
| mcp_tool "list_projects" "{}" | extract_text | |
| fi | |
| } | |
| cmd_status() { | |
| local project_id="$1" process_name="$2" | |
| get_suffix | |
| select_project "$project_id" | |
| mcp_tool "get_process_status" "{\"process_name\":\"${process_name}\"}" | extract_text | |
| } | |
| cmd_process_action() { | |
| local action="$1" project_id="$2" process_name="$3" | |
| get_suffix | |
| select_project "$project_id" | |
| mcp_tool "${action}_process" "{\"process_name\":\"${process_name}\"}" | extract_text | |
| } | |
| cmd_project_action() { | |
| local action="$1" project_id="$2" | |
| get_suffix | |
| select_project "$project_id" | |
| mcp_tool "${action}_all_processes" "{}" | extract_text | |
| } | |
| cmd_output() { | |
| local project_id="$1" process_name="$2" lines="${3:-50}" | |
| get_suffix | |
| select_project "$project_id" | |
| mcp_tool "get_process_output" "{\"process_name\":\"${process_name}\",\"lines\":${lines}}" | extract_text | |
| } | |
| cmd_ports() { | |
| local project_id="$1" process_name="$2" | |
| get_suffix | |
| select_project "$project_id" | |
| mcp_tool "get_process_ports" "{\"process_name\":\"${process_name}\"}" | extract_text | |
| } | |
| cmd_stats() { | |
| local project_id="$1" | |
| get_suffix | |
| select_project "$project_id" | |
| mcp_tool "get_project_stats" "{}" | extract_text | |
| } | |
| cmd_project_status() { | |
| local project_id="$1" | |
| get_suffix | |
| select_project "$project_id" | |
| mcp_tool "get_project_status" "{}" | extract_text | |
| } | |
| # --- main --- | |
| usage() { | |
| cat <<'EOF' | |
| solo-mcp: Stateless CLI for Solo process manager | |
| Usage: | |
| solo-mcp list-projects List all projects | |
| solo-mcp list [project_id] List processes (optionally for a project) | |
| solo-mcp project-status <project_id> Get project status summary | |
| solo-mcp status <project_id> <process_name> Get process status | |
| solo-mcp restart <project_id> <process_name> Restart a process | |
| solo-mcp start <project_id> <process_name> Start a process | |
| solo-mcp stop <project_id> <process_name> Stop a process | |
| solo-mcp restart-all <project_id> Restart all processes | |
| solo-mcp start-all <project_id> Start all processes | |
| solo-mcp stop-all <project_id> Stop all processes | |
| solo-mcp output <project_id> <name> [lines] Get process output | |
| solo-mcp ports <project_id> <process_name> Get process ports | |
| solo-mcp stats <project_id> Get project resource stats | |
| Environment: | |
| SOLO_MCP_PORT MCP server port (default: 45678) | |
| EOF | |
| } | |
| case "${1:-help}" in | |
| list-projects) cmd_list_projects ;; | |
| list) cmd_list "${2:-}" ;; | |
| project-status) cmd_project_status "$2" ;; | |
| status) cmd_status "$2" "$3" ;; | |
| restart) cmd_process_action "restart" "$2" "$3" ;; | |
| start) cmd_process_action "start" "$2" "$3" ;; | |
| stop) cmd_process_action "stop" "$2" "$3" ;; | |
| restart-all) cmd_project_action "restart" "$2" ;; | |
| start-all) cmd_project_action "start" "$2" ;; | |
| stop-all) cmd_project_action "stop" "$2" ;; | |
| output) cmd_output "$2" "$3" "${4:-50}" ;; | |
| ports) cmd_ports "$2" "$3" ;; | |
| stats) cmd_stats "$2" ;; | |
| help|--help|-h) usage ;; | |
| *) echo "Unknown command: $1" >&2; usage >&2; exit 1 ;; | |
| esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment