A mobile-optimized single page chat application that uses the Anthropic Messages API with real-time streaming and MCP (Model Context Protocol) server support, featuring centralized client management and performance optimizations.
Source: https://www.val.town/x/c15r/Chat
Live server: https://chat.parc.land
Bundles Contextual MCP server by default: https://contextual.parc.land/mcp
- 🚀 Real-time streaming responses - See Claude's responses appear word-by-word as they're generated
- ⏹️ Stream control - Stop streaming at any time with the stop button
- 🔧 Client-side Tools - Interactive tools that run in the browser (ask_user, calculator, js_exec)
- 🎨 UI Affordance Framework - Dynamic UI component registration system for rich interactions
- 💬 Inline User Input - Sophisticated ask_user tool with text, multiline, choice, and confirm inputs
- 🧮 Built-in Calculator - Mathematical expression evaluation tool
- 🎨 UI Affordance System - Register custom UI components in overlays, sidebars, headers, footers, and inline
- 🔄 NextSteps Auto-Execution - MCP tools can propose follow-up actions with automatic or manual execution
- 📄 Resource Viewer - MCP tools can display file content with syntax highlighting and fullscreen support
- 🔧 Centralized Client Pool - Unified MCP client management for optimal performance and reliability
- 📊 Performance Optimizations - Memoized rendering, stable references, and efficient connection reuse
- 🔍 Automatic MCP Server Status Checking - Real-time server health monitoring with detailed diagnostics
- 🎯 Command Palette - Quick access to MCP tools, prompts, and client-side tools via
/
commands - 💾 Persistent Storage - Chat history and settings saved locally with automatic restoration
- 🎨 Exquisite Design System - Sophisticated visual design with glassmorphism, smooth animations, and depth
- 📱 Mobile-First Experience - Optimized for mobile viewports with touch-friendly interactions
- ✨ Smooth Animations - Delightful micro-interactions and transitions throughout the interface
- 🌈 Advanced Theming - Comprehensive design tokens with CSS custom properties
- ♿ Accessibility First - Full keyboard navigation, screen reader support, and reduced motion preferences
The application now uses a unified MCPClientPool that eliminates duplicate connections and provides consistent access to MCP operations:
// Single source of truth for all MCP operations
const clientPool = new MCPClientPool(connectedClients, serverConfigs);
// Unified API across all components
await clientPool.testServer(serverName);
await clientPool.fetchTools();
await clientPool.callTool(serverName, toolName, args);
- ✅ No Duplicate Client Connections: Single client instance per server
- ✅ Memoized Client Resolution: Cached lookups prevent unnecessary re-renders
- ✅ Stable Reference Management: Arrays memoized to prevent reload loops
- ✅ Optimized useEffect Dependencies: Minimal effect re-executions
- ✅ Connection Reuse: Existing connections used for all operations
- ❌ Multiple client instances per server (4 separate creation points)
- ❌ Duplicate connection logic across components
- ❌ ResourceViewer reload loops due to unstable references
- ❌ Inconsistent error handling
- ✅ Single client instance per server via centralized pool
- ✅ Unified connection logic in MCPClientPool
- ✅ Stable component rendering with memoized references
- ✅ Consistent error handling across all components
This app implements Anthropic's official streaming guide using:
- Server-Sent Events (SSE) for real-time communication
- Proper event parsing (
message_start
,content_block_delta
,message_stop
, etc.) - Content block reassembly for text, tool use, and thinking responses
- Immediate message visibility: Completed streaming responses are immediately added to chat history during tool execution cycles
- Error handling and keep-alive support
- Token usage tracking
- Support for all delta types (text, JSON, thinking)
The streaming implementation has been enhanced to provide better user experience during tool execution:
- Immediate Message Addition: Each completed streaming response is immediately added to the visible chat history
- Preserved Context: Previous messages remain visible throughout tool execution cycles
- Live Streaming Preview: Only the currently streaming content uses the live preview system
- Seamless Tool Execution: Interactive tools (like
ask_user
) maintain full conversation context
This ensures users never lose sight of previous responses during long tool execution sequences.
├── backend/
│ └── index.ts # Hono server with static file serving
├── frontend/
│ ├── index.html # Main HTML template
│ ├── index.tsx # React app entry point
│ ├── components/
│ │ ├── App.tsx # Main app component
│ │ ├── StreamingChat.tsx # Real-time streaming chat interface
│ │ ├── Settings.tsx # Settings flyout
│ │ ├── MCPStatus.tsx # MCP server status dashboard with progressive disclosure
│ │ ├── CommandPalette.tsx # MCP prompt command palette
│ │ ├── HTMLRenderer.tsx # HTML output renderer with MCP context
│ │ ├── NextSteps.tsx # NextSteps auto-execution component
│ │ ├── ResourceViewer.tsx # File/resource viewer with syntax highlighting
│ │ ├── Message.tsx # Individual message component
│ │ └── affordances/ # UI affordance components
│ │ ├── CounterAffordance.tsx # Example counter component
│ │ ├── StatusDashboard.tsx # System status dashboard
│ │ ├── NotificationCenter.tsx # Notification management
│ │ └── TestAffordance.tsx # Simple test component
│ ├── hooks/
│ │ └── useAnthropicStream.tsx # Streaming chat hook
│ ├── utils/
│ │ ├── clientTools.ts # Client-side tools utility with dynamic tool management
│ │ ├── affordanceManager.ts # UI affordance registration framework
│ │ ├── containers/ # Affordance container managers
│ │ │ ├── overlayContainer.ts # Modal/popup containers
│ │ │ ├── sidebarContainer.ts # Collapsible side panels
│ │ │ ├── headerContainer.ts # Fixed header extensions
│ │ │ ├── footerContainer.ts # Footer extensions
│ │ │ └── inlineContainer.ts # Chat-embedded components
│ │ ├── mcpTesting.ts # Frontend MCP server testing
│ │ ├── mcpPrompts.ts # Frontend MCP prompt fetching
│ │ ├── mcpTools.ts # MCP tools fetching with caching
│ │ ├── mcpClientPool.ts # Centralized MCP client pool
│ │ └── MCPClient.ts # Individual MCP client wrapper
│ └── style.css # Custom styles with streaming animations
├── shared/
│ ├── types.ts # Shared TypeScript types for streaming
│ └── affordance-types.ts # UI affordance framework types
├── test/ # Test suite
│ ├── components/ # Component tests
│ │ └── Message.test.tsx # Message component tests
│ ├── utils/ # Test utilities and helpers
│ │ └── test-helpers.ts # Common test utilities
│ ├── setup.ts # Global test setup and configuration
│ └── README.md # Test-specific documentation
├── package.json # NPM configuration with test scripts
├── TESTING.md # Comprehensive testing guide
└── README.md
The application includes a powerful UI Affordance Registration Framework that allows the assistant to dynamically create and control custom UI components. This system provides:
- Overlay: Modal/popup containers with backdrop support
- Sidebar: Collapsible side panels (left/right positioning)
- Header: Fixed header extensions with priority ordering
- Footer: Footer extensions alongside existing controls
- Inline: Components embedded directly in the chat flow
attach_affordance
: Attach new UI components from file keys with optional persistencecall_affordance_method
: Invoke methods on attached componentsdetach_affordance
: Remove attached componentslist_affordances
: List all active affordancesget_affordance_errors
: Get runtime errors from affordance componentsclear_affordance_errors
: Clear/acknowledge affordance errorsget_affordance_logs
: Get captured console logs from affordance componentsclear_affordance_logs
: Clear captured logs from affordance componentsrestore_affordances
: Manually restore persistent affordances from localStorageclear_persisted_affordances
: Clear all saved affordance configurationsget_persisted_affordances_info
: View information about saved affordances
// Attach a persistent counter in the sidebar
const counterId = await attach_affordance('sidebar',
'/frontend/components/affordances/CounterAffordance.tsx',
{
title: 'Counter',
position: 'right',
width: '250px',
persistent: true // Will be restored on next session
}
);
// Interact with the counter
await call_affordance_method(counterId, 'increment', []);
const value = await call_affordance_method(counterId, 'getValue', []);
// Check for any errors
const errors = await get_affordance_errors(counterId);
if (errors.length > 0) {
console.log('Component has errors:', errors);
// Clear the errors after handling
await clear_affordance_errors(counterId);
}
// Check for any logs
const logs = await get_affordance_logs(counterId);
if (logs.length > 0) {
console.log('Component logs:', logs);
// Clear the logs after reviewing
await clear_affordance_logs(counterId);
}
// View persistent affordances info
const info = await get_persisted_affordances_info();
console.log(`${info.count} affordances will be restored on next session`);
For detailed documentation, see AFFORDANCE-FRAMEWORK.md. For component development guide, see AFFORDANCE-COMPONENT-GUIDE.md.
The affordance framework supports automatic persistence across sessions:
- Persistent Affordances: Set
persistent: true
in the affordance config to automatically save and restore across browser sessions - Automatic Restoration: Persistent affordances are automatically restored when the app starts and MCP clients are ready
- State Management: Components can implement optional
getState()
andsetState()
methods to preserve internal state - Replacement Logic: Attaching an affordance with the same
fileKey
andtype
automatically replaces the existing one (prevents duplicates) - Error Recovery: Failed restorations are logged but don't break the app startup
Storage Location: Persistent affordances are saved in localStorage
under the key affordance_registrations
.
The app stores configuration and chat history in localStorage:
anthropic_api_key
: Your Anthropic API keyselected_model
: The chosen Claude model (defaults to claude-3-5-sonnet-20241022)mcp_servers
: Array of configured MCP serverschat_messages
: Complete chat history (persists between page loads)auto_execute_next_steps
: Global setting for NextSteps auto-execution (defaults to true)
The project includes a comprehensive test suite using Deno Test and React Testing Library:
# Run all tests npm test # Run tests in watch mode npm run test:watch # Run tests with coverage npm run test:coverage # Generate HTML coverage report npm run test:coverage-report
For detailed testing information, see TESTING.md.
GET /
- Main application (serves frontend)GET /frontend/*
- Frontend static filesGET /shared/*
- Shared utility files
Note: MCP server testing and prompt fetching are now handled directly on the frontend for improved performance and reduced server load.
- Open the app at the provided URL
- Click "Settings" in the footer to configure your Anthropic API key and select your preferred Claude model
- Add/remove/toggle MCP servers as needed
- Use the "Test" button next to each MCP server to verify connectivity (shows ✅ for success, ❌ for errors)
- Configure NextSteps auto-execution in settings (enabled by default)
- Start chatting with Claude and watch responses stream in real-time!
- Use the stop button (⏹️) to interrupt streaming at any time
- Switch models anytime in settings without losing your chat history
- Your chat history and settings will be automatically saved and restored when you return
- When MCP tools return NextSteps proposals, they'll appear as interactive pills that can auto-execute or require manual selection
The app comes pre-configured with the Val Town MCP server:
- Name: Val Town MCP
- URL:
https://c15r--81c497c63c0a11f081e29e149126039e.web.val.run/mcp
- Status: Enabled by default (you'll need to add your authorization token)
- 🎨 Exquisite Design System: Sophisticated visual design featuring:
- Glassmorphism Effects: Translucent surfaces with backdrop blur for depth
- Smooth Animations: Delightful micro-interactions and state transitions
- Advanced Typography: Carefully crafted font hierarchy and spacing
- Color Psychology: Harmonious color palette designed for extended use
- Depth & Shadows: Multi-layered shadow system for visual hierarchy
- Responsive Design: Fluid layouts that adapt beautifully to any screen size
- 📱 Mobile-First Experience: Optimized for mobile devices with:
- Touch-Friendly Controls: Generous tap targets and gesture support
- Adaptive Layouts: Content reflows intelligently on smaller screens
- Performance Optimized: Smooth 60fps animations on mobile devices
- iOS/Android Polish: Native-feeling interactions and visual cues
- Real-time Streaming: Watch Claude's responses appear word-by-word as they're generated
- Stream Control: Stop streaming responses at any time with the stop button
- Client-side Tools: Interactive tools that run directly in the browser:
- ask_user: Sophisticated user input with text, multiline, multiple choice, and confirmation dialogs
- calculate: Mathematical expression evaluator for quick calculations
- NextSteps Auto-Execution: MCP tools can propose follow-up actions that execute automatically after a countdown or require manual selection. See NextSteps-README.md for implementation details.
- Resource Viewer: MCP tools can display file and resource content with syntax highlighting, fullscreen support, and intelligent rendering based on file type
- MCP Integration: Support for multiple Model Context Protocol servers
- Enhanced MCP Display: Collapsible sections for tool calls and results with proper JSON formatting
- Unobtrusive Footer Controls: Settings (⚙️) and clear chat (🗑️) buttons positioned in the footer alongside the input
- Persistent Chat History: All messages automatically saved to localStorage and restored on page load
- Persistent Settings: All configuration stored in browser localStorage
- Auto-scroll: Messages automatically scroll to bottom during streaming
- Auto-resize: Input field grows with content
- Error Handling: Clear error messages for API issues with stream recovery
- Loading States: Visual feedback during API calls and streaming
- Structured Responses: MCP tool use and results are displayed in organized, collapsible sections
- Clean Interface: Maximized chat area with no header, footer contains all controls
- Streaming Animations: Visual cursor and highlighting for active streaming responses
- ♿ Accessibility Features:
- Keyboard Navigation: Full keyboard support for all interactions
- Screen Reader Support: Semantic HTML and ARIA labels
- Reduced Motion: Respects user's motion preferences
- High Contrast: Supports high contrast mode
- Focus Management: Clear focus indicators and logical tab order