Skip to main content
Glama

slikkskill, rearranged. A sleek, minimal MCP server that resolves skill names to their filesystem path + metadata, without loading every skill's full content into context.

The name is an anagram of skill that lands on sleek — which is the whole design goal: stay out of the way, add almost no weight, hand back a path and nothing more.

How slikk recovers your context budget

The token savings don't come from slikk doing something clever at runtime — they come from where your skills live. Move your skills out of the default ~/.claude/skills into any directory you like (set SKILLS_DIR), and Claude Code's native loader finds an empty default folder, so it injects zero skill metadata into the system prompt at startup. slikk, pointed at the real directory, then becomes the on-demand way to discover and resolve skills — returning just a path Claude can Read when it actually needs one.

That's the difference from index-and-search tools: slikk doesn't depend on any Claude Code "name-only" loading flag and keeps no derived store — no embeddings, no vector database, no background indexer. It's relocate-and-resolve, not index-and-search.

Related MCP server: Skillz

Install & register

1. Install deps (needs Python 3.10+):

cd /path/to/slikk          # the repo folder
pip install -r requirements.txt

2. Register with Claude Code. Set SKILLS_DIR to the folder you want skills to live in, and enable the optional tools you want (resolve_skill is always on). This example enables doctor and migrate — the relocate-and-resolve workflow:

claude mcp add slikk --scope user \
  -e SKILLS_DIR=~/.agents/skills \
  -e ENABLE_DOCTOR=1 \
  -e ENABLE_MIGRATE=1 \
  -e ENABLE_LIST_SKILLS=0 \
  -e ENABLE_REFRESH_INDEX=0 \
  -e ENABLE_SYNC_COMMANDS=0 \
  -- python3 /absolute/path/to/slikk/server.py

Every optional tool is listed so the full surface is visible — 1 enables a tool, 0 (or omitting the line) disables it. This setup turns on doctor and migrate for the initial relocate-and-resolve flow; flip the 0s to 1 later if you want listing, refresh, or /-autocomplete sync. (resolve_skill is always on and has no flag.)

--scope user registers slikk globally (available in every project) — use it. Without it, claude mcp add defaults to local (current project only), and since relocating skills empties the machine-wide default folder, you want slikk active everywhere, not just one project.

Start (or restart) Claude Code, then run /mcp — you should see slikk connected with resolve_skill, doctor, and migrate.

Prefer editing config by hand? The same registration as a .mcp.json entry is in Register with Claude Code below.

3. Move your skills in: with SKILLS_DIR pointed at your target, ask Claude to plan a migration, review it, then apply. The prompt depends on where your skills currently are:

  • From Claude Code's default folder (~/.claude/skills) — the common case:

    "plan a slikk migration"

    No source needed; migrate defaults to ~/.claude/skills.

  • From a different folder — a custom location, or another tool's skills dir. Name the source explicitly:

    "plan a slikk migration with source ~/my-skills"

After reviewing the plan, say "apply it". You can run migrate more than once — e.g. once for your default folder, then again with a different source to pull in another — and each run is independently reversible. See migrate.

Other optional tools — list_skills, refresh_index, sync_commands — are enabled with their own ENABLE_* flags; see Configuration.

What it does

One real tool that matters: resolve_skill(name)

  • Exact match on skill folder name first

  • Falls back to fuzzy match (typos) and then substring match against descriptions

  • Returns on success: found: true, id, skill_md_path — minimal by design

  • Returns on failure: found: false, error, suggestions (list of close IDs)

  • Never reads/returns the full SKILL.md body, never executes anything

skill_md_path is all Claude needs — it reads that file to get the description, allowed tools, model, argument hint, and full instructions. Returning those fields in the tool result would just duplicate content a single Read away.

Five optional tools (each enabled by an env var — see Configuration):

  • list_skills() — cheap {id, description} listing for browsing (ENABLE_LIST_SKILLS=1)

  • refresh_index() — force re-scan if you just added/edited a skill (ENABLE_REFRESH_INDEX=1)

  • doctor(name=None, apply=False) — health-check skills for broken references (ENABLE_DOCTOR=1)

  • sync_commands() — write ~/.claude/commands/ stubs so every skill appears in / autocomplete (ENABLE_SYNC_COMMANDS=1)

  • migrate(source=None, apply=False, copy=False, link=False, rollback=False) — move (or copy/symlink) your skills into the configured SKILLS_DIR, rewriting stale references so nothing breaks (ENABLE_MIGRATE=1)

migrate — move your skills into SKILLS_DIR without breaking references

This is the setup move (run it once for your main folder, or again later to pull in others). The way you install slikk is to set SKILLS_DIR to the new, permanent home you want your skills to live in — the same dir resolve_skill reads from. But your skills aren't there yet; they're still in Claude Code's default ~/.claude/skills (or another folder). migrate pulls them into your configured SKILLS_DIR, so the default dir ends up empty and Claude Code loads nothing at startup (the whole point).

So the destination is always SKILLS_DIR (your configured target — not an argument). The only thing you specify is the source: where your skills are now. It defaults to ~/.claude/skills, so most users don't pass it at all.

The typical move is therefore Claude Code's default ~/.claude/skills → a dedicated agents dir such as ~/.agents/skills (any path works; slikk doesn't impose a convention).

Move is the normal setup. Just apply=true — it relocates the dirs, rewrites stale refs, and empties the source. Use it unless you have a specific reason not to. copy and link are special cases, not alternatives to reach for by default:

Mode

Flag

What happens

Use when

Move (default, recommended)

apply=true

Relocates the dirs; rewrites stale refs; source ends up empty

Your own skills — the standard relocate-and-resolve setup

Copy

apply=true, copy=true

Duplicates into SKILLS_DIR; rewrites the copies; leaves a second copy in the source

Only if you specifically want to keep the originals

Link

apply=true, link=true

Symlinks into SKILLS_DIR; real dir stays put; originals untouched, refs not rewritten

Only for skills owned by another agent harness you want visible without relocating — not for your own skills

The dry-run plan lists these in placement_options with recommended_mode: move, so the default is clear before you commit.

Moving is exactly where things break: a SKILL.mdor a bundled scripts/*.py / config/*.json — that hardcodes ~/.claude/skills/<other>/... becomes a stale reference once it lives somewhere new. migrate couples the move with the reference rewrite (reusing doctor's stale-base detection) across every text file in the skill, not just SKILL.md, and records a manifest so the whole operation is reversible. Binary assets and undecodable files are left untouched.

Three modes on one tool:

  • Dry-run (default, apply=false) — reports every skill that would move into SKILLS_DIR and every reference that would be rewritten. Touches nothing on disk. Run this first and review it.

  • Apply (apply=true) — places each skill from source into SKILLS_DIR, rewrites the stale references in every bundled text file at the new location, and appends a record to a .slikk-migration.json manifest. Reports whether the source dir ends up empty (the payoff). Placement mode:

    • default — move (source ends up empty)

    • copy=true — duplicate, leaving the originals in place (a safer first pass)

    • link=truesymlink each skill into SKILLS_DIR, leaving the real dir where it is (see below); originals are untouched and not rewritten. copy and link are mutually exclusive.

  • Rollback (rollback=true) — undoes the most recent run: reverts the rewrites and restores the placement (moves dirs back, deletes copies, or removes symlinks). Run it again to step back through earlier runs.

For move/copy, references are rewritten across every skill, so a skill you're not moving that points into one you are moving is fixed too.

Multiple sources, and linking another harness's folder

migrate is re-runnable. Each call records its own run in the manifest, so you can consolidate several folders into one SKILLS_DIR — run it once per source — and roll them back independently, newest first.

link=true is for skills owned by another agent harness: you want them visible in SKILLS_DIR (so slikk and Claude Code can resolve them) without relocating or editing them. slikk symlinks each skill into SKILLS_DIR; the real files stay exactly where the other harness keeps them, byte-for-byte, and their internal references are deliberately left alone (rewriting them would edit another tool's files). Rollback simply removes the symlinks.

A typical mixed setup:

  1. "Migrate." → move your own skills from ~/.claude/skills into SKILLS_DIR

  2. "Migrate with source ~/.other-harness/skills and link=true." → symlink that harness's skills in, untouched

  3. "Roll back." → removes the symlinks; "roll back" again → moves your own skills back

First, set SKILLS_DIR to your target dir (e.g. ~/Downloads/claude-code-skills). If SKILLS_DIR is still ~/.claude/skills, migrate has nothing to do and tells you to configure a destination first.

A natural session (skills currently in the default folder):

  1. "Plan a migration." → review which skills move into SKILLS_DIR + the rewrites

  2. "Looks right — apply it." → moves, rewrites, writes the manifest

  3. (if needed) "Roll that migration back." → restores the original state

Migrating from a different source folder

"Plan a migration" defaults to ~/.claude/skills. If your skills live somewhere else — a custom location, or another tool's folder — name the source in the prompt:

  • "Plan a slikk migration with source ~/my-skills."

  • "Migrate from ~/.other-harness/skills with link=true." (symlink, for a folder you don't want to relocate)

The dry-run plan echoes which source it scanned (source_note); if it reports zero skills, it reminds you to point source at the right folder.

Updating CLAUDE.md after migrating

Once the default folder is empty, Claude Code needs to be told where skills went. Every migrate result (plan and apply) includes a claude_md_suggestion — a ready-to-paste block stating skills now live in your SKILLS_DIR and how to resolve them (Read the path directly when the name is known; call resolve_skill when it's ambiguous). slikk does not write any file — it only suggests the text, and claude_md_target recommends the global ~/.claude/CLAUDE.md (the move is machine-wide, so the guidance belongs there). A claude_md_apply_hint tells Claude Code to reconcile with any existing skill-resolution section rather than appending a duplicate.

In practice: after migrating from Claude Code, ask "add the suggested skills note to my global CLAUDE.md" — Claude reads the suggestion from the result, merges it into your ~/.claude/CLAUDE.md, and you confirm the change.

After migrating: next_steps

A successful move/copy result also includes a next_steps list — structured objects, each with a title, detail, and an automatable flag — covering: applying the CLAUDE.md block, reconnecting so a fresh session loads the empty default folder, optionally running doctor to verify nothing broke, enabling sync_commands for / autocomplete (whitelisting the ones you use most), and — once setup is done — optionally setting ENABLE_MIGRATE=0 / ENABLE_DOCTOR=0 (left in place so they're easy to flip back on) to keep the surface minimal.

The steps marked automatable are config edits Claude Code can do for you — when you run migrate from Claude Code, it can edit the slikk registration (enable sync_commands, toggle the flags) on your confirmation, rather than you hand-editing JSON. The catch is built into each step: any registration change needs the slikk server to reconnect before it takes effect (requires_reconnect). So a flow like "enable sync and run it" is really: Claude edits the registration → you reconnect → Claude runs sync_commands. Toggling those flags edits the registration and the slikk server must reconnect to pick it up; Claude Code can make the edit, but restart the session if the tool list doesn't update.

doctor — find & fix broken references

doctor checks whether a skill points at things that don't exist, so you catch breakage before invocation instead of mid-run.

Scope: doctor() checks all skills; doctor(name="mythic") checks one. Results are grouped per skill, ordered worst-first.

What it detects, in "will break at runtime" order:

  • unloadableSKILL.md missing, no --- frontmatter block, or invalid YAML. The resolver silently drops these, so they can't be invoked at all.

  • missing_skill_ref — a referenced skill that doesn't exist: in permissions.spawns, in ~/.claude/skills/<other>/... paths, or in the body.

  • missing_local_file — a path the body instructs Claude to read/run that should live in the skill's own directory but doesn't (e.g. scripts/foo.py, config/services.json). Resolved against the skill dir and any extra_roots (see below), so scripts kept outside SKILLS_DIR still count.

  • stale_prefix — a skill-to-skill path reference whose base directory doesn't match the configured SKILLS_DIR. SKILLS_DIR can be any folder you choose (e.g. ~/.claude/skills, ~/.agents/skills, or something entirely custom like ~/Downloads/claude-code-skills). If a SKILL.md references another skill using a different base — most commonly the legacy ~/.claude/skills/<other>/... convention when your skills actually live elsewhere — that base is "stale." When the referenced skill exists, this is auto-fixable: the base is rewritten to point at your SKILLS_DIR, preferring a portable home-relative form (e.g. ~/Downloads/claude-code-skills/sentinel/**) when SKILLS_DIR is under your home directory, and falling back to an absolute path only when it isn't. When the referenced skill does not exist (e.g. oracle), it is reported but NOT auto-fixed — rewriting the base wouldn't help while the target is still missing, so it stays a manual suggestion alongside the missing_skill_ref. The rewrite is idempotent: a reference that already uses the correct SKILLS_DIR base is never re-flagged.

  • dangling_symlink — a symlink inside the skill directory whose target doesn't resolve (e.g. medic/scripts/utils.py → ../../oracle/scripts/utils.py when the oracle skill is missing). Suggestion-only — the doctor can't invent the target, so it reports the broken link and what it points at.

Each body reference is classified hard vs illustrative: "hard" means it sits in a code block or on a real read/run instruction line (these actually fail during invocation); "illustrative" means it only appears in prose/tables (likely a false positive for breakage) and is reported at low severity. Templated paths ({SERVICE}, ${TS}, SPRINT_NAME) and runtime output dirs (memory/, reports/, ...) are ignored — those are written at runtime, not bundled.

Every issue carries a suggestion. A subset are auto_fixable:

  • apply=False (default) — diagnose only, never touches files.

  • apply=True — writes ONLY the safe fixes: repairing missing frontmatter, renaming a spawn to its single unambiguous existing match (e.g. ticket-intaketicket-intake-pipeline), and rewriting a stale ~/.claude/skills/ prefix to match SKILLS_DIR (portable ~/... form when possible) when the target skill exists. Risky changes (deleting refs, creating missing skills/files, repointing/rewriting paths to skills that don't exist like oracle, fixing broken YAML structure) are never auto-applied — they stay as suggestions. Re-running with apply=True is idempotent.

Triggering the doctor in Claude Code

doctor is an MCP tool, so you trigger it with natural language — Claude picks the tool and fills in name / apply. The recommended flow is diagnose first, review, then apply (apply only writes the safe fixes).

Diagnose (no changes):

  • "Run the slikk doctor and show me all the broken references."

  • "Run doctor on the mythic skill." (one skill instead of all)

Apply fixes (after reviewing):

  • "Apply the safe fixes for mythic."

  • "Run doctor across all skills and apply the auto-fixes."

If Claude doesn't reach for the tool, name it directly: "use the slikk doctor tool." (The tool only triggers if the slikk MCP is registered in that Claude Code instance.)

Running the doctor directly (no MCP needed)

The same function runs straight from a terminal — server.doctor(name=None, apply=False):

SKILLS_DIR=... python3 -c "import server, json; print(json.dumps(server.doctor(), indent=2))"

Pass name='<id>' for one skill and apply=True to write the safe fixes. You can also call the logic module directly (doctor.run_doctor, needs only pyyaml, no mcp) — note it does not expand ~, so give it an absolute path.

Resolving scripts kept outside SKILLS_DIR (extra_roots)

Some skills keep their scripts outside the skills dir — e.g. grimoire runs ~/.claude/grimoire/scripts/db.py. To stop those from being reported as missing_local_file, the doctor resolves bundled-file references against the skill dir plus a list of extra roots. A file counts as found if it exists at <root>/<skill>/<rel> or <root>/<rel>.

Source order: the extra_roots argument > the CLAUDE_EXTRA_ROOTS env var (os.pathsep-separated) > the default ~/.claude. So out of the box, anything under ~/.claude/<skill>/... already resolves with no extra configuration.

# add more roots for this run
SKILLS_DIR=... python3 -c "import server, json; print(json.dumps(server.doctor(extra_roots=['~/.claude', '~/git_tree']), indent=2))"

# or via env
CLAUDE_EXTRA_ROOTS=~/.claude:~/git_tree SKILLS_DIR=... python3 -c "import server, json; print(json.dumps(server.doctor(), indent=2))"

Note: permissions is not part of the standard Claude Code skill format and is not enforced by Claude Code, so permission-path findings are flagged as intent-only. The references that genuinely break invocation are the ones in the skill body.

sync_commands — keep / autocomplete in sync

When ENABLE_SYNC_COMMANDS=1 is set, the sync_commands tool writes one ~/.claude/commands/<id>.md stub per skill so every skill appears in Claude Code's / autocomplete. It force-refreshes the index before writing, deletes stubs for skills that no longer exist, and skips writes when content is unchanged (idempotent).

Filtering

Whitelist and blacklist are mutually exclusive — set one or neither, not both. If both are set the tool returns an error immediately and touches nothing.

Env var

Effect

(neither set)

sync all skills

SYNC_COMMANDS_WHITELIST=id1,id2,...

sync only the listed skill IDs

SYNC_COMMANDS_BLACKLIST=id1,id2,...

sync everything except the listed IDs

Use whitelist when you want a small explicit opt-in set; use blacklist when you want to exclude a handful of skills from an otherwise full sync.

Response

{
  "synced": 42,
  "added": 3,
  "updated": 0,
  "deleted": 1,
  "unchanged": 38,
  "deleted_ids": ["old-skill"],
  "commands_dir": "/Users/you/.claude/commands"
}

Configuration

All configuration is via environment variables set in your MCP config.

Core

Env var

Default

Description

SKILLS_DIR

~/.claude/skills

Directory to scan for skill folders — set this to the new home you want skills to live in (e.g. ~/.agents/skills or ~/Downloads/claude-code-skills); any path works

Windows: Claude Code runs under WSL, so it's a Linux environment — use the WSL paths (~/.claude/skills, etc.) and run slikk inside WSL like any Linux setup. The default already matches. Native (non-WSL) Windows Python is not supported: the path handling assumes POSIX-style / paths.

Optional tools (disabled by default)

Env var

Enables

ENABLE_LIST_SKILLS=1

list_skills() tool

ENABLE_REFRESH_INDEX=1

refresh_index() tool

ENABLE_DOCTOR=1

doctor() tool

ENABLE_SYNC_COMMANDS=1

sync_commands() tool

ENABLE_MIGRATE=1

migrate() tool

sync_commands options

Env var

Default

Description

COMMANDS_DIR

~/.claude/commands

Where to write slash-command stubs

SYNC_COMMANDS_WHITELIST

(none)

Comma-separated skill IDs to sync (exclusive with blacklist)

SYNC_COMMANDS_BLACKLIST

(none)

Comma-separated skill IDs to exclude (exclusive with whitelist)

doctor options

Env var

Default

Description

CLAUDE_EXTRA_ROOTS

~/.claude

Colon-separated extra roots for resolving bundled-file references

What it deliberately does NOT do

  • No execution. Claude Code already has bash/file access — resolution and execution are kept separate so whatever confirmation gates already exist in your skills (script-level checks, or Claude pausing to ask you) are never silently bypassed by a new layer.

  • No auto-chaining. If a skill needs another, that's expressed in its body ("run X first", "read Y") and Claude resolves it at runtime — calling resolve_skill as needed. The server never walks a dependency graph, and it does not read structured dependency metadata (Claude Code ignores such keys anyway).

  • No safety classification. The server doesn't invent a "safe/unsafe" flag. Use Claude Code's real disable-model-invocation / user-invocable frontmatter if you want to control how a skill is invoked.

Verify the install

Install is covered in Install & register. To smoke-test the server outside Claude Code, run it directly:

# defaults to ~/.claude/skills; set SKILLS_DIR to override
SKILLS_DIR=~/.agents/skills python3 -c "
import server
print(server.list_skills()[:3])
"

Register with Claude Code

The quickest way is the CLI (see Install & register):

claude mcp add slikk --scope user \
  -e SKILLS_DIR=~/.agents/skills \
  -e ENABLE_DOCTOR=1 \
  -e ENABLE_MIGRATE=1 \
  -e ENABLE_LIST_SKILLS=0 \
  -e ENABLE_REFRESH_INDEX=0 \
  -e ENABLE_SYNC_COMMANDS=0 \
  -- python3 /absolute/path/to/slikk/server.py

All optional flags are shown explicitly (1 on, 0 off) so the full surface is visible and easy to toggle. --scope user makes slikk global (every project); the default is local (current project only). Or add it to your MCP config by hand — for the global equivalent, put it in ~/.claude.json rather than a project .mcp.json:

{
  "mcpServers": {
    "slikk": {
      "command": "python3",
      "args": ["/absolute/path/to/slikk/server.py"],
      "env": {
        "SKILLS_DIR": "~/.agents/skills",
        "ENABLE_DOCTOR": "1",
        "ENABLE_MIGRATE": "1",
        "ENABLE_LIST_SKILLS": "0",
        "ENABLE_REFRESH_INDEX": "0",
        "ENABLE_SYNC_COMMANDS": "0",
        "SYNC_COMMANDS_WHITELIST": "",
        "SYNC_COMMANDS_BLACKLIST": ""
      }
    }
  }
}

SKILLS_DIR defaults to ~/.claude/skills if omitted. Point it at wherever you keep your skills — any path works, and the doctor tool adapts its reference-checking to whatever base you configure. Each optional tool (list_skills, refresh_index, doctor, sync_commands, migrate) is off until you set its ENABLE_* flag — see Configuration for the full list.

SYNC_COMMANDS_WHITELIST / SYNC_COMMANDS_BLACKLIST are shown empty as placeholders: leaving both empty is fine — even with ENABLE_SYNC_COMMANDS=1 it just means "sync all skills." Fill in one (comma-separated IDs) to surface only those (whitelist) or hide those (blacklist); setting both to non-empty is an error.

Frontmatter fields the resolver surfaces

The resolver only reads frontmatter keys that Claude Code itself recognizes. All are optional; a skill needs only name + description to be useful.

---
name: my-skill
description: When to use this skill (this is what Claude matches on).
allowed-tools: Read, Grep, Bash      # optional: scope tool access
user-invocable: true                 # optional: who may invoke
argument-hint: <ticket-id>           # optional: expected input
model: claude-sonnet-4-6             # optional: for subagent execution
---

Older versions of this resolver invented extra keys (depends_on, gated_by, calls_next, permissions, executable, entrypoint, requires_confirmation). Claude Code does not read those, so they've been dropped. Express cross-skill dependencies in the skill body instead — Claude follows those instructions and resolves other skills at runtime.

Notes

  • The index is cached for 30 seconds (cache_ttl_seconds in server.py) — call refresh_index() if you need it to pick up changes immediately, e.g. right after creating a new skill with writing-skills or create-playbook.

  • Skill folders with malformed/missing frontmatter are excluded from list_skills() and return a clear parse error from resolve_skill() rather than crashing the server.

  • Folder names with colons (e.g. ape:create-jira) work fine — tested.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kibarayhan/slikk'

If you have feedback or need assistance with the MCP directory API, please join our Discord server