Commit graph

56 commits

Author SHA1 Message Date
Glen Maddern
40c02d2d98 0.0.21
Some checks failed
CI / test (push) Has been cancelled
Publish Any Commit / build (push) Has been cancelled
v0.0.21
2025-07-25 20:14:43 +10:00
Glen Maddern
8337ff0a68
Stopping any window.open if the preventAutoAuth flag is set (#34) 2025-07-25 20:14:35 +10:00
Glen Maddern
8952e3b47d 0.0.20 v0.0.20 2025-07-24 17:24:18 +10:00
Glen Maddern
043efbcf12
feat: Add onPopupWindow callback and update README (#32)
* feat: Add onPopupWindow callback and update README

* feat: Pass window reference to onPopupWindow callback

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-07-24 17:23:52 +10:00
Glen Maddern
c47ea828c3
Fix redirect bug (#31)
* Got the CF agent demo server showing a permission dialog. Works manually in inspector

* Clicking on the approval dialog, tests pass already
2025-07-24 17:19:11 +10:00
Glen Maddern
c3ee0e9b09
Fixing oauth flow on chat example (#27)
* wip

* Successfully getting a token from Groq!

* Simplify PKCE flow to use single key per provider

Previously, the PKCE flow stored multiple keys with timestamps (pkce_${providerId}_${timestamp})
and had complex logic to find the most recent key. This simplified implementation:

- Changes storage key format from `pkce_${providerId}_${timestamp}` to `pkce_${providerId}`
- Removes timestamp-based key sorting logic in completeOAuthFlow()
- Ensures only one PKCE key is stored per provider at any time
- Eliminates potential race conditions with multiple concurrent auth flows
- Simplifies debugging by having predictable key names

This applies to both OpenRouter and Groq OAuth flows. Also fixes TypeScript
build error by removing unused 'state' variable in OAuthCallback component.

Amp-Thread: https://ampcode.com/threads/T-12223468-a950-40a8-9d44-2e1a66e6efbe
Co-authored-by: Amp <amp@ampcode.com>

* Amp getting confused

* Able to run inference against staging Groq

* The old oauth callback got clobbered, try to restore it

* Restored, but still buggy

* updated data

* Pruning Groq models

* deploying

---------

Co-authored-by: Amp <amp@ampcode.com>
2025-07-16 22:21:20 +10:00
Glen Maddern
5b54994da7 Fixing reasoning on Qwen3 2025-07-11 16:02:59 +10:00
Glen Maddern
c260e971d9
Added openrouter (#25)
* Add models.dev data fetching script and pnpm command

- Created scripts/update-models.ts to fetch and filter models from models.dev API
- Added pnpm update-models command to package.json
- Generated initial models.json with 39 models from 3 providers
- Filtered to only include anthropic, groq, and openrouter providers
- Added tsx as dev dependency for TypeScript execution

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Create new type system and authentication for multi-provider support

- Refactored types/models.ts with new Provider and Model interfaces
- Added support for OAuth authentication alongside API keys
- Created useModels hook for favorites management and model data loading
- Added comprehensive auth utils with OAuth PKCE flow implementation
- Updated apiKeys.ts to use new auth system for backward compatibility
- Created OAuthCallback component for OAuth flow completion
- Added support for OpenRouter OAuth configuration

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Implement comprehensive ModelSelector refactor with favorites and OAuth support

- Refactored ModelSelector to use new favorites-based system with search and filtering
- Added star ratings for favorite models with local storage persistence
- Added search functionality to filter models by name/provider
- Added "Tools Only" and "Favorites" filter toggles
- Updated authentication to support OAuth PKCE flow alongside API keys
- Added OpenRouter OAuth support with proper error handling
- Updated ConversationThread, ModelSelectionModal, and ApiKeyModal to use new Provider type
- Added OAuth success message handling in ChatApp
- Updated useStreamResponse to support OpenRouter via @ai-sdk/openai
- Fixed all TypeScript compilation errors for new model system
- Added proper auth headers for all three providers (Groq, Anthropic, OpenRouter)

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Add final touches and documentation for model selector system

- Fixed unused import in useStreamResponse.ts
- Added .env.example for OpenRouter OAuth configuration
- Created comprehensive MODEL_SELECTOR_GUIDE.md with usage instructions
- Documented all features including favorites, search, filtering, and OAuth
- Added setup instructions for OpenRouter OAuth
- Included troubleshooting guide and local storage details

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Implement clean provider-first model selector with favorites workflow

- Refactored ModelSelector to show providers first, then starred models
- Created ProviderModelsModal for provider-specific model selection and starring
- Removed search/filter complexity from main dropdown
- Added handleProviderSelect to route between OAuth/API key flows
- OAuth providers show model selection after successful authentication
- API key providers show model selection after key entry
- Starred models appear grayed out when provider not configured
- Clicking unconfigured starred model redirects to provider setup
- Added OAuth success message handling to auto-open provider models
- Clean two-step workflow: configure provider → select/star models

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Fix ModelSelectionModal to use provider-first workflow

- Replaced the old flat model list in ModelSelectionModal with provider-first design
- Shows 3 provider cards (Anthropic, Groq, OpenRouter) with auth status
- Added starred models section below providers (empty initially)
- OAuth flow for OpenRouter, API key modals for Anthropic/Groq
- Provider selection leads to ProviderModelsModal for browsing and starring
- Grayed out starred models when provider not configured
- Click unconfigured starred model redirects to provider setup
- OAuth success automatically opens provider models modal
- Clean, intuitive workflow: Select Provider → Configure Auth → Browse Models → Star Favorites

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Fix OpenRouter OAuth flow to match their API specification

- Updated authorization URL from /oauth/authorize to /auth
- Changed token URL to /api/v1/auth/keys
- Removed client_id requirement (OpenRouter doesn't use it)
- Removed scopes (OpenRouter doesn't use them)
- Updated OAuth flow to use callback_url instead of redirect_uri
- Changed token exchange to use JSON body instead of form data
- Handle OpenRouter's response format {key: "..."} instead of {access_token: "..."}
- Made state parameter optional for OpenRouter (they don't use it)
- Updated sessionStorage handling for providers without state parameter
- Simplified .env.example to remove client_id requirement

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Fix model selection and favorites system

- **Fixed multiple useModels hook instances**: Removed duplicate hook from ModelSelectionModal and consolidated all model state management in ChatApp
- **Fixed auto-starring**: Models are now automatically starred when selected from any UI (provider modal or favorites list)
- **Fixed favorites persistence**: Starred models now properly persist in localStorage and are restored on page refresh
- **Fixed selected model highlighting**: Currently selected model is now highlighted in the starred models list with blue border, ring effect, and checkmark
- **Improved prop passing**: Pass all model-related functions (addToFavorites, toggleFavorite, isFavorite, getFavoriteModels) down through ChatApp → ConversationThread → ModelSelectionModal
- **Removed debug logs**: Cleaned up console.log statements added during debugging

The root cause was multiple instances of the useModels hook running simultaneously, causing state conflicts where one instance would load favorites correctly but another would reset them to an empty array. Now there's a single source of truth for all model state in ChatApp.

This fixes the specific issues where:
1. Selected models weren't being auto-starred
2. Starred models list was forgotten on page refresh
3. Selected model highlighting wasn't working in the modal

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Replace nested modals with single modal navigation

- **Improved UX**: Replaced stacked modals with a single modal that switches between views
- **Added back navigation**: Provider models view now has a back button in the top left to return to main view
- **Unified modal structure**: Single modal container with conditional rendering for main vs provider views
- **Added search functionality**: Provider models view includes a search bar to filter models
- **Better visual hierarchy**: Provider view shows provider logo and name in header
- **Removed ProviderModelsModal**: Consolidated functionality into ModelSelectionModal
- **Enhanced interaction**: Cleaner navigation flow without modal stacking

Main view shows:
- List of providers with authentication status
- Starred models section

Provider view shows:
- Back button + provider logo/name in header
- Search bar for filtering models
- List of provider's models with star/select actions
- Model count at bottom

This creates a much more intuitive navigation experience similar to mobile app patterns, avoiding the confusing nested modal behavior.

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Fix modal scrolling for overflow content

- **Fixed height constraints**: Modal now uses flexbox layout with proper height management
- **Added flex-shrink-0 to header**: Prevents header from shrinking and maintains fixed height
- **Added flex-1 min-h-0 to content**: Allows content area to take remaining space and scroll properly
- **Improved responsive behavior**: Modal content now scrolls vertically when overflowing on smaller screens

Key changes:
- Modal container: Added `flex flex-col` for vertical layout
- Header: Added `flex-shrink-0` to maintain fixed height
- Content area: Added `flex-1 min-h-0` to fill remaining space and enable scrolling

This ensures that:
1. Header stays fixed at top
2. Content area takes remaining vertical space
3. Content scrolls independently when overflowing
4. Works properly on all screen sizes, including small screens with many models

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* Make provider model rows fully clickable

- **Improved UX consistency**: Provider model rows now behave like starred model rows
- **Full row clickable**: Click anywhere in the row to select and star the model
- **Event handling**: Star button uses stopPropagation to prevent row click when toggling favorites
- **Visual clarity**: Replaced "Select" button with subtle "Click to select" hint
- **Added cursor pointer**: Clear visual indication that rows are clickable

Changes:
- Added `cursor-pointer` and `onClick` to model rows in provider view
- Star button now stops event propagation to allow independent toggling
- Removed separate "Select" button for cleaner, more consistent interface
- Added "Click to select" text hint on the right side

This creates a consistent interaction pattern across both:
- Main view starred models (click row to select)
- Provider view models (click row to select and star)

Users can now efficiently browse and select models with single clicks, while still having granular control over favorites via the star button.

Amp-Thread: https://ampcode.com/threads/T-918d21db-3d47-4c6f-a3d8-96a60b59674a
Co-authored-by: Amp <amp@ampcode.com>

* localstorage saving working

---------

Co-authored-by: Amp <amp@ampcode.com>
2025-07-11 14:34:33 +10:00
Glen Maddern
85efc2de59 Updated chat example readme 2025-07-09 10:58:44 +10:00
Glen Maddern
448e633eef Dev tooling tweaks 2025-07-04 14:45:30 +10:00
Glen Maddern
c7e3e2303d
Merge pull request #22 from modelcontextprotocol/pkg-pr-new
Enabling pkg.pr.new
2025-07-03 14:54:47 +10:00
Glen Maddern
156c956112 welcome back old friend 2025-07-03 14:21:07 +10:00
Glen Maddern
42621bfe02 0.0.19 v0.0.19 2025-07-03 14:12:48 +10:00
Glen Maddern
977fa6f8b4 prettier:fix 2025-07-03 14:12:41 +10:00
Glen Maddern
3af42b0e77 Merge branch 'husky' 2025-07-03 14:12:27 +10:00
Glen Maddern
94ba6ff372
Merge pull request #5 from jem-computer/feat/resources-and-prompts
Feat/resources and prompts
2025-07-03 14:12:12 +10:00
Glen Maddern
e682ad8396 Adding husky config 2025-07-03 14:11:53 +10:00
Jem
6a42f9dc93 feat(examples): transform hono-mcp server to Vengabus party theme
Transform the generic example server into a fun Vengabus-themed MCP server with:
- Replace generic tools with party-themed tools (party capacity calculator, vengabus schedule)
- Update resources to use party-themed URIs and content
- Replace generic prompts with party invitations and announcements
- Fix resource URI handling to strip trailing slashes
- Fix TypeScript errors with proper resource template typing
- Use docs:// protocol for party manual resource

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-02 18:35:12 -07:00
Jem
e0743c35e4 chore: fix prettier formatting and update example server dependencies
- Fix formatting issues in cf-agents, hono-mcp, and test files
- Update dependencies in example servers

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-02 17:59:24 -07:00
Jem
b909730ae2 docs: update README files with resources and prompts documentation
- Add resources, resourceTemplates, and prompts to all feature lists
- Document new properties returned by useMcp hook
- Document new methods: listResources, readResource, listPrompts, getPrompt
- Add code examples showing how to use resources and prompts
- Update quick start examples to demonstrate all features
- Add note about graceful handling of servers with partial MCP support

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-02 16:01:04 -07:00
Jem
d4220ec5f2 fix: make resources and prompts optional features
- Wrap resources/list and prompts/list calls in try-catch blocks
- Continue with connection even if server doesn't support these methods
- Update logging to only show counts for features that are supported
- Fix TypeScript types for optional responses

This allows the hook to work with servers that only implement the core
tools functionality without resources or prompts support.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-02 14:24:59 -07:00
Jem
7a923c3509 feat(examples): add resources and prompts display to inspector
- Import and export Resource, ResourceTemplate, and Prompt types
- Add state management for resources and prompts in McpServers component
- Add UI sections to display available resources and prompts
- Implement readResource functionality with content display
- Implement getPrompt functionality with argument inputs
- Show resource templates with visual distinction
- Add expand/collapse UI for resources and prompts
- Display prompt messages with proper formatting

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-02 14:24:59 -07:00
Jem
8377abf268 feat: add MCP prompts support to useMcp hook
- Add Prompt type from MCP SDK
- Add prompts array to UseMcpResult
- Fetch prompts automatically after resources during connection
- Add listPrompts() method to manually refresh prompts list
- Add getPrompt(name, args) method to get specific prompt messages
- Clear prompts state on disconnect

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-02 14:22:19 -07:00
Jem
8373adfdf9 feat: add MCP resources support to useMcp hook
- Add Resource and ResourceTemplate types from MCP SDK
- Add resources and resourceTemplates arrays to UseMcpResult
- Fetch resources automatically after tools during connection
- Add listResources() method to manually refresh resources list
- Add readResource(uri) method to read resource contents
- Clear resources state on disconnect

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-02 14:22:19 -07:00
Glen Maddern
25797dd4bb 0.0.18 v0.0.18 2025-07-02 20:41:18 +10:00
Glen Maddern
f50a1c588f removing postinstall 2025-07-02 20:41:16 +10:00
Glen Maddern
ec0eae5ea3 0.0.17 v0.0.17 2025-07-02 16:25:04 +10:00
Glen Maddern
ac52a72557 Updated readme 2025-07-02 16:24:53 +10:00
Glen Maddern
26965cb6a3
Adding a full chat example (#19)
* Copying chat example across

* MCP tool calling woo!

* Moving most of the debug logging behind localStorage.USE_MCP_DEBUG

* Working on tool call display

* working tool call ui!

* deployng to workers.dev for sharing

* Simplify chat UI to focus on main input with pastel gradient background

- Hide sidebar (conversations, model picker, MCP servers) while preserving components
- Hide navbar/title bar while preserving component
- Remove title text and description above input field
- Add pastel gradient background (pink-purple-indigo)
- Expand conversation thread to full width
- Create minimal, focused interface with only white input field visible

* Add animated rotating conical gradient background

- Create large 500% conical gradient with pastel color cycle
- Position gradient off-screen (-200% top/left) for smooth rotation
- Add 8s linear infinite rotation animation for fast testing
- Use ::before pseudo-element to avoid repainting main content
- Cycle through various pastel shades (pink, purple, blue, green, yellow, orange)
- Performance-optimized: only transforms, no gradient repainting

* Switch to hue-rotate animation for background gradient

- Revert complex conical gradient approach
- Return to original linear gradient (pink-100 → purple-50 → indigo-100)
- Add hue-rotate filter animation cycling through 360 degrees
- 8s duration for fast testing
- Simpler implementation with continuous color shifting
- Less control over saturation but smoother performance

* Slow down hue-rotate animation to 60 seconds

- Change animation duration from 8s to 60s for subtle color shifting
- Creates gentle, barely noticeable background color transitions
- Maintains visual interest without being distracting

* Add random starting point for hue-rotate animation

- Generate random negative animation-delay between 0 and -60 seconds
- Starts animation at random point in the 60-second cycle
- Each page load will show different initial colors
- Uses useState with initializer function to set delay once on mount
- CSS doesn't have random functions, so JavaScript handles the randomization

* Use CSS custom property for cleaner random animation delay

- Move animation-delay to CSS using custom property --random-delay
- JavaScript still required to generate random value (CSS has no random functions)
- Cleaner separation between styling (CSS) and logic (JavaScript)
- Maintains same functionality with better organization

* Add brain emoji model selector with fullscreen modal

- Create ModelSelectionModal component with list-style interface
- Add brain emoji (🧠) indicator below chat input, left-aligned
- Show current model name in lowercase or red X if not configured
- Fullscreen modal displays all available models with configuration status
- Green checkmark for configured models, red alert for unconfigured
- Integrate with existing API key management and model selection logic
- Modal handles API key setup workflow when selecting unconfigured models
- Clean separation between compact indicator and full selection interface

* Isolate hue-rotate animation to background layer only

- Create separate background layer using ::before pseudo-element
- Move hue-rotate animation to background layer with z-index: -1
- Remove filter from main container to prevent inheritance
- Use equivalent gradient colors in CSS (pink-100, purple-50, indigo-100)
- Foreground elements (brain emoji, text) now maintain original colors
- Background still animates smoothly without affecting content

* Replace red X with grey 'none' text and add pointer cursor

- Change unconfigured model indicator from red ✕ to grey 'none' text
- Add explicit cursor-pointer class to brain emoji button
- Maintains grey text color consistent with configured model names
- Cleaner, less alarming visual for unconfigured state

* Add MCP server indicator with plug emoji and modal

- Create McpServerModal component based on existing McpServers component
- Add plug emoji (🔌) indicator on right side, opposite to brain emoji
- Show '0' when no servers connected, '1 (N)' when connected with N tools
- Fullscreen modal with MCP server configuration UI
- Support for single MCP server connection (foundation for multiple servers)
- Integrate with existing MCP tools logic and useMcp hook
- Clean layout with brain emoji on left, plug emoji on right

* Move number to left of plug emoji

- Change layout from '🔌 0' to '0 🔌'
- Number now appears before the plug icon for better visual balance
- Maintains same functionality and styling

* Keep MCP modal in React tree to maintain connection

- Replace conditional rendering with CSS visibility (hidden/block)
- Remove early return null when modal is closed
- McpConnection component stays mounted to preserve MCP server connection
- Modal is always in DOM but visually hidden when isOpen is false
- Prevents MCP disconnection when modal is dismissed

* Fix MCP tools count update in plug icon indicator

- Add onMcpToolsUpdate prop to ConversationThread interface
- Pass setMcpTools function from ChatApp down to ConversationThread
- Connect McpServerModal onToolsUpdate to parent state update
- Now plug icon will correctly show '1 (N)' when N tools are available
- Fixes issue where tool count remained at 0 despite successful connection

* Add cursor pointer to X button and click-outside-to-dismiss

- Add cursor-pointer class to modal X button
- Add onClick handler to backdrop overlay to close modal
- Add stopPropagation to modal content to prevent backdrop clicks
- Now modal can be dismissed by clicking outside or using X button

* Add cursor pointer and click-outside-to-dismiss to model selector modal

- Add cursor-pointer class to X button in ModelSelectionModal
- Add onClick handler to backdrop overlay to close modal
- Add stopPropagation to modal content to prevent backdrop clicks
- Consistent modal behavior between model selector and MCP server modals

* Implement multiple MCP servers support

- Completely rewrite McpServerModal to support multiple servers
- Add McpServer interface with id, url, enabled, and name fields
- Use localStorage 'mcpServers' array instead of single server URL
- Add server list UI with status badges, toggle, and delete buttons
- Add 'Add New Server' section at bottom with input and Add button
- Support enabling/disabling individual servers with Power/PowerOff icons
- Delete servers with Trash2 icon in top right of each server block
- Aggregate tools from all enabled servers for parent component
- Render multiple McpConnection components for enabled servers
- Update plug indicator to show correct server count
- Add debug information panel showing server and tool counts
- Handle server names using hostname from URL
- Each server gets unique connection state tracking by server ID

* Update plug indicator to show enabled vs total counts

- Change indicator format to show enabled/total for both servers and tools
- Format: 'X (Y servers) A (B tools)' where:
  - X = enabled servers, Y = total servers
  - A = tools from enabled servers, B = total tools from all servers
- Track tool counts per server in localStorage (mcpServerToolCounts)
- Persist tool counts even when servers are disabled
- Examples:
  - No servers: '0 (0 servers) 0 (0 tools)'
  - One disabled server with 2 tools: '0 (1 servers) 0 (2 tools)'
  - One enabled server with 2 tools: '1 (1 servers) 2 (2 tools)'
- Clean up tool counts when servers are deleted

* Update plug indicator format with comma separation

- Change format from '0 (1 servers) 0 (2 tools)' to '0 (1) servers, 0 (2) tools'
- Move words 'servers' and 'tools' outside brackets
- Add comma separation between server and tool counts
- More concise and readable format

* Change plug indicator format to use forward slashes

- Change from '0 (1) servers, 0 (2) tools' to '0/1 servers, 0/2 tools'
- Use forward slash format showing enabled/total for both servers and tools
- Cleaner, more compact visual representation
- Examples:
  - No servers: '0/0 servers, 0/0 tools'
  - One disabled server with 2 tools: '0/1 servers, 0/2 tools'
  - One enabled server with 2 tools: '1/1 servers, 2/2 tools'

* Soften modal background with radial gradient

- Replace solid black 50% opacity with radial gradient
- Center: 80% black (rgba(0,0,0,0.8))
- Corners: 70% black (rgba(0,0,0,0.7))
- Apply to both ModelSelectionModal and McpServerModal
- Creates softer, more visually appealing backdrop
- Remove bg-black bg-opacity-50 classes and use inline style

* Replace gradient with uniform 80% black background

- Remove radial gradient to fix banding issues
- Use solid 80% black background (rgba(0,0,0,0.8))
- Apply to both ModelSelectionModal and McpServerModal
- Clean, consistent backdrop without visual artifacts

* Implement OAuth callback support for MCP servers

- Add react-router-dom dependency for routing support
- Create OAuthCallback component with animated background and loading spinner
- Add routing to App.tsx with /oauth/callback route
- Match styling with main app using animated-bg-container
- Use onMcpAuthorization from use-mcp library for OAuth handling
- Library already handles multiple server differentiation via state parameter
- Each MCP server gets unique OAuth flow identified by state containing server URL
- Clean up unused imports and variables in McpServerModal

* Deploying to chat.use-mcp.dev

* Add Qwen 3 32B model under Groq provider

- Add qwen-3-32b model entry using qwen/qwen3-32b model ID
- Uses same Groq provider as Llama 3.3, sharing API token
- Model appears in selection modal between Llama and Claude
- Clean name 'Qwen 3 32B' for user interface

* Make gradient background fill entire content height

- Change from h-dvh to min-h-screen on main container
- Remove overflow-clip to allow content to expand
- Update inner containers to use min-h-screen for proper height
- Background gradient now extends with content rather than fixed to viewport
- Allows for scrolling when content exceeds viewport height

* Make gradient background repeat every 100vh

- Add background-size: 100% 100vh to fix gradient height to viewport
- Add background-repeat: repeat-y to tile gradient vertically
- Gradient pattern now repeats down the page as content grows
- Animation applies consistently to all repeated background tiles
- Creates seamless repeating pattern while maintaining hue rotation

* Doing some manual CSS hax for a change

* Update AGENT.md with chat UI development guidelines

- Add React Router and use-mcp to tech stack
- Document background animation best practices (hue-rotate, pseudo-elements)
- Modal patterns for UX (click-outside, cursor-pointer, backdrop styling)
- MCP server management (multiple servers, localStorage patterns, OAuth)
- State persistence guidelines (localStorage vs sessionStorage)
- UI indicator patterns (emoji-based, count formatting)
- Component organization for stateful elements
- Routing and OAuth callback implementation
- Performance considerations for animations and aggregation

* I am dum. CSS is smrt

* BG css tweaks

* Added a simple example server for the demo

* feat: Add reasoning token support with expandable thinking blocks

- Add reasoning field to AssistantMessage type
- Create ReasoningBlock component with truncate/expand functionality
- Add reasoning-capable models (Qwen QwQ, DeepSeek R1, Qwen 3 32B)
- Implement reasoning event handling in stream processing
- Enable reasoning format for Groq and Anthropic models
- Style reasoning blocks with grey border and reduced font size
- Display reasoning above assistant messages when available

The reasoning blocks show truncated thinking tokens by default and
expand on click to show full reasoning process from models like
Qwen3-32b that support step-by-step reasoning output.

* fix: Use extractReasoningMiddleware to properly parse thinking blocks

- Import extractReasoningMiddleware and wrapLanguageModel from AI SDK
- Wrap reasoning-capable models with extractReasoningMiddleware
- Use 'think' as tagName to parse <think> XML blocks from models
- Enable startWithReasoning option to handle models missing reasoning tags
- Extract reasoning from result.reasoning after stream completes
- Remove manual reasoning event handling and provider-specific config

This fixes the issue where thinking blocks appeared as raw XML tags
instead of parsed reasoning content. The middleware automatically
extracts reasoning from <think> tags and exposes it via result.reasoning.

* Added a simpe Hono server to test

* fix: Remove thinking XML tags from main message content

- Add regex-based cleaning to remove <think>...</think> tags from display text
- Handle both closed and unclosed think tags in streaming content
- Apply cleaning only for reasoning-capable models to avoid unnecessary processing
- Update conversation content with cleaned response instead of raw response

This ensures thinking tags are extracted for reasoning display but don't
appear in the main message content, providing a clean user experience.

* fix: Improve thinking tag removal with more aggressive cleaning

- Add multiple regex passes to handle various think tag scenarios
- Remove standalone <think> and </think> tags that might remain
- Clean leading whitespace after tag removal
- Add debug logging to track text cleaning process
- Handle streaming cases where tags appear before closing tags arrive

This provides more robust cleaning to ensure no think tags appear
in the final message content during streaming scenarios.

* fix: Add detailed debugging and use result.text for cleaned content

- Add debug logging to track aiResponse vs result.text content
- Use result.text from extractReasoningMiddleware for final content
- This should provide the properly cleaned text without thinking tags
- Comment out unused sidebar and edit functionality to fix TS errors

The result.text should contain content that has been automatically
cleaned by the extractReasoningMiddleware, while result.reasoning
contains the extracted thinking content.

* fix: Capture reasoning events during streaming instead of from result

- Add back reasoning variable to track content during streaming
- Handle reasoning events from extractReasoningMiddleware in stream processing
- Build up reasoning content from individual reasoning textDelta events
- Remove dependency on result.reasoning which wasn't being populated
- Add reasoning to assistant message after stream completes

The logs showed reasoning events were coming through correctly but we
weren't capturing them. This fixes the issue by collecting reasoning
content during streaming as the events arrive.

* debug: Add more detailed logging for reasoning event handling

- Add debug logs inside reasoning event handler to see if it's being triggered
- Log reasoning content length as it's being collected
- Add final reasoning content summary at end of stream
- Log why reasoning isn't being added if conditions aren't met
- Cast event to any to avoid potential TypeScript issues

This will help identify why reasoning events aren't being captured
despite appearing in the event stream logs.

* fix: Clean think tags from reasoning content before display

- Add cleaning logic to remove <think> and </think> tags from reasoning
- Trim whitespace after tag removal for clean display
- Add debug logging to show before/after cleaning
- The middleware extracts reasoning but includes the original tags

This ensures the reasoning blocks show clean thinking content without
the XML tags that were being captured along with the reasoning text.

* feat: Implement live reasoning streaming with timing display

- Update ReasoningBlock to start expanded and show live reasoning content
- Add timing tracking with start/end timestamps for reasoning duration
- Auto-collapse reasoning blocks after completion with 500ms delay
- Show timing summary (e.g. 'Thought for 0.4s') instead of content when collapsed
- Add streaming cursor animation and real-time content updates
- Update types to support reasoning timing and streaming state
- Stream reasoning content live as tokens arrive during thinking phase

This provides a much better UX where users can see the model thinking
in real-time, then get a clean timing summary after completion.

* fix: Create assistant message immediately when reasoning starts

- Create assistant message as soon as first reasoning event arrives
- This ensures reasoning block is visible from the beginning of thinking
- Prevent duplicate message creation in text-delta handler
- Move reasoning end time logic to text-delta start (when thinking finishes)

This fixes the issue where reasoning blocks weren't appearing because
the assistant message was only created after reasoning completed.

* fix: Remove delay for instant reasoning block collapse

- Remove 500ms setTimeout delay when reasoning finishes
- Reasoning block now collapses immediately when response starts
- Creates smoother transition from thinking to response phase
- Eliminates jarring delay between reasoning end and collapse

The reasoning block now collapses instantly as soon as the model
starts generating the actual response, providing better UX flow.

* feat: Add sliding window effect for streaming reasoning text

- Use overflow:hidden + whitespace:nowrap to prevent line breaks
- Apply justify-end flexbox to push content to the right
- New tokens push older ones out to the left edge and hide them
- Creates smooth sliding window effect showing only recent tokens
- Only applies during streaming, keeps normal wrap after completion

This creates a nice visual effect where you can see the latest reasoning
tokens flowing in from right to left as the model thinks.

* Add debug logging and Accept headers for MCP transport debugging

- Added extensive debug logging to transport creation and connection flows
- Added proper Accept header (application/json, text/event-stream) to transport options
- Fixed scroll jittering during streaming with instant scroll behavior
- Investigating HTTP transport 'Not connected' errors and SSE connection hanging

* Add httpOnly option to disable SSE fallback for debugging

- Added httpOnly option to UseMcpOptions to skip SSE fallback
- Updated all HTTP transport failure paths to respect httpOnly flag
- Temporarily enabled httpOnly in chat UI for streamable HTTP debugging
- Updated AGENT.md to require frequent commits after changes

* Replace httpOnly with transportType option and add UI controls

- Replace httpOnly boolean with transportType ('auto'/'http'/'sse') option
- Add transport type cycling button next to 'Add New Server'
- Add blue transport badge next to connected server status
- Save transport preference to localStorage
- Update connection orchestration to handle sse-only and http-only modes
- Remove explicit fallback messaging since orchestration now controls it

* Fix tool results being mixed into thinking blocks

- Add missing tool-result event handling in useStreamResponse
- Tool results now appear as separate ToolResultMessage components
- Prevents tool response content from being incorrectly added to reasoning content
- Maintains proper message order: thinking → tool call → tool result → assistant response

* Fix duplicate tool results and post-tool reasoning being hidden

- Add deduplication logic for tool results to prevent duplicates
- Detect when tool results have been processed and convert subsequent reasoning events to text content
- This fixes the issue where the final assistant response was hidden in the thinking block
- Tool results should now appear once and final response should appear as separate text

* Fix message ordering and prevent content duplication in thinking/final response

- Collect post-tool reasoning content separately instead of processing immediately
- Process collected content as final assistant response after stream completes
- This ensures proper message order: thinking → tool call → tool result → final response
- Prevents duplication of thinking content in final response

* Add intelligent content filtering to extract clean final answer

- Extract only the final answer from post-tool reasoning content
- Filter out thinking/reasoning patterns to prevent duplication
- Use regex matching and line filtering to identify clean response content
- Skip content that appears to be thinking rather than final answer
- Limit response length to prevent long thinking content from appearing

* Fix duplicate assistant messages by updating existing message

- Check if there's already an assistant message with only reasoning content
- Update existing assistant message with final content instead of creating new one
- Add duplicate detection to prevent multiple messages with same content
- Ensures only one assistant response appears after tool calls

* Fix message ordering - create final response at end instead of updating existing

- Remove logic that updates existing assistant message
- Always create new final response message at end of conversation
- This ensures proper order: thinking → tool call → tool result → final response
- Still prevents duplicates by checking existing content

* Make thinking block collapse immediately when tool call starts

- End reasoning phase as soon as first tool-call event is detected
- Set reasoningEndTime and stop reasoning streaming immediately
- Creates linear flow: thinking expands → tool call (thinking collapses) → tool result → final response
- More aggressive/responsive UX that doesn't wait for final response to collapse thinking

* Fix reasoning/content separation and eliminate empty message divs

- Remove extractReasoningMiddleware as it expects <think> tags but API sends reasoning fields directly
- Ensure reasoning and content tokens create separate assistant messages
- Filter empty assistant messages at conversation level to prevent empty divs
- Add deduplication for tool results to prevent duplicates
- Only render content div when message has actual content

* Clean up debug logging in useStreamResponse.ts

- Remove all debugLog calls and debug infrastructure
- Simplify error logging by removing verbose prefixes
- Fix unused options parameter to eliminate warnings
- Clean up formatting and extra blank lines

* Add targeted debug logging for message operations

- Add debugMessages helper function that logs with [Messages] prefix
- Log when new messages are added to conversation (not updates)
- Log reasoning assistant messages, tool calls, tool results, and content messages
- Log stream processing completion and function completion
- Debug logging enabled with localStorage.setItem('USE_MCP_DEBUG', 'true')

* Enhance debug logging to show complete conversation state

- Show entire messages array after each new message addition
- Include message index, role, content/reasoning status, and tool info
- Add final conversation state with content/reasoning lengths
- Provides complete visibility into data structure evolution

* Simplify debug logging to show raw JSON messages

- Replace complex message summaries with JSON.stringify(conv.messages)
- Provides direct, unfiltered view of message data structure
- Easier to inspect actual data and debug issues

* Remove all duplicate detection logic

- Remove existingToolCall and existingToolResult checks
- Add every API event as a new message regardless of duplicates
- Provides complete unfiltered log of all API data after middleware
- Useful for debugging and understanding raw data flow

* Branching off

* fixing prettier

* lfg manual style

* wip, changing the logic in useStreamResponse

* wip, at least prettier likes it

* Big sigh, finally getting control of my markup

* Starting to realise how dumb the vibecoded UI was oops

* Ok turns out I can be dumb too

* Handling reasoning then messages at least

* tool responses are easy now too

* visual tweaks

* Only updating one conversation at a time

* Ok _much_ better timing and just me understanding this stuff

* Almost ready

* fin

* Default transport type to HTTP instead of auto

* Move transport toggle to left and make it only affect new servers

- Add newServerTransportType state for next server to be added
- Move toggle to left side directly after 'Add New Server' label
- Add transportType to McpServer interface to store per-server transport
- Update connections to use server-specific transport type
- Change toggle styling to rounded-full (pill style)

* Round corners more on blue connected server transport type badge

Change from rounded-md to rounded-lg for better visual consistency

* Tighten markdown spacing in chat messages

- Add custom prose-tight CSS class to reduce excessive spacing
- Reduce line height from 1.75 to 1.5 for better readability
- Decrease heading margins (1rem top, 0.5rem bottom)
- Reduce paragraph and list item spacing
- Apply tighter spacing to both user and assistant messages

* removing dupe server

* Forcing parsed reasoning on groq

* Added inline in-conversation errors

* Add `preventAutoAuth` (to chat example) (#18)

* feat: add preventAutoAuth option to prevent automatic authentication popups

- Add preventAutoAuth option to UseMcpOptions to control automatic popup behavior
- Introduce pending_auth state for when auth is required but auto-popup is prevented
- Enhance authentication flow to check for existing tokens before triggering auth
- Add prepareAuthorizationUrl() helper method in BrowserOAuthClientProvider
- Update authenticate() method to handle pending_auth state transitions
- Improve chat UI components to handle new authentication states gracefully
- Add clear call-to-action UI with primary popup button and fallback new tab link
- Maintain backward compatibility - existing code continues to work unchanged

This prevents browser popup blockers from interfering with authentication flows
when users return to pages with MCP servers, providing better UX and control.

* Fixing couple of things

---------

Co-authored-by: Glen Maddern <glen@glenmaddern.com>

* Chat example cooked and ready

* I aint got time for this typescript nonsense rn

* fixing pnpm lock

* prettier

---------

Co-authored-by: Glen Maddern <glen@glenmaddern.com>
2025-07-02 16:24:03 +10:00
Glen Maddern
c189d5af65 0.0.16 v0.0.16 2025-07-02 11:12:36 +10:00
Glen Maddern
eb9432aed2 Make the SDK a normal dependency if it's external to the build 2025-07-02 11:12:31 +10:00
Glen Maddern
feeaade511 0.0.15 v0.0.15 2025-07-02 10:44:44 +10:00
Glen Maddern
f770d57e0a
Bumping to SDK v1.13.2 (#17)
* fix(use-mcp): connect to mcp fails with handleMessage function

* Upping the SDK version cooks every test

* checking out neighbouring SDK

* Getting more random port collisions locally :/

I will fix this properly... eventually.

* Running `wrangler types` on example servers

* Updated to SDK v1.13.2

* prettier

---------

Co-authored-by: ksankaran <kv.coder@gmail.com>
Co-authored-by: Glen Maddern <glen@glenmaddern.com>
2025-07-02 10:42:47 +10:00
Glen Maddern
d80a7e68b0
told amp to make my tests better (#14)
Co-authored-by: Glen Maddern <gmaddern@gmaddern.c.groq-143208.internal>
2025-07-01 15:03:09 +10:00
Glen Maddern
0ea0bc48c6
Oauth tests (#13)
* Moving the non-authed cfagents tests to /public

* Added OAuth CF Agents tests

---------

Co-authored-by: Glen Maddern <glen@glenmaddern.com>
2025-07-01 13:26:26 +10:00
Glen Maddern
fe65d50ec3
Fixing /sse support (#12)
* /sse still not working

* Add transport type selector to inspector UI and comprehensive transport testing

- Add transport type dropdown to inspector UI (auto, HTTP, SSE) with session storage persistence
- Update test framework to support transport type selection in test scenarios
- Add comprehensive test cases covering:
  * Working /mcp endpoints with auto and HTTP transports
  * SSE endpoint with SSE transport (expected to pass)
  * SSE endpoint with auto transport (expected to fail - demonstrates current fallback issue)
- Test structure now provides clear visibility into transport-specific behavior
- All tests properly named and categorized for easy identification of failing scenarios

* Gearing up to "make amp do it"

* fix: improve SSE fallback logic in auto transport mode

- Fix issue where SSE fallback was not attempted when HTTP transport failed
- Specific error types (404, 405, CORS) now correctly trigger SSE fallback
- Allow SSE fallback even when component state is 'failed' from previous attempts
- Maintain proper error handling for non-fallback HTTP errors
- All 6 transport scenarios now pass integration tests

The core issue was that failConnection() was being called for HTTP errors
before returning 'fallback', which set the component state to 'failed' and
prevented the orchestration logic from attempting SSE fallback. Now only
specific HTTP errors that should trigger fallback avoid calling failConnection
immediately, allowing the SSE transport to be attempted as expected.

---------

Co-authored-by: Glen Maddern <glen@glenmaddern.com>
2025-07-01 12:14:32 +10:00
Glen Maddern
7f019fed7f
Adding cf/agents tests (#11)
* Cloning demo repo

* added test for agents/mcp

---------

Co-authored-by: Glen Maddern <glen@glenmaddern.com>
2025-06-30 21:51:49 +10:00
Glen Maddern
ace3220fca
Merge pull request #10 from modelcontextprotocol/e2e-testing
E2E testing
2025-06-30 21:07:45 +10:00
Glen Maddern
6a3130a075 0.0.14 v0.0.14 2025-06-27 22:37:42 +10:00
Glen Maddern
effb28af19 Reworking auth flow. Still buggy.
'auto' now works for http servers, sse needs 'sse' setting.
2025-06-27 22:37:11 +10:00
Glen Maddern
8276b337fe 0.0.13 v0.0.13 2025-06-27 16:28:15 +10:00
Glen Maddern
85e21784fd Forgot I marked the SDK as external so it needs to be a normal dep 2025-06-27 16:28:10 +10:00
Glen Maddern
31d3108225 0.0.12 v0.0.12 2025-06-27 16:23:33 +10:00
Glen Maddern
381001eb74 Fixing pnpm conflict 2025-06-27 16:23:30 +10:00
Glen Maddern
fa0180330f 0.0.11 v0.0.11 2025-06-27 16:12:26 +10:00
Glen Maddern
84b58759ed updated readme 2025-06-27 16:12:00 +10:00
Glen Maddern
a225929ae2 Prettier changes 2025-06-27 16:09:36 +10:00
Glen Maddern
b326e36ccc Adding transportType to API 2025-06-27 16:08:56 +10:00
Glen Maddern
ef08e97a5f 0.0.10 v0.0.10 2025-06-26 21:24:03 +10:00
Glen Maddern
2b8b3773b5 Merge branch 'sanitise-urls' 2025-06-26 21:23:10 +10:00