How to integrate Supabase MCP with LlamaIndex

Framework Integration Gradient
Supabase Logo
LlamaIndex Logo
divider

Introduction

This guide walks you through connecting Supabase to LlamaIndex 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 LlamaIndex 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:
  • Set your OpenAI and Composio API keys
  • Install LlamaIndex and Composio packages
  • Create a Composio Tool Router session for Supabase
  • Connect LlamaIndex to the Supabase MCP server
  • Build a Supabase-powered agent using LlamaIndex
  • Interact with Supabase through natural language

What is LlamaIndex?

LlamaIndex is a data framework for building LLM applications. It provides tools for connecting LLMs to external data sources and services through agents and tools.

Key features include:

  • ReAct Agent: Reasoning and acting pattern for tool-using agents
  • MCP Tools: Native support for Model Context Protocol
  • Context Management: Maintain conversation context across interactions
  • Async Support: Built 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 you begin, make sure you have:
  • Python 3.8/Node 16 or higher installed
  • A Composio account with the API key
  • An OpenAI API key
  • A Supabase account and project
  • Basic familiarity with async Python/Typescript

Getting API Keys for OpenAI, Composio, and Supabase

OpenAI API key (OPENAI_API_KEY)
  • Go to the OpenAI dashboard
  • Create an API key if you don't have one
  • Assign it to OPENAI_API_KEY in .env
Composio API key and user ID
  • Log into the Composio dashboard
  • Copy your API key from Settings
    • Use this as COMPOSIO_API_KEY
  • Pick a stable user identifier (email or ID)
    • Use this as COMPOSIO_USER_ID

Installing dependencies

pip install composio-llamaindex llama-index llama-index-llms-openai llama-index-tools-mcp python-dotenv

Create a new Python project and install the necessary dependencies:

  • composio-llamaindex: Composio's LlamaIndex integration
  • llama-index: Core LlamaIndex framework
  • llama-index-llms-openai: OpenAI LLM integration
  • llama-index-tools-mcp: MCP client for LlamaIndex
  • python-dotenv: Environment variable management

Set environment variables

bash
OPENAI_API_KEY=your-openai-api-key
COMPOSIO_API_KEY=your-composio-api-key
COMPOSIO_USER_ID=your-user-id

Create a .env file in your project root:

These credentials will be used to:

  • Authenticate with OpenAI's GPT-5 model
  • Connect to Composio's Tool Router
  • Identify your Composio user session for Supabase access

Import modules

import asyncio
import os
import dotenv

from composio import Composio
from composio_llamaindex import LlamaIndexProvider
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.workflow import Context
from llama_index.llms.openai import OpenAI
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

dotenv.load_dotenv()

Create a new file called supabase_llamaindex_agent.py and import the required modules:

Key imports:

  • asyncio: For async/await support
  • Composio: Main client for Composio services
  • LlamaIndexProvider: Adapts Composio tools for LlamaIndex
  • ReActAgent: LlamaIndex's reasoning and action agent
  • BasicMCPClient: Connects to MCP endpoints
  • McpToolSpec: Converts MCP tools to LlamaIndex format

Load environment variables and initialize Composio

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
COMPOSIO_API_KEY = os.getenv("COMPOSIO_API_KEY")
COMPOSIO_USER_ID = os.getenv("COMPOSIO_USER_ID")

if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY is not set in the environment")
if not COMPOSIO_API_KEY:
    raise ValueError("COMPOSIO_API_KEY is not set in the environment")
if not COMPOSIO_USER_ID:
    raise ValueError("COMPOSIO_USER_ID is not set in the environment")

What's happening:

This ensures missing credentials cause early, clear errors before the agent attempts to initialise.

Create a Tool Router session and build the agent function

async def build_agent() -> ReActAgent:
    composio_client = Composio(
        api_key=COMPOSIO_API_KEY,
        provider=LlamaIndexProvider(),
    )

    session = composio_client.create(
        user_id=COMPOSIO_USER_ID,
        toolkits=["supabase"],
    )

    mcp_url = session.mcp.url
    print(f"Composio MCP URL: {mcp_url}")

    mcp_client = BasicMCPClient(mcp_url, headers={"x-api-key": COMPOSIO_API_KEY})
    mcp_tool_spec = McpToolSpec(client=mcp_client)
    tools = await mcp_tool_spec.to_tool_list_async()

    llm = OpenAI(model="gpt-5")

    description = "An agent that uses Composio Tool Router MCP tools to perform Supabase actions."
    system_prompt = """
    You are a helpful assistant connected to Composio Tool Router.
    Use the available tools to answer user queries and perform Supabase actions.
    """
    return ReActAgent(tools=tools, llm=llm, description=description, system_prompt=system_prompt, verbose=True)

What's happening here:

  • We create a Composio client using your API key and configure it with the LlamaIndex provider
  • We then create a tool router MCP session for your user, specifying the toolkits we want to use (in this case, supabase)
  • The session returns an MCP HTTP endpoint URL that acts as a gateway to all your configured tools
  • LlamaIndex will connect to this endpoint to dynamically discover and use the available Supabase tools.
  • The MCP tools are mapped to LlamaIndex-compatible tools and plug them into the Agent.

Create an interactive chat loop

async def chat_loop(agent: ReActAgent) -> None:
    ctx = Context(agent)
    print("Type 'quit', 'exit', or Ctrl+C to stop.")

    while True:
        try:
            user_input = input("\nYou: ").strip()
        except (KeyboardInterrupt, EOFError):
            print("\nBye!")
            break

        if not user_input or user_input.lower() in {"quit", "exit"}:
            print("Bye!")
            break

        try:
            print("Agent: ", end="", flush=True)
            handler = agent.run(user_input, ctx=ctx)

            async for event in handler.stream_events():
                # Stream token-by-token from LLM responses
                if hasattr(event, "delta") and event.delta:
                    print(event.delta, end="", flush=True)
                # Show tool calls as they happen
                elif hasattr(event, "tool_name"):
                    print(f"\n[Using tool: {event.tool_name}]", flush=True)

            # Get final response
            response = await handler
            print()  # Newline after streaming
        except KeyboardInterrupt:
            print("\n[Interrupted]")
            continue
        except Exception as e:
            print(f"\nError: {e}")

What's happening here:

  • We're creating a direct terminal interface to chat with your Supabase database
  • The LLM's responses are streamed to the CLI for faster interaction.
  • The agent uses context to maintain conversation history
  • You can type 'quit' or 'exit' to stop the chat loop gracefully
  • Agent responses and any errors are displayed in a clear, readable format

Define the main entry point

async def main() -> None:
    agent = await build_agent()
    await chat_loop(agent)

if __name__ == "__main__":
    # Handle Ctrl+C gracefully
    signal.signal(signal.SIGINT, lambda s, f: (print("\nBye!"), exit(0)))
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nBye!")

What's happening here:

  • We're orchestrating the entire application flow
  • The agent gets built with proper error handling
  • Then we kick off the interactive chat loop so you can start talking to Supabase

Run the agent

npx ts-node llamaindex-agent.ts

When prompted, authenticate and authorise your agent with Supabase, then start asking questions.

Complete Code

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

import asyncio
import os
import signal
import dotenv

from composio import Composio
from composio_llamaindex import LlamaIndexProvider
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.workflow import Context
from llama_index.llms.openai import OpenAI
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

dotenv.load_dotenv()

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
COMPOSIO_API_KEY = os.getenv("COMPOSIO_API_KEY")
COMPOSIO_USER_ID = os.getenv("COMPOSIO_USER_ID")

if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY is not set")
if not COMPOSIO_API_KEY:
    raise ValueError("COMPOSIO_API_KEY is not set")
if not COMPOSIO_USER_ID:
    raise ValueError("COMPOSIO_USER_ID is not set")

async def build_agent() -> ReActAgent:
    composio_client = Composio(
        api_key=COMPOSIO_API_KEY,
        provider=LlamaIndexProvider(),
    )

    session = composio_client.create(
        user_id=COMPOSIO_USER_ID,
        toolkits=["supabase"],
    )

    mcp_url = session.mcp.url
    print(f"Composio MCP URL: {mcp_url}")

    mcp_client = BasicMCPClient(mcp_url, headers={"x-api-key": COMPOSIO_API_KEY})
    mcp_tool_spec = McpToolSpec(client=mcp_client)
    tools = await mcp_tool_spec.to_tool_list_async()

    llm = OpenAI(model="gpt-5")
    description = "An agent that uses Composio Tool Router MCP tools to perform Supabase actions."
    system_prompt = """
    You are a helpful assistant connected to Composio Tool Router.
    Use the available tools to answer user queries and perform Supabase actions.
    """
    return ReActAgent(
        tools=tools,
        llm=llm,
        description=description,
        system_prompt=system_prompt,
        verbose=True,
    );

async def chat_loop(agent: ReActAgent) -> None:
    ctx = Context(agent)
    print("Type 'quit', 'exit', or Ctrl+C to stop.")

    while True:
        try:
            user_input = input("\nYou: ").strip()
        except (KeyboardInterrupt, EOFError):
            print("\nBye!")
            break

        if not user_input or user_input.lower() in {"quit", "exit"}:
            print("Bye!")
            break

        try:
            print("Agent: ", end="", flush=True)
            handler = agent.run(user_input, ctx=ctx)

            async for event in handler.stream_events():
                # Stream token-by-token from LLM responses
                if hasattr(event, "delta") and event.delta:
                    print(event.delta, end="", flush=True)
                # Show tool calls as they happen
                elif hasattr(event, "tool_name"):
                    print(f"\n[Using tool: {event.tool_name}]", flush=True)

            # Get final response
            response = await handler
            print()  # Newline after streaming
        except KeyboardInterrupt:
            print("\n[Interrupted]")
            continue
        except Exception as e:
            print(f"\nError: {e}")

async def main() -> None:
    agent = await build_agent()
    await chat_loop(agent)

if __name__ == "__main__":
    # Handle Ctrl+C gracefully
    signal.signal(signal.SIGINT, lambda s, f: (print("\nBye!"), exit(0)))
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nBye!")

Conclusion

You've successfully connected Supabase to LlamaIndex through Composio's Tool Router MCP layer. Key takeaways:
  • Tool Router dynamically exposes Supabase tools through an MCP endpoint
  • LlamaIndex's ReActAgent handles reasoning and orchestration; Composio handles integrations
  • The agent becomes more capable without increasing prompt size
  • Async Python provides clean, efficient execution of agent workflows
You can easily extend this to other toolkits like Gmail, Notion, Stripe, GitHub, and more by adding them to the toolkits parameter.

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 LlamaIndex?

Yes, you can. LlamaIndex 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.