@openephemeris/mcp-server 3.19.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,24 +1,27 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
3
+ <head>
4
+ <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data:; font-src data:; connect-src 'none'" />
4
5
  <meta charset="UTF-8" />
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
7
  <meta name="color-scheme" content="dark light" />
7
8
  <meta name="mcp-app-preferred-height" content="560" />
9
+ <!-- CSP is injected at build time by shared/singlefile-plugin.ts (the dev
10
+ server needs external src/ references that a strict CSP would block). -->
8
11
  <title>Moon Phase Explorer</title>
9
12
  <!-- External Google Fonts removed: Claude.ai sandbox enforces hardcoded
10
13
  frame-src 'self' blob: data: and blocks external CDN fetches at
11
14
  iframe render time. Styles fall back to the system font stack. -->
12
15
 
13
16
 
14
- <style>*,:before,:after{box-sizing:border-box;margin:0;padding:0}:root{--bg-primary:#090b0f;--bg-secondary:#12161d;--bg-tertiary:#1c222b;--bg-hover:#272e3b;--border:#282e38;--border-subtle:#1d2229;--text-primary:#e1e5eb;--text-secondary:#9da5b1;--text-muted:#6c727b;--accent:#62b3ff;--accent-warm:#e6ac3d;--voc-warn:#f6922e;--cue-warm:#f4a34b;--cue-cool:#6ab3fd;--radius:8px;--radius-sm:4px;--radius-lg:12px;--font-display:"Space Grotesk", system-ui, sans-serif;--font-body:"Inter", system-ui, sans-serif;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}@supports (color:color(display-p3 0 0 0)){:root{--bg-primary:color(display-p3 .036047 .0438664 .059078);--bg-secondary:color(display-p3 .0739679 .0866504 .111186);--bg-tertiary:color(display-p3 .114361 .13221 .166818);--bg-hover:color(display-p3 .15679 .180114 .225406);--border:color(display-p3 .161376 .180145 .216325);--border-subtle:color(display-p3 .118728 .13221 .158123);--text-primary:color(display-p3 .883958 .896627 .920543);--text-secondary:color(display-p3 .622745 .646433 .6914);--text-muted:color(display-p3 .429297 .445909 .477439);--accent:color(display-p3 .446063 .694439 1.01077);--accent-warm:color(display-p3 .866978 .684443 .324483);--voc-warn:color(display-p3 .910067 .591092 .274641);--cue-warm:color(display-p3 .911412 .653072 .360243);--cue-cool:color(display-p3 .48245 .695507 .967802)}}@supports (color:lab(0% 0 0)){:root{--bg-primary:lab(3.02674% -.179462 -2.15476);--bg-secondary:lab(7.16596% -.441141 -5.41423);--bg-tertiary:lab(12.9118% -.60384 -7.27841);--bg-hover:lab(18.6882% -.727877 -9.08878);--border:lab(18.7165% -.689313 -7.30941);--border-subtle:lab(12.9391% -.548743 -5.49436);--text-primary:lab(90.6878% -.517368 -3.73452);--text-secondary:lab(67.45% -.932217 -7.41489);--text-muted:lab(47.7476% -.701487 -5.56231);--accent:lab(70.4043% -7.21234 -50.7672);--accent-warm:lab(74.5248% 14.3487 62.5064);--voc-warn:lab(70.3313% 33.71 65.3029);--cue-warm:lab(74.0849% 25.4197 56.7058);--cue-cool:lab(70.5454% -7.4636 -44.2057)}}@media (prefers-color-scheme:light){:root{--bg-primary:#f3f5f9;--bg-secondary:#e7ebf2;--bg-tertiary:#d8dee8;--bg-hover:#d0d8e5;--border:#bdc5d1;--border-subtle:#d2d8e2;--text-primary:#0f1216;--text-secondary:#414853;--text-muted:#585e67;--accent:#0065b2;--accent-warm:#966800;--voc-warn:#a95a00;--cue-warm:#954200;--cue-cool:#1e5ba1;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@supports (color:color(display-p3 0 0 0)){:root{--bg-primary:color(display-p3 .95471 .961142 .973263);--bg-secondary:color(display-p3 .909797 .922535 .946581);--bg-tertiary:color(display-p3 .852455 .871315 .906983);--bg-hover:color(display-p3 .821139 .84609 .893374);--border:color(display-p3 .745559 .770059 .816515);--border-subtle:color(display-p3 .826933 .845684 .881152);--text-primary:color(display-p3 .0608605 .0691527 .0850621);--text-secondary:color(display-p3 .261513 .281801 .32064);--text-muted:color(display-p3 .350602 .367691 .400197);--accent:color(display-p3 .143802 .388951 .683672);--accent-warm:color(display-p3 .596632 .396992 -.158844);--voc-warn:color(display-p3 .673365 .329149 -.157701);--cue-warm:color(display-p3 .567457 .255699 -.0353967);--cue-cool:color(display-p3 .186321 .349931 .613332)}}@supports (color:lab(0% 0 0)){:root{--bg-primary:lab(96.5044% -.267148 -1.87216);--bg-secondary:lab(93.0079% -.518024 -3.73493);--bg-tertiary:lab(88.3503% -.749856 -5.58736);--bg-hover:lab(86.0117% -.963002 -7.43048);--border:lab(79.0511% -.952899 -7.42528);--border-subtle:lab(86.0302% -.748128 -5.58645);--text-primary:lab(5.23796% -.285208 -3.0582);--text-secondary:lab(30.3224% -.794604 -7.35167);--text-muted:lab(39.6225% -.718519 -5.91861);--accent:lab(41.1205% -1.70796 -50.1423);--accent-warm:lab(47.6194% 20.1868 104.51);--voc-warn:lab(46.8395% 41.0975 106.287);--cue-warm:lab(38.6598% 39.325 67.0649);--cue-cool:lab(37.6228% 1.24846 -44.7496)}}}html,body{width:100%;height:100%;min-height:480px;font-family:var(--font-body);background:var(--bg-primary);color:var(--text-primary);font-size:13px;line-height:1.5;overflow-y:auto}body{flex-direction:column;display:flex}#app{flex-direction:column;flex:1;display:flex;overflow:hidden}#loading-state{color:var(--text-secondary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;display:flex}#loading-state[hidden]{display:none}.oe-loader{width:48px;height:48px;animation:1.2s linear infinite spin}.oe-loader circle{fill:none;stroke:var(--accent);stroke-width:3px;stroke-dasharray:200;stroke-dashoffset:80px;stroke-linecap:round}@keyframes spin{to{transform:rotate(360deg)}}.chart-status{background:var(--bg-secondary);border-top:1px solid var(--border-subtle);color:var(--text-muted);opacity:0;z-index:50;padding:6px 14px;font-size:11px;transition:opacity .2s,transform .2s;position:fixed;bottom:0;left:0;right:0;transform:translateY(100%)}.chart-status.visible{opacity:1;transform:translateY(0)}.pan-zoom-controls{z-index:40;gap:4px;display:flex;position:fixed;top:8px;right:8px}.pan-zoom-controls[hidden]{display:none}.pan-btn{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius-sm);width:28px;height:28px;color:var(--text-secondary);cursor:pointer;justify-content:center;align-items:center;font-size:14px;transition:background .15s,color .15s;display:flex}.pan-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.pan-btn.reset{width:auto;padding:0 10px;font-size:12px}#moon-container{flex-direction:column;flex:1;min-height:440px;padding:16px;display:flex;overflow-y:auto}#moon-container[hidden]{display:none}.moon-layout{flex:1;align-items:flex-start;gap:24px;display:flex}@media (max-width:500px){.moon-layout{flex-direction:column;align-items:center;gap:16px}}.moon-dial-col{flex-direction:column;flex-shrink:0;align-items:center;gap:12px;display:flex}.moon-dial{justify-content:center;align-items:center;width:200px;height:200px;display:flex;position:relative}.moon-svg{filter:drop-shadow(0 0 20px rgba(131,163,187,.2));filter:drop-shadow(0 0 20px color(display-p3 .537913 .6362 .723376/.2));filter:drop-shadow(0 0 20px lab(65.2381% -7.35197 -16.1178/.2));width:100%;height:100%;animation:.8s ease-out moon-fade-in}@keyframes moon-fade-in{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}.moon-illum-ring{background:var(--bg-secondary);border:1px solid var(--border-subtle);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:20px;flex-direction:column;align-items:center;gap:1px;padding:3px 10px;display:flex;position:absolute;bottom:-2px}.moon-illum-value{font-size:22px;font-weight:700;font-family:var(--font-display);font-variant-numeric:tabular-nums;color:var(--accent-warm);letter-spacing:-.02em}.moon-illum-label{text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);font-size:9px}.moon-phase-badge{background:var(--bg-secondary);border:1px solid var(--border);border-radius:20px;align-items:center;gap:6px;padding:6px 14px;display:flex}.moon-phase-icon{font-size:18px}.moon-phase-name{font-size:15px;font-weight:700;font-family:var(--font-display);letter-spacing:-.01em;text-transform:capitalize}.moon-direction{color:var(--text-muted);align-items:center;gap:4px;font-size:12px;display:flex}.dir-arrow{font-size:14px;font-weight:700}.dir-waxing{color:#57bc8a;color:color(display-p3 .44464 .726476 .557142);color:lab(69.1118% -39.6203 15.6094)}.dir-waning{color:#e6857e;color:color(display-p3 .850722 .541293 .507352);color:lab(66.3643% 37.397 20.9063)}.moon-info-col{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.moon-card{background:var(--bg-secondary);border:1px solid var(--border-subtle);border-radius:var(--radius);cursor:pointer;padding:10px 14px;transition:background .15s,border-color .15s,box-shadow .15s}.moon-card:hover{background:var(--bg-hover);border-color:var(--border);box-shadow:0 2px 12px rgba(0,0,0,.1);box-shadow:0 2px 12px color(display-p3 0 0 0/.1);box-shadow:0 2px 12px lab(0% 0 0/.1)}.moon-card--voc.moon-card--active{border-color:var(--voc-warn);background:#2c1e13;background:color(display-p3 .165435 .120647 .0798046);background:lab(12.9057% 5.79391 10.6146)}@media (prefers-color-scheme:light){.moon-card--voc.moon-card--active{background:#ffead8;background:color(display-p3 1.00032 .917094 .842425);background:lab(94.1113% 7.0433 13.5336)}}.moon-card-header{align-items:center;gap:6px;margin-bottom:4px;display:flex}.moon-card-icon{font-size:14px}.moon-card-title{font-size:11px;font-weight:600;font-family:var(--font-body);text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted)}.moon-card-chevron{color:var(--text-muted);flex-shrink:0;margin-left:auto;font-size:13px;transition:transform .2s}.moon-card--open .moon-card-chevron{transform:rotate(90deg)}.moon-card-value{font-size:16px;font-weight:700;font-family:var(--font-display);color:var(--text-primary);text-transform:capitalize;line-height:1.2}.moon-card-detail{color:var(--text-muted);margin-top:2px;font-size:11px}.moon-card--primary{border-color:var(--border);padding:8px 13px}.moon-card--primary .moon-card-value{letter-spacing:-.02em;font-size:16px}.moon-card--primary .moon-card-header{margin-bottom:2px}.moon-card--primary .moon-card-title{font-size:10px}.moon-card--compact{padding:6px 12px}.moon-card--compact .moon-card-header{margin-bottom:2px}.moon-card--compact .moon-card-value{font-size:13px;font-weight:600}.moon-card--compact .moon-card-title{letter-spacing:.06em;font-size:10px}.moon-card--inline{padding:6px 12px}.moon-card--inline .moon-card-header{gap:8px;margin-bottom:0}.moon-card--inline .moon-card-title{letter-spacing:.06em;font-size:10px}.moon-card-inline-value{font-family:var(--font-display);color:var(--text-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;margin-left:auto;font-size:13px;font-weight:600}.moon-card-inline-value.tempo-fast,.moon-card-inline-value.prox-super{color:var(--cue-warm)}.moon-card-inline-value.tempo-slow{color:var(--cue-cool)}.moon-card-inline-value.prox-micro{color:var(--text-secondary)}.moon-card--inline .moon-card-chevron{margin-left:0}.moon-card-expand{grid-template-rows:0fr;margin-top:0;transition:grid-template-rows .22s,margin-top .22s;display:grid}.moon-card--open .moon-card-expand{grid-template-rows:1fr;margin-top:8px}.moon-card-expand-inner{overflow:hidden}.moon-card-expand-text{font-size:11px;font-family:var(--font-body);color:var(--text-secondary);border-top:1px solid var(--border-subtle);padding-top:7px;font-style:italic;line-height:1.55;display:block}.moon-card-row{color:var(--text-secondary);align-items:center;gap:4px;padding:1px 0;font-size:12px;display:flex}.moon-card-row-icon{font-size:12px}.moon-actions{flex-wrap:wrap;gap:8px;margin-top:6px;display:flex}.action-btn{border-radius:var(--radius);border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;align-items:center;gap:4px;padding:8px 14px;font-size:12px;font-weight:600;transition:background .15s,color .15s,box-shadow .15s;display:inline-flex}.action-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.action-btn--primary{color:#cbdfff;color:color(display-p3 .811259 .873257 .992208);color:lab(88.2011% -1.89927 -18.3428);background:#11397b;background:color(display-p3 .112797 .221529 .46413);background:lab(24.6079% 7.13965 -41.9262);border-color:#305289;border-color:color(display-p3 .218625 .316452 .521702);border-color:lab(34.3143% 2.02942 -35.2838)}.action-btn--primary:hover{background:#1b478f;background:color(display-p3 .151166 .273205 .543079);background:lab(30.361% 6.93905 -45.4659);box-shadow:0 0 0 1px #3862a7;box-shadow:0 0 0 1px color(display-p3 .2584 .379139 .634372);box-shadow:0 0 0 1px lab(41.0971% 2.98774 -42.2721)}.error-state,.empty-state{text-align:center;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:32px;display:flex}.error-icon,.empty-icon{font-size:32px}.error-retry-btn{border:1px solid var(--border,rgba(128,128,160,.3));color:var(--accent-warm,var(--text-primary,inherit));font:inherit;letter-spacing:.02em;cursor:pointer;background:0 0;border-radius:999px;margin-top:4px;padding:7px 20px;font-size:11px;font-weight:600;transition:background .18s,border-color .18s}.error-retry-btn:hover{background:rgba(128,128,160,.12)}.tooltip{z-index:100;border-radius:var(--radius-sm);background:var(--bg-tertiary);border:1px solid var(--border);color:var(--text-primary);pointer-events:none;opacity:0;max-width:200px;padding:6px 10px;font-size:11px;transition:opacity .15s;position:fixed}.tooltip.visible{opacity:1}.chart-layer{opacity:1;transform-origin:310px 310px;animation:.5s cubic-bezier(.16,1,.3,1) both svgLayerAssemble;animation-delay:calc(var(--layer-index,0) * 80ms);transform:scale(1)}@keyframes svgLayerAssemble{0%{opacity:0;transform:scale(.97)}to{opacity:1;transform:scale(1)}}.floating-action-btn:after{content:"";background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent);width:50%;height:100%;animation:3s 2s infinite shimmer;position:absolute;top:0;left:-100%;transform:skew(-20deg)}@keyframes shimmer{0%{left:-100%}20%{left:200%}to{left:200%}}
17
+ <style>*,:before,:after{box-sizing:border-box;margin:0;padding:0}:root{--bg-primary:#090b0f;--bg-secondary:#12161d;--bg-tertiary:#1c222b;--bg-hover:#272e3b;--border:#282e38;--border-subtle:#1d2229;--text-primary:#e1e5eb;--text-secondary:#9da5b1;--text-muted:#6c727b;--accent:#62b3ff;--accent-warm:#e6ac3d;--voc-warn:#f6922e;--cue-warm:#f4a34b;--cue-cool:#6ab3fd;--radius:8px;--radius-sm:4px;--radius-lg:12px;--font-display:"Space Grotesk", system-ui, sans-serif;--font-body:"Inter", system-ui, sans-serif;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}@supports (color:color(display-p3 0 0 0)){:root{--bg-primary:color(display-p3 .036047 .0438664 .059078);--bg-secondary:color(display-p3 .0739679 .0866504 .111186);--bg-tertiary:color(display-p3 .114361 .13221 .166818);--bg-hover:color(display-p3 .15679 .180114 .225406);--border:color(display-p3 .161376 .180145 .216325);--border-subtle:color(display-p3 .118728 .13221 .158123);--text-primary:color(display-p3 .883958 .896627 .920543);--text-secondary:color(display-p3 .622745 .646433 .6914);--text-muted:color(display-p3 .429297 .445909 .477439);--accent:color(display-p3 .446063 .694439 1.01077);--accent-warm:color(display-p3 .866978 .684443 .324483);--voc-warn:color(display-p3 .910067 .591092 .274641);--cue-warm:color(display-p3 .911412 .653072 .360243);--cue-cool:color(display-p3 .48245 .695507 .967802)}}@supports (color:lab(0% 0 0)){:root{--bg-primary:lab(3.02674% -.179462 -2.15476);--bg-secondary:lab(7.16596% -.441141 -5.41423);--bg-tertiary:lab(12.9118% -.60384 -7.27841);--bg-hover:lab(18.6882% -.727877 -9.08878);--border:lab(18.7165% -.689313 -7.30941);--border-subtle:lab(12.9391% -.548743 -5.49436);--text-primary:lab(90.6878% -.517368 -3.73452);--text-secondary:lab(67.45% -.932217 -7.41489);--text-muted:lab(47.7476% -.701487 -5.56231);--accent:lab(70.4043% -7.21234 -50.7672);--accent-warm:lab(74.5248% 14.3487 62.5064);--voc-warn:lab(70.3313% 33.71 65.3029);--cue-warm:lab(74.0849% 25.4197 56.7058);--cue-cool:lab(70.5454% -7.4636 -44.2057)}}@media (prefers-color-scheme:light){:root{--bg-primary:#f3f5f9;--bg-secondary:#e7ebf2;--bg-tertiary:#d8dee8;--bg-hover:#d0d8e5;--border:#bdc5d1;--border-subtle:#d2d8e2;--text-primary:#0f1216;--text-secondary:#414853;--text-muted:#585e67;--accent:#0065b2;--accent-warm:#966800;--voc-warn:#a95a00;--cue-warm:#954200;--cue-cool:#1e5ba1;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@supports (color:color(display-p3 0 0 0)){:root{--bg-primary:color(display-p3 .95471 .961142 .973263);--bg-secondary:color(display-p3 .909797 .922535 .946581);--bg-tertiary:color(display-p3 .852455 .871315 .906983);--bg-hover:color(display-p3 .821139 .84609 .893374);--border:color(display-p3 .745559 .770059 .816515);--border-subtle:color(display-p3 .826933 .845684 .881152);--text-primary:color(display-p3 .0608605 .0691527 .0850621);--text-secondary:color(display-p3 .261513 .281801 .32064);--text-muted:color(display-p3 .350602 .367691 .400197);--accent:color(display-p3 .143802 .388951 .683672);--accent-warm:color(display-p3 .596632 .396992 -.158844);--voc-warn:color(display-p3 .673365 .329149 -.157701);--cue-warm:color(display-p3 .567457 .255699 -.0353967);--cue-cool:color(display-p3 .186321 .349931 .613332)}}@supports (color:lab(0% 0 0)){:root{--bg-primary:lab(96.5044% -.267148 -1.87216);--bg-secondary:lab(93.0079% -.518024 -3.73493);--bg-tertiary:lab(88.3503% -.749856 -5.58736);--bg-hover:lab(86.0117% -.963002 -7.43048);--border:lab(79.0511% -.952899 -7.42528);--border-subtle:lab(86.0302% -.748128 -5.58645);--text-primary:lab(5.23796% -.285208 -3.0582);--text-secondary:lab(30.3224% -.794604 -7.35167);--text-muted:lab(39.6225% -.718519 -5.91861);--accent:lab(41.1205% -1.70796 -50.1423);--accent-warm:lab(47.6194% 20.1868 104.51);--voc-warn:lab(46.8395% 41.0975 106.287);--cue-warm:lab(38.6598% 39.325 67.0649);--cue-cool:lab(37.6228% 1.24846 -44.7496)}}}html,body{width:100%;height:100%;min-height:480px;font-family:var(--font-body);background:var(--bg-primary);color:var(--text-primary);font-size:13px;line-height:1.5;overflow-y:auto}body{flex-direction:column;display:flex}#app{flex-direction:column;flex:1;display:flex;overflow:hidden}#loading-state{color:var(--text-secondary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;display:flex}#loading-state[hidden]{display:none}.oe-loader{width:48px;height:48px;animation:1.2s linear infinite spin}.oe-loader circle{fill:none;stroke:var(--accent);stroke-width:3px;stroke-dasharray:200;stroke-dashoffset:80px;stroke-linecap:round}@keyframes spin{to{transform:rotate(360deg)}}.chart-status{background:var(--bg-secondary);border-top:1px solid var(--border-subtle);color:var(--text-muted);opacity:0;z-index:50;padding:6px 14px;font-size:11px;transition:opacity .2s,transform .2s;position:fixed;bottom:0;left:0;right:0;transform:translateY(100%)}.chart-status.visible{opacity:1;transform:translateY(0)}.pan-zoom-controls{z-index:40;gap:4px;display:flex;position:fixed;top:8px;right:8px}.pan-zoom-controls[hidden]{display:none}.pan-btn{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius-sm);width:28px;height:28px;color:var(--text-secondary);cursor:pointer;justify-content:center;align-items:center;font-size:14px;transition:background .15s,color .15s;display:flex}.pan-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.pan-btn.reset{width:auto;padding:0 10px;font-size:12px}#moon-container{flex-direction:column;flex:1;min-height:440px;padding:16px;display:flex;overflow-y:auto}#moon-container[hidden]{display:none}.moon-layout{flex:1;align-items:flex-start;gap:24px;display:flex}@media (max-width:500px){.moon-layout{flex-direction:column;align-items:center;gap:16px}}.moon-dial-col{flex-direction:column;flex-shrink:0;align-items:center;gap:12px;display:flex}.moon-dial{justify-content:center;align-items:center;width:200px;height:200px;display:flex;position:relative}.moon-svg{filter:drop-shadow(0 0 20px rgba(131,163,187,.2));filter:drop-shadow(0 0 20px color(display-p3 .537913 .6362 .723376/.2));filter:drop-shadow(0 0 20px lab(65.2381% -7.35197 -16.1178/.2));width:100%;height:100%;animation:.8s ease-out moon-fade-in}@keyframes moon-fade-in{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}.moon-illum-ring{background:var(--bg-secondary);border:1px solid var(--border-subtle);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:20px;flex-direction:column;align-items:center;gap:1px;padding:3px 10px;display:flex;position:absolute;bottom:-2px}.moon-illum-value{font-size:22px;font-weight:700;font-family:var(--font-display);font-variant-numeric:tabular-nums;color:var(--accent-warm);letter-spacing:-.02em}.moon-illum-label{text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);font-size:9px}.moon-phase-badge{background:var(--bg-secondary);border:1px solid var(--border);border-radius:20px;align-items:center;gap:6px;padding:6px 14px;display:flex}.moon-phase-icon{font-size:18px}.moon-phase-name{font-size:15px;font-weight:700;font-family:var(--font-display);letter-spacing:-.01em;text-transform:capitalize}.moon-direction{color:var(--text-muted);align-items:center;gap:4px;font-size:12px;display:flex}.dir-arrow{font-size:14px;font-weight:700}.dir-waxing{color:#57bc8a;color:color(display-p3 .44464 .726476 .557142);color:lab(69.1118% -39.6203 15.6094)}.dir-waning{color:#e6857e;color:color(display-p3 .850722 .541293 .507352);color:lab(66.3643% 37.397 20.9063)}.moon-info-col{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.moon-card{background:var(--bg-secondary);border:1px solid var(--border-subtle);border-radius:var(--radius);cursor:pointer;padding:10px 14px;transition:background .15s,border-color .15s,box-shadow .15s}.moon-card:hover{background:var(--bg-hover);border-color:var(--border);box-shadow:0 2px 12px rgba(0,0,0,.1);box-shadow:0 2px 12px color(display-p3 0 0 0/.1);box-shadow:0 2px 12px lab(0% 0 0/.1)}.moon-card:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.moon-card--voc.moon-card--active{border-color:var(--voc-warn);background:#2c1e13;background:color(display-p3 .165435 .120647 .0798046);background:lab(12.9057% 5.79391 10.6146)}@media (prefers-color-scheme:light){.moon-card--voc.moon-card--active{background:#ffead8;background:color(display-p3 1.00032 .917094 .842425);background:lab(94.1113% 7.0433 13.5336)}}.moon-card-header{align-items:center;gap:6px;margin-bottom:4px;display:flex}.moon-card-icon{font-size:14px}.moon-card-title{font-size:11px;font-weight:600;font-family:var(--font-body);text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted)}.moon-card-chevron{color:var(--text-muted);flex-shrink:0;margin-left:auto;font-size:13px;transition:transform .2s}.moon-card--open .moon-card-chevron{transform:rotate(90deg)}.moon-card-value{font-size:16px;font-weight:700;font-family:var(--font-display);color:var(--text-primary);text-transform:capitalize;line-height:1.2}.moon-card-detail{color:var(--text-muted);margin-top:2px;font-size:11px}.moon-card--primary{border-color:var(--border);padding:8px 13px}.moon-card--primary .moon-card-value{letter-spacing:-.02em;font-size:16px}.moon-card--primary .moon-card-header{margin-bottom:2px}.moon-card--primary .moon-card-title{font-size:10px}.moon-card--compact{padding:6px 12px}.moon-card--compact .moon-card-header{margin-bottom:2px}.moon-card--compact .moon-card-value{font-size:13px;font-weight:600}.moon-card--compact .moon-card-title{letter-spacing:.06em;font-size:10px}.moon-card--inline{padding:6px 12px}.moon-card--inline .moon-card-header{gap:8px;margin-bottom:0}.moon-card--inline .moon-card-title{letter-spacing:.06em;font-size:10px}.moon-card-inline-value{font-family:var(--font-display);color:var(--text-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;margin-left:auto;font-size:13px;font-weight:600}.moon-card-inline-value.tempo-fast,.moon-card-inline-value.prox-super{color:var(--cue-warm)}.moon-card-inline-value.tempo-slow{color:var(--cue-cool)}.moon-card-inline-value.prox-micro{color:var(--text-secondary)}.moon-card--inline .moon-card-chevron{margin-left:0}.moon-card-expand{grid-template-rows:0fr;margin-top:0;transition:grid-template-rows .22s,margin-top .22s;display:grid}.moon-card--open .moon-card-expand{grid-template-rows:1fr;margin-top:8px}.moon-card-expand-inner{overflow:hidden}.moon-card-expand-text{font-size:11px;font-family:var(--font-body);color:var(--text-secondary);border-top:1px solid var(--border-subtle);padding-top:7px;font-style:italic;line-height:1.55;display:block}.moon-card-row{color:var(--text-secondary);align-items:center;gap:4px;padding:1px 0;font-size:12px;display:flex}.moon-card-row-icon{font-size:12px}.moon-actions{flex-wrap:wrap;gap:8px;margin-top:6px;display:flex}.action-btn{border-radius:var(--radius);border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;align-items:center;gap:4px;padding:8px 14px;font-size:12px;font-weight:600;transition:background .15s,color .15s,box-shadow .15s;display:inline-flex}.action-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.action-btn--primary{color:#cbdfff;color:color(display-p3 .811259 .873257 .992208);color:lab(88.2011% -1.89927 -18.3428);background:#11397b;background:color(display-p3 .112797 .221529 .46413);background:lab(24.6079% 7.13965 -41.9262);border-color:#305289;border-color:color(display-p3 .218625 .316452 .521702);border-color:lab(34.3143% 2.02942 -35.2838)}.action-btn--primary:hover{background:#1b478f;background:color(display-p3 .151166 .273205 .543079);background:lab(30.361% 6.93905 -45.4659);box-shadow:0 0 0 1px #3862a7;box-shadow:0 0 0 1px color(display-p3 .2584 .379139 .634372);box-shadow:0 0 0 1px lab(41.0971% 2.98774 -42.2721)}.error-state,.empty-state{text-align:center;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:32px;display:flex}.error-icon,.empty-icon{font-size:32px}.error-retry-btn{border:1px solid var(--border,rgba(128,128,160,.3));color:var(--accent-warm,var(--text-primary,inherit));font:inherit;letter-spacing:.02em;cursor:pointer;background:0 0;border-radius:999px;margin-top:4px;padding:7px 20px;font-size:11px;font-weight:600;transition:background .18s,border-color .18s}.error-retry-btn:hover{background:rgba(128,128,160,.12)}.tooltip{z-index:100;border-radius:var(--radius-sm);background:var(--bg-tertiary);border:1px solid var(--border);color:var(--text-primary);pointer-events:none;opacity:0;max-width:200px;padding:6px 10px;font-size:11px;transition:opacity .15s;position:fixed}.tooltip.visible{opacity:1}.chart-layer{opacity:1;transform-origin:310px 310px;animation:.5s cubic-bezier(.16,1,.3,1) both svgLayerAssemble;animation-delay:calc(var(--layer-index,0) * 80ms);transform:scale(1)}@keyframes svgLayerAssemble{0%{opacity:0;transform:scale(.97)}to{opacity:1;transform:scale(1)}}.floating-action-btn:after{content:"";background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent);width:50%;height:100%;animation:3s 2s infinite shimmer;position:absolute;top:0;left:-100%;transform:skew(-20deg)}@keyframes shimmer{0%{left:-100%}20%{left:200%}to{left:200%}}
15
18
  /*$vite$:1*/</style>
16
19
  </head>
17
20
  <body>
18
21
  <div id="app">
19
22
  <div id="loading-state">
20
23
  <svg class="oe-loader" viewBox="0 0 100 100"><circle cx="50" cy="50" r="45"/></svg>
21
- <p>Computing lunar phase…</p>
24
+ <p>Reading tonight's moon…</p>
22
25
  </div>
23
26
  <div id="chart-status" class="chart-status" aria-live="polite"></div>
24
27
  <!-- Moon phase doesn't need zoom — image is fixed. Container is kept so
@@ -6635,16 +6638,20 @@ function c_(e4, t2, n2, r2) {
6635
6638
  var t3, n3, r3, i3, a3 = ((t3 = e5.aspect) == null ? "" : t3).toLowerCase().replace(/-/g, ""), o3 = (n3 = t_[a3]) == null ? e5.aspect : n3, s3 = (r3 = n_[a3]) == null ? e5.aspect : r3, c3 = e5.orb === null ? "" : " \xB7 " + (Math.round(((i3 = e5.orb) == null ? 0 : i3) * 100) / 100).toFixed(1) + "\xB0";
6636
6639
  b2 += '<div class="moon-card-row">\u263D ' + o3 + ' <span style="color:var(--text-muted); font-size:10px; letter-spacing:.04em; text-transform:uppercase; margin-right:2px">' + l_(s3) + "</span> \xB7 " + l_(e5.planet) + c3 + "</div>";
6637
6640
  }), b2 += x2("Applying aspects are those the Moon is building toward before leaving the current sign. Tighter orbs (closer to 0\xB0) carry more weight. Aspects to benefics (Venus, Jupiter) are generally favorable; to malefics (Mars, Saturn) may bring tension."), b2 += "</div>"), b2 += '<div class="moon-actions">', b2 += '<button class="action-btn action-btn--primary" id="moon-interpret-btn">\u2728 Interpret this phase</button>', _2 && (b2 += '<button class="action-btn" id="moon-voc-btn">\u{1F52E} What does VOC mean?</button>'), b2 += "</div>", b2 += "</div>", b2 += "</div>", e4.innerHTML = b2, e4.querySelectorAll(".moon-card[data-detail]").forEach(function(t3) {
6638
- t3.addEventListener("click", function(n3) {
6641
+ var n3 = t3.querySelector(".moon-card-title");
6642
+ t3.setAttribute("tabindex", "0"), t3.setAttribute("role", "button"), t3.setAttribute("aria-expanded", "false"), t3.setAttribute("aria-label", (n3 && n3.textContent || t3.dataset.detail || "Detail") + " \u2014 expand details"), t3.addEventListener("keydown", function(e5) {
6643
+ var n4 = e5;
6644
+ n4.key !== "Enter" && n4.key !== " " || (n4.preventDefault(), t3.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true })));
6645
+ }), t3.addEventListener("click", function(n4) {
6639
6646
  var i3;
6640
- if (!n3.target.closest("button")) {
6647
+ if (!n4.target.closest("button")) {
6641
6648
  r2((i3 = t3.dataset.detail) == null ? "" : i3);
6642
6649
  var a3 = t3.classList.contains("moon-card--open");
6643
6650
  e4.querySelectorAll(".moon-card--open").forEach(function(e5) {
6644
- e5.classList.remove("moon-card--open"), e5.querySelectorAll(".moon-card-expand").forEach(function(e6) {
6651
+ e5.classList.remove("moon-card--open"), e5.setAttribute("aria-expanded", "false"), e5.querySelectorAll(".moon-card-expand").forEach(function(e6) {
6645
6652
  e6.setAttribute("aria-hidden", "true");
6646
6653
  });
6647
- }), a3 || (t3.classList.add("moon-card--open"), t3.querySelectorAll(".moon-card-expand").forEach(function(e5) {
6654
+ }), a3 || (t3.classList.add("moon-card--open"), t3.setAttribute("aria-expanded", "true"), t3.querySelectorAll(".moon-card-expand").forEach(function(e5) {
6648
6655
  e5.removeAttribute("aria-hidden");
6649
6656
  }));
6650
6657
  }
@@ -6755,7 +6762,7 @@ function D_(e4, t2) {
6755
6762
  }
6756
6763
  function O_() {
6757
6764
  E_(), __.setAttribute("hidden", ""), g_.removeAttribute("hidden"), T_ = setTimeout(() => {
6758
- D_("Still no response from the server. Please close and re-open the moon phase view.");
6765
+ D_("The moon phase didn't load. Tap to try again.", O_);
6759
6766
  }, 3e4), y_.sendMessage({ role: "user", content: [{ type: "text", text: "Please regenerate the moon phase." }] }).catch(() => {
6760
6767
  });
6761
6768
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openephemeris/mcp-server",
3
- "version": "3.19.0",
3
+ "version": "3.21.0",
4
4
  "description": "Model Context Protocol server for the Open Ephemeris astronomical computation API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,7 +32,6 @@
32
32
  "harness": "vite --config vite.harness.config.ts",
33
33
  "validate:visual": "node scripts/visual-check.mjs",
34
34
  "test:integration": "tsx scripts/test-client.ts",
35
- "test:sse": "tsx scripts/test-sse-client.ts",
36
35
  "test:published": "tsx scripts/test-published.ts",
37
36
  "test:mcp-http": "tsx scripts/test-mcp-http.ts",
38
37
  "typecheck": "tsc --noEmit",
@@ -43,9 +42,11 @@
43
42
  "sync:readme": "tsx scripts/sync-readme.ts --write",
44
43
  "check:readme": "tsx scripts/sync-readme.ts --check",
45
44
  "check:pack": "tsx scripts/pack-audit.ts",
45
+ "regen:plugin": "tsx scripts/plugin-audit.ts --write",
46
+ "check:plugin": "tsx scripts/plugin-audit.ts --check",
46
47
  "build:skills": "node scripts/build-skills.mjs",
47
48
  "check:skills": "node scripts/build-skills.mjs --check",
48
- "verify:release": "npm run check:dev-allowlist && npm run check:schema-packs && npm run check:readme && npm run check:skills && npm run typecheck && npm test && npm run build && npm run check:pack",
49
+ "verify:release": "npm run check:dev-allowlist && npm run check:schema-packs && npm run check:readme && npm run check:skills && npm run check:plugin && npm run typecheck && npm test && npm run build && npm run check:pack",
49
50
  "prepack": "npm run build",
50
51
  "prepublishOnly": "npm run verify:release"
51
52
  },
@@ -83,6 +84,7 @@
83
84
  "devDependencies": {
84
85
  "@axe-core/playwright": "^4.11.3",
85
86
  "@playwright/test": "^1.60.0",
87
+ "@types/adm-zip": "^0.5.8",
86
88
  "@types/express": "^5.0.3",
87
89
  "@types/node": "^25.0.1",
88
90
  "adm-zip": "^0.5.17",