Back to Blog
Business Workflows

Claude + Supabase Edge Functions: Real-Time AI for Full-Stack Apps

Claude Directory January 10, 2026
1 views

Integrate Claude AI into Supabase Edge Functions for lightning-fast, serverless processing of real-time data. Build intelligent full-stack apps with instant insights and automations right at the edge.

Introduction

Imagine a full-stack app where user inputs trigger AI analysis in milliseconds—no separate servers, no cold starts, just seamless intelligence powered by Claude and Supabase. Supabase Edge Functions, running on Deno at the edge, combined with Anthropic's Claude API, enable serverless AI that processes database events instantly. This setup is perfect for real-time apps like chatbots, support ticketing, or collaborative tools needing on-the-fly summarization, sentiment analysis, or auto-responses.

In this guide, we'll build a real-time support ticket system. Users submit tickets via a web app; a database trigger fires an Edge Function that calls Claude to classify urgency, detect sentiment, and generate a suggested response—all streamed back in real-time to the frontend.

Why this stack?

  • Low latency: Edge Functions execute near users (global CDN).
  • Serverless scaling: No infra management.
  • Claude's strengths: Superior reasoning, tool use, and context handling (e.g., Claude 3.5 Sonnet excels at nuanced classification).
  • Supabase Realtime: Broadcasts AI outputs instantly via WebSockets.

We'll cover setup, code, deployment, and optimizations. Let's dive in.

Prerequisites

Before starting:

Pro Tip: Use Claude 3.5 Sonnet (claude-3-5-sonnet-20240620) for best speed/accuracy balance in real-time scenarios.

Step 1: Set Up Your Supabase Project

  1. Log in to Supabase Dashboard and create a new project (e.g., claude-support-tickets).

  2. Create a tickets table for storing submissions:

-- Run in Supabase SQL Editor
CREATE TABLE tickets (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  user_id UUID REFERENCES auth.users(id),
  message TEXT NOT NULL,
  urgency TEXT,  -- AI-classified: low/medium/high
  sentiment TEXT, -- AI-classified: positive/neutral/negative
  suggested_response TEXT, -- AI-generated
  status TEXT DEFAULT 'open'
);

-- Enable RLS
ALTER TABLE tickets ENABLE ROW LEVEL SECURITY;

-- Policy for authenticated inserts
CREATE POLICY "Users can insert tickets" ON tickets
  FOR INSERT WITH CHECK (auth.uid() = user_id);

-- Policy for select (for realtime)
CREATE POLICY "Users can view own tickets" ON tickets
  FOR SELECT USING (auth.uid() = user_id);
  1. Enable Realtime on the tickets table:
    • Dashboard > Database > Replication > Toggle tickets.

Your DB is now ready for real-time AI magic.

Step 2: Secure Your Claude API Key

  1. In Supabase Dashboard > Edge Functions > Secrets, set:
    supabase secrets set ANTHROPIC_API_KEY=sk-ant-...
    
    (Or via CLI: supabase secrets set --env-file ./supabase/.env)

This keeps your key server-side only.

Step 3: Create the Edge Function for Claude Processing

Edge Functions are Deno scripts invoked via HTTPS. We'll make process-ticket call Claude to analyze and enrich tickets.

  1. Init functions locally:

    supabase init
    supabase functions new process-ticket
    
  2. Edit supabase/functions/process-ticket/index.ts:

import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};

serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders });
  }

  try {
    const supabaseClient = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '',
    );

    const { ticket_id } = await req.json();

    // Fetch ticket
    const { data: ticket } = await supabaseClient
      .from('tickets')
      .select('*')
      .eq('id', ticket_id)
      .single();

    if (!ticket) {
      throw new Error('Ticket not found');
    }

    // Claude prompt engineering: Structured output for reliability
    const prompt = `
Analyze this support ticket message: "${ticket.message}"

Classify:
- urgency: low | medium | high
- sentiment: positive | neutral | negative

Generate a helpful suggested response (under 200 words).

Respond ONLY in JSON: {"urgency": "...", "sentiment": "...", "suggested_response": "..."}
    `;

    const claudeResponse = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': Deno.env.get('ANTHROPIC_API_KEY'),
        'anthropic-version': '2023-06-01',
      },
      body: JSON.stringify({
        model: 'claude-3-5-sonnet-20240620',
        max_tokens: 500,
        temperature: 0.2,
        messages: [{ role: 'user', content: prompt }],
      }),
    });

    const claudeData = await claudeResponse.json();
    const analysis = JSON.parse(claudeData.content[0].text);

    // Update ticket with AI results
    const { error } = await supabaseClient
      .from('tickets')
      .update({
        urgency: analysis.urgency,
        sentiment: analysis.sentiment,
        suggested_response: analysis.suggested_response,
      })
      .eq('id', ticket_id);

    if (error) throw error;

    return new Response(
      JSON.stringify({ success: true, analysis }),
      { headers: { ...corsHeaders, 'Content-Type': 'application/json' } },
    );
  } catch (error) {
    return new Response(
      JSON.stringify({ error: error.message }),
      { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } },
    );
  }
});

Key Claude Tips:

  • JSON mode: Force structured output with "Respond ONLY in JSON".
  • Low temperature: Ensures consistent classifications.
  • Context window: Claude handles long messages well (200K tokens).
  1. Deploy: supabase functions deploy process-ticket

Your function is live at https://<project>.supabase.co/functions/v1/process-ticket.

Step 4: Wire Up Database Triggers for Instant Invocation

To auto-trigger on inserts, use Postgres http extension to call the Edge Function server-side.

  1. Enable http extension (Dashboard > Database > Extensions):

    CREATE EXTENSION IF NOT EXISTS http;
    
  2. Create trigger function:

    CREATE OR REPLACE FUNCTION handle_new_ticket()
    RETURNS TRIGGER AS $$
    DECLARE
      function_url TEXT := 'https://<your-project-ref>.supabase.co/functions/v1/process-ticket';
      resp JSON;
    BEGIN
      SELECT * INTO resp
      FROM http_post(
        function_url,
        json_build_object('ticket_id', NEW.id)::text,
        json_build_object(
          'Authorization', 'Bearer ' || current_setting('request.access_token')
        ),
        'application/json'
      );
      RETURN NEW;
    EXCEPTION WHEN OTHERS THEN
      -- Log error, don't fail insert
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    
  3. Attach trigger:

    CREATE TRIGGER on_ticket_insert
    AFTER INSERT ON tickets
    FOR EACH ROW EXECUTE FUNCTION handle_new_ticket();
    

Now, every ticket insert auto-invokes Claude via Edge Function—results update the row instantly!

Step 5: Build the Real-Time Frontend

Create a simple React app with Supabase client for inserts and subscriptions.

  1. Init app: npx create-react-app claude-supabase-tickets && cd claude-supabase-tickets

  2. Install deps: npm i @supabase/supabase-js

  3. src/App.js:

import { useState, useEffect } from 'react';
import { createClient } from '@supabase/supabase-js';

const supabase = createClient('https://<project>.supabase.co', 'your-anon-key');

function App() {
  const [tickets, setTickets] = useState([]);
  const [message, setMessage] = useState('');

  useEffect(() => {
    // Realtime subscription
    const channel = supabase
      .channel('tickets')
      .on(
        'postgres_changes',
        { event: '*', schema: 'public', table: 'tickets' },
        (payload) => {
          setTickets((prev) => {
            if (payload.eventType === 'INSERT') {
              return [payload.new, ...prev];
            }
            // Handle updates
            return prev.map((t) =>
              t.id === payload.new.id ? payload.new : t
            );
          });
        }
      )
      .subscribe();

    // Initial load
    fetchTickets();

    return () => { supabase.removeChannel(channel); };
  }, []);

  const fetchTickets = async () => {
    const { data } = await supabase.from('tickets').select('*');
    setTickets(data || []);
  };

  const submitTicket = async () => {
    const { data: { user } } = await supabase.auth.getUser();
    await supabase.from('tickets').insert({
      user_id: user.id,
      message,
    });
    setMessage('');
  };

  return (
    <div>
      <h1>AI-Powered Support Tickets</h1>
      <input
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        placeholder="Describe your issue..."
      />
      <button onClick={submitTicket}>Submit</button>
      <ul>
        {tickets.map((ticket) => (
          <li key={ticket.id}>
            <strong>{ticket.message}</strong><br/>
            Urgency: {ticket.urgency || 'Processing...'}
            | Sentiment: {ticket.sentiment || '...'}
            <br/><em>Suggested: {ticket.suggested_response || '...'}</em>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;
  1. Add auth (Supabase > Auth > Settings > Enable providers). Wrap in auth check.

  2. Run: npm start. Submit a ticket—watch Claude process it in real-time!

Step 6: Deploy, Monitor, and Scale

  • Frontend: Deploy to Vercel/Netlify, set env vars.
  • Monitoring: Supabase Logs for functions; Anthropic Console for API usage.
  • Costs: Edge Functions ~$0.0001/invocation; Claude ~$3/million tokens.

Optimizations:

  • Streaming: Modify Claude call with stream: true, pipe to client via ReadableStream.
  • Batch: Queue multiple events for cost savings (use Supabase pg_cron).
  • Caching: Redis for repeated analyses.
  • Prompt Tuning: Test with Claude's XML tags for complex outputs: <urgency>high</urgency>.

Advanced: Multi-Modal AI

Extend to images: Upload via Supabase Storage, base64 to Claude Vision (e.g., analyze ticket screenshots).

// In prompt
model: 'claude-3-5-sonnet-20240620',
messages: [{
  role: 'user',
  content: [{ type: 'text', text: prompt }, { type: 'image', source: { url: imageUrl } }]
}]

Conclusion

You've built a production-ready real-time AI app with Claude + Supabase Edge Functions. This pattern scales to HR onboarding (auto-resume screening), marketing (sentiment on leads), or engineering (code review bots). Experiment with Claude's tools for DB queries or MCP servers for extended capabilities.

Fork the code, share your builds on Claude Directory forums! Questions? Drop in comments.

Word count: ~1450

Comments

More Blog

View all
Claude for Developers

Building Voice Agents with Claude API and ElevenLabs: Conversational AI Guide

Build natural voice agents combining Claude API's superior reasoning with ElevenLabs' lifelike TTS. This end-to-end guide creates a conversational web app with STT, AI chat, and speech synthesis.

C
Claude Directory
2
Model Comparisons

Claude vs Mistral Large 2: 2025 Data Analysis Benchmarks and Use Cases

As data volumes explode in 2025, choosing between Claude's reasoning depth and Mistral Large 2's efficiency is critical. We benchmark SQL generation, visualizations, and large datasets to reveal the w

C
Claude Directory
1
Enterprise

Claude Enterprise for Cybersecurity: Threat Modeling and Incident Response

In the high-stakes world of cybersecurity, rapid threat modeling and incident response can mean the difference between containment and catastrophe. Discover how Claude Enterprise empowers security tea

C
Claude Directory
1
Claude Code

Claude Code in VS Code: Custom Commands for Refactoring Large Codebases

Refactoring sprawling codebases manually? Harness Claude Code's power in VS Code with custom commands to automate AI-driven refactors across TypeScript and Python projects—saving hours of drudgery.

C
Claude Directory
1
Claude for Developers

Claude SDK Rust for Blockchain: Smart Contract Auditing Agents

Build blazing-fast smart contract auditing agents in Rust using the Claude SDK. Harness Claude's reasoning to scan Solidity code for vulnerabilities like reentrancy and overflows.

C
Claude Directory
1
Claude Best Practices

Advanced Claude Artifacts: Collaborative Editing in Multi-User Sessions

Elevate team productivity with Claude Artifacts in multi-user projects—enable real-time iterative editing for code reviews and docs without leaving the interface.

C
Claude Directory
1