Skip to main content
The Smithery Connect is Smithery’s managed service for connecting to MCP servers. Instead of implementing the MCP protocol directly, handling OAuth flows, and managing credentials yourself, Smithery Connect provides a simple REST interface that handles all of this for you.

Why Smithery Connect?

Smithery Connect lets you add MCP server integrations to your app without managing the complexity yourself:
  • Zero OAuth configuration — No redirect URIs, client IDs, or secrets to configure. Smithery maintains OAuth apps for popular integrations.
  • Automatic token refresh — Tokens refresh automatically before expiry. If a refresh fails, the connection status changes to auth_required.
  • Secure credential storage — Credentials are encrypted and write-only. They can be used to make requests but never read back.
  • Stateless for you — Smithery Connect manages connection lifecycle. Make requests without worrying about reconnects, keepalives, or session state.
  • Scoped service tokens — Mint short-lived tokens for browser or mobile clients to call tools directly, scoped to specific users and namespaces.

Quick Start

npm install @smithery/api @ai-sdk/mcp ai @ai-sdk/anthropic
import { createMCPClient } from '@ai-sdk/mcp';
import { generateText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { createConnection } from '@smithery/api/mcp';

const { transport } = await createConnection({
  mcpUrl: 'https://server.smithery.ai/exa',
});

const mcpClient = await createMCPClient({ transport });
const tools = await mcpClient.tools();

const { text } = await generateText({
  model: anthropic('claude-sonnet-4-20250514'),
  tools,
  prompt: 'Search for the latest news about MCP.',
});

await mcpClient.close();

Servers with Configuration

Some MCP servers require configuration like API keys or project IDs. How you pass each config value depends on the server’s schema — some values go as headers (typically API keys), while others go as query parameters in the MCP URL. Check the server’s page on smithery.ai to see what configuration it requires and where each value should go.
import Smithery from '@smithery/api';
import { createConnection } from '@smithery/api/mcp';

const smithery = new Smithery();

// 1. Create a connection with the server's config
//    - API keys go in `headers`
//    - Other config goes as query params in `mcpUrl`
const conn = await smithery.experimental.connect.connections.set('my-browserbase', {
  namespace: 'my-app',
  mcpUrl: 'https://server.smithery.ai/@browserbasehq/mcp-browserbase?browserbaseProjectId=your-project-id',
  headers: {
    'browserbaseApiKey': 'your-browserbase-api-key',
  },
});
// conn.status.state === "connected" — ready to use immediately

// 2. Get a transport for the connection
const { transport } = await createConnection({
  client: smithery,
  namespace: 'my-app',
  connectionId: conn.connectionId,
});
Unlike OAuth-based servers that return auth_required, servers configured with API keys return connected immediately.
Each server’s config schema specifies whether a field is passed as a header or query parameter via the x-from metadata. See Session Configuration for details on how servers declare their config transport.

Multi-User Setup

When your agent serves multiple users, you’ll need to track which connections belong to which user. Use the metadata field to associate connections with your users, then filter by metadata to retrieve a specific user’s connections.

1. Create a Connection for a User

When a user wants to connect an integration (e.g., GitHub), create a connection with their userId in metadata:
const conn = await smithery.experimental.connect.connections.set('user-123-github', {
  namespace: 'my-app',
  mcpUrl: 'https://server.smithery.ai/@anthropic/github',
  name: 'GitHub',
  metadata: { userId: 'user-123' }
});

if (conn.status === 'auth_required') {
  // Redirect user to complete OAuth
  redirect(conn.authorizationUrl);
}

2. List a User’s Connections

When your agent needs to know what tools are available for a user, list their connections:
const connections = await smithery.experimental.connect.connections.list('my-app', {
  metadata: { userId: 'user-123' }
});

// Show the user their connected integrations
for (const conn of connections.data) {
  console.log(`${conn.name}: ${conn.status}`);
}

3. Use Tools Across Connections

Create MCP clients for each connection and aggregate their tools:
const allTools = [];

for (const conn of connections.data) {
  if (conn.status === 'connected') {
    const { transport } = await createConnection({
      namespace: 'my-app',
      connectionId: conn.connectionId,
    });
    const client = await createMCPClient({ transport });
    allTools.push(...await client.tools());
  }
}

// Now your agent has tools from all the user's connected integrations
const { text } = await generateText({
  model: anthropic('claude-sonnet-4-20250514'),
  tools: allTools,
  prompt: userMessage,
});

Core Concepts

Namespaces

A namespace is a globally unique identifier that groups your connections. Create one namespace per application or environment (e.g., my-app, my-app-staging). If you don’t specify a namespace, the SDK uses your first existing namespace or creates one automatically.

Connections

A connection is a long-lived session to an MCP server that persists until terminated. Each connection:
  • Has a connectionId (developer-defined or auto-generated)
  • Stores credentials securely (write-only—credentials can never be read back, only used to execute requests)
  • Can include custom metadata for filtering (e.g., userId to associate connections with your users)
  • Returns serverInfo with the MCP server’s name and version
OptionTypeDescription
clientSmithery?The Smithery client instance. If not provided, auto-created using SMITHERY_API_KEY env var
mcpUrlstring?The MCP server URL. Required when connectionId is not provided
namespacestring?If omitted, uses first existing namespace or creates one
connectionIdstring?If omitted, an ID is auto-generated
Returns a SmitheryConnection with { transport, connectionId, url }. Throws SmitheryAuthorizationError if OAuth authorization is required (see Handling Authorization).

Connection Status

When you create or retrieve a connection, it includes a status field:
StatusDescription
connectedConnection is ready to use
auth_requiredOAuth authorization needed. Includes authorizationUrl to redirect the user
errorConnection failed. Includes error message

Authentication

Smithery Connect uses two authentication methods:
TokenUse CaseAccess
API KeyBackend onlyFull namespace access
Service TokenBrowser, mobile, agentsScoped access to specific connections
Get your API key from smithery.ai/account/api-keys.
Never expose your API key to clients. Use service tokens for browser and mobile apps.

OAuth Flow

When an MCP server requires OAuth:
  1. Create a connection—the response status will be auth_required with an authorizationUrl
  2. Redirect the user to authorizationUrl
  3. User completes OAuth with the upstream provider (e.g., GitHub)
  4. User is redirected back to your app
  5. The connection is now ready—subsequent requests will succeed
You don’t need to register OAuth apps, configure redirect URIs, or handle token exchange. Smithery manages the OAuth relationship with upstream providers and stores credentials securely on your behalf.

Handling Authorization

When using the SDK, createConnection() throws a SmitheryAuthorizationError if the MCP server requires OAuth. The error contains the URL to redirect the user to and the connection ID to retry with after authorization completes.
import { createConnection, SmitheryAuthorizationError } from '@smithery/api/mcp';

try {
  const { transport } = await createConnection({
    mcpUrl: 'https://server.smithery.ai/@anthropic/github',
  });

  // Connection succeeded — use transport as normal
  const mcpClient = await createMCPClient({ transport });
  const tools = await mcpClient.tools();
} catch (error) {
  if (error instanceof SmitheryAuthorizationError) {
    // Redirect the user to complete OAuth
    // error.authorizationUrl — where to send the user
    // error.connectionId — save this to retry after auth completes
    redirect(error.authorizationUrl);
  }
  throw error;
}
After the user completes authorization and returns to your app, retry with the saved connectionId:
const { transport } = await createConnection({
  connectionId: savedConnectionId,
});

const mcpClient = await createMCPClient({ transport });
const tools = await mcpClient.tools();

Service Tokens

Service tokens let you safely use the Smithery Connect from browsers, mobile apps, and AI agents without exposing your API key. Your backend mints a scoped token, then your client uses it to call tools directly.
// Create a token scoped to a specific user's connections
const { token } = await smithery.tokens.create({
  policy: [
    {
      namespaces: 'my-app',
      resources: 'connections',
      operations: ['read', 'execute'],
      metadata: { userId: 'user-123' },
      ttl: '1h',
    },
  ],
})

// Send `token` to your client — safe for browser use
This token can only access connections in my-app where metadata.userId matches user-123. Initialize the client with the token:
const smithery = new Smithery({ apiKey: token })

const { transport } = await createConnection({
  client: smithery,
  namespace: 'my-app',
  connectionId: 'user-123-github',
})
Need workspace-level scoping, read-only tokens, or token narrowing? See Token Scoping for the full guide.

Advanced

For full API documentation, see the Smithery Connect Reference.

Direct MCP Calls

Call MCP methods directly via the Streamable HTTP endpoint:
// List available tools
const tools = await smithery.experimental.connect.mcp.call('user-123-github', {
  namespace: 'my-app',
  method: 'tools/list',
  params: {}
});

// Call a tool
const result = await smithery.experimental.connect.mcp.call('user-123-github', {
  namespace: 'my-app',
  method: 'tools/call',
  params: {
    name: 'search_repositories',
    arguments: { query: 'mcp' }
  }
});