Skip to main content
Glama
PRODUCT_AUTOCOMPLETE_SOLUTIONS.md14.6 kB
# Cisco Product Autocomplete API - Creative Access Solutions ## Problem Cisco has a valuable product autocomplete API at: ``` https://bst.cloudapps.cisco.com/api/productAutocomplete?productsearchTerm=4431 ``` **Response Example:** ```json { "autoPopulateHMPProductDetails": [{ "parentMdfConceptId": 286281708, "parentMdfConceptName": "Cisco 4000 Series Integrated Services Routers", "mdfConceptId": 284358776, "mdfConceptName": "Cisco 4431 Integrated Services Router", "mdfMetaclass": "Model" }] } ``` **Challenge:** Requires browser-based authentication (Cookie-based session from cisco.com login) ## Creative Solutions ### Solution 1: MCP Resources with User-Provided Cookies ✨ **RECOMMENDED** Use MCP's resource system to let users provide their own session cookies. **Implementation:** ```typescript // Add to src/mcp-server.ts resource templates { uriTemplate: 'cisco://products/autocomplete/{search_term}', name: 'Cisco Product Autocomplete', description: 'Search Cisco product catalog by name or model (requires user cookie)', mimeType: 'application/json' } // Resource handler server.setRequestHandler(ResourceListRequestSchema, async () => { if (ENABLED_APIS.includes('product')) { resources.push({ uri: 'cisco://products/autocomplete-help', name: 'Product Autocomplete Setup', description: 'How to use Cisco product autocomplete with your session', mimeType: 'text/markdown', text: ` # Using Cisco Product Autocomplete This feature requires your Cisco.com session cookie: 1. Log in to https://bst.cloudapps.cisco.com/ 2. Open browser DevTools (F12) 3. Go to Application/Storage > Cookies 4. Copy the entire Cookie header value 5. Set environment variable: \`\`\` CISCO_WEB_COOKIE="your-cookie-here" \`\`\` Then query: \`\`\` cisco://products/autocomplete/4431 \`\`\` ` }); } }); // Resource read handler if (uri.startsWith('cisco://products/autocomplete/')) { const searchTerm = uri.split('/').pop(); const webCookie = process.env.CISCO_WEB_COOKIE; if (!webCookie) { return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify({ error: 'CISCO_WEB_COOKIE not configured', help: 'See cisco://products/autocomplete-help for setup instructions' }) }] }; } const response = await fetch( `https://bst.cloudapps.cisco.com/api/productAutocomplete?productsearchTerm=${searchTerm}`, { headers: { 'Cookie': webCookie, 'User-Agent': 'Mozilla/5.0...', 'Referer': 'https://bst.cloudapps.cisco.com/' } } ); const data = await response.json(); return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(data, null, 2) }] }; } ``` **Pros:** - ✅ User controls their own authentication - ✅ Respects Cisco's security model - ✅ Works immediately with any valid session - ✅ No proxy or server infrastructure needed **Cons:** - ⚠️ User must manually update cookie when it expires - ⚠️ Cookie exposure risk (though controlled by user) ### Solution 2: Sampling-Based Resolution 🤖 Use MCP sampling to have Claude resolve product names via web search or knowledge. **Implementation:** ```typescript { name: 'resolve_product_id_smart', description: 'Resolve product short codes to full names using AI and web search', inputSchema: { type: 'object', properties: { product_code: { type: 'string', description: 'Product code like ISR4431, C9200-24P, ASA5516' } } } } // In handler async function resolveProductIdSmart(server: Server, productCode: string) { const result = await server.createMessage({ messages: [{ role: 'user', content: { type: 'text', text: `What is the full official Cisco product name for "${productCode}"? Provide: 1. Full product name 2. Product family/series 3. Product category (router, switch, firewall, etc.) Search Cisco documentation if needed. Return as JSON.` } }], systemPrompt: 'You are a Cisco product expert. Use web search to find accurate product names.', maxTokens: 500 }); return parseProductInfo(result.content.text); } ``` **Pros:** - ✅ No authentication needed - ✅ Leverages Claude's knowledge + web search - ✅ Can resolve ambiguous names **Cons:** - ⚠️ Less accurate than official API - ⚠️ Requires sampling capability in client - ⚠️ Slower than direct API ### Solution 3: Static Product Mapping Database 📊 **MOST PRACTICAL** Build a comprehensive static mapping from community data. **Implementation:** ```typescript // src/data/product-mappings.ts export const CISCO_PRODUCT_CATALOG: Record<string, ProductInfo> = { 'ISR4431': { fullName: 'Cisco 4431 Integrated Services Router', series: 'Cisco 4000 Series Integrated Services Routers', seriesId: 'Cisco 4000 Series ISR', aliases: ['ISR4431/K9', '4431', 'ISR 4431'], category: 'router', mdfConceptId: 284358776, parentMdfConceptId: 286281708 }, 'C9200-24P': { fullName: 'Cisco Catalyst 9200 24-Port PoE Switch', series: 'Cisco Catalyst 9200 Series', aliases: ['C9200-24P-A', 'C9200-24P-E', 'Catalyst 9200 24P'], category: 'switch' }, // ... add more as discovered through usage }; export function resolveProductName(code: string): ProductInfo | null { // Direct lookup if (CISCO_PRODUCT_CATALOG[code]) { return CISCO_PRODUCT_CATALOG[code]; } // Try without /K9 suffix const baseCode = code.replace(/\/K9$/, ''); if (CISCO_PRODUCT_CATALOG[baseCode]) { return CISCO_PRODUCT_CATALOG[baseCode]; } // Search aliases for (const [key, product] of Object.entries(CISCO_PRODUCT_CATALOG)) { if (product.aliases?.some(alias => alias.toLowerCase() === code.toLowerCase() )) { return product; } } return null; } ``` **Data Sources:** 1. Cisco Bug Search results (extract product names from bugs) 2. Cisco Support API responses 3. Community forums and documentation 4. Manual curation from common products **Pros:** - ✅ No authentication required - ✅ Fast (local lookup) - ✅ No external dependencies - ✅ Can be incrementally improved - ✅ Works offline **Cons:** - ⚠️ Requires manual curation - ⚠️ May not have newest products - ⚠️ Needs periodic updates ### Solution 4: Proxy Service (External) 🌐 Create a separate authenticated proxy service. **Architecture:** ``` User MCP Client ↓ MCP Server → Proxy Service (has valid cookie) → Cisco API ↓ Refresh cookie periodically ``` **Implementation:** ```typescript // Optional proxy URL in environment const CISCO_PRODUCT_PROXY = process.env.CISCO_PRODUCT_PROXY_URL; async function fetchProductAutocomplete(searchTerm: string) { if (CISCO_PRODUCT_PROXY) { // Use authenticated proxy const response = await fetch( `${CISCO_PRODUCT_PROXY}/autocomplete?q=${searchTerm}` ); return await response.json(); } // Fallback to static mapping return resolveProductName(searchTerm); } ``` **Proxy Service (separate project):** ```typescript // Runs on user's server or cloud import express from 'express'; const app = express(); // Load cookie from secure storage const CISCO_COOKIE = await loadFromSecureStorage('CISCO_WEB_COOKIE'); app.get('/autocomplete', async (req, res) => { const result = await fetch( `https://bst.cloudapps.cisco.com/api/productAutocomplete?productsearchTerm=${req.query.q}`, { headers: { 'Cookie': CISCO_COOKIE } } ); res.json(await result.json()); }); // Auto-refresh cookie before expiry setInterval(refreshCookieFromBrowser, 12 * 60 * 60 * 1000); ``` **Pros:** - ✅ Centralized authentication management - ✅ Can refresh cookies automatically - ✅ Multiple users can share **Cons:** - ⚠️ Requires separate service deployment - ⚠️ Security responsibility - ⚠️ Violates Cisco ToS potentially ### Solution 5: Hybrid Approach ⭐ **BEST OVERALL** Combine multiple methods with intelligent fallback. **Implementation:** ```typescript async function resolveProductSmart(productCode: string): Promise<ProductResolution> { const result: ProductResolution = { input: productCode, confidence: 'unknown', sources: [] }; // Level 1: Static mapping (instant, high confidence for known products) const staticMatch = CISCO_PRODUCT_CATALOG[productCode]; if (staticMatch) { result.fullName = staticMatch.fullName; result.series = staticMatch.series; result.confidence = 'high'; result.sources.push('static_database'); return result; } // Level 2: Check environment for user-provided cookie if (process.env.CISCO_WEB_COOKIE) { try { const apiResult = await fetchWithCookie(productCode); if (apiResult.autoPopulateHMPProductDetails?.[0]) { const product = apiResult.autoPopulateHMPProductDetails[0]; result.fullName = product.mdfConceptName; result.series = product.parentMdfConceptName; result.confidence = 'very_high'; result.sources.push('cisco_api_with_user_cookie'); // Cache this result for future lookups cacheProductMapping(productCode, product); return result; } } catch (error) { logger.warn('Cisco API with cookie failed', { error }); } } // Level 3: Try sampling if available if (mcpServer && hasClientSampling()) { try { const sampledResult = await resolveViasampling(mcpServer, productCode); result.fullName = sampledResult.fullName; result.series = sampledResult.series; result.confidence = 'medium'; result.sources.push('ai_sampling'); return result; } catch (error) { logger.warn('Sampling resolution failed', { error }); } } // Level 4: Fuzzy matching in static DB const fuzzyMatch = fuzzySearchProducts(productCode); if (fuzzyMatch) { result.fullName = fuzzyMatch.fullName; result.series = fuzzyMatch.series; result.confidence = 'low'; result.sources.push('fuzzy_match'); result.alternatives = fuzzyMatch.alternatives; return result; } // Level 5: Return best guess with clear confidence marker result.fullName = `Unknown product: ${productCode}`; result.confidence = 'none'; result.sources.push('no_match'); result.suggestions = [ 'Provide CISCO_WEB_COOKIE environment variable for API access', 'Check product code spelling', 'Try searching with full product name instead' ]; return result; } ``` **Pros:** - ✅ Works in all scenarios - ✅ Degrades gracefully - ✅ Best effort approach - ✅ Transparent confidence levels - ✅ Learns over time (caching) **Cons:** - ⚠️ More complex implementation - ⚠️ Variable latency ## Recommended Implementation Plan ### Phase 1: Static Database (Immediate) 1. Create `src/data/product-mappings.ts` with top 100 products 2. Implement `resolveProductName()` helper 3. Use in `multi_severity_search` fallback 4. Log unknown products for future addition ### Phase 2: User Cookie Support (Week 2) 1. Add MCP resource for `cisco://products/autocomplete/{term}` 2. Document cookie setup in README 3. Add helpful error messages 4. Implement cookie validation check ### Phase 3: Sampling Integration (Week 3) 1. Add `resolve_product_name_ai` sampling tool 2. Use as fallback when cookie not available 3. Cache AI results to static DB ### Phase 4: Community Crowdsourcing (Ongoing) 1. Log all product lookups to analytics 2. Create GitHub issue template for adding products 3. Automated PR generation for new mappings 4. Community can contribute via PRs ## Security Considerations ### Cookie Handling ```typescript // Validate cookie format before use function validateCiscoCookie(cookie: string): boolean { if (!cookie || cookie.length < 100) return false; // Check for required session tokens const requiredFields = ['JSESSIONID', 'OptanonConsent']; return requiredFields.every(field => cookie.includes(field)); } // Never log cookies logger.info('Using Cisco web cookie', { hasLength: cookie?.length || 0, hasSessionId: cookie?.includes('JSESSIONID') || false // NEVER: cookie: cookie }); // Auto-redact in error messages function sanitizeError(error: Error): Error { const message = error.message.replace( /Cookie: [^\n]+/g, 'Cookie: [REDACTED]' ); return new Error(message); } ``` ### User Guidelines ```markdown ## Security Best Practices When using `CISCO_WEB_COOKIE`: 1. **Never commit cookies to git** 2. **Use .env file (already in .gitignore)** 3. **Refresh cookie when expired** (usually 24 hours) 4. **Use a dedicated Cisco account** (not your primary) 5. **Rotate cookies periodically** 6. **Monitor for unusual activity** ### Least Privilege Approach Your Cisco account only needs: - ✅ Basic cisco.com login access - ✅ Access to Bug Search Tool - ❌ Does NOT need CCO download privileges - ❌ Does NOT need support case access ``` ## Example Usage ### Configuration ```bash # .env CISCO_CLIENT_ID=your_oauth_id CISCO_CLIENT_SECRET=your_oauth_secret # Optional: for product autocomplete CISCO_WEB_COOKIE="JSESSIONID=...; OptanonConsent=...; [full cookie]" ``` ### Code Usage ```typescript import { resolveProductSmart } from './utils/product-resolver'; // Automatically uses best available method const product = await resolveProductSmart('ISR4431'); console.log(product.fullName); // "Cisco 4431 Integrated Services Router" console.log(product.confidence); // "high" | "medium" | "low" console.log(product.sources); // ["static_database"] or ["cisco_api_with_user_cookie", "static_database"] ``` ### CLI Usage ```bash # Test product resolution CISCO_WEB_COOKIE="..." npx mcp-cisco-support --resolve-product ISR4431 # Interactive mode npx mcp-cisco-support --product-lookup > ISR4431 Cisco 4431 Integrated Services Router (confidence: high) Series: Cisco 4000 Series Integrated Services Routers Source: static_database ``` ## Conclusion **Recommended Approach:** Hybrid solution (Solution 5) with: 1. **Primary:** Static database for common products 2. **Optional:** User-provided cookie via environment variable 3. **Fallback:** AI sampling when available 4. **Future:** Community crowdsourcing for database growth This approach: - ✅ Works out of the box for most cases - ✅ Gives power users full API access - ✅ Respects Cisco's security model - ✅ Improves over time - ✅ Transparent about confidence levels

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/sieteunoseis/mcp-cisco-support'

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