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

@tthorstenson/juris

v0.1.0

Published

Juris MCP stdio server — UCC Article 9 debtor lien search with honest coverage.

Readme

Juris

Owned multi-niche structured-fact API for Trigg Thorstenson.

Working title: Juris
Phase A / first SKU: UCC Article 9 lien search by debtor name
Not this pass: thin alt-lending KYB pack on the same rails; Nursys; Apify/Amazon distribution.

This repository is first-party API + docs + MCP stub. Responses are labeled with honest provenance. Coverage admits holes.

What works today

| Surface | Status | | --- | --- | | POST /v1/ucc/search {debtor_name, states[]} | Yes. 1 credit. | | GET /v1/coverage | Yes. 50 states + DC. Admits holes. | | Stripe credit packs + API key auth | Yes. Test-mode $1 starter pack. | | MCP search_ucc_liens + list_ucc_coverage | Yes (stdio stub over the HTTP API). | | Day-1 adapters KY / RI / WI | Fixture-first, live interface present. | | CO / MI | Catalogued as next (no adapter). | | NY / TX / CA | HARD holes. No filings invented. |

Default search mode is fixture. Live SOS HTML is opt-in (JURIS_SEARCH_MODE=live or auto) and falls back to golden fixtures when parse fails.

Provenance contract

Every coverage row, search envelope, state result, and filing includes:

{
  "source_url": "https://web.sos.ky.gov/ftucc/search.aspx",
  "as_of": "2026-09-01T00:00:00.000Z",
  "method": "fixture",
  "confidence": 0.42
}

method is fixture or live. Empty fixture rows mean no golden-record match, not “this debtor has no liens.” Juris is not a certified Secretary of State search.

Fixture vs live (probed 2026-09-05)

| State | Portal | Probe | Adapter | | --- | --- | --- | --- | | KY | https://web.sos.ky.gov/ftucc/search.aspx | Reachable. ASP.NET WebForms (tOrgname + bSearch). | Live POST implemented; result-table parse is conservative. Default fixture. | | RI | https://business.sos.ri.gov/CorpWeb/UccSearch/UccSearch.aspx | Reachable HTTP 200. CorpWeb needs a radio postback before organization search. | Live GET/POST attempted; table parse not trusted. Default fixture. | | WI | https://wims.dfi.wi.gov/uccsearch | Reachable HTTP 200. Angular SPA — no HTML form to POST. | Live = reachability probe only. Default fixture. | | CO / MI | Official SOS pages catalogued | Not wrapped | next | | NY / TX / CA | Official systems catalogued | Not wrapped | HARD hole |

Re-run: npm run probe.

Golden fixture debtor that returns filings in KY+RI+WI: ACME INDUSTRIES LLC.
KY ONLY CORP hits KY only. Unknown names return kind=empty with fixture provenance.

ToS: GRAY

Automated access to KY FastTrack UCC, RI CorpWeb UCC, and WI WIMS is GRAY.

  • Those sites are public search UIs, not licensed bulk APIs.
  • KY itself says the HTML index is not a certified search.
  • Live mode identifies as Juris/0.1 and does not bypass CAPTCHA, login, or paywalls.
  • Do not turn JURIS_SEARCH_MODE=live on against production SOS hosts without counsel + acceptable-use review.
  • Fixture mode does not hit SOS hosts.

No Nursys scrape. No third-party scraper marketplace.

Production $1 blockers

The local $1 path below is Stripe test mode. Taking a real dollar needs:

  1. Stripe live keys (sk_live_…) and a public HTTPS webhook (STRIPE_WEBHOOK_SECRET).
  2. A public PUBLIC_BASE_URL (Checkout success + webhook).
  3. Legal review of SOS ToS / acceptable use if you leave fixture mode (GRAY).
  4. Honest product copy: fixture data is demo; live HTML is not certified; NY/TX/CA are holes.
  5. WI has no HTML search surface — live WI needs an official API or a disclosed browser session (not in this pass).
  6. Name-matching is exact/normalized organization match on fixtures, not each state’s RA9 search logic.
  7. Some states will require accounts, fees, or certified-request workflows before a real search SKU.

Quick start

npm install
cp .env.example .env
npm test
npm run build
JURIS_DEV_ISSUE_KEY=true npm start

Dev-only key (never enable in production):

curl -s http://127.0.0.1:8787/v1/billing/dev-issue \
  -H 'content-type: application/json' \
  -d '{"credits":5}'

Stripe test-mode $1 path

  1. Put a Stripe test secret key in .env as STRIPE_SECRET_KEY=sk_test_… (no surrounding quotes; whitespace is trimmed at load).
  2. Start the API: npm start (default http://127.0.0.1:8787).
  3. Optional Render check (no Checkout): GET /v1/billing/stripe-ping → {ok:true} or a mapped stripe_error with nested detail.
  4. Create the $1 starter pack (1 search credit):
curl -s http://127.0.0.1:8787/v1/billing/checkout \
  -H 'content-type: application/json' \
  -d '{"pack":"starter"}'
  1. Open checkout_url. Pay with test card 4242 4242 4242 4242, any future expiry, any CVC, any ZIP.
  2. Stripe redirects to /v1/billing/redeem?session_id=cs_test_… or send checkout.session.completed to /v1/webhooks/stripe (stripe listen --forward-to localhost:8787/v1/webhooks/stripe).
  3. The redeem JSON includes api_key once. Store it.
export JURIS_API_KEY='juris_sk_test_…'

curl -s http://127.0.0.1:8787/v1/account \
  -H "authorization: Bearer $JURIS_API_KEY"

curl -s http://127.0.0.1:8787/v1/ucc/search \
  -H "authorization: Bearer $JURIS_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"debtor_name":"ACME INDUSTRIES LLC","states":["KY","RI","WI"]}'

Packs: starter = $1.00 / 1 credit; pack5 = $5.00 / 6 credits.

Local webhook without a public URL: stripe listen --forward-to localhost:8787/v1/webhooks/stripe. Redeem still works if Checkout can reach PUBLIC_BASE_URL.

Coverage

curl -s http://127.0.0.1:8787/v1/coverage

Hole admission is the product. Requesting NY returns kind=hole, filings=[], confidence=0. Credits are still consumed (one search request, not one state).

MCP (stdio)

Official registry name: io.github.tthorstenson/juris
npm package: @tthorstenson/juris (stdio only; hosted /mcp is not registered)

Tools:

  • search_ucc_liens { debtor_name, states? }
  • list_ucc_coverage

Default search mode on the API is fixture. Live SOS HTML is ToS-GRAY and opt-in on the server (JURIS_SEARCH_MODE=live or auto).

Cursor / Claude Desktop

{
  "mcpServers": {
    "juris": {
      "command": "npx",
      "args": ["-y", "@tthorstenson/juris"],
      "env": {
        "JURIS_API_KEY": "juris_sk_…",
        "JURIS_BASE_URL": "https://jurisapi.com"
      }
    }
  }
}

JURIS_API_KEY is required for search_ucc_liens. JURIS_BASE_URL is optional and defaults to https://jurisapi.com.

Local API

export JURIS_BASE_URL=http://127.0.0.1:8787
export JURIS_API_KEY=juris_sk_test_…
npm run mcp

API

| Method | Path | Auth | | --- | --- | --- | | GET | / /docs /openapi.json | public | | GET | /v1/coverage | public | | GET | /v1/billing/packs | public | | POST | /v1/billing/checkout | public | | GET | /v1/billing/stripe-ping | public (Stripe connectivity; no Checkout) | | GET | /v1/billing/redeem?session_id= | public (paid session) | | POST | /v1/webhooks/stripe | Stripe signature when configured | | GET | /v1/account | API key | | POST | /v1/ucc/search | API key + 1 credit |

Credits live in SQLite (DATABASE_PATH, default ./data/juris.db). API keys are stored as SHA-256 hashes.

Layout

src/app.ts                 HTTP API
src/search-service.ts      paid search
src/coverage-catalog.ts    50-state hole map
src/billing.ts             Stripe packs + fulfillment
src/adapters/              KY / RI / WI + live HTTP
src/adapters/fixtures.ts   golden records
src/mcp/                   stdio MCP stub

Later (not this pass)

  • CO / MI adapters
  • Alt-lending KYB pack on the same credit + provenance rails
  • Official data licenses where ToS requires them