Closes the loop on user-facing surface: $ mcpctl get llm NAME KIND STATUS TYPE MODEL TIER KEY ID qwen3-thinking public active openai qwen3-thinking fast ... ... vllm-local virtual active openai Qwen/Qwen2.5-7B-Instruct fast - ... $ mcpctl chat-llm vllm-local ──────────────────────────────────────── LLM: vllm-local openai → Qwen/Qwen2.5-7B-Instruct-AWQ Kind: virtual Status: active ──────────────────────────────────────── > hello? Hi! … New: chat-llm command (commands/chat-llm.ts) - Stateless chat with any mcpd-registered LLM. No threads, no tools, no project prompts. POSTs to /api/v1/llms/<name>/infer; mcpd's kind=virtual branch handles relay-through-mcplocal transparently, so the same CLI command works for both public and virtual LLMs. - Reuses installStatusBar / formatStats / recordDelta / styleStats / PhaseStats from chat.ts (now exported) so the bottom-row tokens-per- second ticker behaves identically to mcpctl chat. - Flags: --message (one-shot), --system, --temperature, --max-tokens, --no-stream. Streaming uses OpenAI chat.completion.chunk SSE. - REPL mode keeps a per-session history array so multi-turn flows feel natural; each turn is an independent inference call. Updated: get.ts - LlmRow gains optional kind/status fields. - llmColumns layout: NAME, KIND, STATUS, TYPE, MODEL, TIER, KEY, ID. Defaults gracefully when older mcpd responses don't return them. Updated: chat.ts - Re-exports the helpers chat-llm.ts needs (PhaseStats, newPhase, recordDelta, formatStats, styleStats, styleThinking, STDERR_IS_TTY, StatusBar, installStatusBar). No behavior change. Completions: chat-llm picks up the standard option enumeration automatically; bash gets a special-case for first-arg LLM-name completion via _mcpctl_resource_names "llms". CLI suite: 437/437 (was 430, +7 from auto-discovered test cases in the regenerated completions golden). Workspace: 2043/2043 across 152 files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
408 lines
15 KiB
Bash
408 lines
15 KiB
Bash
# mcpctl bash completions — auto-generated by scripts/generate-completions.ts
|
|
# DO NOT EDIT MANUALLY — run: pnpm completions:generate
|
|
|
|
_mcpctl() {
|
|
local cur prev words cword
|
|
_init_completion || return
|
|
|
|
local commands="status login logout config get describe delete logs create edit apply chat chat-llm patch backup approve console cache test migrate rotate"
|
|
local project_commands="get describe delete logs create edit attach-server detach-server"
|
|
local global_opts="-v --version --daemon-url --direct -p --project -h --help"
|
|
local resources="servers instances secrets secretbackends llms agents personalities templates projects users groups rbac prompts promptrequests serverattachments proxymodels all"
|
|
local resource_aliases="servers instances secrets secretbackends llms agents personalities templates projects users groups rbac prompts promptrequests serverattachments proxymodels all server srv instance inst secret sec secretbackend sb llm agent personality template tpl project proj user group rbac-definition rbac-binding prompt promptrequest pr serverattachment sa proxymodel pm"
|
|
|
|
# Check if --project/-p was given
|
|
local has_project=false
|
|
local i
|
|
for ((i=1; i < cword; i++)); do
|
|
if [[ "${words[i]}" == "--project" || "${words[i]}" == "-p" ]]; then
|
|
has_project=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Find the first subcommand
|
|
local subcmd=""
|
|
local subcmd_pos=0
|
|
for ((i=1; i < cword; i++)); do
|
|
if [[ "${words[i]}" == "--project" || "${words[i]}" == "--daemon-url" || "${words[i]}" == "-p" ]]; then
|
|
((i++))
|
|
continue
|
|
fi
|
|
if [[ "${words[i]}" != -* ]]; then
|
|
subcmd="${words[i]}"
|
|
subcmd_pos=$i
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Find the resource type after resource commands
|
|
local resource_type=""
|
|
if [[ -n "$subcmd_pos" ]] && [[ $subcmd_pos -gt 0 ]]; then
|
|
for ((i=subcmd_pos+1; i < cword; i++)); do
|
|
if [[ "${words[i]}" != -* ]] && [[ " $resource_aliases " == *" ${words[i]} "* ]]; then
|
|
resource_type="${words[i]}"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Helper: get --project/-p value
|
|
_mcpctl_get_project_value() {
|
|
local i
|
|
for ((i=1; i < cword; i++)); do
|
|
if [[ "${words[i]}" == "--project" || "${words[i]}" == "-p" ]] && (( i+1 < cword )); then
|
|
echo "${words[i+1]}"
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Helper: fetch resource names
|
|
_mcpctl_resource_names() {
|
|
local rt="$1"
|
|
if [[ -n "$rt" ]]; then
|
|
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
|
|
}
|
|
|
|
# Helper: find sub-subcommand (for config/create)
|
|
_mcpctl_get_subcmd() {
|
|
local parent_pos="$1"
|
|
local i
|
|
for ((i=parent_pos+1; i < cword; i++)); do
|
|
if [[ "${words[i]}" != -* ]]; then
|
|
echo "${words[i]}"
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
# If completing option values
|
|
if [[ "$prev" == "--project" || "$prev" == "-p" ]]; 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
|
|
|
|
case "$subcmd" in
|
|
status)
|
|
COMPREPLY=($(compgen -W "-o --output -h --help" -- "$cur"))
|
|
return ;;
|
|
login)
|
|
COMPREPLY=($(compgen -W "--mcpd-url -h --help" -- "$cur"))
|
|
return ;;
|
|
logout)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
return ;;
|
|
config)
|
|
local config_sub=$(_mcpctl_get_subcmd $subcmd_pos)
|
|
if [[ -z "$config_sub" ]]; then
|
|
COMPREPLY=($(compgen -W "view set path reset claude claude-generate setup impersonate help" -- "$cur"))
|
|
else
|
|
case "$config_sub" in
|
|
view)
|
|
COMPREPLY=($(compgen -W "-o --output -h --help" -- "$cur"))
|
|
;;
|
|
set)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
path)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
reset)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
claude)
|
|
COMPREPLY=($(compgen -W "-p --project -o --output --inspect --stdout -h --help" -- "$cur"))
|
|
;;
|
|
claude-generate)
|
|
COMPREPLY=($(compgen -W "-p --project -o --output --inspect --stdout -h --help" -- "$cur"))
|
|
;;
|
|
setup)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
impersonate)
|
|
COMPREPLY=($(compgen -W "--quit -h --help" -- "$cur"))
|
|
;;
|
|
*)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
esac
|
|
fi
|
|
return ;;
|
|
get)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "$resources -o --output -p --project -A --all -h --help" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -o --output -p --project -A --all -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
describe)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "$resources -o --output --show-values -h --help" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -o --output --show-values -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
delete)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "$resources -p --project --agent -h --help" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -p --project --agent -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
logs)
|
|
if [[ $((cword - subcmd_pos)) -eq 1 ]]; then
|
|
local names
|
|
names=$(mcpctl get instances -o json 2>/dev/null | jq -r '.[][].server.name' 2>/dev/null)
|
|
COMPREPLY=($(compgen -W "$names -t --tail -i --instance -h --help" -- "$cur"))
|
|
else
|
|
COMPREPLY=($(compgen -W "-t --tail -i --instance -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
create)
|
|
local create_sub=$(_mcpctl_get_subcmd $subcmd_pos)
|
|
if [[ -z "$create_sub" ]]; then
|
|
COMPREPLY=($(compgen -W "server secret llm agent secretbackend project user group rbac mcptoken prompt personality serverattachment promptrequest help" -- "$cur"))
|
|
else
|
|
case "$create_sub" in
|
|
server)
|
|
COMPREPLY=($(compgen -W "-d --description --package-name --runtime --docker-image --transport --repository-url --external-url --command --container-port --replicas --env --from-template --env-from-secret --force -h --help" -- "$cur"))
|
|
;;
|
|
secret)
|
|
COMPREPLY=($(compgen -W "--data --force -h --help" -- "$cur"))
|
|
;;
|
|
llm)
|
|
COMPREPLY=($(compgen -W "--type --model --url --tier --description --api-key-ref --extra --force --skip-auth-check -h --help" -- "$cur"))
|
|
;;
|
|
agent)
|
|
COMPREPLY=($(compgen -W "--llm --project --description --system-prompt --system-prompt-file --proxy-model --default-temperature --default-top-p --default-top-k --default-max-tokens --default-seed --default-stop --default-extra --default-params-file --force -h --help" -- "$cur"))
|
|
;;
|
|
secretbackend)
|
|
COMPREPLY=($(compgen -W "--type --description --default --url --namespace --mount --path-prefix --auth --token-secret --role --auth-mount --sa-token-path --config --wizard --setup-token --policy-name --token-role --no-promote-default --force -h --help" -- "$cur"))
|
|
;;
|
|
project)
|
|
COMPREPLY=($(compgen -W "-d --description --proxy-model --prompt --llm --llm-model --gated --no-gated --server --force -h --help" -- "$cur"))
|
|
;;
|
|
user)
|
|
COMPREPLY=($(compgen -W "--password --name --force -h --help" -- "$cur"))
|
|
;;
|
|
group)
|
|
COMPREPLY=($(compgen -W "--description --member --force -h --help" -- "$cur"))
|
|
;;
|
|
rbac)
|
|
COMPREPLY=($(compgen -W "--subject --roleBindings --force -h --help" -- "$cur"))
|
|
;;
|
|
mcptoken)
|
|
COMPREPLY=($(compgen -W "-p --project --rbac --bind --ttl --description --force -h --help" -- "$cur"))
|
|
;;
|
|
prompt)
|
|
COMPREPLY=($(compgen -W "-p --project --agent --content --content-file --priority --link -h --help" -- "$cur"))
|
|
;;
|
|
personality)
|
|
COMPREPLY=($(compgen -W "--agent --description --priority -h --help" -- "$cur"))
|
|
;;
|
|
serverattachment)
|
|
COMPREPLY=($(compgen -W "-p --project -h --help" -- "$cur"))
|
|
;;
|
|
promptrequest)
|
|
COMPREPLY=($(compgen -W "-p --project --content --content-file --priority -h --help" -- "$cur"))
|
|
;;
|
|
*)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
esac
|
|
fi
|
|
return ;;
|
|
edit)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "servers secrets projects groups rbac prompts promptrequests personalities -h --help" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
apply)
|
|
COMPREPLY=($(compgen -f -W "-f --file --dry-run -h --help" -- "$cur"))
|
|
return ;;
|
|
chat)
|
|
if [[ $((cword - subcmd_pos)) -eq 1 ]]; then
|
|
local names
|
|
names=$(_mcpctl_resource_names "agents")
|
|
COMPREPLY=($(compgen -W "$names -m --message --thread --system --system-file --system-append --personality --temperature --top-p --top-k --max-tokens --seed --stop --allow-tool --extra --no-stream -h --help" -- "$cur"))
|
|
else
|
|
COMPREPLY=($(compgen -W "-m --message --thread --system --system-file --system-append --personality --temperature --top-p --top-k --max-tokens --seed --stop --allow-tool --extra --no-stream -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
chat-llm)
|
|
if [[ $((cword - subcmd_pos)) -eq 1 ]]; then
|
|
local names
|
|
names=$(_mcpctl_resource_names "llms")
|
|
COMPREPLY=($(compgen -W "$names -m --message --system --temperature --max-tokens --no-stream -h --help" -- "$cur"))
|
|
else
|
|
COMPREPLY=($(compgen -W "-m --message --system --temperature --max-tokens --no-stream -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
patch)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "$resources -h --help" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
backup)
|
|
local backup_sub=$(_mcpctl_get_subcmd $subcmd_pos)
|
|
if [[ -z "$backup_sub" ]]; then
|
|
COMPREPLY=($(compgen -W "log restore help" -- "$cur"))
|
|
else
|
|
case "$backup_sub" in
|
|
log)
|
|
COMPREPLY=($(compgen -W "-n --limit -h --help" -- "$cur"))
|
|
;;
|
|
restore)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
*)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
esac
|
|
fi
|
|
return ;;
|
|
attach-server)
|
|
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)
|
|
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 ;;
|
|
approve)
|
|
if [[ -z "$resource_type" ]]; then
|
|
COMPREPLY=($(compgen -W "promptrequest -h --help" -- "$cur"))
|
|
else
|
|
local names
|
|
names=$(_mcpctl_resource_names "$resource_type")
|
|
COMPREPLY=($(compgen -W "$names -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
mcp)
|
|
COMPREPLY=($(compgen -W "-p --project -h --help" -- "$cur"))
|
|
return ;;
|
|
console)
|
|
if [[ $((cword - subcmd_pos)) -eq 1 ]]; then
|
|
local names
|
|
names=$(mcpctl get projects -o json 2>/dev/null | jq -r '.[].name' 2>/dev/null)
|
|
COMPREPLY=($(compgen -W "$names --stdin-mcp --audit -h --help" -- "$cur"))
|
|
else
|
|
COMPREPLY=($(compgen -W "--stdin-mcp --audit -h --help" -- "$cur"))
|
|
fi
|
|
return ;;
|
|
cache)
|
|
local cache_sub=$(_mcpctl_get_subcmd $subcmd_pos)
|
|
if [[ -z "$cache_sub" ]]; then
|
|
COMPREPLY=($(compgen -W "stats clear help" -- "$cur"))
|
|
else
|
|
case "$cache_sub" in
|
|
stats)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
clear)
|
|
COMPREPLY=($(compgen -W "--older-than -y --yes -h --help" -- "$cur"))
|
|
;;
|
|
*)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
esac
|
|
fi
|
|
return ;;
|
|
test)
|
|
local test_sub=$(_mcpctl_get_subcmd $subcmd_pos)
|
|
if [[ -z "$test_sub" ]]; then
|
|
COMPREPLY=($(compgen -W "mcp help" -- "$cur"))
|
|
else
|
|
case "$test_sub" in
|
|
mcp)
|
|
COMPREPLY=($(compgen -W "--token --tool --args --expect-tools --timeout -o --output --no-health -h --help" -- "$cur"))
|
|
;;
|
|
*)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
esac
|
|
fi
|
|
return ;;
|
|
migrate)
|
|
local migrate_sub=$(_mcpctl_get_subcmd $subcmd_pos)
|
|
if [[ -z "$migrate_sub" ]]; then
|
|
COMPREPLY=($(compgen -W "secrets help" -- "$cur"))
|
|
else
|
|
case "$migrate_sub" in
|
|
secrets)
|
|
COMPREPLY=($(compgen -W "--from --to --names --keep-source --dry-run -h --help" -- "$cur"))
|
|
;;
|
|
*)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
esac
|
|
fi
|
|
return ;;
|
|
rotate)
|
|
local rotate_sub=$(_mcpctl_get_subcmd $subcmd_pos)
|
|
if [[ -z "$rotate_sub" ]]; then
|
|
COMPREPLY=($(compgen -W "secretbackend help" -- "$cur"))
|
|
else
|
|
case "$rotate_sub" in
|
|
secretbackend)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
*)
|
|
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
|
|
;;
|
|
esac
|
|
fi
|
|
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
|