Skip to main content

kimi-sync

Sync this repo with the latest Kimi official skills. Prefer the agent's built-in browser, then fall back to Playwright MCP or another browser MCP. Run this skill whenever you need to pull new or updated skills from kimi.com.

Source facts

Repository
haomingz/kimi-skills
Last source activity
September 26, 2026 at 18:52
Detected SKILL.md language
English
Stars
17
Forks
4

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
kimi-sync
description
Sync this repo with the latest Kimi official skills. Prefer the agent's built-in browser, then fall back to Playwright MCP or another browser MCP. Run this skill whenever you need to pull new or updated skills from kimi.com.
# Kimi Skills Sync Sync this repo with the skills listed on kimi.com. Drive the Kimi web UI from a browser, then use the local Python scripts to audit names and extract zips. ## Choose a browser Use the first backend that actually exists in this session. Do not require Playwright when a built-in browser is available. 1. **Built-in agent browser (preferred).** Examples: Cursor `cursor-ide-browser` (`browser_navigate`, `browser_snapshot`, `browser_lock`, `browser_click`, `browser_cdp`). This profile is separate from the user's everyday Chrome. If kimi.com is not logged in, unlock the browser and ask the user to log in, then continue. 2. **Playwright MCP.** Use it only when no built-in browser tools are available. - **`--extension` mode:** tools named `mcp__playwright__browser_*`. Drives the user's logged-in Chrome. Downloads land in the normal Chrome Downloads folder. - **Isolated mode:** tools may be named `mcp__plugin_playwright_playwright__browser_*`. Log into kimi.com in that browser. Downloads land in Playwright's output dir (for example `<repo>\.playwright-mcp\`). 3. **Any other browser MCP** that can navigate and evaluate JavaScript in the page. Treat it like the closest of the two backends above. If none of these exist, stop and tell the user. Python 3 (via `uv`) and `scripts/` are also required. ### Running page JavaScript | Backend | How | |---------|-----| | Built-in browser | `browser_cdp` → `Runtime.evaluate`. Set `returnByValue: true`. For async scripts set `awaitPromise: true` and pass an invoked expression: `"(async () => { ... })()"`. There is no `browser_evaluate`. | | Playwright or similar | `browser_evaluate`, passing the script as the `function` argument. Prefix the tool with the namespace that is actually connected. | Lock a built-in browser before a long run (`browser_lock`) and unlock it when you stop or when the user must log in. CDP download, cookie, and filesystem commands are often denied on a built-in browser. Do not depend on its download folder. ## Step 1 — Open the Skills page ``` browser_navigate(url="https://www.kimi.com/skills") ``` `https://www.kimi.com/extensions?tab=skill` currently redirects away from the catalog. If you land on Plugins, click the **Skills** / **技能** tab (`button.top-tab`). Dismiss a promo dialog if one covers the page. Then confirm the grid: ``` () => ({ cards: document.querySelectorAll('.skill-card-title').length, href: location.href }) ``` You want `cards` > 0. Zero cards on a logged-out page means you should ask the user to log in. Zero cards while logged in usually means the Skills tab is not selected. ## Step 2 — Scrape the current skill list Each category first renders about 10 cards. Click every `button.skill-section-overflow` ("View … more"), wait ~700 ms, and repeat until none remain (cap about 25 rounds). `scripts/kimi-list.js` does this, then scrolls and returns a comma-separated name list. - Built-in browser: `Runtime.evaluate` the file as `"(<contents of scripts/kimi-list.js>)()"` with `awaitPromise: true`. - Playwright: pass the file contents as `browser_evaluate`'s `function`. If the result is `null`, the Skills tab is not open — go back to Step 1. ## Step 3 — Audit local vs remote names ```bash uv run python scripts/kimi-audit.py --kimi-names "<comma-separated names from Step 2>" ``` - Missing names must be downloaded. - "Local only" entries were removed from the page. Leave them unless the user asks to prune. - "All Kimi skills are present locally" does **not** finish the sync. Continue to Step 4 and compare file contents. ## Step 4 — Compare file contents For every remote skill that already has a `skills/<name>/` directory, compare the live file tree with the local files. On the logged-in page: 1. Read `document.querySelector('#app').__vue_app__._context.provides`. 2. Use the `VUE_QUERY_CLIENT` cache. Take the successful `skills` / `skillSections` query that has data. A pending query whose user id is null is the logged-out one. 3. Find the provide object that has `getSkillFileTree`. 4. Collect skill ids from installed skills plus each section's `skills` and `overflowSkills`. 5. `await model.getSkillFileTree({ skillId })`. **Omit `versionNo`.** Passing `versionNo: 1` returns an internal error. The result is `{ downloadUrl, skillFileTree }`. Nodes have `name`, `isDir`, `size`, and `children`. Walk the tree to relative paths and byte sizes. Compare with `skills/<name>/`. Skip `.git` and `__pycache__`. If the only size gap equals the number of LF newlines, the files differ by CRLF versus LF — treat them as unchanged. Any other path or size difference means the skill should be replaced. Keep the signed `downloadUrl` for skills that need a download. A GET of that URL returns a zip and does not need browser cookies. Zip entries are paths inside the skill directory (`SKILL.md`, not `<name>/SKILL.md`). Fetch trees with a small concurrency (about 4). One internal error should be retried once without `versionNo`. ## Step 5 — Download missing and changed skills **Preferred on every backend, and required for the built-in browser:** download the signed zip with `curl` or Python, reject entries that are absolute or contain `..`, delete `skills/<name>/`, and extract into that directory. This is the same replace behavior as `scripts/kimi-extract.py`. **Menu-click fallback** (Playwright, or a browser that can save downloads) when a signed URL is unavailable: 1. Set targets: `() => { window._kimiTargets = ["skill-a", "skill-b"]; return 'ok'; }` 2. Run the whole of `scripts/kimi-download.js`. It returns `'started'` and downloads inside the page. For each skill it finds `.skill-card`, clicks **Add** / **Install** / **安装** when that is the primary button (`.skill-card-btn` or `.skill-card-use-btn`), opens `.skill-more-btn`, and clicks **Download** / **下载** (`.kimi-menu-item` or `.skill-menu-item`). 3. Keep the built-in 5.5 s gap. Do not reduce it. 4. If Chrome asks to allow multiple downloads, or a JS dialog appears, accept it (`browser_handle_dialog` on Playwright). 5. Poll `() => ({ done: window._kimiDLDone, log: window._kimiDLLog, error: window._kimiDLError })` about every 10 seconds until `done` is true. Retry names with `ok: false`. 6. Extract: ```bash # Extension mode, or any download that landed in the real Downloads folder uv run python scripts/kimi-extract.py # Isolated Playwright uv run python scripts/kimi-extract.py --downloads-dir "<playwright output dir, e.g. .playwright-mcp>" ``` ## Step 6 — Verify and commit Run the name audit again with the same list from Step 2. Re-check byte sizes for every skill you replaced. When the user asked to sync the repo, commit the skill changes: ```bash git add skills git commit -m "Sync Kimi skills $(date +%Y-%m-%d)" ``` Do not commit unrelated files. Report the remote count, what was added or updated, what was unchanged, and any skills that still failed. Mention local-only names and leave them in place. ## Reference scripts | File | Purpose | |------|---------| | `scripts/kimi-list.js` | Expand category overflow, then scrape `.skill-card-title` | | `scripts/kimi-download.js` | Menu download fallback (⋯ → Download / 下载) | | `scripts/kimi-audit.py` | Diff local skill directory names against the Kimi list. Excludes the 9 kimi-cli skills | | `scripts/kimi-extract.py` | Unzip downloads into `skills/`, keeping the newest `skill (N).zip` | ## Current Kimi UI selectors (2026) If scraping breaks, re-derive these on `https://www.kimi.com/skills`: | Element | Selector | |---------|----------| | Skills tab (when the page opens on Plugins) | `button.top-tab` (text Skills / 技能) | | Category chips | `.carousel-scroll button` (Added, Featured, Productivity, …) | | Skill card | `.skill-card` | | Skill name | `.skill-card-title` | | Scroll host | `main.skill-page` | | Section overflow ("View … more") | `button.skill-section-overflow` | | Add / Use button | `.skill-card-use-btn` or `.skill-card-btn` (Add / Install / 安装, or Use / 使用) | | More (⋯) button | `.skill-more-btn` | | More-menu items | `.kimi-menu-item` or `.skill-menu-item` (Use / Edit / Download / Delete, or 使用 / 编辑 / 下载 / 删除) |
View on GitHub