One Action class answers your web forms, JSON, Artisan, the queue, TypeScript, laravel/ai agents and MCP clients, each through the same checked pipeline.
composer require agentic-actions/laravel:^0.9@betaMark the class #[Expose] for the route, agents and MCP; Artisan and the queue reach it either way.
#[Expose]
final class CreatePost extends Action
{
protected ?Effect $effect = Effect::Write;
public function schema(JsonSchema $schema): array { … }
public function authorize(ActionContext $context): bool { … }
public function handle(ActionContext $context, ValidatedInput $input) { … }
}Whoever calls, the same checks run. A step before authorize() that says no answers “not found”, so a caller cannot tell a hidden action from a missing one.
An agent works on the page. Each action call shows as a live row, and the page reloads what the write touched.
A Destructive or External call waits until the person confirms it, on a card the server builds.
Delete this post? This cannot be undone.
Every tenant-scoped call runs inside one team. A stranger gets the same 404 as a team that does not exist.
Clients connect with a person's token or sign in with OAuth, and reach Read and Write actions only.
A Read action's rows reach the person as a table. The numbers come from your query; the model reads a short copy.
| Author | Posts | Words |
|---|---|---|
| Sam | 12 | 9,400 |
| Alex | 8 | 6,100 |
| Robin | 5 | 2,800 |
Fake every action, assert what ran, and pin what each toolset holds, so a widened toolset fails a test.
Install the package, write CreatePost, and call it from a form, the CLI and an agent.
composer require agentic-actions/laravel:^0.9@beta