MagicSkills, where one registry decides which skills each agent sees
MagicSkills:Stop copying skills between agents. MagicSkills turns scattered SKILL.md folders into reusable, composable, tool-ready capabilities.
At a glance
- What is it?
- MagicSkills is a local-first Python layer for managing SKILL.md directories across many agent runtimes: it keeps one installed pool, builds named subsets for each agent, and writes those subsets into AGENTS.md or exposes them through a CLI tool and a Python API. The interesting details are small ones, including a wheel build that excludes the bundled skills path and a sync that replaces rather than merges.
- Who is it for?
- MagicSkills earns its place if you run more than one agent against the same skill content and are tired of copies drifting apart, and it is easy to skip if you have exactly one agent and one skills folder. Before adopting it, check two things.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 177 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One runtime dependency, and it is a C parser
The package declares a single runtime dependency, pycparser>=2.21, which is a parser for C. For a Python tool whose job is managing directories of markdown files, that is an odd choice, and it says something about the implementation: nearly everything else comes from the standard library.
The surrounding tooling configuration is much heavier than that one line. Ruff runs with a line length of 100 and fix set to true, so invoking the linter rewrites files rather than only reporting on them. Mypy runs in strict mode with the python version pinned to 3.10, plus warn_unreachable and warn_no_return. Pytest is pointed at tests with src on the python path. tox.ini sits at the root beside the dev extras, which pull pytest, ruff, mypy, build, and twine.
So the dependency graph is tiny and the tooling graph is not. For a library that gets dropped into several agent projects, that is a sensible trade, and it also means the install footprint is one small wheel plus whatever the interpreter already carries.
The wheel build excludes the bundled skills directory
Under the hatch build configuration there is one exclusion entry, and it is src/magicskills/skills/**. Everything under that path is left out of the distribution.
That single line is worth pausing on, because the rest of the project is organised around a pool of installed skills. The wheel target packages src/magicskills. If skills are versioned inside that package, a pip install gets the manager without them. If they are not, the exclusion is defensive and costs nothing.
The documented workflow sidesteps the question by installing skills explicitly, from a GitHub repository or from a local directory:
magicskills install anthropics/skills -t ~/allskillsSo the tool is designed around a pool you populate yourself rather than a library that arrives with the package. Worth checking on your own install whether anything landed in that path, because the build configuration and the Quick Start point at two different models of where skills come from.
syncskills overwrites an existing skills section
Sync is a write, not a merge. If the target AGENTS.md already contains a skills section, that section is replaced. If it does not, a new one is appended.
That rule applies to a file that is very often edited by hand and often committed, so the blast radius of a stray sync is larger than the command looks. Nothing in the description mentions a backup, a diff, or a dry run.
The two modes change how much gets written. The mode named none is not a no-op despite the name: it keeps the standard structure of a usage section plus an available skills list, for agents that can read skills straight out of that list. The cli_description mode writes only the usage section, using the collection's own cli_description, for agents that need to be told to call the CLI instead.
Running syncskills with just a collection name takes the full structure, and the file it writes to is whatever was remembered when the collection was created. Agents that read neither AGENTS.md nor the CLI reach the same three operations from Python, described as the same interface exposed directly rather than as a separate API.
--universal points at a directory convention you cannot set
Four install locations are defined, and two of them are guesses about somebody else's conventions.
The current project location is ./.claude/skills/ and the --global form is ~/.claude/skills/. Those two are the Claude Code paths and they are unambiguous. The other two, --universal at ./.agent/skills/ and --global --universal at ~/.agent/skills/, are the ones meant to work for everything else.
The difficulty is that .agent is a directory name this project cannot define. A framework integration will look wherever its own documentation says, and if that is not .agent/skills, the universal location simply stays empty. That is the reason the recommended practice is a shared root such as ~/allskills with -t or --target naming it explicitly: an explicit path sidesteps the convention problem, at the cost of having to tell every agent about it.
All four are defaults rather than constraints, since the same target flag overrides them, but nothing in the tool creates the directory or registers it with a framework that has never heard of it.
The registry on disk decides what an agent can see
The core model has four nouns and only one of them is a directory.
A Skill is one concrete skill directory. ALL_SKILLS() is the built-in Allskills view over everything installed into the pool. Skills is the subset an agent or workflow actually uses. REGISTRY is the global named collection registry, persisted across runs.
That last one is where the state lives. Creating a collection remembers two things: the skill names in it, and the sync target passed as --agent-md-path. Both survive the process, so a team can share the registry, and so a stale entry outlives the directory it pointed at.
The separation between pool and subset is the actual idea here. Without a layer like this the same skill gets copied into each agent folder and drifts, which the README names as the failure it is built against. With it, one directory is the truth and each agent receives a named view. The named scenario is a single reusable skill that thirteen agent apps and frameworks all need, kept in one pool instead of thirteen copies.
Python 3.14 is excluded and 3.13 is the newest classifier
requires-python is >=3.10,<3.14, and the classifiers cover 3.10, 3.11, 3.12, and 3.13. The upper bound and the classifier list agree, so the metadata is at least self consistent.
What it means in practice is that the newest Python is unavailable by policy rather than by accident, and the next language release needs a bounds change before the tool installs on it. For a package sitting underneath several agent integrations that is a decision worth making on purpose rather than inheriting from whatever template produced the file.
The rest of the packaging is small and conventional. The build backend is hatchling with a requirement of 1.24.0 or newer, the readme is README.md, the license is a file reference rather than a classifier-only declaration, and one console script maps magicskills to magicskills.cli:main. The keyword list includes openskills, which reads as a pointer to the naming this project is reacting to rather than a dependency.
The release history is short. The tags are v0.1.1 on 31 December 2025, v1.0 on 10 March 2026 labelled Initial Release, and v1.1 on 22 March 2026. The version in pyproject.toml reads 1.1.0, and the last push to main is 8 April 2026.
Thirteen example directories and one skill template
The repository root is more than half examples. There are Aider_example/, ClaudeCode_example/, Codex_example/, Cursor_example/, Windsurf_example/, autogen_example/, crewai_example/, haystack_example/, langchain_example/, langgraph_example/, llamaindex_example/, semantic_kernel_example/, and smolagents_example/.
Thirteen directories, one per target runtime, each a separate integration to keep working as the underlying CLI and Python API move. That is the maintenance shape implied by a tool whose purpose is to be the layer under many agents. There is also no homepage and no documentation site; the navigation links to two files in the repository, doc/cli.md and doc/python-api.md, and the README exists in English and Simplified Chinese with contributing guides and release notes mirrored in both.
The framework examples share one model configuration. The .env.example at the root holds three variables used by all of them, an OpenAI-compatible API key, an optional base URL pointing at a DeepSeek endpoint, and a model name of deepseek-chat, so the examples run against a third party provider by default.
Alongside them sits skill_template/, the one directory that is not an agent example. The Quick Start reuses it as a stand in for a skill you already have locally, and its example skill is named c_2_ast, a name that recurs through the README wherever a real skill name is needed.
Editorial conclusion
MagicSkills earns its place if you run more than one agent against the same skill content and are tired of copies drifting apart, and it is easy to skip if you have exactly one agent and one skills folder. Before adopting it, check two things. First, whether the sync target AGENTS.md is hand-edited anywhere in your repositories, because syncskills replaces an existing skills section outright. Second, whether the agents you use actually read .agent/skills, since that universal default is a convention the project cannot set on your behalf. Use the explicit target flag rather than the defaults and most of the sharp edges disappear.
Frequently asked questions
Where does magicskills install skills by default?
Four locations: the current project at ./.claude/skills/, --global at ~/.claude/skills/, --universal at ./.agent/skills/, and --global --universal at ~/.agent/skills/. You can also pass -t or --target to install into any explicit path.
What is the difference between AGENTS.md sync and the magicskills CLI tool?
syncskills writes a collection into AGENTS.md, either the standard usage plus available_skills structure in none mode or only the usage section from cli_description in cli_description mode. Agents that do not read AGENTS.md can use magicskills skill-tool with the listskill, readskill, and execskill subcommands instead.
Which Python versions does magicskills support?
pyproject.toml sets requires-python to >=3.10,<3.14, so Python 3.14 is excluded, and the classifiers stop at 3.13. The project is MIT licensed and declares only Python 3 as its platform.
Does magicskills merge into an AGENTS.md that already has a skills section?
No. If the target file already contains a skills section it is replaced, and if not a new one is appended. The default sync target for a collection is the path remembered when the collection was created through the --agent-md-path argument on addskills.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/narwhal-lab-magicskills)