> ## Documentation Index
> Fetch the complete documentation index at: https://docs.civic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Vercel AI SDK

> Build AI applications using Civic with the Vercel AI SDK

## Overview

Build AI applications with Civic and the Vercel AI SDK. Your agents can access external tools via MCP — GitHub, Slack, Google Workspace, and more.

<Note>
  **Framework:** This guide is written for Next.js projects. The core MCP client setup works with any JavaScript framework, but the authentication examples below use Next.js-specific APIs.
</Note>

## Quick Start

The fastest way to get started is with the starter template:

<Card title="AI Chatbot Starter" icon="github" href="https://github.com/civicteam/ai-chatbot">
  Clone our Next.js + Vercel AI SDK template with Civic pre-configured. Includes authentication, streaming, and tool calling out of the box.
</Card>

```bash theme={null}
git clone https://github.com/civicteam/ai-chatbot.git
cd ai-chatbot
pnpm install
cp .env.example .env.local
# Edit .env.local with your CIVIC_AUTH_CLIENT_ID and AI provider keys
pnpm dev
```

## Build From Scratch

### Prerequisites

1. Next.js 14+ project with App Router
2. Civic account at [app.civic.com](https://app.civic.com) with at least one MCP server connected
3. Node.js 18+

### Installation

```bash theme={null}
pnpm install ai @ai-sdk/openai @ai-sdk/anthropic @ai-sdk/react @modelcontextprotocol/sdk @civic/auth
```

<Note>
  **Vercel AI SDK version**: `experimental_createMCPClient` ships in the `ai` package for **AI SDK v5**. If you're on **v6+**, install `@ai-sdk/mcp` and import from there instead:

  ```bash theme={null}
  pnpm install @ai-sdk/mcp
  ```

  ```typescript theme={null}
  // v6+
  import { experimental_createMCPClient } from '@ai-sdk/mcp';
  // v5
  import { experimental_createMCPClient } from 'ai';
  ```
</Note>

### Authentication

**Why user auth for tool calls?** Civic needs to know which user's toolkit and permissions to use. For multi-user apps, each user gets their own access token tied to their Civic account.

**Why Civic Auth?** Civic needs to identify which user is accessing tools and authorize their permissions. Civic Auth provides the secure access token. (Support for additional identity providers coming soon.)

<Tabs>
  <Tab title="1. next.config.ts">
    ```ts theme={null}
    import { createCivicAuthPlugin } from "@civic/auth/nextjs"
    import type { NextConfig } from "next";

    const nextConfig: NextConfig = {};
    const withCivicAuth = createCivicAuthPlugin({ clientId: "YOUR_CLIENT_ID" });
    export default withCivicAuth(nextConfig)
    ```
  </Tab>

  <Tab title="2. API Route">
    **File:** `src/app/api/auth/[...civicauth]/route.ts`

    ```ts theme={null}
    import { handler } from "@civic/auth/nextjs"
    export const GET = handler()
    export const POST = handler()
    ```
  </Tab>

  <Tab title="3. Middleware">
    **File:** `src/middleware.ts`

    ```ts theme={null}
    import { authMiddleware } from "@civic/auth/nextjs/middleware"
    export default authMiddleware();
    export const config = { matcher: ['/((?!_next|favicon.ico|.*\\.png).*)',] };
    ```
  </Tab>

  <Tab title="4. Get Token">
    ```ts theme={null}
    import { getTokens } from "@civic/auth/nextjs";
    const { accessToken } = await getTokens();
    // Use in headers:
    headers: { Authorization: `Bearer ${accessToken}` }
    ```
  </Tab>
</Tabs>

<CardGroup cols={2}>
  <Card title="Full Integration Guide" icon="book" href="/integration/nextjs">
    Complete Next.js setup with frontend components, configuration options, and deployment details
  </Card>

  <Card title="AI Prompt for Next.js" icon="robot" href="/ai-prompts/nextjs">
    Use Claude, ChatGPT, or other AI assistants to automatically set up Civic Auth
  </Card>
</CardGroup>

<Note>
  Get your Client ID at [auth.civic.com](https://auth.civic.com)
</Note>

### Environment Variables

```bash theme={null}
# .env.local
CIVIC_AUTH_CLIENT_ID=your_client_id  # from auth.civic.com
OPENAI_API_KEY=your_openai_key       # or ANTHROPIC_API_KEY
```

## Create Civic Tools Helper

```typescript theme={null}
// lib/ai/tools/civic.ts
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import { getTokens } from "@civic/auth/nextjs";
import { experimental_createMCPClient as createMCPClient } from "ai"; // use @ai-sdk/mcp for v6+

export const getCivicTools = async () => {
  const { accessToken } = (await getTokens()) ?? {};
  // getTokens() exchanges the user's Civic Auth session for a hub access token
  if (!accessToken) {
    return {}; // Return empty tools if user isn't authenticated
  }

  try {
    const transport = new StreamableHTTPClientTransport(
      new URL('https://app.civic.com/hub/mcp'), {
        requestInit: {
          headers: {
            Authorization: `Bearer ${accessToken}`
          }
        }
      }
    );

    const mcpClient = await createMCPClient({ transport });
    return mcpClient.tools();
  } catch (error) {
    console.warn('Failed to load Civic tools, continuing without them:', error);
    return {};
  }
}
```

## App Router API Route

```typescript theme={null}
// app/api/chat/route.ts
import { convertToCoreMessages, streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { getCivicTools } from '@/lib/ai/tools/civic';

export async function POST(request: Request) {
  const { messages } = await request.json();
  const coreMessages = convertToCoreMessages(messages);
  const civicTools = await getCivicTools();

  const result = streamText({
    model: openai('gpt-4o'),
    messages: coreMessages,
    tools: civicTools,
  });

  // toUIMessageStreamResponse() returns a Response compatible with @ai-sdk/react useChat()
  return result.toUIMessageStreamResponse();
}
```

<Note>
  **Using Anthropic/Claude?** Replace the model:

  ```typescript theme={null}
  import { anthropic } from '@ai-sdk/anthropic';
  const result = streamText({
    model: anthropic('claude-sonnet-4-5-20250929'),
    messages: coreMessages,
    tools: civicTools,
  });
  ```
</Note>

## Next Steps

<Steps>
  <Step title="Try the Starter Template">
    Clone [ai-chatbot](https://github.com/civicteam/ai-chatbot) for a working example with UI, auth, and streaming
  </Step>

  <Step title="Connect Your Services">
    Visit [app.civic.com](https://app.civic.com) to connect GitHub, Slack, Notion, and other services
  </Step>

  <Step title="Test Tool Calls">
    Run locally and ask your AI to "list my GitHub repos" or "search Slack messages"
  </Step>

  <Step title="Deploy to Production">
    Deploy to Vercel — all environment variables are pre-configured in the starter template
  </Step>
</Steps>

<CardGroup cols={2}>
  <Card title="Starter Template" icon="github" href="https://github.com/civicteam/ai-chatbot">
    Full Next.js + Vercel AI SDK example with Civic integration
  </Card>

  <Card title="Get Help" icon="slack" href="https://join.slack.com/t/civic-developers/shared_invite/zt-37tv9fyo7-aDT43mUjOFQwdQFmfZLTRw">
    Developer Slack
  </Card>
</CardGroup>
