diff --git a/apps/web/src/app/api/tools/search/route.ts b/apps/web/src/app/api/tools/search/route.ts index f7f68a3..b620549 100644 --- a/apps/web/src/app/api/tools/search/route.ts +++ b/apps/web/src/app/api/tools/search/route.ts @@ -93,7 +93,11 @@ export async function GET(request: NextRequest) { // Accept both 'q' and 'query' parameters for flexibility const query = searchParams.get('q') || searchParams.get('query') || ''; const category = searchParams.get('category'); - const limit = Math.min(Number.parseInt(searchParams.get('limit') || '10'), 50); + const limit = Math.min(Number.parseInt(searchParams.get('limit') || '10'), 100); + + // Parse excludeIds to filter out tools already in user's collection + const excludeIdsParam = searchParams.get('excludeIds'); + const excludeIds = excludeIdsParam ? excludeIdsParam.split(',').filter(Boolean) : []; // Get recent messages for context (passed as JSON in 'messages' param) // Wrap in try-catch to handle malformed JSON gracefully @@ -121,6 +125,8 @@ export async function GET(request: NextRequest) { // Build database filter - pre-filter at DB level to reduce in-memory processing // Use OR conditions to find tools that match ANY search token const dbFilter = { + // Exclude tools already in collection (if provided) + ...(excludeIds.length > 0 && { id: { notIn: excludeIds } }), ...(category && { package: { category } }), ...(hasSearchQuery && { OR: [ diff --git a/apps/web/src/components/collections/AddToolSearch.tsx b/apps/web/src/components/collections/AddToolSearch.tsx index b1b1244..285db58 100644 --- a/apps/web/src/components/collections/AddToolSearch.tsx +++ b/apps/web/src/components/collections/AddToolSearch.tsx @@ -58,9 +58,16 @@ export function AddToolSearch({ setError(null); try { - const response = await fetch( - `/api/tools/search?q=${encodeURIComponent(searchQuery)}&limit=10` - ); + // Build URL with excludeIds to avoid returning tools already in collection + const params = new URLSearchParams({ + q: searchQuery, + limit: '50', // Higher limit to handle large packages like @tpmjs/tools-unsandbox (59 tools) + }); + // Pass existing tool IDs so server can exclude them + if (existingToolIds.length > 0) { + params.set('excludeIds', existingToolIds.join(',')); + } + const response = await fetch(`/api/tools/search?${params.toString()}`); const data = await response.json(); if (data.success && data.results?.tools) { @@ -76,7 +83,7 @@ export function AddToolSearch({ } finally { setIsSearching(false); } - }, []); + }, [existingToolIds]); // Handle query changes with debounce useEffect(() => {