Skip to main content

Overview

The Model Context Protocol (MCP) is an open standard that allows AI assistants to connect to external data sources and tools. Qwen Code supports MCP, enabling you to:
  • Add custom tools from MCP servers
  • Access external data (databases, APIs, filesystems)
  • Integrate services (GitHub, Slack, Jira, etc.)
  • Build extensions without modifying Qwen Code
  • Share tools across different AI assistants
MCP is an open standard by Anthropic. Learn more at modelcontextprotocol.io

Quick Start

Add an MCP Server

# Add filesystem server (stdio transport)
qwen mcp add filesystem npx -y @modelcontextprotocol/server-filesystem /path/to/directory

# Add GitHub server (stdio transport)
qwen mcp add github npx -y @modelcontextprotocol/server-github

# Add HTTP server
qwen mcp add my-api https://api.example.com/mcp --transport http

# Add SSE server
qwen mcp add events https://events.example.com/mcp --transport sse

List MCP Servers

# Command line
qwen mcp list

# Interactive mode
/mcp

Remove an MCP Server

qwen mcp remove github

MCP Transports

Qwen Code supports three MCP transport types:
Use for: Local processes, command-line tools
qwen mcp add myserver node /path/to/server.js
The server:
  • Runs as a subprocess
  • Communicates via stdin/stdout
  • Started on-demand
  • Stopped when Qwen Code exits
Example servers:
  • @modelcontextprotocol/server-filesystem
  • @modelcontextprotocol/server-github
  • @modelcontextprotocol/server-postgres
  • Custom Node.js/Python servers

Configuration

Settings File

MCP servers are configured in your settings:
// ~/.qwen/settings.json or .qwen/settings.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
      "env": {
        "NODE_ENV": "production"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      },
      "trust": true
    },
    "company-api": {
      "httpUrl": "https://api.company.com/mcp",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}",
        "X-Client-Id": "qwen-code"
      },
      "timeout": 30000
    },
    "events": {
      "url": "https://events.company.com/mcp",
      "headers": {
        "Authorization": "Bearer ${EVENTS_TOKEN}"
      }
    }
  }
}

Command Line Options

# Add with environment variables
qwen mcp add postgres \
  npx -y @modelcontextprotocol/server-postgres \
  -e DATABASE_URL="postgresql://localhost/mydb"

# Add with custom timeout
qwen mcp add slow-api \
  https://api.example.com/mcp \
  --transport http \
  --timeout 60000

# Add with headers
qwen mcp add auth-api \
  https://api.example.com/mcp \
  --transport http \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Client-Id: qwen"

# Add with description
qwen mcp add github \
  npx -y @modelcontextprotocol/server-github \
  --description "GitHub API integration for issues and PRs"

# Trust server (bypass approval prompts)
qwen mcp add trusted \
  npx -y @company/trusted-server \
  --trust

# Selectively enable tools
qwen mcp add github \
  npx -y @modelcontextprotocol/server-github \
  --include-tools "create_issue,list_issues"

# Exclude specific tools
qwen mcp add github \
  npx -y @modelcontextprotocol/server-github \
  --exclude-tools "delete_repository"

Using MCP Tools

Once configured, MCP tools are available to the AI:
> List all issues in the main repository

I'll use the GitHub MCP server to list issues...

✓ Executed: mcp_tool("github", "list_issues", {"repo": "owner/repo"})

Found 42 open issues:
1. Fix authentication bug (#123)
2. Add dark mode (#124)
...

Tool Discovery

The AI automatically discovers available tools:
# In interactive mode
/mcp
Shows:
  • Connected servers
  • Available tools from each server
  • Tool descriptions and parameters
  • Connection status

Manual Tool Invocation

You can request specific MCP tools:
> Use the GitHub server to create an issue titled "Add tests" with body "We need more test coverage"

✓ Executed: mcp_tool("github", "create_issue", {
  "title": "Add tests",
  "body": "We need more test coverage",
  "repo": "owner/repo"
})

Created issue #125

Approval and Security

First-Use Approval

By default, MCP tools require approval on first use:
? Allow MCP tool call?
  Server: github
  Tool: create_issue
  Args: { title: "Bug fix", ... }
  
  [Allow] [Reject] [Always Allow Server] [Always Allow Tool]
Choices:
  • Allow: Execute once
  • Reject: Skip this call
  • Always Allow Server: Trust all tools from this server
  • Always Allow Tool: Trust this specific tool

Trusted Servers

Mark servers as trusted to skip approval:
{
  "mcpServers": {
    "trusted-server": {
      "command": "...",
      "trust": true  // Skip approval for all tools
    }
  }
}
# Or via command line
qwen mcp add trusted npx -y @company/trusted-server --trust
Only trust MCP servers you control or from reputable sources. MCP tools can read/write files, make network requests, and execute code.

Tool Filtering

Limit which tools are available:
{
  "mcpServers": {
    "github": {
      "command": "...",
      "includeTools": ["list_issues", "create_issue", "comment_issue"],
      "excludeTools": ["delete_repository", "force_push"]
    }
  }
}
Purpose: Access files outside the workspace
qwen mcp add filesystem \
  npx -y @modelcontextprotocol/server-filesystem \
  /home/user/documents
Tools:
  • read_file - Read files
  • write_file - Write files
  • list_directory - List files
  • search_files - Search content
Use cases:
  • Access data directories
  • Read configuration files
  • Process documents
  • Manage assets
Purpose: GitHub API integration
export GITHUB_TOKEN="ghp_..."
qwen mcp add github \
  npx -y @modelcontextprotocol/server-github
Tools:
  • list_issues - List issues
  • create_issue - Create issues
  • comment_issue - Comment on issues
  • list_pull_requests - List PRs
  • create_pull_request - Create PRs
  • And many more…
Use cases:
  • Automate issue management
  • Create PRs from changes
  • Code review automation
  • Project management
Purpose: PostgreSQL database access
export DATABASE_URL="postgresql://localhost/mydb"
qwen mcp add postgres \
  npx -y @modelcontextprotocol/server-postgres
Tools:
  • query - Execute SQL queries
  • list_tables - List tables
  • describe_table - Get table schema
Use cases:
  • Data analysis
  • Schema exploration
  • Query generation
  • Data migration
Purpose: Slack integration
export SLACK_TOKEN="xoxb-..."
qwen mcp add slack \
  npx -y @modelcontextprotocol/server-slack
Tools:
  • send_message - Send messages
  • list_channels - List channels
  • search_messages - Search history
Use cases:
  • Send notifications
  • Automate workflows
  • Analyze conversations
  • Team communication

Building Custom MCP Servers

Node.js Example

// server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server({
  name: 'my-custom-server',
  version: '1.0.0',
});

// Register a tool
server.tool(
  'greet',
  'Greets a user by name',
  {
    name: {
      type: 'string',
      description: 'The name to greet',
    },
  },
  async ({ name }) => ({
    content: [
      {
        type: 'text',
        text: `Hello, ${name}! Welcome to my custom MCP server.`,
      },
    ],
  })
);

// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);
Build and use:
# Build
npx tsc server.ts

# Add to Qwen Code
qwen mcp add custom node /path/to/server.js

# Use it
> Greet Alice using the custom server

 Executed: mcp_tool("custom", "greet", {"name": "Alice"})

Hello, Alice! Welcome to my custom MCP server.

Python Example

# server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server

app = Server("my-python-server")

@app.tool(
    name="calculate",
    description="Performs a calculation"
)
async def calculate(expression: str) -> str:
    try:
        result = eval(expression)  # Be careful with eval!
        return f"Result: {result}"
    except Exception as e:
        return f"Error: {str(e)}"

if __name__ == "__main__":
    stdio_server(app)
Use:
qwen mcp add calc python /path/to/server.py

Advanced Features

Context Providers

MCP servers can provide context (not just tools):
// Server provides repository context
server.resource(
  'repo-info',
  'Information about the current repository',
  async () => ({
    content: [
      {
        type: 'text',
        text: 'Repository: owner/repo\nBranch: main\nLast commit: abc123',
      },
    ],
  })
);
Qwen Code automatically includes this context when relevant.

Prompts

MCP servers can provide reusable prompts:
server.prompt(
  'code-review',
  'Comprehensive code review template',
  async () => ({
    messages: [
      {
        role: 'user',
        content: [
          {
            type: 'text',
            text: 'Review this code for security, performance, and best practices.',
          },
        ],
      },
    ],
  })
);
Invoke MCP prompts:
# List prompts
/mcp

# Use a prompt (shown in UI as available commands)

Sampling

MCP servers can request AI completions:
// Inside a tool implementation
const response = await server.sample({
  messages: [
    {
      role: 'user',
      content: 'Explain this code briefly',
    },
  ],
  maxTokens: 100,
});
This allows MCP servers to use AI for their own logic.

Troubleshooting

Problem: MCP server fails to connect.Solutions:
  • Check command is correct: qwen mcp list shows command
  • Verify dependencies installed: npm list -g @modelcontextprotocol/server-*
  • Check environment variables are set
  • Look at debug logs: DEBUG=qwen:mcp qwen
  • Test server manually: npx @modelcontextprotocol/server-github --help
Problem: MCP tools don’t appear or can’t be used.Solutions:
  • Verify server is connected: /mcp
  • Check tool filtering: includeTools/excludeTools in config
  • Ensure server implements the tool correctly
  • Try removing and re-adding the server
Problem: MCP server can’t authenticate to external service.Solutions:
  • Check environment variables: echo $GITHUB_TOKEN
  • Verify token has correct permissions
  • Use ${VAR} syntax in settings for env var expansion
  • Check headers are correctly configured
Problem: MCP tool calls are very slow.Solutions:
  • Increase timeout: "timeout": 60000
  • Check server performance
  • Use HTTP transport for remote servers (not stdio)
  • Enable streaming responses if supported
Problem: MCP tool requires approval even when trusted.Solutions:
  • Set "trust": true in server config
  • Or use YOLO approval mode: --approval-mode yolo
  • Check persistent approvals: /permissions

Best Practices

  1. Start with stdio: Use stdio transport for local servers, HTTP for remote
  2. Set timeouts: Prevent hanging with reasonable timeout values
  3. Use environment variables: Don’t hardcode secrets in settings
  4. Filter tools: Only enable tools you need for security
  5. Trust carefully: Only set trust: true for servers you control
  6. Test separately: Verify MCP servers work outside Qwen Code first
  7. Version control: Commit project-level MCP configs (without secrets)
  8. Document setup: Create README for team members setting up MCP servers
  9. Monitor usage: Check logs if servers behave unexpectedly
  10. Update regularly: Keep MCP SDK and servers up to date

Examples

Database Analysis

# Setup
export DATABASE_URL="postgresql://localhost/myapp"
qwen mcp add db npx -y @modelcontextprotocol/server-postgres

# Use
qwen --prompt "Analyze the users table and suggest indexes"

GitHub Automation

# Setup  
export GITHUB_TOKEN="ghp_..."
qwen mcp add github npx -y @modelcontextprotocol/server-github

# Use
qwen --approval-mode yolo \
  --prompt "Create an issue for each TODO comment in the code"

Custom Integration

// company-server.ts - Custom MCP server for your company
import { Server } from '@modelcontextprotocol/sdk/server/index.js';

const server = new Server({ name: 'company-tools', version: '1.0.0' });

// Jira integration
server.tool('create_jira_ticket', 'Create a Jira ticket', {
  summary: { type: 'string' },
  description: { type: 'string' },
  priority: { type: 'string', enum: ['Low', 'Medium', 'High'] },
}, async (args) => {
  // Call Jira API
  const ticket = await jira.createIssue(args);
  return { content: [{ type: 'text', text: `Created ${ticket.key}` }] };
});

// Slack integration
server.tool('notify_team', 'Send Slack notification', {
  channel: { type: 'string' },
  message: { type: 'string' },
}, async (args) => {
  await slack.postMessage(args.channel, args.message);
  return { content: [{ type: 'text', text: 'Notification sent' }] };
});

// Deploy tool
server.tool('deploy', 'Deploy to environment', {
  environment: { type: 'string', enum: ['staging', 'production'] },
}, async (args) => {
  await deploy(args.environment);
  return { content: [{ type: 'text', text: `Deployed to ${args.environment}` }] };
});

// Start server
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
await server.connect(new StdioServerTransport());
# Add to Qwen Code
qwen mcp add company node /path/to/company-server.js

# Use
qwen --approval-mode yolo \
  --prompt "Fix the auth bug, create a Jira ticket for tracking, and notify the team"

Next Steps

MCP SDK Documentation

Learn to build custom MCP servers

Approval Modes

Control MCP tool permissions

Configuration

Advanced MCP configuration

Examples

Browse MCP server examples