Agentic Actions for Laravel
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Agentic Actions for Laraveladd a high priority task for Marcus to review the pricing page"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Agentic Actions demo
A team task board that shows Agentic Actions for Laravel in a real app. Each operation on the board is one Action class. The same class answers the board's forms, a JSON route, php artisan actions:run, a copilot's tool calls and MCP clients such as Claude. Teams are the tenants: every action runs inside the team in the URL, and each role gets a different answer.
Try it at https://demo.agentic-actions.com. "Try the demo" gives you a private sandbox for 24 hours, with no sign-up. The package's documentation is at https://agentic-actions.com.
It is built on the Laravel React starter kit with teams: Laravel 13, Inertia 3, React 19, PHP 8.4 and SQLite. DEMO.md has the hand-test scripts for every feature, and CLAUDE.md is the guide for contributors and coding agents.
What to try
Open the board. The cards and the counts come from the
list-tasksandsummarize-boardactions, run in-process.Change a card's status, or add a task. The board's forms call the same actions through their JSON routes, and Precognition checks the fields against the action's
schema()as you type.Click Ask the assistant and try the suggestion chips. "Add three launch tasks for Marcus" runs real actions, and the cards appear on the board. "Delete 'Order new office chairs'" asks you to confirm on a card first. "Add a task for Marcus to review the pricing page" opens a form for the due date and the priority. "Tasks by status" answers with a table and a chart.
Switch to Vera, a viewer. The same buttons are there, and the server refuses her writes. Gus is not in Acme, so the Acme board answers 403 for him.
Open the team's AI clients page. Make a token for Claude Code or Cursor, or copy the connector URL for a Claude.ai custom connector. Your own model then works on the same board over MCP, with your role.
Related MCP server: boardagent-mcp
Run it locally
You need PHP 8.4 with pdo_sqlite, Composer, and Node 22.18 or later.
git clone https://github.com/agentic-actions/demo.git agentic-actions-demo
cd agentic-actions-demo
composer install
npm install
cp .env.example .env
php artisan key:generate
touch database/database.sqlite
php artisan migrate --seed
php artisan passport:keys
npm run buildLaravel Herd serves the folder at http://agentic-actions-demo.test (run herd link in it if the folder is outside a parked path). Without Herd, set APP_URL=http://127.0.0.1:8000 in .env and run php artisan serve.
passport:keys writes the OAuth key pair to storage/, which git ignores. Without it, the MCP URLs answer 500 instead of 401. The npm client @agentic-actions/client installs from the Composer package (file:vendor/agentic-actions/laravel/js), so run composer install before npm install.
Seeded users
Every password is password. The seeded users are for local use only; the hosted demo makes a sandbox for each visitor instead.
Name | Acme | Globex | |
Olivia Park | Owner | ||
Marcus Reed | Member | Member | |
Vera Lind | Viewer | ||
Gus Novak | Owner |
php artisan migrate:fresh --seed puts the boards back to the seeded state.
What each role may do on a board:
Owner | Admin | Member | Viewer | |
Read, search, summarize | yes | yes | yes | yes |
Create and update tasks | yes | yes | yes | no |
Delete tasks | yes | yes | no | no |
Create projects | yes | yes | no | no |
The copilot
With OPENROUTER_API_KEY empty, the copilot runs in scripted mode. app/Ai/ScriptedPlanner.php plays the model on laravel/ai's fake gateway, and the actions, permissions, cards and forms it drives are real. Set the key (and OPENROUTER_MODEL, anthropic/claude-sonnet-5 by default) to use a real model. ASSISTANT_SCRIPTED=true keeps scripted mode with a key set.
Claude.ai and other OAuth clients
A Claude.ai custom connector or ChatGPT signs in with OAuth and needs a public HTTPS address. php artisan app:tunnel opens a short-lived Cloudflare quick tunnel to a local copy. It refuses to start while any account still has the password password. See DEMO.md.
The CLI
--as takes a user id and --tenant a team slug. The seeded ids are 1 owner, 2 member, 3 viewer and 4 globex.
php artisan actions:list
php artisan actions:run summarize-board --as=1 --tenant=acme
php artisan actions:run create-task title="Call the printer" assignee="Marcus Reed" priority=high --as=1 --tenant=acme
php artisan actions:run create-task title="Nope" --as=3 --tenant=acme # viewer: exit 3, denied
php artisan actions:checkTests
php artisan test --compact
npm testHow hosted mode works
DEMO_HOSTED=true turns the app into the public demo. It is off by default, and a local copy behaves as described above.
A sandbox per visitor. "Try the demo" (POST /demo) creates a sandbox: you as the Acme owner, plus Marcus, Vera and Gus, the Acme and Globex boards, and a personal team for each person. Every person in it has a random password nobody knows. You are signed in straight away. The bar at the top shows the time left and has a "View as" menu that signs you in as one of the other three. The same menu copies a signed resume link, also shown on the AI clients page, that signs you back in from another browser, which is how you approve a Claude.ai connector on another device. Your session lasts as long as the sandbox. Team slugs get a random suffix, such as acme-k3x9qp, and so do the teams you add or rename.
A scripted copilot. On the host the copilot always follows the script, whatever ASSISTANT_SCRIPTED or any key says, and the app refuses every outbound HTTP request. To use a real model on the board, connect your own MCP client.
Kit features off. Sign-up, password reset, email verification, two-factor and passkeys answer 404. Email changes, password changes, account deletion and invitations answer 403, and their controls are hidden. Nothing sends email. The app answers only to the host in APP_URL.
Limits. Each surface has its own named rate limit (AppServiceProvider::configureRateLimits):
Surface | Limit |
Try the demo | 5 an hour per address, 120 an hour in all, at most 500 live sandboxes |
Resume link and View as | 30 a minute per address |
Assistant turns | 10 a minute and 300 a day per person, 30 a minute per address, one reply at a time |
Board actions | 60 calls and 30 change-feed polls a minute per person |
Team, member, token and connection changes | 20 a minute per person; 5 new tokens a minute |
MCP | 30 calls a minute per person (60 on a local copy) |
OAuth | registration 10 a minute and 30 a day per address, 500 a day in all; Anthropic's range 120 a minute and 500 a day of its own; consent 20 a minute |
A sandbox team holds at most 200 tasks and 20 projects, a visitor can add 5 teams, and each person can hold 5 live tokens per team. A token expires with its sandbox.
Resets. When a sandbox expires, its people are signed out and its MCP tokens stop working. The scheduler runs demo:prune-sandboxes every 15 minutes. It deletes each sandbox that expired more than five minutes ago, with everything in it: people, teams, boards, conversations, sessions, Sanctum tokens, OAuth tokens and MCP connections. demo:prune-clients deletes, once a day, OAuth clients that registered and never connected. passport:purge and sanctum:prune-expired run daily too, and with the database cache store, a daily task deletes its expired rows.
Hosting it
These are the steps for a Laravel Forge server with PHP 8.4, nginx, Node 22.18 or later, and optionally Redis. The server's default command-line PHP must be 8.4 too (in Forge, the server's PHP tab): npm run build runs php artisan through whatever php comes first on the path, not $FORGE_PHP.
Site and DNS
Create the site for
demo.agentic-actions.comwith zero-downtime deployments, and add a Let's Encrypt certificate.Point an
Arecord at the server, DNS only. With Cloudflare's proxy off, the app sees the real client address for its rate limits, and Anthropic's addresses (160.79.104.0/21) reach the OAuth routes without Cloudflare's firewall in the way. If you ever turn the proxy on, add$middleware->trustProxies(at: [...])with Cloudflare's ranges inbootstrap/app.php.
Environment
Set these in the site's .env. Never set OPENROUTER_API_KEY or any other model key on the host: not in .env, the PHP-FPM pool or the system environment.
Variable | Value |
|
|
|
|
| Made once, before the first deploy, and never changed (below) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| The absolute path of the SQLite file, outside the release directory |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Make the app key before the first deploy, since php artisan key:generate needs vendor/, which a new site does not have yet:
php -r "echo 'base64:'.base64_encode(random_bytes(32)), PHP_EOL;"The deploy caches the config, so a later change to .env takes effect only after php artisan optimize in the current release, or the next deploy.
Redis takes the rate-limit counters, the board's polling and the sessions off SQLite, but either store works. With the database store, the cache and sessions tables come from the migrations.
Shared files
A zero-downtime release is a new directory each time, so these live outside it:
.env, which Forge shares between releases.storage/, which Forge also shares. Passport's key pair lives there. Make it once, from the current release, after the first deploy, and never again: new keys end every connector's tokens.php artisan passport:keys chmod 600 storage/oauth-private.key storage/oauth-public.keyThe SQLite file. Create it once, for example
touch /home/forge/demo.agentic-actions.com/database.sqlite, and setDB_DATABASEto that path. Never copy a local database to the host.
Deploy script
$CREATE_RELEASE()
cd $FORGE_RELEASE_DIRECTORY
$FORGE_COMPOSER install --no-dev --no-interaction --prefer-dist --optimize-autoloader
npm ci
npm run build
$FORGE_PHP artisan migrate --force
$FORGE_PHP artisan optimize
$ACTIVATE_RELEASE()Composer comes first: the npm client installs from vendor/, and the build runs php artisan to write the route helpers, so vendor/ and .env must exist before npm run build. The build also fetches fonts over HTTPS. .npmrc turns off npm's install scripts.
Scheduler and workers
Turn on Forge's scheduler (
php artisan schedule:runevery minute). It runs the sandbox clean-up and the daily prunes.withoutOverlappingneeds a shared cache, which both the redis and the database store give.No queue worker and no SSR process are needed.
PHP-FPM
pm = dynamic, pm.max_children around 20 on a 2 GB server, and request_terminate_timeout = 60. PHP 8.4 needs pdo_sqlite, and the redis extension when Redis is used.
nginx
In the site's server block:
client_max_body_size 64k;
location ~ \.php$ {
# Forge's existing fastcgi lines stay.
fastcgi_read_timeout 60s;
}The copilot streams its replies as
text/event-stream. Keep that type out ofgzip_types, and never addfastcgi_ignore_headers X-Accel-Buffering: the stream sendsX-Accel-Buffering: noso nginx passes each part on at once.Keep
server_nametodemo.agentic-actions.com. The app also answers 400 to any host other thanAPP_URL's.
An optional per-address limit at the edge also covers requests that reach PHP before the app's own limits, such as MCP calls without a token. Put this in the http context (on Forge, a file in /etc/nginx/conf.d/); it leaves Anthropic's range and the health check alone:
geo $from_claude {
default 0;
160.79.104.0/21 1;
}
map "$from_claude:$uri" $demo_limit_key {
"~^1:" "";
"0:/up" "";
default $binary_remote_addr;
}
limit_req_zone $demo_limit_key zone=demo_per_ip:10m rate=10r/s;and this in the server block:
limit_req zone=demo_per_ip burst=40 nodelay;
limit_req_status 429;After each deploy
curl -si -X POST https://demo.agentic-actions.com/mcp/t/x -H 'Accept: application/json, text/event-stream' | grep -i -E '^HTTP|resource_metadata' # 401, with resource_metadata
curl -so /dev/null -w '%{http_code}\n' https://demo.agentic-actions.com/_inertia/devtools/entries # 404
curl -so /dev/null -w '%{http_code}\n' https://demo.agentic-actions.com/register # 404
php artisan tinker --execute 'echo App\Ai\ScriptedPlanner::active() ? "scripted" : "LIVE";' # scriptedThen click "Try the demo" and run one copilot chip. Do not print the config on the host (config:show), since it includes the app key.
License
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Task & board management for AI agents + humans. Kanban, comments, digests via MCP.
Read and write Mission Control state via MCP — projects, tasks, subtasks, templates, status updates.
Kanban board for teams and coding agents: manage tasks, subtasks, sprints and wiki pages via MCP.
Remote MCP for Kanban AI boards—manage projects, tasks, and comments from AI tools.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to manage Kanban boards, cards, sessions, and automations through a unified MCP interface with real-time updates, supporting delegation, agent sessions, and human-in-the-loop interactions.AGPL 3.0
- AlicenseAqualityAmaintenanceEnables AI agents to manage tasks on a local-first board via MCP, exposing task creation, updates, and queries through a thin adapter over the REST service.7MIT
- AlicenseNot gradedqualityBmaintenanceEnables agents to manage Kanban projects and tasks over MCP, including creating and listing projects/tasks, setting prerequisites, moving/archiving/restoring/deleting/reordering tasks, tracking history, and accessing attachments. Actions affecting multiple tasks return confirmation requests before applying changes.MIT
- AlicenseAqualityAmaintenanceEnables AI coding agents to read TeamStorm tasks, comments, attachments, and links, and to perform limited write operations such as adding comments and updating task names, descriptions, or statuses through MCP.132MIT