How to integrate Supabase MCP with Pydantic AI

Framework Integration Gradient
Supabase Logo
Pydantic AI Logo
divider

Introduction

This guide walks you through connecting Supabase to Pydantic AI using the Composio tool router. By the end, you'll have a working Supabase agent that can create a new secret api key for my project, list all third-party auth providers configured, delete google oauth from my supabase project, check if 'app-preview' subdomain is available through natural language commands.

This guide will help you understand how to give your Pydantic AI agent real control over a Supabase account through Composio's Supabase MCP server.

Before we dive in, let's take a quick look at the key ideas and tools involved.

TL;DR

Here's what you'll learn:
  • How to set up your Composio API key and User ID
  • How to create a Composio Tool Router session for Supabase
  • How to attach an MCP Server to a Pydantic AI agent
  • How to stream responses and maintain chat history
  • How to build a simple REPL-style chat interface to test your Supabase workflows

What is Pydantic AI?

Pydantic AI is a Python framework for building AI agents with strong typing and validation. It leverages Pydantic's data validation capabilities to create robust, type-safe AI applications.

Key features include:

  • Type Safety: Built on Pydantic for automatic data validation
  • MCP Support: Native support for Model Context Protocol servers
  • Streaming: Built-in support for streaming responses
  • Async First: Designed for async/await patterns

What is the Supabase MCP server, and what's possible with it?

The Supabase MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your Supabase account. It provides structured and secure access to your Supabase projects, so your agent can perform actions like managing API keys, configuring authentication, and handling custom domains on your behalf.

  • API key management: Create, update, or permanently delete project API keys, including setting descriptions and customizing JWT templates for secure access control.
  • Third-party auth integration control: List, retrieve, or remove third-party authentication providers (like Google or GitHub) from your Supabase project to tailor user sign-in options.
  • Custom domain and subdomain setup: Activate custom hostnames or vanity subdomains for your Supabase project, ensuring your app is accessible at a branded URL after DNS verification.
  • OAuth authorization handling: Generate OAuth 2.0 authorization URLs for secure user authentication flows, supporting seamless integration with registered apps.
  • Subdomain availability checks: Instantly verify if a desired vanity subdomain is available for your project before making DNS changes or launching branded experiences.

Supported Tools & Triggers

Tools
Create project api keyCreates a 'publishable' or 'secret' api key for an existing supabase project, optionally with a description; 'secret' keys can have customized jwt templates.
Delete an API key from the projectPermanently deletes a specific api key (identified by `id`) from a supabase project (identified by `ref`), revoking its access.
Get a third-party integrationRetrieves the detailed configuration for a specific third-party authentication (tpa) provider, identified by `tpa id`, within an existing supabase project specified by `ref`.
List third-party auth integrations for projectLists all configured third-party authentication provider integrations for an existing supabase project (using its `ref`), suitable for read-only auditing or verifying current authentication settings.
Delete third party auth configRemoves a third-party authentication provider (e.
Update an API key for the projectUpdates an existing supabase project api key's `description` and/or `secret jwt template` (which defines its `role`); does not regenerate the key string.
Beta activate custom hostname for projectActivates a previously configured custom hostname for a supabase project, assuming dns settings are verified externally.
Activate vanity subdomain for projectActivates a vanity subdomain for the specified supabase project, requiring subsequent dns configuration for the subdomain to become operational.
Authorize user through OAuthGenerates a supabase oauth 2.
Check vanity subdomain availabilityChecks if a specific vanity subdomain is available for a supabase project; this action does not reserve or assign the subdomain.
Enable project database webhooksEnables database webhooks for the supabase project `ref`, triggering real-time notifications for insert, update, or delete events.
Get project SSL enforcement configurationRetrieves the ssl enforcement configuration for a specified supabase project, indicating if ssl connections are mandated for its database.
Get current vanity subdomain configFetches the current vanity subdomain configuration, including its status and custom domain name, for a supabase project identified by its reference id.
Beta get project's custom hostname configRetrieves a supabase project's custom hostname configuration, including its status, ssl certificate, and ownership verification, noting that availability may depend on the project's plan.
Retrieve network bans for projectRetrieves the list of banned ipv4 addresses for a supabase project using its unique project reference string; this is a read-only operation.
Retrieve project network restrictionsRetrieves the current network restriction settings (e.
Get project pgsodium configRetrieves the pgsodium configuration, including the root encryption key, for an existing supabase project identified by its `ref`.
Beta remove a read replicaIrreversibly initiates the removal of a specified read replica from an existing supabase project, confirming only the start of the process, not its completion.
Remove project network bansRemoves specified ipv4 addresses from a supabase project's network ban list, granting immediate access; ips not currently banned are ignored.
Execute project database queryExecutes a given sql query against the project's database; use for advanced data operations or when standard api endpoints are insufficient, ensuring queries are valid postgresql and sanitized.
Setup read replica for projectProvisions a read-only replica for a supabase project in a specified, supabase-supported aws region to enhance read performance and reduce latency.
Beta update project network restrictionsUpdates and applies network access restrictions (ipv4/ipv6 cidr lists) for a supabase project, which may terminate existing connections not matching the new rules.
Upgrade the project's PostgreSQL versionInitiates an asynchronous upgrade of a supabase project's postgresql database to a specified `target version` from a selected `release channel`, returning a `tracking id` to monitor status; the `target version` must be available in the chosen channel.
Update pgsodium root keyCritically updates or initializes a supabase project's pgsodium root encryption key for security setup or key rotation, requiring secure backup of the new key to prevent irreversible data loss.
Create a database branchCreates a new, isolated database branch from an existing supabase project (identified by `ref`), useful for setting up separate environments like development or testing, which can optionally be linked to a git branch.
Create a functionCreates a new serverless edge function for a supabase project (identified by `ref`), requiring valid javascript/typescript in `body` and a project-unique `slug 1` identifier.
Create an organizationCreates a new supabase organization, which serves as a top-level container for projects, billing, and team access.
Create new projectCreates a new supabase project, requiring a unique name (no dots) within the organization; project creation is asynchronous.
Create SSO provider configurationCreates a new saml 2.
Create a new third-party auth integrationCall this to add a new third-party authentication method (oidc or jwks) to a supabase project for integrating external identity providers (e.
Reverify custom hostnameRe-verifies dns and ssl configurations for an existing custom hostname associated with a supabase project.
Delete branch by idPermanently and irreversibly deletes a specific, non-default database branch by its `branch id`, without affecting other branches.
Delete an edge function by slugPermanently deletes a specific edge function (by `function slug`) from a supabase project (by `ref`); this action is irreversible and requires prior existence of both project and function.
Delete custom hostname configDeletes an active custom hostname configuration for the project identified by `ref`, reverting to the default supabase-provided hostname; this action immediately makes the project inaccessible via the custom domain and requires subsequent updates to client, oauth, and dns settings.
Delete vanity subdomain for projectPermanently and irreversibly deletes an active vanity subdomain configuration for the specified supabase project, reverting it to its default supabase url.
Delete project by refPermanently and irreversibly deletes a supabase project, identified by its unique `ref` id, resulting in complete data loss.
Deploy functionDeploys edge functions to a supabase project using multipart upload.
Disable project readonly modeTemporarily disables a supabase project's read-only mode for 15 minutes to allow write operations (e.
Disable preview branchingDisables the preview branching feature for an existing supabase project, identified by its unique reference id (`ref`).
Exchange auth code for access and refresh token(beta) implements the oauth 2.
Generate TypeScript typesGenerates and retrieves typescript types from a supabase project's database; any schemas specified in `included schemas` must exist in the project.
Get database branch configRetrieves the read-only configuration and status for a supabase database branch, typically for monitoring or verifying its settings.
Get project API keysRetrieves all api keys for an existing supabase project, specified by its unique reference id (`ref`); this is a read-only operation.
Get project PgBouncer configRetrieves the active pgbouncer configuration (postgresql connection pooler) for a supabase project, used for performance tuning, auditing, or getting the connection string.
Get Project Upgrade EligibilityChecks a supabase project's eligibility for an upgrade, verifying compatibility and identifying potential issues; this action does not perform the actual upgrade.
Get project upgrade statusRetrieves the latest status of a supabase project's database upgrade for monitoring purposes; does not initiate or modify upgrades.
Get a specific SQL snippetRetrieves a specific sql snippet by its unique identifier.
Get a SSO provider by its UUIDRetrieves the configuration details for a specific single sign-on (sso) provider (e.
Get information about an organizationFetches comprehensive details for a specific supabase organization using its unique slug.
Get project's auth configRetrieves the project's complete read-only authentication configuration, detailing all settings (e.
Get project postgres configRetrieves the current read-only postgresql database configuration for a specified supabase project's `ref`, noting that some advanced or security-sensitive details might be omitted from the response.
Get project's PostgREST configRetrieves the postgrest configuration for a specific supabase project.
Get project's service health statusRetrieves the current health status for a supabase project, for specified services or all services if the 'services' list is omitted.
Get project Supavisor configurationRetrieves the supavisor (connection pooler) configuration for a specified supabase project, identified by its reference id.
Get Table SchemasRetrieves column details, types, and constraints for multiple database tables to help debug schema issues and write accurate sql queries.
List all database branchesLists all database branches for a specified supabase project, used for isolated development and testing of schema changes; ensure the project reference id is valid.
List all functionsLists metadata for all edge functions in a supabase project (specified by 'ref'), excluding function code or logs; the project must exist.
List all organizationsLists all organizations (id and name only) associated with the supabase account, excluding project details within these organizations.
List all projectsRetrieves a list of all supabase projects, including their id, name, region, and status, for the authenticated user.
List all secretsRetrieves all secrets for a supabase project using its reference id; secret values in the response may be masked.
List members of an organizationRetrieves all members of a supabase organization, identified by its unique slug, including their user id, username, email, role, and mfa status.
List project database backupsLists all database backups for a supabase project, providing details on existing backups but not creating new ones or performing restores; availability may depend on plan and configuration.
List all bucketsRetrieves a list of all storage buckets for a supabase project, without returning bucket contents or access policies.
List all SSO providersLists all configured single sign-on (sso) providers for a supabase project, requiring the project reference id (`ref`) of an existing project.
List SQL snippets for the logged in userRetrieves a list of sql snippets for the logged-in user, optionally filtered by a specific supabase project if `project ref` is provided.
Remove an SSO providerDeletes a specific sso provider by its id (`provider id`) from a supabase project (`ref`), which disables it and returns its details; ensure this action will not inadvertently lock out users.
Reset a database branchResets an existing supabase database branch, identified by `branch id`, to its initial clean state, irreversibly deleting all its current data and schema changes.
Restore database PITR backupRestores a supabase project's database to a specific unix timestamp using point-in-time recovery (pitr), overwriting the current state; requires a paid plan with pitr and physical backups enabled.
Retrieve a functionRetrieves detailed information, metadata, configuration, and status for a specific edge function using its project reference id and function slug.
Retrieve a function bodyRetrieves the source code (body) for a specified serverless edge function using its project reference and function slug; this is a read-only operation that does not execute the function or return runtime logs.
Get project's read-only mode statusRetrieves the read-only mode status for a specified supabase project to check its operational state; this action does not change the read-only state.
Update a functionUpdates an existing supabase edge function's properties (like name, slug, source code, jwt settings, import map) identified by project `ref` and `function slug`, supporting plain text code or eszip for the body.
Update database branch configUpdates the configuration of a supabase database branch, allowing modification of its name, associated git branch, reset-on-push behavior, persistence, and status.
Update project's custom hostname configurationUpdates the custom hostname for a supabase project, requiring subsequent dns changes to a user-controlled domain for ssl certificate issuance and domain ownership.
Update an SSO provider by its UUIDUpdates an existing sso provider's saml metadata, associated email domains, or attribute mappings for a supabase project, identified by `ref` and `provider id`.
Update project's postgres configUpdates specified postgresql configuration parameters for an existing supabase project (`ref`) to optimize database performance; note that unspecified parameters remain unchanged, and caution is advised as incorrect settings can impact stability or require a restart.
Update project's PostgREST configUpdates postgrest configuration settings (e.
Update database pooler configUpdates the supavisor (database pooler) configuration, such as `default pool size`, for an existing supabase project identified by `ref`; the `pool mode` parameter in the request is deprecated and ignored.
Update SSL enforcement configUpdates the ssl enforcement configuration (enable/disable) for a specified supabase project's database.

What is the Composio tool router, and how does it fit here?

What is Tool Router?

Composio's Tool Router helps agents find the right tools for a task at runtime. You can plug in multiple toolkits (like Gmail, HubSpot, and GitHub), and the agent will identify the relevant app and action to complete multi-step workflows. This can reduce token usage and improve the reliability of tool calls. Read more here: Getting started with Tool Router

The tool router generates a secure MCP URL that your agents can access to perform actions.

How the Tool Router works

The Tool Router follows a three-phase workflow:

  1. Discovery: Searches for tools matching your task and returns relevant toolkits with their details.
  2. Authentication: Checks for active connections. If missing, creates an auth config and returns a connection URL via Auth Link.
  3. Execution: Executes the action using the authenticated connection.

Step-by-step Guide

Prerequisites

Before starting, make sure you have:
  • Python 3.9 or higher
  • A Composio account with an active API key
  • Basic familiarity with Python and async programming

Getting API Keys for OpenAI and Composio

OpenAI API Key
  • Go to the OpenAI dashboard and create an API key. You'll need credits to use the models, or you can connect to another model provider.
  • Keep the API key safe.
Composio API Key
  • Log in to the Composio dashboard.
  • Navigate to your API settings and generate a new API key.
  • Store this key securely as you'll need it for authentication.

Install dependencies

bash
pip install composio pydantic-ai python-dotenv

Install the required libraries.

What's happening:

  • composio connects your agent to external SaaS tools like Supabase
  • pydantic-ai lets you create structured AI agents with tool support
  • python-dotenv loads your environment variables securely from a .env file

Set up environment variables

bash
COMPOSIO_API_KEY=your_composio_api_key_here
USER_ID=your_user_id_here
OPENAI_API_KEY=your_openai_api_key

Create a .env file in your project root.

What's happening:

  • COMPOSIO_API_KEY authenticates your agent to Composio's API
  • USER_ID associates your session with your account for secure tool access
  • OPENAI_API_KEY to access OpenAI LLMs

Import dependencies

python
import asyncio
import os
from dotenv import load_dotenv
from composio import Composio
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP

load_dotenv()
What's happening:
  • We load environment variables and import required modules
  • Composio manages connections to Supabase
  • MCPServerStreamableHTTP connects to the Supabase MCP server endpoint
  • Agent from Pydantic AI lets you define and run the AI assistant

Create a Tool Router Session

python
async def main():
    api_key = os.getenv("COMPOSIO_API_KEY")
    user_id = os.getenv("USER_ID")
    if not api_key or not user_id:
        raise RuntimeError("Set COMPOSIO_API_KEY and USER_ID in your environment")

    # Create a Composio Tool Router session for Supabase
    composio = Composio(api_key=api_key)
    session = composio.create(
        user_id=user_id,
        toolkits=["supabase"],
    )
    url = session.mcp.url
    if not url:
        raise ValueError("Composio session did not return an MCP URL")
What's happening:
  • We're creating a Tool Router session that gives your agent access to Supabase tools
  • The create method takes the user ID and specifies which toolkits should be available
  • The returned session.mcp.url is the MCP server URL that your agent will use

Initialize the Pydantic AI Agent

python
# Attach the MCP server to a Pydantic AI Agent
supabase_mcp = MCPServerStreamableHTTP(url, headers={"x-api-key": COMPOSIO_API_KEY})
agent = Agent(
    "openai:gpt-5",
    toolsets=[supabase_mcp],
    instructions=(
        "You are a Supabase assistant. Use Supabase tools to help users "
        "with their requests. Ask clarifying questions when needed."
    ),
)
What's happening:
  • The MCP client connects to the Supabase endpoint
  • The agent uses GPT-5 to interpret user commands and perform Supabase operations
  • The instructions field defines the agent's role and behavior

Build the chat interface

python
# Simple REPL with message history
history = []
print("Chat started! Type 'exit' or 'quit' to end.\n")
print("Try asking the agent to help you with Supabase.\n")

while True:
    user_input = input("You: ").strip()
    if user_input.lower() in {"exit", "quit", "bye"}:
        print("\nGoodbye!")
        break
    if not user_input:
        continue

    print("\nAgent is thinking...\n", flush=True)

    async with agent.run_stream(user_input, message_history=history) as stream_result:
        collected_text = ""
        async for chunk in stream_result.stream_output():
            text_piece = None
            if isinstance(chunk, str):
                text_piece = chunk
            elif hasattr(chunk, "delta") and isinstance(chunk.delta, str):
                text_piece = chunk.delta
            elif hasattr(chunk, "text"):
                text_piece = chunk.text
            if text_piece:
                collected_text += text_piece
        result = stream_result

    print(f"Agent: {collected_text}\n")
    history = result.all_messages()
What's happening:
  • The agent reads input from the terminal and streams its response
  • Supabase API calls happen automatically under the hood
  • The model keeps conversation history to maintain context across turns

Run the application

python
if __name__ == "__main__":
    asyncio.run(main())
What's happening:
  • The asyncio loop launches the agent and keeps it running until you exit

Complete Code

Here's the complete code to get you started with Supabase and Pydantic AI:

python
import asyncio
import os
from dotenv import load_dotenv
from composio import Composio
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP

load_dotenv()

async def main():
    api_key = os.getenv("COMPOSIO_API_KEY")
    user_id = os.getenv("USER_ID")
    if not api_key or not user_id:
        raise RuntimeError("Set COMPOSIO_API_KEY and USER_ID in your environment")

    # Create a Composio Tool Router session for Supabase
    composio = Composio(api_key=api_key)
    session = composio.create(
        user_id=user_id,
        toolkits=["supabase"],
    )
    url = session.mcp.url
    if not url:
        raise ValueError("Composio session did not return an MCP URL")

    # Attach the MCP server to a Pydantic AI Agent
    supabase_mcp = MCPServerStreamableHTTP(url, headers={"x-api-key": COMPOSIO_API_KEY})
    agent = Agent(
        "openai:gpt-5",
        toolsets=[supabase_mcp],
        instructions=(
            "You are a Supabase assistant. Use Supabase tools to help users "
            "with their requests. Ask clarifying questions when needed."
        ),
    )

    # Simple REPL with message history
    history = []
    print("Chat started! Type 'exit' or 'quit' to end.\n")
    print("Try asking the agent to help you with Supabase.\n")

    while True:
        user_input = input("You: ").strip()
        if user_input.lower() in {"exit", "quit", "bye"}:
            print("\nGoodbye!")
            break
        if not user_input:
            continue

        print("\nAgent is thinking...\n", flush=True)

        async with agent.run_stream(user_input, message_history=history) as stream_result:
            collected_text = ""
            async for chunk in stream_result.stream_output():
                text_piece = None
                if isinstance(chunk, str):
                    text_piece = chunk
                elif hasattr(chunk, "delta") and isinstance(chunk.delta, str):
                    text_piece = chunk.delta
                elif hasattr(chunk, "text"):
                    text_piece = chunk.text
                if text_piece:
                    collected_text += text_piece
            result = stream_result

        print(f"Agent: {collected_text}\n")
        history = result.all_messages()

if __name__ == "__main__":
    asyncio.run(main())

Conclusion

You've built a Pydantic AI agent that can interact with Supabase through Composio's Tool Router. With this setup, your agent can perform real Supabase actions through natural language. You can extend this further by:
  • Adding other toolkits like Gmail, HubSpot, or Salesforce
  • Building a web-based chat interface around this agent
  • Using multiple MCP endpoints to enable cross-app workflows (for example, Gmail + Supabase for workflow automation)
This architecture makes your AI agent "agent-native", able to securely use APIs in a unified, composable way without custom integrations.

How to build Supabase MCP Agent with another framework

FAQ

What are the differences in Tool Router MCP and Supabase MCP?

With a standalone Supabase MCP server, the agents and LLMs can only access a fixed set of Supabase tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from Supabase and many other apps based on the task at hand, all through a single MCP endpoint.

Can I use Tool Router MCP with Pydantic AI?

Yes, you can. Pydantic AI fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right Supabase tools.

Can I manage the permissions and scopes for Supabase while using Tool Router?

Yes, absolutely. You can configure which Supabase scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

How safe is my data with Composio Tool Router?

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your Supabase data and credentials are handled as safely as possible.

Used by agents from

Context
ASU
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
ASU
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
ASU
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai

Never worry about agent reliability

We handle tool reliability, observability, and security so you never have to second-guess an agent action.