> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/QwenLM/qwen-code/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Extensions

> Step-by-step guide to creating your first Qwen Code extension

# Creating Your First Extension

This guide walks you through creating a complete Qwen Code extension from scratch. You'll learn how to set up the project structure, add an MCP server with custom tools, create commands, and configure everything properly.

## Prerequisites

Before starting, ensure you have:

* Qwen Code installed and working
* Node.js 20+ (if creating MCP servers)
* Basic understanding of TypeScript/JavaScript
* A text editor or IDE

## Quick Start: Using Templates

The fastest way to start is using the built-in templates:

```bash theme={null}
# List available templates
qwen extensions new --help

# Create from template
qwen extensions new my-extension mcp-server
```

Available templates:

* `mcp-server` - MCP server with example tools
* `commands` - Custom command examples
* `skills` - Skill examples
* `agent` - Subagent examples
* `context` - Context provider example

## Manual Setup

To create an extension manually:

### Step 1: Create the Extension Directory

```bash theme={null}
mkdir my-first-extension
cd my-first-extension
```

### Step 2: Create the Manifest File

Create `qwen-extension.json`:

```json theme={null}
{
  "name": "my-first-extension",
  "version": "1.0.0"
}
```

**Naming rules:**

* Use lowercase letters, numbers, and dashes only
* No spaces or underscores
* Must be unique among your installed extensions
* Directory name should match the `name` field

### Step 3: Add an MCP Server (Optional)

MCP servers provide tools the AI can use. Let's create a simple server.

#### Create Package Files

Create `package.json`:

```json theme={null}
{
  "name": "my-first-extension",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "build": "tsc"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.11.0",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@types/node": "^20.11.25",
    "typescript": "~5.4.5"
  }
}
```

Create `tsconfig.json`:

```json theme={null}
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist"
  },
  "include": ["server.ts"]
}
```

#### Create the MCP Server

Create `server.ts`:

```typescript theme={null}
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

const server = new McpServer({
  name: 'my-first-extension',
  version: '1.0.0',
});

// Register a simple tool
server.registerTool(
  'get_greeting',
  {
    description: 'Returns a greeting message',
    inputSchema: z.object({
      name: z.string().describe('Name to greet'),
    }).shape,
  },
  async ({ name }) => {
    return {
      content: [
        {
          type: 'text',
          text: `Hello, ${name}! Welcome to my extension.`,
        },
      ],
    };
  },
);

// Register a prompt
server.registerPrompt(
  'greeting-prompt',
  {
    title: 'Greeting Generator',
    description: 'Generate a creative greeting',
    argsSchema: {
      name: z.string(),
      style: z.enum(['formal', 'casual', 'funny']).optional(),
    },
  },
  ({ name, style }) => ({
    messages: [
      {
        role: 'user',
        content: {
          type: 'text',
          text: `Generate a ${style || 'friendly'} greeting for ${name}.`,
        },
      },
    ],
  }),
);

const transport = new StdioServerTransport();
await server.connect(transport);
```

#### Update the Manifest

Update `qwen-extension.json` to reference the MCP server:

```json theme={null}
{
  "name": "my-first-extension",
  "version": "1.0.0",
  "mcpServers": {
    "myServer": {
      "command": "node",
      "args": ["${extensionPath}${/}dist${/}server.js"],
      "cwd": "${extensionPath}"
    }
  }
}
```

**Variable substitution:**

* `${extensionPath}` - Full path to extension directory
* `${workspacePath}` - Current workspace directory
* `${/}` or `${pathSeparator}` - OS-specific path separator

#### Build the Server

```bash theme={null}
npm install
npm run build
```

This compiles `server.ts` to `dist/server.js`.

### Step 4: Add Custom Commands (Optional)

Create a commands directory:

```bash theme={null}
mkdir -p commands/utils
```

Create `commands/utils/summarize.md`:

```markdown theme={null}
---
description: Summarize the content of a file
---

Please provide a concise summary of the following file:

File: {{args}}

!{cat {{args}}}
```

Create `commands/search.md`:

```markdown theme={null}
---
description: Search for pattern and provide analysis
---

Search for: `{{args}}`

Results:
!{grep -r "{{args}}" . --include="*.ts" --include="*.js"}

Please analyze these search results and provide insights.
```

**Command naming:**

* Top-level files: `/search`
* Nested files: `/utils:summarize`
* If conflicts exist: `/my-first-extension.search`

### Step 5: Add a Skill (Optional)

Create a skill directory:

```bash theme={null}
mkdir -p skills/code-reviewer
```

Create `skills/code-reviewer/SKILL.md`:

```markdown theme={null}
---
name: code-reviewer
description: Performs thorough code reviews focusing on best practices, potential bugs, and improvements
license: MIT
---

# Code Reviewer Skill

This skill helps review code for quality, correctness, and maintainability.

## Review Focus Areas

### Code Quality
- Readability and clarity
- Naming conventions
- Code organization
- Documentation completeness

### Potential Issues
- Logic errors
- Edge cases not handled
- Performance concerns
- Security vulnerabilities

### Best Practices
- Design patterns
- SOLID principles
- Error handling
- Testing coverage

## Output Format

Provide reviews in this structure:

1. **Summary**: Overall assessment
2. **Strengths**: What's done well
3. **Issues**: Problems found (severity: critical/major/minor)
4. **Suggestions**: Specific improvements
5. **Examples**: Code snippets showing improvements
```

Update `qwen-extension.json`:

```json theme={null}
{
  "name": "my-first-extension",
  "version": "1.0.0",
  "mcpServers": { ... },
  "commands": "commands",
  "skills": "skills"
}
```

### Step 6: Add a Subagent (Optional)

Create an agents directory:

```bash theme={null}
mkdir agents
```

Create `agents/test-writer.md`:

```markdown theme={null}
---
name: test-writer
description: Specialized in writing comprehensive unit tests and test suites
color: green
tools:
  - Read
  - Write
  - Grep
  - Bash
modelConfig:
  model: qwen3-coder-plus
  temperature: 0.7
---

You are a testing specialist focused on creating high-quality test suites.

## Your Expertise

- Writing unit tests with proper coverage
- Creating integration tests
- Test-driven development (TDD)
- Mocking and stubbing strategies
- Testing edge cases and error conditions

## Testing Approach

1. **Understand the Code**: Read and analyze the implementation
2. **Identify Test Cases**: Consider normal, edge, and error cases
3. **Write Clear Tests**: Use descriptive names and arrange-act-assert pattern
4. **Ensure Coverage**: Test all critical paths and branches
5. **Use Best Practices**: Follow framework conventions and patterns

## Test Structure

For each function or module:
- Test the happy path
- Test boundary conditions
- Test error handling
- Test integration points
- Mock external dependencies

Always run tests after writing them to ensure they pass.
```

Update `qwen-extension.json`:

```json theme={null}
{
  "name": "my-first-extension",
  "version": "1.0.0",
  "mcpServers": { ... },
  "commands": "commands",
  "skills": "skills",
  "agents": "agents"
}
```

### Step 7: Add Context (Optional)

Create `QWEN.md`:

```markdown theme={null}
# My First Extension

This extension provides development tools and AI assistants.

## Available Tools

### get_greeting
Returns a greeting message. Use this when the user wants a friendly greeting.

Example: "Can you greet John?"

## Custom Commands

- `/search <pattern>` - Search codebase and analyze results
- `/utils:summarize <file>` - Summarize file contents

## Guidelines

- Always be helpful and concise
- Use tools when appropriate
- Provide code examples when explaining concepts
```

Update `qwen-extension.json`:

```json theme={null}
{
  "name": "my-first-extension",
  "version": "1.0.0",
  "contextFileName": "QWEN.md",
  "mcpServers": { ... },
  "commands": "commands",
  "skills": "skills",
  "agents": "agents"
}
```

### Step 8: Add Settings (Optional)

If your extension needs configuration, add settings:

```json theme={null}
{
  "name": "my-first-extension",
  "version": "1.0.0",
  "settings": [
    {
      "name": "API Key",
      "description": "Your API key for the external service",
      "envVar": "MY_EXTENSION_API_KEY",
      "sensitive": true
    },
    {
      "name": "Base URL",
      "description": "Base URL for API requests",
      "envVar": "MY_EXTENSION_BASE_URL",
      "sensitive": false
    }
  ],
  "contextFileName": "QWEN.md",
  "mcpServers": {
    "myServer": {
      "command": "node",
      "args": ["${extensionPath}${/}dist${/}server.js"],
      "cwd": "${extensionPath}",
      "env": {
        "API_KEY": "${MY_EXTENSION_API_KEY}",
        "BASE_URL": "${MY_EXTENSION_BASE_URL}"
      }
    }
  }
}
```

Settings are:

* Prompted during installation
* Stored securely (sensitive values in system keychain)
* Passed as environment variables to MCP servers
* Manageable via `qwen extensions settings` command

## Testing Your Extension

### Link for Development

Create a symlink to your extension for development:

```bash theme={null}
qwen extensions link .
```

This allows you to test changes without reinstalling. However, you'll need to restart Qwen Code sessions to see changes (except for runtime commands which hot-reload).

### Test the Extension

Restart Qwen Code and try:

```
# Test MCP tool
"Can you greet Alice?"

# Test command
/search "TODO"

# Test agent
/agents manage
# Select and interact with test-writer

# View skills
/skills
```

### Unlink When Done

To remove the symlink:

```bash theme={null}
qwen extensions uninstall my-first-extension
```

## Final Directory Structure

Your complete extension:

```
my-first-extension/
├── qwen-extension.json
├── package.json
├── tsconfig.json
├── server.ts
├── dist/
│   └── server.js              # Built by `npm run build`
├── QWEN.md
├── commands/
│   ├── search.md
│   └── utils/
│       └── summarize.md
├── skills/
│   └── code-reviewer/
│       └── SKILL.md
└── agents/
    └── test-writer.md
```

## Next Steps

* [Publishing Your Extension](/extensions/releasing) - Share with others
* [Best Practices](/extensions/best-practices) - Extension development guidelines
* [MCP Servers](/extensions/mcp-servers) - Deep dive into MCP development
* [Commands](/extensions/commands) - Advanced command features
* [Skills](/extensions/skills) - Creating effective skills
* [Agents](/extensions/agents) - Building powerful subagents
