Skip to main content

Overview

Integrate Civic Nexus with Vercel AI SDK to build AI applications that can access external tools and services through MCP (Model Context Protocol). This enables your AI agents to interact with GitHub, Slack, Dropbox, and other connected services.
Updated for AI SDK v5: This guide has been updated to use Vercel AI SDK v5. The main changes from v4 include:
  • New tool definition format with execute functions
  • Updated streaming response methods (toDataStreamResponse() instead of toAIStreamResponse())
  • Improved error handling and type safety
  • App Router examples instead of Pages Router
Prerequisites: You’ll need a Civic account and Node.js 18+ installed. Create your account and select your tools first.

Installation

Install the required packages:
npm install ai @ai-sdk/openai @ai-sdk/anthropic @modelcontextprotocol/sdk @civic/auth
AI SDK v5: This guide uses the latest Vercel AI SDK v5, which includes significant improvements and breaking changes from v4. Make sure to use v5 for the best experience.

Vercel AI SDK v5

Latest AI SDK for building AI applications

Model Providers

OpenAI and Anthropic provider packages

MCP SDK

Provides HTTP client transport for MCP protocol

Civic Auth

Handles authentication with Civic Nexus

Basic Setup

Step 1: Create MCP Client

Create a function to initialize the MCP client with authentication:
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { getTokens } from "@civic/auth/nextjs";

const createMCPClient = async () => {
  // Get access token from Civic Auth
  const { accessToken } = await getTokens();
  
  if (!accessToken) {
    throw new Error('No access token available. User needs to authenticate.');
  }

  // Create transport with authentication
  const transport = new StreamableHTTPClientTransport(
    'https://nexus.civic.com/hub/mcp',
    {
      requestInit: {
        headers: {
          Authorization: `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    }
  );

  // Initialize MCP client
  const client = new Client({
    name: 'my-ai-app',
    version: '1.0.0'
  }, {
    capabilities: {}
  });

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

Step 2: List Available Tools

Query available MCP tools from your connected services:
const listAvailableTools = async () => {
  const client = await createMCPClient();
  
  try {
    const tools = await client.listTools();
    console.log('Available tools:', tools.tools);
    return tools.tools;
  } catch (error) {
    console.error('Failed to list tools:', error);
    throw error;
  } finally {
    await client.close();
  }
};

Step 3: Call MCP Tools

Execute tools with the MCP client:
const callMCPTool = async (toolName: string, arguments: Record<string, any>) => {
  const client = await createMCPClient();
  
  try {
    const result = await client.callTool({
      name: toolName,
      arguments
    });
    
    return result.content;
  } catch (error) {
    console.error(`Failed to call tool ${toolName}:`, error);
    throw error;
  } finally {
    await client.close();
  }
};

Integration with Vercel AI SDK

Using with OpenAI

Combine MCP tools with OpenAI’s function calling:
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';

const generateWithMCPTools = async (prompt: string) => {
  // Get available MCP tools
  const client = await createMCPClient();
  const { tools } = await client.listTools();
  
  // Convert MCP tools to AI SDK v5 tool format
  const aiTools = tools.reduce((acc, tool) => {
    acc[tool.name] = {
      description: tool.description,
      parameters: tool.inputSchema,
      execute: async (args: any) => {
        // Execute MCP tool when called
        return await callMCPTool(tool.name, args);
      }
    };
    return acc;
  }, {} as Record<string, any>);

  const result = await generateText({
    model: openai('gpt-4'),
    prompt,
    tools: aiTools,
  });

  await client.close();
  return result;
};

Using with Anthropic Claude

import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const generateWithClaude = async (prompt: string) => {
  const client = await createMCPClient();
  const { tools } = await client.listTools();
  
  // Convert MCP tools to AI SDK v5 tool format
  const aiTools = tools.reduce((acc, tool) => {
    acc[tool.name] = {
      description: tool.description,
      parameters: tool.inputSchema,
      execute: async (args: any) => {
        // Execute MCP tool when called
        return await callMCPTool(tool.name, args);
      }
    };
    return acc;
  }, {} as Record<string, any>);

  const result = await generateText({
    model: anthropic('claude-3-5-sonnet-20241022'),
    prompt,
    tools: aiTools,
  });

  await client.close();
  return result;
};

Complete Example: AI Assistant

Here’s a complete example showing how to authenticate with Nexus and integrate MCP tools:
// app/api/chat/route.ts (Next.js App Router API route)
import { NextRequest } from 'next/server';
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { getTokens } from "@civic/auth/nextjs";

async function createMCPClient() {
  // Get Civic Auth token for Nexus authentication
  const { accessToken } = await getTokens();
  
  // Create MCP transport with Nexus authentication headers
  const transport = new StreamableHTTPClientTransport(
    'https://nexus.civic.com/hub/mcp',
    {
      requestInit: {
        headers: {
          // Required: Bearer token for Nexus authentication
          Authorization: `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    }
  );

  const client = new Client({
    name: 'my-ai-app',
    version: '1.0.0'
  }, {
    capabilities: {}
  });

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

export async function POST(req: NextRequest) {
  const { messages } = await req.json();
  
  // Connect to Nexus MCP Hub
  const client = await createMCPClient();
  const { tools } = await client.listTools();
  
  // Convert MCP tools to AI SDK v5 format
  const aiTools = tools.reduce((acc, tool) => {
    acc[tool.name] = {
      description: tool.description,
      parameters: tool.inputSchema,
      execute: async (args: any) => {
        const result = await client.callTool({
          name: tool.name,
          arguments: args
        });
        return result.content;
      }
    };
    return acc;
  }, {} as Record<string, any>);

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

  await client.close();
  return result.toDataStreamResponse();
}

Nexus Authentication

The key to integrating with Nexus is properly setting up the authentication headers. Here’s what you need:
headers: {
  // Required: Bearer token from Civic Auth
  Authorization: `Bearer ${accessToken}`,
  'Content-Type': 'application/json'
}
Use Civic Auth to get the user’s access token:
import { getTokens } from "@civic/auth/nextjs";
const { accessToken } = await getTokens();
Always connect to the Nexus MCP Hub endpoint:
https://nexus.civic.com/hub/mcp

Next Steps

1

Set up Authentication

Configure Civic Auth in your Next.js application following our auth guide
2

Connect Services

Visit nexus.civic.com to connect GitHub, Slack, or other services
3

Build Your AI App

Use the examples above to create your AI-powered application
4

Deploy

Deploy to Vercel or your preferred platform with proper environment variables

Need Help?

Join our developer community for technical support and implementation assistance