Skip to main content
Glama

Phosphor Icons MCP Server

by lasaths
test-handlers.mjsโ€ข8.65 kB
/** * Direct handler tests for Phosphor Icons MCP Server * Tests the tool handlers directly without needing the full MCP server */ import { z } from 'zod'; // Mock the icon metadata const POPULAR_ICONS = [ { name: "house", category: "interface", tags: ["home", "main", "dashboard"] }, { name: "heart", category: "social", tags: ["like", "favorite", "love"] }, { name: "user", category: "people", tags: ["person", "profile", "account"] }, { name: "gear", category: "interface", tags: ["settings", "config", "preferences"] }, ]; const PHOSPHOR_CORE_RAW_BASE = "https://raw.githubusercontent.com/phosphor-icons/core/main/assets"; console.log('๐Ÿงช Testing Phosphor Icons MCP Handlers\n'); console.log('='.repeat(60)); // Test 1: Test fetching an icon async function testFetchIcon() { console.log('\n๐Ÿ“ฅ Test 1: Fetching icon from GitHub'); try { const iconName = 'heart'; // Use heart which we know exists const weight = 'regular'; const url = `${PHOSPHOR_CORE_RAW_BASE}/${weight}/${iconName}.svg`; const response = await fetch(url, { headers: { 'User-Agent': 'PhosphorIconsMCP/1.0.0' } }); if (response.ok) { const svg = await response.text(); const isValidSvg = svg.trim().startsWith('<svg'); console.log('โœ… Icon fetched successfully'); console.log(' Valid SVG:', isValidSvg ? 'โœ…' : 'โŒ'); console.log(' Size:', svg.length, 'bytes'); console.log(' Preview:', svg.substring(0, 100).replace(/\n/g, ' ') + '...'); return true; } else { console.log('โŒ Failed to fetch icon:', response.status, response.statusText); return false; } } catch (error) { console.log('โŒ Error:', error.message); return false; } } // Test 2: Test icon with color modification async function testIconColorModification() { console.log('\n๐ŸŽจ Test 2: Icon color modification'); try { const iconName = 'heart'; const weight = 'fill'; // For non-regular weights, filename is {name}-{weight}.svg const fileName = weight === 'regular' ? `${iconName}.svg` : `${iconName}-${weight}.svg`; const url = `${PHOSPHOR_CORE_RAW_BASE}/${weight}/${fileName}`; const response = await fetch(url, { headers: { 'User-Agent': 'PhosphorIconsMCP/1.0.0' } }); if (response.ok) { let svg = await response.text(); const originalSvg = svg; // Apply color (simulating the handler logic for fill weight) svg = svg.replace(/fill="[^"]*"/g, `fill="#FF0000"`); const hasColor = svg.includes('#FF0000') || svg.includes('fill="#FF0000"'); console.log('โœ… Color modification test'); console.log(' Color applied:', hasColor ? 'โœ…' : 'โŒ'); console.log(' SVG changed:', originalSvg !== svg ? 'โœ…' : 'โŒ'); return true; } else { console.log('โŒ Failed to fetch icon:', response.status, response.statusText); return false; } } catch (error) { console.log('โŒ Error:', error.message); return false; } } // Test 3: Test icon size modification async function testIconSizeModification() { console.log('\n๐Ÿ“ Test 3: Icon size modification'); try { const iconName = 'heart'; // Use heart which we know exists const weight = 'regular'; const fileName = weight === 'regular' ? `${iconName}.svg` : `${iconName}-${weight}.svg`; const url = `${PHOSPHOR_CORE_RAW_BASE}/${weight}/${fileName}`; const response = await fetch(url, { headers: { 'User-Agent': 'PhosphorIconsMCP/1.0.0' } }); if (response.ok) { let svg = await response.text(); const originalSvg = svg; // Apply size (simulating the handler logic - check if width exists first) const size = 32; if (!svg.includes('width=')) { svg = svg.replace(/<svg([^>]*)>/, `<svg$1 width="${size}" height="${size}">`); } else { svg = svg.replace(/width="[^"]*"/, `width="${size}"`); svg = svg.replace(/height="[^"]*"/, `height="${size}"`); } const hasSize = svg.includes(`width="${size}"`) && svg.includes(`height="${size}"`); console.log('โœ… Size modification test'); console.log(' Size applied:', hasSize ? 'โœ…' : 'โŒ'); console.log(' SVG changed:', originalSvg !== svg ? 'โœ…' : 'โŒ'); return true; } else { console.log('โŒ Failed to fetch icon:', response.status, response.statusText); return false; } } catch (error) { console.log('โŒ Error:', error.message); return false; } } // Test 4: Test search functionality function testSearchIcons() { console.log('\n๐Ÿ” Test 4: Search icons functionality'); try { const query = 'house'; const searchTerm = query.toLowerCase().trim(); const matches = POPULAR_ICONS.filter((icon) => { return ( icon.name.toLowerCase().includes(searchTerm) || icon.category?.toLowerCase().includes(searchTerm) || icon.tags?.some((tag) => tag.toLowerCase().includes(searchTerm)) ); }); const found = matches.length > 0; console.log('โœ… Search test'); console.log(' Query:', query); console.log(' Results found:', found ? `โœ… (${matches.length})` : 'โŒ'); if (found) { console.log(' Matches:', matches.map(i => i.name).join(', ')); } return found; } catch (error) { console.log('โŒ Error:', error.message); return false; } } // Test 5: Test categories function testListCategories() { console.log('\n๐Ÿ“‹ Test 5: List categories'); try { const categories = Array.from( new Set( POPULAR_ICONS.map((icon) => icon.category).filter( (cat) => cat !== undefined ) ) ).sort(); console.log('โœ… Categories test'); console.log(' Categories found:', categories.length); console.log(' Categories:', categories.join(', ')); return categories.length > 0; } catch (error) { console.log('โŒ Error:', error.message); return false; } } // Test 6: Test invalid icon name handling async function testInvalidIcon() { console.log('\nโš ๏ธ Test 6: Invalid icon name handling'); try { const iconName = 'invalid-icon-xyz-123'; const weight = 'regular'; const url = `${PHOSPHOR_CORE_RAW_BASE}/${weight}/${iconName}.svg`; const response = await fetch(url, { headers: { 'User-Agent': 'PhosphorIconsMCP/1.0.0' } }); if (!response.ok) { console.log('โœ… Invalid icon correctly returns error'); console.log(' Status:', response.status); return true; } else { console.log('โš ๏ธ Icon unexpectedly found (might be valid)'); return true; // Not necessarily a failure } } catch (error) { console.log('โŒ Error:', error.message); return false; } } // Test 7: Test different weights async function testDifferentWeights() { console.log('\nโš–๏ธ Test 7: Different icon weights'); const weights = ['thin', 'light', 'regular', 'bold', 'fill', 'duotone']; const iconName = 'heart'; let successCount = 0; for (const weight of weights) { try { // For non-regular weights, filename is {name}-{weight}.svg const fileName = weight === 'regular' ? `${iconName}.svg` : `${iconName}-${weight}.svg`; const url = `${PHOSPHOR_CORE_RAW_BASE}/${weight}/${fileName}`; const response = await fetch(url, { headers: { 'User-Agent': 'PhosphorIconsMCP/1.0.0' } }); if (response.ok) { successCount++; console.log(` โœ… ${weight}`); } else { console.log(` โŒ ${weight} (${response.status})`); } } catch (error) { console.log(` โŒ ${weight} (${error.message})`); } } console.log(`\n Summary: ${successCount}/${weights.length} weights available`); return successCount === weights.length; } // Run all tests async function runAllTests() { const results = []; results.push(await testFetchIcon()); results.push(await testIconColorModification()); results.push(await testIconSizeModification()); results.push(testSearchIcons()); results.push(testListCategories()); results.push(await testInvalidIcon()); results.push(await testDifferentWeights()); console.log('\n' + '='.repeat(60)); const passed = results.filter(r => r).length; const total = results.length; console.log(`\n๐Ÿ“Š Test Results: ${passed}/${total} passed`); if (passed === total) { console.log('โœจ All tests passed!'); process.exit(0); } else { console.log('โš ๏ธ Some tests failed'); process.exit(1); } } runAllTests().catch(console.error);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lasaths/phosphor-icons-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server