# How to use Python skills with Claude Code


Skills bottle up your Python workflow. Instead of re-explaining "tighten these type annotations" or "use [uv](https://pydevtools.com/handbook/reference/uv.md) instead of pip" every session, save the procedure to a markdown file once and let [Claude Code](https://code.claude.com/) reach for it when you ask, either by slash command or by describing the task in plain English. Long reference material that would crowd a [CLAUDE.md](https://pydevtools.com/handbook/how-to/how-to-use-the-pydevtools-claude-md-template.md) only loads when the skill runs.

This guide installs OpenAI's Astral plugin, walks through writing a custom Python skill, and shows when a skill beats CLAUDE.md or a hook.

> [!TIP]
> For a hands-on walkthrough that sets up CLAUDE.md, hooks, and a custom skill together on a fresh project, see the [project setup tutorial](https://pydevtools.com/handbook/tutorial/set-up-a-python-project-for-claude-code.md).

## How skills work

Each skill is a `SKILL.md` file with YAML frontmatter (`name`, `description`, optional fields) plus a markdown body. Claude Code searches the following locations in priority order:

| Location | Path | Scope |
|---|---|---|
| Personal | `~/.claude/skills/<name>/SKILL.md` | Every project on your machine |
| Project | `.claude/skills/<name>/SKILL.md` | Only the project where it lives |
| Plugin | Bundled with `/plugin install`, namespaced as `plugin:skill` | Wherever the plugin is enabled |

Invoke a skill by typing `/<skill-name>` in the Claude Code prompt, or let Claude pick it up automatically when your prompt matches the skill's `description`. Plugin skills carry the plugin name in front of a colon, so OpenAI's Astral plugin's [Ruff](https://pydevtools.com/handbook/reference/ruff.md) skill is `/astral:ruff`.

The `SKILL.md` body loads only when the skill is triggered, so reference material that would crowd a CLAUDE.md file stays out of context until you need it. See the [official skills documentation](https://code.claude.com/docs/en/skills) for the full frontmatter reference.

## Install OpenAI's Astral skill set for uv, Ruff, and ty

The handbook recommends [OpenAI's Astral plugin](https://github.com/astral-sh/claude-code-plugins) as the default skill set for any uv-managed Python project. It bundles `/astral:uv`, `/astral:ruff`, and `/astral:ty`, plus a [ty](https://pydevtools.com/handbook/reference/ty.md) language server that streams type-checking diagnostics into the conversation.

Run two slash commands inside Claude Code:

```
/plugin marketplace add astral-sh/claude-code-plugins
/plugin install astral@astral-sh
```

Once installed, ask Claude to "audit my types with /astral:ty" or "format this file with /astral:ruff" and it follows OpenAI's documented workflow for the tool.

For a team-wide install via `.claude/settings.json` so every collaborator gets the plugin after trusting the repo, see [How to install OpenAI's Astral plugins for Claude Code](https://pydevtools.com/handbook/how-to/how-to-install-astral-plugins-for-claude-code.md).

## Write your own Python skill

Lift repeated Python instructions into a project skill so the next teammate or AI session reuses them instead of regenerating the steps from scratch.

This walkthrough creates a `type-tighten` skill that audits Python type annotations against modern conventions and verifies the result with [ty](https://pydevtools.com/handbook/reference/ty.md).

### Create the skill directory

In any uv-managed Python project:

```bash
mkdir -p .claude/skills/type-tighten
```
```powershell
New-Item -ItemType Directory -Force -Path .claude\skills\type-tighten
```
### Write the SKILL.md

Create `.claude/skills/type-tighten/SKILL.md`:

```markdown {filename=".claude/skills/type-tighten/SKILL.md"}
---
name: type-tighten
description: Tighten Python type annotations in the path provided. Use when the user wants stronger types or modern type syntax.
argument-hint: "[path]"
---

When invoked, audit Python type annotations in $ARGUMENTS:

1. Replace `Any` with the most specific type that still type-checks.
2. For Python 3.10+ code, replace `Optional[X]`, `Union[X, Y]`, and `List[X]` with `X | None`, `X | Y`, and `list[X]`. Skip rewrites of quoted forward references (`Optional["Node"]`) unless `from __future__ import annotations` is active so the result still parses at runtime.
3. Remove now-unused imports from `typing` (`Optional`, `Union`, `List`).
4. Add `-> None` to functions without an explicit return type.
5. Run `uv run ty check $ARGUMENTS` and fix any new errors before reporting back.

Report the number of annotations changed and whether the type checker still passes.
```

The frontmatter's `description` is what Claude reads to decide whether to load the skill automatically. Write it like a brief task summary the model can match against the user's prompt. The `argument-hint` is shown during slash-command autocomplete so the user knows what to pass.

### Invoke the skill

In Claude Code, type:

```
/type-tighten src/myapp/
```

Or ask in natural language ("tighten the types in src/myapp/") and Claude matches the prompt against the skill's `description` to load the same procedure. Either way, Claude reads the skill's instructions, makes the changes in `src/myapp/`, runs `uv run ty check`, and reports back.

To make the skill global instead of project-scoped, move the directory to `~/.claude/skills/type-tighten/`. Personal skills take precedence over project skills with the same name. To stop Claude from auto-loading a skill (so it only fires when you type `/type-tighten`), add `disable-model-invocation: true` to the frontmatter.

> [!TIP]
> Keep `SKILL.md` under 500 lines. For longer reference material, drop additional files into the skill directory and reference them from the body. Claude only reads them when the skill points at them.

## Choose between skills, hooks, and CLAUDE.md

Claude Code gives you several places to encode Python conventions. Each one suits a different shape of guidance:

| Need | Best fit |
|---|---|
| Project conventions Claude reads on every prompt (preferred tools, repository structure) | [CLAUDE.md](https://pydevtools.com/handbook/how-to/how-to-use-the-pydevtools-claude-md-template.md) |
| A repeatable procedure Claude loads on demand, by slash command or natural-language match against the skill's `description` ("tighten types," "review exception handling") | Skill |
| A rule that runs automatically on a tool event, blocking the call or surfacing feedback (no `pip install`, autoformat after every edit) | [Hook](https://pydevtools.com/handbook/how-to/how-to-write-claude-code-hooks-for-python-projects.md) |

Skills sit between the other two. They bundle a step-by-step procedure that loads only when triggered, which keeps the always-on context (CLAUDE.md) lean. Hooks are stricter: they fire on tool events and can block, while skills only run when invoked.

The layers compose. CLAUDE.md sets the default tooling for the project and a skill like `/type-tighten` runs only when the reviewer asks for it. A hook can still block `pip install` underneath, regardless of which skill or guidance Claude is following.

## Try community Python skill collections

Several Python developers maintain public skill repositories that go further than what fits in this guide. They install with the same `/plugin marketplace add` then `/plugin install` flow as OpenAI's Astral plugin.

- Matthew Honnibal's [claude-skills](https://github.com/honnibal/claude-skills): skills focused on code quality, including `tighten-types`, `contract-docstrings`, `hypothesis-tests`, and a `pre-mortem` that drafts incident reports for code that hasn't broken yet. Walkthrough: [Seven Claude Code skills for Python from the creator of spaCy](https://pydevtools.com/blog/matthew-honnibal-claude-skills-for-python.md).
- Dagster's [dignified-python-313](https://github.com/dagster-io/erk/tree/main/.claude/skills/dignified-python-313): Python 3.13 conventions, modern type syntax, Click CLI patterns, and subprocess safety. Walkthrough: [Teaching Claude Code quality patterns with a custom skill](https://pydevtools.com/blog/dignified-python-313-claude-skill.md).
- Will McGinnis's [python-skills](https://github.com/wdm0006/python-skills): skills for professional Python library development, packaged into bundles like `python-library-foundations` and `python-library-quality`.

> [!CAUTION]
> Audit a skill before installing it globally. A `SKILL.md` body can include `` !`command` `` shell snippets that run before Claude sees the rendered prompt, so treat untrusted skills like code, not like inert documentation.

## Learn more

- [Claude Code skills documentation](https://code.claude.com/docs/en/skills) for the full frontmatter reference and the supporting-files pattern
- [How to Set Up CLAUDE.md for a Python Project](https://pydevtools.com/handbook/how-to/how-to-use-the-pydevtools-claude-md-template.md) for the always-on guidance layer
- [How to install OpenAI's Astral plugins for Claude Code](https://pydevtools.com/handbook/how-to/how-to-install-astral-plugins-for-claude-code.md) covers team-wide installs
- [How to write Claude Code hooks for Python projects](https://pydevtools.com/handbook/how-to/how-to-write-claude-code-hooks-for-python-projects.md) shows the enforcement layer skills can't replace
- [How to configure Claude Code to use uv](https://pydevtools.com/handbook/how-to/how-to-configure-claude-code-to-use-uv.md) for the CLAUDE.md-based default
- [Claude Code: a complete guide](https://pydevtools.com/handbook/explanation/claude-code-complete-guide.md) for the broader feature surface
