feat: implement v2 3-tier architecture (mcpctl → mcplocal → mcpd)
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / typecheck (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / package (pull_request) Has been cancelled

- Rename local-proxy to mcplocal with HTTP server, LLM pipeline, mcpd discovery
- Add LLM pre-processing: token estimation, filter cache, metrics, Gemini CLI + DeepSeek providers
- Add mcpd auth (login/logout) and MCP proxy endpoints
- Update CLI: dual URLs (mcplocalUrl/mcpdUrl), auth commands, --direct flag
- Add tiered health monitoring, shell completions, e2e integration tests
- 57 test files, 597 tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michal
2026-02-22 11:42:06 +00:00
parent a4fe5fdbe2
commit b8c5cf718a
82 changed files with 5832 additions and 123 deletions

93
completions/mcpctl.bash Normal file
View File

@@ -0,0 +1,93 @@
_mcpctl() {
local cur prev words cword
_init_completion || return
local commands="config status get describe instance instances apply setup claude project projects backup restore help"
local global_opts="-v --version -o --output --daemon-url -h --help"
local resources="servers profiles projects instances"
case "${words[1]}" in
config)
COMPREPLY=($(compgen -W "view set path reset help" -- "$cur"))
return ;;
status)
COMPREPLY=($(compgen -W "--daemon-url -h --help" -- "$cur"))
return ;;
get)
if [[ $cword -eq 2 ]]; then
COMPREPLY=($(compgen -W "$resources" -- "$cur"))
else
COMPREPLY=($(compgen -W "-o --output --daemon-url -h --help" -- "$cur"))
fi
return ;;
describe)
if [[ $cword -eq 2 ]]; then
COMPREPLY=($(compgen -W "$resources" -- "$cur"))
else
COMPREPLY=($(compgen -W "-o --output --daemon-url -h --help" -- "$cur"))
fi
return ;;
instance|instances)
if [[ $cword -eq 2 ]]; then
COMPREPLY=($(compgen -W "list ls start stop restart remove rm logs inspect help" -- "$cur"))
else
case "${words[2]}" in
logs)
COMPREPLY=($(compgen -W "--tail --since -h --help" -- "$cur"))
;;
start)
COMPREPLY=($(compgen -W "--env --image -h --help" -- "$cur"))
;;
list|ls)
COMPREPLY=($(compgen -W "--server-id -o --output -h --help" -- "$cur"))
;;
esac
fi
return ;;
claude)
if [[ $cword -eq 2 ]]; then
COMPREPLY=($(compgen -W "generate show add remove help" -- "$cur"))
else
case "${words[2]}" in
generate|show|add|remove)
COMPREPLY=($(compgen -W "--path -p -h --help" -- "$cur"))
;;
esac
fi
return ;;
project|projects)
if [[ $cword -eq 2 ]]; then
COMPREPLY=($(compgen -W "list ls create delete rm show profiles set-profiles help" -- "$cur"))
else
case "${words[2]}" in
create)
COMPREPLY=($(compgen -W "--description -d -h --help" -- "$cur"))
;;
list|ls)
COMPREPLY=($(compgen -W "-o --output -h --help" -- "$cur"))
;;
esac
fi
return ;;
apply)
COMPREPLY=($(compgen -f -- "$cur"))
return ;;
backup)
COMPREPLY=($(compgen -W "-o --output -p --password -r --resources -h --help" -- "$cur"))
return ;;
restore)
COMPREPLY=($(compgen -W "-i --input -p --password -c --conflict -h --help" -- "$cur"))
return ;;
setup)
return ;;
help)
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
return ;;
esac
if [[ $cword -eq 1 ]]; then
COMPREPLY=($(compgen -W "$commands $global_opts" -- "$cur"))
fi
}
complete -F _mcpctl mcpctl

81
completions/mcpctl.fish Normal file
View File

@@ -0,0 +1,81 @@
# mcpctl fish completions
set -l commands config status get describe instance instances apply setup claude project projects backup restore help
# Disable file completions by default
complete -c mcpctl -f
# Global options
complete -c mcpctl -s v -l version -d 'Show version'
complete -c mcpctl -s o -l output -d 'Output format' -xa 'table json yaml'
complete -c mcpctl -l daemon-url -d 'mcpd daemon URL' -x
complete -c mcpctl -s h -l help -d 'Show help'
# Top-level commands
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a config -d 'Manage configuration'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a status -d 'Show status and connectivity'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a get -d 'List resources'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a describe -d 'Show resource details'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a instance -d 'Manage instances'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a apply -d 'Apply configuration from file'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a setup -d 'Interactive setup wizard'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a claude -d 'Manage Claude .mcp.json'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a project -d 'Manage projects'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a backup -d 'Backup configuration'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a restore -d 'Restore from backup'
complete -c mcpctl -n "not __fish_seen_subcommand_from $commands" -a help -d 'Show help'
# get/describe resources
complete -c mcpctl -n "__fish_seen_subcommand_from get describe" -a 'servers profiles projects instances' -d 'Resource type'
# config subcommands
complete -c mcpctl -n "__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from view set path reset" -a view -d 'Show configuration'
complete -c mcpctl -n "__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from view set path reset" -a set -d 'Set a config value'
complete -c mcpctl -n "__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from view set path reset" -a path -d 'Show config file path'
complete -c mcpctl -n "__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from view set path reset" -a reset -d 'Reset to defaults'
# instance subcommands
set -l instance_cmds list ls start stop restart remove rm logs inspect
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and not __fish_seen_subcommand_from $instance_cmds" -a list -d 'List instances'
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and not __fish_seen_subcommand_from $instance_cmds" -a start -d 'Start instance'
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and not __fish_seen_subcommand_from $instance_cmds" -a stop -d 'Stop instance'
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and not __fish_seen_subcommand_from $instance_cmds" -a restart -d 'Restart instance'
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and not __fish_seen_subcommand_from $instance_cmds" -a remove -d 'Remove instance'
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and not __fish_seen_subcommand_from $instance_cmds" -a logs -d 'Get logs'
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and not __fish_seen_subcommand_from $instance_cmds" -a inspect -d 'Inspect container'
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and __fish_seen_subcommand_from logs" -l tail -d 'Number of lines' -x
complete -c mcpctl -n "__fish_seen_subcommand_from instance instances; and __fish_seen_subcommand_from logs" -l since -d 'Since timestamp' -x
# claude subcommands
set -l claude_cmds generate show add remove
complete -c mcpctl -n "__fish_seen_subcommand_from claude; and not __fish_seen_subcommand_from $claude_cmds" -a generate -d 'Generate .mcp.json'
complete -c mcpctl -n "__fish_seen_subcommand_from claude; and not __fish_seen_subcommand_from $claude_cmds" -a show -d 'Show .mcp.json'
complete -c mcpctl -n "__fish_seen_subcommand_from claude; and not __fish_seen_subcommand_from $claude_cmds" -a add -d 'Add server entry'
complete -c mcpctl -n "__fish_seen_subcommand_from claude; and not __fish_seen_subcommand_from $claude_cmds" -a remove -d 'Remove server entry'
complete -c mcpctl -n "__fish_seen_subcommand_from claude; and __fish_seen_subcommand_from $claude_cmds" -s p -l path -d 'Path to .mcp.json' -rF
# project subcommands
set -l project_cmds list ls create delete rm show profiles set-profiles
complete -c mcpctl -n "__fish_seen_subcommand_from project projects; and not __fish_seen_subcommand_from $project_cmds" -a list -d 'List projects'
complete -c mcpctl -n "__fish_seen_subcommand_from project projects; and not __fish_seen_subcommand_from $project_cmds" -a create -d 'Create project'
complete -c mcpctl -n "__fish_seen_subcommand_from project projects; and not __fish_seen_subcommand_from $project_cmds" -a delete -d 'Delete project'
complete -c mcpctl -n "__fish_seen_subcommand_from project projects; and not __fish_seen_subcommand_from $project_cmds" -a show -d 'Show project'
complete -c mcpctl -n "__fish_seen_subcommand_from project projects; and not __fish_seen_subcommand_from $project_cmds" -a profiles -d 'List profiles'
complete -c mcpctl -n "__fish_seen_subcommand_from project projects; and not __fish_seen_subcommand_from $project_cmds" -a set-profiles -d 'Set profiles'
complete -c mcpctl -n "__fish_seen_subcommand_from project projects; and __fish_seen_subcommand_from create" -s d -l description -d 'Description' -x
# backup options
complete -c mcpctl -n "__fish_seen_subcommand_from backup" -s o -l output -d 'Output file' -rF
complete -c mcpctl -n "__fish_seen_subcommand_from backup" -s p -l password -d 'Encryption password' -x
complete -c mcpctl -n "__fish_seen_subcommand_from backup" -s r -l resources -d 'Resources to backup' -xa 'servers profiles projects'
# restore options
complete -c mcpctl -n "__fish_seen_subcommand_from restore" -s i -l input -d 'Input file' -rF
complete -c mcpctl -n "__fish_seen_subcommand_from restore" -s p -l password -d 'Decryption password' -x
complete -c mcpctl -n "__fish_seen_subcommand_from restore" -s c -l conflict -d 'Conflict strategy' -xa 'skip overwrite fail'
# apply takes a file
complete -c mcpctl -n "__fish_seen_subcommand_from apply" -F
# help completions
complete -c mcpctl -n "__fish_seen_subcommand_from help" -a "$commands"