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

@yakdo/cairn

v0.1.0

Published

Type an address, get a pictogram map. Korean-style 약도, auto-generated. MCP server + CLI.

Readme

cairn

Type an address, get a pictogram map. Korean-style 약도, auto-generated, anywhere in the world.

ci npm license

Part of: Human-Controlled AI Systems — the MCP server stays a tool, never an agent. Curation is a deterministic heuristic; an LLM only enters the loop when the host (Claude Code, Cursor, Codex CLI, …) chooses to compose it.


Why

Most maps are too accurate to be useful. Korean 약도 (yakdo) and Japanese 略地図 are wayfinding diagrams: a handful of landmarks, simple arrows, a station exit number. They're easier to read at a glance than any GPS screenshot — exactly what a business card, wedding invitation, or shop flyer needs.

cairn brings that pictogram-first approach to anywhere with OpenStreetMap coverage.


Currently implemented

  • 4 MCP tools over stdio: generate_map (one-shot address → SVG), geocode (address → coords via Nominatim), find_landmarks (coords → POI list via Overpass), find_roads (coords → simplified road polylines via Overpass).
  • Zero-API-key path. OSM Nominatim + Overpass only. No Mapbox / Google keys, no account, no quota signup.
  • Road skeleton in src/roads.ts — fetches nearby roads, classifies them by importance tier (primary / secondary / tertiary / residential), and simplifies each polyline with Douglas-Peucker (src/geometry.ts). This is what turns the output from a scatter of points into an actual 약도: a few roads you navigate along, with the major ones labeled.
  • Deterministic curation heuristic in src/curate.ts — weights importance (transit > civic > shop), targets a ~150 m sweet-spot distance, enforces category diversity, caps at the requested limit (default 5).
  • Pictogram SVG renderer — curated road bands, compact landmark badges, deduped road-name labels, and destination callouts tuned for print-style 약도 output.
  • CLI with file output, label override, and a --no-roads toggle:
    node dist/cli.js "서울 강남구 테헤란로 152" -o office.svg --label "스튜디오"
    node dist/cli.js "Shibuya Crossing, Tokyo" -o shibuya.svg --no-roads
  • Bounded inputs on public tool/CLI parameters — search radii max out at 5 km and SVG canvas dimensions at 4000 px to keep public OSM services and the single-process renderer healthy.
  • HTTP rate-limiting and timeouts on outbound calls — 1.1s minimum spacing to Nominatim, 1 req/s to Overpass, per their usage policies.
  • Tests: 142 passing (vitest, run on every push).

Planned

  • Publish v0.1.0 to npm as @yakdo/cairn.
  • Pictogram component library + force-directed label layout (Track A — building on the road skeleton just landed).
  • Wedding invitation template variant (Track C — addressable-market expansion).
  • Optional Mapbox / Google geocoder adapters (opt-in only; the default stays zero-key).
  • Figma plugin export.

Design intent

  • Fewer landmarks by design. A good cairn is one stone stacked carefully, not a quarry. Every extra element costs cognitive load, so the default heuristic picks fewer landmarks than you'd expect — and that's the point.
  • Granular and high-level tools, side by side. generate_map is convenient; geocode + find_landmarks + find_roads exist so a host LLM can compose smarter pipelines than any single one-shot ever could.
  • No server-side LLM calls. The MCP server is a tool, not an agent: curation is deterministic, so it's debuggable, testable, and doesn't push token costs onto the user. Any LLM-powered refinement happens in the host process.
  • Domain-neutral by design. Business cards are the primary use case, but the render pipeline doesn't lock to that domain — wedding invitations, real estate listings, and event flyers all reuse the same primitives.
  • Single-file MCP server style (anvil / AirMCP pattern): minimal dependencies, single-responsibility modules, easy to audit end-to-end.

Privacy

cairn sends the address you type to two OpenStreetMap services in order to do its job: Nominatim for geocoding and Overpass for landmark lookup. Both run on the OSM Foundation's public infrastructure and follow the OSMF privacy policy. cairn itself stores nothing, has no telemetry, and reads no environment variables for credentials. If your address is sensitive, run a self-hosted Nominatim / Overpass instance and point cairn at it (custom-endpoint support is on the roadmap).

Non-goals

  • A web frontend. MCP server + CLI only. A hosted UI is scope-creep that the project consciously rejects.
  • Paid geocoders as the default. Mapbox / Google may ship as opt-in adapters; the zero-config npx path will always work without a key.
  • Server-side LLM calls. No model invocation happens inside cairn — not for curation, not for label translation, not anywhere. LLM use is the host's responsibility.
  • A custom domain language. Wedding-invitation, real-estate, etc. variants will share the same render primitives, not fork into bespoke pipelines.

Quick start

Status: v0.1 pre-release. The package is prepared for npm as @yakdo/cairn; until v0.1.0 is published, install from source: clone → npm install && npm run build, then use node dist/cli.js for CLI or wire node /absolute/path/to/dist/server.js into your MCP config.

As an MCP server

{
  "mcpServers": {
    "cairn": {
      "command": "npx",
      "args": ["-y", "-p", "@yakdo/cairn", "cairn-mcp"]
    }
  }
}

Then ask the assistant:

Make a pictogram map for 서울 강남구 테헤란로 152, label it "스튜디오".

As a CLI

npx -p @yakdo/cairn cairn "서울 강남구 테헤란로 152" -o office.svg
npx -p @yakdo/cairn cairn "1600 Amphitheatre Pkwy, Mountain View" --label "Office"

How it works

  1. Geocode the address (Nominatim — no API key).
  2. Find landmarks within a configurable radius (Overpass): transit stations, schools, parks, recognizable shops, distinctive buildings.
  3. Find roads in the same area (Overpass), classify them by importance tier, and simplify each polyline (Douglas-Peucker).
  4. Curate the most useful 4–6 landmarks with the heuristic above.
  5. Render a pictogram SVG: road skeleton underneath, landmark icons and labels on top, destination marked.
  6. Output vector SVG, ready for print or digital embed.

MCP tools

| Tool | What it does | |---|---| | generate_map | One-shot: address → SVG (set roads: false to skip the skeleton) | | geocode | Address → coordinates | | find_landmarks | Coordinates → nearby points of interest | | find_roads | Coordinates → simplified road polylines, classified by tier |

Granular tools let an LLM compose smarter pipelines — for example, "find landmarks and roads, keep the two biggest roads and the three most recognizable landmarks, render with those."

Why "cairn"?

A cairn is a stack of stones hikers use to mark trails through complex terrain — just enough to say "you're on the path." Cousins exist across cultures: Korean 돌탑, Mongolian ovoo, Scottish cairns. All of them solve the same problem: simplify wayfinding by leaving only what matters.

License

MIT © heznpc

Author

Built by @heznpc, author of AirMCP and anvil.