{
  "markdown": "# dsh-skills-anywhere\n\n**Your skills, anywhere.** Install an [Agent Skill](https://agentskills.io) once, use it in every agent: a live skill provider for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`) and an MCP server for Claude Code, Cursor, Codex and friends.\n\nEnglish | [中文](README.zh.md)\n\n**[Try the interactive Hugging Face playground](https://huggingface.co/spaces/glayguo/dsh-skills-anywhere)** — explore an example workspace, resolve name clashes, and search beyond the catalog budget. No installation or model API needed. [How it works](docs/HUGGINGFACE.md).\n\n**Bring your own `SKILL.md`.** Compare the provider's strict and lenient parsing\nlocally: inspect repairs, invocation settings and a downloadable check report.\nYour file stays in the browser. The same checks are available in the\n[command line and CI](docs/CHECKING.md), with file hashes and actionable exit codes.\nThis is a parser check, not a security audit or a guarantee of compatibility with every client.\n\n<a href=\"https://huggingface.co/spaces/glayguo/dsh-skills-anywhere\"><img src=\"docs/skill-check.png\" width=\"880\" alt=\"Actual local SKILL.md check: strict mode rejects an invalid name, while lenient mode explains the name and description repairs.\"></a>\n\n[![CI](https://github.com/noteflowai/dsh-skills-anywhere/actions/workflows/ci.yml/badge.svg)](https://github.com/noteflowai/dsh-skills-anywhere/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/dsh-skills-anywhere?label=npm)](https://www.npmjs.com/package/dsh-skills-anywhere)\n[![dsh plugin](https://img.shields.io/badge/dsh-plugin-blue)](https://github.com/topics/dsh-plugin)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/noteflowai/dsh-skills-anywhere/badge)](https://scorecard.dev/viewer/?uri=github.com/noteflowai/dsh-skills-anywhere)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\nAgent Skills are portable by design: a folder with a `SKILL.md`. Every agent still looks only in its own folder, so a skill you install for Claude Code is invisible to Codex, Cursor and DeepSeek Harness, and the ones you wrote for them are invisible back. `dsh-skills-anywhere` reads all of those folders where they live and serves them everywhere: as a live skill provider inside dsh, and as an MCP server for Claude Code, Cursor, Codex and any other MCP client.\n\n<p align=\"center\"><img src=\"docs/demo.gif\" alt=\"dsh-skills-anywhere list finds skills from Claude Code, Codex, Cursor, Gemini CLI, Goose, Windsurf and Kiro, then adds anthropics/skills from GitHub\" width=\"880\"></p>\n\nInside dsh, it registers one extra provider on the built-in `ctx.skills` registry, so the model's normal `skill` tool and `/name` invocation simply see more skills:\n\n- **Every other agent's skill directories.** 60+ agents out of the box: Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, Windsurf, Kiro, Goose, OpenCode, Roo, Cline, Qwen Code, Trae and more. Project-level and user-level.\n- **Claude Code plugin marketplaces.** The skills nested inside `~/.claude/plugins/marketplaces/*/plugins/*/skills/*`, including the official Anthropic marketplace.\n- **Any git repository full of skills.** Point at `anthropics/skills`, a sub-directory, a branch, a tag, or a commit. It is shallow-cloned into a local cache, refreshed in the background, and pinned in a lock file.\n- **Zero copies, zero symlinks.** Files are read where they live and re-read on every load. Edit a skill in Cursor and dsh sees the change. Nothing to import, nothing to keep in sync.\n\nHundreds of skills would bloat every model request, so the provider keeps a **catalog budget**: at most 50 skills enter the model's session catalog by default, and the rest stay one `find_skills` call away through two small tools the plugin adds, with `/name` invocation untouched.\n\nThe same pool is available **outside dsh** too: `dsh-skills-anywhere mcp` serves it to any [MCP](https://modelcontextprotocol.io) client (Claude Code, Cursor, Codex, Windsurf…) as `find_skills` / `open_skill` tools and `skill://` resources, so one install of a skill reaches every agent you use.\n\nIt also **deduplicates** symlinked and byte-identical installs (the `skills` CLI links one canonical copy into several agents), **repairs** common frontmatter drift instead of silently dropping a skill, and **renames** colliding names (`discord/configure` vs `telegram/configure`) so every skill stays reachable. A small CLI shows you exactly what dsh will see and why.\n\n## Quick start\n\n```sh\n# 1. Install into the dsh profile you use (web is the default UI profile)\ndsh plugin --profile web add dsh-skills-anywhere\n\n# 2. See what the model will get, without booting dsh\nnpx dsh-skills-anywhere list\n\n# 3. Add a whole repository of skills\nnpx dsh-skills-anywhere add anthropics/skills\n```\n\nPublished on [npm](https://www.npmjs.com/package/dsh-skills-anywhere) with build provenance; every [GitHub release](https://github.com/noteflowai/dsh-skills-anywhere/releases) also carries the same tarball.\n\nStart dsh as usual. The skill catalog now includes everything above; load a skill with the `skill` tool or `/skill-name` exactly as before.\n\nOn a machine with only Claude Code installed, `list` already finds the 31 skills inside the official plugin marketplace, none of which dsh sees on its own:\n\n```\n$ npx dsh-skills-anywhere list\nNAME                 FROM                                                    PATH\ndiscord-access       claude plugin discord @ claude-plugins-official         ~/.claude/plugins/marketplaces/.../discord/skills/access/SKILL.md\nfrontend-design      claude plugin frontend-design @ claude-plugins-official ~/.claude/plugins/marketplaces/.../frontend-design/skills/frontend-design/SKILL.md\nskill-creator        claude plugin skill-creator @ claude-plugins-official   ~/.claude/plugins/marketplaces/.../skill-creator/skills/skill-creator/SKILL.md\n...\n31 skills, 6 renamed — run `dsh-skills-anywhere doctor` for details\n```\n\n<details>\n<summary>Install from a git checkout or a release tarball instead of npm</summary>\n\nEvery [GitHub release](https://github.com/noteflowai/dsh-skills-anywhere/releases) carries a prebuilt tarball, and both `dsh plugin add` and `npx` accept its URL directly (`https://github.com/noteflowai/dsh-skills-anywhere/releases/download/v0.6.0/dsh-skills-anywhere-0.6.0.tgz`). If you want an unreleased commit:\n\n```sh\ndsh plugin --profile web add github:noteflowai/dsh-skills-anywhere\n```\n\nA git install ships sources, so pnpm has to run this package's `prepare` build. pnpm 10+ refuses until you allow it: the first `add` fails and prints the exact key to allow. Copy that key (it includes the commit) into the profile's `pnpm-workspace.yaml` and run the `add` again.\n\n```yaml\n# $DSH_HOME/profiles/web/pnpm-workspace.yaml\nallowBuilds:\n  'dsh-skills-anywhere@https://codeload.github.com/noteflowai/dsh-skills-anywhere/tar.gz/<sha>': true\n```\n\nPin a commit (`github:noteflowai/dsh-skills-anywhere#<sha>`) if you want the install to be reproducible.\n\n</details>\n\n<details>\n<summary>Requirements</summary>\n\n- DeepSeek Harness `0.1.5-rc.1` or newer (the suite runs against `0.1.5-rc.1` and `0.1.5-rc.2`), any profile that mounts `@deepseek-ai/dsh-skill` (the shipped `web`, `acp`, `headless` and `sdk` profiles all do)\n- Node.js 22.19+ or 24+\n- `git` on `PATH` for git sources (everything else works without it)\n\n</details>\n\n## What gets discovered\n\n| Where | Example | dsh source label | Default rank |\n|---|---|---|---|\n| Another agent's **project** skills | `<project>/.claude/skills/*` | `anywhere-project` | 250 |\n| Another agent's **user** skills | `~/.codex/skills/*`, `~/.cursor/skills/*` | `anywhere-user` | 550 |\n| **Claude Code plugin marketplaces** and the installed-plugin cache | `~/.claude/plugins/marketplaces/*/plugins/*/skills/*` | `anywhere-claude-plugins` | 580 |\n| **Git sources** | `anthropics/skills`, `vercel-labs/agent-skills/skills` | `anywhere-source` | 700 |\n\nLower rank wins a duplicate name inside the dsh registry. The built-in dsh roots keep their ranks (`.dsh/skills` 100, `.agents/skills` 200, `~/.dsh/skills` 400, `~/.agents/skills` 500), so a skill you wrote for dsh always beats the same name found elsewhere. `.agents/skills` and `.dsh/skills` are deliberately not re-scanned here.\n\nRun `npx dsh-skills-anywhere agents` for the full agent table and which directories exist on your machine.\n\n### Skill format\n\nAny directory with a `SKILL.md` following the [Agent Skills specification](https://agentskills.io/specification), plus dsh's flat `<name>.md` form. `name`, `description`, `license`, `compatibility`, `allowed-tools`, `metadata`, and dsh's `disable-model-invocation` / `user-invocable` are all understood. Unknown frontmatter (Claude Code's `argument-hint`, `context`, ...) is preserved under `metadata.frontmatter`. `scripts/`, `references/` and `assets/` are exposed through the skill's resource directory like any dsh skill.\n\nIn the default **lenient** mode a missing name falls back to the directory, an invalid name is normalised to kebab-case, and a missing description is derived from the first paragraph. Each repair is recorded and shown by `doctor`. Set `lenient: false` to match the strict behaviour of the built-in provider.\n\n## Git sources\n\n```sh\nnpx dsh-skills-anywhere add anthropics/skills                      # default branch\nnpx dsh-skills-anywhere add anthropics/skills@v1.0.0               # tag or branch\nnpx dsh-skills-anywhere add vercel-labs/agent-skills/skills        # sub-directory\nnpx dsh-skills-anywhere add https://github.com/o/r/tree/main/dir   # GitHub tree URL\nnpx dsh-skills-anywhere add git@gitlab.com:group/skills.git        # any git URL\nnpx dsh-skills-anywhere add ./local/skills-repo --project          # local repo, project-scoped\nnpx dsh-skills-anywhere add o/r --ref 3f2a9c1 --rank 300           # pin a commit, set precedence\n```\n\nSources come from three places, merged in this order: the plugin `config.sources`, the user file `~/.dsh/skills-anywhere/sources.json`, and the project file `<project>/.dsh/skills-anywhere.json` (commit it to share skills with your team). The CLI edits the last two.\n\nEach repository is shallow-cloned once into `~/.dsh/skills-anywhere/cache/<host>/<owner>/<repo>` (`<repo>@<ref>` when a branch, tag or commit is set, so several refs of one repository never share a checkout) and refreshed when dsh starts, every `syncIntervalMs` (6 hours by default), and whenever a sources file changes. The resolved commit of every source is written to `~/.dsh/skills-anywhere/lock.json`. Discovery only ever reads the cache, so a failed refresh means yesterday's skills, never an empty catalog. The catalog is invalidated as soon as a refresh brings changes; dsh never waits on the network.\n\n## Catalog budget and the `find_skills` / `open_skill` tools\n\ndsh publishes every model-invocable skill's name and description into the session, on every request. With marketplaces and a few git sources that is hundreds of lines of context. The provider therefore ranks its skills and marks only the first `catalog.limit` (default 50) as model-invocable; the remainder is published with model invocation off, which keeps it out of the catalog but still loadable by you with `/name`.\n\nTwo tools, registered by the `dsh-skills-anywhere/tools` row, make the hidden part reachable for the model:\n\n- **`find_skills(query, limit?)`** searches every skill by keyword (name, description, `whenToUse`, origin), catalog or not, and says which matches are listed.\n- **`open_skill(name)`** loads any skill by exact name, including ones the budget hid. Skills whose own frontmatter says `disable-model-invocation: true` are still refused, exactly as the built-in `skill` tool does.\n\n```yaml\n- id: skills-anywhere\n  config:\n    catalog:\n      limit: 30                       # 0 = unlimited (old behaviour)\n      pin: [frontend-design]          # always listed\n      hide: [example-skill]           # never listed, still searchable and /name-invocable\n- id: skills-anywhere-tools\n  config:\n    findLimit: 10\n```\n\nAuthor-disabled skills never count against the budget. Which skills stay listed follows the precedence order below, so project-level skills win over user-level, which win over marketplaces and git sources. The tools row needs the tool runtime (`ctx.tools`); in a profile without one it stays pending and the provider works alone.\n\n## CLI\n\n**Check before committing.** Run `npx -y dsh-skills-anywhere@0.6.0 check\nskills/example/SKILL.md --fail-on-repair`. The same parser used in the playground\nnow has batch file checks, JSON reports with file hashes, and CI exit codes.\nChecks read only the named files. [Commands, CI example and scope](docs/CHECKING.md).\n\n```\ndsh-skills-anywhere list [--all] [--json]     Skills the provider publishes (--all shows hidden duplicates)\ndsh-skills-anywhere agents [--json]           Supported agents and which directories exist here\ndsh-skills-anywhere sources [--json]          Configured git sources and their synced commits\ndsh-skills-anywhere add <source> [--ref] [--path] [--rank] [--project]\ndsh-skills-anywhere remove <source> [--project]\ndsh-skills-anywhere sync [--force] [--json]   Clone or refresh every source now\ndsh-skills-anywhere doctor [--json]           Repaired, skipped, renamed and duplicate skills, with reasons\ndsh-skills-anywhere check <files...> [--json] Explicit local files; strict parser gate by default\ndsh-skills-anywhere mcp                       Serve the same skills to any MCP client over stdio\n```\n\nAll commands accept `--cwd <dir>`. For `check`, it resolves the named files; other\ncommands use it to pick the project. `check --lenient` accepts provider repairs;\n`--fail-on-repair` rejects any reported repair in the selected mode.\nThe CLI uses the same parsing code as the plugin and never needs dsh running.\n\n## Use as an MCP server\n\nSkills are not a dsh-only idea, and neither is this provider. `dsh-skills-anywhere mcp` starts a [Model Context Protocol](https://modelcontextprotocol.io) server over stdio that exposes the identical pool (agent directories, Claude Code marketplaces, git sources, same dedupe and rename rules) to any MCP client:\n\n| Tool | What it does |\n| --- | --- |\n| `list_skills` | Browse every model-invocable skill with its description and origin (`limit`, `offset`) |\n| `find_skills` | Keyword search across names, descriptions and origins |\n| `open_skill` | Load one skill's instructions plus the directory its scripts and references live in |\n\nSkills are also exposed as `skill://<name>` resources (with completion), for clients that let you @-mention resources. Skills whose frontmatter sets `disable-model-invocation: true` are never listed or opened. The server needs no dsh installation at all.\n\n**Claude Code** (as a plugin; this repo doubles as a plugin marketplace)\n\n```sh\nclaude plugin marketplace add noteflowai/dsh-skills-anywhere\nclaude plugin install dsh-skills-anywhere@noteflowai\n```\n\nOr register the bare server instead: `claude mcp add skills-anywhere -- npx -y dsh-skills-anywhere mcp`. Either way, restart Claude Code once so it connects.\n\n**Cursor** (`.cursor/mcp.json` or `~/.cursor/mcp.json`)\n\n```json\n{ \"mcpServers\": { \"skills-anywhere\": { \"command\": \"npx\", \"args\": [\"-y\", \"dsh-skills-anywhere\", \"mcp\"] } } }\n```\n\n**Codex** (`~/.codex/config.toml`)\n\n```toml\n[mcp_servers.skills-anywhere]\ncommand = \"npx\"\nargs = [\"-y\", \"dsh-skills-anywhere\", \"mcp\"]\n```\n\nThe server is also listed in the [official MCP registry](https://registry.modelcontextprotocol.io) as `io.github.noteflowai/dsh-skills-anywhere`, so registry-aware clients can install it by name. The repository is also an [Agent Plugin](https://agent-plugins.org) (`plugin.json` + `mcp.json` at the root), so Cursor and other open-plugin clients can install it from the repository URL. Add `--cwd <dir>` when the client does not start the server inside the project you are working on. Git sources sync in the background on start, exactly as in dsh. Programmatic use: `import { createSkillsAnywhereServer } from 'dsh-skills-anywhere/mcp'` returns the `McpServer` and the provider so you can attach your own transport.\n\n## Browse and toggle skills in the dsh web UI\n\nIn `dsh web`, open **Settings → Plugins → Plugin configuration**. The **Skills Anywhere** card lists every skill the provider found, grouped by where it lives (agent directories, Claude Code plugins, git sources), with its catalog state — *listed* for the model, *not listed* (kept out by the budget or by you) or *author disabled* — and the name it was renamed to when it collided. Each row offers **Pin** (always listed), **Hide** (out of the model catalog, still `/name`- and `find_skills`-reachable) and **Exclude** (dropped from the provider); the catalog budget is editable in place, and a filter box searches names, descriptions and origins.\n\n<p align=\"center\"><img src=\"docs/web-card.png\" alt=\"The Skills Anywhere card in dsh web settings: skills grouped by origin with listed / not listed / author disabled states, renames, and Pin, Hide, Exclude actions\" width=\"720\"></p>\n\nEdits are written to the profile's dsh settings document as the `skills-anywhere` namespace, layered over `catalog` and `excludeSkills` from `cordis.patch.yml`, and the model catalog follows immediately: no restart, no file editing. The card only appears in profiles that mount dsh's settings service and web server (the shipped `web` profile does); everywhere else the provider behaves exactly as composed.\n\n## Configuration\n\nOverride the row in your profile's `cordis.patch.yml`. A patch replaces the whole `config` block, so restate every key you care about:\n\n```yaml\n- id: skills-anywhere\n  config:\n    agents: true\n    excludeAgents: [openclaw]\n    claudePlugins: true\n    sources:\n      - anthropics/skills\n      - { repo: vercel-labs/agent-skills, path: skills, ref: main, rank: 650 }\n    excludeSkills: [example-skill]\n```\n\n| Field | Default | Meaning |\n|---|---|---|\n| `providerName` | `skills-anywhere` | Provider name on `ctx.skills` |\n| `agents` | `true` | Scan other agents' skill directories |\n| `excludeAgents` | `[]` | Agent ids to skip (see `agents` command) |\n| `extraProjectDirs` | `[]` | Additional project-relative skill directories |\n| `extraUserDirs` | `[]` | Additional absolute or `~/` skill directories |\n| `claudePlugins` | `true` | Scan Claude Code plugin marketplaces and cache |\n| `sources` | `[]` | Git sources: strings or `{ repo, ref?, path?, rank? }` |\n| `sourcesFiles` | `true` | Also read the user and project `sources.json` files |\n| `cacheDir` | `~/.dsh/skills-anywhere/cache` | Where sources are checked out |\n| `sync` | `true` | Clone and refresh git sources at all |\n| `syncOnStart` | `true` | Refresh when the plugin starts and on first use of a project |\n| `syncIntervalMs` | `21600000` | Background refresh interval; `0` disables |\n| `syncTimeoutMs` | `120000` | Per-git-command timeout |\n| `maxDepth` | `5` | Directory depth walked inside sources and marketplaces |\n| `dedupe` | `true` | Collapse symlinked and byte-identical duplicates |\n| `lenient` | `true` | Repair recoverable frontmatter instead of skipping |\n| `watch` | `true` | Watch local roots and refresh the catalog on change |\n| `excludeSkills` | `[]` | Skill names to hide (raw frontmatter name or the published name shown by `list`); editable at runtime from the web card |\n| `ranks` | `{ project: 250, user: 550, claudePlugins: 580, sources: 700 }` | Precedence per group |\n| `catalog.limit` | `50` | Skills from this provider listed in the model catalog; `0` = unlimited |\n| `catalog.pin` | `[]` | Names always listed |\n| `catalog.hide` | `[]` | Names never listed (still `/name`-invocable and searchable) |\n| `dshHome`, `home` | `$DSH_HOME` / `~` | Path roots, mainly for tests |\n\nThe `dsh-skills-anywhere/tools` row accepts `findLimit` (default 10), `findMaxLimit` (50), and `find` / `open` booleans to register only one tool.\n\n## How precedence and duplicates work\n\n1. Roots are scanned in rank order. Within one rank, the agent table order, then path.\n2. Entries pointing at the **same file** (symlinks) collapse to the first. Entries with the **same name and byte-identical body** collapse to the first. Both appear in `doctor` as hidden duplicates.\n3. Entries that still **share a name** but differ are all kept. If one of them is yours (an agent directory) it keeps the bare name and the others are prefixed with their plugin, repository, or agent (`telegram-configure`). If every member comes from a marketplace or a git source, all of them are prefixed, so you get `discord-access` and `telegram-access` rather than a meaningless bare `access`. `doctor` lists the renames.\n4. The dsh registry then merges this provider's candidates with the built-in ones by rank.\n\n## Security notes\n\n- The plugin **reads** skill files. It never writes to your agent directories.\n- Git sources run `git` on your machine at plugin start and on the refresh interval. Pin a commit for anything you do not fully trust, and review `lock.json`.\n- A skill is instructions the model will follow. Adding a source is a trust decision, exactly like installing a plugin.\n- Skills are read with Node's filesystem API, not through dsh's sandboxed `ctx.fs`; the built-in provider does the same for its bundled root.\n\n## Development\n\n```sh\npnpm install\npnpm run check        # typecheck + lint + tests + build\npnpm pack             # tarball for `dsh plugin --profile <name> add ./dsh-skills-anywhere-*.tgz`\n```\n\nTests run against the real `@deepseek-ai/dsh-skill` registry and real git repositories in temp directories.\n\n## Contributing\n\nIssues and pull requests are welcome. Adding an agent is a one-line change in [`src/agents.ts`](src/agents.ts). See [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\n[MIT](LICENSE) © Note Flow AI\n",
  "bytes": 21821,
  "sha": "87aad1ac32b752451aac960426aaa49e898925f108019b49a0ad21bf8600b4d0",
  "repo_slug": "noteflowai/dsh-skills-anywhere",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_noteflowai_dsh_skills_anywhere_99c996dd/readme"
}