diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..bee3e49 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,10 @@ +{ + "mcpServers": { + "tip": { + "command": "npx", + "args": ["tsx", "packages/mcp-server/src/index.ts"], + "cwd": "/Users/renefichtmueller/Desktop/Claude Code/github-repos/transceiver-db", + "description": "Transceiver Intelligence Platform — 12 tools for transceiver search, pricing, compatibility, hype cycle, and blog generation" + } + } +} diff --git a/package-lock.json b/package-lock.json index a60b11f..261112f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1377,6 +1377,18 @@ "node": ">=18" } }, + "node_modules/@hono/node-server": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, "node_modules/@inquirer/external-editor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", @@ -1413,6 +1425,64 @@ "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", "license": "MIT" }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.28.0.tgz", + "integrity": "sha512-gmloF+i+flI8ouQK7MWW4mOwuMh4RePBuPFAEPC6+pdqyWOUMDOixb6qZ69owLJpz6XmyllCouc4t8YWO+E2Nw==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", + "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, "node_modules/@sapphire/async-queue": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz", @@ -1462,6 +1532,10 @@ "resolved": "packages/core", "link": true }, + "node_modules/@tip/mcp-server": { + "resolved": "packages/mcp-server", + "link": true + }, "node_modules/@tip/scraper": { "resolved": "packages/scraper", "link": true @@ -1698,6 +1772,39 @@ "node": ">= 14" } }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -2286,6 +2393,20 @@ "node": ">=12.0.0" } }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -2703,6 +2824,27 @@ "through": "~2.3.1" } }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", @@ -2767,6 +2909,22 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fflate": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", @@ -3272,6 +3430,15 @@ "node": ">=18.0.0" } }, + "node_modules/hono": { + "version": "4.12.9", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz", + "integrity": "sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -3566,6 +3733,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jose": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz", + "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/jquery": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", @@ -3641,6 +3823,18 @@ "node": ">=16" } }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -4237,6 +4431,15 @@ "node": ">=8" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-to-regexp": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", @@ -4368,6 +4571,15 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -4584,6 +4796,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", @@ -4832,6 +5053,27 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -5409,6 +5651,21 @@ "node": ">=18" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -5631,6 +5888,15 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, "packages/api": { "name": "@tip/api", "version": "0.1.0", @@ -5662,6 +5928,24 @@ "node": ">=14" } }, + "packages/mcp-server": { + "name": "@tip/mcp-server", + "version": "0.1.0", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.9.0", + "dotenv": "^16.4.7", + "pg": "^8.13.1", + "zod": "^3.24.0" + }, + "bin": { + "tip-mcp": "dist/index.js" + }, + "devDependencies": { + "@types/pg": "^8.11.11", + "tsx": "^4.19.0", + "typescript": "^5.9.3" + } + }, "packages/scraper": { "name": "@tip/scraper", "version": "0.1.0", diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json new file mode 100644 index 0000000..c4d8bd0 --- /dev/null +++ b/packages/mcp-server/package.json @@ -0,0 +1,26 @@ +{ + "name": "@tip/mcp-server", + "version": "0.1.0", + "private": true, + "description": "TIP MCP Server — 12 tools for LLM access to transceiver intelligence", + "main": "dist/index.js", + "bin": { + "tip-mcp": "dist/index.js" + }, + "scripts": { + "build": "tsc", + "dev": "tsx src/index.ts", + "start": "node dist/index.js" + }, + "dependencies": { + "@modelcontextprotocol/sdk": "^1.9.0", + "pg": "^8.13.1", + "dotenv": "^16.4.7", + "zod": "^3.24.0" + }, + "devDependencies": { + "@types/pg": "^8.11.11", + "typescript": "^5.9.3", + "tsx": "^4.19.0" + } +} diff --git a/packages/mcp-server/src/db.ts b/packages/mcp-server/src/db.ts new file mode 100644 index 0000000..7945ff4 --- /dev/null +++ b/packages/mcp-server/src/db.ts @@ -0,0 +1,15 @@ +import { Pool } from "pg"; +import { config } from "dotenv"; +import { join } from "path"; + +config({ path: join(__dirname, "..", "..", "..", ".env") }); + +export const pool = new Pool({ + host: process.env.POSTGRES_HOST || "localhost", + port: parseInt(process.env.POSTGRES_PORT || "5433"), + database: process.env.POSTGRES_DB || "transceiver_db", + user: process.env.POSTGRES_USER || "tip", + password: process.env.POSTGRES_PASSWORD || "tip_dev_2026", + max: 5, + idleTimeoutMillis: 30000, +}); diff --git a/packages/mcp-server/src/index.ts b/packages/mcp-server/src/index.ts new file mode 100644 index 0000000..ecd58bb --- /dev/null +++ b/packages/mcp-server/src/index.ts @@ -0,0 +1,244 @@ +#!/usr/bin/env node +/** + * TIP MCP Server — Transceiver Intelligence Platform + * + * 12 Tools for LLM access to transceiver data, pricing, compatibility, + * hype cycle, knowledge base, news, and blog generation. + * + * Transport: stdio (for Claude Code, EO Global Pulse, etc.) + * + * Usage: + * tsx src/index.ts — Run MCP server via stdio + * npx @tip/mcp-server — After npm install -g + * + * Claude Code config (~/.claude/mcp.json): + * { "tip": { "command": "npx", "args": ["@tip/mcp-server"] } } + */ +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { z } from "zod"; +import { pool } from "./db.js"; +import { registerPricingTools } from "./tools/pricing.js"; +import { registerCompatibilityTools } from "./tools/compatibility.js"; +import { registerKnowledgeTools } from "./tools/knowledge.js"; +import { registerContentTools } from "./tools/content.js"; + +async function main() { + const server = new McpServer({ + name: "tip-mcp-server", + version: "0.1.0", + }); + + // --- Tool: search_transceivers --- + server.tool( + "search_transceivers", + "Search transceivers by free text, specs, or compatibility. Returns matching transceivers with current pricing if available.", + { + query: z.string().optional().describe("Free text query, e.g. '10km for Cisco Nexus' or '400G QSFP-DD ZR'"), + form_factor: z.string().optional().describe("SFP, SFP+, SFP28, QSFP+, QSFP28, QSFP-DD, OSFP, CFP2, etc."), + speed_gbps: z.number().optional().describe("Speed in Gbps: 1, 10, 25, 40, 100, 200, 400, 800"), + reach_label: z.string().optional().describe("SR, LR, ER, ZR, or distance like 10km, 80km"), + fiber_type: z.enum(["SMF", "MMF"]).optional().describe("Single-mode or Multi-mode fiber"), + wdm_type: z.enum(["CWDM", "DWDM"]).optional().describe("Wavelength division multiplexing type"), + vendor: z.string().optional().describe("Vendor filter, e.g. 'Cisco', 'Juniper', 'FS.COM'"), + max_results: z.number().default(10).describe("Maximum results to return"), + }, + async ({ query, form_factor, speed_gbps, reach_label, fiber_type, wdm_type, vendor, max_results }) => { + const conditions: string[] = []; + const values: unknown[] = []; + let idx = 1; + + if (query) { + conditions.push(`t.search_vector @@ plainto_tsquery('english', $${idx})`); + values.push(query); + idx++; + } + if (form_factor) { + conditions.push(`t.form_factor ILIKE $${idx}`); + values.push(`%${form_factor}%`); + idx++; + } + if (speed_gbps) { + conditions.push(`t.speed_gbps = $${idx}`); + values.push(speed_gbps); + idx++; + } + if (reach_label) { + conditions.push(`(t.reach_label ILIKE $${idx} OR t.standard_name ILIKE $${idx})`); + values.push(`%${reach_label}%`); + idx++; + } + if (fiber_type) { + conditions.push(`t.fiber_type = $${idx}`); + values.push(fiber_type); + idx++; + } + if (wdm_type) { + conditions.push(`t.wdm_type = $${idx}`); + values.push(wdm_type); + idx++; + } + if (vendor) { + conditions.push(`v.name ILIKE $${idx}`); + values.push(`%${vendor}%`); + idx++; + } + + const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : ""; + const orderBy = query + ? `ORDER BY ts_rank(t.search_vector, plainto_tsquery('english', $1)) DESC` + : "ORDER BY t.speed_gbps DESC, t.reach_meters ASC"; + + values.push(max_results); + + const result = await pool.query( + `SELECT t.id, t.slug, t.standard_name, t.form_factor, t.speed, t.speed_gbps, + t.reach_label, t.reach_meters, t.fiber_type, t.connector, t.wdm_type, + t.wavelengths, t.power_consumption_w, t.temp_range, t.category, + v.name as vendor_name, + (SELECT jsonb_agg(jsonb_build_object( + 'vendor', sv.name, 'price', po.price, 'currency', po.currency, + 'stock', po.stock_level, 'url', po.url + ) ORDER BY po.time DESC) + FROM price_observations po + JOIN vendors sv ON sv.id = po.source_vendor_id + WHERE po.transceiver_id = t.id + AND po.time > NOW() - INTERVAL '7 days' + ) as pricing + FROM transceivers t + LEFT JOIN vendors v ON v.id = t.vendor_id + ${where} + ${orderBy} + LIMIT $${idx}`, + values + ); + + if (result.rows.length === 0) { + return { + content: [{ type: "text", text: "No transceivers found matching your criteria." }], + }; + } + + const formatted = result.rows.map((r) => ({ + slug: r.slug, + standard: r.standard_name, + form_factor: r.form_factor, + speed: r.speed, + reach: r.reach_label, + fiber: r.fiber_type, + connector: r.connector, + wdm: r.wdm_type, + wavelengths: r.wavelengths, + power_w: r.power_consumption_w, + temp: r.temp_range, + category: r.category, + vendor: r.vendor_name, + pricing: r.pricing || [], + })); + + return { + content: [{ + type: "text", + text: JSON.stringify({ count: result.rows.length, transceivers: formatted }, null, 2), + }], + }; + } + ); + + // --- Tool: check_compatibility --- + server.tool( + "check_compatibility", + "Check compatibility between a switch model and transceivers. Returns verified compatible transceivers with firmware requirements.", + { + switch_model: z.string().describe("Switch model, e.g. 'Cisco Nexus 93180YC-FX3' or 'Juniper EX4300'"), + transceiver_query: z.string().optional().describe("Optional: filter by transceiver type or part number"), + speed_gbps: z.number().optional().describe("Optional: filter by speed"), + reach: z.string().optional().describe("Optional: filter by reach (SR, LR, etc.)"), + }, + async ({ switch_model, transceiver_query, speed_gbps, reach }) => { + // First: find the switch + const switchResult = await pool.query( + `SELECT s.id, s.model, s.series, v.name as vendor + FROM switches s + JOIN vendors v ON v.id = s.vendor_id + WHERE s.model ILIKE $1 OR s.series ILIKE $1 + LIMIT 5`, + [`%${switch_model}%`] + ); + + if (switchResult.rows.length === 0) { + return { + content: [{ + type: "text", + text: `No switch found matching "${switch_model}". Try a shorter model name or check spelling.`, + }], + }; + } + + const sw = switchResult.rows[0]; + const conditions = [`c.switch_id = $1`]; + const values: unknown[] = [sw.id]; + let idx = 2; + + if (transceiver_query) { + conditions.push(`(t.standard_name ILIKE $${idx} OR t.slug ILIKE $${idx})`); + values.push(`%${transceiver_query}%`); + idx++; + } + if (speed_gbps) { + conditions.push(`t.speed_gbps = $${idx}`); + values.push(speed_gbps); + idx++; + } + if (reach) { + conditions.push(`t.reach_label ILIKE $${idx}`); + values.push(`%${reach}%`); + idx++; + } + + const compatResult = await pool.query( + `SELECT t.slug, t.standard_name, t.form_factor, t.speed, t.reach_label, + t.fiber_type, c.status, c.firmware_min, c.verified_by, c.verification_method + FROM compatibility c + JOIN transceivers t ON t.id = c.transceiver_id + WHERE ${conditions.join(" AND ")} + AND c.status = 'compatible' + ORDER BY t.speed_gbps DESC, t.reach_meters ASC + LIMIT 20`, + values + ); + + return { + content: [{ + type: "text", + text: JSON.stringify({ + switch: { model: sw.model, series: sw.series, vendor: sw.vendor }, + compatible_transceivers: compatResult.rows, + count: compatResult.rows.length, + }, null, 2), + }], + }; + } + ); + + // Register remaining tools + await registerPricingTools(server); + await registerCompatibilityTools(server); + await registerKnowledgeTools(server); + await registerContentTools(server); + + // Start server + const transport = new StdioServerTransport(); + await server.connect(transport); + + // Graceful shutdown + process.on("SIGINT", async () => { + await pool.end(); + process.exit(0); + }); +} + +main().catch((err) => { + console.error("Fatal MCP server error:", err); + process.exit(1); +}); diff --git a/packages/mcp-server/src/tools/compatibility.ts b/packages/mcp-server/src/tools/compatibility.ts new file mode 100644 index 0000000..b9b2023 --- /dev/null +++ b/packages/mcp-server/src/tools/compatibility.ts @@ -0,0 +1,144 @@ +/** + * Compatibility & template tools: suggest_alternatives, get_templates + */ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { z } from "zod"; +import { pool } from "../db.js"; + +export async function registerCompatibilityTools(server: McpServer): Promise { + // --- Tool: suggest_alternatives --- + server.tool( + "suggest_alternatives", + "Suggest alternative transceivers with similar specs. Useful for finding cheaper or more available options.", + { + part_number: z.string().describe("Part number, slug, or standard name"), + optimize_for: z.enum(["price", "availability", "performance"]).default("price"), + }, + async ({ part_number, optimize_for }) => { + // Find the reference transceiver + const refResult = await pool.query( + `SELECT t.id, t.slug, t.standard_name, t.form_factor, t.speed_gbps, + t.reach_meters, t.fiber_type, t.wdm_type, t.connector + FROM transceivers t + WHERE t.slug ILIKE $1 OR t.part_number ILIKE $1 OR t.standard_name ILIKE $1 + LIMIT 1`, + [`%${part_number}%`] + ); + + if (refResult.rows.length === 0) { + return { + content: [{ type: "text", text: `Reference transceiver not found: "${part_number}"` }], + }; + } + + const ref = refResult.rows[0]; + + // Find alternatives: same form_factor + speed, similar reach + const altResult = await pool.query( + `SELECT t.id, t.slug, t.standard_name, t.form_factor, t.speed, t.reach_label, + t.fiber_type, t.connector, v.name as vendor, + (SELECT MIN(po.price) FROM price_observations po + WHERE po.transceiver_id = t.id + AND po.time > NOW() - INTERVAL '7 days' + ) as min_price, + (SELECT COUNT(DISTINCT po.source_vendor_id) FROM price_observations po + WHERE po.transceiver_id = t.id + AND po.stock_level = 'in_stock' + AND po.time > NOW() - INTERVAL '7 days' + ) as vendor_count + FROM transceivers t + LEFT JOIN vendors v ON v.id = t.vendor_id + WHERE t.form_factor = $1 + AND t.speed_gbps = $2 + AND t.fiber_type = $3 + AND ABS(t.reach_meters - $4) <= $4 * 0.2 + AND t.id != $5 + ORDER BY + CASE $6 + WHEN 'price' THEN (SELECT MIN(po.price) FROM price_observations po WHERE po.transceiver_id = t.id) + WHEN 'availability' THEN -(SELECT COUNT(DISTINCT po.source_vendor_id) FROM price_observations po WHERE po.transceiver_id = t.id AND po.stock_level = 'in_stock') + ELSE t.power_consumption_w + END ASC NULLS LAST + LIMIT 10`, + [ref.form_factor, ref.speed_gbps, ref.fiber_type, ref.reach_meters, ref.id, optimize_for] + ); + + return { + content: [{ + type: "text", + text: JSON.stringify({ + reference: { + slug: ref.slug, + standard: ref.standard_name, + form_factor: ref.form_factor, + speed_gbps: ref.speed_gbps, + reach_meters: ref.reach_meters, + }, + optimize_for, + alternatives: altResult.rows, + }, null, 2), + }], + }; + } + ); + + // --- Tool: get_templates --- + server.tool( + "get_templates", + "Find FlexBox coding templates or switch configuration templates for specific vendor/technology combinations.", + { + type: z.enum(["flexbox_coding", "switch_config"]).describe("Template type"), + switch_vendor: z.string().optional().describe("Switch vendor, e.g. 'Cisco', 'Juniper', 'Arista'"), + transceiver_type: z.string().optional().describe("e.g. 'SFP+', 'QSFP28', '10G', '100G'"), + technology: z.string().optional().describe("CWDM, DWDM, BiDi, SR, LR, ER, ZR, etc."), + }, + async ({ type, switch_vendor, transceiver_type, technology }) => { + const conditions = [`t.template_type = $1`]; + const values: unknown[] = [type]; + let idx = 2; + + if (switch_vendor) { + conditions.push(`t.switch_vendor ILIKE $${idx}`); + values.push(`%${switch_vendor}%`); + idx++; + } + if (transceiver_type) { + conditions.push(`t.transceiver_type ILIKE $${idx}`); + values.push(`%${transceiver_type}%`); + idx++; + } + if (technology) { + conditions.push(`t.technology ILIKE $${idx}`); + values.push(`%${technology}%`); + idx++; + } + + const result = await pool.query( + `SELECT t.id, t.name, t.template_type, t.switch_vendor, t.transceiver_type, + t.technology, t.content, t.description, t.notes, + t.verified, t.firmware_version + FROM templates t + WHERE ${conditions.join(" AND ")} + ORDER BY t.verified DESC, t.name ASC + LIMIT 20`, + values + ); + + if (result.rows.length === 0) { + return { + content: [{ + type: "text", + text: `No ${type} templates found for the given criteria. Templates are added as they are verified in the field.`, + }], + }; + } + + return { + content: [{ + type: "text", + text: JSON.stringify({ templates: result.rows, count: result.rows.length }, null, 2), + }], + }; + } + ); +} diff --git a/packages/mcp-server/src/tools/content.ts b/packages/mcp-server/src/tools/content.ts new file mode 100644 index 0000000..584a6f8 --- /dev/null +++ b/packages/mcp-server/src/tools/content.ts @@ -0,0 +1,233 @@ +/** + * Content tools: get_market_news, generate_blog_draft + */ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { z } from "zod"; +import { pool } from "../db.js"; + +export async function registerContentTools(server: McpServer): Promise { + // --- Tool: get_market_news --- + server.tool( + "get_market_news", + "Get latest news from the optics and networking industry. Filtered by relevance to transceiver technology.", + { + query: z.string().optional().describe("Optional: search within news content"), + event: z.enum(["OFC", "ECOC", "CIOE", "PHOTONICS_WEST"]).optional().describe("Filter by trade show/event"), + days_back: z.number().default(30).describe("How many days back to look (default: 30)"), + min_relevance: z.number().default(0).describe("Minimum relevance score (0=all, 3=transceiver-related, 9=highly relevant)"), + }, + async ({ query, event, days_back, min_relevance }) => { + const conditions = [`na.published_at > NOW() - INTERVAL '${days_back} days'`]; + const values: unknown[] = []; + let idx = 1; + + if (query) { + conditions.push(`(na.search_vector @@ plainto_tsquery('english', $${idx}) OR na.title ILIKE $${idx + 1})`); + values.push(query, `%${query}%`); + idx += 2; + } + if (event) { + conditions.push(`na.event = $${idx}`); + values.push(event); + idx++; + } + if (min_relevance > 0) { + conditions.push(`na.relevance_score >= $${idx}`); + values.push(min_relevance); + idx++; + } + + const result = await pool.query( + `SELECT na.title, na.source, na.published_at, na.summary, + na.source_url, na.relevance_score, na.event, + na.mentioned_vendors, na.mentioned_products + FROM news_articles na + WHERE ${conditions.join(" AND ")} + ORDER BY na.relevance_score DESC, na.published_at DESC + LIMIT 20`, + values + ); + + const bySource: Record = {}; + for (const row of result.rows) { + bySource[row.source] = (bySource[row.source] || 0) + 1; + } + + return { + content: [{ + type: "text", + text: JSON.stringify({ + articles: result.rows, + count: result.rows.length, + sources: bySource, + period: `Last ${days_back} days`, + }, null, 2), + }], + }; + } + ); + + // --- Tool: generate_blog_draft --- + server.tool( + "generate_blog_draft", + "Generate a blog post draft based on market data, price trends, hype cycle position, and recent news. Saved to blog_drafts table for review.", + { + topic: z.enum(["hype_cycle", "price_trend", "new_product", "comparison", "tutorial"]), + technology: z.string().optional().describe("Technology to focus on, e.g. '800G OSFP', 'DWDM', '400G'"), + target_audience: z.enum(["sales", "technical", "customer", "seo"]).default("technical"), + }, + async ({ topic, technology, target_audience }) => { + // Gather data for the blog post + const data: Record = { topic, technology, target_audience }; + + // Get relevant transceivers + if (technology) { + const txResult = await pool.query( + `SELECT t.standard_name, t.form_factor, t.speed, t.reach_label, + t.fiber_type, t.category, + (SELECT MIN(po.price) FROM price_observations po + WHERE po.transceiver_id = t.id + AND po.time > NOW() - INTERVAL '7 days') as min_price, + (SELECT MAX(po.price) FROM price_observations po + WHERE po.transceiver_id = t.id + AND po.time > NOW() - INTERVAL '7 days') as max_price + FROM transceivers t + WHERE t.standard_name ILIKE $1 OR t.speed ILIKE $1 + LIMIT 10`, + [`%${technology}%`] + ); + data.transceivers = txResult.rows; + } + + // Get recent news + const newsResult = await pool.query( + `SELECT title, source, published_at, summary + FROM news_articles + WHERE ($1 IS NULL OR title ILIKE $1 OR summary ILIKE $1) + ORDER BY relevance_score DESC, published_at DESC + LIMIT 5`, + [technology ? `%${technology}%` : null] + ); + data.recent_news = newsResult.rows; + + // Get price trends + const priceResult = await pool.query( + `SELECT t.standard_name, t.speed, + AVG(po.price) as avg_price, + MIN(po.price) as min_price, + COUNT(DISTINCT po.source_vendor_id) as vendor_count + FROM price_observations po + JOIN transceivers t ON t.id = po.transceiver_id + WHERE ($1 IS NULL OR t.standard_name ILIKE $1 OR t.speed ILIKE $1) + AND po.time > NOW() - INTERVAL '30 days' + GROUP BY t.id, t.standard_name, t.speed + ORDER BY vendor_count DESC + LIMIT 10`, + [technology ? `%${technology}%` : null] + ); + data.price_trends = priceResult.rows; + + // Generate blog outline based on topic and audience + const outlines: Record> = { + hype_cycle: { + sales: [ + `## Where is ${technology || "The Market"} on the Hype Cycle?`, + "## What This Means for Your Customers", + "## When to Buy: Timing the Market", + "## Flexoptix Recommendation", + ], + technical: [ + `## ${technology || "Technology"} Market Analysis — Norton-Bass Diffusion Model`, + "## Current Phase: Technical Readiness", + "## Vendor Ecosystem Status", + "## Price Trajectory & ASP Forecast", + "## Deployment Considerations", + ], + customer: [ + `## Is ${technology || "This Technology"} Right for You?`, + "## Cost vs. Performance Analysis", + "## Compatibility & Migration Path", + "## When Will Prices Drop?", + ], + seo: [ + `## ${technology || "Optical Transceiver"} Market 2026: Complete Guide`, + "## Best Vendors & Pricing Comparison", + "## Compatibility Guide", + "## FAQ", + ], + }, + price_trend: { + sales: ["## Price Alert", "## Competitor Pricing Analysis", "## Sales Opportunity"], + technical: ["## Price Trend Analysis", "## ASP History", "## Market Drivers"], + customer: ["## How Much Should You Pay?", "## Price Forecast", "## When to Buy"], + seo: ["## Price Guide 2026", "## Best Deals", "## Comparison Table"], + }, + comparison: { + sales: ["## Why Flexoptix Beats the Competition", "## Price Advantage", "## Quality & Compatibility"], + technical: ["## Vendor Comparison", "## Spec Analysis", "## Performance Benchmarks"], + customer: ["## OEM vs. Compatible: The Facts", "## Risk Analysis", "## Cost Savings"], + seo: ["## Best Transceiver Vendors 2026", "## Comparison Table", "## Reviews"], + }, + tutorial: { + technical: ["## Prerequisites", "## Step-by-Step Configuration", "## Troubleshooting", "## Verification"], + customer: ["## Getting Started", "## Installation Guide", "## Tips & Tricks"], + sales: ["## Product Overview", "## Use Cases", "## Getting Support"], + seo: ["## How To Guide", "## Step-by-Step", "## FAQ"], + }, + new_product: { + sales: ["## New Product Alert", "## What's New", "## Pricing & Availability"], + technical: ["## Technical Specs", "## Compatibility Matrix", "## Performance Data"], + customer: ["## What You Get", "## Why You Need It", "## How to Order"], + seo: ["## Product Announcement", "## Specs & Features", "## Where to Buy"], + }, + }; + + const outline = outlines[topic]?.[target_audience] || []; + + // Build draft content + const draft = { + title: `${technology || "Optical Transceiver"} ${topic.replace(/_/g, " ")} — ${new Date().getFullYear()} Analysis`, + topic, + technology, + target_audience, + outline, + data_points: data, + generation_note: "This is a data-driven draft. Review and enrich with specific product details before publishing.", + generated_at: new Date().toISOString(), + status: "draft", + }; + + // Save to blog_drafts table + await pool.query( + `INSERT INTO blog_drafts (title, topic, technology, target_audience, outline, draft_content, status) + VALUES ($1, $2, $3, $4, $5, $6, 'draft') + ON CONFLICT DO NOTHING`, + [ + draft.title, + topic, + technology || null, + target_audience, + JSON.stringify(outline), + JSON.stringify(draft), + ] + ); + + return { + content: [{ + type: "text", + text: JSON.stringify({ + draft, + saved_to_database: true, + next_steps: [ + "Review the outline and data points", + "Enrich with specific product examples from search_transceivers", + "Add competitor pricing from compare_prices", + "Include current news context from get_market_news", + "Submit to content team for writing/editing", + ], + }, null, 2), + }], + }; + } + ); +} diff --git a/packages/mcp-server/src/tools/knowledge.ts b/packages/mcp-server/src/tools/knowledge.ts new file mode 100644 index 0000000..2cdade9 --- /dev/null +++ b/packages/mcp-server/src/tools/knowledge.ts @@ -0,0 +1,197 @@ +/** + * Knowledge tools: search_knowledge_base, search_manuals, get_hype_cycle + */ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { z } from "zod"; +import { pool } from "../db.js"; + +export async function registerKnowledgeTools(server: McpServer): Promise { + // --- Tool: search_knowledge_base --- + server.tool( + "search_knowledge_base", + "Search troubleshooting guides, FAQs, and best practices. Use for diagnosing transceiver/switch issues.", + { + query: z.string().describe("Problem description or question, e.g. 'low Rx power QSFP28' or 'link flapping SFP+'"), + category: z.enum(["troubleshooting", "faq", "best_practice", "configuration"]).optional(), + severity: z.enum(["critical", "high", "medium", "low"]).optional().describe("Filter by issue severity"), + }, + async ({ query, category, severity }) => { + const conditions = [`kb.search_vector @@ plainto_tsquery('english', $1)`]; + const values: unknown[] = [query]; + let idx = 2; + + if (category) { + conditions.push(`kb.category = $${idx}`); + values.push(category); + idx++; + } + if (severity) { + conditions.push(`kb.severity = $${idx}`); + values.push(severity); + idx++; + } + + const result = await pool.query( + `SELECT kb.id, kb.title, kb.content, kb.category, kb.severity, + kb.affected_products, kb.resolution, kb.source_url, + ts_rank(kb.search_vector, plainto_tsquery('english', $1)) as rank + FROM knowledge_base kb + WHERE ${conditions.join(" AND ")} + ORDER BY rank DESC + LIMIT 10`, + values + ); + + if (result.rows.length === 0) { + return { + content: [{ + type: "text", + text: `No knowledge base entries found for: "${query}". Knowledge base grows as vendor FAQs are scraped.`, + }], + }; + } + + return { + content: [{ + type: "text", + text: JSON.stringify({ results: result.rows, count: result.rows.length }, null, 2), + }], + }; + } + ); + + // --- Tool: search_manuals --- + server.tool( + "search_manuals", + "Search switch manuals, configuration guides, and compatibility lists. Returns relevant document excerpts.", + { + query: z.string().describe("Query, e.g. 'configure DWDM on Juniper MX' or 'QSFP28 installation guide'"), + vendor: z.string().optional().describe("Document vendor filter, e.g. 'Cisco', 'Juniper', 'Arista'"), + doc_type: z.enum(["manual", "config_guide", "compatibility_list", "datasheet", "release_notes"]).optional(), + }, + async ({ query, vendor, doc_type }) => { + const conditions = [`d.search_vector @@ plainto_tsquery('english', $1)`]; + const values: unknown[] = [query]; + let idx = 2; + + if (vendor) { + conditions.push(`v.name ILIKE $${idx}`); + values.push(`%${vendor}%`); + idx++; + } + if (doc_type) { + conditions.push(`d.doc_type = $${idx}`); + values.push(doc_type); + idx++; + } + + const result = await pool.query( + `SELECT d.id, d.title, d.doc_type, d.version, + v.name as vendor, d.source_url, d.pages, + d.summary, + ts_rank(d.search_vector, plainto_tsquery('english', $1)) as rank + FROM documents d + LEFT JOIN vendors v ON v.id = d.vendor_id + WHERE ${conditions.join(" AND ")} + ORDER BY rank DESC + LIMIT 10`, + values + ); + + if (result.rows.length === 0) { + return { + content: [{ + type: "text", + text: `No manuals found for: "${query}". Document library grows as manuals are processed by OCR pipeline.`, + }], + }; + } + + return { + content: [{ + type: "text", + text: JSON.stringify({ results: result.rows, count: result.rows.length }, null, 2), + }], + }; + } + ); + + // --- Tool: get_hype_cycle --- + server.tool( + "get_hype_cycle", + "Get Hype Cycle position and Norton-Bass diffusion forecast for a transceiver technology. Shows market maturity, adoption phase, and price trajectory.", + { + technology: z.string().describe("Technology to analyze, e.g. '800G OSFP', 'CPO', '400ZR', '100G LR4', 'DWDM'"), + include_forecast: z.boolean().default(true).describe("Include Norton-Bass 5-year adoption forecast"), + }, + async ({ technology, include_forecast }) => { + // Look for market metrics data + const result = await pool.query( + `SELECT mm.time, mm.metric_type, mm.value, mm.unit, mm.vendor_count, + mm.segment, mm.notes + FROM market_metrics mm + WHERE mm.segment ILIKE $1 + OR mm.notes ILIKE $1 + ORDER BY mm.time DESC + LIMIT 50`, + [`%${technology}%`] + ); + + // Also check news for recent developments + const newsResult = await pool.query( + `SELECT title, published_at, source, summary + FROM news_articles + WHERE search_vector @@ plainto_tsquery('english', $1) + OR title ILIKE $2 + ORDER BY published_at DESC + LIMIT 5`, + [technology, `%${technology}%`] + ); + + // Hype Cycle position mapping based on known data + // This will be enriched by Norton-Bass engine (Phase 3) + const hypePositions: Record = { + "1.6T": { phase: "Innovation Trigger", position: 5, description: "Just announced, pre-commercial" }, + "800G": { phase: "Peak of Inflated Expectations", position: 15, description: "High buzz, early deployments" }, + "400G": { phase: "Slope of Enlightenment", position: 70, description: "Proven, cost decreasing, mainstream adoption" }, + "100G": { phase: "Plateau of Productivity", position: 95, description: "Mature, commoditized, price floor reached" }, + "40G": { phase: "Plateau of Productivity", position: 98, description: "Legacy, declining, being replaced by 100G" }, + "CPO": { phase: "Innovation Trigger", position: 3, description: "Research phase, datacenter hyperscalers testing" }, + "400ZR": { phase: "Peak of Inflated Expectations", position: 20, description: "DCI market developing" }, + "OSFP": { phase: "Slope of Enlightenment", position: 40, description: "800G form factor, gaining traction" }, + "DWDM": { phase: "Plateau of Productivity", position: 90, description: "Core long-haul standard, stable market" }, + }; + + let hypeData = null; + for (const [key, data] of Object.entries(hypePositions)) { + if (technology.toLowerCase().includes(key.toLowerCase())) { + hypeData = { technology: key, ...data }; + break; + } + } + + // Norton-Bass forecast placeholder (Phase 3 will compute this) + const forecast = include_forecast ? { + model: "Norton-Bass Multigenerational Diffusion", + note: "Full Norton-Bass computation available in Phase 3 (Hype Cycle Engine)", + estimated_peak_year: hypeData?.position < 20 ? 2027 : + hypeData?.position < 60 ? 2025 : "Already peaked", + current_adoption_pct: hypeData?.position || "Unknown", + price_trend: hypeData?.position && hypeData.position > 70 ? "Declining (-15%/year)" : "Stabilizing", + } : undefined; + + return { + content: [{ + type: "text", + text: JSON.stringify({ + technology, + hype_cycle: hypeData || { note: "Detailed position requires more market data" }, + market_metrics: result.rows, + recent_news: newsResult.rows, + norton_bass_forecast: forecast, + }, null, 2), + }], + }; + } + ); +} diff --git a/packages/mcp-server/src/tools/pricing.ts b/packages/mcp-server/src/tools/pricing.ts new file mode 100644 index 0000000..9cf5b9a --- /dev/null +++ b/packages/mcp-server/src/tools/pricing.ts @@ -0,0 +1,234 @@ +/** + * Pricing tools: get_pricing, compare_prices, get_competitor_stock + */ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { z } from "zod"; +import { pool } from "../db.js"; + +export async function registerPricingTools(server: McpServer): Promise { + // --- Tool: get_pricing --- + server.tool( + "get_pricing", + "Get current prices and availability across all sources for a specific transceiver. Includes price history if requested.", + { + part_number: z.string().describe("Part number or slug, e.g. 'qsfp28-lr4' or 'SFP-10G-LR'"), + vendor: z.string().optional().describe("Filter to specific vendor only"), + include_history: z.boolean().default(false).describe("Include 30-day price history"), + }, + async ({ part_number, vendor, include_history }) => { + // Find transceiver + const txResult = await pool.query( + `SELECT t.id, t.slug, t.standard_name, t.form_factor, t.speed, t.reach_label + FROM transceivers t + WHERE t.slug ILIKE $1 OR t.part_number ILIKE $1 OR t.standard_name ILIKE $1 + LIMIT 1`, + [`%${part_number}%`] + ); + + if (txResult.rows.length === 0) { + return { + content: [{ type: "text", text: `No transceiver found for "${part_number}".` }], + }; + } + + const tx = txResult.rows[0]; + const vendorFilter = vendor ? `AND v.name ILIKE '%${vendor}%'` : ""; + + // Current prices (latest per vendor) + const currentPrices = await pool.query( + `SELECT DISTINCT ON (po.source_vendor_id) + v.name as vendor, po.price, po.currency, po.stock_level, + po.quantity_available, po.url, po.time + FROM price_observations po + JOIN vendors v ON v.id = po.source_vendor_id + WHERE po.transceiver_id = $1 ${vendorFilter} + ORDER BY po.source_vendor_id, po.time DESC`, + [tx.id] + ); + + let history = null; + if (include_history) { + const histResult = await pool.query( + `SELECT v.name as vendor, po.price, po.currency, po.stock_level, po.time + FROM price_observations po + JOIN vendors v ON v.id = po.source_vendor_id + WHERE po.transceiver_id = $1 ${vendorFilter} + AND po.time > NOW() - INTERVAL '30 days' + ORDER BY po.time DESC + LIMIT 200`, + [tx.id] + ); + history = histResult.rows; + } + + const response = { + transceiver: { + slug: tx.slug, + standard: tx.standard_name, + form_factor: tx.form_factor, + speed: tx.speed, + reach: tx.reach_label, + }, + current_prices: currentPrices.rows, + cheapest: currentPrices.rows.length > 0 + ? currentPrices.rows.reduce((min, r) => r.price < min.price ? r : min) + : null, + history: include_history ? history : undefined, + }; + + return { + content: [{ type: "text", text: JSON.stringify(response, null, 2) }], + }; + } + ); + + // --- Tool: compare_prices --- + server.tool( + "compare_prices", + "Compare prices across all vendors for a transceiver. Shows savings opportunities vs competitors.", + { + transceiver_query: z.string().describe("Free text or part number to search for"), + competitors: z.array(z.string()).optional().describe("Limit to specific competitors"), + }, + async ({ transceiver_query, competitors }) => { + const vendorFilter = competitors && competitors.length > 0 + ? `AND v.name ILIKE ANY(ARRAY[${competitors.map((_, i) => `$${i + 2}`).join(",")}])` + : ""; + + const values: unknown[] = [transceiver_query]; + if (competitors) { + competitors.forEach((c) => values.push(`%${c}%`)); + } + + const result = await pool.query( + `SELECT t.slug, t.standard_name, t.form_factor, t.speed, t.reach_label, + v.name as vendor, v.vendor_type, + po.price, po.currency, po.stock_level, po.time + FROM price_observations po + JOIN transceivers t ON t.id = po.transceiver_id + JOIN vendors v ON v.id = po.source_vendor_id + WHERE (t.standard_name ILIKE $1 OR t.slug ILIKE $1) + ${vendorFilter} + AND po.time = ( + SELECT MAX(time) FROM price_observations + WHERE transceiver_id = t.id AND source_vendor_id = v.id + ) + ORDER BY t.slug, po.price ASC`, + values + ); + + if (result.rows.length === 0) { + return { + content: [{ type: "text", text: `No pricing data found for "${transceiver_query}".` }], + }; + } + + // Group by transceiver + const grouped: Record; + min_price: number; + max_price: number; + savings_vs_max: number; + }> = {}; + + for (const row of result.rows) { + if (!grouped[row.slug]) { + grouped[row.slug] = { + transceiver: { + slug: row.slug, + standard: row.standard_name, + form_factor: row.form_factor, + speed: row.speed, + reach: row.reach_label, + }, + prices: [], + min_price: Infinity, + max_price: 0, + savings_vs_max: 0, + }; + } + grouped[row.slug].prices.push({ + vendor: row.vendor, + type: row.vendor_type, + price: parseFloat(row.price), + currency: row.currency, + stock: row.stock_level, + }); + grouped[row.slug].min_price = Math.min(grouped[row.slug].min_price, parseFloat(row.price)); + grouped[row.slug].max_price = Math.max(grouped[row.slug].max_price, parseFloat(row.price)); + } + + for (const slug of Object.keys(grouped)) { + const g = grouped[slug]; + g.savings_vs_max = Math.round((1 - g.min_price / g.max_price) * 100); + } + + return { + content: [{ + type: "text", + text: JSON.stringify({ comparisons: Object.values(grouped) }, null, 2), + }], + }; + } + ); + + // --- Tool: get_competitor_stock --- + server.tool( + "get_competitor_stock", + "Check live stock levels at a specific competitor. Useful for identifying sales opportunities when competitor is out of stock.", + { + competitor: z.string().describe("Competitor name, e.g. 'FS.COM', 'Optcore', 'ProLabs'"), + product_query: z.string().optional().describe("Optional product filter"), + out_of_stock_only: z.boolean().default(false).describe("Only show out-of-stock items (sales opportunities)"), + }, + async ({ competitor, product_query, out_of_stock_only }) => { + const conditions = [`v.name ILIKE $1`]; + const values: unknown[] = [`%${competitor}%`]; + let idx = 2; + + if (product_query) { + conditions.push(`(t.standard_name ILIKE $${idx} OR t.slug ILIKE $${idx})`); + values.push(`%${product_query}%`); + idx++; + } + + if (out_of_stock_only) { + conditions.push(`po.stock_level IN ('out_of_stock', 'discontinued')`); + } + + const result = await pool.query( + `SELECT DISTINCT ON (t.id) + v.name as competitor, t.slug, t.standard_name, t.form_factor, t.speed, + t.reach_label, po.price, po.currency, po.stock_level, + po.quantity_available, po.time + FROM price_observations po + JOIN vendors v ON v.id = po.source_vendor_id + JOIN transceivers t ON t.id = po.transceiver_id + WHERE ${conditions.join(" AND ")} + ORDER BY t.id, po.time DESC + LIMIT 100`, + values + ); + + const inStock = result.rows.filter((r) => r.stock_level === "in_stock").length; + const outOfStock = result.rows.filter((r) => + ["out_of_stock", "discontinued"].includes(r.stock_level) + ).length; + + return { + content: [{ + type: "text", + text: JSON.stringify({ + competitor, + summary: { total: result.rows.length, in_stock: inStock, out_of_stock: outOfStock }, + items: result.rows, + sales_opportunities: out_of_stock_only + ? result.rows.length + : `${outOfStock} items out of stock at ${competitor}`, + }, null, 2), + }], + }; + } + ); +} diff --git a/tsconfig.json b/packages/mcp-server/tsconfig.json similarity index 74% rename from tsconfig.json rename to packages/mcp-server/tsconfig.json index b2640bd..eeee132 100644 --- a/tsconfig.json +++ b/packages/mcp-server/tsconfig.json @@ -1,19 +1,18 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "module": "commonjs", - "lib": ["ES2020"], - "declaration": true, - "declarationMap": true, - "sourceMap": true, + "lib": ["ES2022"], "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, - "moduleResolution": "node" + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "isolatedModules": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] diff --git a/src/breakouts.ts b/src/breakouts.ts deleted file mode 100644 index e3377ba..0000000 --- a/src/breakouts.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Breakout cable configurations. - * Maps high-speed ports to multiple lower-speed connections. - */ - -import type { Breakout } from "./types"; - -export const breakouts: readonly Breakout[] = [ - { id: "40g-4x10g-sr", from: "40GBASE-SR4", to: "4x 10GBASE-SR", formFactor: "QSFP+ to 4x SFP+", description: "Break out one 40G QSFP+ port into four 10G SFP+ ports. Uses MPO-to-LC harness.", cableType: "Passive", maxLength: "5m (passive) / 100m (active)", speedPerLane: "10G" }, - { id: "40g-4x10g-aoc", from: "40GBASE-SR4", to: "4x 10GBASE-SR", formFactor: "QSFP+ to 4x SFP+ AOC", description: "Active optical breakout cable from 40G QSFP+ to four 10G SFP+.", cableType: "Active", maxLength: "1-30m", speedPerLane: "10G" }, - { id: "100g-4x25g-sr", from: "100GBASE-SR4", to: "4x 25GBASE-SR", formFactor: "QSFP28 to 4x SFP28", description: "Break out one 100G QSFP28 port into four 25G SFP28 ports.", cableType: "Passive", maxLength: "5m (passive) / 100m (active)", speedPerLane: "25G" }, - { id: "100g-4x25g-dac", from: "100G QSFP28", to: "4x 25G SFP28", formFactor: "QSFP28 to 4x SFP28 DAC", description: "Passive copper breakout DAC from 100G QSFP28 to four 25G SFP28.", cableType: "Passive", maxLength: "1-5m", speedPerLane: "25G" }, - { id: "400g-4x100g-dr", from: "400GBASE-DR4", to: "4x 100GBASE-DR", formFactor: "QSFP-DD to 4x QSFP28 (MPO-12 to 4x LC)", description: "Break out one 400G DR4 port into four 100G DR ports. Parallel SMF to duplex LC.", cableType: "Passive", maxLength: "500m (fiber reach)", speedPerLane: "100G" }, - { id: "400g-4x100g-fr", from: "400GBASE-XDR4", to: "4x 100GBASE-FR1", formFactor: "QSFP-DD to 4x QSFP28", description: "Break out one 400G XDR4 port into four 100G FR1 ports. 2km reach per lane.", cableType: "Passive", maxLength: "2km (fiber reach)", speedPerLane: "100G" }, - { id: "400g-4x100g-lr", from: "400G-PLR4", to: "4x 100GBASE-LR1", formFactor: "QSFP-DD to 4x QSFP28", description: "Break out one 400G PLR4 port into four 100G LR1 ports. 10km reach per lane.", cableType: "Passive", maxLength: "10km (fiber reach)", speedPerLane: "100G" }, - { id: "800g-2x400g-dr", from: "800GBASE-DR8", to: "2x 400GBASE-DR4", formFactor: "OSFP to 2x QSFP-DD", description: "Break out one 800G DR8 port into two 400G DR4 ports.", cableType: "Passive", maxLength: "500m (fiber reach)", speedPerLane: "100G" }, - { id: "800g-8x100g-dr", from: "800GBASE-DR8", to: "8x 100GBASE-DR", formFactor: "OSFP to 8x QSFP28", description: "Break out one 800G DR8 port into eight 100G DR ports.", cableType: "Passive", maxLength: "500m (fiber reach)", speedPerLane: "100G" }, - { id: "200g-4x50g-sr", from: "200GBASE-SR4", to: "4x 50GBASE-SR", formFactor: "QSFP56 to 4x SFP56", description: "Break out one 200G SR4 port into four 50G SR ports.", cableType: "Passive", maxLength: "100m (OM4)", speedPerLane: "50G" }, - { id: "200g-2x100g-dr", from: "200GBASE-DR4", to: "2x 100GBASE-DR", formFactor: "QSFP56 to 2x QSFP28", description: "Break out one 200G DR4 port into two 100G DR ports.", cableType: "Passive", maxLength: "500m (fiber reach)", speedPerLane: "50G" }, -]; diff --git a/src/database.ts b/src/database.ts deleted file mode 100644 index 3ffebcc..0000000 --- a/src/database.ts +++ /dev/null @@ -1,217 +0,0 @@ -/** - * Transceiver product database — 159 optical transceiver products. - * Covers GBIC, XFP, SFP, SFP+, SFP28, SFP56, QSFP+, QSFP28, QSFP56, - * QSFP-DD, OSFP, CFP/CFP2/CFP4, CFP2-DCO, CXP, DAC, and AOC. - * - * Speeds: 1G, 10G, 25G, 40G, 50G, 100G, 200G, 400G, 800G. - * - * Data sourced from publicly available IEEE standards, MSA specifications, - * vendor datasheets, and industry documentation. - */ - -import type { Transceiver, VendorCompat } from "./types"; - -// Vendor shorthand helpers (internal) -const V_CISCO: VendorCompat = { vendor: "Cisco", partPattern: "SFP-*-*" }; -const V_JUNIPER: VendorCompat = { vendor: "Juniper", partPattern: "EX-SFP-*" }; -const V_ARISTA: VendorCompat = { vendor: "Arista", partPattern: "SFP-*-*" }; -const V_HUAWEI: VendorCompat = { vendor: "Huawei", partPattern: "SFP-*-*" }; -const V_NOKIA: VendorCompat = { vendor: "Nokia", partPattern: "3HE*" }; -const V_HPE: VendorCompat = { vendor: "HPE/Aruba", partPattern: "J*" }; -const V_DELL: VendorCompat = { vendor: "Dell", partPattern: "407-*" }; -const V_EXTREME: VendorCompat = { vendor: "Extreme", partPattern: "10*" }; -const V_NVIDIA: VendorCompat = { vendor: "NVIDIA", partPattern: "MMS4*|MMA1*" }; - -function allMajorVendors(): VendorCompat[] { - return [V_CISCO, V_JUNIPER, V_ARISTA, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME]; -} - -function dcVendors(): VendorCompat[] { - return [V_CISCO, V_JUNIPER, V_ARISTA, V_HUAWEI, V_DELL, V_EXTREME]; -} - -function carrierVendors(): VendorCompat[] { - return [V_CISCO, V_JUNIPER, V_HUAWEI, V_NOKIA]; -} - -/** - * Complete transceiver database — all 159 products. - */ -export const transceivers: readonly Transceiver[] = [ - // ── GBIC — 1G Legacy ── - { id: "gbic-sx", standard: "1000BASE-SX", formFactor: "GBIC", speed: "1G", speedGbps: 1, reachMeters: 550, reachLabel: "550m", fiberType: "MMF", wavelengths: "850nm", connector: "SC", powerConsumptionW: 1.5, tempRange: "COM", category: "Legacy", priceTier: "Budget", useCase: "Legacy 1G multimode short-reach links in older switches using GBIC slots.", vendors: [{ vendor: "Cisco", partPattern: "WS-G5484" }, { vendor: "Juniper", partPattern: "SRX-SFP-1GE-SX" }], tags: ["1G", "legacy", "multimode", "short-reach", "GBIC"] }, - { id: "gbic-lx", standard: "1000BASE-LX", formFactor: "GBIC", speed: "1G", speedGbps: 1, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "SC", powerConsumptionW: 1.5, tempRange: "COM", category: "Legacy", priceTier: "Budget", useCase: "Legacy 1G single-mode links up to 10km in older GBIC-slot equipment.", vendors: [{ vendor: "Cisco", partPattern: "WS-G5486" }], tags: ["1G", "legacy", "singlemode", "10km", "GBIC"] }, - - // ── SFP — 1G ── - { id: "sfp-sx", standard: "1000BASE-SX", formFactor: "SFP", speed: "1G", speedGbps: 1, reachMeters: 550, reachLabel: "550m", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 0.8, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "Standard 1G multimode short-reach for data center and campus backbone links.", vendors: [{ vendor: "Cisco", partPattern: "GLC-SX-MMD" }, { vendor: "Juniper", partPattern: "EX-SFP-1GE-SX" }, { vendor: "Arista", partPattern: "SFP-1G-SX" }, { vendor: "Huawei", partPattern: "SFP-GE-SX" }, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["1G", "multimode", "short-reach", "campus", "SFP"] }, - { id: "sfp-lx", standard: "1000BASE-LX", formFactor: "SFP", speed: "1G", speedGbps: 1, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 0.8, tempRange: "COM", category: "Metro", priceTier: "Budget", useCase: "1G single-mode for campus/metro links up to 10km. Most common 1G SFP.", vendors: [{ vendor: "Cisco", partPattern: "GLC-LH-SMD" }, { vendor: "Juniper", partPattern: "EX-SFP-1GE-LX" }, { vendor: "Arista", partPattern: "SFP-1G-LX" }, { vendor: "Huawei", partPattern: "SFP-GE-LX-SM1310" }, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["1G", "singlemode", "10km", "metro", "campus", "SFP"] }, - { id: "sfp-zx", standard: "1000BASE-ZX", formFactor: "SFP", speed: "1G", speedGbps: 1, reachMeters: 80000, reachLabel: "80km", fiberType: "SMF", wavelengths: "1550nm", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "LongHaul", priceTier: "Standard", useCase: "1G long-haul single-mode up to 80km for inter-city or metro ring links.", vendors: [{ vendor: "Cisco", partPattern: "GLC-ZX-SMD" }, { vendor: "Juniper", partPattern: "SFP-1GE-LH" }, V_HUAWEI, V_NOKIA], tags: ["1G", "singlemode", "80km", "long-haul", "SFP"] }, - { id: "sfp-t", standard: "1000BASE-T", formFactor: "SFP", speed: "1G", speedGbps: 1, reachMeters: 100, reachLabel: "100m", fiberType: "Copper", wavelengths: "N/A", connector: "RJ45", powerConsumptionW: 1.0, tempRange: "COM", category: "Access", priceTier: "Budget", useCase: "1G copper SFP for short-reach RJ45 connections to servers or endpoints.", vendors: allMajorVendors(), tags: ["1G", "copper", "RJ45", "access", "SFP"] }, - { id: "sfp-bidi-1310-1550", standard: "1000BASE-BX10", formFactor: "SFP", speed: "1G", speedGbps: 1, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm TX / 1550nm RX", connector: "LC", powerConsumptionW: 0.8, tempRange: "COM", category: "BiDi", priceTier: "Standard", useCase: "Bidirectional 1G over a single fiber strand. Sold in pairs (upstream/downstream). Saves fiber.", vendors: [{ vendor: "Cisco", partPattern: "GLC-BX-U / GLC-BX-D" }, { vendor: "Juniper", partPattern: "SFP-1GE-BX" }, V_ARISTA, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["1G", "BiDi", "single-fiber", "singlemode", "10km", "SFP"] }, - { id: "sfp-cwdm-1470", standard: "SFP CWDM", formFactor: "SFP", speed: "1G", speedGbps: 1, reachMeters: 80000, reachLabel: "40-80km", fiberType: "SMF", wavelengths: "1470-1610nm (8 channels, 20nm spacing)", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "CWDM", priceTier: "Standard", useCase: "1G CWDM for multiplexing up to 8 channels on a single fiber pair. Cost-effective WDM.", vendors: [{ vendor: "Cisco", partPattern: "CWDM-SFP-*" }, { vendor: "Juniper", partPattern: "SFP-1GE-CWDM*" }, V_HUAWEI, V_NOKIA], tags: ["1G", "CWDM", "WDM", "multiplexing", "SFP"] }, - - // ── XFP — 10G Legacy ── - { id: "xfp-sr", standard: "10GBASE-SR", formFactor: "XFP", speed: "10G", speedGbps: 10, reachMeters: 300, reachLabel: "300m", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "Legacy", priceTier: "Budget", useCase: "Legacy 10G short-reach for older platforms with XFP slots. Replaced by SFP+ in modern gear.", vendors: [{ vendor: "Cisco", partPattern: "XFP-10G-MM-SR" }, { vendor: "Juniper", partPattern: "XFP-10G-S" }], tags: ["10G", "legacy", "multimode", "short-reach", "XFP"] }, - { id: "xfp-lr", standard: "10GBASE-LR", formFactor: "XFP", speed: "10G", speedGbps: 10, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "Legacy", priceTier: "Budget", useCase: "Legacy 10G single-mode for metro links on older XFP-based routers.", vendors: [{ vendor: "Cisco", partPattern: "XFP-10GLR-OC192SR" }, { vendor: "Juniper", partPattern: "XFP-10G-L-OC192-SR1" }], tags: ["10G", "legacy", "singlemode", "10km", "XFP"] }, - { id: "xfp-er", standard: "10GBASE-ER", formFactor: "XFP", speed: "10G", speedGbps: 10, reachMeters: 40000, reachLabel: "40km", fiberType: "SMF", wavelengths: "1550nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "Legacy", priceTier: "Standard", useCase: "Legacy 10G extended reach for metro/regional links on XFP platforms.", vendors: [{ vendor: "Cisco", partPattern: "XFP-10GER-OC192IR" }, { vendor: "Juniper", partPattern: "XFP-10GE-ER" }], tags: ["10G", "legacy", "singlemode", "40km", "XFP", "extended-reach"] }, - - // ── SFP+ — 10G ── - { id: "sfpp-sr", standard: "10GBASE-SR", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 300, reachLabel: "300m (OM3) / 400m (OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "The workhorse of 10G data center connectivity. Short-reach multimode for server-to-switch links.", vendors: [{ vendor: "Cisco", partPattern: "SFP-10G-SR" }, { vendor: "Juniper", partPattern: "EX-SFP-10GE-SR" }, { vendor: "Arista", partPattern: "SFP-10G-SR" }, { vendor: "Huawei", partPattern: "SFP-10G-USR" }, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["10G", "multimode", "short-reach", "data-center", "server", "SFP+"] }, - { id: "sfpp-lr", standard: "10GBASE-LR", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "Metro", priceTier: "Budget", useCase: "10G single-mode for campus backbone and metro links up to 10km.", vendors: [{ vendor: "Cisco", partPattern: "SFP-10G-LR" }, { vendor: "Juniper", partPattern: "EX-SFP-10GE-LR" }, { vendor: "Arista", partPattern: "SFP-10G-LR" }, { vendor: "Huawei", partPattern: "SFP-10G-LR" }, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["10G", "singlemode", "10km", "metro", "campus", "SFP+"] }, - { id: "sfpp-er", standard: "10GBASE-ER", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 40000, reachLabel: "40km", fiberType: "SMF", wavelengths: "1550nm", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "10G extended reach for metro rings and inter-building links up to 40km.", vendors: [{ vendor: "Cisco", partPattern: "SFP-10G-ER" }, { vendor: "Juniper", partPattern: "EX-SFP-10GE-ER" }, { vendor: "Arista", partPattern: "SFP-10G-ER" }, V_HUAWEI, V_NOKIA], tags: ["10G", "singlemode", "40km", "metro", "extended-reach", "SFP+"] }, - { id: "sfpp-zr", standard: "10GBASE-ZR", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 80000, reachLabel: "80km", fiberType: "SMF", wavelengths: "1550nm", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "LongHaul", priceTier: "Standard", useCase: "10G long-reach for inter-city metro and regional network links up to 80km.", vendors: [{ vendor: "Cisco", partPattern: "SFP-10G-ZR" }, { vendor: "Juniper", partPattern: "SFP-10GE-ZR" }, V_HUAWEI, V_NOKIA], tags: ["10G", "singlemode", "80km", "long-haul", "SFP+"] }, - { id: "sfpp-bidi-10", standard: "10GBASE-BX", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1270nm TX / 1330nm RX", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "BiDi", priceTier: "Standard", useCase: "Bidirectional 10G over single fiber. Pairs required (upstream/downstream). Halves fiber count.", vendors: [{ vendor: "Cisco", partPattern: "SFP-10G-BXU-I / SFP-10G-BXD-I" }, { vendor: "Juniper", partPattern: "SFP-10GE-BX" }, V_ARISTA, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["10G", "BiDi", "single-fiber", "singlemode", "10km", "SFP+"] }, - { id: "sfpp-cwdm", standard: "10G SFP+ CWDM", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 80000, reachLabel: "40-80km", fiberType: "SMF", wavelengths: "1270-1610nm (18 channels, 20nm spacing)", connector: "LC", powerConsumptionW: 1.2, tempRange: "COM", category: "CWDM", priceTier: "Standard", useCase: "10G CWDM SFP+ for WDM multiplexing. Up to 18 channels over a single fiber pair.", vendors: [{ vendor: "Cisco", partPattern: "CWDM-SFP10G-*" }, { vendor: "Juniper", partPattern: "SFP-10GE-CWDM*" }, V_HUAWEI, V_NOKIA], tags: ["10G", "CWDM", "WDM", "multiplexing", "SFP+"] }, - { id: "sfpp-dwdm", standard: "10G SFP+ DWDM", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 80000, reachLabel: "40-80km", fiberType: "SMF", wavelengths: "C-band (1528-1565nm, 80+ channels, 100GHz/50GHz spacing)", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "DWDM", priceTier: "Premium", useCase: "10G DWDM for high-density wavelength multiplexing. 80+ channels on C-band. Fixed or tunable.", vendors: [{ vendor: "Cisco", partPattern: "DWDM-SFP10G-*" }, { vendor: "Juniper", partPattern: "SFP-10GE-DWDM*" }, V_HUAWEI, V_NOKIA], tags: ["10G", "DWDM", "WDM", "C-band", "tunable", "SFP+"] }, - { id: "sfpp-t", standard: "10GBASE-T", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 30, reachLabel: "30m", fiberType: "Copper", wavelengths: "N/A", connector: "RJ45", powerConsumptionW: 2.5, tempRange: "COM", category: "Access", priceTier: "Budget", useCase: "10G copper SFP+ for short-reach RJ45 connections. Higher power than fiber variants.", vendors: allMajorVendors(), tags: ["10G", "copper", "RJ45", "access", "SFP+"] }, - { id: "sfpp-usr", standard: "10GBASE-USR", ieeeReference: "SFF-8431", formFactor: "SFP+", speed: "10G", speedGbps: 10, lanes: 1, laneRate: "10.3125 Gbaud", modulation: "NRZ", reachMeters: 100, reachLabel: "10-100m (OM3/OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "Ultra short-reach 10G for within-rack and adjacent-rack connections.", vendors: [{ vendor: "Cisco", partPattern: "SFP-10G-SR" }, { vendor: "Huawei", partPattern: "SFP-10G-USR" }], tags: ["10G", "multimode", "ultra-short-reach", "data-center", "SFP+"], generation: "Gen1 NRZ", marketStatus: "Mainstream" }, - { id: "sfpp-lrm", standard: "10GBASE-LRM", ieeeReference: "IEEE 802.3aq", formFactor: "SFP+", speed: "10G", speedGbps: 10, lanes: 1, laneRate: "10.3125 Gbaud", modulation: "NRZ", reachMeters: 220, reachLabel: "220m (FDDI/OM1 legacy MMF)", fiberType: "MMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "10G over legacy multimode fiber (OM1/OM2). Uses 1310nm to achieve 220m on older fiber.", vendors: [{ vendor: "Cisco", partPattern: "SFP-10G-LRM" }, { vendor: "Juniper", partPattern: "EX-SFP-10GE-LRM" }], tags: ["10G", "multimode", "legacy-fiber", "LRM", "SFP+"], generation: "Gen1 NRZ", marketStatus: "Legacy", yearIntroduced: 2006 }, - - // ── SFP28 — 25G ── - { id: "sfp28-sr", standard: "25GBASE-SR", ieeeReference: "IEEE 802.3by", formFactor: "SFP28", speed: "25G", speedGbps: 25, lanes: 1, laneRate: "25.78125 Gbaud", modulation: "NRZ", reachMeters: 100, reachLabel: "70m (OM3) / 100m (OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "Standard 25G data center server access. Replaced 10G SFP+ in hyperscale deployments.", vendors: [{ vendor: "Cisco", partPattern: "SFP-25G-SR-S" }, { vendor: "Juniper", partPattern: "SFP-25G-SR" }, { vendor: "Arista", partPattern: "SFP-25G-SR" }, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["25G", "multimode", "short-reach", "data-center", "server", "SFP28"], generation: "Gen1 NRZ", marketStatus: "Mainstream", yearIntroduced: 2016 }, - { id: "sfp28-lr", standard: "25GBASE-LR", ieeeReference: "IEEE 802.3cc", formFactor: "SFP28", speed: "25G", speedGbps: 25, lanes: 1, laneRate: "25.78125 Gbaud", modulation: "NRZ", reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.0, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "25G single-mode for campus backbone and 5G fronthaul links up to 10km.", vendors: [{ vendor: "Cisco", partPattern: "SFP-25G-LR-S" }, { vendor: "Juniper", partPattern: "SFP-25G-LR" }, { vendor: "Arista", partPattern: "SFP-25G-LR" }, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["25G", "singlemode", "10km", "metro", "5G-fronthaul", "SFP28"], generation: "Gen1 NRZ", marketStatus: "Growth", yearIntroduced: 2017 }, - { id: "sfp28-er", standard: "25GBASE-ER", ieeeReference: "IEEE 802.3cc", formFactor: "SFP28", speed: "25G", speedGbps: 25, lanes: 1, laneRate: "25.78125 Gbaud", modulation: "NRZ", reachMeters: 30000, reachLabel: "30km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "25G extended reach for metro and 5G midhaul applications.", vendors: [{ vendor: "Cisco", partPattern: "SFP-25G-ER-S" }, { vendor: "Juniper", partPattern: "SFP-25G-ER" }], tags: ["25G", "singlemode", "30km", "metro", "5G-midhaul", "SFP28"], generation: "Gen1 NRZ", marketStatus: "Growth", yearIntroduced: 2017 }, - { id: "sfp28-bidi", standard: "25GBASE-BX", formFactor: "SFP28", speed: "25G", speedGbps: 25, lanes: 1, modulation: "NRZ", reachMeters: 10000, reachLabel: "10-30km", fiberType: "SMF", wavelengths: "1270nm TX / 1330nm RX (or reverse)", connector: "LC", powerConsumptionW: 1.2, tempRange: "COM", category: "BiDi", priceTier: "Standard", useCase: "Bidirectional 25G over single fiber. Sold in pairs. Ideal for 5G fronthaul with limited fiber.", vendors: [{ vendor: "Cisco", partPattern: "SFP-25G-BX*" }, V_JUNIPER, V_ARISTA, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["25G", "BiDi", "single-fiber", "singlemode", "5G", "SFP28"], generation: "Gen1 NRZ", marketStatus: "Growth" }, - { id: "sfp28-cwdm", standard: "25G SFP28 CWDM", formFactor: "SFP28", speed: "25G", speedGbps: 25, lanes: 1, modulation: "NRZ", reachMeters: 40000, reachLabel: "10-40km", fiberType: "SMF", wavelengths: "1270-1610nm (CWDM channels, 20nm spacing)", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "CWDM", priceTier: "Standard", useCase: "25G CWDM for wavelength multiplexing. Enables multiple 25G channels over a single fiber pair for 5G midhaul aggregation.", vendors: carrierVendors(), tags: ["25G", "CWDM", "WDM", "5G", "aggregation", "SFP28"], generation: "Gen1 NRZ", marketStatus: "Growth" }, - { id: "sfp28-lr-ind", standard: "25GBASE-LR Industrial", ieeeReference: "IEEE 802.3cc", formFactor: "SFP28", speed: "25G", speedGbps: 25, lanes: 1, modulation: "NRZ", reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.2, tempRange: "IND", category: "5G", priceTier: "Premium", useCase: "Industrial temperature 25G SFP28 for 5G fronthaul in outdoor cabinets. Rated -40C to +85C.", vendors: carrierVendors(), tags: ["25G", "industrial", "outdoor", "5G", "fronthaul", "SFP28"], generation: "Gen1 NRZ", marketStatus: "Growth" }, - - // ── SFP56 — 50G ── - { id: "sfp56-sr", standard: "50GBASE-SR", ieeeReference: "IEEE 802.3cd", formFactor: "SFP56", speed: "50G", speedGbps: 50, lanes: 1, laneRate: "26.5625 Gbaud", modulation: "PAM4", reachMeters: 100, reachLabel: "70m (OM3) / 100m (OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "50G single-lane for emerging high-density server access. Used in 200G-SR4 breakout scenarios.", vendors: dcVendors(), tags: ["50G", "multimode", "short-reach", "PAM4", "SFP56", "data-center"], generation: "Gen2 PAM4", marketStatus: "Growth", yearIntroduced: 2019 }, - { id: "sfp56-lr", standard: "50GBASE-LR", formFactor: "SFP56", speed: "50G", speedGbps: 50, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.5, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "50G single-mode for high-bandwidth campus and metro links.", vendors: dcVendors(), tags: ["50G", "PAM4", "singlemode", "10km", "SFP56"] }, - - // ── QSFP+ — 40G ── - { id: "qsfpp-sr4", standard: "40GBASE-SR4", formFactor: "QSFP+", speed: "40G", speedGbps: 40, reachMeters: 150, reachLabel: "100m (OM3) / 150m (OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "MPO-12", powerConsumptionW: 2.5, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "Standard 40G multimode for data center spine-leaf links using MPO cabling.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-40G-SR4" }, { vendor: "Juniper", partPattern: "QSFP-40G-SR4" }, { vendor: "Arista", partPattern: "QSFP-40G-SR4" }, { vendor: "Huawei", partPattern: "QSFP-40G-SR4" }, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["40G", "multimode", "short-reach", "data-center", "MPO", "QSFP+"] }, - { id: "qsfpp-lr4", standard: "40GBASE-LR4", formFactor: "QSFP+", speed: "40G", speedGbps: 40, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1271/1291/1311/1331nm (4 CWDM lanes)", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "40G single-mode for campus backbone and DCI links up to 10km using LC duplex fiber.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-40G-LR4" }, { vendor: "Juniper", partPattern: "QSFP-40G-LR4" }, { vendor: "Arista", partPattern: "QSFP-40G-LR4" }, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["40G", "singlemode", "10km", "metro", "CWDM", "DCI", "QSFP+"] }, - { id: "qsfpp-er4", standard: "40GBASE-ER4", formFactor: "QSFP+", speed: "40G", speedGbps: 40, reachMeters: 40000, reachLabel: "40km", fiberType: "SMF", wavelengths: "1271/1291/1311/1331nm (4 CWDM lanes)", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "Metro", priceTier: "Premium", useCase: "40G extended reach for metro and DCI links up to 40km.", vendors: carrierVendors(), tags: ["40G", "singlemode", "40km", "metro", "extended-reach", "QSFP+"] }, - { id: "qsfpp-sr-bidi", standard: "40GBASE-SR-BiDi", formFactor: "QSFP+", speed: "40G", speedGbps: 40, reachMeters: 150, reachLabel: "100m (OM3) / 150m (OM4)", fiberType: "MMF", wavelengths: "832nm / 918nm BiDi", connector: "LC", powerConsumptionW: 2.5, tempRange: "COM", category: "BiDi", priceTier: "Standard", useCase: "40G BiDi multimode over LC duplex. Enables 40G upgrade reusing existing 10G LC cabling.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-40G-SR-BD" }, { vendor: "Arista", partPattern: "QSFP-40G-SRBD" }, V_JUNIPER, V_HUAWEI, V_DELL, V_EXTREME], tags: ["40G", "BiDi", "multimode", "LC-reuse", "data-center", "QSFP+"] }, - - // ── QSFP28 — 100G ── - { id: "qsfp28-sr4", standard: "100GBASE-SR4", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 100, reachLabel: "70m (OM3) / 100m (OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "MPO-12", powerConsumptionW: 3.5, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "Standard 100G multimode for data center spine-leaf. The most deployed 100G optic. Breakout to 4x25G possible.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-SR4-S" }, { vendor: "Juniper", partPattern: "QSFP-100G-SR4" }, { vendor: "Arista", partPattern: "QSFP-100G-SR4" }, { vendor: "Huawei", partPattern: "QSFP-100G-SR4" }, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["100G", "multimode", "short-reach", "data-center", "MPO", "breakout", "QSFP28", "IXP"] }, - { id: "qsfp28-sr1", standard: "100GBASE-SR1", ieeeReference: "IEEE 802.3cd", formFactor: "QSFP28", speed: "100G", speedGbps: 100, lanes: 1, laneRate: "53.125 Gbaud", modulation: "PAM4", reachMeters: 100, reachLabel: "70m (OM3) / 100m (OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "100G single-lane over duplex LC MMF. Uses PAM4 modulation. Simpler and cheaper than SR4.", vendors: dcVendors(), tags: ["100G", "multimode", "short-reach", "PAM4", "duplex-LC", "QSFP28"], generation: "Gen2 PAM4", marketStatus: "Growth", yearIntroduced: 2018 }, - { id: "qsfp28-sr2", standard: "100GBASE-SR2", ieeeReference: "100G Lambda MSA", formFactor: "QSFP28", speed: "100G", speedGbps: 100, lanes: 2, laneRate: "26.5625 Gbaud", modulation: "PAM4", reachMeters: 100, reachLabel: "100m (OM4)", fiberType: "MMF", wavelengths: "850nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "100G SR2 uses 2x50G PAM4 over duplex LC. No MPO needed. Popular in DCs moving to duplex fiber.", vendors: dcVendors(), tags: ["100G", "multimode", "duplex-LC", "short-reach", "data-center", "PAM4", "QSFP28"], generation: "Gen2 PAM4", marketStatus: "Mainstream", yearIntroduced: 2018 }, - { id: "qsfp28-dr1", standard: "100GBASE-DR1", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 500, reachLabel: "500m", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "100G single-lane single-mode for intra-campus data center. Uses PAM4 modulation.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-DR-S" }, { vendor: "Arista", partPattern: "QSFP-100G-DR" }, V_JUNIPER, V_HUAWEI, V_DELL, V_EXTREME], tags: ["100G", "singlemode", "500m", "data-center", "PAM4", "single-lane", "QSFP28"] }, - { id: "qsfp28-fr1", standard: "100GBASE-FR1", ieeeReference: "IEEE 802.3cu", formFactor: "QSFP28", speed: "100G", speedGbps: 100, lanes: 1, laneRate: "53.125 Gbaud", modulation: "PAM4", reachMeters: 2000, reachLabel: "2km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "DCI", priceTier: "Standard", useCase: "100G single-lambda for 2km campus DCI. Interworks with 400GBASE-FR4 breakout.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-FR-S" }, { vendor: "Juniper", partPattern: "QSFP-100G-FR" }, { vendor: "Arista", partPattern: "QSFP-100G-FR" }, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["100G", "singlemode", "2km", "DCI", "campus", "PAM4", "QSFP28"], generation: "Gen2 PAM4", marketStatus: "Growth", yearIntroduced: 2021 }, - { id: "qsfp28-lr1", standard: "100GBASE-LR1", ieeeReference: "IEEE 802.3cu", formFactor: "QSFP28", speed: "100G", speedGbps: 100, lanes: 1, laneRate: "53.125 Gbaud", modulation: "PAM4", reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "IXP", priceTier: "Standard", useCase: "100G single-lambda for 10km. The new IXP standard (100G LR-1) replacing LR4 at major exchanges.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-LR1-S" }, { vendor: "Juniper", partPattern: "QSFP-100G-LR1" }, { vendor: "Nokia", partPattern: "3HE*" }, V_ARISTA, V_HUAWEI, V_HPE, V_DELL, V_EXTREME], tags: ["100G", "singlemode", "10km", "IXP", "LR-1", "PAM4", "QSFP28"], generation: "Gen2 PAM4", marketStatus: "Growth", yearIntroduced: 2021 }, - { id: "qsfp28-lr4", standard: "100GBASE-LR4", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm (4 LAN-WDM lanes)", connector: "LC", powerConsumptionW: 4.5, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "100G single-mode for metro DCI and campus backbone up to 10km. Uses 4x25G LAN-WDM lanes.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-LR4-S" }, { vendor: "Juniper", partPattern: "QSFP-100G-LR4" }, { vendor: "Arista", partPattern: "QSFP-100G-LR4" }, { vendor: "Huawei", partPattern: "QSFP-100G-LR4" }, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["100G", "singlemode", "10km", "metro", "DCI", "LAN-WDM", "QSFP28", "IXP"] }, - { id: "qsfp28-cwdm4", standard: "100G CWDM4", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 2000, reachLabel: "2km", fiberType: "SMF", wavelengths: "1271/1291/1311/1331nm (4 CWDM lanes)", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "DCI", priceTier: "Budget", useCase: "100G CWDM4 for short-reach DCI up to 2km. Lower cost than LR4 for inter-building links.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-CWDM4-S" }, { vendor: "Juniper", partPattern: "QSFP-100G-CWDM4" }, { vendor: "Arista", partPattern: "QSFP-100G-CWDM4" }, V_HUAWEI, V_DELL, V_EXTREME], tags: ["100G", "CWDM4", "singlemode", "2km", "DCI", "cost-effective", "QSFP28"] }, - { id: "qsfp28-er4", standard: "100GBASE-ER4", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 40000, reachLabel: "40km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm (4 LAN-WDM lanes)", connector: "LC", powerConsumptionW: 4.5, tempRange: "COM", category: "Metro", priceTier: "Premium", useCase: "100G extended reach for metro rings and longer DCI links up to 40km.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-ER4L" }, { vendor: "Juniper", partPattern: "QSFP-100G-ER4" }, V_HUAWEI, V_NOKIA], tags: ["100G", "singlemode", "40km", "metro", "extended-reach", "QSFP28"] }, - { id: "qsfp28-zr4", standard: "100GBASE-ZR4", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 80000, reachLabel: "80km", fiberType: "SMF", wavelengths: "1296/1300/1305/1309nm (4 LAN-WDM lanes)", connector: "LC", powerConsumptionW: 5.0, tempRange: "COM", category: "LongHaul", priceTier: "Premium", useCase: "100G long-haul for regional networks up to 80km without amplification.", vendors: carrierVendors(), tags: ["100G", "singlemode", "80km", "long-haul", "regional", "QSFP28"] }, - { id: "qsfp28-lr8", standard: "100G LR8", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "8 CWDM wavelengths (1271-1411nm)", connector: "LC", powerConsumptionW: 4.0, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "100G using 8 CWDM lanes at 12.5G each. For platforms that do not support 25G-per-lane optics.", vendors: carrierVendors(), tags: ["100G", "singlemode", "10km", "CWDM", "8-lane", "legacy-platform", "QSFP28"] }, - { id: "qsfp28-psm4", standard: "100G PSM4", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 500, reachLabel: "500m", fiberType: "SMF", wavelengths: "1310nm (4 parallel fibers)", connector: "MPO-12", powerConsumptionW: 3.5, tempRange: "COM", category: "DataCenter", priceTier: "Budget", useCase: "100G parallel single-mode for intra-DC links up to 500m. MPO-12 connector.", vendors: dcVendors(), tags: ["100G", "singlemode", "500m", "parallel", "MPO", "data-center", "QSFP28"] }, - { id: "qsfp28-sr-bidi", standard: "100GBASE-SR BiDi", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 100, reachLabel: "70m (OM3) / 100m (OM4)", fiberType: "MMF", wavelengths: "832nm / 918nm BiDi (PAM4)", connector: "LC", powerConsumptionW: 3.5, tempRange: "COM", category: "BiDi", priceTier: "Standard", useCase: "100G BiDi over LC duplex multimode. Enables 100G upgrade reusing existing 10G/25G LC MMF cabling.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-100G-SR1.2" }, { vendor: "Arista", partPattern: "QSFP-100G-SRBD" }], tags: ["100G", "BiDi", "multimode", "LC-reuse", "data-center", "QSFP28"] }, - { id: "qsfp28-dwdm", standard: "100G QSFP28 DWDM Tunable", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 80000, reachLabel: "80km", fiberType: "SMF", wavelengths: "C-band tunable (1528-1565nm)", connector: "LC", powerConsumptionW: 5.0, tempRange: "COM", category: "DWDM", priceTier: "Premium", useCase: "100G DWDM tunable for metro/regional WDM networks. Integrates with ROADM systems.", vendors: carrierVendors(), tags: ["100G", "DWDM", "tunable", "C-band", "metro", "ROADM", "QSFP28"] }, - { id: "qsfp28-zr-coherent", standard: "100GBASE-ZR (Coherent)", ieeeReference: "IEEE 802.3ct", formFactor: "QSFP28", speed: "100G", speedGbps: 100, lanes: 1, laneRate: "~64 Gbaud", modulation: "DP-QPSK (coherent)", reachMeters: 80000, reachLabel: "80km+ (DWDM amplified)", fiberType: "SMF", wavelengths: "C-band (tunable, DWDM)", connector: "LC", powerConsumptionW: 5.0, tempRange: "COM", category: "Coherent", priceTier: "Premium", useCase: "100G coherent pluggable for DWDM long-haul. Phase/amplitude modulation with coherent detection.", vendors: carrierVendors(), tags: ["100G", "coherent", "DWDM", "long-haul", "C-band", "tunable", "QSFP28"], generation: "Coherent", marketStatus: "Mainstream", yearIntroduced: 2021 }, - - // ── CXP — 100G/120G Legacy ── - { id: "cxp-sr10", standard: "100GBASE-SR10", formFactor: "CXP", speed: "100G", speedGbps: 100, reachMeters: 150, reachLabel: "100m (OM3) / 150m (OM4)", fiberType: "MMF", wavelengths: "850nm (10 lanes x 10G)", connector: "MPO-24", powerConsumptionW: 6.0, tempRange: "COM", category: "Legacy", priceTier: "Standard", useCase: "Legacy 100G/120G CXP form factor for InfiniBand and early 100G Ethernet.", vendors: [{ vendor: "Cisco", partPattern: "CXP-100G-SR10" }], tags: ["100G", "120G", "legacy", "InfiniBand", "CXP", "multimode"] }, - - // ── CFP / CFP2 / CFP4 — 100G ── - { id: "cfp-lr4", standard: "100GBASE-LR4 CFP", formFactor: "CFP", speed: "100G", speedGbps: 100, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm", connector: "LC", powerConsumptionW: 24.0, tempRange: "COM", category: "Legacy", priceTier: "Standard", useCase: "First-generation 100G CFP form factor. Large footprint, being replaced by CFP2/QSFP28.", vendors: carrierVendors(), tags: ["100G", "singlemode", "10km", "legacy", "CFP"] }, - { id: "cfp2-lr4", standard: "100GBASE-LR4 CFP2", formFactor: "CFP2", speed: "100G", speedGbps: 100, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm", connector: "LC", powerConsumptionW: 9.0, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "100G CFP2 for carrier/service provider routers with CFP2 slots.", vendors: carrierVendors(), tags: ["100G", "singlemode", "10km", "carrier", "CFP2"] }, - { id: "cfp4-lr4", standard: "100GBASE-LR4 CFP4", formFactor: "CFP4", speed: "100G", speedGbps: 100, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm", connector: "LC", powerConsumptionW: 6.0, tempRange: "COM", category: "Metro", priceTier: "Standard", useCase: "Compact 100G CFP4 for high-density router line cards.", vendors: carrierVendors(), tags: ["100G", "singlemode", "10km", "carrier", "high-density", "CFP4"] }, - - // ── CFP2-DCO — Coherent 100G-400G ── - { id: "cfp2dco-100g", standard: "100G CFP2-DCO Coherent", formFactor: "CFP2-DCO", speed: "100G", speedGbps: 100, reachMeters: 2000000, reachLabel: "2000km+", fiberType: "SMF", wavelengths: "C-band tunable (1528-1565nm)", connector: "LC", powerConsumptionW: 18.0, tempRange: "COM", category: "Coherent", priceTier: "Premium", useCase: "100G coherent for long-haul and submarine links. DP-QPSK modulation.", vendors: carrierVendors(), tags: ["100G", "coherent", "DP-QPSK", "long-haul", "submarine", "DWDM", "tunable", "CFP2-DCO"] }, - { id: "cfp2dco-200g", standard: "200G CFP2-DCO Coherent", formFactor: "CFP2-DCO", speed: "200G", speedGbps: 200, reachMeters: 1000000, reachLabel: "1000km+", fiberType: "SMF", wavelengths: "C-band tunable (1528-1565nm)", connector: "LC", powerConsumptionW: 20.0, tempRange: "COM", category: "Coherent", priceTier: "Premium", useCase: "200G coherent for long-haul transport. DP-16QAM or DP-QPSK modulation.", vendors: carrierVendors(), tags: ["200G", "coherent", "DP-16QAM", "long-haul", "DWDM", "tunable", "CFP2-DCO"] }, - { id: "cfp2dco-400g", standard: "400G CFP2-DCO Coherent", formFactor: "CFP2-DCO", speed: "400G", speedGbps: 400, reachMeters: 600000, reachLabel: "600km+", fiberType: "SMF", wavelengths: "C-band tunable (1528-1565nm)", connector: "LC", powerConsumptionW: 22.0, tempRange: "COM", category: "Coherent", priceTier: "Premium", useCase: "400G coherent for long-haul and DCI. DP-16QAM modulation at high baud rate.", vendors: carrierVendors(), tags: ["400G", "coherent", "DP-16QAM", "long-haul", "DCI", "DWDM", "tunable", "CFP2-DCO"] }, - - // ── QSFP56 — 200G ── - { id: "qsfp56-sr4", standard: "200GBASE-SR4", ieeeReference: "IEEE 802.3cd", formFactor: "QSFP56", speed: "200G", speedGbps: 200, lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", reachMeters: 100, reachLabel: "70m (OM3) / 100m (OM4)", fiberType: "MMF", wavelengths: "850nm (4x50G PAM4)", connector: "MPO-12", powerConsumptionW: 7.0, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "200G multimode for data center links. 4 lanes at 50G PAM4 each.", vendors: [{ vendor: "Cisco", partPattern: "QSFP-200G-SR4" }, { vendor: "Arista", partPattern: "QSFP-200G-SR4" }, V_JUNIPER, V_HUAWEI, V_DELL, V_EXTREME], tags: ["200G", "multimode", "PAM4", "data-center", "QSFP56"], generation: "Gen2 PAM4", marketStatus: "Mainstream", yearIntroduced: 2019, breakoutCapable: true, breakoutTo: "4x50GBASE-SR or 2x100GBASE-SR2" }, - { id: "qsfp56-dr4", standard: "200GBASE-DR4", ieeeReference: "IEEE 802.3cd", formFactor: "QSFP56", speed: "200G", speedGbps: 200, lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", reachMeters: 500, reachLabel: "500m", fiberType: "SMF", wavelengths: "1310nm (4x50G PAM4 parallel)", connector: "MPO-12", powerConsumptionW: 7.0, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "200G parallel single-mode for intra-DC links up to 500m. Breakout to 4x50G possible.", vendors: dcVendors(), tags: ["200G", "singlemode", "500m", "parallel", "breakout", "data-center", "QSFP56"], generation: "Gen2 PAM4", marketStatus: "Mainstream", yearIntroduced: 2019, breakoutCapable: true, breakoutTo: "2x100GBASE-DR or 4x50G" }, - { id: "qsfp56-fr4", standard: "200GBASE-FR4", ieeeReference: "IEEE 802.3cu", formFactor: "QSFP56", speed: "200G", speedGbps: 200, lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", reachMeters: 2000, reachLabel: "2km", fiberType: "SMF", wavelengths: "1271/1291/1311/1331nm (CWDM4)", connector: "LC", powerConsumptionW: 7.0, tempRange: "COM", category: "DCI", priceTier: "Standard", useCase: "200G for short-reach DCI up to 2km. Uses CWDM wavelengths over LC duplex fiber.", vendors: dcVendors(), tags: ["200G", "CWDM", "singlemode", "2km", "DCI", "QSFP56"], generation: "Gen2 PAM4", marketStatus: "Mainstream", yearIntroduced: 2021 }, - { id: "qsfp56-lr4", standard: "200GBASE-LR4", ieeeReference: "IEEE 802.3cu", formFactor: "QSFP56", speed: "200G", speedGbps: 200, lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm (4 LAN-WDM lanes x 50G)", connector: "LC", powerConsumptionW: 8.0, tempRange: "COM", category: "Metro", priceTier: "Premium", useCase: "200G metro DCI links up to 10km using LAN-WDM.", vendors: carrierVendors(), tags: ["200G", "singlemode", "10km", "metro", "DCI", "LAN-WDM", "QSFP56"], generation: "Gen2 PAM4", marketStatus: "Mainstream", yearIntroduced: 2021 }, - - // ── QSFP-DD — 400G ── - { id: "qsfpdd-sr8", standard: "400GBASE-SR8", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 100, reachLabel: "70m (OM3) / 100m (OM4)", fiberType: "MMF", wavelengths: "850nm (8x50G PAM4)", connector: "MPO-16", powerConsumptionW: 12.0, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "400G multimode for short-reach data center links. 8 lanes at 50G PAM4.", vendors: [{ vendor: "Cisco", partPattern: "QDD-400G-SR8" }, { vendor: "Arista", partPattern: "QDD-400G-SR8" }, V_JUNIPER, V_HUAWEI, V_DELL, V_EXTREME], tags: ["400G", "multimode", "short-reach", "data-center", "MPO-16", "PAM4", "QSFP-DD"] }, - { id: "qsfpdd-sr4-2", standard: "400GBASE-SR4.2", ieeeReference: "IEEE 802.3cm", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, lanes: 4, laneRate: "53.125 Gbaud", modulation: "PAM4", reachMeters: 100, reachLabel: "100m (OM4)", fiberType: "MMF", wavelengths: "850nm + 910nm (bidirectional)", connector: "MPO-12", powerConsumptionW: 12.0, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "400G BiDi over MPO-12 using two wavelengths. Saves fiber vs SR8.", vendors: dcVendors(), tags: ["400G", "multimode", "BiDi", "data-center", "MPO-12", "cabling-reuse", "QSFP-DD"], generation: "Gen2 PAM4", marketStatus: "Mainstream", yearIntroduced: 2020, breakoutCapable: true, breakoutTo: "2x200GBASE-SR4 or 4x100GBASE-SR" }, - { id: "qsfpdd-dr4", standard: "400GBASE-DR4", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 500, reachLabel: "500m", fiberType: "SMF", wavelengths: "1310nm (4x100G PAM4 parallel)", connector: "MPO-12", powerConsumptionW: 12.0, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "400G parallel single-mode for intra-DC. Breakout to 4x100G DR1 possible. Key DCI building block.", vendors: [{ vendor: "Cisco", partPattern: "QDD-400G-DR4-S" }, { vendor: "Juniper", partPattern: "QDD-400G-DR4" }, { vendor: "Arista", partPattern: "QDD-400G-DR4" }, V_HUAWEI, V_DELL, V_EXTREME], tags: ["400G", "singlemode", "500m", "parallel", "breakout", "data-center", "DCI", "QSFP-DD"] }, - { id: "qsfpdd-fr4", standard: "400GBASE-FR4", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 2000, reachLabel: "2km", fiberType: "SMF", wavelengths: "1271/1291/1311/1331nm (4 CWDM lanes x 100G)", connector: "LC", powerConsumptionW: 12.0, tempRange: "COM", category: "DCI", priceTier: "Standard", useCase: "400G FR4 for DCI up to 2km using CWDM4 over LC duplex. Most popular 400G DCI optic.", vendors: [{ vendor: "Cisco", partPattern: "QDD-400G-FR4-S" }, { vendor: "Juniper", partPattern: "QDD-400G-FR4" }, { vendor: "Arista", partPattern: "QDD-400G-FR4" }, V_HUAWEI, V_NOKIA, V_HPE, V_DELL, V_EXTREME], tags: ["400G", "CWDM", "singlemode", "2km", "DCI", "popular", "QSFP-DD"] }, - { id: "qsfpdd-lr4", standard: "400GBASE-LR4", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm (4 LAN-WDM lanes x 100G)", connector: "LC", powerConsumptionW: 14.0, tempRange: "COM", category: "Metro", priceTier: "Premium", useCase: "400G for metro DCI and campus backbone up to 10km.", vendors: [{ vendor: "Cisco", partPattern: "QDD-400G-LR4-S" }, { vendor: "Juniper", partPattern: "QDD-400G-LR4" }, V_HUAWEI, V_NOKIA], tags: ["400G", "singlemode", "10km", "metro", "DCI", "LAN-WDM", "QSFP-DD"] }, - { id: "qsfpdd-lr8", standard: "400GBASE-LR8", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "8 CWDM wavelengths (1271-1411nm, 8x50G)", connector: "LC", powerConsumptionW: 14.0, tempRange: "COM", category: "Metro", priceTier: "Premium", useCase: "400G LR8 using 8 CWDM lanes at 50G each. For platforms with 50G-per-lane electronics.", vendors: carrierVendors(), tags: ["400G", "CWDM8", "singlemode", "10km", "metro", "8-lane", "QSFP-DD"] }, - { id: "qsfpdd-er4", standard: "400GBASE-ER4", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 40000, reachLabel: "40km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm (4 LAN-WDM lanes, amplified)", connector: "LC", powerConsumptionW: 16.0, tempRange: "COM", category: "Metro", priceTier: "Premium", useCase: "400G extended reach for metro rings up to 40km.", vendors: carrierVendors(), tags: ["400G", "singlemode", "40km", "metro", "extended-reach", "SOA", "QSFP-DD"] }, - { id: "qsfpdd-xdr4", standard: "400GBASE-XDR4 (4x100G-FR)", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, lanes: 4, laneRate: "53.125 Gbaud", modulation: "PAM4", reachMeters: 2000, reachLabel: "2km", fiberType: "SMF", wavelengths: "1310nm", connector: "MPO-12", powerConsumptionW: 12.0, tempRange: "COM", category: "DCI", priceTier: "Standard", useCase: "400G XDR4 = 4 parallel SMF lanes at 100G each for 2km. Breaks out to 4x100G-FR1.", vendors: [{ vendor: "Arista", partPattern: "QDD-400G-XDR4" }, { vendor: "Juniper", partPattern: "QDD-4X100G-FR" }, V_CISCO, V_HUAWEI, V_DELL, V_EXTREME], tags: ["400G", "singlemode", "2km", "parallel-SMF", "DCI", "breakout", "PAM4", "QSFP-DD"], generation: "Gen2 PAM4", marketStatus: "Growth", breakoutCapable: true, breakoutTo: "4x100GBASE-FR1" }, - { id: "qsfpdd-plr4", standard: "400G-PLR4 (4x100G-LR)", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, lanes: 4, laneRate: "53.125 Gbaud", modulation: "PAM4", reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "MPO-12", powerConsumptionW: 14.0, tempRange: "COM", category: "Metro", priceTier: "Premium", useCase: "400G parallel-LR for 10km. 4 parallel SMF lanes. Breaks out to 4x100G-LR1.", vendors: [{ vendor: "Arista", partPattern: "QDD-400G-PLR4" }, { vendor: "Juniper", partPattern: "QDD-400G-PLR4" }, V_CISCO, V_HUAWEI], tags: ["400G", "singlemode", "10km", "parallel-SMF", "metro", "breakout", "QSFP-DD"], generation: "Gen2 PAM4", marketStatus: "Growth", breakoutCapable: true, breakoutTo: "4x100GBASE-LR1" }, - { id: "qsfpdd-zr", standard: "400G-ZR (OIF)", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 120000, reachLabel: "120km (unamplified)", fiberType: "SMF", wavelengths: "C-band tunable (1528-1565nm), DP-16QAM", connector: "LC", powerConsumptionW: 18.0, tempRange: "COM", category: "Coherent", priceTier: "Premium", useCase: "400G-ZR coherent in QSFP-DD form factor. Industry standard (OIF) for DCI up to 120km unamplified.", vendors: [{ vendor: "Cisco", partPattern: "QDD-400G-ZR-S" }, { vendor: "Juniper", partPattern: "QDD-400G-ZR" }, { vendor: "Arista", partPattern: "QDD-400G-ZR" }, V_HUAWEI, V_NOKIA], tags: ["400G", "coherent", "ZR", "DP-16QAM", "DCI", "120km", "OIF", "pluggable", "QSFP-DD"] }, - { id: "qsfpdd-zrp", standard: "400G-ZR+ (OpenZR+)", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 2000000, reachLabel: "500km+ (amplified)", fiberType: "SMF", wavelengths: "C-band tunable, flexible modulation (QPSK/8QAM/16QAM)", connector: "LC", powerConsumptionW: 20.0, tempRange: "COM", category: "Coherent", priceTier: "Premium", useCase: "400G-ZR+ coherent with flexible modulation for metro-to-long-haul. OpenZR+ MSA standard.", vendors: [{ vendor: "Cisco", partPattern: "QDD-400G-ZRP-S" }, { vendor: "Juniper", partPattern: "QDD-400G-ZRP" }, { vendor: "Arista", partPattern: "QDD-400G-ZRP" }, V_HUAWEI, V_NOKIA], tags: ["400G", "coherent", "ZR+", "OpenZR+", "flexible-modulation", "metro", "long-haul", "DCI", "pluggable", "QSFP-DD"] }, - - // ── OSFP — 400G / 800G ── - { id: "osfp-sr8", standard: "400GBASE-SR8 OSFP", formFactor: "OSFP", speed: "400G", speedGbps: 400, reachMeters: 100, reachLabel: "100m (OM4)", fiberType: "MMF", wavelengths: "850nm (8x50G PAM4)", connector: "MPO-16", powerConsumptionW: 15.0, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "400G multimode OSFP for platforms with OSFP cages.", vendors: [{ vendor: "Arista", partPattern: "OSFP-400G-SR8" }, V_CISCO, V_JUNIPER, V_HUAWEI, V_DELL, V_EXTREME], tags: ["400G", "multimode", "data-center", "OSFP"] }, - { id: "osfp-dr4", standard: "400GBASE-DR4 OSFP", formFactor: "OSFP", speed: "400G", speedGbps: 400, reachMeters: 500, reachLabel: "500m", fiberType: "SMF", wavelengths: "1310nm (4x100G PAM4)", connector: "MPO-12", powerConsumptionW: 15.0, tempRange: "COM", category: "DataCenter", priceTier: "Standard", useCase: "400G parallel single-mode OSFP for next-gen data center fabrics.", vendors: dcVendors(), tags: ["400G", "singlemode", "500m", "data-center", "OSFP"] }, - { id: "osfp-fr4", standard: "400GBASE-FR4 OSFP", formFactor: "OSFP", speed: "400G", speedGbps: 400, reachMeters: 2000, reachLabel: "2km", fiberType: "SMF", wavelengths: "1271/1291/1311/1331nm (4 CWDM x 100G)", connector: "LC", powerConsumptionW: 15.0, tempRange: "COM", category: "DCI", priceTier: "Standard", useCase: "400G FR4 in OSFP form factor for DCI links up to 2km.", vendors: dcVendors(), tags: ["400G", "CWDM", "singlemode", "2km", "DCI", "OSFP"] }, - { id: "osfp-800g-sr8", standard: "800GBASE-SR8", formFactor: "OSFP", speed: "800G", speedGbps: 800, reachMeters: 50, reachLabel: "30m (OM3) / 50m (OM4)", fiberType: "MMF", wavelengths: "850nm (8x100G PAM4)", connector: "MPO-16", powerConsumptionW: 22.0, tempRange: "COM", category: "DataCenter", priceTier: "Premium", useCase: "800G multimode for AI/ML GPU cluster interconnects in hyperscale data centers.", vendors: [{ vendor: "Cisco", partPattern: "OSFP-800G-SR8" }, { vendor: "Arista", partPattern: "OSFP-800G-SR8" }], tags: ["800G", "multimode", "data-center", "AI", "GPU", "hyperscale", "OSFP"] }, - { id: "osfp-800g-dr8", standard: "800GBASE-DR8", formFactor: "OSFP", speed: "800G", speedGbps: 800, reachMeters: 500, reachLabel: "500m", fiberType: "SMF", wavelengths: "1310nm (8x100G PAM4 parallel)", connector: "MPO-16", powerConsumptionW: 22.0, tempRange: "COM", category: "DataCenter", priceTier: "Premium", useCase: "800G parallel single-mode for hyperscale DC fabrics. Breakout to 2x400G or 8x100G possible.", vendors: [{ vendor: "Cisco", partPattern: "OSFP-800G-DR8" }, { vendor: "Arista", partPattern: "OSFP-800G-DR8" }], tags: ["800G", "singlemode", "500m", "parallel", "breakout", "hyperscale", "data-center", "OSFP"] }, - { id: "osfp-800g-2fr4", standard: "800G-2FR4", formFactor: "OSFP", speed: "800G", speedGbps: 800, reachMeters: 2000, reachLabel: "2km", fiberType: "SMF", wavelengths: "8 CWDM wavelengths (4 per fiber direction)", connector: "CS", powerConsumptionW: 22.0, tempRange: "COM", category: "DCI", priceTier: "Premium", useCase: "800G for DCI up to 2km using duplex CS connector. Dual FR4 in a single module.", vendors: dcVendors(), tags: ["800G", "CWDM", "singlemode", "2km", "DCI", "CS-connector", "OSFP"] }, - { id: "osfp-800g-zr", standard: "800G-ZR", formFactor: "OSFP", speed: "800G", speedGbps: 800, reachMeters: 120000, reachLabel: "80-120km", fiberType: "SMF", wavelengths: "C-band tunable, DP-64QAM/DP-16QAM", connector: "LC", powerConsumptionW: 25.0, tempRange: "COM", category: "Coherent", priceTier: "Premium", useCase: "800G coherent pluggable for DCI. Next-gen after 400G-ZR.", vendors: [{ vendor: "Cisco", partPattern: "OSFP-800G-ZR" }, { vendor: "Arista", partPattern: "OSFP-800G-ZR" }, V_JUNIPER, V_HUAWEI, V_NOKIA], tags: ["800G", "coherent", "ZR", "DCI", "pluggable", "next-gen", "OSFP"] }, - - // ── DAC — Direct Attach Cables ── - { id: "dac-sfpp-1m", standard: "10G SFP+ DAC", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 5, reachLabel: "1-5m", fiberType: "Copper", wavelengths: "N/A", connector: "None", powerConsumptionW: 0.5, tempRange: "COM", category: "DAC", priceTier: "Budget", useCase: "10G passive copper DAC for in-rack server-to-switch links. Lowest cost and latency option.", vendors: allMajorVendors(), tags: ["10G", "DAC", "copper", "passive", "in-rack", "low-latency", "SFP+"] }, - { id: "dac-sfp28-3m", standard: "25G SFP28 DAC", formFactor: "SFP28", speed: "25G", speedGbps: 25, reachMeters: 5, reachLabel: "1-5m", fiberType: "Copper", wavelengths: "N/A", connector: "None", powerConsumptionW: 0.5, tempRange: "COM", category: "DAC", priceTier: "Budget", useCase: "25G passive copper DAC for in-rack 25G server connections.", vendors: allMajorVendors(), tags: ["25G", "DAC", "copper", "passive", "in-rack", "leaf-spine", "SFP28"] }, - { id: "dac-qsfpp-3m", standard: "40G QSFP+ DAC", formFactor: "QSFP+", speed: "40G", speedGbps: 40, reachMeters: 5, reachLabel: "1-5m", fiberType: "Copper", wavelengths: "N/A", connector: "None", powerConsumptionW: 0.5, tempRange: "COM", category: "DAC", priceTier: "Budget", useCase: "40G passive copper DAC for spine-to-leaf and storage links within a rack.", vendors: allMajorVendors(), tags: ["40G", "DAC", "copper", "passive", "in-rack", "QSFP+"] }, - { id: "dac-qsfp28-3m", standard: "100G QSFP28 DAC", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 5, reachLabel: "1-5m", fiberType: "Copper", wavelengths: "N/A", connector: "None", powerConsumptionW: 1.0, tempRange: "COM", category: "DAC", priceTier: "Budget", useCase: "100G passive copper DAC for spine-leaf and storage interconnects within racks.", vendors: allMajorVendors(), tags: ["100G", "DAC", "copper", "passive", "in-rack", "QSFP28"] }, - { id: "dac-qsfpdd-3m", standard: "400G QSFP-DD DAC", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 3, reachLabel: "1-3m", fiberType: "Copper", wavelengths: "N/A", connector: "None", powerConsumptionW: 1.5, tempRange: "COM", category: "DAC", priceTier: "Budget", useCase: "400G passive copper DAC for in-rack high-bandwidth interconnects.", vendors: dcVendors(), tags: ["400G", "DAC", "copper", "passive", "in-rack", "QSFP-DD"] }, - { id: "dac-osfp-800g", standard: "800G OSFP DAC", formFactor: "OSFP", speed: "800G", speedGbps: 800, reachMeters: 2, reachLabel: "1-2m", fiberType: "Copper", wavelengths: "N/A", connector: "None", powerConsumptionW: 2.0, tempRange: "COM", category: "DAC", priceTier: "Standard", useCase: "800G DAC for GPU-to-switch and AI cluster interconnects. Shortest latency option for 800G.", vendors: [{ vendor: "Cisco", partPattern: "OSFP-800G-CU*" }, { vendor: "Arista", partPattern: "OSFP-800G-DAC*" }], tags: ["800G", "DAC", "copper", "AI", "GPU", "OSFP"] }, - - // ── AOC — Active Optical Cables ── - { id: "aoc-sfpp-10m", standard: "10G SFP+ AOC", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 100, reachLabel: "1-100m", fiberType: "MMF", wavelengths: "850nm (embedded)", connector: "None", powerConsumptionW: 1.0, tempRange: "COM", category: "AOC", priceTier: "Budget", useCase: "10G AOC for inter-rack links beyond DAC reach. Lighter than copper.", vendors: allMajorVendors(), tags: ["10G", "AOC", "multimode", "inter-rack", "SFP+"] }, - { id: "aoc-qsfp28-30m", standard: "100G QSFP28 AOC", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 100, reachLabel: "1-100m", fiberType: "MMF", wavelengths: "850nm (embedded)", connector: "None", powerConsumptionW: 3.0, tempRange: "COM", category: "AOC", priceTier: "Budget", useCase: "100G AOC for inter-rack DC links. Lighter and cheaper than SR4 + MPO patch cords.", vendors: allMajorVendors(), tags: ["100G", "AOC", "multimode", "inter-rack", "data-center", "QSFP28"] }, - { id: "aoc-qsfpdd-30m", standard: "400G QSFP-DD AOC", formFactor: "QSFP-DD", speed: "400G", speedGbps: 400, reachMeters: 100, reachLabel: "1-100m", fiberType: "MMF", wavelengths: "850nm (embedded)", connector: "None", powerConsumptionW: 10.0, tempRange: "COM", category: "AOC", priceTier: "Standard", useCase: "400G AOC for short inter-rack links in high-density data centers.", vendors: dcVendors(), tags: ["400G", "AOC", "multimode", "inter-rack", "QSFP-DD"] }, - - // ── Industrial Temperature Variants ── - { id: "sfpp-lr-ind", standard: "10GBASE-LR Industrial", formFactor: "SFP+", speed: "10G", speedGbps: 10, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.2, tempRange: "IND", category: "Access", priceTier: "Standard", useCase: "10G industrial-temp (-40 to +85C) for outdoor deployments, telecom shelters, and cell towers.", vendors: allMajorVendors(), tags: ["10G", "industrial", "outdoor", "telecom", "cell-tower", "SFP+"] }, - { id: "sfp-lx-ind", standard: "1000BASE-LX Industrial", formFactor: "SFP", speed: "1G", speedGbps: 1, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1310nm", connector: "LC", powerConsumptionW: 1.0, tempRange: "IND", category: "Access", priceTier: "Standard", useCase: "1G industrial-temp for outdoor access networks, utility SCADA, and harsh environments.", vendors: allMajorVendors(), tags: ["1G", "industrial", "outdoor", "SCADA", "utility", "SFP"] }, - { id: "qsfp28-lr4-ind", standard: "100GBASE-LR4 Industrial", formFactor: "QSFP28", speed: "100G", speedGbps: 100, reachMeters: 10000, reachLabel: "10km", fiberType: "SMF", wavelengths: "1295/1300/1305/1310nm", connector: "LC", powerConsumptionW: 5.0, tempRange: "IND", category: "Metro", priceTier: "Premium", useCase: "100G industrial-temp for telecom outdoor cabinets and cell-site aggregation.", vendors: carrierVendors(), tags: ["100G", "industrial", "outdoor", "telecom", "QSFP28"] }, -]; - -// ── Search & Filter Functions ── - -/** - * Search transceivers by any keyword. Searches across standard, form factor, - * speed, use case, tags, and vendor names. - */ -export function searchTransceivers(query: string): Transceiver[] { - const q = query.toLowerCase(); - return transceivers.filter( - (t) => - t.standard.toLowerCase().includes(q) || - t.formFactor.toLowerCase().includes(q) || - t.speed.toLowerCase().includes(q) || - t.useCase.toLowerCase().includes(q) || - t.category.toLowerCase().includes(q) || - t.wavelengths.toLowerCase().includes(q) || - t.tags.some((tag) => tag.toLowerCase().includes(q)) || - t.vendors.some((v) => v.vendor.toLowerCase().includes(q)) || - (t.modulation && t.modulation.toLowerCase().includes(q)) || - (t.generation && t.generation.toLowerCase().includes(q)) - ); -} - -/** Filter by form factor (e.g., "SFP+", "QSFP-DD", "OSFP"). */ -export function getByFormFactor(formFactor: string): Transceiver[] { - return transceivers.filter( - (t) => t.formFactor.toLowerCase() === formFactor.toLowerCase() - ); -} - -/** Filter by speed tier (e.g., "10G", "100G", "400G", "800G"). */ -export function getBySpeed(speed: string): Transceiver[] { - return transceivers.filter( - (t) => t.speed.toLowerCase() === speed.toLowerCase() - ); -} - -/** Filter by maximum reach in meters. Returns transceivers that reach at least `minMeters`. */ -export function getByReach(minMeters: number): Transceiver[] { - return transceivers.filter((t) => t.reachMeters >= minMeters); -} - -/** Filter by product category (e.g., "DataCenter", "Coherent", "DAC"). */ -export function getByCategory(category: string): Transceiver[] { - return transceivers.filter( - (t) => t.category.toLowerCase() === category.toLowerCase() - ); -} - -/** Get a single transceiver by its unique ID. */ -export function getById(id: string): Transceiver | undefined { - return transceivers.find((t) => t.id === id); -} diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index 18aaa19..0000000 --- a/src/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * transceiver-db — Open-source optical transceiver database - * - * 159 products, 42 IEEE/MSA standards, 16 form factors, 9 speed tiers. - * From 1G SFP to 800G OSFP. Zero dependencies. - */ - -export { - transceivers, - searchTransceivers, - getByFormFactor, - getBySpeed, - getByReach, - getByCategory, - getById, -} from "./database"; - -export { standards, getStandard, searchStandards } from "./standards"; - -export { competitors, getCompetitor } from "./market"; - -export { breakouts } from "./breakouts"; - -export type { - Transceiver, - Standard, - Competitor, - Breakout, - FormFactor, - FiberType, - ConnectorType, - TempRange, - ProductCategory, - PriceTier, - MarketStatus, - VendorCompat, -} from "./types"; diff --git a/src/market.ts b/src/market.ts deleted file mode 100644 index af0eefb..0000000 --- a/src/market.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Competitor landscape — neutral industry data. - * No vendor bias. No sales language. - */ - -import type { Competitor } from "./types"; - -export const competitors: readonly Competitor[] = [ - { name: "Cisco", type: "OEM", headquarters: "San Jose, USA", marketPosition: "Largest networking vendor globally. Sells branded optics. Acquired Acacia Communications for coherent technology.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "QSFP+", "QSFP28", "QSFP-DD", "OSFP", "CFP2-DCO"], speedTiersOffered: ["1G", "10G", "25G", "40G", "100G", "400G", "800G"], strengths: ["Dominant installed base", "End-to-end solution", "TAC support tied to branded optics"], weaknesses: ["Significant price premium over compatible optics", "Vendor lock-in practices"] }, - { name: "Juniper Networks", type: "OEM", headquarters: "Sunnyvale, USA (acquired by HPE 2024)", marketPosition: "Strong in service provider and large enterprise. MX/PTX series for routing, QFX/EX for switching.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "QSFP+", "QSFP28", "QSFP-DD", "CFP2-DCO"], speedTiersOffered: ["1G", "10G", "25G", "40G", "100G", "400G"], strengths: ["Junos OS reliability", "Strong SP/carrier presence", "PTX for massive scale"], weaknesses: ["Optics premium over compatible alternatives", "Smaller market share than Cisco"] }, - { name: "Arista Networks", type: "OEM", headquarters: "Santa Clara, USA", marketPosition: "Dominant in hyperscale data centers and cloud. Largest DC switching vendor by port volume. Leader in 400G/800G deployments.", formFactorsOffered: ["SFP+", "SFP28", "QSFP+", "QSFP28", "QSFP-DD", "OSFP"], speedTiersOffered: ["10G", "25G", "40G", "100G", "400G", "800G"], strengths: ["EOS software quality", "Hyperscale dominance", "Early 800G adoption", "Liquid-cooled optics for AI"], weaknesses: ["Optics premium over compatible alternatives", "Primarily DC focused"] }, - { name: "Huawei", type: "OEM", headquarters: "Shenzhen, China", marketPosition: "Largest carrier/SP equipment vendor globally. Strong in EMEA, APAC, Middle East. CloudEngine for DC switching.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "QSFP+", "QSFP28", "QSFP-DD", "OSFP", "CFP2-DCO"], speedTiersOffered: ["1G", "10G", "25G", "40G", "100G", "400G", "800G"], strengths: ["Aggressive pricing vs Western OEMs", "Massive carrier installed base", "Strong in coherent/DWDM"], weaknesses: ["Geopolitical restrictions in some markets"] }, - { name: "Nokia", type: "OEM", headquarters: "Espoo, Finland", marketPosition: "Major carrier/SP vendor. 7750 SR series for routing, 7250 IXR for DC. Strong in IXP infrastructure.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "QSFP+", "QSFP28", "QSFP-DD", "CFP2-DCO"], speedTiersOffered: ["1G", "10G", "25G", "40G", "100G", "400G", "800G"], strengths: ["IXP platform dominance", "FP5 silicon for high-performance routing", "Strong coherent optics"], weaknesses: ["Optics premium", "Smaller DC switching presence"] }, - { name: "FLEXOPTIX", type: "Compatible", headquarters: "Darmstadt, Germany", marketPosition: "Premium compatible optics vendor with unique FlexBox hardware programmer. Codes transceivers on-site for any vendor. 300+ supported switch/router vendors. Lifetime warranty. Strong in service provider, IXP, and enterprise markets across EMEA.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "SFP56", "QSFP+", "QSFP28", "QSFP56", "QSFP-DD", "OSFP", "CFP", "CFP2", "CFP4", "CFP2-DCO", "XFP", "CXP"], speedTiersOffered: ["1G", "10G", "25G", "40G", "50G", "100G", "200G", "400G", "800G"], strengths: ["FlexBox: on-site hardware programmer — recode any transceiver for any vendor in seconds", "300+ supported vendors (largest compatibility matrix in the industry)", "Multi-vendor infrastructure support — one transceiver works across Cisco, Juniper, Arista, Nokia, Huawei and 295+ more", "Lifetime warranty on all products", "Technical support by network engineers, not call center scripts", "Same-day shipping from German warehouse", "Strong NOG/peering community presence"], weaknesses: ["Not the cheapest option (premium quality positioning)", "European-focused logistics (expanding globally)"] }, - { name: "FS.COM", type: "Whitebox", headquarters: "Wilmington, USA (manufacturing in China)", marketPosition: "Major compatible optics vendor. Massive online catalog. Tests compatibility with Cisco, Arista, Juniper, NVIDIA.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "SFP56", "QSFP+", "QSFP28", "QSFP56", "QSFP-DD", "OSFP"], speedTiersOffered: ["1G", "10G", "25G", "40G", "50G", "100G", "200G", "400G", "800G", "1.6T"], strengths: ["Aggressive pricing", "Huge catalog", "Online ordering", "NVIDIA InfiniBand compatibility"], weaknesses: ["Pre-coded only — no field recoding", "Limited field customization", "Quality varies by batch", "No equivalent to FlexBox programmer"] }, - { name: "Innolight Technology", type: "Manufacturer", headquarters: "Suzhou, China", marketPosition: "Top optical transceiver manufacturer by revenue. Primary supplier to NVIDIA and major hyperscalers. Dominates 800G market.", formFactorsOffered: ["SFP28", "QSFP28", "QSFP56", "QSFP-DD", "OSFP", "OSFP-XD"], speedTiersOffered: ["25G", "100G", "200G", "400G", "800G", "1.6T"], strengths: ["Primary supplier to NVIDIA", "Massive manufacturing scale", "Silicon photonics leader", "800G/1.6T early adopter"], weaknesses: ["Primarily sells to hyperscalers/OEMs", "Not direct to enterprise"] }, - { name: "Coherent Corp", type: "Manufacturer", headquarters: "Saxonburg, USA", marketPosition: "Top-tier transceiver manufacturer (formerly II-VI/Finisar). Vertically integrated. Strong in coherent optics and telecom.", formFactorsOffered: ["SFP+", "SFP28", "QSFP28", "QSFP-DD", "OSFP", "CFP2-DCO", "OSFP-XD"], speedTiersOffered: ["10G", "25G", "100G", "400G", "800G", "1.6T"], strengths: ["Vertical integration", "Coherent optics leadership", "InP and SiPh capabilities"], weaknesses: ["Premium pricing", "OEM/hyperscale focus"] }, - { name: "Broadcom", type: "Manufacturer", headquarters: "San Jose, USA", marketPosition: "Major silicon + optics vendor. Tomahawk switch ASICs plus transceiver modules. Co-packaged optics initiative.", formFactorsOffered: ["SFP+", "SFP28", "QSFP28", "QSFP-DD", "OSFP"], speedTiersOffered: ["10G", "25G", "100G", "400G", "800G"], strengths: ["Switch ASIC + optics synergy", "Co-packaged optics leadership"], weaknesses: ["Premium pricing", "Mostly hyperscale/OEM channel"] }, - { name: "HPE/Aruba", type: "OEM", headquarters: "Houston, USA", marketPosition: "Strong in campus/enterprise networking. Aruba CX for modern campus. Juniper acquisition expanding portfolio.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "QSFP+", "QSFP28", "QSFP-DD"], speedTiersOffered: ["1G", "10G", "25G", "40G", "100G", "400G"], strengths: ["Campus/enterprise dominance", "Aruba CX modern OS", "Juniper integration expanding"], weaknesses: ["Optics premium", "Less DC presence (pre-Juniper)"] }, - { name: "Dell Technologies", type: "OEM", headquarters: "Round Rock, USA", marketPosition: "PowerSwitch for DC switching. Strong server attach rate driving optics demand.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "QSFP+", "QSFP28", "QSFP-DD"], speedTiersOffered: ["1G", "10G", "25G", "40G", "100G", "400G"], strengths: ["Server + switch bundle deals", "OS10/FTOS flexibility", "Open networking friendly"], weaknesses: ["Optics premium", "Smaller networking market share"] }, - { name: "Extreme Networks", type: "OEM", headquarters: "Morrisville, USA", marketPosition: "Consolidated multiple brands (Brocade, Avaya Networking, Enterasys, Aerohive). Strong in campus and education.", formFactorsOffered: ["SFP", "SFP+", "SFP28", "QSFP+", "QSFP28"], speedTiersOffered: ["1G", "10G", "25G", "40G", "100G"], strengths: ["Campus/education market", "Fabric Connect technology", "Unified management"], weaknesses: ["Optics premium", "Complex legacy product lines"] }, -]; - -/** Find a competitor by name (partial match). */ -export function getCompetitor(name: string): Competitor | undefined { - const q = name.toLowerCase(); - return competitors.find((c) => c.name.toLowerCase().includes(q)); -} diff --git a/src/standards.ts b/src/standards.ts deleted file mode 100644 index 9697de5..0000000 --- a/src/standards.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * IEEE 802.3 and MSA standards reference — 42 standards. - */ - -import type { Standard } from "./types"; - -export const standards: readonly Standard[] = [ - // 1G - { standard: "1000BASE-SX", ieeeReference: "IEEE 802.3z", speed: "1G", lanes: 1, laneRate: "1.25 Gbaud", modulation: "NRZ", fiberType: "MMF (OM1-OM4)", wavelength: "850nm", maxReachMeters: 550, maxReachLabel: "220m (OM1) / 550m (OM2+)", connector: "LC/SC", fecRequired: false, formFactors: ["SFP", "GBIC"], yearRatified: 1998, notes: "Original Gigabit Ethernet multimode standard." }, - { standard: "1000BASE-LX", ieeeReference: "IEEE 802.3z", speed: "1G", lanes: 1, laneRate: "1.25 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1310nm", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC/SC", fecRequired: false, formFactors: ["SFP", "GBIC"], yearRatified: 1998, notes: "Standard 1G single-mode. Also works on MMF with mode conditioning patch cable." }, - { standard: "1000BASE-ZX", ieeeReference: "Vendor-defined (not IEEE)", speed: "1G", lanes: 1, laneRate: "1.25 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1550nm", maxReachMeters: 80000, maxReachLabel: "70-80km", connector: "LC", fecRequired: false, formFactors: ["SFP"], yearRatified: 0, notes: "Not an IEEE standard. Vendor-defined. Uses 1550nm for extended reach." }, - { standard: "1000BASE-T", ieeeReference: "IEEE 802.3ab", speed: "1G", lanes: 4, laneRate: "250 Mbaud", modulation: "PAM5", fiberType: "Copper (Cat5e+)", wavelength: "N/A", maxReachMeters: 100, maxReachLabel: "100m", connector: "RJ45", fecRequired: false, formFactors: ["SFP"], yearRatified: 1999, notes: "Gigabit over copper. SFP form factor draws ~1W." }, - { standard: "1000BASE-BX10", ieeeReference: "IEEE 802.3ah", speed: "1G", lanes: 1, laneRate: "1.25 Gbaud", modulation: "NRZ", fiberType: "SMF (single fiber)", wavelength: "1310/1490nm", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: false, formFactors: ["SFP"], yearRatified: 2004, notes: "Bidirectional over single fiber strand. Sold in pairs." }, - - // 10G - { standard: "10GBASE-SR", ieeeReference: "IEEE 802.3ae", speed: "10G", lanes: 1, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "MMF (OM3/OM4)", wavelength: "850nm", maxReachMeters: 400, maxReachLabel: "300m (OM3) / 400m (OM4)", connector: "LC", fecRequired: false, formFactors: ["SFP+", "XFP"], yearRatified: 2002, notes: "Most deployed 10G optic worldwide." }, - { standard: "10GBASE-LR", ieeeReference: "IEEE 802.3ae", speed: "10G", lanes: 1, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1310nm", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: false, formFactors: ["SFP+", "XFP"], yearRatified: 2002, notes: "Standard 10G single-mode. Backbone of campus and metro networks." }, - { standard: "10GBASE-ER", ieeeReference: "IEEE 802.3ae", speed: "10G", lanes: 1, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1550nm", maxReachMeters: 40000, maxReachLabel: "40km", connector: "LC", fecRequired: false, formFactors: ["SFP+", "XFP"], yearRatified: 2002, notes: "Extended reach 10G for metro rings and inter-city links." }, - { standard: "10GBASE-ZR", ieeeReference: "Vendor-defined (not IEEE)", speed: "10G", lanes: 1, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1550nm", maxReachMeters: 80000, maxReachLabel: "80km", connector: "LC", fecRequired: false, formFactors: ["SFP+", "XFP"], yearRatified: 0, notes: "Not an IEEE standard. Vendor-defined. 80km reach with high-power laser." }, - { standard: "10GBASE-T", ieeeReference: "IEEE 802.3an", speed: "10G", lanes: 4, laneRate: "2.5 Gbaud", modulation: "PAM16/DSQ128", fiberType: "Copper (Cat6a/Cat7)", wavelength: "N/A", maxReachMeters: 100, maxReachLabel: "100m (Cat6a)", connector: "RJ45", fecRequired: false, formFactors: ["SFP+"], yearRatified: 2006, notes: "10G over copper. 30m on Cat6, 100m on Cat6a." }, - { standard: "10GBASE-LRM", ieeeReference: "IEEE 802.3aq", speed: "10G", lanes: 1, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "MMF (legacy OM1/OM2)", wavelength: "1310nm", maxReachMeters: 220, maxReachLabel: "220m", connector: "LC", fecRequired: false, formFactors: ["SFP+"], yearRatified: 2006, notes: "10G over legacy multimode fiber." }, - - // 25G - { standard: "25GBASE-SR", ieeeReference: "IEEE 802.3by", speed: "25G", lanes: 1, laneRate: "25.78125 Gbaud", modulation: "NRZ", fiberType: "MMF (OM3/OM4)", wavelength: "850nm", maxReachMeters: 100, maxReachLabel: "70m (OM3) / 100m (OM4)", connector: "LC", fecRequired: true, formFactors: ["SFP28"], yearRatified: 2016, notes: "Standard 25G data center server access." }, - { standard: "25GBASE-LR", ieeeReference: "IEEE 802.3cc", speed: "25G", lanes: 1, laneRate: "25.78125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1310nm", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: false, formFactors: ["SFP28"], yearRatified: 2017, notes: "25G single-mode for campus/metro. Critical for 5G fronthaul (eCPRI)." }, - { standard: "25GBASE-ER", ieeeReference: "IEEE 802.3cc", speed: "25G", lanes: 1, laneRate: "25.78125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1310nm", maxReachMeters: 30000, maxReachLabel: "30km", connector: "LC", fecRequired: true, formFactors: ["SFP28"], yearRatified: 2017, notes: "Extended reach 25G for metro and 5G midhaul." }, - - // 40G - { standard: "40GBASE-SR4", ieeeReference: "IEEE 802.3ba", speed: "40G", lanes: 4, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "MMF (OM3/OM4)", wavelength: "850nm", maxReachMeters: 150, maxReachLabel: "100m (OM3) / 150m (OM4)", connector: "MPO-12", fecRequired: false, formFactors: ["QSFP+"], yearRatified: 2010, notes: "4x10G parallel optics. Can break out to 4x10GBASE-SR." }, - { standard: "40GBASE-LR4", ieeeReference: "IEEE 802.3ba", speed: "40G", lanes: 4, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1310nm (4 CWDM wavelengths)", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: false, formFactors: ["QSFP+"], yearRatified: 2010, notes: "4 CWDM wavelengths over duplex LC." }, - { standard: "40GBASE-ER4", ieeeReference: "IEEE 802.3bm", speed: "40G", lanes: 4, laneRate: "10.3125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1310nm (4 CWDM wavelengths)", maxReachMeters: 40000, maxReachLabel: "40km", connector: "LC", fecRequired: false, formFactors: ["QSFP+"], yearRatified: 2015, notes: "Extended reach 40G for metro ring and DCI." }, - - // 100G - { standard: "100GBASE-SR4", ieeeReference: "IEEE 802.3bm", speed: "100G", lanes: 4, laneRate: "25.78125 Gbaud", modulation: "NRZ", fiberType: "MMF (OM3/OM4)", wavelength: "850nm", maxReachMeters: 100, maxReachLabel: "70m (OM3) / 100m (OM4)", connector: "MPO-12", fecRequired: true, formFactors: ["QSFP28"], yearRatified: 2015, notes: "4x25G parallel. Breakout to 4x25GBASE-SR." }, - { standard: "100GBASE-SR2", ieeeReference: "100G Lambda MSA", speed: "100G", lanes: 2, laneRate: "26.5625 Gbaud", modulation: "PAM4", fiberType: "MMF (OM4)", wavelength: "850nm", maxReachMeters: 100, maxReachLabel: "100m (OM4)", connector: "LC", fecRequired: true, formFactors: ["QSFP28"], yearRatified: 2018, notes: "MSA-defined. 2x50G PAM4 over duplex LC." }, - { standard: "100GBASE-DR", ieeeReference: "IEEE 802.3cd", speed: "100G", lanes: 1, laneRate: "53.125 Gbaud", modulation: "PAM4", fiberType: "SMF", wavelength: "1310nm", maxReachMeters: 500, maxReachLabel: "500m", connector: "LC", fecRequired: true, formFactors: ["QSFP28", "SFP-DD"], yearRatified: 2018, notes: "Single-lambda 100G. Key for leaf-spine architectures." }, - { standard: "100GBASE-FR1", ieeeReference: "IEEE 802.3cu", speed: "100G", lanes: 1, laneRate: "53.125 Gbaud", modulation: "PAM4", fiberType: "SMF", wavelength: "1310nm", maxReachMeters: 2000, maxReachLabel: "2km", connector: "LC", fecRequired: true, formFactors: ["QSFP28"], yearRatified: 2021, notes: "Single-lambda 100G for 2km." }, - { standard: "100GBASE-LR1", ieeeReference: "IEEE 802.3cu", speed: "100G", lanes: 1, laneRate: "53.125 Gbaud", modulation: "PAM4", fiberType: "SMF", wavelength: "1310nm", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: true, formFactors: ["QSFP28"], yearRatified: 2021, notes: "Single-lambda 100G for 10km. New IXP standard replacing LR4." }, - { standard: "100GBASE-LR4", ieeeReference: "IEEE 802.3ba", speed: "100G", lanes: 4, laneRate: "25.78125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1310nm (4 LAN-WDM wavelengths)", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: false, formFactors: ["QSFP28", "CFP", "CFP2", "CFP4"], yearRatified: 2010, notes: "4x25G LAN-WDM over duplex LC. Being replaced by LR1 single-lambda." }, - { standard: "100GBASE-CWDM4", ieeeReference: "100G CWDM4 MSA", speed: "100G", lanes: 4, laneRate: "25.78125 Gbaud", modulation: "NRZ", fiberType: "SMF", wavelength: "1271/1291/1311/1331nm", maxReachMeters: 2000, maxReachLabel: "2km", connector: "LC", fecRequired: false, formFactors: ["QSFP28"], yearRatified: 2014, notes: "MSA-defined. Lower-cost alternative to LR4 for 2km." }, - { standard: "100GBASE-PSM4", ieeeReference: "100G PSM4 MSA", speed: "100G", lanes: 4, laneRate: "25.78125 Gbaud", modulation: "NRZ", fiberType: "SMF (parallel)", wavelength: "1310nm", maxReachMeters: 500, maxReachLabel: "500m", connector: "MPO-12", fecRequired: false, formFactors: ["QSFP28"], yearRatified: 2014, notes: "MSA-defined. 4x25G parallel single-mode." }, - { standard: "100GBASE-ZR", ieeeReference: "IEEE 802.3ct", speed: "100G", lanes: 1, laneRate: "~64 Gbaud", modulation: "DP-QPSK (coherent)", fiberType: "SMF (DWDM)", wavelength: "C-band (tunable)", maxReachMeters: 80000, maxReachLabel: "80km+ (DWDM amplified)", connector: "LC", fecRequired: true, formFactors: ["QSFP28"], yearRatified: 2021, notes: "Coherent 100G over DWDM systems." }, - - // 200G - { standard: "200GBASE-SR4", ieeeReference: "IEEE 802.3cd", speed: "200G", lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", fiberType: "MMF (OM4)", wavelength: "850nm", maxReachMeters: 100, maxReachLabel: "70m (OM3) / 100m (OM4)", connector: "MPO-12", fecRequired: true, formFactors: ["QSFP56", "QSFP-DD"], yearRatified: 2018, notes: "4x50G PAM4 parallel." }, - { standard: "200GBASE-DR4", ieeeReference: "IEEE 802.3cd", speed: "200G", lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", fiberType: "SMF (parallel)", wavelength: "1310nm", maxReachMeters: 500, maxReachLabel: "500m", connector: "MPO-12", fecRequired: true, formFactors: ["QSFP56", "QSFP-DD"], yearRatified: 2018, notes: "4x50G parallel SMF. Can break out to 2x100G-DR or 4x50G." }, - { standard: "200GBASE-FR4", ieeeReference: "IEEE 802.3cu", speed: "200G", lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", fiberType: "SMF", wavelength: "1310nm (4 CWDM wavelengths)", maxReachMeters: 2000, maxReachLabel: "2km", connector: "LC", fecRequired: true, formFactors: ["QSFP56", "QSFP-DD"], yearRatified: 2021, notes: "4x50G CWDM over duplex LC for 2km reach." }, - { standard: "200GBASE-LR4", ieeeReference: "IEEE 802.3cu", speed: "200G", lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", fiberType: "SMF", wavelength: "1310nm (4 CWDM wavelengths)", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: true, formFactors: ["QSFP56", "QSFP-DD"], yearRatified: 2021, notes: "4x50G CWDM over duplex LC for 10km reach." }, - - // 400G - { standard: "400GBASE-SR8", ieeeReference: "IEEE 802.3cm", speed: "400G", lanes: 8, laneRate: "26.5625 Gbaud", modulation: "PAM4", fiberType: "MMF (OM4)", wavelength: "850nm", maxReachMeters: 100, maxReachLabel: "100m (OM4)", connector: "MPO-16", fecRequired: true, formFactors: ["QSFP-DD", "OSFP"], yearRatified: 2020, notes: "8x50G PAM4 parallel." }, - { standard: "400GBASE-SR4.2", ieeeReference: "IEEE 802.3cm", speed: "400G", lanes: 4, laneRate: "26.5625 Gbaud", modulation: "PAM4", fiberType: "MMF", wavelength: "850nm + 910nm (BiDi)", maxReachMeters: 100, maxReachLabel: "100m", connector: "MPO-12", fecRequired: true, formFactors: ["QSFP-DD", "OSFP"], yearRatified: 2020, notes: "BiDi 400G over MPO-12 using two wavelengths." }, - { standard: "400GBASE-DR4", ieeeReference: "IEEE 802.3bs", speed: "400G", lanes: 4, laneRate: "53.125 Gbaud", modulation: "PAM4", fiberType: "SMF (parallel)", wavelength: "1310nm", maxReachMeters: 500, maxReachLabel: "500m", connector: "MPO-12", fecRequired: true, formFactors: ["QSFP-DD", "OSFP"], yearRatified: 2017, notes: "4x100G parallel SMF. THE key 400G data center optic." }, - { standard: "400GBASE-FR4", ieeeReference: "IEEE 802.3cu", speed: "400G", lanes: 4, laneRate: "53.125 Gbaud", modulation: "PAM4", fiberType: "SMF", wavelength: "1271/1291/1311/1331nm (CWDM4)", maxReachMeters: 2000, maxReachLabel: "2km", connector: "LC", fecRequired: true, formFactors: ["QSFP-DD", "OSFP"], yearRatified: 2021, notes: "4x100G CWDM over duplex LC." }, - { standard: "400GBASE-LR4-10", ieeeReference: "IEEE 802.3cu", speed: "400G", lanes: 4, laneRate: "53.125 Gbaud", modulation: "PAM4", fiberType: "SMF", wavelength: "1271/1291/1311/1331nm (CWDM4)", maxReachMeters: 10000, maxReachLabel: "10km", connector: "LC", fecRequired: true, formFactors: ["QSFP-DD", "OSFP"], yearRatified: 2021, notes: "4x100G CWDM for 10km. Standard for metro/IXP 400G." }, - { standard: "400GBASE-ZR (OIF 400ZR)", ieeeReference: "OIF-400ZR-01.0", speed: "400G", lanes: 1, laneRate: "~60 Gbaud", modulation: "DP-16QAM (coherent)", fiberType: "SMF", wavelength: "C-band (tunable, 75 GHz DWDM grid)", maxReachMeters: 120000, maxReachLabel: "up to 120km (amplified)", connector: "LC", fecRequired: true, formFactors: ["QSFP-DD", "OSFP", "CFP2-DCO"], yearRatified: 2020, notes: "OIF interoperable coherent 400G. Collapses IP/optical layers." }, - - // 800G - { standard: "800GBASE-SR8", ieeeReference: "IEEE 802.3df", speed: "800G", lanes: 8, laneRate: "106.25 Gbaud", modulation: "PAM4", fiberType: "MMF (OM4)", wavelength: "850nm", maxReachMeters: 50, maxReachLabel: "50m (OM3) / 100m (OM4)", connector: "2x MPO-12", fecRequired: true, formFactors: ["OSFP"], yearRatified: 2024, notes: "8x100G PAM4 parallel." }, - { standard: "800GBASE-DR8", ieeeReference: "IEEE 802.3df", speed: "800G", lanes: 8, laneRate: "106.25 Gbaud", modulation: "PAM4", fiberType: "SMF (parallel)", wavelength: "1310nm", maxReachMeters: 500, maxReachLabel: "500m", connector: "2x MPO-12", fecRequired: true, formFactors: ["OSFP", "QSFP-DD800"], yearRatified: 2024, notes: "Primary 800G DC optic. 8x100G parallel SMF." }, - { standard: "OIF 800ZR", ieeeReference: "OIF-800ZR", speed: "800G", lanes: 1, laneRate: "~90 Gbaud", modulation: "DP-16QAM / DP-64QAM (coherent)", fiberType: "SMF", wavelength: "C-band (tunable)", maxReachMeters: 120000, maxReachLabel: "up to 120km+ (amplified)", connector: "LC", fecRequired: true, formFactors: ["OSFP", "QSFP-DD800", "CFP2-DCO"], yearRatified: 2024, notes: "800G pluggable coherent. Building on 400ZR success for DCI." }, -]; - -/** Find a standard by exact or partial name. */ -export function getStandard(name: string): Standard | undefined { - const q = name.toLowerCase(); - return standards.find((s) => s.standard.toLowerCase() === q) || - standards.find((s) => s.standard.toLowerCase().includes(q)); -} - -/** Search standards by keyword (speed, modulation, IEEE reference, etc.). */ -export function searchStandards(query: string): Standard[] { - const q = query.toLowerCase(); - return standards.filter( - (s) => - s.standard.toLowerCase().includes(q) || - s.speed.toLowerCase().includes(q) || - s.ieeeReference.toLowerCase().includes(q) || - s.modulation.toLowerCase().includes(q) || - s.notes.toLowerCase().includes(q) - ); -} diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 451022e..0000000 --- a/src/types.ts +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Core type definitions for the transceiver database. - */ - -export type FormFactor = - | "SFP" - | "SFP+" - | "SFP28" - | "SFP56" - | "QSFP+" - | "QSFP28" - | "QSFP56" - | "QSFP-DD" - | "OSFP" - | "CFP" - | "CFP2" - | "CFP4" - | "CFP2-DCO" - | "XFP" - | "GBIC" - | "CXP" - | "SFP-DD" - | "SFP56-DD" - | "QSFP-DD800" - | "OSFP-XD"; - -export type FiberType = "MMF" | "SMF" | "MMF/SMF" | "Copper" | "N/A"; - -export type ConnectorType = - | "LC" - | "SC" - | "MPO-12" - | "MPO-16" - | "MPO-24" - | "RJ45" - | "None" - | "CS" - | "SN" - | "2xMPO-12"; - -export type TempRange = "COM" | "IND"; - -export type ProductCategory = - | "DataCenter" - | "Metro" - | "LongHaul" - | "DCI" - | "Access" - | "Coherent" - | "CWDM" - | "DWDM" - | "BiDi" - | "AOC" - | "DAC" - | "Breakout" - | "Legacy" - | "IXP" - | "5G" - | "AI"; - -export type PriceTier = "Budget" | "Standard" | "Premium"; - -export type MarketStatus = "Mainstream" | "Growth" | "Emerging" | "Legacy" | "EOL"; - -export interface VendorCompat { - vendor: string; - partPattern: string; -} - -export interface Transceiver { - id: string; - standard: string; - ieeeReference?: string; - formFactor: FormFactor; - speed: string; - speedGbps: number; - lanes?: number; - laneRate?: string; - modulation?: string; - reachMeters: number; - reachLabel: string; - fiberType: FiberType; - wavelengths: string; - connector: ConnectorType; - powerConsumptionW: number; - tempRange: TempRange; - category: ProductCategory; - priceTier: PriceTier; - useCase: string; - vendors: VendorCompat[]; - tags: string[]; - generation?: string; - marketStatus?: MarketStatus; - yearIntroduced?: number; - breakoutCapable?: boolean; - breakoutTo?: string; -} - -export interface Standard { - standard: string; - ieeeReference: string; - speed: string; - lanes: number; - laneRate: string; - modulation: string; - fiberType: string; - wavelength: string; - maxReachMeters: number; - maxReachLabel: string; - connector: string; - fecRequired: boolean; - formFactors: string[]; - yearRatified: number; - notes: string; -} - -export interface Competitor { - name: string; - type: "OEM" | "Whitebox" | "Manufacturer" | "Distributor" | "Compatible"; - headquarters: string; - marketPosition: string; - formFactorsOffered: string[]; - speedTiersOffered: string[]; - strengths: string[]; - weaknesses: string[]; -} - -export interface Breakout { - id: string; - from: string; - to: string; - formFactor: string; - description: string; - cableType: "Passive" | "Active"; - maxLength: string; - speedPerLane: string; -}