<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Mouser Component Search Service</title>
<style>
@font-face {
  font-family: 'Familjen Grotesk';
  src: url('https://adom.inc/fonts/familjen-grotesk/familjen-grotesk-latin-600-normal.woff2') format('woff2');
  font-weight: 600; font-display: swap;
}
@font-face {
  font-family: 'Satoshi';
  src: url('https://adom.inc/fonts/satoshi/satoshi-400-normal.woff2') format('woff2');
  font-weight: 400; font-display: swap;
}
:root {
  --bg: #0d1117;
  --surface: #161b22;
  --surface2: #1c2129;
  --border: #30363d;
  --text: #e6edf3;
  --text-dim: #8b949e;
  --accent: #00b8b0;
  --green: #3fb950;
  --red: #f85149;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: 'Satoshi', sans-serif;
  padding: 32px;
  line-height: 1.6;
  max-width: 800px;
  margin: 0 auto;
}
h1 { font-family: 'Familjen Grotesk', sans-serif; font-size: 28px; margin-bottom: 8px; }
h2 { font-family: 'Familjen Grotesk', sans-serif; font-size: 18px; margin: 24px 0 8px; color: var(--accent); }
.subtitle { color: var(--text-dim); margin-bottom: 24px; }
.status { display: inline-block; padding: 4px 12px; border-radius: 8px; font-size: 13px; font-weight: 600; margin-bottom: 24px; }
.status.ok { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid rgba(63,185,80,0.3); }
.status.err { background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid rgba(248,81,73,0.3); }
pre { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px; overflow-x: auto; font-size: 13px; line-height: 1.5; margin: 8px 0 16px; }
code { font-family: 'JetBrains Mono', monospace; }
.endpoint { margin: 12px 0; }
.method { display: inline-block; background: #1f6feb; color: #fff; padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 700; margin-right: 8px; font-family: 'JetBrains Mono', monospace; }
.method.post { background: var(--green); }
p { margin: 8px 0; color: var(--text); }
a { color: var(--accent); }
</style>
</head><body>
<h1>Mouser Component Search Service</h1>
<p class="subtitle">Shared HTTP proxy for the Mouser Electronics API v2. Keeps the API key server-side with in-memory caching.</p>
<span class="status {{STATUS_CLASS}}">{{STATUS_TEXT}}</span>

<h2>Endpoints</h2>

<div class="endpoint">
  <span class="method">GET</span> <code>/search?keyword=...&amp;limit=10&amp;inStockOnly=true</code>
  <p>Search by keyword, MPN, or description. Returns normalized component data.</p>
  <pre>curl '{{BASE_URL}}/search?keyword=STM32F103&amp;limit=5'</pre>
</div>

<div class="endpoint">
  <span class="method">GET</span> <code>/part?partNumber=...</code>
  <p>Look up a specific part by Mouser PN or manufacturer PN.</p>
  <pre>curl '{{BASE_URL}}/part?partNumber=STM32F103RBT6'</pre>
</div>

<div class="endpoint">
  <span class="method">GET</span> <code>/health</code>
  <p>Service health check (API key status, cache stats, live API ping).</p>
  <pre>curl '{{BASE_URL}}/health'</pre>
</div>

<div class="endpoint">
  <span class="method post">POST</span> <code>/</code>
  <p>Action-based API. Send JSON body with <code>action</code> field.</p>
  <pre>curl -X POST '{{BASE_URL}}' \
  -H 'Content-Type: application/json' \
  -d '{"action":"search","keyword":"USB-C connector","limit":10}'</pre>
</div>

<h2>Using from Claude Code</h2>
<p>Install the <code>adom-mouser</code> CLI, then:</p>
<pre>adom-mouser search "USB-C connector"
adom-mouser part 511-STM32F103RBT6
adom-mouser app    # open an interactive search UI in Hydrogen</pre>

<h2>Cache</h2>
<p>Responses are cached in-memory for 10 minutes (LRU, max 200 entries).</p>
</body></html>