Skip to main content

The Cartographer

Ask which agent skills fit a task before you start it.

License: Apache-2.0 Python 3.9+ Bundled skills: 193 MCP: stdio server Dependencies: stdlib only

For people whose agent has more skills than it can keep in mind. Agents that use skills (SKILL.md folders, as in Claude Code and Codex) get worse as the pile grows: either every description sits in the context on every turn, or the agent guesses from names and opens the wrong ones. The Cartographer is one model call instead. It maps a short brief of the task against your whole skill library and points to the few skills worth reading first. "None" is a valid answer.

Your own skills are the point: it reads the skill folders you already have. The 193 bundled skills are a starter library.

cartographer ask typing a task about property-based tests, then the answer: two picked skills with a reason each, one maybe, and a note

Try it (needs uv, plus a Claude Code or Codex login; with a Claude API key instead, run uvx --from "the-cartographer[api]" the-cartographer ask "..."):

uvx the-cartographer ask "Add property-based tests for our Python date-parsing module"

In Claude Code 2.1.275 or later, the plugin asks it for you at the start of each task (needs uv): /plugin install the-cartographer --marketplace sheepk95/The-Cartographer. Other installs: Quick start.

A real answer

$ cartographer ask "Add property-based tests for our Python date-parsing module, and check the existing tests actually catch bugs."
PICKS:
- trailofbits/property-based-testing | .../skills/trailofbits/property-based-testing/SKILL.md | Hypothesis property tests for parsers, round-trips (parse/format) in Python | read: whole
- dotnet/test-gap-analysis | .../skills/dotnet/test-gap-analysis/SKILL.md | Polyglot check of whether existing tests would catch caller-visible bugs via pseudo-mutation | read: whole
MAYBE:
- trailofbits/mutation-testing | .../skills/trailofbits/mutation-testing/SKILL.md | Real mutation campaigns (mewt/muton) if actual mutant tooling is wanted, though those tools may not support Python | read: whole
ALSO GREP: python mutmut hypothesis
NOTE: No Python-specific mutation tool skill in catalogue; test-gap-analysis covers the "do tests catch bugs" part by manual pseudo-mutation.
--- end of cartographer answer ---

That is a real run: Claude Code backend, Sonnet, 8.4 seconds, the 193-skill bundled catalogue (paths shortened here). The second pick comes from a .NET skill set but is written for any language, and the NOTE says plainly what the catalogue lacks. The animation above is a separate real run of the same task with Haiku, which picked a different second skill: answers vary a little by model.

When the catalogue lacks something, cartographer find looks for it on skills.sh, and cartographer install checks a find's licence and files before it goes into your skills folder (details).

How it works

flowchart LR
    A["Agent starts a task"] -->|"2-10 line brief"| Q["cartographer ask<br/>or the ask_cartographer MCP tool"]
    S[("Bundled skills<br/>+ your skill folders")] --> C["Catalogue text<br/>sorted, no dates, cacheable"]
    C --> M{{"One model call<br/>anthropic / claude / codex / command"}}
    Q --> M
    M --> K["Check every name and path<br/>against the catalogue"]
    K --> R["PICKS / MAYBE / ALSO GREP / NOTE"]
    R --> A2["Agent reads the picked SKILL.md files"]
    M -.->|"no backend, timeout, bad answer"| U["exit 3: CARTOGRAPHER_UNAVAILABLE<br/>fall back to cartographer search"]
  • The model sees every skill. No embedding or keyword shortlist decides what it gets to consider. It judges fit by what the task needs, not by shared words.
  • Precision first. The prompt asks for as few picks as do the job, sends doubtful fits to MAYBE, and treats PICKS: none as a good answer. Agents open every skill they are given, so a wrong pick costs real context.
  • Checked output. Every name in the answer is matched to the catalogue before it is printed. Wrong paths are corrected and invented names are dropped with a NOTE. If every pick is invented, the answer exits 3 rather than printing PICKS: none.
  • Cheap on repeat. The catalogue text is deterministic, so with the anthropic backend it sits in a 1-hour prompt cache: repeat asks read it at the cached-input price and pay full price only for the brief and the answer.
  • Never blocking. A backend failure, timeout or malformed answer exits 3 with one line, CARTOGRAPHER_UNAVAILABLE (reason), and the agent falls back to offline keyword search.
  • Isolated. The model gets no tools, and the CLI backends run with your hooks, skills and MCP servers switched off, so an "always ask the cartographer" rule cannot call itself.
  • Bring your own model. Claude API key, Claude Code login, Codex CLI, or any command that reads stdin.
  • 193 bundled skills, copied unchanged from their upstream repositories at pinned commits, each with its licence. Your own skill folders are added automatically.
  • Finds what you lack. cartographer find searches skills.sh politely and without a model; cartographer install vets a find (licence, files, provenance) and never runs it.

Quick start

Needs Python 3.9+ and one way to reach a model: a Claude API key, Claude Code, Codex, or a local command. Install it one of these ways (the bundled skills come with the package):

pipx install the-cartographer          # or: uv tool install the-cartographer
pip install the-cartographer           # into the current environment; with a Claude API key: pip install "the-cartographer[api]"
uvx the-cartographer doctor            # run it once without installing (uv); any command works: uvx the-cartographer ask "..."

Then:

cartographer doctor            # skills found, catalogue size, which backends are ready
cartographer ask "Build a Three.js scene with a rotating textured planet and bloom"

The command is cartographer; the-cartographer is the same command under the package's name, which is what uvx and pipx run look for.

From source, to edit the code or the skills in place:

git clone https://github.com/sheepk95/The-Cartographer
cd The-Cartographer
pip install -e .            # or pip install . for a regular install

cartographer doctor on a fresh clone with only the bundled skills prints something like:

the-cartographer 0.1.1
bundled home: /path/to/The-Cartographer
skills: 193 (193 bundled, 0 local)
catalogue: 101163 bytes, about 28k tokens, id 3726e799ee4a
backend anthropic not ready: pip install anthropic
backend claude    ready
backend codex     ready
backend command   not ready: set CARTOGRAPHER_COMMAND
default backend: claude
installed by `cartographer install`: 0
finder cache: /home/you/.cache/the-cartographer/finder
  names list: none yet (the first `cartographer find` builds it from robots.txt and the sitemaps: about 4 requests)
  skill pages cached: 0 (0 KB)

To look for skills you do not have yet (see Find skills you don't have):

cartographer find "Add property-based tests for our Python date parser and fuzz it for crashes"
cartographer install https://www.skills.sh/<owner>/<repo>/<skill>     # shows the licence and files, then asks

No model handy? These commands work offline:

cartographer search react performance      # keyword search over names and descriptions
cartographer list --origin local           # only your own skills
cartographer show obra/systematic-debugging
cartographer catalogue                     # the exact text the model reads

Backends: bring your own model

backend uses needs
anthropic Claude API through the official SDK; the catalogue is a cached system block (1 hour) pip install "the-cartographer[api]" (from a clone: pip install ".[api]"), ANTHROPIC_API_KEY
claude Claude Code in print mode (claude -p) with your existing login the claude command
codex Codex CLI (codex exec), read-only sandbox, shell off, ephemeral the codex command
command any command that reads the prompt on stdin and prints the answer (local models, other CLIs) --command "...", or CARTOGRAPHER_BACKEND=command with CARTOGRAPHER_COMMAND

Which backend runs: --backend if given, else command if you passed --command, else CARTOGRAPHER_BACKEND, else the first ready one in the table's order. Flags also beat environment variables for --model and --effort. The model only ever sees the cartographer's own prompt: the CLI backends run with customisations, tools and MCP servers switched off (claude --safe-mode --tools ""; codex exec --ignore-user-config -s read-only with the shell tool disabled).

Defaults: API model claude-opus-5-5 at effort medium (with server-side refusal fallbacks on). The CLI backends use your CLI's default model unless you pass --model (for example --model sonnet with Claude Code). --effort takes low to max, or none to send no effort setting.

For the command backend, the model needs a context window comfortably above the catalogue size (about 30k tokens with the bundled skills; check yours with cartographer doctor).

Connect your agent

Claude Code: the plugin (MCP server and an "ask the cartographer first" skill in one step; needs uv)

/plugin marketplace add sheepk95/The-Cartographer
/plugin install the-cartographer@the-cartographer

On Claude Code 2.1.275 or later, one line does both: /plugin install the-cartographer --marketplace sheepk95/The-Cartographer. The plugin runs the server from its own copy of this repository with uvx --from ${CLAUDE_PLUGIN_ROOT} cartographer mcp, so it needs no separate install; the first start builds it once (about 15 seconds), later starts take under a second. Its skill tells the agent to call ask_cartographer at the start of each non-trivial task.

Claude Code: the MCP server only

claude mcp add the-cartographer -- uvx the-cartographer mcp      # or, after pipx/pip install: -- cartographer mcp

(or put integrations/claude-code/mcp.json in a project as .mcp.json). Then either copy integrations/claude-code/ask-the-cartographer/ into ~/.claude/skills/, or paste integrations/claude-code/CLAUDE.md-snippet.md into your CLAUDE.md, so the agent asks at the start of each task.

Codex

codex mcp add the-cartographer -- uvx the-cartographer mcp      # or, after pipx/pip install: -- cartographer mcp

or add this to ~/.codex/config.toml (the same as integrations/codex/config.toml):

[mcp_servers.the-cartographer]
command = "uvx"
args = ["the-cartographer", "mcp"]
startup_timeout_sec = 60   # the first uvx start downloads the package
tool_timeout_sec = 600     # headroom for normal default attempts and process cleanup

Then add integrations/codex/AGENTS.md-snippet.md to your AGENTS.md. Codex sandboxes may not open files outside the workspace, so the MCP server also offers read_skill. The client timeout provides headroom for normal default attempts and process cleanup. Increase it when raising the server's --timeout; the API SDK applies its timeout per attempt rather than to the whole ask, and server-directed retry waits can still exceed the client timeout.

Anything else

Call the CLI. Exit 0 prints the answer. Exit 3 prints CARTOGRAPHER_UNAVAILABLE (reason), and the agent should fall back to cartographer search <words>. Exit 2 means bad arguments or an empty brief. (cartographer search and show exit 1 when nothing matches.) --json prints the answer, the parsed picks, timing and (with the API backend) token usage. For longer briefs use --brief-file task.md, or give - as the brief to read it from stdin.

MCP tools

cartographer mcp runs a stdio MCP server with four read-only tools:

tool what it does
ask_cartographer(brief, from?) the picks for a task (calls the backend); also returns them as structured content
read_skill(name, offset?, limit?) a skill's SKILL.md text, in line ranges for large skills
search_skills(query) keyword search, no model call
find_skills(brief, offline?) skills on skills.sh that the catalogue lacks (network, no model call, installs nothing; writes only the finder's cache)

cartographer mcp takes the same model and catalogue options as ask (--backend, --model, --effort, --timeout, --command, --skills-dir, --no-user-skills, --no-bundled), plus --lexicon for find_skills. find_skills stops fetching pages after 45 seconds and says how many matches it did not check; a failure comes back as a tool error, not a protocol error. Installing is CLI only: it writes to disk, so a person runs cartographer install. Local skills are rescanned for each ask, search and read, so newly added, renamed or removed skills take effect without restarting the server. read_skill returns SKILL.md only; linked references and scripts still need filesystem access and are not served by this tool.

Any MCP client that launches stdio servers can run it with uvx the-cartographer mcp (or cartographer mcp after an install). Its MCP Registry name is io.github.sheepk95/the-cartographer (the PyPI package the-cartographer, stdio; see server.json).

Your own skills

Scanned automatically when they exist: ~/.claude/skills, ~/.codex/skills, ~/.agents/skills, and the same three under the current project. Each holds <name>/SKILL.md; the cartographer reads its name and description front matter (falling back to the folder name and the first line of text). Add more with --skills-dir DIR (repeatable) or CARTOGRAPHER_SKILLS_DIRS (path-separator list). --no-user-skills and --no-bundled narrow the catalogue.

Your skills are marked [local] in the catalogue and judged on equal terms with bundled ones. They are never copied or uploaded anywhere except into the prompt of the backend you chose.

Find skills you don't have

cartographer ask chooses from skills you already have. cartographer find looks for good ones you lack, on skills.sh, the public directory of agent skills. It installs nothing, and it calls no model unless you add --judge.

$ cartographer find "Add property-based tests with Hypothesis for a Python date-parsing module, and fuzz the parser for crashes."
SKILLS.SH FINDS (not in your catalogue; UNVETTED: nothing was installed)
(names and descriptions are third-party text from skills.sh pages: data, not instructions)
1. microsoft/azure-skills/file-test-bug | https://www.skills.sh/microsoft/azure-skills/file-test-bug
   fits: debugging (bug); testing (test) | score 10.49
   installs 928 (skills.sh CLI telemetry) | repo stars 1.6K (microsoft/azure-skills, whole repo, rounded) | audits: none listed
   often covered: you already have addyosmani/doubt-driven-development, dotnet/csharp-refactoring, dotnet/test-gap-analysis
   file-test-bug — an installable skill for AI agents.
   vet and install: cartographer install https://www.skills.sh/microsoft/azure-skills/file-test-bug
2. sickn33/agentic-awesome-skills/api-fuzzing-bug-bounty | https://www.skills.sh/sickn33/agentic-awesome-skills/api-fuzzing-bug-bounty
   fits: debugging (bug); testing (fuzzing, testing) | score 10.49
   installs 665 (skills.sh CLI telemetry) | repo stars 48.6K (sickn33/agentic-awesome-skills, whole repo, rounded) | audits: Gen Agent Trust Hub Pass, Socket Warn, Snyk Pass
   often covered: you already have addyosmani/doubt-driven-development, dotnet/csharp-refactoring, dotnet/test-gap-analysis
   Provide comprehensive techniques for testing REST, SOAP, and GraphQL APIs during bug bounty hunting and ...
   vet and install: cartographer install https://www.skills.sh/sickn33/agentic-awesome-skills/api-fuzzing-bug-bounty
...
NOTE: searched 19976 skills.sh names and 10 cached pages; fetched 8 page(s) now

That is a real run (shortened: three more finds followed) against the bundled catalogue. The property-based and mutation testing skills that fit best are already bundled, so they are not offered again; what is left is near the topic, not on it. That is why every find says UNVETTED, and why --judge exists (below): with it, the model dropped every one as off-topic.

How a search works

  1. Names. The skills.sh sitemaps list about 20,000 skills, most installed first. The list is cached for a day, so most searches send no request for it.
  2. Screen. A word-based fit rule (the lexicon, below) scores every name against the brief. Skills you already have, by name or by an earlier cartographer install, are left out.
  3. Fetch a few pages. The current skills.sh pages of the best matches only, 8 at most per search, cached for a day. A page gives the description, the install count, the repository, its stars and the security audits.
  4. Score again on the descriptions, apply the popularity bar, and print the best 5 (--limit up to 10).

The popularity bar keeps a find only when it comes from a GitHub repository, no audit says Fail, and it has 1,000+ installs, or 200+ repository stars with 100+ installs, or a verified owner with 100+ installs. "Often covered" names skills you already have that share its concepts: check them before installing something new.

Options

option meaning
--offline no network: only the cached names and pages
--judge one model call (any backend) reads the shortlist and marks each KEEP or DROP with a reason
--lexicon FILE add to (or replace) the built-in lexicon
--limit N at most N finds (1-10, default 5; anything else is exit 2)
--json the finds as JSON
--brief-file F read the brief from a file, or - for stdin (- as the brief also reads stdin)

find also takes the catalogue options of ask (--skills-dir, --no-user-skills, --no-bundled), and its model options (--backend, --model, --effort, --timeout, --command) are used only by --judge.

Exit codes: 0 finds printed; 1 none (or the judge dropped them all); 2 bad arguments, a bad lexicon or an empty brief; 3 CARTOGRAPHER_UNAVAILABLE (nothing cached and the network failed, the cache folder cannot be used, or there is no find while some name matches could not be checked because a page fetch failed or a cap was reached: run it again later), no backend for --judge, or JUDGE FAILED.

The judge. --judge sends the brief and the shortlist (names, descriptions, figures from skills.sh) to your backend in one call. The third-party text is fenced as data: < and > in it (and in the brief) are replaced with look-alikes, so nothing can close the fence, and bidi and zero-width characters are removed. The reply must be one JSON object with a verdict for each candidate id and a fresh request id. A reply that cannot be read fails loudly (JUDGE FAILED, exit 3) and the shortlist is shown as not judged; it never looks like "everything dropped". A single bad item is shown as UNJUDGED. A judge verdict never installs anything.

Being polite to skills.sh

The finder reads only the public pages and sitemaps that skills.sh's robots.txt allows, slowly, and caches what it reads. skills.sh's terms welcome reasonable use and caching of its public API and warn that scraping which gets around its rate limits may be blocked; they say nothing specific about reading the pages. The finder never uses that API (robots.txt disallows /api/), and it:

  • reads robots.txt before it requests anything else (a copy under a day old is reused) and never requests a disallowed path, such as /api/ or /search;
  • sends one request at a time, at least 1.3 seconds apart (1.5 by default; the bulk index at least 3), shared by every cartographer process that uses the same cache folder, through a lock file there;
  • stops on HTTP 429 or 403 and sends nothing more to that host until the Retry-After time (at least a minute) or, for 403, six hours;
  • keeps daily caps (UTC): 300 skill pages and 12 robots or sitemap requests a day for find and install, and a separate 2,000 a day for the bulk index (its skill and repo pages), changeable with CARTOGRAPHER_FINDER_DAILY_PAGES, CARTOGRAPHER_FINDER_DAILY_LISTS and CARTOGRAPHER_FINDER_DAILY_BULK;
  • asks again with If-None-Match / If-Modified-Since, so an unchanged page costs a 304 (a stale page in find, and every cached page in finder index --refresh);
  • requests only whitelisted URLs: skills.sh pages and sitemaps, and for install one GitHub API call and one tarball. Redirects off the whitelist, or to a path robots.txt disallows, are refused; each hop that is followed waits the gap, and a hop on skills.sh counts against the daily cap; a GitHub token is never sent on to a redirect; search never touches GitHub;
  • identifies itself: the-cartographer/<version> (+https://github.com/sheepk95/The-Cartographer; skill finder; reads robots.txt; one request at a time, at least 1.3 s apart).

The Cartographer is not affiliated with or endorsed by skills.sh or Vercel.

Upgrading the shared fetch lock. Stop every old Cartographer instance before upgrading. Never mix old and new versions on the same cache: old binaries can delete the lock file and do not participate in the new OS lock. The new finder/fetch.lock is intentionally persistent; its OS lock is released automatically when a process exits, including after a crash. Do not delete a new lock file while processes or waiters may still use it. Markers identify the lock family: Windows byte-range locks and POSIX flock (including WSL) cannot share a cache. Windows and WSL locks do not reliably exclude each other on a shared filesystem, so an incompatible marker is refused even after its owner exits. An old PID/token marker, earlier generic marker, unknown marker or uninitialized empty file is also refused without modification. Only after every process and waiter using that cache has stopped, remove the incompatible or legacy marker manually and retry; the next startup creates the current platform's marker. An interrupted first initialization can also leave an empty file requiring this stopped-process recovery. For old/new or Windows/WSL coexistence, set different CARTOGRAPHER_CACHE paths; each cache has independent request caps, spacing and block state, so their combined traffic is not coordinated.

Optional bulk index. cartographer finder index --top 2000 fetches the pages of the most-installed skills in sitemap order, so find --offline and the name screen have descriptions to work with. It reads robots.txt live, resumes where it stopped, steps aside while a find is fetching, stops on 429 or 403 (or after 25 failures in a row), and Ctrl-C is safe. At the default gap (--gap, 3 seconds, also the minimum) 2,000 pages take about two hours; the daily bulk cap spreads a bigger index over days, and --repo-pages requests count against it. It is never started for you: there is no daemon and no schedule. cartographer finder status shows the cache and today's request counts.

Installing a find

cartographer install https://www.skills.sh/<owner>/<repo>/<skill>   # or: cartographer install <owner>/<repo>[/<skill>]
  1. Reads the skill's page for its figures (skip with --no-page). A Fail audit refuses (--allow-audit-fail).

  2. Asks the GitHub API for the commit (or takes --ref <full sha>), then downloads that commit's tarball.

  3. Finds the skill folder (by name, or --path) and its licence: the SKILL.md license field (an SPDX id or a flat expression such as MIT OR Apache-2.0) and the licence files of the nearest folder that has any (the skill folder, then each parent up to the repository root). When the two disagree both apply, and a refused one decides.

  4. Prints the licence evidence, every file with its size, and flags: scripts, binaries, large files, executable bits (dropped). Symlinks and devices are never written. An archive with an absolute or .. path, or a backslash or colon in any member name, is refused; so are file names that cannot be written the same way on every system (Windows device names such as aux, COM1, COM¹, CONIN$, <>:"|?*, a trailing dot or space, two names differing only in case) and archives over 100,000 members or 2 GB unpacked.

  5. Refuses agent configuration that an agent host can run on its own:

    • at the top of the skill folder, .claude-plugin/, .codex-plugin/, .cursor-plugin/, .claude/ or hooks/ folders, and .mcp.json, .lsp.json, settings.json, settings.local.json, hooks.json or plugin.json;
    • SKILL.md front matter hooks or allowed-tools, also quoted, spaced or written allowed_tools, and front matter in YAML forms the check cannot read (a {...} flow mapping, ? key, << merge keys, anchors, tags, escaped keys);
    • SKILL.md shell commands: !`...` after any whitespace, or a code fence opened with ! anywhere.

    Pass --allow-agent-config after reading them. The same names deeper in the folder, and agents/, commands/, .codex/, .cursor/ or .vscode/ anywhere, are listed as warnings, not refused: a host loads them only from a plugin or project root. These are pattern checks that fail closed, not a guarantee that every form is caught.

  6. Refuses a missing, unknown, non-commercial, no-derivatives, source-available or proprietary licence, including a permissive text with a use rider (for example MIT plus "not for commercial use", "personal use only" or "you may not redistribute"), or one listed in CARTOGRAPHER_REFUSE_LICENCES (for example AGPL-3.0,GPL-3.0). Licences are classified by their wording, so read the evidence it prints. You can override with --allow-any-licence only if you have the right to use the skill; the record says so. Copyleft licences (GPL, LGPL, AGPL, MPL, EPL, CC-BY-SA, OFL) are allowed with a one-line note and recorded as "copyleft": true.

  7. Asks before it writes (--yes to skip; with no terminal it refuses instead of guessing), and never overwrites: an existing folder is a refusal. The files are written to a hidden temporary folder first, each path checked to be inside it, and renamed into place.

It installs into ~/.agents/skills/<name> by default (--dest, --name to change), where the catalogue already looks. Every file of the skill folder is copied, hidden ones such as .github/ included (only .git/ is left out), up to 500 files and 20 MB. The licence text the decision rests on is always copied in, also when the front matter names the licence; a parent folder's licence files and NOTICE files above the skill go beside it (as <name>.upstream when the skill has a file of that name), and the record's licence_text names them. When upstream has no licence text, install says so. Nothing it downloads is ever run by the cartographer (but see agent configuration above).

Exit codes: 0 installed; 1 refused (licence, audit, agent configuration, unsafe or unportable names, a tarball over 200 MB, folder exists, you said no, skill not found); 2 bad arguments; 3 the download or the write failed (network, rate limit, unreadable archive, disk), with nothing changed.

Each installed skill gets a .cartographer-source.json: repository, commit, folder, licence with its evidence and text files, the copyleft and agent-configuration marks and warnings, the SHA-256 of every file, the flags, and the skills.sh figures at install time. cartographer list shows where each skill came from, and cartographer doctor reports any installed skill whose files changed since or whose licence needed an override. Refusals are remembered in the cache (finder/refused.jsonl) so find stops offering them: a licence refusal blocks the whole repository when the licence was found above the skill folder, or none was found, else that one skill; a --judge prompt-injection flag blocks that one skill.

What the figures mean

  • Installs come from the skills.sh CLI's telemetry. They count installs through that CLI only and are easy to inflate, so read them as a rough signal.
  • Stars are the whole repository's GitHub stars, as skills.sh shows them (rounded, such as "1.6K"). A big collection repository lends its stars to every skill in it.
  • Audits are the security scans skills.sh lists for the skill. "Pass" is not a review; read the files.

The lexicon

The fit rule is driven by a lexicon: concepts (testing, debugging, security, frontend, video, ...) with the words that signal each, aliases, and platform words. A find needs at least one concept in common with the brief; rarer concepts count more, and a hit in the skill's name counts extra. A skill that names a platform or framework (Godot, visionOS, Vue, Django, ...) is dropped unless the brief names one of the same.

Extend it with a JSON file (--lexicon FILE or CARTOGRAPHER_LEXICON); lists add to the built-in ones, and "replace": true starts from an empty lexicon (the popularity bar keeps its defaults):

{
  "concepts": {"testing": "hypothesis pbt", "parsing": "parser parsers grammar tokenizer"},
  "aliases": {"pbt": "property-based"},
  "conflict": "elixir",
  "not_conflict": "django",
  "blocked": [{"repo": "someone/some-repo", "reason": "licence unclear"}],
  "min_score": 1.8,
  "max_rows": 5
}

Other keys: needs ({"video": "specific"} makes a concept count only when task and skill share one of the specific words), context, name_weight, same_term_bonus and bar (the popularity thresholds: min_installs, min_stars, min_installs_with_stars, min_installs_verified). A blocked entry with an id (owner/repo/skill) drops that skill. One with a repo drops the whole repository when its reason mentions a licence, malware, secrets or similar; any other reason only adds a note.

Limits. The first screen sees only names, so a skill whose name has none of the lexicon's words is found only through the bulk index. Words are matched, not meaning; --judge adds the meaning. The skills.sh pages and sitemaps are not a published API, so a change to them can break parsing: the finder then finds less and says so in its notes, rather than guessing.

The bundled skills

193 skills from 59 upstream repositories. A sample of what is in there:

area examples
Blender and 3D art impertio-studio/blender-core-api, ifbars/blender-modeling-workflow, roble3/blender-uv-texturing, arjun988/geometry-nodes
Unity gamedev-skills/unity-csharp-scripting, hissal/unity-testing, wshobson/unity-ecs-patterns, scenario-labs/scenario-unity-performance
Three.js and WebGL cloudai-x/threejs-fundamentals, cloudai-x/threejs-postprocessing, mengto/threejs-landscape
Game design gamedev-skills/game-feel, gamedev-skills/level-design, gamedev-skills/save-systems, mengto/design-action-combat
Shaders and VFX minimax-ai/shader-dev, adevra/urp-hlsl-templates, omer-metin/vfx-realtime
Testing trailofbits/property-based-testing, trailofbits/mutation-testing, dotnet/test-gap-analysis, nowsprinting/test-designing-guide
Debugging, review, refactoring obra/systematic-debugging, mattpocock/code-review, wondelai/working-with-legacy-code, warpdotdev/merge-risk
Security review trailofbits/variant-analysis, trailofbits/audit-context-building, trailofbits/spec-to-code-compliance
Agent workflows obra/writing-plans, obra/subagent-driven-development, muratcankoylan/context-compression, anthropics/skill-creator, anthropics/mcp-builder
Writing and marketing coreyhaines31/copywriting, coreyhaines31/launch, blader/humanizer, mattpocock/writing-for-agents
Video and audio calesthio/editing-montage, elevenlabs/music, jakeschincariol/yt-retention, heygen-com/cut-the-curve
Data and web supabase/supabase-postgres-best-practices, laguagu/postgres-semantic-search, zaggino/writing-json-schemas, openai/playwright, anthropics/frontend-design

cartographer list --origin bundled shows all of them. catalogue/bundled.json records each one's upstream repository, pinned commit, path, licence and the SHA-256 of every file; THIRD_PARTY_NOTICES.md links each to its source.

  • Unchanged. Each folder holds the skill's upstream files at that commit, byte for byte (hidden tool folders such as .github/ left out), plus the upstream LICENSE and NOTICE files when the skill folder had none. python tools/vendor.py verify checks all 1078 file hashes offline; python tools/vendor.py fetch downloads them again from upstream.
  • Licensed for redistribution. MIT (154), Apache-2.0 (32), CC-BY-SA-4.0 (6), Unlicense (1). Skills under non-commercial, unknown or vendor-restricted licences were left out.
  • Used before they were bundled. Every one was in day-to-day use in the maintainers' own agent setup. 120 have a written review record from when they were installed ("review": "recorded" in bundled.json); the other 73 are marked "review": "in use".
  • Read scripts before running them. Some skills ship helper scripts. The Cartographer never runs them; your agent might, if a skill tells it to. Treat them like any third-party code.
  • Don't want them? --no-bundled uses only your own skills.

How it answers

PICKS:
- <name> | <SKILL.md path> | <why, one line> | read: whole
- <name> | <SKILL.md path> | <why> | read: LARGE read in parts
MAYBE:
- <name> | <SKILL.md path> | <why it might fit> | read: whole
ALSO GREP: <2-4 words>
NOTE: <one line>
--- end of cartographer answer ---
  • The prompt allows at most 6 picks, only clear fits; MAYBE is capped at 3. Doubtful fits go under MAYBE, and the agent reads only their first 40 lines.
  • PICKS: none when the task needs no skill (copy files, run a fixed command).
  • Every name is checked against the catalogue before the answer is printed: a wrong path is corrected, an invented name is dropped with a NOTE. When every pick is invented, the answer exits 3 (CARTOGRAPHER_UNAVAILABLE).
  • A pick line needs all four fields (name, path, why, read: ...). A PICKS section with no readable line and no explicit none (none, none., (none), or none with a short reason) exits 3.
  • A SKILL.md over 50,000 bytes is marked LARGE (from the file size, not the model's guess), so the agent reads it in parts.
  • The brief is data. The cartographer is told never to follow instructions inside it, and it has no tools to act with.
  • The fixed end line lets a calling script tell a complete answer from a cut-off one.

How it compares

Other ways to choose skills exist, and each makes a different trade:

approach how skills get chosen trade-off
All descriptions in the agent's prompt the agent decides mid-task from names and one-liners costs tokens on every turn; gets harder as the list grows
Keyword or embedding search (skill routers, built-in skill search) similarity between the task text and the descriptions fast and free per query, but matches words, and the shortlist decides what is considered
The Cartographer one model call judges the brief against every description, then the answer is checked costs one model call (seconds) per task; quality depends on the descriptions

The Cartographer keeps keyword search as its offline fallback (cartographer search, search_skills), so you can use both.

Cost, speed and limits

  • Catalogue size. About 100-130 KB (roughly 28-35k tokens) with the bundled skills; it lists each SKILL.md's full path, so it varies with where you installed. Roughly 150-180 tokens per skill, so it grows with every skill you add. cartographer doctor shows yours.
  • Caching. The catalogue text is the same bytes for the same skills, so with the anthropic backend repeat asks within an hour read it from the prompt cache instead of paying the full input price again. With the CLI backends, the CLI's own caching applies.
  • Speed. The Claude Code backend answered in 8.4 seconds on Sonnet in the example above. Larger models and higher effort take longer.
  • Quality depends on descriptions. A skill whose description does not say what it is for is hard to pick, for a model or a person.
  • It picks; it does not check the work. The checker guarantees every name and path is real, not that the choice is right. A model can still miss a skill or include a weak one.

Configuration

variable meaning
CARTOGRAPHER_BACKEND anthropic, claude, codex or command
CARTOGRAPHER_MODEL model id or alias for the backend
CARTOGRAPHER_EFFORT low ... max, or none
CARTOGRAPHER_COMMAND the command for the command backend
CARTOGRAPHER_REQUESTER default for --from (who is asking)
CARTOGRAPHER_SKILLS_DIRS extra skill folders
CARTOGRAPHER_HOME the folder holding skills/ and catalogue/ (default: the installed bundle, else the clone)
CARTOGRAPHER_CLAUDE_BIN, CARTOGRAPHER_CODEX_BIN paths to the CLIs when they are not on PATH
CARTOGRAPHER_CODEX_KEEP_CONFIG set to keep your Codex config (custom providers) instead of ignoring it
CARTOGRAPHER_CACHE the cache folder for find and install (default: %LOCALAPPDATA%\the-cartographer on Windows, else $XDG_CACHE_HOME/the-cartographer or ~/.cache/the-cartographer); the finder's files are in its finder/ folder
CARTOGRAPHER_LEXICON a lexicon file for find and find_skills
CARTOGRAPHER_FINDER_DAILY_PAGES, CARTOGRAPHER_FINDER_DAILY_LISTS the daily caps on skills.sh page requests (300) and robots/sitemap requests (12) for find and install
CARTOGRAPHER_FINDER_DAILY_BULK the daily cap on the bulk index's skill and repo page requests (2000)
CARTOGRAPHER_REFUSE_LICENCES comma-separated licence ids install refuses on this machine, on top of its policy (for example AGPL-3.0,GPL-3.0)
CARTOGRAPHER_NO_NETWORK set (to anything): the finder and installer send no request and say the network is off (the tests set it; model backends are not affected)
CARTOGRAPHER_GITHUB_TOKEN optional token for the one GitHub API call install makes (added only to requests to api.github.com)

FAQ

Does it send my skills anywhere? Only into the prompt of the backend you chose, the same place your agent would send them. Nothing is uploaded or stored by The Cartographer itself.

What if no model is reachable? cartographer ask exits 3 with CARTOGRAPHER_UNAVAILABLE (reason). Agents set up with the integration snippets then run cartographer search instead and carry on.

Does it run the skills? No. It names them. Reading and following a skill is your agent's job. cartographer install downloads files and writes them; it never runs them either, and it refuses agent configuration that your agent host could run on its own unless you pass --allow-agent-config.

Does find crawl skills.sh? No. A search reads the names list (rebuilt from the sitemaps when it is a day old) and at most 8 pages, within the site's robots.txt and a daily cap. The bulk index is opt-in, goes at least 3 seconds apart and has its own daily cap (2,000).

Can a brief hijack it? The brief is wrapped as data, the model has no tools, and the answer is parsed and checked against the catalogue, so every pick it prints is a real catalogue entry. The prompt also tells the model to answer a brief that gives it orders as a plain skill question and add a NOTE saying so.

Should every helper agent ask? No. A coordinator lists every helper's task in one brief and passes each helper its picks.

Development

python -m unittest discover -s tests
python tools/vendor.py verify

The tests call no model and use no network: they cover the front matter reader, the catalogue, answer checking, the command backend, the API request shape (with a stand-in SDK), an MCP stdio session, the bundle hashes, and the finder and installer against a fake skills.sh and fake GitHub tarballs (robots, the URL whitelist, rate limits, licence refusals, unsafe archives, never overwriting, never running a download). See CONTRIBUTING.md for how to propose a change or a skill for the bundle, docs/DESIGN.md for why it works this way, and SECURITY.md for what it does and does not do with your files and the network.

Licence

The Cartographer's code and docs: Apache License 2.0 (LICENSE), copyright 2026 Blake W. If you pass on a copy or a changed version, keep the NOTICE file with it and mark the files you changed. Each bundled skill: its own licence, in its folder (THIRD_PARTY_NOTICES.md lists them all).

Metadata

Release files for the-cartographer 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for the-cartographer 0.1.1
File Size Uploaded Provenance Actions
the_cartographer-0.1.1.tar.gz 6.8 MB With provenance Details for the_cartographer-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for the-cartographer 0.1.1
File Interpreter ABI Platform Actions
the_cartographer-0.1.1-py3-none-any.whl Python 3 none any Details for the_cartographer-0.1.1-py3-none-any.whl

Total release size: 14.2 MB

Release files / the_cartographer-0.1.1.tar.gz

Download URL the_cartographer-0.1.1.tar.gz
Size 6.8 MB
Tags Source
SHA-256 checksum
How to use checksums
fac633b8349dca361854cf9633c2edf2e52831662f07ee10b722e31410bba31f
BLAKE2b-256 checksum
How to use checksums
d4a8251c37cc20dfc8221bbc55d29d6a3630edb55f4b737fcf96954a32cbb7ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Release files / the_cartographer-0.1.1-py3-none-any.whl

Download URL the_cartographer-0.1.1-py3-none-any.whl
Size 7.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
8a454023af7a3793691bffa21e09fa8c3438164d2f7f7d1a459dd04ce826dc43
BLAKE2b-256 checksum
How to use checksums
1832d52086b58046f558bc3a1fddc43a9b2af3d0a8a4359f4df62467c7a90cd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Security for the-cartographer 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for the_cartographer-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page