Added __mcpctl_needs_server_arg guard in fish and position check in bash so completions stop after one server name is selected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
167 lines
5.4 KiB
Bash
167 lines
5.4 KiB
Bash
_mcpctl() {
|
|
local cur prev words cword
|
|
_init_completion || return
|
|
|
|
local commands="status login logout config get describe delete logs create edit apply backup restore help"
|
|
local project_commands="attach-server detach-server get describe delete logs create edit help"
|
|
local global_opts="-v --version --daemon-url --direct --project -h --help"
|
|
local resources="servers instances secrets templates projects users groups rbac"
|
|
|
|
# Check if --project was given
|
|
local has_project=false
|
|
local i
|
|
for ((i=1; i < cword; i++)); do
|
|
if [[ "${words[i]}" == "--project" ]]; then
|
|
has_project=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Find the first subcommand (skip --project and its argument, skip flags)
|
|
local subcmd=""
|
|
local subcmd_pos=0
|
|
for ((i=1; i < cword; i++)); do
|
|
if [[ "${words[i]}" == "--project" || "${words[i]}" == "--daemon-url" ]]; then
|
|
((i++)) # skip the argument
|
|
continue
|
|
fi
|
|
if [[ "${words[i]}" != -* ]]; then
|
|
subcmd="${words[i]}"
|
|
subcmd_pos=$i
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Find the resource type after get/describe/delete/edit
|
|
local resource_type=""
|
|
if [[ -n "$subcmd_pos" ]] && [[ $subcmd_pos -gt 0 ]]; then
|
|
for ((i=subcmd_pos+1; i < cword; i++)); do
|
|
if [[ "${words[i]}" != -* ]] && [[ " $resources " == *" ${words[i]} "* ]]; then
|
|
resource_type="${words[i]}"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# If completing the --project value
|
|
if [[ "$prev" == "--project" ]]; then
|
|
local names
|
|
names=$(mcpctl get projects -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null)
|
|
COMPREPLY=($(compgen -W "$names" -- "$cur"))
|
|
return
|
|
fi
|
|
|
|
# Fetch resource names dynamically (jq extracts only top-level names)
|
|
_mcpctl_resource_names() {
|
|
local rt="$1"
|
|
if [[ -n "$rt" ]]; then
|
|
# Instances don't have a name field — use server.name instead
|
|
if [[ "$rt" == "instances" ]]; then
|
|
mcpctl get instances -o json 2>/dev/null | jq -r '.[][].server.name' 2>/dev/null
|
|
else
|
|
mcpctl get "$rt" -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Get the --project value from the command line
|
|
_mcpctl_get_project_value() {
|
|
local i
|
|
for ((i=1; i < cword; i++)); do
|
|
if [[ "${words[i]}" == "--project" ]] && (( i+1 < cword )); then
|
|
echo "${words[i+1]}"
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
case "$subcmd" in
|
|
config)
|
|
if [[ $((cword - subcmd_pos)) -eq 1 ]]; then
|
|
COMPREPLY=($(compgen -W "view set path reset claude-generate impersonate help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
status)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
return ;;
|
|
login)
|
|
COMPREPLY=($(compgen -W "--url --email --password -h --help" -- "$cur"))
|
|
return ;;
|
|
logout)
|
|
return ;;
|
|
get|describe|delete)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "$resources" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -o --output -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
edit)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "servers projects" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
logs)
|
|
COMPREPLY=($(compgen -W "--tail --since -f --follow -h --help" -- "$cur"))
|
|
return ;;
|
|
create)
|
|
if [[ $((cword - subcmd_pos)) -eq 1 ]]; then
|
|
COMPREPLY=($(compgen -W "server secret project user group rbac help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
apply)
|
|
COMPREPLY=($(compgen -f -- "$cur"))
|
|
return ;;
|
|
backup)
|
|
COMPREPLY=($(compgen -W "-o --output -p --password -h --help" -- "$cur"))
|
|
return ;;
|
|
restore)
|
|
COMPREPLY=($(compgen -W "-i --input -p --password -c --conflict -h --help" -- "$cur"))
|
|
return ;;
|
|
attach-server)
|
|
# Only complete if no server arg given yet (first arg after subcmd)
|
|
if [[ $((cword - subcmd_pos)) -ne 1 ]]; then return; fi
|
|
local proj names all_servers proj_servers
|
|
proj=$(_mcpctl_get_project_value)
|
|
if [[ -n "$proj" ]]; then
|
|
all_servers=$(mcpctl get servers -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null)
|
|
proj_servers=$(mcpctl --project "$proj" get servers -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null)
|
|
names=$(comm -23 <(echo "$all_servers" | sort) <(echo "$proj_servers" | sort))
|
|
else
|
|
names=$(_mcpctl_resource_names "servers")
|
|
fi
|
|
COMPREPLY=($(compgen -W "$names" -- "$cur"))
|
|
return ;;
|
|
detach-server)
|
|
# Only complete if no server arg given yet (first arg after subcmd)
|
|
if [[ $((cword - subcmd_pos)) -ne 1 ]]; then return; fi
|
|
local proj names
|
|
proj=$(_mcpctl_get_project_value)
|
|
if [[ -n "$proj" ]]; then
|
|
names=$(mcpctl --project "$proj" get servers -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null)
|
|
fi
|
|
COMPREPLY=($(compgen -W "$names" -- "$cur"))
|
|
return ;;
|
|
help)
|
|
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
|
|
return ;;
|
|
esac
|
|
|
|
# No subcommand yet — offer commands based on context
|
|
if [[ -z "$subcmd" ]]; then
|
|
if $has_project; then
|
|
COMPREPLY=($(compgen -W "$project_commands $global_opts" -- "$cur"))
|
|
else
|
|
COMPREPLY=($(compgen -W "$commands $global_opts" -- "$cur"))
|
|
fi
|
|
fi
|
|
}
|
|
|
|
complete -F _mcpctl mcpctl
|