MCP Tools for Developers

How LaraDashboard MCP tools are registered, authorized, and extended by modules using McpFilterHook.

MCP Tools for Developers

LaraDashboard exposes admin capabilities to AI agents through MCP tools. Core ships foundational tools; modules register additional tools without modifying core code.

Architecture

AI Client (Cursor / Claude)
        ↓
   POST /mcp
        ↓
 LaraDashboardServer
        ↓
 McpRegistryService ← McpFilterHook::TOOLS
        ↓
 Tool classes (core + modules)

Core never imports module classes directly. Modules hook into App\Enums\Hooks\McpFilterHook.

Core tools (22)

Registered in app/Mcp/Tools/ and loaded by McpRegistryService:

Tool Ability (typical) Permission
get-daily-briefing mcp:briefing.read dashboard.view
list-posts / get-post mcp:posts.read post.view
create-post mcp:posts.write post.create
update-post mcp:posts.update post.edit
delete-post mcp:posts.delete post.delete
list-terms / assign-post-terms mcp:terms.read term.view
list-media mcp:media.read media.view
upload-media / attach-featured-image mcp:media.write media.create
generate-seo-meta mcp:posts.update post.edit
list-email-templates / get-email-template mcp:email_templates.read email_template.view
send-email mcp:email.send email_template.view
clear-cache mcp:ops.cache settings.edit
list-logs / get-log-tail mcp:ops.logs.read settings.edit
get-site-health mcp:ops.health.read dashboard.view
list-mcp-tools mcp:access (token base ability)
list-modules mcp:modules.read module.view
activate-module / deactivate-module mcp:modules.activate / deactivate module.activate / module.deactivate

Module examples: CRM (16 tools), DocForge (4), CustomForm (2).

Available hooks

Hook Purpose
McpFilterHook::TOOLS Register tool class names
McpFilterHook::ABILITY_PERMISSION_MAP Map mcp:* abilities to Spatie permissions
McpFilterHook::TOKEN_ABILITIES Final token ability list per user
McpFilterHook::BRIEFING_PROVIDERS Daily briefing sections
McpFilterHook::TOOL_DEFINITIONS Mutate settings UI metadata

Register tools from a module

In your module bootstrap service (see CRM or DocForge for examples):

use App\Enums\Hooks\McpFilterHook;
use App\Support\Facades\Hook;

Hook::addFilter(McpFilterHook::TOOLS, [$this, 'registerMcpTools']);
Hook::addFilter(McpFilterHook::ABILITY_PERMISSION_MAP, [$this, 'registerMcpAbilities']);

public function registerMcpTools(array $tools): array
{
    return array_merge($tools, [
        \Modules\YourModule\Mcp\Tools\YourTool::class,
    ]);
}

public function registerMcpAbilities(array $map): array
{
    return array_merge($map, [
        'mcp:yourmodule.read' => 'yourmodule.view',
    ]);
}

Authoring a tool class

Place tools in modules/YourModule/app/Mcp/Tools/.

#[Name('your-tool')]
#[Description('What this tool does.')]
#[McpToolMeta(ability: 'mcp:yourmodule.read', permission: 'yourmodule.view', group: 'Your Module')]
class YourTool extends Tool
{
    use InteractsWithMcpAuthorization;

    public function shouldRegister(): bool
    {
        return Schema::hasTable('your_table');
    }

    public function handle(Request $request): Response
    {
        if ($response = $this->authorizeMcpAbility('mcp:yourmodule.read', 'yourmodule.view')) {
            return $response;
        }

        // Validate, call a service, return JSON
        return Response::json(['ok' => true]);
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'id' => $schema->integer()->description('Record ID.')->required(),
        ];
    }
}

Conventions

  • Use kebab-case tool names (list-contacts, search-docs).
  • Put business logic in services, not in the tool class.
  • Use shouldRegister() when the tool depends on optional tables.
  • Return structured JSON via Response::json() or errors via Response::error().
  • Reuse InteractsWithMcpAuthorization for token + permission checks.

Token generation

McpTokenService builds tokens with:

  1. Base ability mcp:access
  2. Every mcp:* ability whose mapped permission the user holds

Users generate tokens at Settings → MCP. Tokens are named laradashboard-mcp.

Server instructions

Update instructions in App\Mcp\Servers\LaraDashboardServer when you add major workflows so agents know which tools to chain.

Testing

Feature-test tools with:

LaraDashboardServer::actingAs($user, 'sanctum')
    ->tool(YourTool::class, ['id' => 1])
    ->assertOk();

Grant the user the mapped permission and create an MCP token via McpTokenService.

Related

/