mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-06 03:08:42 +02:00
refactor: better claude integration
This commit is contained in:
@@ -1056,7 +1056,6 @@ export default function Home() {
|
||||
onExtensionManagementDialogOpen={setExtensionManagementDialogOpen}
|
||||
searchQuery={searchQuery}
|
||||
onSearchQueryChange={setSearchQuery}
|
||||
crossOsUnlocked={crossOsUnlocked}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full mt-2.5">
|
||||
|
||||
@@ -177,7 +177,6 @@ type Props = {
|
||||
onExtensionManagementDialogOpen: (open: boolean) => void;
|
||||
searchQuery: string;
|
||||
onSearchQueryChange: (query: string) => void;
|
||||
crossOsUnlocked?: boolean;
|
||||
};
|
||||
|
||||
const HomeHeader = ({
|
||||
@@ -191,7 +190,6 @@ const HomeHeader = ({
|
||||
onExtensionManagementDialogOpen,
|
||||
searchQuery,
|
||||
onSearchQueryChange,
|
||||
crossOsUnlocked = false,
|
||||
}: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
|
||||
@@ -31,7 +31,6 @@ interface AppSettings {
|
||||
interface McpConfig {
|
||||
port: number;
|
||||
token: string;
|
||||
config_json: string;
|
||||
}
|
||||
|
||||
interface IntegrationsDialogProps {
|
||||
@@ -59,6 +58,8 @@ export function IntegrationsDialog({
|
||||
const [showMcpToken, setShowMcpToken] = useState(false);
|
||||
const [isApiStarting, setIsApiStarting] = useState(false);
|
||||
const [isMcpStarting, setIsMcpStarting] = useState(false);
|
||||
const [mcpInClaudeDesktop, setMcpInClaudeDesktop] = useState(false);
|
||||
const [mcpInClaudeCode, setMcpInClaudeCode] = useState(false);
|
||||
|
||||
const { termsAccepted } = useWayfernTerms();
|
||||
|
||||
@@ -98,12 +99,32 @@ export function IntegrationsDialog({
|
||||
}
|
||||
}, []);
|
||||
|
||||
const loadClaudeDesktopStatus = useCallback(async () => {
|
||||
try {
|
||||
const exists = await invoke<boolean>("is_mcp_in_claude_desktop");
|
||||
setMcpInClaudeDesktop(exists);
|
||||
} catch {
|
||||
// Not critical
|
||||
}
|
||||
}, []);
|
||||
|
||||
const loadClaudeCodeStatus = useCallback(async () => {
|
||||
try {
|
||||
const exists = await invoke<boolean>("is_mcp_in_claude_code");
|
||||
setMcpInClaudeCode(exists);
|
||||
} catch {
|
||||
// Claude CLI may not be installed
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
loadSettings();
|
||||
loadApiServerStatus();
|
||||
loadMcpConfig();
|
||||
loadMcpServerStatus();
|
||||
loadClaudeDesktopStatus();
|
||||
loadClaudeCodeStatus();
|
||||
}
|
||||
}, [
|
||||
isOpen,
|
||||
@@ -111,6 +132,8 @@ export function IntegrationsDialog({
|
||||
loadApiServerStatus,
|
||||
loadMcpConfig,
|
||||
loadMcpServerStatus,
|
||||
loadClaudeDesktopStatus,
|
||||
loadClaudeCodeStatus,
|
||||
]);
|
||||
|
||||
const handleApiToggle = async (enabled: boolean) => {
|
||||
@@ -175,45 +198,9 @@ export function IntegrationsDialog({
|
||||
}
|
||||
};
|
||||
|
||||
const obfuscateToken = (token: string) =>
|
||||
const _obfuscateToken = (token: string) =>
|
||||
"•".repeat(Math.min(token.length, 32));
|
||||
|
||||
const getFormattedMcpConfig = () => {
|
||||
if (!mcpConfig) return "";
|
||||
return JSON.stringify(
|
||||
{
|
||||
mcpServers: {
|
||||
"donut-browser": {
|
||||
url: `http://127.0.0.1:${mcpConfig.port}/mcp`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${mcpConfig.token}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
};
|
||||
|
||||
const getObfuscatedMcpConfig = () => {
|
||||
if (!mcpConfig) return "";
|
||||
return JSON.stringify(
|
||||
{
|
||||
mcpServers: {
|
||||
"donut-browser": {
|
||||
url: `http://127.0.0.1:${mcpConfig.port}/mcp`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${obfuscateToken(mcpConfig.token)}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
||||
<DialogContent className="max-w-xl max-h-[80vh] my-8 flex flex-col">
|
||||
@@ -331,39 +318,129 @@ export function IntegrationsDialog({
|
||||
</div>
|
||||
|
||||
{mcpConfig && (
|
||||
<div className="space-y-3 p-4 rounded-md border bg-muted/40">
|
||||
<div className="relative">
|
||||
<pre className="p-3 text-xs font-mono rounded-md bg-background border overflow-x-auto whitespace-pre">
|
||||
{showMcpToken
|
||||
? getFormattedMcpConfig()
|
||||
: getObfuscatedMcpConfig()}
|
||||
</pre>
|
||||
<div className="absolute top-2 right-2 flex items-center space-x-1">
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-7 w-7 p-0"
|
||||
onClick={() => setShowMcpToken(!showMcpToken)}
|
||||
>
|
||||
{showMcpToken ? (
|
||||
<EyeOff className="h-3.5 w-3.5" />
|
||||
) : (
|
||||
<Eye className="h-3.5 w-3.5" />
|
||||
)}
|
||||
</Button>
|
||||
<div className="space-y-4 p-4 rounded-md border bg-muted/40">
|
||||
<div className="space-y-2">
|
||||
<Label className="text-sm font-medium">
|
||||
{t("integrations.mcp.url")}
|
||||
</Label>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="relative flex-1">
|
||||
<Input
|
||||
type={showMcpToken ? "text" : "password"}
|
||||
value={`http://127.0.0.1:${mcpConfig.port}/mcp/${mcpConfig.token}`}
|
||||
readOnly
|
||||
className="font-mono text-xs pr-10"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="absolute right-0 top-0 h-full px-3 hover:bg-transparent"
|
||||
onClick={() => setShowMcpToken(!showMcpToken)}
|
||||
>
|
||||
{showMcpToken ? (
|
||||
<EyeOff className="h-4 w-4" />
|
||||
) : (
|
||||
<Eye className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
<CopyToClipboard
|
||||
text={getFormattedMcpConfig()}
|
||||
successMessage="Configuration copied"
|
||||
text={`http://127.0.0.1:${mcpConfig.port}/mcp/${mcpConfig.token}`}
|
||||
successMessage={t("integrations.mcp.urlCopied")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("integrations.mcpCopyHint")}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("integrations.mcpConfigPath")}
|
||||
</p>
|
||||
|
||||
<div className="space-y-2 pt-1 border-t">
|
||||
<p className="text-xs font-medium text-muted-foreground">
|
||||
{t("integrations.mcp.claudeDesktopTitle")}
|
||||
</p>
|
||||
{mcpInClaudeDesktop ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full"
|
||||
onClick={async () => {
|
||||
try {
|
||||
await invoke("remove_mcp_from_claude_desktop");
|
||||
setMcpInClaudeDesktop(false);
|
||||
showSuccessToast(
|
||||
t("integrations.mcp.removedFromClaudeDesktop"),
|
||||
);
|
||||
} catch (e) {
|
||||
showErrorToast(String(e));
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("integrations.mcp.removeFromClaudeDesktop")}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full"
|
||||
onClick={async () => {
|
||||
try {
|
||||
await invoke("add_mcp_to_claude_desktop");
|
||||
setMcpInClaudeDesktop(true);
|
||||
showSuccessToast(
|
||||
t("integrations.mcp.addedToClaudeDesktop"),
|
||||
);
|
||||
} catch (e) {
|
||||
showErrorToast(String(e));
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("integrations.mcp.addToClaudeDesktop")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2 pt-1 border-t">
|
||||
<p className="text-xs font-medium text-muted-foreground">
|
||||
{t("integrations.mcp.claudeCodeTitle")}
|
||||
</p>
|
||||
{mcpInClaudeCode ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full"
|
||||
onClick={async () => {
|
||||
try {
|
||||
await invoke("remove_mcp_from_claude_code");
|
||||
setMcpInClaudeCode(false);
|
||||
showSuccessToast(
|
||||
t("integrations.mcp.removedFromClaudeCode"),
|
||||
);
|
||||
} catch (e) {
|
||||
showErrorToast(String(e));
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("integrations.mcp.removeFromClaudeCode")}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full"
|
||||
onClick={async () => {
|
||||
try {
|
||||
await invoke("add_mcp_to_claude_code");
|
||||
setMcpInClaudeCode(true);
|
||||
showSuccessToast(
|
||||
t("integrations.mcp.addedToClaudeCode"),
|
||||
);
|
||||
} catch (e) {
|
||||
showErrorToast(String(e));
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("integrations.mcp.addToClaudeCode")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</TabsContent>
|
||||
|
||||
@@ -417,12 +417,24 @@
|
||||
"enabled": "MCP Enabled",
|
||||
"disabled": "MCP Disabled",
|
||||
"port": "Port",
|
||||
"token": "MCP Token",
|
||||
"token": "Authentication Token",
|
||||
"tokenCopied": "Token copied",
|
||||
"url": "MCP Server URL",
|
||||
"urlCopied": "URL copied",
|
||||
"claudeDesktopTitle": "Claude Desktop",
|
||||
"claudeDesktopHint": "Configures claude_desktop_config.json automatically",
|
||||
"addToClaudeDesktop": "Add to Claude Desktop",
|
||||
"removeFromClaudeDesktop": "Remove from Claude Desktop",
|
||||
"addedToClaudeDesktop": "Added to Claude Desktop. Restart Claude Desktop and enable the extension in Settings.",
|
||||
"removedFromClaudeDesktop": "Removed from Claude Desktop config. Please restart Claude Desktop.",
|
||||
"claudeCodeTitle": "Claude Code",
|
||||
"addToClaudeCode": "Add to Claude Code",
|
||||
"removeFromClaudeCode": "Remove from Claude Code",
|
||||
"addedToClaudeCode": "Added to Claude Code",
|
||||
"removedFromClaudeCode": "Removed from Claude Code",
|
||||
"config": "MCP Configuration",
|
||||
"copyConfig": "Copy Configuration"
|
||||
},
|
||||
"mcpCopyHint": "Copy and paste this into your MCP client configuration.",
|
||||
"mcpConfigPath": "Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Import Profile",
|
||||
|
||||
@@ -417,12 +417,24 @@
|
||||
"enabled": "MCP Habilitado",
|
||||
"disabled": "MCP Deshabilitado",
|
||||
"port": "Puerto",
|
||||
"token": "Token MCP",
|
||||
"token": "Token de autenticación",
|
||||
"tokenCopied": "Token copiado",
|
||||
"url": "URL del servidor MCP",
|
||||
"urlCopied": "URL copiada",
|
||||
"claudeDesktopTitle": "Claude Desktop",
|
||||
"claudeDesktopHint": "Configura claude_desktop_config.json automáticamente",
|
||||
"addToClaudeDesktop": "Agregar a Claude Desktop",
|
||||
"removeFromClaudeDesktop": "Eliminar de Claude Desktop",
|
||||
"addedToClaudeDesktop": "Agregado a Claude Desktop. Reinicia Claude Desktop y activa la extensión en Configuración.",
|
||||
"removedFromClaudeDesktop": "Eliminado de la configuración de Claude Desktop. Reinicia Claude Desktop.",
|
||||
"claudeCodeTitle": "Claude Code",
|
||||
"addToClaudeCode": "Agregar a Claude Code",
|
||||
"removeFromClaudeCode": "Eliminar de Claude Code",
|
||||
"addedToClaudeCode": "Agregado a Claude Code",
|
||||
"removedFromClaudeCode": "Eliminado de Claude Code",
|
||||
"config": "Configuración MCP",
|
||||
"copyConfig": "Copiar Configuración"
|
||||
},
|
||||
"mcpCopyHint": "Copia y pega esto en la configuración de tu cliente MCP.",
|
||||
"mcpConfigPath": "Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) o %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importar Perfil",
|
||||
|
||||
@@ -417,12 +417,24 @@
|
||||
"enabled": "MCP activé",
|
||||
"disabled": "MCP désactivé",
|
||||
"port": "Port",
|
||||
"token": "Jeton MCP",
|
||||
"token": "Jeton d'authentification",
|
||||
"tokenCopied": "Jeton copié",
|
||||
"url": "URL du serveur MCP",
|
||||
"urlCopied": "URL copiée",
|
||||
"claudeDesktopTitle": "Claude Desktop",
|
||||
"claudeDesktopHint": "Configure claude_desktop_config.json automatiquement",
|
||||
"addToClaudeDesktop": "Ajouter à Claude Desktop",
|
||||
"removeFromClaudeDesktop": "Supprimer de Claude Desktop",
|
||||
"addedToClaudeDesktop": "Ajouté à Claude Desktop. Redémarrez Claude Desktop et activez l'extension dans les Paramètres.",
|
||||
"removedFromClaudeDesktop": "Supprimé de la configuration de Claude Desktop. Veuillez redémarrer Claude Desktop.",
|
||||
"claudeCodeTitle": "Claude Code",
|
||||
"addToClaudeCode": "Ajouter à Claude Code",
|
||||
"removeFromClaudeCode": "Supprimer de Claude Code",
|
||||
"addedToClaudeCode": "Ajouté à Claude Code",
|
||||
"removedFromClaudeCode": "Supprimé de Claude Code",
|
||||
"config": "Configuration MCP",
|
||||
"copyConfig": "Copier la configuration"
|
||||
},
|
||||
"mcpCopyHint": "Copiez et collez ceci dans la configuration de votre client MCP.",
|
||||
"mcpConfigPath": "Claude Desktop : ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) ou %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importer un profil",
|
||||
|
||||
@@ -417,12 +417,24 @@
|
||||
"enabled": "MCP有効",
|
||||
"disabled": "MCP無効",
|
||||
"port": "ポート",
|
||||
"token": "MCPトークン",
|
||||
"token": "認証トークン",
|
||||
"tokenCopied": "トークンをコピーしました",
|
||||
"url": "MCPサーバーURL",
|
||||
"urlCopied": "URLをコピーしました",
|
||||
"claudeDesktopTitle": "Claude Desktop",
|
||||
"claudeDesktopHint": "claude_desktop_config.json を自動的に設定します",
|
||||
"addToClaudeDesktop": "Claude Desktop に追加",
|
||||
"removeFromClaudeDesktop": "Claude Desktop から削除",
|
||||
"addedToClaudeDesktop": "Claude Desktop に追加しました。Claude Desktop を再起動し、設定で拡張機能を有効にしてください。",
|
||||
"removedFromClaudeDesktop": "Claude Desktop の設定から削除しました。Claude Desktop を再起動してください。",
|
||||
"claudeCodeTitle": "Claude Code",
|
||||
"addToClaudeCode": "Claude Code に追加",
|
||||
"removeFromClaudeCode": "Claude Code から削除",
|
||||
"addedToClaudeCode": "Claude Code に追加しました",
|
||||
"removedFromClaudeCode": "Claude Code から削除しました",
|
||||
"config": "MCP設定",
|
||||
"copyConfig": "設定をコピー"
|
||||
},
|
||||
"mcpCopyHint": "MCPクライアントの設定にコピーして貼り付けてください。",
|
||||
"mcpConfigPath": "Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) または %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "プロファイルをインポート",
|
||||
|
||||
@@ -417,12 +417,24 @@
|
||||
"enabled": "MCP Ativado",
|
||||
"disabled": "MCP Desativado",
|
||||
"port": "Porta",
|
||||
"token": "Token MCP",
|
||||
"token": "Token de autenticação",
|
||||
"tokenCopied": "Token copiado",
|
||||
"url": "URL do servidor MCP",
|
||||
"urlCopied": "URL copiada",
|
||||
"claudeDesktopTitle": "Claude Desktop",
|
||||
"claudeDesktopHint": "Configura claude_desktop_config.json automaticamente",
|
||||
"addToClaudeDesktop": "Adicionar ao Claude Desktop",
|
||||
"removeFromClaudeDesktop": "Remover do Claude Desktop",
|
||||
"addedToClaudeDesktop": "Adicionado ao Claude Desktop. Reinicie o Claude Desktop e ative a extensão em Configurações.",
|
||||
"removedFromClaudeDesktop": "Removido da configuração do Claude Desktop. Reinicie o Claude Desktop.",
|
||||
"claudeCodeTitle": "Claude Code",
|
||||
"addToClaudeCode": "Adicionar ao Claude Code",
|
||||
"removeFromClaudeCode": "Remover do Claude Code",
|
||||
"addedToClaudeCode": "Adicionado ao Claude Code",
|
||||
"removedFromClaudeCode": "Removido do Claude Code",
|
||||
"config": "Configuração MCP",
|
||||
"copyConfig": "Copiar Configuração"
|
||||
},
|
||||
"mcpCopyHint": "Copie e cole isso na configuração do seu cliente MCP.",
|
||||
"mcpConfigPath": "Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) ou %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Importar Perfil",
|
||||
|
||||
@@ -417,12 +417,24 @@
|
||||
"enabled": "MCP включён",
|
||||
"disabled": "MCP выключен",
|
||||
"port": "Порт",
|
||||
"token": "MCP токен",
|
||||
"token": "Токен аутентификации",
|
||||
"tokenCopied": "Токен скопирован",
|
||||
"url": "URL MCP сервера",
|
||||
"urlCopied": "URL скопирован",
|
||||
"claudeDesktopTitle": "Claude Desktop",
|
||||
"claudeDesktopHint": "Автоматически настраивает claude_desktop_config.json",
|
||||
"addToClaudeDesktop": "Добавить в Claude Desktop",
|
||||
"removeFromClaudeDesktop": "Удалить из Claude Desktop",
|
||||
"addedToClaudeDesktop": "Добавлено в Claude Desktop. Перезапустите Claude Desktop и включите расширение в Настройках.",
|
||||
"removedFromClaudeDesktop": "Удалено из конфигурации Claude Desktop. Перезапустите Claude Desktop.",
|
||||
"claudeCodeTitle": "Claude Code",
|
||||
"addToClaudeCode": "Добавить в Claude Code",
|
||||
"removeFromClaudeCode": "Удалить из Claude Code",
|
||||
"addedToClaudeCode": "Добавлено в Claude Code",
|
||||
"removedFromClaudeCode": "Удалено из Claude Code",
|
||||
"config": "Конфигурация MCP",
|
||||
"copyConfig": "Копировать конфигурацию"
|
||||
},
|
||||
"mcpCopyHint": "Скопируйте и вставьте это в конфигурацию вашего MCP-клиента.",
|
||||
"mcpConfigPath": "Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) или %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "Импорт профиля",
|
||||
|
||||
@@ -417,12 +417,24 @@
|
||||
"enabled": "MCP 已启用",
|
||||
"disabled": "MCP 已禁用",
|
||||
"port": "端口",
|
||||
"token": "MCP 令牌",
|
||||
"token": "认证令牌",
|
||||
"tokenCopied": "令牌已复制",
|
||||
"url": "MCP 服务器 URL",
|
||||
"urlCopied": "URL 已复制",
|
||||
"claudeDesktopTitle": "Claude Desktop",
|
||||
"claudeDesktopHint": "自动配置 claude_desktop_config.json",
|
||||
"addToClaudeDesktop": "添加到 Claude Desktop",
|
||||
"removeFromClaudeDesktop": "从 Claude Desktop 移除",
|
||||
"addedToClaudeDesktop": "已添加到 Claude Desktop。请重启 Claude Desktop 并在设置中启用扩展。",
|
||||
"removedFromClaudeDesktop": "已从 Claude Desktop 配置移除。请重启 Claude Desktop。",
|
||||
"claudeCodeTitle": "Claude Code",
|
||||
"addToClaudeCode": "添加到 Claude Code",
|
||||
"removeFromClaudeCode": "从 Claude Code 移除",
|
||||
"addedToClaudeCode": "已添加到 Claude Code",
|
||||
"removedFromClaudeCode": "已从 Claude Code 移除",
|
||||
"config": "MCP 配置",
|
||||
"copyConfig": "复制配置"
|
||||
},
|
||||
"mcpCopyHint": "将此内容复制并粘贴到您的 MCP 客户端配置中。",
|
||||
"mcpConfigPath": "Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) 或 %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"title": "导入配置文件",
|
||||
|
||||
Reference in New Issue
Block a user