content/providers/03-community-providers/26-mcp-sampling.mdx
The MCP Sampling AI Provider allows MCP servers to use AI models through the AI SDK by leveraging your existing client subscriptions (like VS Code Copilot). This transforms your MCP server into an agentic tool that can reason and make decisions, without requiring separate API keys or subscriptions.
The provider implements LanguageModelV4 by forwarding requests through MCP's sampling feature to the MCP client, offering unique advantages:
generateText, streamText, structured output with Output, and experimental tool callingLearn more about MCP Sampling in the MCP Specification.
Warning: This provider has specific requirements:
See the full list of MCP clients for more options.
Alternative: Use setupClientSampling() to add sampling to any MCP client (see example below).
The MCP Sampling AI Provider is available in the @mcpc-tech/mcp-sampling-ai-provider module. You can install it with:
<Tabs items={['pnpm', 'npm', 'yarn', 'bun', 'deno']}> <Tab> <Snippet text="pnpm add @mcpc-tech/mcp-sampling-ai-provider" dark /> </Tab> <Tab> <Snippet text="npm install @mcpc-tech/mcp-sampling-ai-provider" dark /> </Tab> <Tab> <Snippet text="yarn add @mcpc-tech/mcp-sampling-ai-provider" dark /> </Tab> <Tab> <Snippet text="bun add @mcpc-tech/mcp-sampling-ai-provider" dark /> </Tab> <Tab> <Snippet text="deno add jsr:@mcpc/mcp-sampling-ai-provider" dark /> </Tab> </Tabs>
To create an MCP Sampling provider instance, use the createMCPSamplingProvider function with your MCP server instance:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
// Create an MCP server with sampling capability
const server = new Server(
{ name: 'my-agent', version: '1.0.0' },
{ capabilities: { sampling: {}, tools: {} } },
);
const provider = createMCPSamplingProvider({ server });
The provider accepts the following configuration:
server MCP Server instance
An MCP Server instance that has sampling capability enabled.
Create a language model instance using the languageModel() method:
const model = provider.languageModel({
modelPreferences: {
hints: [{ name: 'gpt-5-mini' }],
costPriority: 0.5,
speedPriority: 0.8,
intelligencePriority: 0.9,
},
});
The languageModel() method accepts optional model preferences:
hints Array<{ name: string }>
Array of model name hints (e.g., [{ name: "gpt-5-mini" }]). These suggest preferred models to the MCP client.
costPriority number (0-1)
Higher values prefer cheaper models. Default is 0.
speedPriority number (0-1)
Higher values prefer faster models. Default is 0.
intelligencePriority number (0-1)
Higher values prefer more capable models. Default is 0.
See MCP Model Preferences for more details.
generateTextGenerate text using the MCP Sampling Provider in an MCP server tool:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateText } from 'ai';
// Create MCP server with sampling capability
const server = new Server(
{ name: 'translator', version: '1.0.0' },
{ capabilities: { sampling: {}, tools: {} } },
);
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'translate',
description: 'Translate text to a target language using AI',
inputSchema: {
type: 'object',
properties: {
text: {
type: 'string',
description: 'The text to translate',
},
target_lang: {
type: 'string',
description: 'The target language (e.g., "Spanish", "French")',
},
},
required: ['text', 'target_lang'],
},
},
],
};
});
// Register a translation tool that uses AI
server.setRequestHandler(CallToolRequestSchema, async request => {
if (request.params.name === 'translate') {
// Create provider from the server
const provider = createMCPSamplingProvider({ server });
// Use AI SDK to translate text
const { text } = await generateText({
model: provider.languageModel({
modelPreferences: { hints: [{ name: 'gpt-5-mini' }] },
}),
prompt: `Translate to ${request.params.arguments?.target_lang}: ${request.params.arguments?.text}`,
});
return { content: [{ type: 'text', text }] };
}
});
// Connect and start
const transport = new StdioServerTransport();
await server.connect(transport);
streamTextStream text responses using the MCP Sampling Provider:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { streamText } from 'ai';
const server = new Server(
{ name: 'ai-assistant', version: '1.0.0' },
{ capabilities: { sampling: {}, tools: {} } },
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'generate-story',
description: 'Generate a story or poem using AI',
inputSchema: {
type: 'object',
properties: {},
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async request => {
if (request.params.name === 'generate-story') {
const provider = createMCPSamplingProvider({ server });
const result = streamText({
model: provider.languageModel({
modelPreferences: {
hints: [{ name: 'gpt-5-mini' }],
speedPriority: 0.9,
},
}),
prompt: 'Write a short poem about coding.',
});
const text = await result.text;
return { content: [{ type: 'text', text }] };
}
});
const transport = new StdioServerTransport();
await server.connect(transport);
Generate structured objects using the MCP Sampling Provider:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateText, Output } from 'ai';
import { z } from 'zod';
const server = new Server(
{ name: 'recipe-generator', version: '1.0.0' },
{ capabilities: { sampling: {}, tools: {} } },
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'generate-recipe',
description: 'Generate a recipe using AI',
inputSchema: {
type: 'object',
properties: {},
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async request => {
if (request.params.name === 'generate-recipe') {
const provider = createMCPSamplingProvider({ server });
const recipeSchema = z.object({
recipe: z.object({
name: z.string(),
cuisine: z.string(),
ingredients: z.array(z.string()),
steps: z.array(z.string()),
}),
});
const { output } = await generateText({
model: provider.languageModel({
modelPreferences: { hints: [{ name: 'gpt-5-mini' }] },
}),
output: Output.object({ schema: recipeSchema }),
prompt: 'Generate a delicious lasagna recipe.',
});
return {
content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
};
}
});
const transport = new StdioServerTransport();
await server.connect(transport);
Use tools with the MCP Sampling Provider. Note: This is implemented via system prompt and may not be as reliable as native tool support:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateText } from 'ai';
import { z } from 'zod';
const server = new Server(
{ name: 'weather-agent', version: '1.0.0' },
{ capabilities: { sampling: {}, tools: {} } },
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'ask-weather',
description: 'Ask a weather-related question',
inputSchema: {
type: 'object',
properties: {
question: {
type: 'string',
description: 'The weather question to ask',
},
},
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async request => {
if (request.params.name === 'ask-weather') {
const provider = createMCPSamplingProvider({ server });
const result = await generateText({
model: provider.languageModel({
modelPreferences: { hints: [{ name: 'gpt-5-mini' }] },
}),
tools: {
getWeather: {
description: 'Get the weather for a location',
parameters: z.object({
city: z.string().describe('The city name'),
}),
execute: async ({ city }) => {
return `The weather in ${city} is sunny and 72°F`;
},
},
},
prompt:
request.params.arguments?.question ||
'What is the weather in San Francisco?',
maxSteps: 5,
});
return { content: [{ type: 'text', text: result.text }] };
}
});
const transport = new StdioServerTransport();
await server.connect(transport);
See the examples directory for more complete working examples:
If your MCP client doesn't support sampling natively, you can add sampling capability using setupClientSampling with model preferences:
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import {
convertAISDKFinishReasonToMCP,
selectModelFromPreferences,
setupClientSampling,
} from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateText } from 'ai';
const client = new Client(
{ name: 'my-client', version: '1.0.0' },
{ capabilities: { sampling: {} } },
);
setupClientSampling(client, {
handler: async params => {
const modelId = selectModelFromPreferences(params.modelPreferences, {
hints: {
'gpt-5': 'openai/gpt-5-mini',
'gpt-mini': 'openai/gpt-5-mini',
},
priorities: {
speed: 'openai/gpt-5-mini',
intelligence: 'openai/gpt-5-mini',
},
default: 'openai/gpt-5-mini',
});
const result = await generateText({
model: modelId,
messages: params.messages,
});
return {
model: modelId,
role: 'assistant',
content: { type: 'text', text: result.text },
stopReason: convertAISDKFinishReasonToMCP(result.finishReason),
};
},
});
const transport = new StdioClientTransport({
command: 'npx',
args: ['-y', 'example_mcp_server.ts'],
});
await client.connect(transport);
See the complete example for more details.
The request flow is straightforward:
sampling/createMessage formatThe MCP client (e.g., VS Code, Claude Desktop) decides which actual model to use based on the provided modelPreferences.
doGenerate first, then emits the complete response as stream events