Human Approval
Let the agent inspect Supabase without interruption, but pause before it performs a database mutation.
Add approval to the Supabase connection
The Supabase MCP server publishes both read-only and mutation-capable tools. Add a policy to the existing connection so eve asks for approval only when the model selects an operation that can change data or infrastructure.
Update agent/connections/supabase.ts, keeping the connector UID that eve add generated for you:
import { connect } from "@vercel/connect/eve";
import { defineMcpClientConnection } from "eve/connections";
const MUTATING_TOOL_PATTERN =
/__(execute_sql|apply_migration|create_|update_|delete_|deploy_|pause_|restore_|merge_|reset_|rebase_)/i;
export default defineMcpClientConnection({
url: "https://mcp.supabase.com/mcp",
description:
"Supabase: databases, authentication, and storage. Mutation-capable operations are gated by eve human approval before execution.",
auth: connect("mcp.supabase.com/<your-connector-name>"),
approval: ({ toolName }) =>
MUTATING_TOOL_PATTERN.test(toolName)
? "user-approval"
: "not-applicable",
});The policy receives a qualified tool name such as supabase__execute_sql. Read-only discovery operations continue without an approval prompt; matching operations park the run before the MCP request reaches Supabase.
This workshop uses a conservative approval policy. For your own agent, decide what requires human approval based on your risk tolerance and the consequences of an incorrect call.
Add approval rules to instructions
The approval policy runs outside the model and is not automatically included in an MCP tool's description. Update agent/instructions.md so the agent knows it may request protected operations and that eve will pause before they run:
- The Supabase MCP connection is configured to require human approval for
mutation-capable operations, including `execute_sql` and `apply_migration`.
You may request these tools when the user explicitly asks for a mutation;
eve will pause before execution.
- Use read-only Supabase discovery tools to identify the project and schema
before requesting a mutation. If more than one project matches, ask the user
to choose.The runtime policy remains the enforcement layer. These instructions give the model accurate context so it requests the gated tool instead of incorrectly refusing the task.
Test the approval flow
Request a gated Supabase mutation, deny it once, then approve it. Eve pauses the turn while you decide and resumes the same session after you respond.
Restart local development.
npm run devRequest a ticket update.
PromptUse read-only Supabase tools to find the project whose public schema contains the tickets table. Then request an update to ticket TKT-1042: set its status to investigating and its internal note to "Account facts collected; escalating to identity team." Do not modify any other record.Watch for
connection_searchfollowed by a qualified Supabase MCP tool such assupabase__execute_sql. The policy parks the run before Supabase receives the mutation.Deny the first request.
Review the tool name and arguments, then choose Deny. Open the
ticketstable in Supabase and confirm thatTKT-1042is stillopen.Repeat and approve.
Send the same prompt again. Confirm that the proposed SQL targets only
TKT-1042with the expected status and note, then choose Approve.Verify the database result.
Refresh the
ticketstable. The approved request should changeTKT-1042toinvestigatingand preserve every other row.Deploy the updated agent.
npx eve deploySlack uses the production deployment, so publish the new connection policy and instructions before testing the approval there. Wait for the deployment to finish successfully.
Try the same flow in Slack.
PromptUse read-only Supabase tools to find the project whose public schema contains the tickets table. Then request an update to ticket TKT-1042: keep its status as investigating and set its internal note to "Slack update: still investigating." Do not modify any other record.The Slack channel renders the pending approval as native interactive controls. The durable session can wait without holding compute, then resumes when someone answers.
What happens under the hood
Model requests a mutation
The model discovers the Supabase connection and selects a mutation-capable MCP tool, such as supabase__execute_sql.
Policy requires approval
The connection policy returns user-approval before the MCP request runs.
Session parks
eve emits input.requested, enters session.waiting, and checkpoints the turn durably.
Human responds
A terminal, Slack, or web client submits Approve or Deny.
Approve
Resumes the same turn and sends the request to Supabase.
Deny
Prevents the MCP call. No database change runs.
The approval gate protects every matching call, including one replayed after an interruption. Production mutations should still use database constraints or transactions appropriate to their side effects.
Pause to ask clarifying questions
The built-in ask_question tool uses the same durable pause-and-resume protocol as approval. You do not need to define it. Instructions such as “ask for the account ID when it is missing” tell the model to wait for an answer instead of inventing one.
You are ready when
Congratulations, you built an agent! You now have an agent that uses tools, connects to Supabase, runs in Slack, and pauses sensitive actions for human approval.