{
  "markdown": "<p align=\"center\">\n  <img src=\"assets/logo/starlog-avatar-A.png\" alt=\"Starlog\" width=\"120\" height=\"120\">\n</p>\n\n<h1 align=\"center\">Starlog</h1>\n\n<p align=\"center\"><strong>Vet a package before your AI coding agent uses it — authoritative facts (CVEs, license, maintenance), free, local, no account.</strong></p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/starloghq\"><img src=\"https://img.shields.io/npm/v/starloghq?color=cb3837&logo=npm\" alt=\"npm version\"></a>\n  <a href=\"https://github.com/starloghq/index/actions/workflows/ci.yml\"><img src=\"https://github.com/starloghq/index/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n  <a href=\"#license\"><img src=\"https://img.shields.io/badge/license-BUSL--1.1-blue\" alt=\"License: BUSL-1.1\"></a>\n  <img src=\"https://img.shields.io/badge/MCP-server-6E40C9\" alt=\"MCP server\">\n</p>\n\n<p align=\"center\">\n  <img src=\"demo/facts-demo.gif\" alt=\"An AI coding agent vetting a package through the Starlog MCP server — pulling its known incidents, license, and maintenance before using it\" width=\"820\">\n</p>\n\n**Vet a package in one command — nothing to install, no API key, no account:**\n\n```bash\nnpx starloghq facts ua-parser-js\n```\n\nThen wire it into your coding agent (Claude Code, Cursor, Copilot, Codex):\n\n```bash\nnpx starloghq init\n```\n\n> **Source-available** under BUSL-1.1 — free to use, modify, and self-host; **converts to Apache-2.0 in 2030**. [Details ↓](#license)\n\n---\n\n## Why\n\nAI coding agents (Claude Code, Cursor, Copilot) pick libraries from **training recall** — a snapshot of scraped code, frozen at a cutoff date and ranked by how often an option appeared, not by what fits your task or what's safe *now*. That recall can't know about a CVE disclosed last week, and it has never seen your company's internal libraries. The agent recommends anyway, with the same confidence either way.\n\nThe failure modes are measurable: research finds ~49% of AI-suggested dependencies carry known vulnerabilities and ~34% are hallucinated outright — the package doesn't exist. And for whole categories — most dangerously auth — agents default to hand-rolling custom code instead of reaching for a vetted library.\n\nYou can't fix recall by prompting harder. **Starlog puts authoritative, dated facts in front of your agent at decision time.** Its hero surface is **vetting by name** — `starlog facts <package>` returns known CVEs/incidents, SPDX license + risk, and maintenance status (or an honest *\"no facts on file\"*) — so the install/avoid/pick call rides on facts, not recall. It runs entirely on your machine as an MCP server and a package-install hook, no API key, no sign-up. A companion `starlog_search` finds candidate packages for a capability; facts vet the pick.\n\n**Does it actually change what the agent decides?** Yes — measured before/after, on the venue that matters (private libraries and post-cutoff advisories). → [the validated result](#does-it-change-the-agents-decision).\n\n## What you get\n\n- **`starlog_facts` MCP tool** — your agent looks up **authoritative facts about a specific package** before recommending it: known CVEs/supply-chain incidents, SPDX license and license risk, maintenance status (active/deprecated/abandoned/compromised), and effect surface. In a 4-model benchmark, agents called this tool unprompted on package decisions (100% recall, 98% specificity) and it moved them toward the correct install/avoid/pick call. Every record is sourced, verified, and **dated** — each result shows an \"as of `<date>`\" line so a stale \"no known vulns\" is never mistaken for a fresh one. A package with no record returns an honest \"no facts on file.\" Facts are three independent layers, composed at query time: **L1** capability/effect-surface (immutable), **L2** reputation/vuln/license/maintenance (mutable — carries the `as of` recency), **L3** org policy (your suitability verdict). Override or extend any layer locally: point `STARLOG_PRIVATE_FACTS` at a JSON file with independent `l1`/`l2` arrays (internal packages, license rulings) and `STARLOG_POLICY` at an org policy (`{ org, rules }`) for allow/deny/flag verdicts. With `STARLOG_API_KEY` set, org-private overlays and policy come from the hosted facts API (local corpus is the offline fallback); `starlog facts push` uploads your org's overlays + policy. See [docs/FACTS-CONTRACT.md](docs/FACTS-CONTRACT.md).\n- **Package-install hook** — fires the moment your agent runs `npm install` / `pnpm add` / `yarn add` / `pip install` and **surfaces that package's facts** (known incidents, license, maintenance) *before* the agent builds on it. Advisory — it informs the next move, it doesn't block the install. Packages with no record are queued for coverage.\n- **`starlog_search` MCP tool** — discovery: find candidate packages for a capability (org-sanctioned options first), then vet the named pick with `starlog_facts`. Discovery surfaces what exists; facts vet it.\n- **`starlog_advise` MCP tool** — when your agent sees DIY or repeated capability code, advises **MIGRATE** to a safe library (e.g. Clerk/Auth0/Supabase over DIY auth) or **PACKAGEIZE** only when no safe corpus alternative exists. Tracks patterns in `.starlog/patterns.json`.\n- **`starlog facts` / `starlog search` / `starlog advise` / `starlog patterns` CLI** — the same facts, discovery, and migrate-or-packageize advisories from your terminal.\n- **Runs on your machine** — the engine and corpus are local; the default (keyless) path needs no account, no API key, and no network. Setting `STARLOG_API_KEY` opts into the hosted facts/search tiers (with local fallback) — get a key at [starlog.dev](https://starlog.dev) and wire it with `starlog init --api-key <key>`; anonymous, opt-out usage telemetry is the only thing sent otherwise — see [Telemetry](#telemetry).\n\nThis repo ships the engine plus a curated **facts corpus** and a discovery corpus of **26 capability manifests across 7 categories** (including authentication playbooks for migration).\n\n## Quick start\n\n```bash\nnpx starloghq init\n```\n\nThis wires Starlog into Claude Code (and drops instruction files for Cursor, Copilot, Codex):\n\n- **MCP server** added to `~/.claude/settings.json` — exposes `starlog_facts` (vet a package by name), `starlog_search` (discover candidates), and `starlog_advise` (migrate-or-packageize for DIY patterns), and wires your **per-project private overlays** (`${CLAUDE_PROJECT_DIR}/.starlog/*`) into the agent so internal-package facts + discovery work automatically in each project\n- **PostToolUse hook** installed — surfaces a package's facts on install\n- Previews every change and asks before writing; **idempotent** and safe to re-run\n\nPrefer a bare `starlog` command over typing `npx`? Install it globally:\n\n```bash\nnpm install -g starloghq\nstarlog init\n```\n\n> If `starlog` then reports **`command not found`**, your npm global bin directory isn't on your `PATH` (a common npm setup gap — not a Starlog issue). Either run `export PATH=\"$(npm prefix -g)/bin:$PATH\"` (add it to your shell profile to persist), or just keep using `npx starloghq init` / `npx starloghq facts <pkg>`, which always work without any PATH setup. If the install itself printed an `EACCES`/permission error, it didn't complete — fix your npm prefix or use `npx`.\n\nAdd `--project` to also drop Starlog guidance into your project's `CLAUDE.md`; preview without writing, or remove cleanly:\n\n```bash\nstarlog init --project\nstarlog init --dry-run\nstarlog init --uninstall\n```\n\n### Onboard a whole org at once\n\nDon't hand-author facts for every internal repo — point Starlog at a directory of checkouts and it derives them in one pass:\n\n```bash\nstarlog org sync ~/code/my-org\n```\n\nFor each published package it finds (npm `package.json` **and** Python `pyproject.toml`), it derives:\n\n- **L2 facts** → `.starlog/private-facts.json` — license + license risk (from the manifest, or detected from the `LICENSE` file), maintenance from git last-commit recency, stamped `source: analyzer` with a dated `as of`. Your agent **vets these by name**.\n- **Discovery corpus** → `.starlog/private-corpus.json` — captures each manifest's description + keywords so your agent can **find** internal packages by capability via `starlog_search`, not just vet them by name.\n- **Suggested policy** → `.starlog/policy.suggested.json` — flag candidates (e.g. strong-copyleft, no declared license) derived from the signals. These are **proposals the agent does not read** — review them, then adopt the ones you trust with `starlog facts policy <pkg> flag`.\n\nSource never leaves your machine; only derived facts are written. Re-run anytime to refresh (it merges over existing facts and regenerates suggestions). Repos with no published name — or no description — are reported, never fabricated. Known-vulnerability scanning and remote GitHub-org enumeration are on the roadmap.\n\n### From source\n\n```bash\ngit clone https://github.com/starloghq/index.git starlog-index\ncd starlog-index && npm install\nnpx tsx src/cli.ts facts ua-parser-js\n```\n\n### Manual MCP setup\n\n`starlog init` writes this for you automatically. To configure by hand, add to `~/.claude/settings.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"starlog\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"starloghq\", \"mcp\"]\n    }\n  }\n}\n```\n\nThis is the same launch command MCP registries use. (From a local source clone instead, point `node` at `dist/mcp.js` — `$(npm root -g)/starloghq/dist/mcp.js` for a global install, or your clone's path.) The server exposes two tools: `starlog_facts` (an authoritative per-package fact lookup — CVEs, license, maintenance) and `starlog_search` (a natural-language capability query with optional `category`, `stack`, and `top_k` filters).\n\n## CLI usage\n\n**Vet a package by name** — the hero. Local, no key, no network:\n\n```bash\nstarlog facts ua-parser-js\n```\n\n```\n## ua-parser-js (npm)\n**Effect surface:** Parses User-Agent strings; pure data transformation, in-process.\n**Capabilities:** parsing\n**Maintenance:** active\n**License:** MIT (risk: none)\n**Known vulnerabilities / incidents:**\n  - INCIDENT:ua-parser-js-2021 [critical] affected: 0.7.29, 0.8.0, 1.0.0 — Maintainer account hijacked (Oct 2021); these versions shipped a password stealer and cryptominer. Treat installs as account-compromise.\n**Transitive risk:** Frequently a transitive dep — pin away from the three bad versions.\n**Source:** GitHub Security Advisory; CISA alert Oct 2021 (hand)\n**Verified:** as of 2026-06-01\n```\n\nA package with no record returns an honest **\"No facts on file\"** — not a guess. Add `--format json` for machine-readable output with the independent `l1` / `l2` / `l3` layers.\n\n**Discover candidates** for a capability, then vet the named pick with `facts`:\n\n```bash\nstarlog search \"auth for a Next.js app\"\n```\n\n```\n#   Library             Category          Score   Solves\n--------------------------------------------------------------------------------\n1   Auth0 Next.js SDK   authentication    71.36   Implements user authentication in Next.js applications using Auth0 ...\n2   Clerk               authentication    60.64   Provides a fully managed authentication and user management platfor...\n```\n\nSearch **ranks locally** with the keyword ranker — scores are absolute (a strong match lands in the 70s–80s), so a query outside the indexed categories returns *\"no strong match\"* rather than a confident wrong answer. Keyless, the candidate set is the bundled corpus (no network). With `STARLOG_API_KEY` set, candidates come from the **hosted full corpus** (`api.starlog.dev/search`) and are ranked by the same local engine — so a key widens *what* can be found, never *how* it's scored; any hosted hiccup silently falls back to the bundled corpus.\n\n```\n--category <cat>    Filter by category (authentication, feature-flags, etc.)\n--stack <stack>     Filter by stack affinity (e.g., \"next.js\", \"python\")\n--top-k <n>         Number of results (default: 5)\n--format <type>     Output format: table or json\n--context <desc>    Project context to tailor the \"vs custom\" rationale\n```\n\n### Your internal packages — the hero case, in two commands\n\nThe model structurally **can't** know your private `@acme/*` packages exist — so this is where facts change the most decisions (DIY → the org's sanctioned library). You don't hand-write JSON; two commands author the overlays, and `starlog init` already wired the agent to read them **per-project**:\n\n```bash\n# Make it discoverable — search will surface it (private-first) for a capability:\nstarlog corpus add @acme/flags --solves \"Feature flags + remote config for Acme Node services\" \\\n    --category feature-flags --stack node --best-for \"gradual rollout,kill switches\"\n\n# Make it vet clean — facts confirms it's active/maintained:\nstarlog facts add @acme/flags --status active --license MIT\n```\n\nThese write `.starlog/private-corpus.json` (discovery) and `.starlog/private-facts.json` (vetting) in your project. Because `starlog init` bakes `${CLAUDE_PROJECT_DIR}/.starlog/*` into the MCP server's env, your coding agent picks them up **automatically in that project** — no shell `export`, nothing to re-run. Confirm with `starlog doctor` (it reports the wiring and what each project has authored). For richer overlays — full `l1`/`l2` arrays, org `STARLOG_POLICY` allow/deny verdicts, or pushing to the hosted API with `starlog facts push` — see [docs/FACTS-CONTRACT.md](docs/FACTS-CONTRACT.md).\n\n## How it works\n\nStarlog vets a package as **three independent layers, composed at query time** — never collapsed into one blurry \"score\":\n\n| Layer | Answers | Mutability |\n|---|---|---|\n| **L1** capability / effect-surface | what does the code *do*? | immutable |\n| **L2** reputation overlay | what's *known*? — CVEs, license, maintenance | mutable; carries the dated `as of` recency |\n| **L3** org policy | is it *allowed here*? | your rules → allow / deny / flag |\n\n`starlog facts <pkg>` composes the three for the caller and returns them — or an honest miss — over the **MCP server**, the **CLI**, or the **install hook**. The corpus is local and cacheable; override or extend any layer with `STARLOG_PRIVATE_FACTS` (internal packages, license rulings) and `STARLOG_POLICY`. The full contract: [docs/FACTS-CONTRACT.md](docs/FACTS-CONTRACT.md).\n\nDiscovery (`starlog_search`) is a separate surface: it ranks capability manifests against each library's `solves` / `best_for` / `stack_affinity` with a local keyword ranker, reporting an *absolute* score so an out-of-corpus query returns \"no strong match\" instead of a forced result. The candidate set is the bundled corpus, or — with `STARLOG_API_KEY` set — the hosted full corpus, ranked by the same local engine either way. When your agent installs a package with no manifest yet, the hook queues it (`.starlog/pending.json`) for coverage.\n\nFor the full picture — surfaces, engine, data sources, and what telemetry leaves the machine — see **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** (with diagrams).\n\n## Does it change the agent's decision?\n\nThe real test of a facts tool isn't \"does it return data\" — it's \"does the agent decide differently.\" Measured before/after (control = recall only; treatment = same prompt + Starlog facts):\n\n- **Private packages (the hero case):** given an *informational-only* fact that an active internal library exists — no \"you must use it\" — the agent stops hand-rolling and picks the internal library. **2/2, DIY → internal, on information alone.** The model structurally can't recall your private `@acme/*` packages; facts are how it learns they exist.\n- **Post-cutoff supply chain:** for `posthog-node`, facts add *\"pin away from the malicious 4.18.1 / 5.11.3 / 5.13.3\"* — advisory `MAL-2025-190925`, published after the model's training cutoff. It can't know this; the facts can.\n- **No spurious flips:** healthy decoys (`zod`, `fastify`) don't change, and `node-cache` (ambiguous, no ground truth) is deliberately **not** counted as a win — a tool that books every change as a victory is lying to you.\n\nBacked by a powered benchmark across **four model vendors**: correct adopt/avoid decisions moved **~20% → ~78%**, with **100% unprompted adoption**.\n\n**Full before/after, the honest scope, and the experiment we threw out → [docs/VALIDATION.md](docs/VALIDATION.md).**\n\n## Coverage\n\n**Facts corpus — 42 packages.** Curated and dated: known supply-chain incidents (xz, event-stream, ua-parser-js, node-ipc, …), notable deprecations, and clean baselines — each with SPDX license + risk, maintenance status, and an `as of` date. Extend it for your org via `STARLOG_PRIVATE_FACTS` (internal packages) without touching the public set.\n\n**Discovery corpus — 25 capability manifests across 7 categories:**\n\n| Category | Examples |\n|---|---|\n| Authentication | Clerk, Auth0 |\n| Real-time | Socket.IO, Ably, Pusher, Supabase Realtime, ws |\n| ORM/Database | Prisma, Drizzle, Kysely |\n| Background Jobs | BullMQ, Inngest, Bree |\n| Email | Resend, SendGrid, Nodemailer |\n| Feature Flags | LaunchDarkly, PostHog, Flagsmith, ConfigCat, DevCycle |\n| Caching | ioredis, Upstash Redis, Keyv, Cacheable |\n\n> **Note:** facts and manifest data are **point-in-time** — sourced and dated, but a decision aid, not ground truth. Verify anything load-bearing; corrections via PR are welcome.\n\n## Testing\n\n```bash\nnpx vitest run\n```\n\nUnit and e2e tests cover schema validation, corpus loading + integrity, facts/format output, the spawned-CLI round-trip, and search ranking. All run without API keys or external binaries.\n\n## Telemetry\n\nStarlog collects **anonymous, opt-out** usage analytics to understand which\ncommands, tools, and packages are used. It sends: the command/tool run\n(`init`/`facts`/`search`/`doctor` and the `starlog_facts`/`starlog_search` MCP\ntools), the CLI/Node/OS version, detected agents, coarse result counts, the\n**public** package names you look up, and your **search queries / project\ncontext** — with emails, secrets/tokens, absolute file paths, and IP addresses\n**scrubbed before send**.\n\nIt **never** sends your **org-private** package names (those are redacted to a\nboolean when you use a private overlay), your username/hostname, or any file\ncontents. It's also disabled automatically in CI and test runs.\n\nA notice is printed on first run and **re-shown whenever the disclosure changes**\n(so a broadened collection can never happen silently). Through the MCP tools, the\nserver **includes the disclosure in its first tool result** (which your agent\nrelays to you) and only begins recording from the next call — so MCP analytics are\nnever collected before you've been shown what's collected. Opt out at any time:\n\n```bash\nstarlog telemetry disable          # persistent opt-out\nstarlog telemetry status           # see current state + anonymous id\nexport STARLOG_TELEMETRY=0         # env opt-out\nexport DO_NOT_TRACK=1              # honored too\nstarlog <command> --no-telemetry   # one-off\n```\n\n## Links\n\n- Website: [starlog.dev](https://starlog.dev)\n\n## License\n\n**Source-available** under the Business Source License 1.1 — see [LICENSE](LICENSE). Not an OSI open-source license: free to use, modify, and self-host (non-competing use), and it **converts to Apache-2.0 on 2030-06-01**.\n",
  "bytes": 19168,
  "sha": "c1542745cad6ee6044047b13b4fc357a8fa2f2037e5ace0ac2f491611129d889",
  "repo_slug": "starloghq/index",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_starloghq_starlog_d2f3d32a/readme"
}