feat: interactive MCP console (mcpctl console <project>)

Ink-based TUI that shows exactly what an LLM sees through MCP.
Browse tools/resources/prompts, execute them, and see raw JSON-RPC
traffic in a protocol log. Supports gated session flow with
begin_session, raw JSON-RPC input, and session reconnect.

- McpSession class wrapping HTTP transport with typed methods
- 12 React/Ink components (header, protocol-log, menu, tool/resource/prompt views, etc.)
- 21 unit tests for McpSession against a mock MCP server
- Fish + Bash completions with project name argument
- bun compile with --external react-devtools-core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michal
2026-02-25 23:56:23 +00:00
parent d4aa677bfc
commit a59d2237b9
23 changed files with 2093 additions and 9 deletions

View File

@@ -2,7 +2,7 @@ _mcpctl() {
local cur prev words cword
_init_completion || return
local commands="status login logout config get describe delete logs create edit apply backup restore mcp approve help"
local commands="status login logout config get describe delete logs create edit apply backup restore mcp console approve 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 prompts promptrequests"
@@ -91,6 +91,14 @@ _mcpctl() {
return ;;
mcp)
return ;;
console)
# First arg is project name
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" -- "$cur"))
fi
return ;;
get|describe|delete)
if [[ -z "$resource_type" ]]; then
COMPREPLY=($(compgen -W "$resources" -- "$cur"))

View File

@@ -3,7 +3,7 @@
# Erase any stale completions from previous versions
complete -c mcpctl -e
set -l commands status login logout config get describe delete logs create edit apply patch backup restore mcp approve help
set -l commands status login logout config get describe delete logs create edit apply patch backup restore mcp console approve help
set -l project_commands attach-server detach-server get describe delete logs create edit help
# Disable file completions by default
@@ -162,6 +162,7 @@ complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a backup -d 'Backup configuration'
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a restore -d 'Restore from backup'
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a patch -d 'Patch a resource field'
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a console -d 'Interactive MCP console'
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a approve -d 'Approve a prompt request'
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a help -d 'Show help'
@@ -318,6 +319,28 @@ end
complete -c mcpctl -n "__fish_seen_subcommand_from approve; and __mcpctl_approve_needs_type" -a 'promptrequest' -d 'Resource type'
complete -c mcpctl -n "__fish_seen_subcommand_from approve; and __mcpctl_approve_needs_name" -a '(__mcpctl_promptrequest_names)' -d 'Prompt request name'
# console: takes a project name as first argument
function __mcpctl_console_needs_project
set -l tokens (commandline -opc)
set -l found false
for tok in $tokens
if $found
if not string match -q -- '-*' $tok
return 1 # project arg already present
end
end
if test "$tok" = "console"
set found true
end
end
if $found
return 0 # console found but no project yet
end
return 1
end
complete -c mcpctl -n "__fish_seen_subcommand_from console; and __mcpctl_console_needs_project" -a '(__mcpctl_project_names)' -d 'Project name'
# apply takes a file
complete -c mcpctl -n "__fish_seen_subcommand_from apply" -s f -l file -d 'Configuration file' -rF
complete -c mcpctl -n "__fish_seen_subcommand_from apply" -F