slikk
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@slikkresolve skill 'test-plan'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
slikk — skill, 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.txt2. 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.pyEvery 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.jsonentry 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 designReturns on failure:
found: false,error,suggestions(list of close IDs)Never reads/returns the full
SKILL.mdbody, 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 configuredSKILLS_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) |
| Relocates the dirs; rewrites stale refs; source ends up empty | Your own skills — the standard relocate-and-resolve setup |
Copy |
| Duplicates into | Only if you specifically want to keep the originals |
Link |
| Symlinks into | 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.md — or 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 intoSKILLS_DIRand every reference that would be rewritten. Touches nothing on disk. Run this first and review it.Apply (
apply=true) — places each skill fromsourceintoSKILLS_DIR, rewrites the stale references in every bundled text file at the new location, and appends a record to a.slikk-migration.jsonmanifest. 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=true— symlink each skill intoSKILLS_DIR, leaving the real dir where it is (see below); originals are untouched and not rewritten.copyandlinkare 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:
"Migrate." → move your own skills from
~/.claude/skillsintoSKILLS_DIR"Migrate with source
~/.other-harness/skillsand link=true." → symlink that harness's skills in, untouched"Roll back." → removes the symlinks; "roll back" again → moves your own skills back
First, set
SKILLS_DIRto your target dir (e.g.~/Downloads/claude-code-skills). IfSKILLS_DIRis 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):
"Plan a migration." → review which skills move into
SKILLS_DIR+ the rewrites"Looks right — apply it." → moves, rewrites, writes the manifest
(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/skillswithlink=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:
unloadable—SKILL.mdmissing, 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: inpermissions.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 anyextra_roots(see below), so scripts kept outsideSKILLS_DIRstill count.stale_prefix— a skill-to-skill path reference whose base directory doesn't match the configuredSKILLS_DIR.SKILLS_DIRcan be any folder you choose (e.g.~/.claude/skills,~/.agents/skills, or something entirely custom like~/Downloads/claude-code-skills). If aSKILL.mdreferences 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 yourSKILLS_DIR, preferring a portable home-relative form (e.g.~/Downloads/claude-code-skills/sentinel/**) whenSKILLS_DIRis 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 themissing_skill_ref. The rewrite is idempotent: a reference that already uses the correctSKILLS_DIRbase 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.pywhen theoracleskill 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-intake→ticket-intake-pipeline), and rewriting a stale~/.claude/skills/prefix to matchSKILLS_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 likeoracle, fixing broken YAML structure) are never auto-applied — they stay as suggestions. Re-running withapply=Trueis 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
mythicskill." (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:
permissionsis 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 only the listed skill IDs |
| 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 |
|
| Directory to scan for skill folders — set this to the new home you want skills to live in (e.g. |
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 |
|
|
|
|
|
|
|
|
|
|
sync_commands options
Env var | Default | Description |
|
| Where to write slash-command stubs |
| (none) | Comma-separated skill IDs to sync (exclusive with blacklist) |
| (none) | Comma-separated skill IDs to exclude (exclusive with whitelist) |
doctor options
Env var | Default | Description |
|
| 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_skillas 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-invocablefrontmatter 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.pyAll 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_secondsinserver.py) — callrefresh_index()if you need it to pick up changes immediately, e.g. right after creating a new skill withwriting-skillsorcreate-playbook.Skill folders with malformed/missing frontmatter are excluded from
list_skills()and return a clear parse error fromresolve_skill()rather than crashing the server.Folder names with colons (e.g.
ape:create-jira) work fine — tested.
This server cannot be installed
Maintenance
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