feat: deep linking implementation for ToolHive Studio#953
Open
feat: deep linking implementation for ToolHive Studio#953
Conversation
added 2 commits
October 2, 2025 10:40
- Add deep link handler and control server - Add deep link React components and hooks - Update main window and toolhive manager for deep linking - Add comprehensive documentation - Fix linting errors (unused variables, require imports)
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR implements deep linking functionality for ToolHive Studio, enabling one-click navigation from external sources (error messages, documentation) directly to the server installation page. The implementation includes a custom toolhive:// protocol handler, HTTP control server for programmatic navigation, and comprehensive UI integration.
Key changes include:
- Custom protocol registration for
toolhive://URLs with cross-platform support - HTTP control server running on localhost:51234 for programmatic navigation when the app is running
- React hooks and UI components for handling deep link navigation and automatically opening installation dialogs
Reviewed Changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| main/src/main.ts | Adds deep link protocol registration, IPC handlers, and control server lifecycle management |
| main/src/deep-link.ts | Core deep linking logic with URL parsing and link generation utilities |
| main/src/control-server.ts | HTTP control endpoint for programmatic navigation with health checks |
| renderer/src/common/hooks/use-deep-link.tsx | React hook for handling deep link events and router navigation |
| renderer/src/routes/__root.tsx | Initializes deep link handling at the root level |
| renderer/src/routes/(registry)/registry_.$name.tsx | Enhanced to auto-open install dialog when navigating via deep links |
| preload/src/preload.ts | Exposes deep link API to renderer process |
| main/src/tests/deep-link.test.ts | Comprehensive unit tests for URL parsing and link generation |
| docs/deep-linking.md | Complete documentation with usage examples and API reference |
Comments suppressed due to low confidence (2)
renderer/src/features/deep-link/components/deep-link-generator.tsx:1
- This catch block appears to be in the wrong file. It contains server response code but this is a React component file. This code should be in main/src/control-server.ts instead.
import { useState } from 'react'
main/src/toolhive-manager.ts:1
- [nitpick] The ternary operator formatting is inconsistent with the existing codebase pattern. The closing parenthesis on line 32 should align with the opening condition on line 18 for better readability.
import { spawn } from 'node:child_process'
added 3 commits
October 2, 2025 10:48
- Format docs/deep-linking.md with prettier - Remove unused deep-link-generator component - Add ignoreExportsUsedInFile config to knip - Mock electron and electron-log in vitest setup to fix test failures
added 6 commits
October 2, 2025 11:30
- Add @public JSDoc tags to exported functions in control-server.ts to tell knip they are public API - Add deepLink API mock to vitest.setup.ts to fix registry tests
- Use standard URLSearchParams instead of router's useSearch hook - Avoids test failures due to missing search params schema - All tests now pass (483 passed)
broken in check fixes...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deep Linking Implementation for ToolHive Studio
Closes #956
🎯 Goal
Enable one-click navigation from error messages or documentation directly to ToolHive Studio's server installation page, providing a seamless UX when handling missing secrets or configuration issues.
Use Case
When an MCP server reports a missing secret or configuration issue, provide a clickable link that:
UX Improvement
Before: User sees error → Must manually open Studio → Navigate to Registry → Search for server → Click install (5 steps)
After: User sees error → Clicks link → Done! (1 click) ✨
📋 Changes Overview
New Files Created
Core Implementation
main/src/deep-link.ts- Core deep linking logictoolhive://URL scheme)main/src/control-server.ts- HTTP control endpoint for programmatic navigationhttp://127.0.0.1:51234GET /health- Health check endpointPOST /navigate- Navigate with JSON bodyGET /navigate?url=<encoded>- Navigate with query parameterrenderer/src/common/hooks/use-deep-link.tsx- React hook for deep link navigationTesting & Documentation
main/src/tests/deep-link.test.ts- Comprehensive unit testsdocs/deep-linking.md- Complete user documentationModified Files
main/src/main.tsChanges:
handleDeepLink,registerProtocol,generateInstallServerLink,generateCliCommand)toolhive://protocol on app startupopen-urlevent handler (macOS deep link support)second-instanceevent handler (Windows/Linux deep link support)deep-link:generate-install-link- Generate deep link URLsdeep-link:generate-cli-command- Generate equivalent CLI commandsimport.meta.envinstead ofprocess.envfor Sentry DSNpreload/src/preload.tsChanges:
deepLink.onNavigate()listener registrationdeepLink.generateInstallLink()methoddeepLink.generateCliCommand()methodrenderer/src/routes/__root.tsxChanges:
useDeepLinkhook at the root levelrenderer/src/routes/(registry)/registry_.$name.tsxChanges:
serversearch parameter in URLConfiguration Files
.gitignore- Added.vscode/to ignore VS Code settingsknip.ts- AddedignoreExportsUsedInFileconfig for test filesvitest.setup.ts- Added mocks forelectronandelectron-logto fix test execution🎯 Functionality Implemented
1. Custom URL Protocol (
toolhive://)install-server- Navigate to server installation page with auto-opening dialogExample:
2. HTTP Control Endpoint
When ToolHive Studio is running, a local HTTP server on
http://127.0.0.1:51234provides programmatic navigation:Endpoints:
GET /health- Check if control server is runningPOST /navigate- Navigate using JSON body{"url": "toolhive://..."}GET /navigate?url=<encoded-url>- Navigate using query parameterExample:
3. Link & CLI Command Generation
Helper functions to generate deep links and equivalent CLI commands:
4. Automatic Dialog Opening
When navigating via deep link, the registry page automatically:
🧪 Testing
Deep link from terminal:
open "toolhive://install-server?server=github"HTTP control endpoint:
App not running: Deep link launches app and navigates
App already running: Deep link focuses app and navigates
🎨 User Experience
The implementation focuses on simplicity and reliability:
Result: 5 manual steps → 1 click! ✨