Skip to main content

Overview

Integrate Civic Nexus with OpenAI Agents SDK using the hostedMcpTool() approach. This is the simplest way to use Nexus with OpenAI - no manual tool looping or conversion code required.
Updated for OpenAI Agents SDK: This guide uses the new hosted MCP tool feature. For the older function calling approach, see OpenAI SDK (Node.js).

Prerequisites

Prerequisites:
  1. Node.js 18+ project (Next.js 14+ or any Node.js framework)
  2. Civic account - Create account
  3. Connect services at nexus.civic.com (GitHub, Slack, etc.)
  4. OpenAI API Key - Get yours at platform.openai.com
  5. Complete Civic Auth setup (see Access Token Setup below)

Access Token Setup (Next.js + Civic Auth)

Why Civic Auth? Nexus 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.)
  • 1. next.config.ts
  • 2. API Route
  • 3. Middleware
  • 4. Get Token
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)
Get your Client ID at auth.civic.com
Non-Next.js: Forward a Bearer token from your frontend or validate incoming tokens server-side (see /libraries/auth-verify).

Environment Variables

Create a .env.local file in your project root:
# Get your Client ID at https://auth.civic.com
CIVIC_AUTH_CLIENT_ID=your_client_id_here

# OpenAI API key
OPENAI_API_KEY=your_openai_api_key
Getting your Civic Client ID:
  1. Visit auth.civic.com
  2. Create a new application or use an existing one
  3. Copy the Client ID from your application settings

Installation

Install the required packages:
npm install @openai/agents openai

Basic Setup

Step 1: Create Agent with Hosted MCP Tool

import { Agent, hostedMcpTool } from '@openai/agents';
import { getTokens } from '@civic/auth/nextjs';

async function createNexusAgent() {
  const { accessToken } = await getTokens();

  if (!accessToken) {
    throw new Error('No access token available. User must be authenticated.');
  }

  return new Agent({
    name: 'Nexus Assistant',
    model: 'gpt-4o-mini',
    instructions: 'You are a helpful assistant with access to external tools through Civic Nexus. Use the available tools to help users with their tasks.',
    tools: [
      hostedMcpTool({
        serverLabel: 'civic-nexus',
        serverUrl: 'https://nexus.civic.com/hub/mcp',
        authorization: {
          type: 'bearer',
          token: accessToken
        }
      }),
    ],
  });
}

Step 2: Run the Agent

import { run } from '@openai/agents';

async function main() {
  const agent = await createNexusAgent();

  const result = await run(
    agent,
    'List my GitHub repositories'
  );

  console.log(result.finalOutput);
}

main().catch(console.error);
That’s it! The Agent automatically:
  • Discovers available tools from Nexus
  • Selects the appropriate tool to use
  • Calls the tool with the right parameters
  • Returns the result to you

Complete Example: Next.js API Route

// app/api/agent/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { Agent, hostedMcpTool, run } from '@openai/agents';
import { getTokens } from '@civic/auth/nextjs';

export async function POST(req: NextRequest) {
  try {
    const { message } = await req.json();

    if (!message) {
      return NextResponse.json(
        { error: 'Message is required' },
        { status: 400 }
      );
    }

    const { accessToken } = await getTokens();

    if (!accessToken) {
      return NextResponse.json(
        { error: 'Not authenticated' },
        { status: 401 }
      );
    }

    const agent = new Agent({
      name: 'Nexus Assistant',
      model: 'gpt-4o-mini',
      instructions: 'You are a helpful assistant with access to external tools through Civic Nexus.',
      tools: [
        hostedMcpTool({
          serverLabel: 'civic-nexus',
          serverUrl: 'https://nexus.civic.com/hub/mcp',
          authorization: {
            type: 'bearer',
            token: accessToken
          }
        }),
      ],
    });

    const result = await run(agent, message);

    return NextResponse.json({
      response: result.finalOutput
    });
  } catch (error) {
    console.error('Agent error:', error);
    const errorMessage = error instanceof Error ? error.message : 'Failed to process request';
    return NextResponse.json(
      { error: errorMessage },
      { status: 500 }
    );
  }
}

Streaming Responses

For real-time streaming:
const result = await run(agent, 'Your question here?', { stream: true });

for await (const event of result) {
  if (event.type === 'response.output_text.delta') {
    console.log(event.delta);
  }
}

console.log(`Final result: ${result.finalOutput}`);

Tool Approval

Control which tools require approval before execution. Configure this in the hostedMcpTool:
import { Agent, hostedMcpTool } from '@openai/agents';
import { getTokens } from '@civic/auth/nextjs';

const { accessToken } = await getTokens();

const agent = new Agent({
  name: 'Nexus Assistant',
  model: 'gpt-4o-mini',
  instructions: 'You are a helpful assistant with access to external tools through Civic Nexus.',
  tools: [
    hostedMcpTool({
      serverLabel: 'civic-nexus',
      serverUrl: 'https://nexus.civic.com/hub/mcp',
      authorization: {
        type: 'bearer',
        token: accessToken
      },
      requireApproval: {
        // Never require approval for these tools
        never: { toolNames: ['github__list_repos', 'slack__search_messages'] },
        // Always require approval for these tools
        always: { toolNames: ['github__delete_repo'] },
      }
    }),
  ],
});

Key Advantages

Simplest Setup

Minimal code - just hostedMcpTool() configuration

Automatic Tools

Agent discovers and calls tools automatically

Remote Execution

Tools run through OpenAI’s Responses API

Built-in Streaming

Easy streaming support with stream: true option

Nexus Authentication

authorization: {
  type: 'bearer',
  token: accessToken  // Civic access token from getTokens()
}
import { getTokens } from "@civic/auth/nextjs";
const { accessToken } = await getTokens();
https://nexus.civic.com/hub/mcp

Comparison with Other Approaches

FeatureOpenAI Agents SDK (hostedMcpTool)OpenAI SDK (function calling)Vercel AI SDK
Setup ComplexityLowMediumMedium
Tool LoopingNo (automatic)Yes (manual)Yes (manual)
Tool ConversionNoYesYes
Best ForQuick prototypesFull controlNext.js apps
StreamingYesYesYes

Next Steps

1

Test with Simple Queries

Try “list my GitHub repos” or “search Slack messages about X”
2

Connect More Services

Visit nexus.civic.com to connect additional tools
3

Add Streaming

Implement real-time responses with the stream option
4

Deploy

Deploy your agent to production
I