Comparing Smithery and MCPSDK integration approaches for Vercel AI SDK
Both Smithery and MCPSDK provide hosted MCP servers, eliminating the need to manage local processes. The core differences lie in integration approach and developer experience.
One-sentence summary: Smithery requires manual MCP client management, while MCPSDK provides zero-config tool functions.
1. At a Glance
| Dimension | Smithery | MCPSDK |
|---|---|---|
| Core Positioning | Hosted MCP Server + Registry | Hosted MCP Server + Developer API |
| Server Hosting | Cloud-hosted (HTTP) | Cloud-hosted (API) |
| Server State | Local MCP needs preloading / Remote MCP direct | Always-on / No type distinction |
| Integration Method | experimental_createMCPClient |
getAISDKTool() / getOpenAISDKTool()
|
| Authentication | OAuth Provider | API Key |
| Multi-tool Management | Manual aggregation of clients | Unified API client |
| Client Lifecycle | Manual close() required |
Automatic management |
| API Key Management | Handled in OAuth | Configured in package() call |
| Tool Invocation | AI invocation only | AI invocation + Direct developer invocation |
2. Deep Dive
2.1 Smithery: Hosted MCP Server + HTTP Integration
Smithery provides hosted MCP servers (server.smithery.ai) accessible via HTTP transport protocol, suitable for use with Vercel AI SDK.
Advantages:
- ☁️ No need to manage local processes (cloud-hosted)
- 🌐 HTTP access (suitable for Serverless environments)
- 📚 Beautiful tool registry and documentation
- 🔒 OAuth authentication mechanism
Architecture Characteristics:
- 🔄 MCP Type Separation: Distinguishes between Local MCP and Remote MCP
- Local MCP: Requires preloading to server, cannot be invoked directly (cold start)
-
Remote MCP: Direct access via dedicated endpoints (e.g.,
server.smithery.ai/exa)
- ⚠️ Invocation Complexity: Developers need to understand and distinguish between different MCP types
Vercel AI SDK Integration Code:
import { experimental_createMCPClient as createMCPClient } from '@ai-sdk/mcp';
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
// 1. Create MCP client (experimental API)
const mcpClient = await createMCPClient({
transport: {
type: 'http',
url: 'https://server.smithery.ai/exa',
authProvider: myOAuthClientProvider, // OAuth configuration required
},
});
// 2. Get tool list
const tools = await mcpClient.tools();
// 3. Use in AI calls
const result = await streamText({
model: openai('gpt-4o-mini'),
tools,
prompt: 'Search the web for the latest AI news',
onFinish: async () => {
await mcpClient.close(); // Manual client closure required
},
});
Multi-tool Integration (Manual Aggregation Required):
import { experimental_createMCPClient as createMCPClient } from '@ai-sdk/mcp';
// Need to create separate clients for each server
const servers = [
'https://server.smithery.ai/exa',
'https://server.smithery.ai/@anthropics/brave-search',
];
const clients = await Promise.all(
servers.map(url =>
createMCPClient({
transport: { type: 'http', url, authProvider: myOAuthClientProvider },
})
)
);
// Manually aggregate all tools
const allTools = Object.assign(
{},
...(await Promise.all(clients.map(c => c.tools())))
);
Key Considerations:
- ⚠️ Uses
experimental_createMCPClient(experimental API, subject to change) - ⚠️ Requires OAuth Provider configuration (additional authentication complexity)
- ⚠️ Manual management of multiple clients for multiple tools
- ⚠️ Manual
close()calls required for lifecycle management - ⚠️ Third-party tool API keys (e.g., Exa) handled in OAuth (opaque)
- ⚠️ Local MCP requires preloading: Cannot be invoked directly, slower response
- ⚠️ MCP type distinction required: Local MCP and Remote MCP have different invocation patterns
2.2 MCPSDK: Hosted MCP Server + Developer-Friendly API
MCPSDK also provides hosted MCP servers, but with higher-level API wrapping optimized for developer experience.
Advantages:
- 🎯 Stable API (non-experimental)
- 🔑 Simple API key authentication
- 🛠️ Zero-config tool function generation
- 🔄 Automatic client lifecycle management
- 📦 Unified third-party tool API key management
- 🎮 Flexible invocation: Supports both AI invocation and direct developer invocation
Architecture Characteristics:
- ⚡ All MCP Servers Always-On: No installation or startup needed, use on demand
- 🚀 Zero Cold Start: All tool packages preloaded in cloud, faster response
- 🔌 Unified API Gateway: Access all tool packages through single entry point
- 🎯 No Type Distinction: Local MCP and Remote MCP handled uniformly, transparent to developers
Vercel AI SDK Integration Code:
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { MCPSDKApiClient } from 'toolsdk/api';
// 1. Initialize MCPSDK (simple API key)
const toolSDK = new MCPSDKApiClient({
apiKey: process.env.TOOLSDK_API_KEY
});
// 2. Get tool (chained call, one line)
const searchTool = await toolSDK
.package('tavily-mcp', { TAVILY_API_KEY: process.env.TAVILY_API_KEY })
.getAISDKTool('tavily-search');
// 3. Use directly (no manual close)
const result = await generateText({
model: openai('gpt-4o'),
tools: { searchTool },
prompt: 'What is the latest news about AI?'
});
Direct Developer Tool Invocation (No AI Required):
import { MCPSDKApiClient } from 'toolsdk/api';
const toolSDK = new MCPSDKApiClient({ apiKey: 'xxx' });
// Invoke tool directly without AI
const result = await toolSDK
.package('github', { GITHUB_TOKEN: 'xxx' })
.run({
toolKey: 'create-issue',
inputData: {
title: 'New Issue',
body: 'Issue description'
}
});
console.log(result); // Get tool execution result directly
Multi-tool Integration (Unified Client):
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { MCPSDKApiClient } from 'toolsdk/api';
const toolSDK = new MCPSDKApiClient({ apiKey: 'xxx' });
// Parallel tool fetching (Promise.all + chaining)
const [searchTool, emailTool] = await Promise.all([
toolSDK
.package('tavily-mcp', { TAVILY_API_KEY: 'xxx' })
.getAISDKTool('tavily-search'),
toolSDK
.package('@mcpsdk.dev/mcp-send-email', { RESEND_API_KEY: 'xxx' })
.getAISDKTool('send-email'),
]);
// Use directly
const result = await generateText({
model: openai('gpt-4o'),
tools: { searchTool, emailTool },
prompt: 'Search AI news and send to john@example.com'
});
Developer Experience Advantages:
- ✅ Stable API (not
experimental_) - ✅ No OAuth Provider configuration required
- ✅ Unified API client manages all tools
- ✅ Transparent third-party API key management
- ✅ Automatic client lifecycle management (no
close()) - ✅ Better TypeScript type inference
- ✅ No MCP type distinction: Local and Remote MCP handled uniformly
- ✅ Flexible invocation: Can be used by AI or invoked directly by developers
3. Code Comparison: Side by Side
Let's compare implementing the same functionality: Using a search tool to query the latest AI news
3.1 Smithery Approach
import { experimental_createMCPClient as createMCPClient } from '@ai-sdk/mcp';
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
// 1. Create MCP client (experimental API)
const mcpClient = await createMCPClient({
transport: {
type: 'http',
url: 'https://server.smithery.ai/exa',
authProvider: myOAuthClientProvider, // ⚠️ OAuth configuration required
},
});
// 2. Get tools
const tools = await mcpClient.tools();
// 3. Use tool
const result = await streamText({
model: openai('gpt-4o-mini'),
tools,
prompt: 'Search the web for the latest AI news',
onFinish: async () => {
await mcpClient.close(); // ⚠️ Manual closure required
},
});
Lines of Code: 18 lines
Configuration Required: OAuth Provider
Manual Management: Client lifecycle (close)
3.2 MCPSDK Approach
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { MCPSDKApiClient } from 'toolsdk/api';
// 1. Initialize (simple API key)
const toolSDK = new MCPSDKApiClient({ apiKey: 'xxx' });
// 2. Get tool (chained call)
const searchTool = await toolSDK
.package('tavily-mcp', { TAVILY_API_KEY: 'xxx' })
.getAISDKTool('tavily-search');
// 3. Use tool
const result = await generateText({
model: openai('gpt-4o'),
tools: { searchTool },
prompt: 'Search the web for the latest AI news'
});
Lines of Code: 12 lines
Configuration Required: API Key (standard)
Manual Management: None
3.3 Additional Scenario: Direct Developer Tool Invocation
Sometimes you need to invoke tools directly without AI.
Smithery Approach
❌ Does not support direct developer tool invocation
Smithery's MCP client can only pass tools to AI SDK, cannot execute tools directly.
MCPSDK Approach
✅ Supports direct tool invocation
import { MCPSDKApiClient } from 'toolsdk/api';
const toolSDK = new MCPSDKApiClient({ apiKey: 'xxx' });
// Invoke tool directly (no AI)
const result = await toolSDK
.package('github', { GITHUB_TOKEN: 'xxx' })
.run({
toolKey: 'create-issue',
inputData: {
title: 'New Issue',
body: 'Issue description'
}
});
console.log(result); // Get tool execution result directly
Lines of Code: 8 lines
Use Cases: Background tasks, scheduled jobs, webhook handlers, and other non-AI scenarios
4. When to use which?
4.1 Choose Smithery if...
- ✅ You prefer OAuth authentication (over API keys)
- ✅ You're comfortable using experimental APIs (
experimental_createMCPClient) - ✅ You need specific tools from the Smithery registry (e.g., Brave Search)
- ✅ You need to use tools in both Claude Desktop and code
4.2 Choose MCPSDK if...
- ✅ You want to use stable APIs (non-experimental)
- ✅ You need to manage multiple tools uniformly (no need to create clients for each)
- ✅ You want transparent third-party API key management (e.g., Tavily, Resend)
- ✅ You don't want to handle client lifecycle (automatic management)
- ✅ You need better TypeScript type support
- ✅ You want to uniformly invoke all MCP types (no Local/Remote distinction, no cold start)
- ✅ You need direct developer tool invocation (background tasks, scheduled jobs, webhooks, and other non-AI scenarios)
5. The Core Difference
| Smithery | MCPSDK | |
|---|---|---|
| Design Philosophy | Hosted server + Low-level MCP client | Hosted server + High-level developer API |
| MCP Types | Distinguishes Local MCP and Remote MCP | Handles all MCP types uniformly |
| Server Architecture | Local MCP needs preloading, Remote MCP dedicated endpoints | All always-on, unified gateway |
| Startup Method | Local MCP has cold start, Remote MCP direct | Preloaded always-on (zero cold start) |
| Invocation Method | AI invocation only | AI invocation + Direct developer invocation |
| Integration Layer | Protocol layer (createMCPClient) |
Application layer (getAISDKTool / run) |
| Complexity | Requires understanding MCP types, clients, transport, lifecycle | One line to get/execute tool |
| Use Cases | Deep MCP integration customization | AI apps + Background tasks + Automation |
Analogy:
- Smithery is like AWS SDK (you manage clients, connections, authentication)
- MCPSDK is like Firebase (you just call simple APIs)
Server Architecture Analogy:
- Smithery is like hybrid cloud (Local MCP = on-premise deployment needs preloading, Remote MCP = cloud direct)
- MCPSDK is like unified fully-managed service (all MCPs always-on in cloud, instant response)
6. Try MCPSDK
Experience zero-config MCP tool integration:
npm install toolsdk
2 lines of code to integrate search + email tools:
const toolSDK = new MCPSDKApiClient({ apiKey: 'xxx' });
const [searchTool, emailTool] = await Promise.all([
toolSDK.package('tavily-mcp', {...}).getAISDKTool('tavily-search'),
toolSDK.package('@mcpsdk.dev/mcp-send-email', {...}).getAISDKTool('send-email'),
]);
Top comments (0)