AI Can Build Your MVP. But Who Controls What Its Agents Can Do?
A few prompts. A React frontend. Supabase for auth and data. An AI agent to connect everything. Suddenly, you have a working SaaS MVP. That's a real improvement in how we build software. But there's a question that rar
A few prompts. A React frontend. Supabase for auth and data. An AI agent to connect everything.
Suddenly, you have a working SaaS MVP.
That's a real improvement in how we build software. But there's a question that rarely appears in the demo:
Who decides what the application β and its AI agents β are actually allowed to do?
The answer cannot live in a React component, an AI prompt, or a database connection string. It needs to be enforced by the application architecture.
This isn't an argument that Supabase is insecure or that every startup needs Laravel on day one. It's an argument for clear backend boundaries β and for why Laravel is a strong choice once an AI-first product starts handling complex workflows, payments, permissions, and autonomous actions.
TLDR
- Supabase is a real backend platform. A frontend + Supabase architecture can be production-ready when its RLS policies, server-side logic, and permissions are designed correctly.
- An MCP server is not an authorization system. It exposes tools to AI clients; the application still has to enforce business rules.
- Laravel provides a useful domain layer: Policies, Actions, queues, transactions, and dedicated MCP tools can share the same business operations across web, mobile, and AI clients.
- The goal isn't more infrastructure. It's to prevent a simple user request from becoming an unauthorized or duplicate real-world action.
The MVP is easy. The business rules are not.
A typical AI-assisted MVP stack looks something like this:
For a small product with straightforward CRUD operations, this can be a perfectly reasonable architecture.
But products tend to grow beyond CRUD:
- A booking can be cancelled only under specific conditions.
- A refund depends on payment status, provider policies, and previous requests.
- A B2B user must never cross an organization's data boundary.
- A webhook may arrive twice or before another event.
- An AI agent may retry an action after a timeout. The hard part isn't building a Cancel booking button. It's ensuring that every possible caller follows the same cancellation rules.
That includes your web UI, mobile app, admin dashboard, external API clients, and AI agents using MCP.
What recent security research tells us
In October 2026, UpGuard investigated approximately 300,000 domains with indicators of Supabase usage. The researchers found 16,326 databases with publicly readable tables; more than half had schema indicators of personally identifiable information.
Those figures need context: an accessible table isn't automatically a breach, and schema indicators aren't the same as verifying that every row contains sensitive data. Still, the study illustrates the scale of access-control misconfigurations.
In February 2026, Wiz reported a misconfigured Supabase database at Moltbook, a social network for AI agents. The exposure included around 1.5 million API authentication tokens, 35,000 email addresses, and private messages; researchers also found unauthorized read/write access. The issue was secured following disclosure.
And in May 2026, Akamai documented vulnerabilities in three MCP backend integrations, involving Apache Doris, Apache Pinot, and Alibaba RDS. The findings included SQL injection, missing authentication, and unauthorized data exposure.
These cases involve different technologies and failure modes. They don't prove that Supabase, MCP, or AI-generated code is inherently unsafe.
They point to a common engineering problem: capabilities were exposed without sufficiently enforceable boundaries.
Supabase vs. Laravel: the question isn't which one has a backend
Supabase offers PostgreSQL, Auth, Row Level Security (RLS), Edge Functions, Storage, and other backend capabilities. It can host secure application logic and user-scoped MCP tools without a standalone Laravel service.
Laravel is different: it's an application framework for organizing domain behavior across controllers, APIs, background jobs, and integrations.
Neither choice automatically makes an app secure. The useful comparison is where responsibilities live.
| Concern | Frontend + Supabase | Laravel application layer | Hybrid: Laravel + Supabase |
|---|---|---|---|
| Fast MVP | Excellent | Good | Good |
| Authentication | Supabase Auth | Sanctum / Passport | Choose one clear identity model |
| Authorization | RLS + server-side checks | Policies + domain checks | Policies + coordinated RLS |
| Business workflows | SQL / Edge Functions | Shared Actions and services | Laravel owns domain workflows |
| Jobs and retries | Queues / Functions / Cron | Jobs / Queues / Horizon | Both, with clear ownership |
| MCP tools | Edge Functions + user-scoped access | Laravel MCP + domain Actions | Laravel MCP over shared services |
| Operational complexity | Managed services | Application + infrastructure | Both systems to coordinate |
The hybrid column matters. Laravel and Supabase are not mutually exclusive. You can keep managed PostgreSQL or other Supabase services while putting business operations behind Laravel.
The real reason to add Laravel
Consider four different entry points:
The key is not the number of layers. It's that the same business operation is invoked regardless of who asks for it.
A cancellation rule should not be reimplemented separately in a React handler, a database function, an admin endpoint, and an agent tool.
In Laravel, it can live in a shared CancelBookingAction or RequestRefundAction, with Policies and domain validations applied consistently.
MCP changes who can trigger an operation
Imagine a user telling an AI assistant:
Cancel my hotel booking and request a refund if the cancellation policy allows it.
The agent might call getBookingDetails, followed by checkRefundEligibility, followed by requestBookingRefund.
But MCP only provides a way to describe and call tools. It doesn't automatically know whether the booking belongs to this user, whether a refund is allowed, or whether that exact refund was already initiated.
Those are application responsibilities.
Here's the architectural trade-off:
| Security question | Broad database MCP tools | Domain-specific MCP tools via Laravel |
|---|---|---|
| What can the agent do? | Depends on DB credentials and tool scope | Only exposed business operations |
| Who checks ownership? | RLS or explicit tool logic | Policy + domain authorization |
| Who enforces refund rules? | Database functions or tool code | Shared RequestRefundAction
|
| How are repeated requests handled? | Must be implemented | Shared idempotency logic |
| Can approval be required? | Yes, if designed | Yes, in the domain workflow |
| Is prompt injection eliminated? | No | No β but narrower tools reduce impact |
Important: restricted database roles and correctly designed RLS can be secure. Laravel is not a substitute for least privilege, testing, or secure deployment. The point is to expose business capabilities, not unnecessarily broad data manipulation.
A practical Laravel + MCP refund workflow
A safer design doesn't give the agent a tool named execute_sql or update_booking_status.
Instead, it exposes narrow tools:
getBookingDetails
checkRefundEligibility
requestBookingRefund
The last tool creates a refund request, not an immediate payment transfer. The server remains responsible for validation and execution.
With Laravel MCP, a tool can be a small adapter around an existing domain Action.
<?php
namespace App\Mcp\Tools;
use App\Actions\Bookings\RequestRefundAction;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Attributes\Description;
use Laravel\Mcp\Server\Tool;
[Description('Create an authorized refund request; never transfer money directly.')]
final class RequestRefundTool extends Tool
{
public function __construct(
private RequestRefundAction $refunds,
) {}
public function schema(JsonSchema $schema): array
{
return [
'booking_id' => $schema->integer()->required(),
'approval_token' => $schema->string()->required(),
];
}
public function handle(Request $request): Response
{
$input = $request->validate([
'booking_id' => ['required', 'integer', 'min:1'],
'approval_token' => ['required', 'string'],
]);
if (! $request->user()) {
return Response::error('Authentication required.');
}
$result = $this->refunds->execute(
user: $request->user(),
bookingId: (int) $input['booking_id'],
approvalToken: $input['approval_token'],
);
return Response::structured([
'request_id' => $result->id,
'status' => $result->status,
]);
}
}
This is an illustrative tool adapter, not a complete production refund implementation. RequestRefundAction is application-specific and must implement the security and transaction controls below.
The domain Action needs to:
- Resolve the booking within the correct tenant and authorize the user with a Laravel Policy.
- Verify refund eligibility against current booking and payment state.
- Validate and consume a server-issued, single-use approval token bound to this user, booking, and operation. An AI-generated claim of approval does not count.
- Create an idempotent request so retries cannot produce duplicate refunds.
- Queue payment-provider work and reconcile results using verified webhooks.
- Record an audit trail with the user identity, client context, decision, and outcome. In other words, the MCP tool is deliberately thin. The Action is the authority.
Why not put all of this inside the MCP tool?
Because tomorrow the customer may request the same refund from a mobile app or speak to a human support agent.
If the actual rules are embedded in the MCP adapter, you'll have to maintain another copy elsewhere.
When the rules live in Laravel's domain layer, all entry points use the same implementation.
This also makes tests more meaningful. You can test the domain operation independently, then verify that the API and MCP interfaces cannot bypass it.
What Laravel gives an AI-first SaaS team
Laravel doesn't magically solve distributed systems, but it provides mature building blocks:
- Policies and Gates for resource-level authorization, including tenant boundaries.
- Sanctum and Passport for API authentication and OAuth-based clients.
- Actions and services (an application design choice) for shared domain rules.
- Transactions, Jobs, Queues, and Horizon for reliable, observable workflows.
- Laravel MCP to expose controlled tools to external AI clients.
- Laravel AI SDK for AI features inside the application. None of these replaces engineering judgment. A database transaction cannot atomically commit a Stripe refund, and a Job is not automatically idempotent. Those failure paths still need explicit design.
The advantage is having a coherent place to implement and test the rules.
When should a startup add Laravel?
Not every project needs a dedicated application framework from the start.
| Product stage | Reasonable starting point | Architectural priority |
|---|---|---|
| Prototype / proof of concept | Frontend + Supabase | Validate the idea quickly |
| CRUD MVP | Supabase + properly tested RLS | Correct data permissions |
| MVP with payments | Edge Functions or Laravel | Authoritative payment workflows |
| Multi-tenant B2B SaaS | Laravel, or a carefully structured BaaS | Tenant isolation + shared rules |
| Booking / fintech / healthcare | Laravel or another mature domain layer | Auditability, reliability, compliance |
| AI product with MCP tools | Laravel MCP or secure Edge Functions | Least privilege + operation-level checks |
The transition point isn't a magic number of users. It's the moment when business rules become more expensive to duplicate, audit, and maintain than a dedicated backend layer.
And for many startups, a modular Laravel monolith is a better starting point than jumping straight to microservices.
The important distinction: generating code vs. designing authority
AI coding agents can generate controllers, migrations, database policies, payment integrations, and MCP tools. That's useful β and increasingly powerful.
But an agent generating a working endpoint doesn't establish which actor has the authority to invoke it.
That requires deliberate decisions about:
- Identity: Which user and tenant does this request represent?
- Authority: Which exact action can that user perform?
- State: Is the action valid right now?
- Consistency: What happens on retries, timeouts, and concurrent calls?
- Accountability: Can we reconstruct who requested what and what actually happened?
These are backend architecture questions, regardless of whether the code was written by a human or generated by AI.
AI can build an impressive MVP in days. Supabase can provide a strong, production-capable backend. Laravel can provide a maintainable domain layer for complex business operations. MCP can make those operations accessible to AI agents.
All four can fit into a sound product architecture.
The risk starts when we confuse the ability to call a tool with permission to perform the action behind it.
The frontend expresses intent. The AI agent selects a tool. The backend enforces the rules.
That's the boundary worth designing before the first autonomous agent reaches production.
How are you separating AI tools from your business logic β Laravel Actions, database functions, serverless workflows, or something else?
Research mentioned
- UpGuard β Everything Everywhere: Systemic Data Exposure in Supabase Apps (October 2026).
- Wiz β Hacking Moltbook (February 2026).
- Akamai β One Is a Fluke, 3 Is a Pattern: MCP Back-End Vulnerabilities (May 2026).
Building beyond the MVP? If you need a reliable foundation for an AI-first MVP or a growing SaaS platform, Kavita Systems can help you design and build Laravel backends, modern React/Vue interfaces, secure APIs, and MCP integrationsβwith clear boundaries between AI tools and business logic.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.

