Inspector looking good

This commit is contained in:
Glen Maddern 2025-06-10 17:11:27 +10:00
commit 61ab6f71ea
5 changed files with 171 additions and 1569 deletions

View file

@ -29,7 +29,7 @@
"rehype-highlight": "^7.0.2", "rehype-highlight": "^7.0.2",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"tailwindcss": "^4.0.14", "tailwindcss": "^4.0.14",
"use-mcp": "link:..", "use-mcp": "link:../..",
"workers-ai-provider": "^0.1.3" "workers-ai-provider": "^0.1.3"
}, },
"devDependencies": { "devDependencies": {

View file

@ -5,9 +5,11 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc -b && vite build", "build": "tsc -b && pnpm run build:only",
"build:only": "vite build",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview" "preview": "vite preview",
"deploy": "pnpm run build:only && wrangler deploy"
}, },
"dependencies": { "dependencies": {
"@tailwindcss/vite": "^4.0.14", "@tailwindcss/vite": "^4.0.14",
@ -15,10 +17,12 @@
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"tailwindcss": "^4.0.14", "tailwindcss": "^4.0.14",
"use-mcp": "link:.." "use-mcp": "link:../.."
}, },
"devDependencies": { "devDependencies": {
"@cloudflare/vite-plugin": "^1.5.0",
"@eslint/js": "^9.21.0", "@eslint/js": "^9.21.0",
"@tailwindcss/typography": "^0.5.16",
"@types/react": "^19.0.10", "@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4", "@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4", "@vitejs/plugin-react": "^4.3.4",
@ -29,7 +33,8 @@
"prettier": "^3.5.3", "prettier": "^3.5.3",
"typescript": "~5.7.2", "typescript": "~5.7.2",
"typescript-eslint": "^8.24.1", "typescript-eslint": "^8.24.1",
"vite": "^6.2.0" "vite": "^6.2.0",
"wrangler": "^4.19.1"
}, },
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977" "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
} }

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
import { useState, useRef, useEffect } from 'react' import { useState, useRef, useEffect } from 'react'
import { useMcp, type Tool } from 'use-mcp/react' import { useMcp, type Tool } from 'use-mcp/react'
import { Settings, Info } from 'lucide-react'
// MCP Connection wrapper that only renders when active // MCP Connection wrapper that only renders when active
function McpConnection({ function McpConnection({
@ -42,7 +42,7 @@ export function McpServers({
return sessionStorage.getItem('mcpServerUrl') || '' return sessionStorage.getItem('mcpServerUrl') || ''
}) })
const [isActive, setIsActive] = useState(false) const [isActive, setIsActive] = useState(false)
const [showSettings, setShowSettings] = useState(false)
const [connectionData, setConnectionData] = useState<any>({ const [connectionData, setConnectionData] = useState<any>({
state: 'not-connected', state: 'not-connected',
tools: [], tools: [],
@ -177,18 +177,8 @@ export function McpServers({
return ( return (
<section className="rounded-lg bg-white p-4 border border-zinc-200"> <section className="rounded-lg bg-white p-4 border border-zinc-200">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center"> <span className="text-sm font-semibold">MCP Servers</span>
<span className="text-sm font-semibold">MCP Servers</span> {getStatusBadge()}
<div className="ml-2">
<Info size={14} className="text-gray-400" />
</div>
</div>
<button
className="rounded-md border border-gray-200 p-1 hover:bg-gray-50"
onClick={() => setShowSettings(!showSettings)}
>
<Settings size={16} className="text-gray-500" />
</button>
</div> </div>
<p className="text-gray-500 text-xs mt-1 mb-3"> <p className="text-gray-500 text-xs mt-1 mb-3">
@ -202,16 +192,12 @@ export function McpServers({
{getStatusBadge()} {getStatusBadge()}
</div> </div>
{error && state === 'failed' && (
<div className="text-xs text-red-600 p-2 bg-red-50 rounded border">
{error}
</div>
)}
<div className="space-y-2">
<div className="flex gap-2">
<input <input
type="text" type="text"
className="w-full p-2 border border-gray-200 rounded text-sm placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-blue-300" className="flex-1 p-2 border border-gray-200 rounded text-sm placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-blue-300"
placeholder="Enter MCP server URL" placeholder="Enter MCP server URL"
value={serverUrl} value={serverUrl}
onChange={(e) => { onChange={(e) => {
@ -225,14 +211,14 @@ export function McpServers({
{state === 'ready' || {state === 'ready' ||
(isActive && state !== 'not-connected' && state !== 'failed') ? ( (isActive && state !== 'not-connected' && state !== 'failed') ? (
<button <button
className="w-full px-3 py-2 bg-orange-100 hover:bg-orange-200 text-orange-900 rounded text-sm font-medium" className="px-4 py-2 bg-orange-100 hover:bg-orange-200 text-orange-900 rounded text-sm font-medium whitespace-nowrap"
onClick={handleDisconnect} onClick={handleDisconnect}
> >
Disconnect Disconnect
</button> </button>
) : ( ) : (
<button <button
className="w-full bg-blue-600 hover:bg-blue-700 text-white rounded py-2 px-4 text-sm font-medium disabled:opacity-50" className="bg-blue-600 hover:bg-blue-700 text-white rounded py-2 px-4 text-sm font-medium disabled:opacity-50 whitespace-nowrap"
onClick={handleConnect} onClick={handleConnect}
disabled={isActive || !serverUrl.trim()} disabled={isActive || !serverUrl.trim()}
> >
@ -265,7 +251,7 @@ export function McpServers({
<h3 className="font-medium text-sm mb-3"> <h3 className="font-medium text-sm mb-3">
Available Tools ({tools.length}) Available Tools ({tools.length})
</h3> </h3>
<div className="border border-gray-200 rounded p-4 bg-gray-50 max-h-96 overflow-y-auto space-y-3"> <div className="border border-gray-200 rounded p-4 bg-gray-50 space-y-3">
{tools.map((tool: Tool, index: number) => ( {tools.map((tool: Tool, index: number) => (
<div <div
key={index} key={index}
@ -294,49 +280,47 @@ export function McpServers({
)} )}
{/* Debug Log */} {/* Debug Log */}
{showSettings && ( <div>
<div> <label className="font-medium text-xs block mb-2">Debug Log</label>
<label className="font-medium text-xs block mb-2">Debug Log</label> <div
<div ref={logRef}
ref={logRef} className="border border-gray-200 rounded p-2 bg-gray-50 h-32 overflow-y-auto font-mono text-xs"
className="border border-gray-200 rounded p-2 bg-gray-50 h-32 overflow-y-auto font-mono text-xs" >
> {log.length > 0 ? (
{log.length > 0 ? ( log.map((entry: any, index: number) => (
log.map((entry: any, index: number) => ( <div
<div key={index}
key={index} className={`py-0.5 ${
className={`py-0.5 ${ entry.level === 'debug'
entry.level === 'debug' ? 'text-gray-500'
? 'text-gray-500' : entry.level === 'info'
: entry.level === 'info' ? 'text-blue-600'
? 'text-blue-600' : entry.level === 'warn'
: entry.level === 'warn' ? 'text-orange-600'
? 'text-orange-600' : 'text-red-600'
: 'text-red-600' }`}
}`} >
> [{entry.level}] {entry.message}
[{entry.level}] {entry.message} </div>
</div> ))
)) ) : (
) : ( <div className="text-gray-400">No log entries yet</div>
<div className="text-gray-400">No log entries yet</div>
)}
</div>
{connectionData?.state !== 'not-connected' && (
<button
onClick={() => {
connectionData?.clearStorage()
if (isActive) {
handleDisconnect()
}
}}
className="text-xs text-orange-600 hover:text-orange-800 hover:underline mt-2"
>
Clear stored authentication
</button>
)} )}
</div> </div>
)} {connectionData?.state !== 'not-connected' && (
<button
onClick={() => {
connectionData?.clearStorage()
if (isActive) {
handleDisconnect()
}
}}
className="text-xs text-orange-600 hover:text-orange-800 hover:underline mt-2"
>
Clear stored authentication
</button>
)}
</div>
</div> </div>
{/* Only render the actual MCP connection when active */} {/* Only render the actual MCP connection when active */}

View file

@ -5,7 +5,7 @@
{ {
"$schema": "node_modules/wrangler/config-schema.json", "$schema": "node_modules/wrangler/config-schema.json",
"name": "inspector-use-mcp", "name": "inspector-use-mcp",
"route": "inspector.use-mcp-.dev", "route": "inspector.use-mcp.dev",
// "main": "api/index.ts", // "main": "api/index.ts",
"compatibility_date": "2025-02-07", "compatibility_date": "2025-02-07",
// "ai": { // "ai": {
@ -13,7 +13,6 @@
// }, // },
"assets": { "assets": {
"not_found_handling": "single-page-application", "not_found_handling": "single-page-application",
"binding": "ASSETS",
"directory": "dist/client" "directory": "dist/client"
}, },
"observability": { "observability": {