Commit graph

29 commits

Author SHA1 Message Date
Jerome
496a0a382b
Adding WIP notice 2025-06-24 12:47:57 -07:00
Jerome
e746c42f8d
Add documentation for creating in-memory MCP servers
- Explain how to create and register in-memory servers
- Provide examples using the Server class and tool() method
- Include best practices and debugging tips
- Document limitations of in-memory servers
- Add complete calculator server example
2025-06-19 17:12:50 +01:00
Jerome
e53be9ec42
Add support for in-memory MCP servers
- Add InMemoryTransport support for local servers running in the same process
- Update MCPConnectionManager to pass full connection object in callbacks for better context
- Filter out local servers from persistence (they auto-connect on startup)
- Add 'In-Memory' badge in UI to distinguish local servers
- Fix connection state management to properly update connectionsRef
- Auto-connect to available in-memory servers on startup

This enables testing MCP functionality without external servers by running
servers directly in the browser using the InMemoryTransport from the SDK.
2025-06-19 16:55:47 +01:00
Jerome
c9feacd763
Reduce OAuth state timeout from 10 to 5 minutes for improved security
- Update MCP OAuth state expiration in connection.ts
- Update OpenRouter OAuth state expiration in oauth-provider.ts
- Addresses security review feedback to minimize window for potential attacks
2025-06-19 13:40:47 +01:00
Jerome
8ae2da590f
Enable static site deployment with OAuth callback support
- Update OAuth callbacks to use query parameters instead of path routing
- Change redirect URIs to use current page URL (works with any base path)
- Add callback type prefix to state parameter (inference: or mcp:)
- Update App.tsx to route OAuth callbacks based on query params
- Add base path configuration to vite.config.ts for GitHub Pages
- Now works with static hosting (GitHub Pages, python http.server, etc)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-18 20:03:20 +01:00
Jerome
728fea3665
Simplify MCP connection handling and remove health checks
- Remove auth type selection from UI - servers will auto-detect OAuth when needed
- Remove auto-reconnect logic and health checks to reduce complexity
- Always initialize OAuth provider for all connections
- Simplify transport selection - always try streamable-http first, then SSE
- Remove unused config options (transport preference, auto-reconnect)
- Add TODO comment about CORS issues for failed fetch errors
- Make authType and transport optional in connection types
- Clean up connection state notifications for better UI updates

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-18 18:33:55 +01:00
Jerome
7872b5fdb7
Using ping for the keep alive, doing it on a 10min cycle 2025-06-18 13:53:42 +01:00
Jerome
4771d8f1c8
Fix duplicate key warnings and improve inference message details
- Fix duplicate React keys by using unique IDs for request/response/error messages
- Show complete JSON data in Request/Response/Error details sections
- Add Message Metadata section showing all message properties
- Remove debug console.log statements

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-17 15:02:22 +01:00
Jerome
91608a0b97
Fix MCP message monitor layout and add collapsible sections
- Made MCP tab sections (Summary, Add Servers, Server List) collapsible to save space
- Expanded sidebar width limit from 600px to 80% of window width for better debugging
- Fixed message monitor overflow by establishing proper height constraint chain
- Removed auto-scroll and show/hide toggle for message monitor - always visible now
- Server list now has fixed height (max-h-60) with internal scroll
- Message monitor takes remaining space with proper internal scrolling
- Used h-full chain instead of flex-1 to establish explicit height constraints
- Message monitor now properly scrolls within its container instead of at app level

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-13 19:07:01 +01:00
Jerome
1ab5496e0a
Add tabbed sidebar with MCP server management and resizable interface
- Created tabbed interface with MCP, Conversations, and Inference tabs
- Set MCP tab as default tab
- Added quick connect button for example server with OAuth auth
- Created form to add custom MCP servers with auth type selection
- Implemented server management UI with connect/disconnect/remove actions
- Made sidebar resizable with drag handle (240px-600px range)
- Added comprehensive MCP server status display and tools listing
- Created dedicated Inference tab for OpenRouter connection management

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 15:28:20 +01:00
Jerome
6605fbcab6
Rename logout to reset and clear all localStorage
- Renamed "Log Out" button to "Reset All Data" to better reflect functionality
- Renamed handleLogout to handleReset for consistency
- Updated confirmation dialog text to say "reset the application"
- Replaced selective localStorage clearing with localStorage.clear() for complete data removal
- Ensures all conversations, authentication, and MCP data is properly cleared

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 15:11:26 +01:00
Jerome
253db5ebc1
Enhance logout to clear MCP OAuth tokens and disconnect all servers
## Problem
The logout button only cleared inference provider authentication, leaving
MCP OAuth tokens and server connections active. Users remained authenticated
to MCP servers after logging out.

## Solution
- **Clear MCP OAuth tokens**: Remove OAuth tokens and state for all MCP connections
- **Disconnect all servers**: Remove all MCP server connections on logout
- **Complete cleanup**: Comprehensive logout that clears all authentication state
- **Enhanced confirmation**: Updated dialog to inform users about MCP disconnection

## Technical Implementation
- Added MCP context integration to access connections and removal methods
- Clear OAuth tokens from localStorage for each OAuth-enabled connection
- Remove all MCP servers to properly disconnect and clean up connections
- Maintained existing inference provider logout functionality

## User Experience
- ✅ **Complete logout**: All authentication state cleared (inference + MCP)
- ✅ **Clean slate**: No residual authentication data after logout
- ✅ **Clear communication**: User informed about full scope of logout action
- ✅ **Security**: No orphaned authentication tokens left behind

## Data Cleared on Logout
- Inference provider API keys and OAuth tokens
- MCP OAuth tokens and authentication state
- Model selection preferences
- All active MCP server connections

Note: Conversation history remains intact as it's stored separately from auth data.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 15:04:08 +01:00
Jerome
c726e63353
Add logout button to conversation sidebar
## Features
- **Logout button**: Added "Log Out" button at bottom of conversation sidebar
- **Confirmation dialog**: Prompts user to confirm before logging out
- **Conditional display**: Only shows when user is authenticated with a provider
- **Proper styling**: Matches sidebar design with subtle gray styling

## Implementation
- Integrated with existing InferenceContext for logout functionality
- Uses `clearProvider()` to handle complete logout process
- Added border separator between conversations and logout button
- Positioned at bottom of sidebar with fixed placement

## User Experience
- ✅ **Easy access**: Logout button always visible when authenticated
- ✅ **Safety confirmation**: Prevents accidental logout with confirm dialog
- ✅ **Clean design**: Subtle styling that doesn't distract from conversations
- ✅ **Complete logout**: Clears all authentication state and persisted data

## Technical Details
- Leverages existing clearProvider() functionality
- Automatically clears API keys, OAuth tokens, and selected models
- Maintains responsive design and dark mode compatibility
- No impact on conversation data (conversations persist locally)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:55:45 +01:00
Jerome
e5a16a1146
Remove test tabs and simplify UI to conversation-only interface
## Changes
- **Removed navigation tabs**: Eliminated inference and MCP provider test tabs
- **Simplified App component**: Now directly shows ConversationApp without navigation
- **Full-screen layout**: ConversationApp now uses full viewport height (h-screen)
- **Cleaned up imports**: Removed unused test component imports
- **Deleted test components**: Removed InferenceTest.tsx and MCPTest.tsx files

## Benefits
- ✅ **Streamlined UX**: Single-purpose interface focused on conversations
- ✅ **Smaller bundle**: Reduced JS bundle size by ~25KB and CSS by ~3KB
- ✅ **Cleaner codebase**: Removed complexity of tab navigation and test interfaces
- ✅ **Better focus**: All functionality accessible through conversation interface

## Integration Points Preserved
- MCP server management available through conversation sidebar MCP status
- Model selection integrated into conversation header
- All authentication flows still work through conversation interface
- OAuth callbacks remain functional

The conversation interface now provides access to all functionality:
- Model selection in chat header
- MCP server status/management in sidebar
- Test tools still available through agent loop
- Full authentication and provider management

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:53:47 +01:00
Jerome
a901e90b59
Fix agent loop UI bleeding between conversations
## Problem
When starting an agent loop in one conversation and switching to another,
the "assistant thinking" UI would incorrectly appear in the second
conversation, even though it was idle.

## Root Cause
The `isLoading` state in ChatInterface was global/shared across all
conversations. When conversation A started generating, `isLoading` was
set to `true`. Switching to conversation B would still show the thinking
UI because `isGenerating = agentLoopState?.isRunning || isLoading`
evaluated to `true` due to the shared loading state.

## Solution
- **Conversation-specific loading**: Changed from single `isLoading` boolean
  to `loadingConversations` Set tracking which conversations are loading
- **Isolated state**: Each conversation now has independent loading state
- **Proper cleanup**: Loading state is properly added/removed per conversation

## Technical Changes
- Replaced `useState<boolean>` with `useState<Set<string>>`
- Updated `handleSendMessage` to add/remove conversation IDs from Set
- Modified `isGenerating` calculation to check current conversation only

## User Experience
- ✅ **Isolated UI state**: Thinking UI only appears for actually running conversations
- ✅ **No cross-conversation interference**: Switching conversations shows correct state
- ✅ **Maintained functionality**: All existing behavior preserved

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:49:53 +01:00
Jerome
d9e63a790e
Fix model selector being empty after page refresh
## Problem
After page refresh, the model selector would be empty even though the
authentication provider was restored and models were loaded successfully.
Users had to manually click "reload models" to populate the selector.

## Root Cause
The context state wasn't being properly updated after models were loaded
during provider restoration. The provider had the models, but React
components weren't re-rendering to show them.

## Solution
- **Added forced re-render**: Added extra `setAuthStateVersion()` call after
  model loading to trigger React context update
- **Auto-load models on restore**: Provider restoration now automatically
  loads models and restores saved model selection
- **Improved error handling**: Better error handling during model restoration

## Technical Details
- Modified `restoreProviderWithModels()` to force context re-render
- Ensured model loading happens immediately when provider is restored
- Maintained existing model persistence functionality
- Cleaned up debugging logs

## User Experience
- ✅ **Seamless model selection**: Model selector is populated immediately after refresh
- ✅ **Persistent choice**: Previously selected model is automatically restored
- ✅ **No manual intervention**: No need to click "reload models" button

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:38:52 +01:00
Jerome
e8197fb2a5
Add persistent model selection with localStorage
## Features
- **Sticky model selection**: Chosen model persists across browser sessions
- **Automatic restoration**: Saved model is restored when loading models
- **Validation**: Invalid saved models are automatically cleared
- **Provider switching**: Model selection is reset when switching providers

## Implementation Details
- Model ID saved to localStorage on selection
- Model restored during loadModels() if still available
- Saved selection cleared when:
  - Switching inference providers
  - Logging out
  - Model no longer exists in available models

## User Experience
- Users no longer need to reselect their preferred model after refresh
- Model selector maintains state across page reloads
- Graceful handling when saved model becomes unavailable

## Technical Notes
- Uses 'selected_model_id' localStorage key
- Integrates with existing InferenceContext state management
- Maintains backward compatibility with existing provider logic

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:26:08 +01:00
Jerome
0266b4871e
Fix server name normalization for tool routing compatibility
## Problem
MCP server names with invalid characters (spaces, special chars, etc.)
caused tool routing failures when prefixed to tool names, as OpenRouter
API requires tool names to match pattern ^[a-zA-Z0-9_-]{1,64}$

## Solution
- **Added normalizeServerName utility**: Converts invalid characters to underscores
- **Centralized normalization logic**: Shared utility prevents code duplication
- **Fixed tool routing**: Agent loop now matches normalized server names correctly
- **Updated tool discovery**: MCP tools use normalized prefixes consistently

## Examples
- "My Weather Service\!" → "My_Weather_Service"
- "Test@Server#123" → "Test_Server_123"
- "Server...with...dots" → "Server_with_dots"
- "  spaces_and__double__underscores  " → "spaces_and_double_underscores"

## Technical Details
- Created /src/utils/mcpUtils.ts for shared normalization function
- Updated MCPConnectionManager to use normalized prefixes in tool names
- Fixed agent loop to match connections using normalized names
- Maintains original server names in UI while using normalized names for API

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:23:51 +01:00
Jerome
8c46e57b49
Implement comprehensive QoL improvements for MCP client
## Features Added
- **Unique server name validation**: Prevent duplicate MCP server names to avoid tool routing conflicts
- **Quick-add server examples**: Added example server buttons for "Everything" and "Test Server" configurations
- **Conversation model selector**: Added dropdown to change AI models directly in chat interface
- **Fixed nav bar height**: Conversation widget now properly accounts for navigation bar height

## User Experience Improvements
- Server name uniqueness prevents tool naming conflicts and confusion
- Quick-add buttons make it easier to get started with common MCP servers
- Model selector allows switching between AI models without leaving conversation
- Proper height calculation eliminates layout issues with conversation interface

## Technical Details
- Server name validation happens before calling addMcpServer API
- Model selector integrates with existing inference context
- Height calculation uses CSS calc(100vh - 4rem) for nav bar compensation
- All changes maintain backward compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:05:01 +01:00
Jerome
763742ed30
Implement improved auto-reconnect logic and fix TypeScript errors
## Features
- Add proactive health check monitoring for MCP connections (30s intervals)
- Implement automatic reconnection on health check failures
- Add proper cleanup of health check intervals on disconnect

## Fixes
- Resolve OAuth type compatibility issues with MCP SDK
- Fix naming collision between InferenceProvider class and React component
- Remove unused React imports across all components (new JSX transform)
- Clean up unused type imports and variables
- Remove unused handleOAuthAuthentication function

## Technical Details
- Health checks use lightweight listTools() calls to verify connection state
- Automatic reconnection triggers when health checks fail
- Maintains existing exponential backoff retry logic
- All TypeScript compilation errors resolved

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 14:02:00 +01:00
Jerome
2038ea5957
Implement auth token persistence and MCP connection improvements
- Add OpenRouter API key persistence to localStorage with auto-restore
- Add automatic provider restoration on app startup for seamless login
- Fix MCP OAuth token persistence by preserving connection IDs across refreshes
- Add manual reconnect button for failed/disconnected MCP servers
- Add auto-reconnect for MCP servers on app startup
- Maintain backward compatibility with old connection storage format

Resolves auth token loss on page refresh for both inference and MCP providers.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 13:38:20 +01:00
Jerome
d028846a14
Update conversation system documentation for tool naming fix
- Update MCP tool naming from server.tool to server__tool format
- Add tool naming requirements section with OpenRouter API constraints
- Update troubleshooting guide with tool naming validation errors
- Add specific troubleshooting for agent loop hanging with MCP tools

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 12:08:10 +01:00
Jerome
0a06544bda
Fix MCP tool naming for OpenRouter API compatibility
- Change tool name separator from dot to double underscore (server__tool)
- Update tool discovery to use server__tool_name format
- Update tool execution routing to parse double underscore separator
- Fix OpenRouter API error: tool names must match pattern '^[a-zA-Z0-9_-]{1,64}'

This resolves the silent failure when MCP tools were present in conversations.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-12 12:06:06 +01:00
Jerome
e689acee53
Add comprehensive conversation system design documentation
- Document conversation system architecture and data models
- Explain agent loop implementation and tool integration
- Cover state management, authentication flow, and UI components
- Provide development guidelines and troubleshooting guide
- Include performance, security, and testing considerations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-11 18:28:06 +01:00
Jerome
aed7a25ea7
Fix authentication state consistency across components
- Fix ChatInterface to use context's reactive isAuthenticated value
- Fix useAgentLoop to use context's reactive isAuthenticated value
- Ensure consistent authentication state checking across the application
- Add isAuthenticated to useCallback dependencies for proper reactivity

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-11 18:26:06 +01:00
Jerome
3a4a5cdc52
Implement complete conversation system with agent loops
- Add conversation management with persistence and multi-conversation support
- Create agent loop hook with test tools and MCP tool integration
- Implement full chat UI with message display, tool call visualization
- Add inline authentication flow for inference providers
- Support both API key and OAuth authentication methods
- Add conversation sidebar with conversation list and management
- Integrate MCP status display for debugging
- Create message input with proper disabled states and tooltips

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-11 18:16:27 +01:00
Jerome
12cb59e765
Implement MCP OAuth authentication system
- Add MCPOAuthProvider implementing OAuthClientProvider interface
- Implement popup-based OAuth flow with message passing
- Add automatic connection retry after OAuth completion
- Support client registration persistence per server URL
- Add proper error suppression for expected OAuth UnauthorizedErrors
- Create comprehensive OAuth implementation documentation
- Clean up debug logging with emoji status indicators

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-10 22:55:33 +01:00
Jerome
438ceb333c
Implement complete InferenceProvider system with OpenRouter integration
## Features
- 🔧 InferenceProvider interface with pluggable architecture
- 🔑 OpenRouter API key and OAuth PKCE authentication providers
- 🛠️ Tool calling support with automatic agent loop execution
- 📱 Interactive test UI with model selection and chat interface
- 🎯 Provider-level filtering to tool-capable models only
- ⚛️ React context with proper state management for UI reactivity

## Components
- Core types and interfaces in src/types/inference.ts
- OpenRouter client with shared utilities for both auth methods
- Two separate providers (composition over inheritance):
  - OpenRouterApiProvider for API key authentication
  - OpenRouterOAuthProvider for OAuth PKCE flow
- React InferenceContext with useInference hook
- Interactive test UI with tool calling demonstration
- OAuth callback routing with proper namespacing

## Tool Calling
- 3 test tools: weather, calculator, time
- Automatic tool execution and agent loop
- Visual tool call display with arguments and results
- Error handling for malformed tool calls

## Bug Fixes
- Fixed model selection UI reactivity issue
- Fixed OAuth popup race condition causing "cancelled" errors
- Proper cleanup of event listeners and intervals

## Documentation
- Comprehensive interface design document
- Implementation strategy and key design decisions
- Testing approach and security considerations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-10 17:37:11 +01:00
Jerome
aa97d655aa
Initial prompts / design doc with claude 2025-06-10 13:27:47 +01:00