Skip to content

Connecting Vercel AI SDK & v0

Step-by-step guide to connect Vercel AI SDK and v0 to your Seed MCP server.

Prerequisites

Before you begin:

  • [ ] Vercel account - Sign up at vercel.com
  • [ ] Seed server URL - Get this from your administrator (e.g., https://mcp.example.com)
  • [ ] OAuth endpoints - Authorization and token URLs from your administrator
  • [ ] Credentials - Login credentials for your organization's identity provider

Overview

The Vercel AI SDK has built-in support for the Model Context Protocol (MCP). You can connect v0 or any Vercel AI SDK application to your Seed server to access custom tools, prompts, and resources.

Option 1: Using v0

v0 is Vercel's AI-powered interface builder that supports MCP out of the box.

Step 1: Access v0

  1. Go to v0.dev
  2. Sign in with your Vercel account
  3. Open Settings or MCP Configuration

Step 2: Add Seed Server

Add your Seed server as an MCP source:

json
{
  "mcpServers": {
    "seed": {
      "url": "https://YOUR_SERVER_URL/mcp",
      "transport": "http",
      "authentication": {
        "type": "oauth2",
        "authorizationUrl": "https://YOUR_SERVER_URL/oauth/authorize",
        "tokenUrl": "https://YOUR_SERVER_URL/oauth/token",
        "clientId": "v0-client",
        "scope": "openid profile email"
      }
    }
  }
}

Step 3: Authenticate

  1. v0 will detect the OAuth requirement
  2. Your browser will redirect to the login page
  3. Log in with your organization credentials
  4. Grant consent when prompted
  5. You'll be redirected back to v0

Step 4: Use Your Tools

Now you can reference your Seed tools in v0 prompts:

"Create a dashboard that shows the server health status from the Seed healthcheck tool"
"Build a user profile component using data from the Seed user-info tool"

Option 2: Using Vercel AI SDK

Integrate Seed into your own Vercel AI SDK application.

Step 1: Install Dependencies

bash
npm install ai @ai-sdk/openai
npm install @modelcontextprotocol/sdk

Step 2: Configure MCP Client

Create an MCP client configuration:

typescript
// lib/mcp-client.ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { HTTPClientTransport } from '@modelcontextprotocol/sdk/client/http.js';

export async function createMCPClient(accessToken: string) {
  const client = new Client({
    name: 'my-vercel-app',
    version: '1.0.0'
  }, {
    capabilities: {
      tools: {},
      prompts: {},
      resources: {}
    }
  });

  const transport = new HTTPClientTransport({
    url: process.env.SEED_SERVER_URL + '/mcp',
    headers: {
      'Authorization': `Bearer ${accessToken}`
    }
  });

  await client.connect(transport);
  return client;
}

Step 3: Implement OAuth Flow

Set up OAuth authentication in your Next.js app:

typescript
// app/api/auth/seed/route.ts
import { NextRequest } from 'next/server';

export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams;
  const code = searchParams.get('code');

  if (!code) {
    // Redirect to authorization
    const authUrl = new URL(process.env.SEED_AUTH_URL!);
    authUrl.searchParams.append('client_id', process.env.SEED_CLIENT_ID!);
    authUrl.searchParams.append('redirect_uri', process.env.SEED_REDIRECT_URI!);
    authUrl.searchParams.append('response_type', 'code');
    authUrl.searchParams.append('scope', 'openid profile email');

    return Response.redirect(authUrl.toString());
  }

  // Exchange code for token
  const tokenResponse = await fetch(process.env.SEED_TOKEN_URL!, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: process.env.SEED_CLIENT_ID!,
      redirect_uri: process.env.SEED_REDIRECT_URI!,
      code: code,
    }),
  });

  const tokens = await tokenResponse.json();

  // Store tokens securely (use session/cookies)
  // Redirect to app
  return Response.redirect('/dashboard');
}

Step 4: Use MCP Tools in AI SDK

Integrate MCP tools with the AI SDK:

typescript
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
import { createMCPClient } from '@/lib/mcp-client';

export async function POST(req: Request) {
  const { messages, accessToken } = await req.json();

  // Connect to Seed MCP server
  const mcpClient = await createMCPClient(accessToken);

  // List available tools
  const toolsList = await mcpClient.listTools();

  // Convert MCP tools to AI SDK tool format
  const tools = toolsList.tools.reduce((acc, tool) => {
    acc[tool.name] = {
      description: tool.description,
      parameters: tool.inputSchema,
      execute: async (args: any) => {
        const result = await mcpClient.callTool({
          name: tool.name,
          arguments: args
        });
        return result.content[0].text;
      }
    };
    return acc;
  }, {} as Record<string, any>);

  const result = await streamText({
    model: openai('gpt-4-turbo'),
    messages,
    tools,
  });

  return result.toDataStreamResponse();
}

Step 5: Environment Variables

Add to your .env.local:

bash
SEED_SERVER_URL=https://mcp.example.com
SEED_AUTH_URL=https://mcp.example.com/oauth/authorize
SEED_TOKEN_URL=https://mcp.example.com/oauth/token
SEED_CLIENT_ID=your-client-id
SEED_REDIRECT_URI=http://localhost:3000/api/auth/seed

Option 3: Deploy MCP Server to Vercel

You can also deploy your Seed server to Vercel for seamless integration.

Step 1: Prepare for Deployment

Ensure your Seed server is compatible with Vercel Functions:

typescript
// api/mcp.ts
import { createMCPHandler } from '@modelcontextprotocol/sdk';

export default createMCPHandler({
  server: {
    name: 'seed',
    version: '1.0.0'
  },
  tools: [
    // Your tools
  ]
});

Step 2: Deploy to Vercel

bash
# Install Vercel CLI
npm i -g vercel

# Deploy
vercel deploy

Step 3: Configure Environment

Set environment variables in Vercel dashboard:

  • OIDC_ISSUER
  • OAUTH_TOKEN_URL
  • OAUTH_AUTHORIZATION_URL
  • REDIS_URL

Testing Your Connection

Test with AI SDK

typescript
// Test MCP connection
import { createMCPClient } from '@/lib/mcp-client';

async function testConnection() {
  const client = await createMCPClient(accessToken);

  // List tools
  const tools = await client.listTools();
  console.log('Available tools:', tools.tools.map(t => t.name));

  // Call a tool
  const result = await client.callTool({
    name: 'healthcheck',
    arguments: {}
  });
  console.log('Health check:', result);
}

Test with v0

In v0, try prompts that use your Seed tools:

"Show me the server health status"
"Get my user information"
"Echo back: Hello from v0"

Troubleshooting

Connection Issues

"Cannot connect to MCP server"

  • Verify the SEED_SERVER_URL is correct
  • Check CORS settings allow requests from Vercel domains
  • Ensure server is accessible from Vercel's infrastructure

"MCP server not responding"

  • Check server logs for errors
  • Verify OAuth endpoints are accessible
  • Test the /health endpoint directly

Authentication Issues

"OAuth flow failed"

  • Verify redirect_uri matches exactly (including protocol)
  • Check client_id is registered with the server
  • Ensure OAuth URLs are correct and accessible

"Invalid token"

  • Token may have expired, implement refresh flow
  • Verify token is being passed in Authorization header
  • Check OIDC provider configuration

Tool Issues

"Tool not found"

  • Verify tools are registered in your Seed server
  • Check tool names match exactly (case-sensitive)
  • List available tools to confirm they're exposed

Best Practices

Token Management

typescript
// Store tokens securely
import { cookies } from 'next/headers';

export async function storeTokens(tokens: any) {
  cookies().set('seed_access_token', tokens.access_token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'lax',
    maxAge: tokens.expires_in
  });

  cookies().set('seed_refresh_token', tokens.refresh_token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'lax',
  });
}

Error Handling

typescript
// Robust error handling
try {
  const result = await mcpClient.callTool({ name: 'healthcheck' });
  return result;
} catch (error) {
  if (error.code === 401) {
    // Token expired, refresh it
    await refreshAccessToken();
    return retry();
  }
  throw error;
}

Caching

typescript
// Cache MCP tool definitions
import { unstable_cache } from 'next/cache';

export const getTools = unstable_cache(
  async (accessToken: string) => {
    const client = await createMCPClient(accessToken);
    return client.listTools();
  },
  ['mcp-tools'],
  { revalidate: 3600 } // Cache for 1 hour
);

Next Steps

Resources

Released under the MIT License.