imcp2 0.2.0

Minimal MCP server that bridges an LLM to the Internet Computer, speaking textual Candid.
Documentation
:root {
  color-scheme: light dark;
  --bg: #faf9f5;
  --surface: #ffffff;
  --ink: #1a1a1a;
  --secondary: #4b4943;
  --muted: #868078;
  --accent: #a8482b;
  --hairline: #e7e3da;
  --grid: rgba(26, 26, 26, 0.04);
  --font-display: ui-serif, "Iowan Old Style", Georgia, Cambria, "Times New Roman", serif;
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
:root[data-theme="dark"] {
  --bg: #14110d; --surface: #1c1813; --ink: #f0ebe0; --secondary: #cfc7b8;
  --muted: #9a9384; --accent: #c25a37; --hairline: #342e25; --grid: rgba(240, 235, 224, 0.05);
}
:root[data-theme="light"] {
  --bg: #faf9f5; --surface: #ffffff; --ink: #1a1a1a; --secondary: #4b4943;
  --muted: #868078; --accent: #a8482b; --hairline: #e7e3da; --grid: rgba(26, 26, 26, 0.04);
}
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-ui);
  line-height: 1.5;
  color: var(--ink);
  background-color: var(--bg);
  background-image:
    linear-gradient(to right, var(--grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px);
  background-size: 24px 24px;
}
/* Full-bleed screen: the status stage fills the viewport and stays centered,
   while the "Hosted by" mark sits anchored at the foot of the page. */
.screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.stage {
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.25rem;
  padding: 2rem 1.5rem;
  text-align: center;
}
/* The spinner sits on a soft elevated tile, subtly lighter than the grid. */
.spinner-tile {
  width: 8.5rem;
  height: 8.5rem;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 20px;
}
.spinner {
  width: 3.1rem;
  height: 3.1rem;
  border-radius: 50%;
  border: 4px solid var(--hairline);
  border-top-color: var(--accent);
  animation: connect-spin 0.8s linear infinite;
}
/* Editorial serif headline, allowed to wrap to a couple of lines. `text-wrap:
   balance` evens the lines so a headline never leaves one lonely word on the
   last line (browsers that predate it just fall back to normal wrapping). A hair
   more width than the copy needs lets balancing pick the nicer break point. */
.msg {
  margin: 0;
  max-width: 24ch;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.85rem, 6vw, 2.45rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-wrap: balance;
}
/* Body copy uses `text-wrap: pretty` so the last line is never a single orphan
   word; both selectors degrade gracefully where the property is unsupported. */
.detail { margin: 0; max-width: 34ch; font-size: 1.02rem; line-height: 1.55; color: var(--secondary); text-wrap: pretty; }
.hint { margin: 0; max-width: 34ch; font-size: 0.9rem; line-height: 1.5; color: var(--muted); text-wrap: pretty; }
/* Links appear in the error copy (the error page's contact line, and the callback
   page's contact line once it enters the error state): keep them on the Ember
   accent so they read as links in both themes without a UA blue. */
.detail a, .hint a { color: var(--accent); }
/* The callback page carries a "contact us to report it" line that stays hidden
   during a normal connect and appears only once a terminal error is shown (the
   page's script adds `.error` to `.screen`). The standalone error pages ship the
   `.error` state, so their `.hint` (which is not a `.contact-hint`) is unaffected
   and always visible. */
.contact-hint { display: none; }
.screen.error .contact-hint { display: block; }
/* On the callback page the status message and its contact line share one
   `role=status` (polite, atomic) live region, so a screen reader announces the
   error AND the "contact us" line together when the page enters its error state.
   The wrapper mirrors the stage's own column layout and gap so the grouping does
   not change the visual spacing. */
.status { display: flex; flex-direction: column; align-items: center; gap: 2.25rem; }
/* Foot-of-page attribution: an eyebrow label + the DFINITY mark in a soft pill. */
.hosted {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 1rem 1.5rem 2.75rem;
}
.hosted-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--secondary);
}
.hosted-logo {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 0.9rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 12px;
}
.dfinity-logo { height: 1.1rem; width: auto; color: var(--ink); }
/* Terminal error: the spinner tile is dropped and the message carries the state.
   The pinned page's script adds `.error` to `.screen`; the error page ships it. */
.screen.error .spinner-tile { display: none; }
@keyframes connect-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #14110d; --surface: #1c1813; --ink: #f0ebe0; --secondary: #cfc7b8;
    --muted: #9a9384; --accent: #c25a37; --hairline: #342e25; --grid: rgba(240, 235, 224, 0.05);
  }
}