feat: audit console TUI, system prompt management, and CLI improvements

Audit Console Phase 1: tool_call_trace emission from mcplocal router,
session_bind/rbac_decision event kinds, GET /audit/sessions endpoint,
full Ink TUI with session sidebar, event timeline, and detail view
(mcpctl console --audit).

System prompts: move 6 hardcoded LLM prompts to mcpctl-system project
with extensible ResourceRuleRegistry validation framework, template
variable enforcement ({{maxTokens}}, {{pageCount}}), and delete-resets-
to-default behavior. All consumers fetch via SystemPromptFetcher with
hardcoded fallbacks.

CLI: -p shorthand for --project across get/create/delete/config commands,
console auto-scroll improvements, shell completions regenerated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michal
2026-03-03 23:50:54 +00:00
parent 89f869f460
commit 5d859ca7d8
42 changed files with 1932 additions and 77 deletions

View File

@@ -119,10 +119,10 @@ _mcpctl() {
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
;;
claude)
COMPREPLY=($(compgen -W "--project -o --output --inspect --stdout -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "-p --project -o --output --inspect --stdout -h --help" -- "$cur"))
;;
claude-generate)
COMPREPLY=($(compgen -W "--project -o --output --inspect --stdout -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "-p --project -o --output --inspect --stdout -h --help" -- "$cur"))
;;
setup)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
@@ -138,11 +138,11 @@ _mcpctl() {
return ;;
get)
if [[ -z "$resource_type" ]]; then
COMPREPLY=($(compgen -W "$resources -o --output --project -A --all -h --help" -- "$cur"))
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 --project -A --all -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "$names -o --output -p --project -A --all -h --help" -- "$cur"))
fi
return ;;
describe)
@@ -156,11 +156,11 @@ _mcpctl() {
return ;;
delete)
if [[ -z "$resource_type" ]]; then
COMPREPLY=($(compgen -W "$resources --project -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "$resources -p --project -h --help" -- "$cur"))
else
local names
names=$(_mcpctl_resource_names "$resource_type")
COMPREPLY=($(compgen -W "$names --project -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "$names -p --project -h --help" -- "$cur"))
fi
return ;;
logs)
@@ -197,13 +197,13 @@ _mcpctl() {
COMPREPLY=($(compgen -W "--subject --binding --operation --force -h --help" -- "$cur"))
;;
prompt)
COMPREPLY=($(compgen -W "--project --content --content-file --priority --link -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "-p --project --content --content-file --priority --link -h --help" -- "$cur"))
;;
serverattachment)
COMPREPLY=($(compgen -W "--project -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "-p --project -h --help" -- "$cur"))
;;
promptrequest)
COMPREPLY=($(compgen -W "--project --content --content-file --priority -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "-p --project --content --content-file --priority -h --help" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "-h --help" -- "$cur"))
@@ -276,9 +276,9 @@ _mcpctl() {
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 -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "$names --stdin-mcp --audit -h --help" -- "$cur"))
else
COMPREPLY=($(compgen -W "--stdin-mcp -h --help" -- "$cur"))
COMPREPLY=($(compgen -W "--stdin-mcp --audit -h --help" -- "$cur"))
fi
return ;;
help)

View File

@@ -265,13 +265,13 @@ complete -c mcpctl -n "__fish_seen_subcommand_from config; and not __fish_seen_s
complete -c mcpctl -n "__mcpctl_subcmd_active config view" -s o -l output -d 'output format (json, yaml)' -x
# config claude options
complete -c mcpctl -n "__mcpctl_subcmd_active config claude" -l project -d 'Project name' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active config claude" -s p -l project -d 'Project name' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active config claude" -s o -l output -d 'Output file path' -x
complete -c mcpctl -n "__mcpctl_subcmd_active config claude" -l inspect -d 'Include mcpctl-inspect MCP server for traffic monitoring'
complete -c mcpctl -n "__mcpctl_subcmd_active config claude" -l stdout -d 'Print to stdout instead of writing a file'
# config claude-generate options
complete -c mcpctl -n "__mcpctl_subcmd_active config claude-generate" -l project -d 'Project name' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active config claude-generate" -s p -l project -d 'Project name' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active config claude-generate" -s o -l output -d 'Output file path' -x
complete -c mcpctl -n "__mcpctl_subcmd_active config claude-generate" -l inspect -d 'Include mcpctl-inspect MCP server for traffic monitoring'
complete -c mcpctl -n "__mcpctl_subcmd_active config claude-generate" -l stdout -d 'Print to stdout instead of writing a file'
@@ -338,17 +338,17 @@ complete -c mcpctl -n "__mcpctl_subcmd_active create rbac" -l operation -d 'Oper
complete -c mcpctl -n "__mcpctl_subcmd_active create rbac" -l force -d 'Update if already exists'
# create prompt options
complete -c mcpctl -n "__mcpctl_subcmd_active create prompt" -l project -d 'Project name to scope the prompt to' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active create prompt" -s p -l project -d 'Project name to scope the prompt to' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active create prompt" -l content -d 'Prompt content text' -x
complete -c mcpctl -n "__mcpctl_subcmd_active create prompt" -l content-file -d 'Read prompt content from file' -rF
complete -c mcpctl -n "__mcpctl_subcmd_active create prompt" -l priority -d 'Priority 1-10 (default: 5, higher = more important)' -x
complete -c mcpctl -n "__mcpctl_subcmd_active create prompt" -l link -d 'Link to MCP resource (format: project/server:uri)' -x
# create serverattachment options
complete -c mcpctl -n "__mcpctl_subcmd_active create serverattachment" -l project -d 'Project name' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active create serverattachment" -s p -l project -d 'Project name' -xa '(__mcpctl_project_names)'
# create promptrequest options
complete -c mcpctl -n "__mcpctl_subcmd_active create promptrequest" -l project -d 'Project name to scope the prompt request to' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active create promptrequest" -s p -l project -d 'Project name to scope the prompt request to' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__mcpctl_subcmd_active create promptrequest" -l content -d 'Prompt content text' -x
complete -c mcpctl -n "__mcpctl_subcmd_active create promptrequest" -l content-file -d 'Read prompt content from file' -rF
complete -c mcpctl -n "__mcpctl_subcmd_active create promptrequest" -l priority -d 'Priority 1-10 (default: 5, higher = more important)' -x
@@ -361,7 +361,7 @@ complete -c mcpctl -n "__fish_seen_subcommand_from login" -l mcpd-url -d 'mcpd U
# get options
complete -c mcpctl -n "__fish_seen_subcommand_from get" -s o -l output -d 'output format (table, json, yaml)' -x
complete -c mcpctl -n "__fish_seen_subcommand_from get" -l project -d 'Filter by project' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__fish_seen_subcommand_from get" -s p -l project -d 'Filter by project' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__fish_seen_subcommand_from get" -s A -l all -d 'Show all (including project-scoped) resources'
# describe options
@@ -369,7 +369,7 @@ complete -c mcpctl -n "__fish_seen_subcommand_from describe" -s o -l output -d '
complete -c mcpctl -n "__fish_seen_subcommand_from describe" -l show-values -d 'Show secret values (default: masked)'
# delete options
complete -c mcpctl -n "__fish_seen_subcommand_from delete" -l project -d 'Project name (for serverattachment)' -xa '(__mcpctl_project_names)'
complete -c mcpctl -n "__fish_seen_subcommand_from delete" -s p -l project -d 'Project name (for serverattachment)' -xa '(__mcpctl_project_names)'
# logs options
complete -c mcpctl -n "__fish_seen_subcommand_from logs" -s t -l tail -d 'Number of lines to show' -x
@@ -391,6 +391,7 @@ complete -c mcpctl -n "__fish_seen_subcommand_from restore" -s c -l conflict -d
# console options
complete -c mcpctl -n "__fish_seen_subcommand_from console" -l stdin-mcp -d 'Run inspector as MCP server over stdin/stdout (for Claude)'
complete -c mcpctl -n "__fish_seen_subcommand_from console" -l audit -d 'Browse audit events from mcpd'
# logs: takes a server/instance name
complete -c mcpctl -n "__fish_seen_subcommand_from logs; and __mcpctl_needs_arg_for logs" -a '(__mcpctl_instance_names)' -d 'Server name'