You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+92-18Lines changed: 92 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,9 +7,29 @@ A powerful, feature-rich command-line interface for interacting with Model Conte
7
7
8
8
**Default Configuration**: MCP CLI defaults to using Ollama with the `gpt-oss` reasoning model for local, privacy-focused operation without requiring API keys.
9
9
10
-
## 🆕 Recent Updates (v0.12.0)
11
-
12
-
### Performance & Polish (Tier 3)
10
+
## 🆕 Recent Updates (v0.14.0)
11
+
12
+
### Production Hardening (Tier 5)
13
+
-**Secret Redaction**: All log output (console and file) is automatically redacted for Bearer tokens, API keys, OAuth tokens, and Authorization headers
14
+
-**Structured File Logging**: Optional `--log-file` flag enables rotating JSON log files (10MB, 3 backups) at DEBUG level with secret redaction
15
+
-**Per-Server Timeouts**: Server configs now support `tool_timeout` and `init_timeout` overrides, resolved per-server → global → default
16
+
-**Thread-Safe OAuth**: Concurrent OAuth flows are serialized with `asyncio.Lock` and copy-on-write header mutation
17
+
18
+
### Code Quality (Tier 4)
19
+
-**Core/UI Separation**: Core modules (`chat/conversation.py`, `chat/tool_processor.py`, `chat/chat_context.py`) no longer import `chuk_term.ui.output` — all logging goes through `logging` module
20
+
-**Message Class Clarity**: Local `Message` renamed to `HistoryMessage` (backward-compat alias preserved) to distinguish from `chuk_llm.core.models.Message`
21
+
-**Removed Global Singletons**: `_GLOBAL_TOOL_MANAGER` and associated getter/setter functions deleted
22
+
-**Integration Test Framework**: Real MCP server tests with `@pytest.mark.integration` marker (SQLite server)
23
+
-**Coverage Reporting**: Branch coverage enabled with `fail_under = 60` threshold in pyproject.toml
24
+
25
+
### Previous: MCP Apps (SEP-1865)
26
+
-**Interactive HTML UIs**: MCP servers can now serve interactive HTML applications (charts, tables, maps, markdown viewers) that render in your browser
27
+
-**Sandboxed iframes**: Apps run in secure sandboxed iframes with CSP protection
28
+
-**WebSocket bridge**: Real-time bidirectional communication between browser apps and MCP servers
29
+
-**Automatic launch**: Tools with `_meta.ui` annotations automatically open in the browser when called
30
+
-**Session reliability**: Message queuing, reconnection with exponential backoff, deferred tool result delivery
31
+
32
+
### Previous: Performance & Polish (Tier 3)
13
33
-**O(1) Tool Lookups**: Indexed tool lookup replacing O(n) linear scans in both ToolManager and ChatContext
14
34
-**Cached LLM Tool Metadata**: Per-provider caching of tool definitions with automatic invalidation
15
35
-**Startup Progress**: Real-time progress messages during initialization instead of a single spinner
@@ -18,21 +38,6 @@ A powerful, feature-rich command-line interface for interacting with Model Conte
18
38
-**Conversation Export**: Export conversations as Markdown or JSON with metadata (`/export`)
19
39
-**Trusted Domains**: Tools from trusted server domains (e.g. chukai.io) skip confirmation prompts
20
40
21
-
### Architecture & Performance
22
-
-**Updated to chuk-llm v0.16+**: Dynamic model discovery with capability-based selection, llama.cpp integration (1.53x faster), 52x faster imports
23
-
-**Updated to chuk-tool-processor v0.13+**: Now using CTP's production-grade middleware (retry, circuit breaker, rate limiting)
24
-
-**Slimmed ToolManager**: Reduced from 2000+ lines to ~800 lines by delegating to StreamManager while keeping OAuth, filtering, and LLM adaptation
25
-
26
-
### Reliability Improvements
27
-
-**Transport Failure Detection**: Automatic tracking of consecutive transport failures with warnings and recovery suggestions
28
-
-**Enhanced Tool Processing**: Improved MCP SDK ToolResult handling with proper content extraction from nested structures
29
-
-**Connection Monitoring**: Built-in health checks with automatic detection of unhealthy connections
30
-
31
-
### Bug Fixes
32
-
-**Fixed cmd mode**: `--provider` and `--model` flags now work correctly in command mode (PR #188)
33
-
-**OAuth Improvements**: Enhanced OAuth token handling and storage
34
-
-**Pydantic Migration**: Clean migration to Pydantic for better validation and type safety
35
-
36
41
## 🔄 Architecture Overview
37
42
38
43
The MCP CLI is built on a modular architecture with clean separation of concerns:
@@ -88,6 +93,14 @@ MCP CLI supports all providers and models from CHUK-LLM, including cutting-edge
88
93
-**Middleware**: Retry with exponential backoff, circuit breakers, and rate limiting via CTP
89
94
-**Streaming Tool Calls**: Support for tools that return streaming data
90
95
96
+
### MCP Apps (Interactive UIs)
97
+
-**Browser-based UIs**: MCP servers can serve interactive HTML applications that render in your browser
98
+
-**Automatic Detection**: Tools with `_meta.ui` annotations automatically launch browser apps on tool call
99
+
-**Sandboxed Execution**: Apps run in secure sandboxed iframes with Content Security Policy protection
100
+
-**WebSocket Bridge**: Real-time JSON-RPC bridge between browser apps and MCP tool servers
101
+
-**Session Persistence**: Message queuing during disconnects, automatic reconnection, deferred tool result delivery
102
+
-**structuredContent Support**: Full MCP spec compliance including structured content extraction and forwarding
103
+
91
104
### Advanced Configuration Management
92
105
-**Environment Integration**: API keys and settings via environment variables
93
106
-**File-based Config**: YAML and JSON configuration files
@@ -112,6 +125,7 @@ Comprehensive documentation is available in the `docs/` directory:
112
125
-**[Token Management](docs/TOKEN_MANAGEMENT.md)** - Comprehensive token management for providers and servers including OAuth, bearer tokens, and API keys
113
126
114
127
### Specialized Documentation
128
+
-**[MCP Apps](docs/MCP_APPS.md)** - Interactive browser UIs served by MCP servers (SEP-1865)
115
129
-**[OAuth Authentication](docs/OAUTH.md)** - OAuth flows, storage backends, and MCP server integration
-`--log-file`: Write debug logs to a rotating file (secrets auto-redacted)
236
254
237
255
### Environment Variables
238
256
@@ -343,6 +361,47 @@ mcp-cli token backends # Show available storage backends
343
361
mcp-cli --token-backend encrypted token list # Use specific backend
344
362
```
345
363
364
+
## 🌐 MCP Apps (Interactive Browser UIs)
365
+
366
+
MCP Apps allow tool servers to provide interactive HTML UIs that render in your browser. When a tool has a `_meta.ui` annotation pointing to a UI resource, mcp-cli automatically launches a local web server and opens the app in your browser.
367
+
368
+
### Prerequisites
369
+
370
+
```bash
371
+
# Install the apps extra (adds websockets dependency)
372
+
pip install "mcp-cli[apps]"
373
+
```
374
+
375
+
### How It Works
376
+
377
+
1. Connect to an MCP server that provides app-enabled tools
378
+
2. Call a tool that has `_meta.ui` metadata (e.g., `show_chart`, `show_table`)
379
+
3. mcp-cli automatically fetches the UI resource, starts a local server, and opens your browser
380
+
4. The app receives tool results in real-time via WebSocket
381
+
382
+
### Example
383
+
384
+
```bash
385
+
# Connect to a server with app-enabled tools
386
+
mcp-cli --server view_demo
387
+
388
+
# In chat, ask for something visual:
389
+
> Show me the sales data as a chart
390
+
# Browser opens automatically with an interactive chart
391
+
392
+
# The /tools command shows which tools have app UIs (APP column)
393
+
> /tools
394
+
```
395
+
396
+
### Architecture
397
+
398
+
-**Host page** serves a sandboxed iframe with the app HTML
399
+
-**WebSocket bridge** proxies JSON-RPC between the browser and MCP servers
- **API Keys**: Only needed for cloud providers (OpenAI, Anthropic, etc.), stored securely using token management system
1153
1215
- **OAuth 2.0 Support**: Secure authentication for MCP servers using PKCE and resource indicators (RFC 7636, RFC 8707)
1154
1216
1217
+
### Log Security
1218
+
- **Secret Redaction**: All log output (console and file) is automatically redacted for Bearer tokens, API keys (sk-*), OAuth access tokens, and Authorization headers
1219
+
- **Rotating File Logs**: Optional `--log-file` with JSON format, 10MB rotation, and 3 backup files
1220
+
1155
1221
### Execution Security
1156
1222
- **Tool Validation**: All tool calls are validated before execution
Copy file name to clipboardExpand all lines: architecture.md
+91-8Lines changed: 91 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -112,12 +112,93 @@ Every user-facing feature must have a working example in the `examples/` directo
112
112
113
113
---
114
114
115
-
## Known Violations (Tier 4 Backlog)
115
+
## MCP Apps (SEP-1865)
116
116
117
-
Architecture review performed after Tier 2. These are tracked for remediation in Tier 4 (Code Quality).
117
+
MCP Apps are interactive HTML UIs served by MCP servers and rendered in the user's browser via sandboxed iframes. When a tool has a `_meta.ui` annotation, mcp-cli launches a local web server that bridges the browser and the MCP backend.
-**XSS prevention:** Tool names are `html.escape()`d before template injection
143
+
-**CSP domain sanitization:** Server-supplied domains validated against `^[a-zA-Z0-9\-.:/*]+$`
144
+
-**Tool name validation:** Bridge rejects tool names not matching `^[a-zA-Z0-9_\-./]+$`
145
+
-**URL scheme validation:**`ui/open-link` only allows `http://` and `https://` schemes
146
+
-**Safe JSON serialization:**`_safe_json_dumps()` with `_to_serializable()` fallback; circular reference protection
147
+
148
+
### Session Reliability
149
+
150
+
-**Message queue:**`_pending_notifications: deque[str]` (maxlen=50) queues notifications when WS is disconnected
151
+
-**Drain on reconnect:**`drain_pending()` flushes queued messages when WS reconnects
152
+
-**State reset:**`set_ws()` resets state to INITIALIZING, closes old WS
153
+
-**Reconnect notification:** Host page sends `ui/notifications/reconnected` to app iframe on WS reconnect
154
+
-**Exponential backoff:** WS reconnection uses 1s→30s exponential backoff with reset on success
155
+
-**Initialization timeout:** Configurable JS timeout (default 30s) shows "initialization timed out" if app never initializes
156
+
-**Deferred tool result delivery:** Initial tool results are stored on the bridge and pushed only after the app sends `ui/notifications/initialized`, preventing race conditions where postMessage is dropped before the app sets up its listener
157
+
-**Duplicate prevention:**`launch_app()` closes previous instance before launching new one
158
+
-**Push to existing:**`tool_processor.py` pushes new tool results to running apps instead of re-launching
-`ui/resource-teardown` sent to iframe on `beforeunload`
164
+
-`ui/notifications/host-context-changed` sent after display mode changes
165
+
-`structuredContent` recovered from JSON text blocks when transport loses it (CTP normalization)
166
+
167
+
---
168
+
169
+
## Two Message Classes
170
+
171
+
The codebase has two classes that represent messages, serving different purposes:
172
+
173
+
-**`chuk_llm.core.models.Message`** (re-exported via `chat/response_models.py`) — canonical LLM message with typed `ToolCall` objects. Used by `tool_processor.py` and `conversation.py`.
174
+
-**`mcp_cli.chat.models.HistoryMessage`** (aliased as `Message` for backward compat) — SessionManager-compatible message with `tool_calls: list[dict]`. Used by `chat_context.py`.
The filter is a module-level singleton (`secret_filter`) that can be added to custom handlers.
189
+
190
+
---
191
+
192
+
## Known Violations (Remaining)
193
+
194
+
Architecture review performed after Tier 2. Tier 4 (Code Quality) resolved the most impactful issues. Remaining items are tracked here.
118
195
119
196
### Core/UI Separation (#5)
120
197
198
+
**Resolved in Tier 4.3:**`chat/conversation.py`, `chat/tool_processor.py`, and `chat/chat_context.py` no longer import `chuk_term.ui.output`. All core logging goes through the `logging` module.
199
+
200
+
**Remaining:**
201
+
121
202
| File | Issue | Severity |
122
203
|------|-------|----------|
123
204
|`chat/ui_manager.py`| Imports `prompt_toolkit`, `display/`, `commands/`| HIGH — move to `interactive/`|
@@ -130,15 +211,17 @@ Architecture review performed after Tier 2. These are tracked for remediation in
130
211
| File | Issue | Severity |
131
212
|------|-------|----------|
132
213
|`chat/chat_context.py`|`openai_tools: list[dict]` instead of typed model | MEDIUM |
133
-
|`chat/models.py`|`Message.tool_calls: list[dict]` instead of `list[ToolCallData]`| MEDIUM |
214
+
|`chat/models.py`|`HistoryMessage.tool_calls: list[dict]` instead of `list[ToolCallData]`| MEDIUM — by design for SessionManager compat|
134
215
|`chat/conversation.py`|`_validate_tool_messages()` works on raw dicts | MEDIUM — by design at serialization boundary |
135
216
136
217
### Explicit Dependencies (#7)
137
218
219
+
**Resolved in Tier 4.1:**`_GLOBAL_TOOL_MANAGER` singleton removed. ToolManager is constructor-injected everywhere.
220
+
221
+
**Remaining (deferred — low impact):**
222
+
138
223
| File | Issue | Severity |
139
224
|------|-------|----------|
140
-
|`chat/tool_processor.py`| Uses `get_tool_state()`, `get_search_engine()` globals | MEDIUM |
141
-
|`chat/conversation.py`| Uses `get_tool_state()` global | MEDIUM |
142
-
|`chat/tool_processor.py`| Uses `get_preference_manager()` global | LOW |
143
-
144
-
These are deferred to **Tier 4.1 (Replace Global Singletons)** and **Tier 4.2 (Consolidate Message Classes)**.
0 commit comments