Files
docs/standards/mcp/modules/library_registry.json
Vishesh 'ironeagle' Bangotra 322741e00c
All checks were successful
continuous-integration/drone/push Build is passing
Document npm registry endpoints and auth gotchas
Add the exact pip/npm registry endpoints and secret names, the
scope-scoped (not global) registry requirement given Verdaccio's missing
uplink, the host-scoped _auth rule, the per-item Drone shell caveat, and
the Verdaccio storage uid/permissions gotcha behind the confusing
"404 no such package available" error on publish.
2026-10-21 01:31:07 +05:30

8 lines
7.3 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"module": "library_registry",
"content": {
"path": "library_registry",
"docstring": "# Library Registry\n\n## Summary\n\nThe Aetos ecosystem provides internal libraries for the shared concerns of\nevery application. **Use them.** Writing a private copy of any capability below\nis a defect.\n\nEach library also exposes its own documentation as an MCP server. An AI agent\ncan read a library's full API by connecting to its MCP and reading\n`docs://index`, `docs://nav`, and `docs://modules/{module}`.\n\n---\n\n## Catalog\n\n| Library | Import | Purpose | Use instead of | MCP |\n|---|---|---|---|---|\n| DAG Pipe | `dagpipe` | Deterministic state-transformation DAG engine | hand-rolled orchestration/topological ordering | `:8006` |\n| Hexa | `hexa` | Declarative DI / composition-root tooling | manual wiring, hand-written factories | `:8008` |\n| Mongo Ops | `mongo_ops` | Async MongoDB repositories, cache, populate, transactions | raw Motor CRUD and connection lifecycle | `:8007` |\n| Omniread | `omniread` | Format-agnostic fetch + parse (HTML, PDF, CSV, XLSX) | custom scrapers/parsers | `:8003` |\n| OpenAPI First | `openapi_first` | Spec-first FastAPI bootstrap, client, codegen | decorator routers and hand-written clients | `:8004` |\n| Mail Intake | `mail_intake` | Provider-agnostic read-only email ingestion | Gmail OAuth + MIME parsing | `:8002` |\n| Py JWT | `jwtlib` | JWT auth primitives (register/login/introspect) | password hashing + token code | `:8005` |\n| Doc Forge | `docforge` | Docstring compiler → MkDocs + MCP docs | custom doc generators | `:8001` |\n| Doc Weaver | `doc-weaver` | JSDoc compiler → TypeDoc + MCP docs (React/TS) | custom TypeScript doc generators | `:8010` |\n| React Auth | `react-auth` | JWT-backed React auth UI: provider, login page, profile screens, bearer axios client | hand-rolled auth contexts and token handling in React apps | `:8011` |\n| React OpenAPI | `react-openapi` | Spec-driven React admin UI (CRUD, tables, forms, SSE) derived from an OpenAPI document | per-resource hand-written admin screens | `:8012` |\n| Auth Server | *(service)* | Central identity service (register/login/me/logout/introspect) | building auth endpoints yourself | spec: `docs://spec` |\n\n## How to choose\n\n| You need to… | Use |\n|---|---|\n| persist and query documents | Mongo Ops |\n| compose dependencies | Hexa |\n| run a multi-step transformation | DAG Pipe |\n| read/parse an arbitrary input format | Omniread |\n| expose a contract-first HTTP API | OpenAPI First |\n| ingest email | Mail Intake |\n| authenticate users / verify tokens | Py JWT (+ Auth Server) |\n| generate documentation | Doc Forge |\n| generate React/TypeScript documentation | Doc Weaver |\n| authenticate a React front-end | React Auth (+ Auth Server) |\n| build a React admin UI from an OpenAPI spec | React OpenAPI |\n\n## Discovery\n\nA single **standards MCP** exposes `find_library(capability)`, which returns the\nmatching library, its import name, its \"use instead of\" guidance, and its MCP\nendpoint (or, for the auth-server service, a spec pointer). It also serves the\npinned auth-server OpenAPI contract at `docs://spec`. Query it before writing\nany infrastructure.\n\n## Publishing & registry auth\n\nPython packages publish to the private index (`pip.aetoskia.com`, `pypiserver`)\nand npm packages to the private registry (`npm.aetoskia.com`, Verdaccio). Both\nauthenticate against the **same `htpasswd` file** (`/auth/htpasswd`) used by the\nDocker registry and the Traefik basic-auth middleware; registration is disabled,\nso the CI credentials (`PIP_USERNAME` / `PIP_PASSWORD`, `NPM_USERNAME` /\n`NPM_PASSWORD`) are one and the same account — there is no separate npm user.\nVerdaccio requires **bcrypt** htpasswd entries; see\n[90 – Drone Pipelines](90_drone_pipelines.md) for the CI wiring.\n\n### Endpoints\n\n| Registry | URL | Backend | CI secret |\n|---|---|---|---|\n| PyPI | `https://pip.aetoskia.com` | pypiserver (`server-pi:6007`) | `PIP_REPO_URL` |\n| npm | `https://npm.aetoskia.com` | Verdaccio (`server-pi:6008`) | `NPM_REPO_URL` |\n\nBoth are exposed through Traefik on the `websecure` entrypoint as **bare\norigins** — no path, no trailing slash. Set the secret values exactly as above.\n\n### npm: scope the registry, never set it globally\n\nVerdaccio here has **no uplink / proxy**, so it can only serve `@aetoskia/*`\npackages. A global `registry=https://npm.aetoskia.com` in `.npmrc` would route\n*every* dependency — including public transitive deps such as\n`zod-to-json-schema` (pulled in by `@modelcontextprotocol/sdk`) — through\nVerdaccio, which 404s on anything it does not host. Always scope the registry to\nthe account:\n\n```\n@aetoskia:registry=https://npm.aetoskia.com\n//npm.aetoskia.com/:_auth=<base64(user:password)>\n```\n\nPublic deps then resolve from `registry.npmjs.org` and only `@aetoskia/*` hits\nthe private registry. The auth line must be **scoped to the host**\n(`//host/:_auth=`), not a bare `_auth=` — modern npm rejects the bare form with\n`ERR_INVALID_AUTH`. The drone template derives both from the package scope and\n`NPM_REPO_URL` automatically; see\n[90 – Drone Pipelines](90_drone_pipelines.md).\n\n> The Drone pipeline runs each `commands:` list item in a **separate shell**, so\n> shell variables defined in one item do not survive into the next. Keep the\n> variable definitions and the commands that use them in the same `|` block.\n\n### Verdaccio storage permissions\n\nVerdaccio runs as uid **10001** (`verdaccio`) inside `verdaccio/verdaccio`.\nThe `storage` directory is bind-mounted from the server\n(`/mnt/omnissiah-vault/data/verdaccio/storage`); if it is owned by `root:root`\n(mode `755`) the process cannot write to it and every publish fails with a\nconfusing `404 no such package available` (`NotFoundError` from\n`local-storage`). Ensure the directory — and its `plugins` subdirectory — are\nowned by `10001:101`:\n\n```sh\nsudo chown -R 10001:101 /mnt/omnissiah-vault/data/verdaccio/storage\ndocker restart npm-registry\n```\n\n## Notes\n\n- **Hexa** is a full library with its own MCP server on `:8008`: read\n `docs://index`, `docs://nav`, and `docs://modules/{module}` (e.g.\n `docs://modules/hexa.container`) to discover the DI surface — `build(cls, *,\n instances, config)` and the `PortNode` model.\n- **Auth Server** is a **service**, not an importable library: it has no MCP\n bundle by design. Read its client contract from the pinned OpenAPI document\n via `docs://spec` and wire it by declaring a `bearerAuth` security scheme in\n the app's own spec (see **Auth Integration**); `py-jwt` covers the\n low-level token path.\n- **Doc Weaver** is the TypeScript counterpart to **Doc Forge**: it reads\n JSDoc comments and emits a TypeDoc site plus the same doc-forge-shaped MCP\n bundle for React packages. Its convention is **RDFC** (the React Doc-forge\n Convention), the JSDoc parallel to GSDFC.\n- **React Auth** and **React OpenAPI** are front-end libraries (TypeScript,\n React 18 + MUI + React Router peers), not Python services — they consume the\n **Auth Server** and an OpenAPI document rather than serving one. Each ships\n a wiki, a TypeDoc site and an MCP bundle like every other library above.\n- Library MCP servers expose **documentation resources** (not executable tools):\n they tell an agent the available API surface so it does not invent code.\n",
"objects": {}
}
}