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 createSdkMcpServer() function creates an MCP server instance that runs in the same process as your SDK application.
Import
import { createSdkMcpServer } from '@qwen-code/sdk';
import type { CreateSdkMcpServerOptions, McpSdkServerConfigWithInstance } from '@qwen-code/sdk';
Signature
function createSdkMcpServer(
options: CreateSdkMcpServerOptions
): McpSdkServerConfigWithInstance
Parameters
options
CreateSdkMcpServerOptions
required
Configuration options for the MCP server.
CreateSdkMcpServerOptions
Unique name for the MCP server. Used to identify the server in logs and error messages.createSdkMcpServer({
name: 'calculator',
// ...
})
Server version string. Used for compatibility and debugging.createSdkMcpServer({
name: 'my-server',
version: '2.1.0',
// ...
})
Array of tools created with the tool() function.createSdkMcpServer({
name: 'utilities',
tools: [timeTool, weatherTool, calculatorTool],
})
Return Value
McpSdkServerConfigWithInstance
A server configuration object that can be passed directly to the mcpServers option in query().{
type: 'sdk';
name: string;
instance: McpServer;
}
Examples
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';
const addTool = tool(
'add',
'Add two numbers',
{ a: z.number(), b: z.number() },
async (args) => ({
content: [{ type: 'text', text: String(args.a + args.b) }],
})
);
const server = createSdkMcpServer({
name: 'calculator',
tools: [addTool],
});
const result = query({
prompt: 'What is 5 + 3?',
options: {
permissionMode: 'yolo',
mcpServers: { calculator: server },
},
});
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';
const addTool = tool(
'add',
'Add two numbers',
{ a: z.number(), b: z.number() },
async (args) => ({
content: [{ type: 'text', text: String(args.a + args.b) }],
})
);
const subtractTool = tool(
'subtract',
'Subtract two numbers',
{ a: z.number(), b: z.number() },
async (args) => ({
content: [{ type: 'text', text: String(args.a - args.b) }],
})
);
const multiplyTool = tool(
'multiply',
'Multiply two numbers',
{ a: z.number(), b: z.number() },
async (args) => ({
content: [{ type: 'text', text: String(args.a * args.b) }],
})
);
const server = createSdkMcpServer({
name: 'calculator',
version: '1.0.0',
tools: [addTool, subtractTool, multiplyTool],
});
const result = query({
prompt: 'Calculate (5 + 3) * 2',
options: {
permissionMode: 'yolo',
mcpServers: { calculator: server },
},
});
Multiple Servers
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';
// Calculator server
const calculatorServer = createSdkMcpServer({
name: 'calculator',
tools: [
tool('add', 'Add numbers', {
a: z.number(), b: z.number()
}, async (args) => ({
content: [{ type: 'text', text: String(args.a + args.b) }],
})),
],
});
// Weather server
const weatherServer = createSdkMcpServer({
name: 'weather',
tools: [
tool('get_weather', 'Get weather for a city', {
city: z.string()
}, async (args) => ({
content: [{ type: 'text', text: `Weather in ${args.city}: Sunny` }],
})),
],
});
// Time server
const timeServer = createSdkMcpServer({
name: 'time',
tools: [
tool('get_time', 'Get current time', {}, async () => ({
content: [{ type: 'text', text: new Date().toISOString() }],
})),
],
});
const result = query({
prompt: 'What time is it and what is the weather in Paris?',
options: {
permissionMode: 'yolo',
mcpServers: {
calculator: calculatorServer,
weather: weatherServer,
time: timeServer,
},
},
});
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';
// State shared between tools
const storage = new Map<string, string>();
const setValueTool = tool(
'set_value',
'Store a key-value pair',
{ key: z.string(), value: z.string() },
async (args) => {
storage.set(args.key, args.value);
return {
content: [{ type: 'text', text: `Stored: ${args.key} = ${args.value}` }],
};
}
);
const getValueTool = tool(
'get_value',
'Retrieve a value by key',
{ key: z.string() },
async (args) => {
const value = storage.get(args.key);
if (value === undefined) {
return {
content: [{ type: 'text', text: `Key not found: ${args.key}` }],
isError: true,
};
}
return {
content: [{ type: 'text', text: value }],
};
}
);
const storageServer = createSdkMcpServer({
name: 'storage',
tools: [setValueTool, getValueTool],
});
const result = query({
prompt: 'Store my name as John, then retrieve it',
options: {
permissionMode: 'yolo',
mcpServers: { storage: storageServer },
},
});
Server with Async Operations
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';
const fetchTool = tool(
'fetch_url',
'Fetch content from a URL',
{ url: z.string().url() },
async (args) => {
try {
const response = await fetch(args.url);
const content = await response.text();
return {
content: [{
type: 'text',
text: `Content from ${args.url}:\n${content.slice(0, 500)}...`,
}],
};
} catch (error) {
return {
content: [{ type: 'text', text: `Failed to fetch: ${error.message}` }],
isError: true,
};
}
}
);
const httpServer = createSdkMcpServer({
name: 'http',
tools: [fetchTool],
});
Server with Environment Access
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';
const apiKeyTool = tool(
'check_api_key',
'Check if API key is configured',
{ service: z.string() },
async (args) => {
const envVar = `${args.service.toUpperCase()}_API_KEY`;
const hasKey = !!process.env[envVar];
return {
content: [{
type: 'text',
text: hasKey
? `API key for ${args.service} is configured`
: `API key for ${args.service} is NOT configured`,
}],
};
}
);
const envServer = createSdkMcpServer({
name: 'environment',
tools: [apiKeyTool],
});
Validation
The function validates that all tools have unique names:
import { tool, createSdkMcpServer } from '@qwen-code/sdk';
const tool1 = tool('duplicate', 'First tool', {}, async () => ({
content: [{ type: 'text', text: 'First' }],
}));
const tool2 = tool('duplicate', 'Second tool', {}, async () => ({
content: [{ type: 'text', text: 'Second' }],
}));
// This will throw an error:
// "Duplicate tool name 'duplicate' in MCP server 'my-server'"
const server = createSdkMcpServer({
name: 'my-server',
tools: [tool1, tool2],
});
Server Name Validation
Server name must be a non-empty string:
// ✅ Valid
createS dkMcpServer({ name: 'my-server', tools: [] })
createSdkMcpServer({ name: 'calculator-v2', tools: [] })
// ❌ Invalid - throws error
createS dkMcpServer({ name: '', tools: [] })
createSdkMcpServer({ name: null, tools: [] })
Error Handling
Creation Errors
try {
const server = createSdkMcpServer({
name: 'my-server',
tools: [/* invalid tools */],
});
} catch (error) {
console.error('Failed to create server:', error.message);
}
Tool errors are caught and returned to the AI:
const errorTool = tool(
'risky_operation',
'Perform a risky operation',
{ input: z.string() },
async (args) => {
// If this throws, it's caught and returned as an error
const result = await riskyOperation(args.input);
return { content: [{ type: 'text', text: result }] };
}
);
const server = createSdkMcpServer({
name: 'risky',
tools: [errorTool],
});
Better approach - handle errors explicitly:
const errorTool = tool(
'risky_operation',
'Perform a risky operation',
{ input: z.string() },
async (args) => {
try {
const result = await riskyOperation(args.input);
return { content: [{ type: 'text', text: result }] };
} catch (error) {
return {
content: [{ type: 'text', text: `Error: ${error.message}` }],
isError: true,
};
}
}
);
Server Capabilities
The MCP server automatically advertises its capabilities based on provided tools:
const server = createSdkMcpServer({
name: 'my-server',
tools: [tool1, tool2, tool3],
});
// Server instance has:
// - capabilities.tools = {} (indicates tool support)
// - Registered tool handlers for tool1, tool2, tool3
Usage in Queries
Direct Usage
const server = createSdkMcpServer({
name: 'utilities',
tools: [/* ... */],
});
const result = query({
prompt: 'Use the utility tools',
options: {
mcpServers: {
utilities: server, // Direct reference
},
},
});
Reuse Across Queries
const sharedServer = createSdkMcpServer({
name: 'shared',
tools: [/* ... */],
});
// Use in multiple queries
const query1 = query({
prompt: 'First task',
options: { mcpServers: { shared: sharedServer } },
});
const query2 = query({
prompt: 'Second task',
options: { mcpServers: { shared: sharedServer } },
});
Mixed with External Servers
const sdkServer = createSdkMcpServer({
name: 'sdk-tools',
tools: [/* SDK tools */],
});
const result = query({
prompt: 'Use both SDK and external tools',
options: {
mcpServers: {
// SDK-embedded server
'sdk-tools': sdkServer,
// External server
'external-db': {
command: 'node',
args: ['db-server.js'],
},
},
},
});
Best Practices
// ✅ Good - related tools in one server
const mathServer = createSdkMcpServer({
name: 'math',
tools: [addTool, subtractTool, multiplyTool, divideTool],
});
// ❌ Bad - unrelated tools mixed
const mixedServer = createSdkMcpServer({
name: 'utilities',
tools: [addTool, weatherTool, databaseTool, timeTool],
});
2. Use Descriptive Names
// ✅ Good
createS dkMcpServer({ name: 'weather-api', tools: [/* ... */] })
createS dkMcpServer({ name: 'database-queries', tools: [/* ... */] })
// ❌ Bad
createS dkMcpServer({ name: 'tools', tools: [/* ... */] })
createS dkMcpServer({ name: 'server1', tools: [/* ... */] })
3. Specify Versions
const server = createSdkMcpServer({
name: 'my-api',
version: '2.1.0', // Track version changes
tools: [/* ... */],
});
4. Keep Servers Focused
// ✅ Good - focused servers
const authServer = createSdkMcpServer({
name: 'auth',
tools: [loginTool, logoutTool, validateTokenTool],
});
const dataServer = createSdkMcpServer({
name: 'data',
tools: [queryTool, createTool, updateTool, deleteTool],
});
// ❌ Bad - monolithic server
const everythingServer = createSdkMcpServer({
name: 'everything',
tools: [
loginTool, logoutTool, queryTool, createTool,
weatherTool, calculatorTool, /* ... 20 more tools */
],
});
5. Initialize Once, Reuse
// ✅ Good - create once, use many times
const utilities = createSdkMcpServer({
name: 'utilities',
tools: [/* ... */],
});
function runQuery(prompt: string) {
return query({
prompt,
options: { mcpServers: { utilities } },
});
}
// ❌ Bad - recreate on every call
function runQuery(prompt: string) {
const utilities = createSdkMcpServer({ // Wasteful
name: 'utilities',
tools: [/* ... */],
});
return query({
prompt,
options: { mcpServers: { utilities } },
});
}
See Also