Skip to main content
Glama

Supabase MCP Server

by Quegenx
list-realtime-channels.ts6.31 kB
import { z } from "zod"; import { ToolHandlerParams, ToolHandlerResult } from "../../types.js"; // Schema for list-realtime-channels tool export const listRealtimeChannelsSchema = { channelName: z.string().optional().describe("Channel name pattern to filter by (supports SQL LIKE pattern)"), includeDetails: z.boolean().optional().default(true).describe("Include detailed channel information"), limit: z.number().optional().default(50).describe("Maximum number of channels to return"), offset: z.number().optional().default(0).describe("Offset for pagination") }; // Interface for Realtime channel information interface RealtimeChannel { id: string; name: string; type: string; created_at: string; updated_at: string; subscribers_count?: number; presence_count?: number; broadcast_count?: number; } // Handler for list-realtime-channels tool export const listRealtimeChannelsHandler = async ({ pool, params }: ToolHandlerParams): Promise<ToolHandlerResult> => { try { const { channelName = "", includeDetails = true, limit = 5, offset = 0 } = params as { channelName?: string; includeDetails?: boolean; limit?: number; offset?: number; }; // Check if the realtime schema exists const schemaCheckResult = await pool.query(` SELECT EXISTS ( SELECT 1 FROM pg_namespace WHERE nspname = 'realtime' ) as schema_exists; `); if (!schemaCheckResult.rows[0].schema_exists) { return { content: [ { type: "text", text: JSON.stringify({ error: "The 'realtime' schema does not exist. Please use the manage-realtime-status tool with action 'enable' to set up Realtime properly." }, null, 2) } ] }; } // Check if the messages table exists const messagesTableCheckResult = await pool.query(` SELECT EXISTS ( SELECT 1 FROM pg_tables WHERE schemaname = 'realtime' AND tablename = 'messages' ) as table_exists; `); if (!messagesTableCheckResult.rows[0].table_exists) { return { content: [ { type: "text", text: JSON.stringify({ error: "The 'realtime.messages' table does not exist. Please use the manage-realtime-status tool with action 'enable' to set up Realtime properly." }, null, 2) } ] }; } // Check if the channels table exists const tableCheckResult = await pool.query(` SELECT EXISTS ( SELECT 1 FROM pg_tables WHERE schemaname = 'realtime' AND tablename = 'channels' ) as table_exists; `); // Check if the channels view exists const viewCheckResult = await pool.query(` SELECT EXISTS ( SELECT 1 FROM pg_views WHERE schemaname = 'realtime' AND viewname = 'channels' ) as view_exists; `); if (!tableCheckResult.rows[0].table_exists && !viewCheckResult.rows[0].view_exists) { return { content: [ { type: "text", text: JSON.stringify({ error: "The 'realtime.channels' view does not exist. Please use the manage-realtime-status tool with action 'enable' to set up Realtime properly." }, null, 2) } ] }; } // Try to determine the structure of the channels table/view let channelsQuery = ` SELECT column_name FROM information_schema.columns WHERE table_schema = 'realtime' AND table_name = 'channels' `; const columnsResult = await pool.query(channelsQuery); const columns = columnsResult.rows.map(row => row.column_name); // Build the query based on available columns let selectColumns = ['id', 'name']; if (columns.includes('type')) { selectColumns.push('type'); } if (columns.includes('created_at')) { selectColumns.push('created_at'); } if (columns.includes('updated_at')) { selectColumns.push('updated_at'); } if (includeDetails) { if (columns.includes('subscribers_count')) { selectColumns.push('subscribers_count'); } if (columns.includes('presence_count')) { selectColumns.push('presence_count'); } if (columns.includes('broadcast_count')) { selectColumns.push('broadcast_count'); } } // Build the query to fetch channels let query = ` SELECT ${selectColumns.join(', ')} FROM realtime.channels `; // Add channel name filter if provided const queryParams: any[] = []; let paramIndex = 1; if (channelName && channelName.trim() !== "") { query += ` WHERE name LIKE $${paramIndex}`; queryParams.push(`%${channelName}%`); paramIndex++; } // Add ORDER BY clause query += ` ORDER BY name`; // Add LIMIT and OFFSET query += ` LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`; queryParams.push(limit, offset); // Execute the query const result = await pool.query(query, queryParams); // Format the result const channels: RealtimeChannel[] = result.rows.map(row => ({ id: row.id, name: row.name, type: row.type || 'standard', created_at: row.created_at ? new Date(row.created_at).toISOString() : new Date().toISOString(), updated_at: row.updated_at ? new Date(row.updated_at).toISOString() : new Date().toISOString(), ...(row.subscribers_count !== undefined && { subscribers_count: parseInt(row.subscribers_count) }), ...(row.presence_count !== undefined && { presence_count: parseInt(row.presence_count) }), ...(row.broadcast_count !== undefined && { broadcast_count: parseInt(row.broadcast_count) }) })); // Return the result return { content: [ { type: "text", text: JSON.stringify({ channels }, null, 2) } ] }; } catch (error: any) { return { content: [ { type: "text", text: JSON.stringify({ error: `Failed to list Realtime channels: ${error.message}` }, null, 2) } ] }; } };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Quegenx/supabase-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server