Files
mcpctl/completions/mcpctl.bash
Michal 859150770f
Some checks failed
CI/CD / typecheck (pull_request) Successful in 1m16s
CI/CD / lint (pull_request) Successful in 2m16s
CI/CD / test (pull_request) Successful in 1m24s
CI/CD / build (pull_request) Successful in 2m10s
CI/CD / smoke (pull_request) Failing after 3m15s
CI/CD / publish (pull_request) Has been skipped
feat(servers): per-server memory ceiling, because 512Mi OOMKills silently
Server pods have always had a hardcoded 512Mi limit. That is right for a
server that proxies an API and fatal for one that drives a browser: the
`docs` server (docs-mcp-server, which scrapes with headless Chromium)
idles at ~228Mi and crosses 512Mi within seconds of its first scrape.

An OOMKill is the quietest failure we have. The kernel kills it, the pod
restarts, the readiness probe passes, and the instance reads `healthy`
again — while the six scrape jobs whose queue lived in memory are gone
and the index has 17 pages in it. Nothing is logged, because the process
never got to say anything.

memoryLimitMb is declared per server, in MiB, and converted to bytes in
the container spec. NULL keeps DEFAULT_MEMORY_LIMIT, so every existing
server is bit-for-bit unchanged — a bigger default would have cost real
memory on every node for servers that do not need it.

  mcpctl create server docs --memory-limit-mb 2048 --force

Tests assert the two places a new column dies quietly: the repository's
field-by-field mapping (a column not mapped there returns "patched" and
changes nothing) and the spec built in instance.service. docs/reliability
gains the OOMKill section — the `lastState.terminated.reason` check is
what turns "it restarted again" into an answer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JPjtnE6Gd343oRNtMU9Bcd
2026-09-17 00:24:18 +01:00

525 lines
20 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 statusline login logout config get describe delete logs create edit apply chat chat-llm patch passwd errors trace backup approve review skills console cache provider test migrate rotate"
local project_commands="get describe delete logs create edit trace attach-server detach-server favourites"
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 inference-tasks all"
local resource_aliases="servers instances secrets secretbackends llms agents personalities templates projects users groups rbac prompts promptrequests serverattachments proxymodels inference-tasks 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 task tasks inference-task"
# 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 ;;
statusline)
COMPREPLY=($(compgen -W "-d --directory --prefix -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 pi prime-agent prime-agent-generate opencode 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 --scope -o --output --inspect --stdout --skip-skills --skip-marker --skip-ui --claude-dir --dry-run -h --help" -- "$cur"))
;;
claude-generate)
COMPREPLY=($(compgen -W "-p --project --scope -o --output --inspect --stdout --skip-skills --skip-marker --skip-ui --claude-dir --dry-run -h --help" -- "$cur"))
;;
pi)
COMPREPLY=($(compgen -W "-p --project --extension-dir --skip-skills --settings --pi-dir --dry-run -h --help" -- "$cur"))
;;
prime-agent)
COMPREPLY=($(compgen -W "-p --project -o --output --gateway-url --token --skip-skills --skip-extension --skip-marker --dry-run -h --help" -- "$cur"))
;;
prime-agent-generate)
COMPREPLY=($(compgen -W "-p --project -o --output --gateway-url --token --skip-skills --skip-extension --skip-marker --dry-run -h --help" -- "$cur"))
;;
opencode)
COMPREPLY=($(compgen -W "-p --project --gateway-url --token --opencode-dir --skip-skills --skip-plugin --skip-marker --dry-run -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 skill 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 --volume --health-check-tool --health-check-args --health-check-interval --health-check-timeout --tool-call-timeout --memory-limit-mb --health-check-failure-threshold --secret-delivery --entrypoint --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 --pool-name --visibility --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 --visibility --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 --favourite --favourite-index --no-favourite-index --max-favourites --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"))
;;
skill)
COMPREPLY=($(compgen -W "-p --project --agent --content --content-file --description --priority --semver --metadata-file --files-dir -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 --bump --semver --note -h --help" -- "$cur"))
else
local names
names=$(_mcpctl_resource_names "$resource_type")
COMPREPLY=($(compgen -W "$names --bump --semver --note -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 -p --project --allow-secrets -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 "-p --project --allow-secrets -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 --async -h --help" -- "$cur"))
else
COMPREPLY=($(compgen -W "-m --message --system --temperature --max-tokens --no-stream --async -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 ;;
passwd)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
return ;;
errors)
COMPREPLY=($(compgen -W "-n --limit -h --help" -- "$cur"))
return ;;
trace)
COMPREPLY=($(compgen -W "-o --output --strict -h --help" -- "$cur"))
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 ;;
favourites)
local favourites_sub=$(_mcpctl_get_subcmd $subcmd_pos)
if [[ -z "$favourites_sub" ]]; then
COMPREPLY=($(compgen -W "suggest list help" -- "$cur"))
else
case "$favourites_sub" in
suggest)
COMPREPLY=($(compgen -W "--top --window -h --help" -- "$cur"))
;;
list)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
esac
fi
return ;;
review)
local review_sub=$(_mcpctl_get_subcmd $subcmd_pos)
if [[ -z "$review_sub" ]]; then
COMPREPLY=($(compgen -W "pending next show approve reject diff help" -- "$cur"))
else
case "$review_sub" in
pending)
COMPREPLY=($(compgen -W "--type -h --help" -- "$cur"))
;;
next)
COMPREPLY=($(compgen -W "--type -h --help" -- "$cur"))
;;
show)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
approve)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
reject)
COMPREPLY=($(compgen -W "--reason -h --help" -- "$cur"))
;;
diff)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
esac
fi
return ;;
skills)
local skills_sub=$(_mcpctl_get_subcmd $subcmd_pos)
if [[ -z "$skills_sub" ]]; then
COMPREPLY=($(compgen -W "sync help" -- "$cur"))
else
case "$skills_sub" in
sync)
COMPREPLY=($(compgen -W "-p --project --agent --dry-run --force --quiet --skip-postinstall --keep-orphans -h --help" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
esac
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 ;;
provider)
local provider_sub=$(_mcpctl_get_subcmd $subcmd_pos)
if [[ -z "$provider_sub" ]]; then
COMPREPLY=($(compgen -W "status up down disable enable help" -- "$cur"))
else
case "$provider_sub" in
status)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
up)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
down)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
disable)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
enable)
COMPREPLY=($(compgen -W "-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