1- import React , { useState } from "react" ;
1+ import React , { useEffect , useState } from "react" ;
22import { Download , Upload , FileText , Loader2 , Info , Network , Settings2 } from "lucide-react" ;
33import { Button } from "@/components/ui/button" ;
44import { Card } from "@/components/ui/card" ;
@@ -15,6 +15,10 @@ interface MCPImportExportProps {
1515 * Callback for error messages
1616 */
1717 onError : ( message : string ) => void ;
18+ /**
19+ * Callback for success/info messages
20+ */
21+ onSuccess : ( message : string ) => void ;
1822}
1923
2024/**
@@ -23,11 +27,31 @@ interface MCPImportExportProps {
2327export const MCPImportExport : React . FC < MCPImportExportProps > = ( {
2428 onImportCompleted,
2529 onError,
30+ onSuccess,
2631} ) => {
2732 const [ importingDesktop , setImportingDesktop ] = useState ( false ) ;
2833 const [ importingJson , setImportingJson ] = useState ( false ) ;
2934 const [ importScope , setImportScope ] = useState ( "local" ) ;
3035
36+ const [ mcpServeRunning , setMcpServeRunning ] = useState ( false ) ;
37+ const [ mcpServeChecking , setMcpServeChecking ] = useState ( false ) ;
38+
39+ const refreshMcpServeStatus = async ( ) => {
40+ try {
41+ const statuses = await api . mcpGetServerStatus ( ) ;
42+ setMcpServeRunning ( Boolean ( statuses [ "claude-code" ] ?. running ) ) ;
43+ } catch {
44+ // If status fails, don't block UX; just assume stopped
45+ setMcpServeRunning ( false ) ;
46+ }
47+ } ;
48+
49+ useEffect ( ( ) => {
50+ refreshMcpServeStatus ( ) ;
51+ const handle = window . setInterval ( refreshMcpServeStatus , 2000 ) ;
52+ return ( ) => window . clearInterval ( handle ) ;
53+ } , [ ] ) ;
54+
3155 /**
3256 * Imports servers from Claude Desktop
3357 */
@@ -39,23 +63,18 @@ export const MCPImportExport: React.FC<MCPImportExportProps> = ({
3963
4064 // Show detailed results if available
4165 if ( result . servers && result . servers . length > 0 ) {
42- const successfulServers = result . servers . filter ( s => s . success ) ;
4366 const failedServers = result . servers . filter ( s => ! s . success ) ;
4467
45- if ( successfulServers . length > 0 ) {
46- const successMessage = `Successfully imported: ${ successfulServers . map ( s => s . name ) . join ( ", " ) } ` ;
47- onImportCompleted ( result . imported_count , result . failed_count ) ;
48- // Show success details
49- if ( failedServers . length === 0 ) {
50- onError ( successMessage ) ;
51- }
52- }
68+ // Always call onImportCompleted for server list refresh and count-based toast
69+ onImportCompleted ( result . imported_count , result . failed_count ) ;
5370
71+ // Only show detailed error messages for failed servers (onImportCompleted already shows success)
5472 if ( failedServers . length > 0 ) {
5573 const failureDetails = failedServers
5674 . map ( s => `${ s . name } : ${ s . error || "Unknown error" } ` )
5775 . join ( "\n" ) ;
58- onError ( `Failed to import some servers:\n${ failureDetails } ` ) ;
76+ console . warn ( "Failed to import some servers:" , failureDetails ) ;
77+ // Don't call onError here - onImportCompleted already handles the toast
5978 }
6079 } else {
6180 onImportCompleted ( result . imported_count , result . failed_count ) ;
@@ -152,11 +171,29 @@ export const MCPImportExport: React.FC<MCPImportExportProps> = ({
152171 */
153172 const handleStartMCPServer = async ( ) => {
154173 try {
155- await api . mcpServe ( ) ;
156- onError ( "Claude Code MCP server started. You can now connect to it from other applications." ) ;
174+ setMcpServeChecking ( true ) ;
175+ const message = await api . mcpServe ( ) ;
176+ await refreshMcpServeStatus ( ) ;
177+ onSuccess ( message ) ;
157178 } catch ( error ) {
158179 console . error ( "Failed to start MCP server:" , error ) ;
159180 onError ( "Failed to start Claude Code as MCP server" ) ;
181+ } finally {
182+ setMcpServeChecking ( false ) ;
183+ }
184+ } ;
185+
186+ const handleStopMCPServer = async ( ) => {
187+ try {
188+ setMcpServeChecking ( true ) ;
189+ const message = await api . mcpStop ( ) ;
190+ await refreshMcpServeStatus ( ) ;
191+ onSuccess ( message ) ;
192+ } catch ( error ) {
193+ console . error ( "Failed to stop MCP server:" , error ) ;
194+ onError ( "Failed to stop Claude Code MCP server" ) ;
195+ } finally {
196+ setMcpServeChecking ( false ) ;
160197 }
161198 } ;
162199
@@ -305,20 +342,39 @@ export const MCPImportExport: React.FC<MCPImportExportProps> = ({
305342 < Network className = "h-5 w-5 text-green-500" />
306343 </ div >
307344 < div className = "flex-1" >
308- < h4 className = "text-sm font-medium" > Use Claude Code as MCP Server</ h4 >
345+ < div className = "flex items-center justify-between gap-3" >
346+ < h4 className = "text-sm font-medium" > Use Claude Code as MCP Server</ h4 >
347+ < div className = "text-xs text-muted-foreground" >
348+ { mcpServeChecking ? "Checking…" : mcpServeRunning ? "Running" : "Stopped" }
349+ </ div >
350+ </ div >
309351 < p className = "text-xs text-muted-foreground mt-1" >
310352 Start Claude Code as an MCP server that other applications can connect to
311353 </ p >
312354 </ div >
313355 </ div >
314- < Button
315- onClick = { handleStartMCPServer }
316- variant = "outline"
317- className = "w-full gap-2 border-green-500/20 hover:bg-green-500/10 hover:text-green-600 hover:border-green-500/50"
318- >
319- < Network className = "h-4 w-4" />
320- Start MCP Server
321- </ Button >
356+
357+ { mcpServeRunning ? (
358+ < Button
359+ onClick = { handleStopMCPServer }
360+ variant = "outline"
361+ className = "w-full gap-2 border-red-500/20 hover:bg-red-500/10 hover:text-red-600 hover:border-red-500/50"
362+ disabled = { mcpServeChecking }
363+ >
364+ < Network className = "h-4 w-4" />
365+ Stop MCP Server
366+ </ Button >
367+ ) : (
368+ < Button
369+ onClick = { handleStartMCPServer }
370+ variant = "outline"
371+ className = "w-full gap-2 border-green-500/20 hover:bg-green-500/10 hover:text-green-600 hover:border-green-500/50"
372+ disabled = { mcpServeChecking }
373+ >
374+ < Network className = "h-4 w-4" />
375+ Start MCP Server
376+ </ Button >
377+ ) }
322378 </ div >
323379 </ Card >
324380 </ div >
0 commit comments