Search by

hemp / nova-mcp

davidhemphill

Exposes Laravel Nova dashboards, resources, lenses, actions and notifications as MCP tools.

v0.2.0 2026-10-17 13:07 UTC

This package is auto-updated.

Last update: 2026-10-17 18:35:43 UTC


README

Nova MCP gives AI agents a way into your Laravel Nova panel over the Model Context Protocol. Your resources, lenses, actions, dashboards, and notifications all become MCP tools.

Every request runs as the Nova user who created the token, so your policies still do their job.

Requirements

Nova must already be installed in your application using your own Nova license. Nova MCP does not include or redistribute Nova.

The Laravel AI SDK is optional. Nova MCP can be installed alongside Laravel AI 1.2+; that SDK requires Laravel 12.62+ or 13.15+. The test suite installs both packages and covers calling a Nova catalog tool through the SDK's McpServerTool adapter. In-process calls must already have an authenticated Nova user; they do not pass through the MCP endpoint's bearer-token middleware.

Install

composer require hemp/nova-mcp
php artisan migrate

Then register the tool in your NovaServiceProvider:

use Hemp\NovaMcp\NovaMcp;

public function tools(): array
{
    return [
        new NovaMcp,
    ];
}

You'll get a Nova MCP item in the Nova sidebar, where you can see the published tools and manage tokens.

Upgrading from 0.1

Version 0.2.0 requires Laravel 12 or 13 and Laravel MCP 1.x. Laravel 11 and Laravel MCP 0.9 are no longer supported. Upgrade your application's Laravel version first, then update the packages together:

composer require "hemp/nova-mcp:^0.2" "laravel/mcp:^1.0" --with-all-dependencies

Laravel AI is not required to use the MCP endpoint. If your application uses the AI SDK, it can remain installed alongside Nova MCP.

Make a token

Head to the Nova MCP screen and create one. It acts as the user who created it, you can give it an expiry, and revoking it cuts off access right away, even mid-session. Only a SHA-256 digest of the token gets stored.

Connect a client

The package serves both transports. Over HTTP, point your client at:

https://your-app.test/nova-vendor/nova-mcp/mcp

with the token in the authorization header:

Authorization: Bearer <token>

Locally, run the server over stdio with php artisan mcp:start nova and pass the token as NOVA_MCP_TOKEN.

Claude Code

Over HTTP:

claude mcp add --transport http nova https://your-app.test/nova-vendor/nova-mcp/mcp \
  --header "Authorization: Bearer novamcp_..."

Or over stdio, straight against your local app:

claude mcp add --env NOVA_MCP_TOKEN=novamcp_... --transport stdio nova \
  -- php /path/to/your-app/artisan mcp:start nova

Codex

codex mcp add nova --env NOVA_MCP_TOKEN=novamcp_... \
  -- php /path/to/your-app/artisan mcp:start nova

For the HTTP transport, add it to ~/.codex/config.toml yourself. The bearer token is read from an environment variable, not written in the file:

[mcp_servers.nova]
url = "https://your-app.test/nova-vendor/nova-mcp/mcp"
bearer_token_env_var = "NOVA_MCP_TOKEN"

Claude Desktop

Drop this in your config and fix up the path:

{
    "mcpServers": {
        "nova": {
            "command": "php",
            "args": ["/path/to/your-app/artisan", "mcp:start", "nova"],
            "env": { "NOVA_MCP_TOKEN": "novamcp_..." }
        }
    }
}

What the client sees

Two tools are always there:

Tool What it does
nova_overview Lists resources, dashboards, capabilities, and the current user
nova_resource_schema Fields, validation rules, filters, lenses, and actions for one resource

The rest come from your registered resources, named nova_<resource>_<operation>. So you'll see things like nova_posts_list, nova_posts_get, nova_posts_create, nova_posts_action_publish, nova_posts_lens_most_viewed, and nova_dashboard_main.

Once the catalog gets big enough (40 tools by default), Laravel MCP puts it behind search_tools and execute_tools so the client isn't drowning in a tool list.

The catalog is rebuilt from Nova's live registration on every request. Add a resource while the server is running and it shows up on the next request, along with a tools/list_changed notification.

Configuration

php artisan vendor:publish --tag=nova-mcp-config

The interesting bits of config/nova-mcp.php:

Key Default What it does
writes true Publish create, update, and delete tools
actions true Publish Nova action tools
web.enabled / local.enabled true Turn each transport on or off
tool_search_threshold 40 Catalog size that switches on tool search
resources.only / resources.except [] Limit which resources get published

Security

Both transports need a token. If the middleware stack ends up empty, Nova MCP refuses to register the endpoint rather than leave it open.

Requests go through Nova's viewNova gate and your resource policies, so a tool can show up in the catalog and still turn down the request if the user isn't allowed. Delete tools tell you what they changed and what they skipped.

Testing

From a source checkout, install the development dependencies using your Nova Composer credentials, then run the suite and lint:

composer install
composer test
vendor/bin/pint --test

The suite boots a Laravel application through Orchestra Testbench, using the models, migrations, Nova resources, and provider in tests/Fixtures. No separate example repository or database server is needed; tests use SQLite, so enable PHP's pdo_sqlite extension.

CI runs the full suite, including the Laravel AI adapter, and lint in all six combinations:

Laravel Testbench PHP
12 10 8.3, 8.4, 8.5
13 11 8.3, 8.4, 8.5

The Laravel AI SDK is installed as a development dependency for these tests, not as a runtime dependency for package consumers.

To rebuild the tool's frontend assets after changing resources/:

npm install
npm run production

Install Composer dependencies first: the frontend build uses the Nova devtool package from vendor/.

Amp orbs

Set NOVA_USERNAME and the secret NOVA_LICENSE_KEY in the Amp project's environment settings. .agents/setup installs PHP 8.4, its extensions, Composer, and the PHP and JavaScript dependencies, using the orb's preinstalled Node/npm. Nova credentials are passed to Composer in memory, never saved to auth.json. Warm setup reuses installed dependencies; .agents/resume only checks that they are present and the PHP platform requirements are satisfied.

License

MIT