MCPSDK LogoMCPSDK
Comparisons

MCPSDK vs Smithery

Comparing Smithery and MCPSDK integration approaches for Vercel AI SDK

MCPSDK vs Smithery

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

DimensionSmitheryMCPSDK
Core PositioningHosted MCP Server + RegistryHosted MCP Server + Developer API
Server HostingCloud-hosted (HTTP)Cloud-hosted (API)
Server StateLocal MCP needs preloading / Remote MCP directAlways-on / No type distinction
Integration Methodexperimental_createMCPClientgetAISDKTool() / getOpenAISDKTool()
AuthenticationOAuth ProviderAPI Key
Multi-tool ManagementManual aggregation of clientsUnified API client
Client LifecycleManual close() requiredAutomatic management
API Key ManagementHandled in OAuthConfigured in package() call
Tool InvocationAI invocation onlyAI 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

SmitheryMCPSDK
Design PhilosophyHosted server + Low-level MCP clientHosted server + High-level developer API
MCP TypesDistinguishes Local MCP and Remote MCPHandles all MCP types uniformly
Server ArchitectureLocal MCP needs preloading, Remote MCP dedicated endpointsAll always-on, unified gateway
Startup MethodLocal MCP has cold start, Remote MCP directPreloaded always-on (zero cold start)
Invocation MethodAI invocation onlyAI invocation + Direct developer invocation
Integration LayerProtocol layer (createMCPClient)Application layer (getAISDKTool / run)
ComplexityRequires understanding MCP types, clients, transport, lifecycleOne line to get/execute tool
Use CasesDeep MCP integration customizationAI 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'),
]);

View complete examples →