How to Create Custom Skills for Kimi Code: A Complete Developer's Guide

You create custom skills for Kimi Code by authoring Markdown files with YAML front matter defining a name and description, storing them in project-specific skills/ directories or the user-wide ~/.kimi-code/skills/ folder, and invoking them via slash commands or the Node SDK.

Kimi Code, the open-source AI coding agent developed by MoonshotAI, extends LLM capabilities through reusable prompting logic called "skills." Creating custom skills for Kimi Code allows you to encapsulate repetitive tasks, specific linting workflows, or project conventions into invocable commands that integrate seamlessly with the agent's session management.

Understanding the Skill Structure

In Kimi Code, a skill is formally defined by the SkillDefinition interface located in packages/agent-core/src/skill/types.ts. Each skill is a Markdown file containing a front-matter block with metadata and a body that serves as the prompt template.

The core structure includes:

  • name: The unique identifier used in slash commands (e.g., write-goal)
  • description: Human-readable summary displayed in the skill picker UI
  • content: The prompt template (the Markdown body sent to the LLM)
  • metadata: Optional settings including type, whenToUse, and invocation policies
  • source: Origin classification (project, user, extra, or builtin)

Where to Store Custom Skills

Kimi Code discovers skills from four distinct sources during session initialization. The SessionSkillRegistry.loadRoots() method in packages/agent-core/src/skill/registry.ts scans these locations:

  • Project: Place skills in <repo-root>/skills/ or any directory specified in the extra_skill_dirs configuration option. These are visible only to the current project.
  • User: Store personal skills in ~/.kimi-code/skills/ (or the path set via the KIMI_CODE_USER_SKILLS environment variable). These apply across all projects for a single user.
  • Extra: Additional directories passed via configuration, useful for admin-managed skill bundles.
  • Built-in: Reference templates provided by the engine in packages/agent-core/src/skill/builtin/ (e.g., write-goal.md, update-config.md).

Writing a Custom Skill Definition

Skills are Markdown files with YAML front matter. At minimum, you must specify name and description. Additional fields control invocation behavior:

  • type: Set to prompt (default, user-only) or inline (allows automatic model invocation)
  • disableModelInvocation: Set to true to prevent the LLM from calling the skill automatically
  • whenToUse: Human-readable hint describing the skill's purpose
---
name: lint-changed
description: Run ESLint on modified TypeScript files
type: prompt
disableModelInvocation: false
whenToUse: "When the repository contains uncommitted TypeScript changes"
---
Run the following command in the project root and capture the output:

```bash
npx eslint {{changedFiles}}

If ESLint reports errors, summarize them for the user and suggest fixes.


## How the Engine Discovers Skills

When a session starts, the registry executes `discoverSkills` (implemented in [`packages/agent-core/src/skill/scanner.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core/src/skill/scanner.ts)) to walk the configured skill roots. For each `*.skill.md` or `*.md` file with valid front matter, the scanner builds a `SkillDefinition` object.

The registry then indexes skills using `normalizeSkillName()` and stores them in a map keyed by the normalized name. If a skill belongs to a plugin, `indexPluginSkill()` additionally indexes it by plugin ID. This process is triggered during `SessionSkillRegistry.loadRoots()` at lines 41-58 of [`packages/agent-core/src/skill/registry.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core/src/skill/registry.ts).

## Activating and Using Custom Skills

### Via Slash Commands

Type `/` followed by the skill name and optional arguments:

/lint-changed src/**/*.ts


The `skill_activation` event defined in [`packages/protocol/src/events.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/protocol/src/events.ts) triggers the registry to resolve the skill name. The `expandSkillParameters` function in [`packages/agent-core/src/skill/parser.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core/src/skill/parser.ts) handles template substitution for placeholders like `{{changedFiles}}`.

### Programmatically with the Node SDK

Use the REST API endpoints exposed through the SDK:

```typescript
import { KimiHarness } from '@moonshot-ai/kimi-code-sdk';

async function runSkill() {
  const harness = await KimiHarness.create();
  const session = await harness.session('my-session-id');

  // List available skills
  const { skills } = await session.get('/v1/sessions/my-session-id/skills');
  console.log('Available:', skills.map(s => s.name));

  // Activate with arguments
  await session.post(
    `/v1/sessions/my-session-id/skills/${encodeURIComponent('lint-changed')}:activate`,
    { args: 'src/**/*.ts' }
  );
}

The SDK forwards requests to /v1/sessions/{id}/skills/{skill_name}:activate, which the server translates into a skill.activated event per the schema in packages/protocol/src/events.ts.

From a Plugin

If your skill belongs to a plugin, include an instructions field in the plugin manifest. When rendered, SessionSkillRegistry.renderSkillPrompt (lines 100-106 of packages/agent-core/src/skill/registry.ts) wraps these instructions in a <kimi-plugin-instructions> XML block, allowing the model to access plugin-specific guidance.

Summary

  • Skills are Markdown files with YAML front matter stored in project skills/, user ~/.kimi-code/skills/, or configured extra directories.
  • Discovery happens automatically via SessionSkillRegistry.loadRoots() and the scanner in packages/agent-core/src/skill/scanner.ts, which indexes skills by normalized name.
  • Control invocation behavior using type: inline for automatic model execution or disableModelInvocation: true to restrict skills to manual use.
  • Activate via slash commands (/skill-name args) or the REST API endpoint /v1/sessions/{id}/skills/{name}:activate.
  • Use built-in examples in packages/agent-core/src/skill/builtin/ as templates for your own implementations.

Frequently Asked Questions

What file extension should I use for Kimi Code skills?

Use .skill.md or standard .md files containing YAML front matter with at minimum a name and description field. The scanner in packages/agent-core/src/skill/scanner.ts automatically detects and parses these files from configured skill roots during session initialization.

Can I prevent the model from automatically invoking my skill?

Yes. Set disableModelInvocation: true in the skill's front matter. This restricts the skill to manual activation via slash commands or the Node SDK, ensuring the LLM never calls it automatically during conversation turns. Alternatively, use type: prompt (the default) instead of type: inline.

How do I pass dynamic values to a custom skill?

Include template placeholders like {{variableName}} in the Markdown body. When invoking via the SDK, pass arguments in the args field of the request body; for slash commands, append arguments after the command name. The expandSkillParameters function in packages/agent-core/src/skill/parser.ts handles the substitution at runtime.

Where can I find example skill templates?

Reference the built-in skills located in packages/agent-core/src/skill/builtin/. These working examples, including write-goal.md and update-config.md, demonstrate proper front matter structure, prompt templating conventions, and metadata configuration patterns.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →