diff --git a/app/Http/Controllers/DocsController.php b/app/Http/Controllers/DocsController.php index 4beec49..ca4537b 100644 --- a/app/Http/Controllers/DocsController.php +++ b/app/Http/Controllers/DocsController.php @@ -2,7 +2,11 @@ namespace App\Http\Controllers; +use App\Mcp\Servers\FiveMServer; +use Illuminate\Support\Str; use Illuminate\View\View; +use Laravel\Mcp\Server\Attributes\Description; +use ReflectionClass; class DocsController extends Controller { @@ -27,6 +31,64 @@ class DocsController extends Controller */ public function documentation(): View { - return view('docs.documentation'); + $serverReflection = new ReflectionClass(FiveMServer::class); + + $toolsProperty = $serverReflection->getProperty('tools'); + $resourcesProperty = $serverReflection->getProperty('resources'); + $promptsProperty = $serverReflection->getProperty('prompts'); + + $toolsProperty->setAccessible(true); + $resourcesProperty->setAccessible(true); + $promptsProperty->setAccessible(true); + + $defaultProperties = $serverReflection->getDefaultProperties(); + + $tools = $this->extractComponentDetails($defaultProperties['tools'] ?? [], 'tool'); + $resources = $this->extractComponentDetails($defaultProperties['resources'] ?? [], 'resource'); + $prompts = $this->extractComponentDetails($defaultProperties['prompts'] ?? [], 'prompt'); + + return view('docs.documentation', [ + 'tools' => $tools, + 'resources' => $resources, + 'prompts' => $prompts, + ]); + } + + /** + * Extract details from MCP components. + */ + protected function extractComponentDetails(array $components, string $type): array + { + return collect($components)->map(function ($componentClass) use ($type) { + $reflection = new ReflectionClass($componentClass); + $descriptionAttr = $reflection->getAttributes(Description::class)[0] ?? null; + $description = $descriptionAttr ? $descriptionAttr->getArguments()[0] : 'No description available'; + + // Get the simple class name and convert it to a readable format + $className = $reflection->getShortName(); + $name = $this->formatClassName($className); + + // Get category from namespace + $namespace = $reflection->getNamespaceName(); + $parts = explode('\\', $namespace); + $category = $parts[count($parts) - 1] ?? 'General'; + + return [ + 'name' => $name, + 'class' => $className, + 'description' => $description, + 'category' => $category, + 'type' => $type, + ]; + })->toArray(); + } + + /** + * Format class name to readable format. + */ + protected function formatClassName(string $className): string + { + // Convert PascalCase to Title Case with spaces + return Str::of($className)->kebab()->replace('-', ' ')->title(); } } diff --git a/resources/views/docs/documentation.blade.php b/resources/views/docs/documentation.blade.php index a62d7f3..1fd954f 100644 --- a/resources/views/docs/documentation.blade.php +++ b/resources/views/docs/documentation.blade.php @@ -3,589 +3,359 @@ @section('title', 'Full Documentation - FiveM MCP Server') @section('content') -
-
-

FiveM Development MCP Server

+
+
+

FiveM Development MCP Server

-

- A comprehensive Model Context Protocol (MCP) server for FiveM (GTA5) development, built with Laravel MCP. - This server provides AI assistants with powerful tools to help you develop FiveM resources more efficiently. +

+ A comprehensive Model Context Protocol (MCP) server for FiveM (GTA5) development, built with Laravel MCP. + This server provides AI assistants with powerful tools to help you develop FiveM resources more efficiently. +

+ + +
+

Installation & Connection

+

Choose how you want to connect to the FiveM MCP server:

+ + +
+ +
+ + +
+ +
+
+

+ Easy setup! Connect to a hosted MCP server. This is the easiest option and works from anywhere without any local setup. +

+ +

Claude Desktop Configuration:

+

Edit your configuration file:

+
    +
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • +
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • +
+ +

Add this configuration (replace with your actual server URL):

+
{
+      "mcpServers": {
+        "fivem": {
+          "url": "https://your-domain.com/fivem"
+        }
+      }
+    }
+
+ +
+

VSCode Configuration (Cline Extension):

+

If using VSCode with the Cline extension, edit your settings:

+
    +
  • Open VSCode Settings (JSON)
  • +
  • Add to your global or workspace settings.json
  • +
+ +
{
+      "mcp": {
+        "servers": {
+          "fivem": {
+            "url": "https://your-domain.com/fivem"
+          }
+        }
+      }
+    }
+
+
+ + + +
+ +
+

+ 💡 Tip: After configuring Claude Desktop, completely quit and restart the application for changes to take effect. +

+
+
+ + +
+

Available Tools

+

+ The FiveM MCP Server provides {{ count($tools) }} tools organized by category. + These tools allow AI assistants to search documentation, generate code, and lookup framework functions.

- -
-

Installation & Connection

-

Choose how you want to connect to the FiveM MCP server:

+ @php + $groupedTools = collect($tools)->groupBy('category'); + @endphp - -
- -
+ @foreach ($groupedTools as $category => $categoryTools) +
+

+ + {{ $category }} Tools + ({{ count($categoryTools) }}) +

- -
- -
-
-

- Easy setup! Connect to a hosted MCP server. This is the easiest option and works from anywhere without any local setup. -

- -

Claude Desktop Configuration:

-

Edit your configuration file:

-
    -
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • -
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • -
- -

Add this configuration (replace with your actual server URL):

-
{
-          "mcpServers": {
-            "fivem": {
-              "url": "https://your-domain.com/fivem"
-            }
-          }
-        }
+ @foreach ($categoryTools as $index => $tool) +
+

{{ $tool['name'] }}

+

{{ $tool['description'] }}

- -
-

VSCode Configuration (Cline Extension):

-

If using VSCode with the Cline extension, edit your settings:

-
    -
  • Open VSCode Settings (JSON)
  • -
  • Add to your global or workspace settings.json
  • -
- -
{
-          "mcp": {
-            "servers": {
-              "fivem": {
-                "url": "https://your-domain.com/fivem"
-              }
-            }
-          }
-        }
-
-
- - - + @endforeach
+ @endforeach -
-

- 💡 Tip: After configuring Claude Desktop, completely quit and restart the application for changes to take effect. -

-
-
- -
-

Available Tools

- - -
-

1. SearchFiveMDocs

-

Search FiveM, QBCore, and COX MySQL documentation for specific topics.

- -

Parameters:

-
    -
  • query (required): Search query (e.g., "events", - "natives", "mysql", "database")
  • -
  • category (optional): Filter by category (all, - scripting, natives, networking, resources, qbcore, coxdocs)
  • -
- -

Examples:

-
Search for QBCore callbacks and exports
-
How do I query the database with COX MySQL?
-
- - -
-

2. GetNativeFunction

-

Look up GTA5/FiveM native functions.

- -

Parameters:

-
    -
  • function_name (required): Native function name - (e.g., "GetPlayerPed", "SetEntityCoords")
  • -
  • language (optional): Code example language (lua - or js)
  • -
- -

Common Native Examples:

-
    -
  • Common natives: GetPlayerPed, SetEntityCoords, GetEntityCoords
  • -
  • CFX natives: RegisterNetEvent, TriggerServerEvent, TriggerClientEvent
  • -
  • ESX: ESX.GetPlayerFromId
  • -
  • QBCore: QBCore.Functions.GetPlayer
  • -
-
- - -
-

3. GenerateManifest

-

Generate a fxmanifest.lua file.

- -

Parameters:

-
    -
  • resource_name (required): Resource name
  • -
  • author (optional): Author name
  • -
  • description (optional): Resource description
  • -
  • version (optional): Version number (default: - "1.0.0")
  • -
  • script_type (optional): lua or js (default: lua) -
  • -
  • include_client (optional): Include client scripts - (default: true)
  • -
  • include_server (optional): Include server scripts - (default: true)
  • -
  • framework (optional): standalone, esx, or qbcore - (default: standalone)
  • -
- -

Example:

-
Generate a manifest for an ESX resource called "my-shop"
-
- - -
-

4. GetEventReference

-

Get information about FiveM, ESX, and QBCore events.

- -

Parameters:

-
    -
  • event_name (optional): Specific event name to - look up
  • -
  • event_type (optional): Filter by type (all, core, - esx, qbcore)
  • -
  • language (optional): Code example language (lua - or js)
  • -
- -

Examples:

-
Show me all core FiveM events
-
Look up the QBCore:Client:OnPlayerLoaded event
-
List all ESX events
-
- - -
-

5. GenerateResourceBoilerplate

-

Generate complete resource boilerplate code.

- -

Parameters:

-
    -
  • resource_name (required): Resource name
  • -
  • framework (optional): standalone, esx, or qbcore - (default: standalone)
  • -
  • script_type (optional): lua or js (default: lua) -
  • -
  • include_nui (optional): Include NUI files - (default: false)
  • -
- -

Example:

-
Generate boilerplate for a QBCore resource with NUI called "admin-panel"
-
- - -
-

6. GetQBCoreEventReference

-

Get information about QBCore framework events.

- -

Parameters:

-
    -
  • event_name (optional): Specific event name to - look up
  • -
  • event_category (optional): Filter by category - (all, player, job, inventory, vehicle, money)
  • -
  • language (optional): Code example language (lua - or js)
  • -
- -

Examples:

-
What's the QBCore:Client:OnPlayerLoaded event?
-
Show me all QBCore player events
-
List all QBCore inventory events
-
- - -
-

7. GetQBCoreFunction

-

Look up QBCore functions and exports.

- -

Parameters:

-
    -
  • function_name (required): QBCore function name - (e.g., "QBCore.Functions.GetPlayer", "AddMoney")
  • -
  • language (optional): Code example language (lua - or js)
  • -
- -

Common QBCore Functions:

-
    -
  • Player: QBCore.Functions.GetPlayer, QBCore.Functions.GetPlayerData
  • -
  • Items: AddItem, RemoveItem, GetItemByName
  • -
  • Money: AddMoney, RemoveMoney, GetMoney
  • -
  • Jobs: SetJob, GetJob
  • -
  • Vehicles: AddVehicle, DeleteVehicle
  • -
- -

Example:

-
How do I use the AddMoney function in QBCore?
-
- -
-

8. GetCOXEventReference

-

Get information about COX MySQL events and callbacks.

- -

Parameters:

-
    -
  • event_name (optional): Specific event name to - look up
  • -
  • event_type (optional): Filter by type (all, - query, connection, transaction, error)
  • -
  • language (optional): Code example language (lua - or js)
  • -
- -

Examples:

-
What are the COX MySQL connection events?
-
Show me all COX transaction events
-
How do I handle query errors in COX?
-
- - -
-

9. GetCOXFunction

-

Look up COX MySQL functions and methods.

- -

Parameters:

-
    -
  • function_name (required): COX function name - (e.g., "MySQL.query", "MySQL.insert")
  • -
  • language (optional): Code example language (lua - or js)
  • -
- -

Common COX Methods:

-
    -
  • Query: MySQL.query, MySQL.single, MySQL.scalar
  • -
  • Modify: MySQL.insert, MySQL.update
  • -
  • Transactions: MySQL.transaction.begin, MySQL.transaction.commit
  • -
  • Connection: MySQL.ready, MySQL.getStatus
  • -
  • Security: MySQL.prepare (prepared statements) -
  • -
- -

Example:

-
How do I query the database safely with prepared statements?
-

Available Resources

-

MCP Resources provide read-only reference documentation that AI assistants can access:

+

+ MCP Resources provide read-only reference documentation that AI assistants can access. + Currently available: {{ count($resources) }} resources. +

- -
-

1. Code Snippets

-

Common FiveM code patterns and snippets for quick reference.

-

URI: fivem://snippets/common

-

Includes patterns for distance checks, event handlers, threads with cleanup, database queries, and NUI callbacks in both Lua and JavaScript.

-
- - -
-

2. Best Practices

-

FiveM development best practices and optimization tips.

-

URI: fivem://guides/best-practices

-

Covers performance optimization, security best practices, code organization, resource management, testing, and common pitfalls.

-
- - -
-

4. Database Queries

-

FiveM database query examples and common patterns for COX MySQL.

-

URI: fivem://guides/database-queries

-

Covers CRUD operations, prepared statements, transactions, async queries, error handling, - performance tips, and common database patterns (SELECT, INSERT, UPDATE, DELETE).

-
+ @forelse ($resources as $index => $resource) +
+

{{ $index + 1 }}. {{ $resource['name'] }}

+

{{ $resource['description'] }}

+
+ @empty +

No resources configured.

+ @endforelse

Available Prompts

-

MCP Prompts are pre-built prompt templates for common tasks:

+

+ MCP Prompts are pre-built prompt templates for common tasks. + Currently available: {{ count($prompts) }} prompts. +

- -
-

1. Create New Resource

-

Create a new FiveM resource with framework and language selection.

-

Parameters: resource_name, framework (standalone/esx/qbcore), language (lua/js)

-
+ @forelse ($prompts as $index => $prompt) +
+

{{ $index + 1 }}. {{ $prompt['name'] }}

+

{{ $prompt['description'] }}

+
+ @empty +

No prompts configured.

+ @endforelse +
- -
-

2. Debug Issues

-

Debug common FiveM issues and errors with detailed analysis.

-

Parameters: issue (description), error_message (from console)

-
+ +
+

Testing the Server

+

You can test the MCP server locally using the inspector:

+
php artisan mcp:inspector fivem
+

This will open the MCP Inspector in your browser where you can test all the tools interactively.

+
- -
-

3. Optimize Performance

-

Optimize FiveM script performance with detailed suggestions.

-

Parameters: code (script to optimize), script_type (client/server/shared)

-
+ +
+

Development

- -
-

4. Convert Language

-

Convert code between Lua and JavaScript with proper syntax.

-

Parameters: code, from (lua/js), to (lua/js)

-
+

Adding New Tools

+

1. Create a new tool class in app/Mcp/Tools/:

- -
-

5. Add Framework Integration

-

Add ESX or QBCore framework integration to existing resource.

-

Parameters: code (current resource), current_framework, target_framework (esx/qbcore)

-
-
+
<?php
 
-                
-                
-

Testing the Server

-

You can test the MCP server locally using the inspector:

-
php artisan mcp:inspector fivem
-

This will open the MCP Inspector in your browser where you can test all the tools interactively.

-
+ namespace App\Mcp\Tools; - -
-

Development

+ use Illuminate\Contracts\JsonSchema\JsonSchema; + use Laravel\Mcp\Request; + use Laravel\Mcp\Response; + use Laravel\Mcp\Server\Attributes\Description; + use Laravel\Mcp\Server\Tool; -

Adding New Tools

-

1. Create a new tool class in app/Mcp/Tools/:

- -
<?php
-
-        namespace App\Mcp\Tools;
-
-        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('Your tool description')]
-        class YourTool extends Tool
+    #[Description('Your tool description')]
+    class YourTool extends Tool
+    {
+        public function handle(Request $request): Response
         {
-            public function handle(Request $request): Response
-            {
-                // Tool logic here
-                return Response::text('Result');
-            }
+            // Tool logic here
+            return Response::text('Result');
+        }
 
-            public function schema(JsonSchema $schema): array
-            {
-                return [
-                    'param' => $schema->string()->required(),
-                ];
-            }
-        }
+ public function schema(JsonSchema $schema): array + { + return [ + 'param' => $schema->string()->required(), + ]; + } + }
-

2. Register the tool in app/Mcp/Servers/FiveMServer.php:

+

2. Register the tool in app/Mcp/Servers/FiveMServer.php:

-
protected array $tools = [
-            // ... existing tools
-            \App\Mcp\Tools\YourTool::class,
-        ];
+
protected array $tools = [
+        // ... existing tools
+        \App\Mcp\Tools\YourTool::class,
+    ];
-

Code Formatting

-

Format code with Laravel Pint:

-
vendor/bin/pint
-
+

Code Formatting

+

Format code with Laravel Pint:

+
vendor/bin/pint
+ - -
-

Supported Frameworks

-
    -
  • Standalone: Basic FiveM resources without framework dependencies
  • -
  • ESX: ESX Framework (es_extended)
  • -
  • QBCore: QBCore Framework (qb-core)
  • -
+ +
+

Supported Frameworks

+
    +
  • Standalone: Basic FiveM resources without framework dependencies
  • +
  • ESX: ESX Framework (es_extended)
  • +
  • QBCore: QBCore Framework (qb-core)
  • +
-

Scripting Languages

-

Both Lua and JavaScript are fully supported across all tools and generators.

-
+

Scripting Languages

+

Both Lua and JavaScript are fully supported across all tools and generators.

+
- -
-

Resources

- -
+ +
+

Resources

+ +
- -
-

Contributing

-

Contributions are welcome! Areas for expansion:

-
    -
  • More native functions in the database
  • -
  • Additional framework support (vRP, etc.)
  • -
  • More event types
  • -
  • Advanced code generators
  • -
  • Database query builders
  • -
-
+ +
+

Contributing

+

Contributions are welcome! Areas for expansion:

+
    +
  • More native functions in the database
  • +
  • Additional framework support (vRP, etc.)
  • +
  • More event types
  • +
  • Advanced code generators
  • +
  • Database query builders
  • +
+
- -
-

License

-

MIT License

-
-
+ +
+

License

+

MIT License

+
+
- + }); + @endsection diff --git a/tests/Feature/DocsRoutesTest.php b/tests/Feature/DocsRoutesTest.php index 1e84ca4..f710663 100644 --- a/tests/Feature/DocsRoutesTest.php +++ b/tests/Feature/DocsRoutesTest.php @@ -42,6 +42,20 @@ it('documentation renders correct view', function () { $response->assertViewIs('docs.documentation'); }); +it('documentation page includes dynamic tools data', function () { + $response = $this->get('/documentation'); + + $response->assertViewHas('tools'); + $response->assertViewHas('resources'); + $response->assertViewHas('prompts'); + + expect($response->viewData('tools'))->toBeArray(); + expect($response->viewData('resources'))->toBeArray(); + expect($response->viewData('prompts'))->toBeArray(); + + expect($response->viewData('tools'))->not()->toBeEmpty(); +}); + it('nonexistent route returns 404', function () { $response = $this->get('/nonexistent-page-xyz');