npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@workingdevshero/olympia-ait-adapter

v0.1.1

Published

MCP adapter that converts between Olympia Fitness & Performance program XLSX workbooks and a strict JSON schema.

Readme

olympia-ait-adapter

MCP adapter that converts Olympia Fitness & Performance program XLSX workbooks to and from a strict JSON schema. Built for the Automate It framework so AI agents can author new strength-and-conditioning programs from prior client data without ever touching XLSX directly.

Why this exists

Olympia's coaches build client programs in XLSX workbooks — one client per file, one sheet per training day, with merged cells, custom borders, an embedded logo, and a domain-specific notation (12E, :20E, 12EL, x3 Rest :60, etc.). Asking an LLM to edit XLSX directly is fragile: it corrupts merges, loses the logo, and can't reason about the implicit 6-week / 1A-1B / set-by-set structure encoded in the visual layout.

This package gives the agent a clean structured view of an Olympia program and guarantees well-formed output: the LLM reads JSON, reasons about it, writes JSON, and the adapter handles all the visual fidelity on the way back to XLSX.

What it does

Two MCP tools, exposed over stdio:

| Tool | Direction | Purpose | | ------------------------ | --------------- | ------------------------------------------------------------------ | | olympia_xlsx_to_json | XLSX → JSON | Parse an Olympia workbook into a typed Program document. | | olympia_json_to_xlsx | JSON → XLSX | Render a Program document back to a styled .xlsx on disk. |

The JSON schema is defined once in src/schema/program.ts using Zod and surfaces as:

  1. The TypeScript type used internally
  2. The runtime validator at each tool boundary
  3. The JSON Schema published as each tool's inputSchema so the LLM sees the full typed contract at discovery time

JSON shape

type Program = {
  client: string;                  // "Bobby Galli"
  programDate: string;             // "4.26"
  weekDates?: (string | null)[];   // optional, length 6
  days: Day[];
};

type Day = {
  name: string;                    // "Day 1"
  sections: Section[];
  supplementalNotes?: SupplementalNote[];
};

type Section = {
  kind: "warmup" | "main" | "sportSpecific" | "supplemental" | "conditioning";
  exercises: Exercise[];
};

type Exercise = {
  name: string;                    // "2DB Alternating Bench Press"
  groupLabel?: string;             // "1A", "1B", "2A"…  matches /^\d+[A-Z]$/
  notes?: string;
  sets: (string | null)[][];       // [setIdx][weekIdx]; inner length 6
};

type SupplementalNote = {
  row: number;                     // offset from "Sport Specific/" label row
  col: string;                     // "C" | "D" | … | "P"
  value: string;
};

Prescription cell grammar

Olympia does not prescribe weights. Each sets[setIdx][weekIdx] is a single opaque string encoding reps, time, or breaths:

| Format | Meaning | | --------------------- | ------------------------------------ | | "12" / "10E" | reps (E = each side) | | ":20" / ":20E" | seconds (E = each side) | | "5 breaths" | breath count | | "12EL" / "10ER" | reps each side, left or right lead | | free-form strings | circuit-style instructions, OK too | | null | empty cell |

The schema enforces shape (6 weeks per set, group label regex, allowed section kinds) but does not validate the grammar of each prescription string — Olympia's own files include free-form entries in some spots.

Supplemental area

The bottom of every day sheet is a trainer-managed "Sport Specific / Supplemental" area where coaches write athlete-specific instructions that don't fit the structured exercise table (conditioning circuits, sport drills, recovery work). The adapter:

  • Reads that area as a sparse list of { row, col, value } entries (master cells only) so the signal is preserved for downstream agents.
  • Writes the fixed 10-row template (with "Sport Specific/" and "Supplemental" labels) at the bottom of every day, then layers any supplied supplementalNotes on top.

Installation

npm install
npm run build

The built CLI lives at dist/server.js; the bin entry registers it as olympia-ait-adapter.

Running the MCP server

# Dev (TypeScript via tsx)
npm run dev

# Built (after `npm run build`)
npm start
# or
npx olympia-ait-adapter

The server speaks the Model Context Protocol over stdio. To wire it into Claude or another MCP client, add an entry like:

{
  "mcpServers": {
    "olympia-ait-adapter": {
      "command": "npx",
      "args": ["olympia-ait-adapter"]
    }
  }
}

Both tools take absolute paths to .xlsx files on the local filesystem.

Repo layout

src/
  schema/program.ts          # Zod schema — single source of truth
  reader/
    parse-workbook.ts        # Workbook → Program JSON
    parse-day-sheet.ts       # One sheet, section detection, supplemental capture
  writer/
    build-workbook.ts        # Program → ExcelJS workbook
    layout.ts                # Column widths, row positions, logo anchor
    styles.ts                # All borders/fonts/fills as constants
    stamp-exercise.ts        # One exercise block (variable sets, group borders)
    supplemental-template.ts # Fixed bottom template + supplementalNotes overlay
  tools/
    xlsx-to-json.ts          # MCP handler
    json-to-xlsx.ts          # MCP handler
  server.ts                  # Bootstrap, registers both tools
  assets/
    olympia-logo.png         # Extracted from sample workbooks; embedded in output

samples/                     # Real Olympia .xlsx files used as round-trip fixtures
scripts/                     # Inspection helpers used during development
tests/                       # vitest — schema, reader, round-trip, MCP smoke

Tests

npm test                     # one-shot
npm run test:watch           # vitest watch mode
npm run typecheck            # tsc --noEmit

Coverage:

  • schema.test.ts — Zod rejects malformed input (week count, group label regex, section kinds, missing fields).
  • reader.test.ts — All three sample workbooks parse into schema-valid Program documents; spot checks on Bobby's first exercise, Giulianna's variable set counts, exercise notes, supplemental notes.
  • round-trip.test.ts — The primary determinism guarantee: for each sample, parse → write → parse produces JSON equal to the original.
  • mcp-smoke.test.ts — End-to-end MCP server check via the in-memory transport: tool discovery, round-trip via client.callTool, schema rejection of malformed input at the SDK boundary.

Determinism

The writer is fully programmatic — no template .xlsx file. Every byte of the output is determined by code plus the input JSON, so the same JSON produces the same workbook. The Olympia logo is the only binary asset (src/assets/olympia-logo.png).

This trade-off is intentional: templates introduce hidden state that ExcelJS occasionally drops (drawings, theme colors), whereas pure code → output gives byte-stable, snapshot-testable results.

License

Internal — Automate It / Olympia Fitness & Performance RI.