mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 20:23:36 +00:00
feat: add API key masking and 80+ tools warning for MCP servers
Security improvements: - Mask sensitive values in URLs (api_key, token, auth, secret, etc.) - Prevents accidental API key leaks when sharing screen or screenshots Performance guidance: - Show warning banner when total MCP tools exceed 80 - Warns users that high tool count may degrade AI model performance 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
|
||||
import { useAppStore } from '@/store/app-store';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
ChevronDown,
|
||||
ChevronRight,
|
||||
Code,
|
||||
AlertTriangle,
|
||||
} from 'lucide-react';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { cn } from '@/lib/utils';
|
||||
@@ -77,6 +78,51 @@ interface ServerTestState {
|
||||
connectionTime?: number;
|
||||
}
|
||||
|
||||
// Patterns that indicate sensitive values in URLs or config
|
||||
const SENSITIVE_PARAM_PATTERNS = [
|
||||
/api[-_]?key/i,
|
||||
/api[-_]?token/i,
|
||||
/auth/i,
|
||||
/token/i,
|
||||
/secret/i,
|
||||
/password/i,
|
||||
/credential/i,
|
||||
/bearer/i,
|
||||
];
|
||||
|
||||
/**
|
||||
* Mask sensitive values in URLs (query params with key-like names)
|
||||
*/
|
||||
function maskSensitiveUrl(url: string): string {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
const params = new URLSearchParams(urlObj.search);
|
||||
let hasSensitive = false;
|
||||
|
||||
for (const [key] of params.entries()) {
|
||||
if (SENSITIVE_PARAM_PATTERNS.some((pattern) => pattern.test(key))) {
|
||||
params.set(key, '***');
|
||||
hasSensitive = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasSensitive) {
|
||||
urlObj.search = params.toString();
|
||||
return urlObj.toString();
|
||||
}
|
||||
return url;
|
||||
} catch {
|
||||
// If URL parsing fails, try simple regex replacement for common patterns
|
||||
return url.replace(
|
||||
/([?&])(api[-_]?key|auth|token|secret|password|credential)=([^&]*)/gi,
|
||||
'$1$2=***'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Maximum recommended MCP tools before performance degradation
|
||||
const MAX_RECOMMENDED_TOOLS = 80;
|
||||
|
||||
export function MCPServersSection() {
|
||||
const {
|
||||
mcpServers,
|
||||
@@ -103,6 +149,22 @@ export function MCPServersSection() {
|
||||
const [globalJsonValue, setGlobalJsonValue] = useState('');
|
||||
const autoTestedServersRef = useRef<Set<string>>(new Set());
|
||||
|
||||
// Calculate total tools across all enabled servers
|
||||
const totalToolsCount = useMemo(() => {
|
||||
let count = 0;
|
||||
for (const server of mcpServers) {
|
||||
if (server.enabled !== false) {
|
||||
const testState = serverTestStates[server.id];
|
||||
if (testState?.status === 'success' && testState.tools) {
|
||||
count += testState.tools.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}, [mcpServers, serverTestStates]);
|
||||
|
||||
const showToolsWarning = totalToolsCount > MAX_RECOMMENDED_TOOLS;
|
||||
|
||||
// Auto-load MCP servers from settings file on mount
|
||||
useEffect(() => {
|
||||
loadMCPServersFromServer().catch((error) => {
|
||||
@@ -806,6 +868,24 @@ export function MCPServersSection() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Tools Count Warning */}
|
||||
{showToolsWarning && (
|
||||
<div className="mx-6 mt-4 p-3 rounded-lg border border-yellow-500/50 bg-yellow-500/10">
|
||||
<div className="flex items-start gap-3">
|
||||
<AlertTriangle className="w-5 h-5 text-yellow-500 shrink-0 mt-0.5" />
|
||||
<div className="text-sm">
|
||||
<p className="font-medium text-yellow-600 dark:text-yellow-400">
|
||||
High tool count detected ({totalToolsCount} tools)
|
||||
</p>
|
||||
<p className="text-muted-foreground mt-1">
|
||||
Having more than {MAX_RECOMMENDED_TOOLS} MCP tools may degrade AI model performance.
|
||||
Consider disabling unused servers or removing unnecessary tools.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Server List */}
|
||||
<div className="p-6">
|
||||
{mcpServers.length === 0 ? (
|
||||
@@ -883,7 +963,7 @@ export function MCPServersSection() {
|
||||
<div className="text-xs text-muted-foreground/60 mt-0.5 truncate">
|
||||
{server.type === 'stdio'
|
||||
? `${server.command}${server.args?.length ? ' ' + server.args.join(' ') : ''}`
|
||||
: server.url}
|
||||
: maskSensitiveUrl(server.url || '')}
|
||||
</div>
|
||||
{testState?.status === 'error' && testState.error && (
|
||||
<div className="text-xs text-destructive mt-1 line-clamp-2 break-words">
|
||||
|
||||
Reference in New Issue
Block a user