MCP CLI features a comprehensive theme system that controls the visual appearance of all UI components. The theme system is designed to be internally managed - application code doesn't need to be theme-aware, as all theme handling happens automatically within the UI components.
MCP CLI includes five built-in themes:
- Colors: Standard terminal colors with cyan/blue/magenta accents
- Icons: Full emoji and symbol support (💬, 🤖, 🔧, ✓, ✗)
- Decorations: Rich boxes, panels, and formatting
- Use Case: Modern terminals with full Unicode support
- Colors: Bright variants optimized for dark backgrounds
- Icons: Full emoji and symbol support
- Decorations: Enhanced contrast for dark terminals
- Use Case: Dark terminal backgrounds
- Colors: Dark variants optimized for light backgrounds
- Icons: Full emoji and symbol support
- Decorations: Adjusted contrast for light terminals
- Use Case: Light terminal backgrounds
- Colors: No colors - plain white text only
- Icons: No emojis - basic ASCII characters (-, >, [x])
- Decorations: No boxes or panels - plain text output
- Use Case: Compatibility mode, screen readers, or logging
- Colors: Basic ANSI colors only (8-color palette)
- Icons: No emojis - basic ASCII characters
- Decorations: Simple boxes using ASCII characters
- Use Case: Legacy terminals or SSH sessions
The main theme class that combines colors, icons, and styles:
from mcp_cli.ui.theme import Theme, set_theme, get_theme
# Set a theme globally
set_theme("minimal")
# Get the current theme
theme = get_theme()
# Access theme properties
print(theme.name) # "minimal"
print(theme.colors.success) # Color for success messages
print(theme.icons.check) # Icon for checkmarksDefines color mappings for different UI elements:
@dataclass
class ColorScheme:
# Status colors
success: str = "green"
error: str = "red"
warning: str = "yellow"
info: str = "cyan"
# Text styles
normal: str = "white"
emphasis: str = "bold"
# UI element colors
primary: str = "cyan"
secondary: str = "blue"
accent: str = "magenta"
# Semantic colors
user: str = "yellow"
assistant: str = "blue"
tool: str = "magenta"Defines icons and symbols used in the UI:
@dataclass
class Icons:
# Status icons
success: str = "✓"
error: str = "✗"
warning: str = "⚠"
# Mode indicators
chat: str = "💬"
interactive: str = "⚡"
# Special
robot: str = "🤖"
user: str = "👤"
tool: str = "🔧"Themes can be set programmatically or through command-line options:
# In Python code
from mcp_cli.ui.theme import set_theme
# Set theme at application start
set_theme("dark")
# Change theme during runtime
set_theme("minimal")# Via environment variable (future support)
export MCP_CLI_THEME=minimal
mcp-cli chat --server sqliteThe key principle is that application code should not check themes. UI components handle theme differences internally:
from mcp_cli.ui import output, display_code, display_diff
# Just use the components - they handle themes internally
output.success("Operation completed!")
display_code(my_code, "python", title="Example")
display_diff(old_code, new_code, title="Changes")# Don't do this!
theme = get_theme()
if theme.name == "minimal":
print(f"Code: {code}")
else:
console.print(Syntax(code, "python"))UI components automatically adapt based on the theme:
| Feature | Default | Dark | Light | Minimal | Terminal |
|---|---|---|---|---|---|
| Colors | ✅ Full | ✅ Full | ✅ Full | ❌ None | ✅ Basic |
| Emojis | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No | ❌ No |
| Boxes/Panels | ✅ Rich | ✅ Rich | ✅ Rich | ❌ None | ✅ Simple |
| Syntax Highlighting | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No | ✅ Basic |
| Markdown Rendering | ✅ Full | ✅ Full | ✅ Full | ❌ Plain | ✅ Basic |
| Progress Bars | ✅ Rich | ✅ Rich | ✅ Rich | ❌ Text | ✅ Simple |
Themes provide helper methods for checking capabilities:
theme = get_theme()
# Check theme capabilities
if theme.is_minimal():
# Theme has no decorations
pass
if theme.should_show_banners():
# Theme supports decorative banners
pass
if theme.should_show_icons():
# Theme supports emojis/icons
pass
if theme.should_show_boxes():
# Theme supports boxes/panels
passThe repository includes several demo scripts that showcase UI and terminal capabilities. Following our package management guidelines, use uv run to execute them:
# Interactive UI demo with theme switching
uv run examples/ui_demo.py
# Quick test of all UI components
uv run examples/ui_quick_test.py default
uv run examples/ui_quick_test.py minimal
uv run examples/ui_quick_test.py terminal
# Code-focused UI demo
uv run examples/ui_code_demo.py
# Theme independence demonstration
uv run examples/ui_theme_independence.py
# Terminal management demo (NEW)
uv run examples/ui_terminal_demo.py# In chat mode, use slash commands
/theme minimal # Switch to minimal theme
/theme dark # Switch to dark theme
/theme default # Back to defaultfrom mcp_cli.ui.theme import Theme, ColorScheme, Icons, use_theme
# Create a custom color scheme
class CustomColorScheme(ColorScheme):
def __init__(self):
super().__init__(
success="bright_green",
error="bright_red",
primary="bright_cyan",
accent="bright_magenta"
)
# Create a custom theme
custom_theme = Theme("custom")
custom_theme.colors = CustomColorScheme()
# Use the custom theme
use_theme(custom_theme)Different UI components receive theme-appropriate styling:
- Default/Dark/Light: Colored border with emoji icon (👤 You)
- Minimal: Plain text with "You:" prefix
- Terminal: Simple border with "You:" label
- Default/Dark/Light: Colored border with robot emoji (🤖 Assistant)
- Minimal: Plain text with "Assistant:" prefix
- Terminal: Simple border with "Assistant:" label
- Default/Dark/Light: Colored panel with tool emoji (🔧 Tool Invocation)
- Minimal: Plain text with tool name and arguments
- Terminal: Simple box with tool information
- Default/Dark/Light: Syntax highlighting with line numbers
- Minimal: Plain text code block
- Terminal: Basic highlighting if supported
Never check theme names in application code. UI components know how to render themselves appropriately.
Instead of checking colors directly, use semantic methods:
output.success("Done!") # Green in default, plain in minimal
output.error("Failed!") # Red in default, plain in minimal
output.info("Processing...") # Cyan in default, plain in minimalAlways create Rich components normally - the UI system handles conversion:
# ✅ CORRECT - Theme-agnostic
from rich.table import Table
table = Table(title="Results")
table.add_column("Name")
table.add_column("Status")
table.add_row("Test 1", "✅ Passed")
ui.print_table(table) # Automatically handles all themes
# ❌ WRONG - Don't check themes
if theme.name == "minimal":
print("Name Status")
print("Test 1 Passed")
else:
# Create Rich table...The print_table method automatically:
- Displays Rich formatting for default/dark/light themes
- Converts to aligned plain text for minimal theme
- Converts to simple ASCII for terminal theme
Use the demo scripts to test your UI across all themes:
# Test all themes automatically
uv run examples/ui_theme_independence.py
# Test terminal integration
uv run examples/ui_terminal_demo.pyThe theme is set globally and affects all UI components:
from mcp_cli.ui.theme import set_theme
# At application start
set_theme("minimal") # All UI components now use minimal themeTheme settings can be persisted (future feature):
# ~/.mcp-cli/config.yaml
ui:
theme: minimal
show_timestamps: true
compact_mode: false- Solution: Switch to
minimalorterminaltheme - Command:
set_theme("minimal")
- Cause: Terminal doesn't support colors
- Solution: Use
minimaltheme for plain text
- Cause: Terminal doesn't support Unicode
- Solution: Use
terminaltheme for ASCII-only output
- Solution:
minimaltheme removes all decorations
Planned theme system improvements:
- Custom Theme Loading: Load themes from YAML/JSON files
- Theme Detection: Auto-detect terminal capabilities
- Per-Component Overrides: Override theme for specific components
- Theme Inheritance: Create themes that extend existing ones
- Dynamic Theme Switching: Change themes without restart
- Terminal Capability Detection: Automatically choose best theme
- UI Components Guide - Overview of all UI components
- Output System - Detailed output system documentation
- Prompts and Input - Interactive prompt system
- Code Display - Code rendering and syntax highlighting