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.
The SDK provides built-in support for the Model Context Protocol (MCP), allowing you to create custom tools that extend the AI’s capabilities.
What is MCP?
The Model Context Protocol is an open standard for connecting AI models to external tools and data sources. It enables:
Custom Tools : Create application-specific functionality
External APIs : Connect to third-party services
Data Sources : Access databases, file systems, and more
Process Isolation : Run tools in separate processes or in-process
MCP Server Types
The SDK supports two types of MCP servers:
SDK-Embedded Servers (Recommended)
Run in the same process as your application. No separate server process needed.
Benefits:
Simple setup - no process management
Direct access to your application’s state
Type-safe with Zod schema validation
Lower latency - no IPC overhead
Use cases:
Application-specific tools
Tools that need access to app state
Simple utility functions
import { z } from 'zod' ;
import { tool , createSdkMcpServer , query } from '@qwen-code/sdk' ;
const weatherTool = tool (
'get_weather' ,
'Get current weather for a city' ,
{ city: z . string () },
async ( args ) => ({
content: [{ type: 'text' , text: `Weather in ${ args . city } : Sunny, 72°F` }],
})
);
const server = createSdkMcpServer ({
name: 'weather' ,
tools: [ weatherTool ],
});
const result = query ({
prompt: 'What is the weather in San Francisco?' ,
options: {
mcpServers: { weather: server },
},
});
External Servers
Run as separate processes, connected via stdio, SSE, HTTP, or WebSocket.
Benefits:
Process isolation and security
Language agnostic - write servers in any language
Share servers across multiple SDK instances
Standard MCP protocol compliance
Use cases:
Complex server implementations
Shared services across applications
Third-party MCP servers
Security-sensitive operations
import { query } from '@qwen-code/sdk' ;
const result = query ({
prompt: 'Use the database tool' ,
options: {
mcpServers: {
database: {
command: 'node' ,
args: [ './mcp-servers/database-server.js' ],
env: { DB_CONNECTION: 'postgresql://...' },
},
},
},
});
Quick Start
Create your first SDK-embedded MCP server in 3 steps:
Step 1: Install Dependencies
npm install @qwen-code/sdk zod
import { z } from 'zod' ;
import { tool , createSdkMcpServer , query } from '@qwen-code/sdk' ;
// Define a calculator tool
const calculatorTool = tool (
'calculate_sum' ,
'Add two numbers together' ,
{
a: z . number (). describe ( 'First number' ),
b: z . number (). describe ( 'Second number' ),
},
async ( args ) => {
const result = args . a + args . b ;
return {
content: [{
type: 'text' ,
text: ` ${ args . a } + ${ args . b } = ${ result } ` ,
}],
};
}
);
// Create MCP server
const server = createSdkMcpServer ({
name: 'calculator' ,
version: '1.0.0' ,
tools: [ calculatorTool ],
});
// Use in query
const result = query ({
prompt: 'What is 42 + 17?' ,
options: {
permissionMode: 'yolo' ,
mcpServers: {
calculator: server ,
},
},
});
for await ( const message of result ) {
if ( message . type === 'assistant' ) {
console . log ( message . message . content );
}
}
Step 3: Run It
Architecture
SDK-Embedded Servers
┌─────────────────────────────────┐
│ Your Application │
│ ┌────────────────────────────┐ │
│ │ SDK Query Instance │ │
│ │ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ SDK MCP Server │ │ │
│ │ │ (In-process) │ │ │
│ │ │ - Tool handlers │ │ │
│ │ │ - Zod validation │ │ │
│ │ └─────────────────────┘ │ │
│ └────────────────────────────┘ │
└─────────────────────────────────┘
│
│ JSON Protocol
▼
┌─────────────────────────────────┐
│ Qwen CLI Process │
└─────────────────────────────────┘
External Servers
┌─────────────────────────────────┐
│ Your Application │
│ ┌────────────────────────────┐ │
│ │ SDK Query Instance │ │
│ └────────────────────────────┘ │
└─────────────────────────────────┘
│
│ JSON Protocol
▼
┌─────────────────────────────────┐
│ Qwen CLI Process │
└─────────────────────────────────┘
│
│ MCP Protocol
│ (stdio/SSE/HTTP)
▼
┌─────────────────────────────────┐
│ External MCP Server │
│ (Separate Process) │
└─────────────────────────────────┘
Communication Flow
When the AI calls an MCP tool:
CLI requests tool execution : AI decides to use a tool and sends request to CLI
CLI routes to SDK : CLI identifies SDK-embedded server and sends control request
SDK invokes handler : SDK validates input and calls your tool handler
Handler returns result : Your function returns MCP-formatted result
SDK sends response : Result is sent back to CLI as control response
CLI forwards to AI : Tool result is included in the AI’s context
All tool handlers must return a CallToolResult object:
type CallToolResult = {
content : Array <
| { type : 'text' ; text : string }
| { type : 'image' ; data : string ; mimeType : string }
| { type : 'resource' ; uri : string ; mimeType ?: string ; text ?: string }
>;
isError ?: boolean ;
};
Text Response
return {
content: [{ type: 'text' , text: 'Operation successful' }],
};
Image Response
return {
content: [{
type: 'image' ,
data: base64ImageData ,
mimeType: 'image/png' ,
}],
};
Multiple Content Blocks
return {
content: [
{ type: 'text' , text: 'Here is the chart:' },
{ type: 'image' , data: chartData , mimeType: 'image/png' },
],
};
Error Response
return {
content: [{ type: 'text' , text: 'Failed to process request' }],
isError: true ,
};
Configuration Options
When connecting MCP servers to a query:
import { query , createSdkMcpServer } from '@qwen-code/sdk' ;
const result = query ({
prompt: 'Use my tools' ,
options: {
mcpServers: {
// SDK-embedded server
'my-server' : createSdkMcpServer ({
name: 'my-server' ,
tools: [ /* ... */ ],
}),
// External server (stdio)
'external-stdio' : {
command: 'node' ,
args: [ 'server.js' ],
env: { API_KEY: 'xxx' },
},
// External server (SSE)
'external-sse' : {
url: 'http://localhost:3000/sse' ,
},
// External server (HTTP)
'external-http' : {
httpUrl: 'http://localhost:3000/mcp' ,
headers: { 'Authorization' : 'Bearer token' },
},
},
},
});
Timeout Configuration
Configure timeouts for MCP operations:
options : {
mcpServers : { /* ... */ },
timeout : {
mcpRequest : 600000 , // 10 minutes for long-running tools
},
}
Best Practices
const simpleTool = tool (
'get_time' ,
'Get current time' ,
{},
async () => ({
content: [{ type: 'text' , text: new Date (). toISOString () }],
})
);
2. Use External Servers for Complex Operations
options : {
mcpServers : {
database : {
command : 'node' ,
args : [ 'database-server.js' ],
},
},
}
const tool = tool (
'create_user' ,
'Create a new user' ,
{
email: z . string (). email (),
age: z . number (). min ( 0 ). max ( 120 ),
},
async ( args ) => {
// args.email is validated email
// args.age is validated number
}
);
4. Handle Errors Gracefully
const tool = tool (
'risky_operation' ,
'Perform a risky operation' ,
{ input: z . string () },
async ( args ) => {
try {
const result = await performOperation ( args . input );
return {
content: [{ type: 'text' , text: result }],
};
} catch ( error ) {
return {
content: [{
type: 'text' ,
text: `Error: ${ error . message } ` ,
}],
isError: true ,
};
}
}
);
5. Provide Clear Descriptions
const tool = tool (
'search_docs' ,
'Search technical documentation using semantic search. Returns relevant excerpts.' ,
{
query: z . string (). describe ( 'Search query (natural language)' ),
limit: z . number (). default ( 5 ). describe ( 'Maximum number of results' ),
},
async ( args ) => { /* ... */ }
);
Next Steps
tool() Function Learn how to create tools
createSdkMcpServer() Create MCP server instances
MCP Examples Complete working examples
External MCP Servers Connect to external servers